import { memo, PropsWithChildren } from 'react'; import { Route as AppRoute, RouteProps as ReactRouterProps, Routes } from 'react-router-dom'; /** * Generic type for a parameter in a route * @example * ```ts * interface RouteParams { * userId: RouteParamId * } * ``` */ export type RouteParamId = string | number; /** * Type wrapper that combines component props and route params to create an object of * both the component props and all Router props with params set internally. * @example * ```jsx * interface RouteParams { * userId: string; * } * * interface RoutedComponentProps { * name: string; * } * * export const RoutedComponent = (props: PropsWithChildren>) => ( *
* The UserID is: {props.match.params.userId} * The name is: {props.name} *
* ) * ``` */ export type ComponentOwnProps< CP extends Record, Params extends { [K in keyof Params]?: string } = Record > = CP; export interface Route { path: ReactRouterProps['path']; component: ReactRouterProps['element']; reactRouterProps?: Omit; /** Data-qa tag to apply to the route */ 'data-qa'?: string; } export interface RouterProps extends ReactRouterProps { /** The component and route that should be rendered by default (root path and fallback) */ defaultComponent: Route; /** Additional routes to render other than the default component */ otherComponents?: Route[]; /** Data-qa tag to apply to the default component route */ 'data-qa'?: string; } /** * Constructs a Router with provided routes and components * @param params Includes list of paths and components as well as the option to pass data-qa and additional props * @example * ```jsx *
*
TEST
}} * data-qa='TestRouter' * otherComponents={[ * { path: '/app', component: () =>
APP
, 'data-qa': 'AppRoute' }, * { path: '/contact', component: () => , 'data-qa': 'ContactRoute' } * ]} * /> *
* ``` */ export const Router = memo(({ defaultComponent, otherComponents, ...props }: PropsWithChildren) => { return ( {otherComponents?.map((child, index) => ( ))} ); });