Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | 1x 1x 1x 1x 12x 12x 12x 12x 4x 1x 1x 1x 1x 1x 1x 3x 3x 12x 1x 1x 1x 12x 1x 1x 1x 1x 1x 6x 4x 2x 2x 2x 2x 4x 6x 2x 2x 6x 1x 6x 6x 6x 1x 1x 1x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 1x 1x 1x 9x 9x 9x 9x 1x 9x 9x | import type { RouteOptions, RoutePath, Router, RouteRegistry, UnknownRoute } from '@anchorlib/router';
import type { FC, ReactNode } from 'react';
import { snippet } from '../hoc.js';
import { createEffect } from '../hooks.js';
import type { AnyRoute, RouteComponent } from './types.js';
export const RouteViewer = snippet<{ route: UnknownRoute; children?: ReactNode }>(
({ route, children }) => {
const Index = route.index?.renderer;
const Layout = route.renderer;
if (!route.active) return children;
if (Layout) {
if (Index && route.index?.active) {
return (
<Layout>
<Index />
{children}
</Layout>
);
}
return <Layout>{children}</Layout>;
}
if (Index) {
return <Index />;
}
return children;
},
'Route',
'Renderer',
false
);
const CRouteRenderer: FC<{ route: UnknownRoute; registry: RouteRegistry }> = ({ route, registry }) => {
if (route.renderer) {
if (route.index?.renderer) {
(route.renderer as FC).displayName = `Layout(${route.path || '/'})`;
} else {
(route.renderer as FC).displayName = `Index(${route.path || '/'})`;
}
}
if (route.index?.renderer) {
(route.index.renderer as FC).displayName = `Index(${route.path || '/'})`;
}
const children = Array.from(registry).map(([, child]) => {
return <RouteRenderer key={child.route.path} route={child.route} registry={child} />;
});
return <RouteViewer route={route}>{children}</RouteViewer>;
};
CRouteRenderer.displayName = 'Definition(Route)';
export const RouteRenderer = CRouteRenderer;
const CUIRouter: FC<{ router: Router<ReactNode>; root: RouteComponent<AnyRoute> }> = ({ router }) => {
const activate = async () => {
await router.activate(location.href);
window.scrollTo(0, 0);
};
activate();
createEffect(() => {
window.addEventListener('popstate', activate);
return () => {
window.removeEventListener('popstate', activate);
};
});
return <RouteRenderer key={'/'} route={router.rootRoute} registry={router.rootRegistry} />;
};
CUIRouter.displayName = 'UIRouter';
export const UIRouter = CUIRouter;
export function route<T extends AnyRoute>(route: T): RouteComponent<T> {
const UIRoute: FC<{ children?: ReactNode }> = ({ children }) => children;
UIRoute.displayName = `Route Factory(${route.path || '/'})`;
(UIRoute as RouteComponent<T>).index = route as T;
(UIRoute as RouteComponent<T>).route = (path: RoutePath, options?: RouteOptions) =>
route.route(path as never, options);
return UIRoute as RouteComponent<T>;
}
|