react-i18next#I18nextProvider TypeScript Examples
The following examples show how to use
react-i18next#I18nextProvider.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: InlineDatePicker.tsx From ant-extensions with MIT License | 7 votes |
InlineDatePicker: React.FC<DatePickerProps> = React.forwardRef<
React.Component,
DatePickerProps
>((props, ref) => {
const refContainer = useRef<HTMLDivElement>(null);
const refPicker = useRef<HTMLDivElement>(document.createElement("div"));
useLayoutEffect(() => {
if (refContainer.current) {
refContainer.current.appendChild(refPicker.current);
}
}, []);
return (
<I18nextProvider i18n={i18next}>
<div ref={refContainer} className="ant-ext-sd__inlinePicker">
<DatePicker
{...props}
ref={ref}
open
inputReadOnly
getPopupContainer={() => refPicker.current}
/>
</div>
</I18nextProvider>
);
})
Example #2
Source File: index.tsx From ant-extensions with MIT License | 6 votes |
I18nProvider: React.FC<{ locale: string }> = ({ children, locale }) => {
useEffect(() => {
console.log("=====> change locale", locale);
i18next.changeLanguage(locale).then(() => {
document.documentElement.lang = locale;
document.documentElement.dir = i18next.dir();
});
}, [locale]);
return <I18nextProvider i18n={i18next}>{children}</I18nextProvider>;
}
Example #3
Source File: renderer.tsx From TidGi-Desktop with Mozilla Public License 2.0 | 6 votes |
function App(): JSX.Element {
const theme = useThemeObservable();
return (
<ThemeProvider theme={theme?.shouldUseDarkColors === true ? darkTheme : lightTheme}>
<StyledEngineProvider injectFirst>
<LocalizationProvider dateAdapter={DateFnsUtils}>
<CssBaseline />
<React.Suspense fallback={<div />}>
<I18nextProvider i18n={i18n}>
<RootStyle>
<Pages />
</RootStyle>
</I18nextProvider>
</React.Suspense>
</LocalizationProvider>
</StyledEngineProvider>
</ThemeProvider>
);
}
Example #4
Source File: App.tsx From metro-fare with MIT License | 6 votes |
App = () => {
return (
<>
<I18nextProvider i18n={i18n}>
<BrowserRouter>
<TripProvider>
<MapProvider>
<DrawerProvider>
<RealApp />
</DrawerProvider>
</MapProvider>
</TripProvider>
</BrowserRouter>
</I18nextProvider>
</>
);
}
Example #5
Source File: TestContext.tsx From longwave with MIT License | 6 votes |
export function TestContext(props: {
gameState: GameState;
playerId: string;
children: ReactChild;
setState?: (newState: Partial<GameState>) => void;
}) {
return (
<GameModelContext.Provider
value={BuildGameModel(
props.gameState,
props.setState || jest.fn(),
props.playerId,
() => ["left", "right"],
() => {}
)}
>
<Suspense fallback={<div>Loading...</div>}>
<I18nextProvider i18n={i18n}>{props.children}</I18nextProvider>
</Suspense>
</GameModelContext.Provider>
);
}
Example #6
Source File: ReceiveModal.test.tsx From raspiblitz-web with MIT License | 6 votes |
describe("ReceiveModal", () => {
test("Retrieves new on-chain address on click of on-chain button", async () => {
const { container } = render(
<I18nextProvider i18n={i18n}>
<ReceiveModal onClose={() => {}} />
</I18nextProvider>
);
await act(async () => {
(await screen.findByText("wallet.on_chain")).click();
});
await waitFor(() => expect(container.querySelector("svg")).toBeDefined());
});
});
Example #7
Source File: TransactionCard.test.tsx From raspiblitz-web with MIT License | 6 votes |
describe("TransactionCard", () => {
test("if info is being displayed if transactions are empty", async () => {
render(
<I18nextProvider i18n={i18n}>
<TransactionCard {...props} />
</I18nextProvider>
);
expect(screen.getByText("tx.transactions_none")).toBeInTheDocument();
});
});
Example #8
Source File: AppCard.test.tsx From raspiblitz-web with MIT License | 6 votes |
describe("AppCard", () => {
test("display install button if installed is false", async () => {
render(
<I18nextProvider i18n={i18n}>
<AppCard {...basicProps} installed={false} />
</I18nextProvider>
);
expect(await screen.findByText("apps.install")).toBeDefined();
});
test("display open button if installed & address is available", async () => {
render(
<I18nextProvider i18n={i18n}>
<AppCard {...basicProps} address={"addr"} installed={true} />
</I18nextProvider>
);
expect(await screen.findByText("apps.open")).toBeDefined();
});
test("display no_page button if installed & address is not available", async () => {
render(
<I18nextProvider i18n={i18n}>
<AppCard {...basicProps} installed={true} />
</I18nextProvider>
);
expect(await screen.findByText("apps.no_page")).toBeDefined();
});
});
Example #9
Source File: App.tsx From BlinkWebUI with GNU General Public License v3.0 | 6 votes |
render(): JSX.Element {
return (
<>
<CssBaseline />
<ThemeProvider theme={theme}>
<I18nextProvider i18n={i18n}>
<Router>
<MainLayout />
</Router>
</I18nextProvider>
</ThemeProvider>
</>
);
}
Example #10
Source File: UnlockModal.test.tsx From raspiblitz-web with MIT License | 5 votes |
describe("UnlockModal", () => {
const setup = () => {
render(
<I18nextProvider i18n={i18n}>
<UnlockModal onClose={handleClose} />
</I18nextProvider>
);
};
test("renders", () => {
setup();
const input = screen.getByPlaceholderText("forms.validation.unlock.pass_c");
expect(input).toHaveClass("input-underline");
expect(input).toBeInTheDocument();
});
// https://github.com/cstenglein/raspiblitz-web/issues/234
// skipped due to react v18 update
test.skip("should enable button if input is not empty", async () => {
setup();
const input = screen.getByPlaceholderText("forms.validation.unlock.pass_c");
const button = screen.getByRole("button");
expect(button).toBeDisabled();
userEvent.type(input, "1234");
expect(await screen.findByRole("button")).toBeEnabled();
});
// https://github.com/cstenglein/raspiblitz-web/issues/234
// skipped due to react v18 update
test.skip("should show text on wrong password", async () => {
server.use(
rest.post("/api/v1/lightning/unlock-wallet", (_, res, ctx) => {
return res(ctx.status(401));
})
);
setup();
const input = screen.getByPlaceholderText("forms.validation.unlock.pass_c");
userEvent.type(input, "1234");
userEvent.click(screen.getByText("wallet.unlock"));
expect(await screen.findByText("login.invalid_pass")).toBeInTheDocument();
});
// https://github.com/cstenglein/raspiblitz-web/issues/234
// skipped due to react v18 update
test.skip("should display unlocking text on unlock", async () => {
server.use(
rest.post("/api/v1/lightning/unlock-wallet", (_, res, ctx) => {
return res(ctx.status(200));
})
);
setup();
const input = screen.getByPlaceholderText("forms.validation.unlock.pass_c");
userEvent.type(input, "1234");
userEvent.click(await screen.findByText("wallet.unlock"));
expect(await screen.findByText("wallet.unlocking")).toBeInTheDocument();
});
});
Example #11
Source File: index.tsx From landy-react-template with MIT License | 5 votes |
App = () => (
<BrowserRouter>
<I18nextProvider i18n={i18n}>
<Router />
</I18nextProvider>
</BrowserRouter>
)
Example #12
Source File: index.tsx From website-docs with MIT License | 5 votes |
export default function NotFoundPage({ data }: { data: AllLocales }) {
const { docInfo, searchValue } = useSelector(state => state) as any
const dispatch = useDispatch()
const handleSetSearchValue = (value: string) =>
dispatch(setSearchValue(value))
const pathname = typeof window === 'undefined' ? '' : window.location.pathname
const context = useContext(I18nextContext)
const language = useMemo(() => {
const lang = pathname.slice(1)?.split('/')?.pop() || ''
switch (lang) {
case 'zh':
return 'zh'
case 'ja':
return 'ja'
default:
break
}
return 'en'
}, [pathname])
const i18n = useMemo(() => {
const i18n = i18next.createInstance()
const resources = data.locales.edges.reduce((acc, cur) => {
acc[cur.node.language] = { [cur.node.ns]: JSON.parse(cur.node.data) }
return acc
}, {} as Record<string, Record<string, any>>)
i18n.init({
resources,
lng: language,
fallbackLng: 'en',
react: {
useSuspense: false,
},
})
return i18n
}, [language, data])
return (
<I18nextProvider i18n={i18n}>
<I18nextContext.Provider value={{ ...context, language }}>
<Layout>
<Seo title="404 Not Found" noindex />
<div className={styles.container}>
<div className={clsx('markdown-body', styles.left)}>
<h1 className={clsx(styles.title)}>
{<Trans i18nKey="doc404.title" />}
</h1>
<div>{<Trans i18nKey="doc404.youMayWish" />}</div>
<ul className={clsx(styles.optionsContainer)}>
<li>
{
<Trans
i18nKey="doc404.goToDocHome"
components={[<Link to="/" />]}
/>
}
</li>
<li>{<Trans i18nKey="doc404.searchDoc" />}</li>
</ul>
<div className={styles.searchInput}>
<SearchInput
docInfo={docInfo}
searchValue={searchValue}
setSearchValue={handleSetSearchValue}
/>
</div>
</div>
<div className={clsx(styles.right)}></div>
</div>
</Layout>
</I18nextContext.Provider>
</I18nextProvider>
)
}
Example #13
Source File: _app.tsx From nextclade with MIT License | 5 votes |
export function MyApp({ Component, pageProps, router }: AppProps) {
const queryClient = useMemo(() => new QueryClient(), [])
const { store } = useMemo(() => configureStore(), [])
const fallback = useMemo(() => <Loading />, [])
useEffect(() => {
if (process.env.NODE_ENV !== 'development' && router.pathname === '/results') {
void router.replace('/') // eslint-disable-line no-void
}
void router.prefetch('/') // eslint-disable-line no-void
void router.prefetch('/results') // eslint-disable-line no-void
}, [router])
return (
<Suspense fallback={fallback}>
<ReactReduxProvider store={store}>
<RecoilRoot>
<ThemeProvider theme={theme}>
<MDXProvider components={mdxComponents}>
<Plausible domain={DOMAIN_STRIPPED} />
<QueryClientProvider client={queryClient}>
<I18nextProvider i18n={i18n}>
<ErrorBoundary>
<Suspense>
<RecoilStateInitializer />
</Suspense>
<Suspense fallback={fallback}>
<SEO />
<Component {...pageProps} />
<ErrorPopup />
<ReactQueryDevtools initialIsOpen={false} />
</Suspense>
</ErrorBoundary>
</I18nextProvider>
</QueryClientProvider>
</MDXProvider>
</ThemeProvider>
</RecoilRoot>
</ReactReduxProvider>
</Suspense>
)
}
Example #14
Source File: TreePage.tsx From nextclade with MIT License | 5 votes |
function TreePageDisconnected({ treeMeta }: TreePageProps) {
const isDataFromGisaid = useMemo(
() => treeMeta?.dataProvenance?.some((provenance) => provenance.name?.toLowerCase() === 'gisaid'),
[treeMeta],
)
return (
<LayoutResults>
<Container>
<Header>
<HeaderLeft>
<ButtonBack />
</HeaderLeft>
<HeaderCenter />
</Header>
<MainContent>
<AuspiceContainer>
<I18nextProvider i18n={i18nAuspice}>
<SidebarContainer>
<Sidebar />
</SidebarContainer>
<TreeContainer>
<TreeTopPanel>
<FiltersSummaryWrapper>
<FiltersSummary />
</FiltersSummaryWrapper>
{isDataFromGisaid && (
<LogoGisaidWrapper>
<LogoGisaid />
</LogoGisaidWrapper>
)}
</TreeTopPanel>
<Tree />
</TreeContainer>
</I18nextProvider>
</AuspiceContainer>
</MainContent>
</Container>
</LayoutResults>
)
}
Example #15
Source File: wrapPageElement.tsx From gatsby-plugin-react-i18next with MIT License | 5 votes |
withI18next = (i18n: I18n, context: I18NextContext) => (children: any) => {
return (
<I18nextProvider i18n={i18n}>
<I18nextContext.Provider value={context}>{children}</I18nextContext.Provider>
</I18nextProvider>
);
}
Example #16
Source File: TestWrapper.tsx From ant-extensions with MIT License | 5 votes |
TestWrapper: React.FC = ({ children }) => {
return <I18nextProvider i18n={i18next}>{children}</I18nextProvider>;
}
Example #17
Source File: FronteggProvider.tsx From frontegg-react with MIT License | 5 votes |
FeState: FC<FeProviderProps> = (props) => {
const history = useHistory();
const storeRef = useRef<any>({});
const location = useLocation();
const baseName = isSSR
? ''
: window.location.pathname.substring(0, window.location.pathname.lastIndexOf(location.pathname));
const onRedirectTo =
props.onRedirectTo ??
((_path: string, opts?: RedirectOptions) => {
let path = _path;
if (path.startsWith(baseName)) {
path = path.substring(baseName.length);
}
if (opts?.preserveQueryParams) {
path = `${path}${window.location.search}`;
}
if (opts?.refresh && !isSSR) {
window.Cypress ? history.push(path) : (window.location.href = path);
} else {
opts?.replace ? history.replace(path) : history.push(path);
}
});
ContextHolder.setOnRedirectTo(onRedirectTo);
const store = useMemo(
() =>
props.store ??
createFronteggStore(
{ context: props.context },
storeRef.current,
false,
{
...(props.plugins?.find((n) => n.storeName === authStoreName)?.preloadedState ?? {}),
onRedirectTo,
},
{
audits: {
context: props.context,
...props.context.auditsOptions,
...(props.plugins?.find((n) => n.storeName === 'audits')?.preloadedState ?? {}),
} as any,
}
),
[props.store]
);
useEffect(
() => () => {
try {
(storeRef.current as any)?.store.destroy?.();
} catch (e) {}
},
[]
);
/* for Cypress tests */
if (!isSSR && window.Cypress) {
window.cypressHistory = history;
}
return (
<Provider context={FronteggStoreContext} store={store}>
<I18nextProvider i18n={i18n}>
<FePlugins {...props} />
</I18nextProvider>
</Provider>
);
}
Example #18
Source File: Provider.tsx From nosgestesclimat-site with MIT License | 5 votes |
export default function Provider({ tracker = new Tracker(), reduxMiddlewares, initialStore, onStoreCreated, children, sitePaths = {} as SitePaths, dataBranch, rulesURL, }: ProviderProps) { const history = useMemo(() => createBrowserHistory(), []) useEffect(() => { tracker?.connectToHistory(history) return () => { tracker?.disconnectFromHistory() } }) const storeEnhancer = composeEnhancers( applyMiddleware( // Allows us to painlessly do route transition in action creators thunk.withExtraArgument({ history, sitePaths, }), ...(reduxMiddlewares ?? []) ) ) // Hack: useMemo is used to persist the store across hot reloads. const store = useMemo(() => { return createStore(reducers, initialStore, storeEnhancer) }, []) onStoreCreated?.(store) const iframeCouleur = new URLSearchParams(document?.location.search.substring(1)).get( 'couleur' ) ?? undefined return ( // If IE < 11 display nothing <ReduxProvider store={store}> <RulesProvider dataBranch={dataBranch} rulesURL={rulesURL}> <ThemeColorsProvider color={iframeCouleur && decodeURIComponent(iframeCouleur)} > <IframeOptionsProvider tracker={tracker}> <TrackerProvider value={tracker}> <SitePathProvider value={sitePaths}> <I18nextProvider i18n={i18next}> <Router history={history}> <>{children}</> </Router> </I18nextProvider> </SitePathProvider> </TrackerProvider> </IframeOptionsProvider> </ThemeColorsProvider> </RulesProvider> </ReduxProvider> ) }
Example #19
Source File: SwitchTxType.test.tsx From raspiblitz-web with MIT License | 5 votes |
describe("SwitchTxType", () => {
test("txType: lightning", async () => {
const handeTxTypeChangeMock = jest.fn();
render(
<I18nextProvider i18n={i18n}>
<SwitchTxType
invoiceType={TxType.LIGHTNING}
onTxTypeChange={handeTxTypeChangeMock}
/>
</I18nextProvider>
);
const buttonLn = screen.getByText("home.lightning");
const buttonOnChain = screen.getByText("wallet.on_chain");
expect(buttonLn).toBeDisabled();
expect(buttonOnChain).not.toBeDisabled();
buttonOnChain.click();
expect(handeTxTypeChangeMock).toHaveBeenCalledTimes(1);
expect(handeTxTypeChangeMock).toHaveBeenCalledWith(TxType.ONCHAIN);
});
test("txType: onchain", async () => {
const handeTxTypeChangeMock = jest.fn();
render(
<I18nextProvider i18n={i18n}>
<SwitchTxType
invoiceType={TxType.ONCHAIN}
onTxTypeChange={handeTxTypeChangeMock}
/>
</I18nextProvider>
);
const buttonLn = screen.getByText("home.lightning");
const buttonOnChain = screen.getByText("wallet.on_chain");
expect(buttonLn).not.toBeDisabled();
expect(buttonOnChain).toBeDisabled();
buttonLn.click();
expect(handeTxTypeChangeMock).toHaveBeenCalledTimes(1);
expect(handeTxTypeChangeMock).toHaveBeenCalledWith(TxType.LIGHTNING);
});
});
Example #20
Source File: SendLN.test.tsx From raspiblitz-web with MIT License | 5 votes |
setup = () => {
render(
<I18nextProvider i18n={i18n}>
<SendLN {...basicProps} />
</I18nextProvider>
);
}
Example #21
Source File: InlineRangePicker.tsx From ant-extensions with MIT License | 5 votes |
InlineRangePicker: React.FC<RangePickerProps> = React.forwardRef<
React.Component,
RangePickerProps
>(({ value, ...props }, ref) => {
const refContainer = useRef<HTMLDivElement>(null);
const refRangePicker = useRef<AnyObject>(null);
const refPicker = useRef<HTMLDivElement>(document.createElement("div"));
useEffect(() => {
if (typeof ref === "function") {
ref(refRangePicker.current);
} else if (ref) {
ref.current = refRangePicker.current;
}
}, [ref]);
useLayoutEffect(() => {
if (refContainer.current) {
refContainer.current.appendChild(refPicker.current);
}
}, []);
const [_value, setValue] = useState<AnyObject>([null, null]);
useEffect(() => {
setValue(value || [null, null]);
}, [value]);
const doUpdate = useCallback((v) => {
setValue(v);
}, []);
const resetValue = useCallback(
(e: AnyObject) => {
if (
_value[0] &&
_value[1] &&
(e.target.classList.contains("ant-picker-content") ||
e.target.classList.contains("ant-picker-cell-inner"))
) {
setValue([null, null]);
setTimeout(() => refRangePicker.current && refRangePicker.current.focus(), 10);
}
return true;
},
[_value]
);
return (
<I18nextProvider i18n={i18next}>
<div ref={refContainer} className="ant-ext-sd__inlinePicker" onMouseDownCapture={resetValue}>
<RangePicker
{...props}
open
ref={refRangePicker}
inputReadOnly
value={_value as AnyObject}
onCalendarChange={doUpdate}
getPopupContainer={() => refPicker.current}
/>
</div>
</I18nextProvider>
);
})
Example #22
Source File: InputField.test.tsx From raspiblitz-web with MIT License | 5 votes |
describe("InputField", () => {
test("render with placeholder", async () => {
render(
<I18nextProvider i18n={i18n}>
<InputField {...basicProps} placeholder="A yellow fruit" />
</I18nextProvider>
);
const input = await screen.findByLabelText("Banana Label");
await waitFor(() => expect(input).toHaveClass("input-underline"));
expect(input).toBeInTheDocument();
expect(screen.getByPlaceholderText("A yellow fruit")).toBeInTheDocument();
});
test("render with error-message", async () => {
render(
<I18nextProvider i18n={i18n}>
<InputField
{...basicProps}
errorMessage={{ type: "required", message: "Banana required!" }}
/>
</I18nextProvider>
);
const input = await screen.findByLabelText("Banana Label");
await waitFor(() => expect(input).toHaveClass("input-error"));
expect(input).toBeInTheDocument();
expect(screen.getByText("Banana required!")).toBeInTheDocument();
});
test("prop inputRightAddon", async () => {
render(
<I18nextProvider i18n={i18n}>
<InputField {...basicProps} inputRightAddon="Right add-on text" />
</I18nextProvider>
);
expect(screen.getByText("Right add-on text")).toBeInTheDocument();
});
test("prop inputRightElement", async () => {
render(
<I18nextProvider i18n={i18n}>
<InputField
{...basicProps}
inputRightElement={<button>Click me!</button>}
/>
</I18nextProvider>
);
expect(screen.getByText("Click me!")).toBeInTheDocument();
});
});
Example #23
Source File: TagPicker.tsx From ant-extensions with MIT License | 5 votes |
TagPicker: React.FC<AnyObject> = ({
value,
onChange,
onVisibleChange,
readOnly,
disabled,
pickerEl: E
}) => {
const {
i18n: { language }
} = useTranslation(I18nKey);
const refDropdown = useRef<typeof Popover>(null);
const [visible, setVisible] = useState(false);
const [_value, setValue] = useState(value);
const isDisabled = useMemo(() => disabled || readOnly, [disabled, readOnly]);
useEffect(() => {
setValue(value);
}, [value]);
const doUpdate = useCallback(
(v: DateValue) => {
setValue(v);
setVisible(false);
onChange && onChange(v);
},
[onChange]
);
const toggleVisible = useCallback(
(v) => {
if (!isDisabled) {
setVisible(v);
onVisibleChange && onVisibleChange(v);
}
},
[onVisibleChange, isDisabled]
);
const displayLabel = useMemo(
() => (value && !!language ? parseDateLabel(value.toString()) : ""),
[value, language]
);
return (
<I18nextProvider i18n={i18next}>
<Tooltip overlayClassName="ant-ext-sd__tooltip" title={DateUtils.toString(_value)}>
<Popover
ref={refDropdown}
visible={visible}
destroyTooltipOnHide
onVisibleChange={toggleVisible}
overlayClassName="ant-ext-sd__popover"
content={!readOnly && <E dropdown={refDropdown} value={value} onChange={doUpdate} />}
trigger="click"
placement="bottomLeft"
>
<Tag
color="blue"
icon={<FieldTimeOutlined />}
className="ant-ext-sd__tag"
data-testid="input-el"
>
{displayLabel}
</Tag>
</Popover>
</Tooltip>
</I18nextProvider>
);
}
Example #24
Source File: App.test.tsx From raspiblitz-web with MIT License | 5 votes |
describe("App", () => {
afterEach(() => {
server.resetHandlers();
});
test("should route to /setup if setup is not done", async () => {
server.use(
rest.get("/api/v1/setup/status", (_, res, ctx) => {
return res(
ctx.status(200),
ctx.json({
setupPhase: "STARTING",
state: "",
message: "",
})
);
})
);
render(
<I18nextProvider i18n={i18n}>
<BrowserRouter>
<App />
</BrowserRouter>
</I18nextProvider>
);
await waitFor(() => expect(mockedUsedNavigate).toHaveBeenCalledTimes(1));
});
test("should route to /login if setup is done", async () => {
server.use(
rest.get("/api/v1/setup/status", (_, res, ctx) => {
return res(
ctx.status(200),
ctx.json({
setupPhase: "DONE",
state: "",
message: "",
})
);
})
);
render(
<I18nextProvider i18n={i18n}>
<BrowserRouter>
<App />
</BrowserRouter>
</I18nextProvider>
);
await waitFor(() => expect(mockedUsedNavigate).toHaveBeenCalledTimes(0));
});
});
Example #25
Source File: Main.tsx From clearflask with Apache License 2.0 | 4 votes |
render() {
const Router = (windowIso.isSsr ? StaticRouter : BrowserRouter) as React.ElementType;
// Redirect www to homepage
if (windowIso.location.hostname.startsWith('www.')) {
return (<RedirectIso to={windowIso.location.origin.replace(`www.`, '')} />);
}
const isSelfHost = detectEnv() === Environment.PRODUCTION_SELF_HOST;
const isParentDomain = windowIso.location.hostname === windowIso.parentDomain
|| (!isProd() && windowIso.location.hostname === 'localhost');
const showSite = isParentDomain && !isSelfHost;
const showProject = !showSite;
const showDashboard = isParentDomain || isSelfHost;
if (showSite || showDashboard) {
trackingImplicitConsent();
}
return (
<ErrorBoundary showDialog>
<React.StrictMode>
<I18nextProvider i18n={this.props.i18n}>
<StylesProvider injectFirst>
<MuiThemeProvider theme={this.theme}>
<MuiSnackbarProvider notistackRef={notistackRef}>
<CssBaseline />
<ServerErrorNotifier />
<CaptchaChallenger />
<RemoveSsrCss />
<CrowdInInlineEditing />
<div style={{
minHeight: windowIso.isSsr ? undefined : this.theme.vh(100),
display: 'flex',
flexDirection: 'column',
background: this.theme.palette.background.default,
}}>
<Router
{...(windowIso.isSsr ? {
location: this.props.ssrLocation,
context: this.props.ssrStaticRouterContext,
} : {})}
>
<ScrollAnchor scrollOnNavigate />
<Route path='/' render={routeProps => {
trackingBlock(() => {
ReactGA.set({ page: routeProps.location.pathname + routeProps.location.search });
ReactGA.pageview(routeProps.location.pathname + routeProps.location.search);
});
return null;
}} />
<Route render={routeProps => routeProps.location.pathname.startsWith('/embed-status') ? null : (
<EnvironmentNotifier key='env-notifier' />
)} />
<Switch>
{[
(
<Route key='api-docs' path='/api' render={props => (
<NoSsr>
<ApiDocs />
</NoSsr>
)} />
),
...(!isProd() ? [(
<Route key='mock-oauth-provider-bathtub' path='/bathtub/authorize' render={props => (
<Provider store={ServerAdmin.get().getStore()}>
<BathtubOauthProvider />
</Provider>
)} />
)] : []),
...(showDashboard ? [(
<Route key='dashboard' path="/dashboard/:path?/:subPath*" render={props => (
<Provider store={ServerAdmin.get().getStore()}>
<SentryIdentifyAccount />
<SetMaxAge val={0 /* If you want to cache, don't cache if auth is present in URL */} />
<NoSsr>
<Dashboard {...props} />
</NoSsr>
<IntercomWrapperMain suppressBind />
<HotjarWrapperMain />
</Provider>
)} />
), (
<Route key='invoice' path="/invoice/:invoiceId" render={props => (
<Provider store={ServerAdmin.get().getStore()}>
<SentryIdentifyAccount />
<SetMaxAge val={0} />
<Invoice invoiceId={props.match.params['invoiceId']} />
</Provider>
)} />
), (
<Route key='enter' exact path='/:type(login|signup|invitation|coupon)/:id([a-z0-9]*)?' render={props => (
<Provider store={ServerAdmin.get().getStore()}>
<SetMaxAge val={0} />
<SetTitle title={props.match.params['type'] === 'login'
? 'Login'
: (props.match.params['type'] === 'signup'
? 'Sign up'
: (props.match.params['type'] === 'invitation'
? 'Invitation'
: 'Coupon'))} />
<AccountEnterPage
type={props.match.params['type']}
invitationId={props.match.params['type'] === 'invitation' ? props.match.params['id'] : undefined}
couponId={props.match.params['type'] === 'coupon' ? props.match.params['id'] : undefined}
/>
</Provider>
)} />
)] : []),
...(showProject ? [(
<Route key='embed-status' path="/embed-status/post/:postId" render={props => (
<>
<SetMaxAge val={24 * 60 * 60} />
<PostStatus
{...props}
postId={props.match.params['postId'] || ''}
/>
</>
)} />
), (
<Route key='app' path='/' render={props => (
<>
<SetMaxAge val={60} />
<App slug={windowIso.location.hostname} {...props} />
</>
)} />
)] : []),
...(showSite ? [(
<Route key='site' path='/' render={props => (
<Provider store={ServerAdmin.get().getStore()}>
<SentryIdentifyAccount />
<SetMaxAge val={24 * 60 * 60} />
<Site {...props} />
<IntercomWrapperMain />
<HotjarWrapperMain />
</Provider>
)} />
)] : []),
]}
</Switch>
</Router>
</div>
</MuiSnackbarProvider>
</MuiThemeProvider>
</StylesProvider>
</I18nextProvider>
</React.StrictMode>
</ErrorBoundary>
);
}
Example #26
Source File: index.tsx From ant-extensions with MIT License | 4 votes |
ContextProvider: React.FC<Partial<ISearchProps & IFilterProps>> = ({
children,
fields = [],
filters: _filters = [],
query: _query = "",
onQueryChange,
onFilterAdded,
onFilterUpdate,
onFilterRemoved,
onFilterChanged,
onSearch
}) => {
const [filters, setFilters] = useState<IFilterObject[]>([]);
const [query, setQuery] = useState<string>("");
useEffect(() => {
Array.isArray(_filters) && setFilters(_filters);
}, [_filters]);
useEffect(() => {
setQuery(_query);
}, [_query]);
const updateQuery = useCallback(
(q: string) => {
setQuery(q);
onQueryChange && onQueryChange(q);
},
[onQueryChange]
);
const doSearch = () => {
onSearch &&
onSearch({
filters,
query
});
};
const addFilter = (filter: IFilterObject) => {
const newFilters = [...filters, filter];
setFilters([...filters, filter]);
onFilterAdded && onFilterAdded(filter);
onFilterChanged && onFilterChanged(newFilters);
};
const updateFilter = (index: number, filter: Partial<IFilterObject>) => {
const newFilters = [...filters];
const oldFilter = filters[index];
newFilters.splice(index, 1, {
...oldFilter,
...filter
} as AnyObject);
setFilters(newFilters);
onFilterUpdate &&
onFilterUpdate({
...oldFilter,
...filter
} as AnyObject);
onFilterChanged && onFilterChanged(newFilters);
};
const removeFilter = (index: number) => {
const newFilters = [...filters];
const [filter] = newFilters.splice(index, 1);
setFilters(newFilters);
onFilterRemoved && onFilterRemoved(filter);
onFilterChanged && onFilterChanged(newFilters);
};
const enableAll = (value: boolean) => {
const newFilters = filters.map((f) => (f.required ? f : { ...f, active: value }));
setFilters(newFilters);
onFilterChanged && onFilterChanged(newFilters);
};
const toggleExclude = () => {
const newFilters = filters.map((f) => (f.required ? f : { ...f, negative: !f.negative }));
setFilters(newFilters);
onFilterChanged && onFilterChanged(newFilters);
};
const removeAll = () => {
const newFilters = filters.filter((f) => f.required);
setFilters(newFilters);
onFilterChanged && onFilterChanged(newFilters);
};
return (
<I18nextProvider i18n={i18next}>
<Context.Provider
value={{
filters,
fields,
query,
updateQuery,
doSearch,
addFilter,
updateFilter,
removeFilter,
enableAll,
toggleExclude,
removeAll
}}
>
{children}
</Context.Provider>
</I18nextProvider>
);
}
Example #27
Source File: SendOnChain.test.tsx From raspiblitz-web with MIT License | 4 votes |
describe("SendOnChain", () => {
const setup = () => {
render(
<I18nextProvider i18n={i18n}>
<SendOnChain {...basicProps} />
</I18nextProvider>
);
};
test("render", async () => {
setup();
expect(screen.getByText("wallet.send_onchain")).toBeInTheDocument();
expect(screen.getByLabelText("wallet.address")).toBeInTheDocument();
expect(screen.getByLabelText("wallet.amount")).toBeInTheDocument();
expect(screen.getByLabelText("tx.fee")).toBeInTheDocument();
expect(screen.getByLabelText("tx.comment")).toBeInTheDocument();
expect(
screen.getByRole("button", { name: "wallet.confirm" })
).not.toBeDisabled();
});
// https://github.com/cstenglein/raspiblitz-web/issues/234
// skipped due to react v18 update
test.skip("validates the input for empty value", async () => {
setup();
expect(
screen.getByRole("button", { name: "wallet.confirm" })
).not.toBeDisabled();
userEvent.click(screen.getByRole("button", { name: "wallet.confirm" }));
await waitFor(() =>
expect(screen.getByLabelText("wallet.address")).toHaveClass("input-error")
);
expect(
screen.getByText("forms.validation.chainAddress.required")
).toBeInTheDocument();
await waitFor(() =>
expect(screen.getByLabelText("tx.fee")).toHaveClass("input-error")
);
expect(
screen.getByText("forms.validation.chainFee.required")
).toBeInTheDocument();
});
// https://github.com/cstenglein/raspiblitz-web/issues/234
// skipped due to react v18 update
test.skip("validates the address-input for BTC address format", async () => {
setup();
let addressInput = screen.getByLabelText("wallet.address");
userEvent.clear(addressInput);
userEvent.type(addressInput, "abc123456789");
addressInput = await screen.findByLabelText("wallet.address");
await waitFor(() => expect(addressInput).toHaveClass("input-error"));
expect(
screen.getByText("forms.validation.chainAddress.patternMismatch")
).toBeInTheDocument();
userEvent.clear(addressInput);
userEvent.type(addressInput, "bc1");
await waitFor(() => expect(addressInput).toHaveClass("input-error"));
expect(
screen.getByText("forms.validation.chainAddress.patternMismatch")
).toBeInTheDocument();
});
// https://github.com/cstenglein/raspiblitz-web/issues/234
// skipped due to react v18 update
test.skip("validates amount is lower than balance", async () => {
setup();
const amountInput = screen.getByLabelText(
"wallet.amount"
) as HTMLInputElement;
userEvent.clear(amountInput);
userEvent.type(amountInput, "999");
userEvent.click(await screen.findByText("wallet.confirm"));
await waitFor(() => expect(amountInput).toHaveClass("input-error"));
expect(
await screen.findByText("forms.validation.chainAmount.max")
).toBeInTheDocument();
});
// https://github.com/cstenglein/raspiblitz-web/issues/234
// skipped due to react v18 update
test.skip("validates amount is bigger than zero", async () => {
setup();
const amountInput = screen.getByLabelText(
"wallet.amount"
) as HTMLInputElement;
userEvent.clear(amountInput);
userEvent.type(amountInput, "0");
await waitFor(() => expect(amountInput).toHaveClass("input-error"));
expect(
screen.getByText("forms.validation.chainAmount.required")
).toBeInTheDocument();
});
// https://github.com/cstenglein/raspiblitz-web/issues/234
// skipped due to react v18 update
test.skip("valid form passes", async () => {
setup();
const addressInput = screen.getByLabelText(
"wallet.address"
) as HTMLInputElement;
const feeInput = screen.getByLabelText("tx.fee") as HTMLInputElement;
userEvent.type(addressInput, "bc1123456789");
await waitFor(() => expect(addressInput).not.toHaveClass("input-error"));
userEvent.type(feeInput, "1");
await waitFor(() => expect(feeInput).not.toHaveClass("input-error"));
expect(
screen.getByRole("button", { name: "wallet.confirm" })
).not.toBeDisabled();
});
});
Example #28
Source File: ConfirmSendModal.test.tsx From raspiblitz-web with MIT License | 4 votes |
describe("ConfirmSendModal", () => {
describe("ln-invoice with zero amount", () => {
const setup = () => {
render(
<I18nextProvider i18n={i18n}>
<ConfirmSendModal {...basicProps} />
</I18nextProvider>
);
};
test("validates amount is lower than balance", async () => {
setup();
let amountInput = screen.getByLabelText("wallet.amount");
userEvent.clear(amountInput);
userEvent.type(amountInput, "999");
amountInput = await screen.findByLabelText("wallet.amount");
await waitFor(() => expect(amountInput).toHaveClass("input-error"));
expect(
await screen.findByText("forms.validation.chainAmount.max")
).toBeInTheDocument();
});
test("validates amount is bigger than zero", async () => {
setup();
let amountInput = screen.getByLabelText("wallet.amount");
userEvent.clear(amountInput);
userEvent.type(amountInput, "0");
amountInput = await screen.findByLabelText("wallet.amount");
await waitFor(() => expect(amountInput).toHaveClass("input-error"));
expect(
screen.getByText("forms.validation.chainAmount.required")
).toBeInTheDocument();
});
test("valid form passes", async () => {
setup();
const amountInput = screen.getByLabelText(
"wallet.amount"
) as HTMLInputElement;
userEvent.type(amountInput, "100");
await waitFor(() => expect(amountInput).not.toHaveClass("input-error"));
expect(
screen.getByRole("button", { name: "check.svg settings.confirm" })
).not.toBeDisabled();
});
});
describe("ln-invoice with amount above zero", () => {
test("show error if invoice is expired", async () => {
render(
<I18nextProvider i18n={i18n}>
<ConfirmSendModal
{...basicProps}
timestamp={1640995200000} // "Sat Jan 01 2022 08:00:00
expiry={36000}
/>
</I18nextProvider>
);
expect(
screen.getByText(
"forms.validation.lnInvoice.expired",
{ exact: false } /* exclude displayed date */
)
).toBeInTheDocument();
expect(
screen.getByRole("button", { name: "check.svg settings.confirm" })
).toBeDisabled();
});
test("show error if amount is bigger than balance", async () => {
render(
<I18nextProvider i18n={i18n}>
<ConfirmSendModal {...basicProps} invoiceAmount={111} />
</I18nextProvider>
);
expect(
await screen.findByText("forms.validation.lnInvoice.max")
).toBeInTheDocument();
expect(
screen.getByRole("button", { name: "check.svg settings.confirm" })
).toBeDisabled();
});
test("valid form passes", async () => {
render(
<I18nextProvider i18n={i18n}>
<ConfirmSendModal {...basicProps} invoiceAmount={100} />
</I18nextProvider>
);
const submitButton = screen.queryByText("wallet.amount");
expect(submitButton).not.toBeInTheDocument();
expect(
await screen.findByRole("button", {
name: "check.svg settings.confirm",
})
).not.toBeDisabled();
});
});
});