@solidjs/router 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,111 @@
1
+ /*@refresh skip*/
2
+ import { children, createMemo, createRoot, mergeProps, on, Show, splitProps } from "solid-js";
3
+ import { isServer } from "solid-js/web";
4
+ import { pathIntegration, staticIntegration } from "./integration";
5
+ import { createBranches, createRouteContext, createRouterContext, getRouteMatches, RouteContextObj, RouterContextObj, useHref, useLocation, useNavigate, useResolvedPath, useRoute, useRouter } from "./routing";
6
+ import { joinPaths } from "./utils";
7
+ export const Router = (props) => {
8
+ const { source, url, base, data, out } = props;
9
+ const integration = source || (isServer ? staticIntegration({ value: url || "" }) : pathIntegration());
10
+ const routerState = createRouterContext(integration, base, data, out);
11
+ return (<RouterContextObj.Provider value={routerState}>{props.children}</RouterContextObj.Provider>);
12
+ };
13
+ export const Routes = (props) => {
14
+ const router = useRouter();
15
+ const parentRoute = useRoute();
16
+ const routeDefs = children(() => props.children);
17
+ const branches = createMemo(() => createBranches(routeDefs(), joinPaths(parentRoute.pattern, props.base || ""), Outlet));
18
+ const matches = createMemo(() => getRouteMatches(branches(), router.location.pathname));
19
+ if (router.out) {
20
+ router.out.matches.push(matches().map(({ route, path, params }) => ({
21
+ originalPath: route.originalPath,
22
+ pattern: route.pattern,
23
+ path,
24
+ params
25
+ })));
26
+ }
27
+ const disposers = [];
28
+ let root;
29
+ const routeStates = createMemo(on(matches, (nextMatches, prevMatches, prev) => {
30
+ let equal = prevMatches && nextMatches.length === prevMatches.length;
31
+ const next = [];
32
+ for (let i = 0, len = nextMatches.length; i < len; i++) {
33
+ const prevMatch = prevMatches && prevMatches[i];
34
+ const nextMatch = nextMatches[i];
35
+ if (prev && prevMatch && nextMatch.route.key === prevMatch.route.key) {
36
+ next[i] = prev[i];
37
+ }
38
+ else {
39
+ equal = false;
40
+ if (disposers[i]) {
41
+ disposers[i]();
42
+ }
43
+ createRoot(dispose => {
44
+ disposers[i] = dispose;
45
+ next[i] = createRouteContext(router, next[i - 1] || parentRoute, () => routeStates()[i + 1], () => matches()[i]);
46
+ });
47
+ }
48
+ }
49
+ disposers.splice(nextMatches.length).forEach(dispose => dispose());
50
+ if (prev && equal) {
51
+ return prev;
52
+ }
53
+ root = next[0];
54
+ return next;
55
+ }));
56
+ return (<Show when={routeStates() && root}>
57
+ {route => <RouteContextObj.Provider value={route}>{route.outlet()}</RouteContextObj.Provider>}
58
+ </Show>);
59
+ };
60
+ export const useRoutes = (routes, base) => {
61
+ return () => <Routes base={base}>{routes}</Routes>;
62
+ };
63
+ export const Route = (props) => {
64
+ const childRoutes = children(() => props.children);
65
+ return mergeProps(props, {
66
+ get children() {
67
+ return childRoutes();
68
+ }
69
+ });
70
+ };
71
+ export const Outlet = () => {
72
+ const route = useRoute();
73
+ return (<Show when={route.child}>
74
+ {child => <RouteContextObj.Provider value={child}>{child.outlet()}</RouteContextObj.Provider>}
75
+ </Show>);
76
+ };
77
+ function LinkBase(props) {
78
+ const [, rest] = splitProps(props, ["children", "to", "href", "state"]);
79
+ const href = useHref(() => props.to);
80
+ return (<a {...rest} href={href() || props.href} state={JSON.stringify(props.state)}>
81
+ {props.children}
82
+ </a>);
83
+ }
84
+ export function Link(props) {
85
+ const to = useResolvedPath(() => props.href);
86
+ return <LinkBase {...props} to={to()}/>;
87
+ }
88
+ export function NavLink(props) {
89
+ props = mergeProps({ inactiveClass: "inactive", activeClass: "active" }, props);
90
+ const [, rest] = splitProps(props, ["activeClass", "inactiveClass", "end"]);
91
+ const location = useLocation();
92
+ const to = useResolvedPath(() => props.href);
93
+ const isActive = createMemo(() => {
94
+ const to_ = to();
95
+ if (to_ === undefined) {
96
+ return false;
97
+ }
98
+ const path = to_.split(/[?#]/, 1)[0].toLowerCase();
99
+ const loc = location.pathname.toLowerCase();
100
+ return props.end ? path === loc : loc.startsWith(path);
101
+ });
102
+ return (<LinkBase {...rest} to={to()} classList={{ [props.inactiveClass]: !isActive(), [props.activeClass]: isActive(), ...rest.classList }} aria-current={isActive() ? "page" : undefined}/>);
103
+ }
104
+ export function Navigate(props) {
105
+ const navigate = useNavigate();
106
+ const location = useLocation();
107
+ const { href, state } = props;
108
+ const path = typeof href === "function" ? href({ navigate, location }) : href;
109
+ navigate(path, { replace: true, state });
110
+ return null;
111
+ }
@@ -0,0 +1,5 @@
1
+ export * from "./components";
2
+ export * from "./integration";
3
+ export { useRouteData, useHref, useIsRouting, useLocation, useMatch, useNavigate, useParams, useResolvedPath, useSearchParams } from "./routing";
4
+ export { mergeSearchString as _mergeSearchString } from "./utils";
5
+ export type { Location, LocationChange, LocationChangeSignal, NavigateOptions, Navigator, OutputMatch, Params, RouteDataFunc, RouteDataFuncArgs, RouteDefinition, RouterIntegration, RouterOutput, RouterUtils, SetParams } from "./types";