solid-navigator 0.2.4 → 0.3.1

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.
package/dist/dev.js CHANGED
@@ -96,15 +96,31 @@ var isValidPath = (routes, pathname) => {
96
96
  });
97
97
  };
98
98
  var getHashAndSearch = () => location.hash + location.search;
99
+ function expandOptionals(pattern) {
100
+ let match = /(\/?\:[^\/]+)\?/.exec(pattern);
101
+ if (!match)
102
+ return [pattern];
103
+ let prefix = pattern.slice(0, match.index);
104
+ let suffix = pattern.slice(match.index + match[0].length);
105
+ const prefixes = [prefix, prefix += match[1]];
106
+ while (match = /^(\/\:[^\/]+)\?/.exec(suffix)) {
107
+ prefixes.push(prefix += match[1]);
108
+ suffix = suffix.slice(match[0].length);
109
+ }
110
+ return expandOptionals(suffix).reduce(
111
+ (results, expansion) => [...results, ...prefixes.map((p) => p + expansion)],
112
+ []
113
+ );
114
+ }
99
115
 
100
116
  // src/Router.tsx
101
117
  var RouterContext = createContext();
102
118
  function Router(props) {
103
- const childRoutes = children(() => props.children).toArray;
104
- const routes = createMemo(() => flattenedRoutes(childRoutes()));
105
119
  if (!props.children) {
106
120
  throw new Error("Router: No children provided.");
107
121
  }
122
+ const childRoutes = children(() => props.children).toArray;
123
+ const routes = createMemo(() => expandOptionalRoutes(flattenedRoutes(childRoutes())));
108
124
  const [pathname, setPathname] = createSignal(location.pathname);
109
125
  const [hashAndSearch, setHashAndSearch] = createSignal(getHashAndSearch());
110
126
  const [params, setParams] = createStore({});
@@ -238,6 +254,18 @@ var flattenedRoute = (route) => {
238
254
  }
239
255
  return routes;
240
256
  };
257
+ var expandOptionalRoutes = (routes) => {
258
+ const newRoutes = [];
259
+ routes.forEach((route) => {
260
+ expandOptionals(route.path).forEach((path) => {
261
+ newRoutes.push({
262
+ ...route,
263
+ path
264
+ });
265
+ });
266
+ });
267
+ return newRoutes;
268
+ };
241
269
  var createNavigate = (routes, pathname, setPathname, setHashAndSearch) => {
242
270
  return (path, options) => {
243
271
  let newPath = path;
@@ -254,8 +282,7 @@ var createNavigate = (routes, pathname, setPathname, setHashAndSearch) => {
254
282
  history.pushState({}, "", newPath);
255
283
  }
256
284
  if (!isValidPath(routes, location.pathname)) {
257
- console.error("Invalid path: " + path);
258
- return;
285
+ console.warn("Invalid path: " + path);
259
286
  }
260
287
  setPathname(location.pathname);
261
288
  setHashAndSearch(getHashAndSearch());
@@ -305,10 +332,10 @@ var Outlet = (props) => {
305
332
  }
306
333
  return component2;
307
334
  });
308
- const MemodComponent = createMemo(() => {
335
+ const MemoComponent = createMemo(() => {
309
336
  return component()();
310
337
  });
311
- return MemodComponent;
338
+ return MemoComponent;
312
339
  };
313
340
  var Route = (props) => {
314
341
  const childRoutes = children(() => props.children).toArray;
@@ -318,6 +345,17 @@ var Route = (props) => {
318
345
  }
319
346
  });
320
347
  };
348
+ var matchComponent = (name) => {
349
+ const context = useRouterContext();
350
+ const matched = () => context.matched();
351
+ const component = createMemo(() => {
352
+ const components = matched()?.route.components || matched()?.route.mergedComponents || {};
353
+ return components[name()];
354
+ });
355
+ return createMemo(() => {
356
+ return component();
357
+ });
358
+ };
321
359
  var _tmpl$ = /* @__PURE__ */ template(`<a sn-link>`);
322
360
  var A = (props) => {
323
361
  return (() => {
@@ -327,9 +365,19 @@ var A = (props) => {
327
365
  })();
328
366
  };
329
367
  var useMatch = (path) => {
330
- const context = useRouterContext();
331
- const matcher = createMemo(() => createMatcher(path()));
332
- return createMemo(() => matcher()(context.location.pathname));
368
+ const location2 = useLocation();
369
+ const matchers = createMemo(() => {
370
+ return expandOptionals(path()).map((path2) => createMatcher(path2));
371
+ });
372
+ return createMemo(() => {
373
+ for (let i = 0; i < matchers().length; i++) {
374
+ const matcher = matchers()[i];
375
+ const match = matcher(location2.pathname);
376
+ if (match) {
377
+ return match;
378
+ }
379
+ }
380
+ });
333
381
  };
334
382
 
335
- export { A, Navigate, Outlet, Route, Router, useLocation, useMatch, useNavigate, useParams, useSearchParams };
383
+ export { A, Navigate, Outlet, Route, Router, matchComponent, useLocation, useMatch, useNavigate, useParams, useSearchParams };
package/dist/dev.jsx CHANGED
@@ -106,15 +106,31 @@ var isValidPath = (routes, pathname) => {
106
106
  });
107
107
  };
108
108
  var getHashAndSearch = () => location.hash + location.search;
109
+ function expandOptionals(pattern) {
110
+ let match = /(\/?\:[^\/]+)\?/.exec(pattern);
111
+ if (!match)
112
+ return [pattern];
113
+ let prefix = pattern.slice(0, match.index);
114
+ let suffix = pattern.slice(match.index + match[0].length);
115
+ const prefixes = [prefix, prefix += match[1]];
116
+ while (match = /^(\/\:[^\/]+)\?/.exec(suffix)) {
117
+ prefixes.push(prefix += match[1]);
118
+ suffix = suffix.slice(match[0].length);
119
+ }
120
+ return expandOptionals(suffix).reduce(
121
+ (results, expansion) => [...results, ...prefixes.map((p) => p + expansion)],
122
+ []
123
+ );
124
+ }
109
125
 
110
126
  // src/Router.tsx
111
127
  var RouterContext = createContext();
112
128
  function Router(props) {
113
- const childRoutes = children(() => props.children).toArray;
114
- const routes = createMemo2(() => flattenedRoutes(childRoutes()));
115
129
  if (!props.children) {
116
130
  throw new Error("Router: No children provided.");
117
131
  }
132
+ const childRoutes = children(() => props.children).toArray;
133
+ const routes = createMemo2(() => expandOptionalRoutes(flattenedRoutes(childRoutes())));
118
134
  const [pathname, setPathname] = createSignal(location.pathname);
119
135
  const [hashAndSearch, setHashAndSearch] = createSignal(getHashAndSearch());
120
136
  const [params, setParams] = createStore2({});
@@ -240,6 +256,15 @@ var flattenedRoute = (route) => {
240
256
  }
241
257
  return routes;
242
258
  };
259
+ var expandOptionalRoutes = (routes) => {
260
+ const newRoutes = [];
261
+ routes.forEach((route) => {
262
+ expandOptionals(route.path).forEach((path) => {
263
+ newRoutes.push({ ...route, path });
264
+ });
265
+ });
266
+ return newRoutes;
267
+ };
243
268
 
244
269
  // src/navigator.ts
245
270
  import { reconcile as reconcile3 } from "solid-js/store";
@@ -259,8 +284,7 @@ var createNavigate = (routes, pathname, setPathname, setHashAndSearch) => {
259
284
  history.pushState({}, "", newPath);
260
285
  }
261
286
  if (!isValidPath(routes, location.pathname)) {
262
- console.error("Invalid path: " + path);
263
- return;
287
+ console.warn("Invalid path: " + path);
264
288
  }
265
289
  setPathname(location.pathname);
266
290
  setHashAndSearch(getHashAndSearch());
@@ -313,14 +337,14 @@ var Outlet = (props) => {
313
337
  }
314
338
  return component2;
315
339
  });
316
- const MemodComponent = createMemo3(() => {
340
+ const MemoComponent = createMemo3(() => {
317
341
  return component()();
318
342
  });
319
- return <>{MemodComponent}</>;
343
+ return <>{MemoComponent}</>;
320
344
  };
321
345
 
322
346
  // src/Route.ts
323
- import { children as children2, mergeProps } from "solid-js";
347
+ import { children as children2, createMemo as createMemo4, mergeProps } from "solid-js";
324
348
  var Route = (props) => {
325
349
  const childRoutes = children2(() => props.children).toArray;
326
350
  return mergeProps(props, {
@@ -329,16 +353,37 @@ var Route = (props) => {
329
353
  }
330
354
  });
331
355
  };
356
+ var matchComponent = (name) => {
357
+ const context = useRouterContext();
358
+ const matched = () => context.matched();
359
+ const component = createMemo4(() => {
360
+ const components = matched()?.route.components || matched()?.route.mergedComponents || {};
361
+ return components[name()];
362
+ });
363
+ return createMemo4(() => {
364
+ return component();
365
+ });
366
+ };
332
367
 
333
368
  // src/Link.tsx
334
- import { createMemo as createMemo4 } from "solid-js";
369
+ import { createMemo as createMemo5 } from "solid-js";
335
370
  var A = (props) => {
336
371
  return <a sn-link {...props} />;
337
372
  };
338
373
  var useMatch = (path) => {
339
- const context = useRouterContext();
340
- const matcher = createMemo4(() => createMatcher(path()));
341
- return createMemo4(() => matcher()(context.location.pathname));
374
+ const location2 = useLocation();
375
+ const matchers = createMemo5(() => {
376
+ return expandOptionals(path()).map((path2) => createMatcher(path2));
377
+ });
378
+ return createMemo5(() => {
379
+ for (let i = 0; i < matchers().length; i++) {
380
+ const matcher = matchers()[i];
381
+ const match = matcher(location2.pathname);
382
+ if (match) {
383
+ return match;
384
+ }
385
+ }
386
+ });
342
387
  };
343
388
  export {
344
389
  A,
@@ -346,6 +391,7 @@ export {
346
391
  Outlet,
347
392
  Route,
348
393
  Router,
394
+ matchComponent,
349
395
  useLocation,
350
396
  useMatch,
351
397
  useNavigate,
package/dist/index.d.ts CHANGED
@@ -1,15 +1,16 @@
1
1
  import * as solid_js from 'solid-js';
2
- import { JSX } from 'solid-js';
2
+ import { JSX, Component } from 'solid-js';
3
3
 
4
4
  interface RouteObject {
5
5
  path: string;
6
6
  children?: RouteObject[];
7
7
  component?: () => JSX.Element;
8
- components?: Record<string, () => JSX.Element>;
8
+ components?: Record<string, () => JSX.Element | undefined>;
9
9
  }
10
10
  declare const Route: (props: Omit<RouteObject, 'children'> & {
11
11
  children?: JSX.Element;
12
12
  }) => JSX.Element;
13
+ declare const matchComponent: (name: () => string) => () => Component;
13
14
 
14
15
  interface NavigateOptions {
15
16
  replace?: boolean;
@@ -48,6 +49,6 @@ type LinkProps = {
48
49
  replace?: boolean;
49
50
  } & JSX.AnchorHTMLAttributes<HTMLAnchorElement>;
50
51
  declare const A: (props: LinkProps) => JSX.Element;
51
- declare const useMatch: (path: () => string) => solid_js.Accessor<PathMatch | null>;
52
+ declare const useMatch: (path: () => string) => solid_js.Accessor<PathMatch | undefined>;
52
53
 
53
- export { A, Navigate, type NavigateOptions, Outlet, Route, type RouteObject, Router, type RouterProps, useLocation, useMatch, useNavigate, useParams, useSearchParams };
54
+ export { A, Navigate, type NavigateOptions, Outlet, Route, type RouteObject, Router, type RouterProps, matchComponent, useLocation, useMatch, useNavigate, useParams, useSearchParams };
package/dist/index.js CHANGED
@@ -96,15 +96,31 @@ var isValidPath = (routes, pathname) => {
96
96
  });
97
97
  };
98
98
  var getHashAndSearch = () => location.hash + location.search;
99
+ function expandOptionals(pattern) {
100
+ let match = /(\/?\:[^\/]+)\?/.exec(pattern);
101
+ if (!match)
102
+ return [pattern];
103
+ let prefix = pattern.slice(0, match.index);
104
+ let suffix = pattern.slice(match.index + match[0].length);
105
+ const prefixes = [prefix, prefix += match[1]];
106
+ while (match = /^(\/\:[^\/]+)\?/.exec(suffix)) {
107
+ prefixes.push(prefix += match[1]);
108
+ suffix = suffix.slice(match[0].length);
109
+ }
110
+ return expandOptionals(suffix).reduce(
111
+ (results, expansion) => [...results, ...prefixes.map((p) => p + expansion)],
112
+ []
113
+ );
114
+ }
99
115
 
100
116
  // src/Router.tsx
101
117
  var RouterContext = createContext();
102
118
  function Router(props) {
103
- const childRoutes = children(() => props.children).toArray;
104
- const routes = createMemo(() => flattenedRoutes(childRoutes()));
105
119
  if (!props.children) {
106
120
  throw new Error("Router: No children provided.");
107
121
  }
122
+ const childRoutes = children(() => props.children).toArray;
123
+ const routes = createMemo(() => expandOptionalRoutes(flattenedRoutes(childRoutes())));
108
124
  const [pathname, setPathname] = createSignal(location.pathname);
109
125
  const [hashAndSearch, setHashAndSearch] = createSignal(getHashAndSearch());
110
126
  const [params, setParams] = createStore({});
@@ -238,6 +254,18 @@ var flattenedRoute = (route) => {
238
254
  }
239
255
  return routes;
240
256
  };
257
+ var expandOptionalRoutes = (routes) => {
258
+ const newRoutes = [];
259
+ routes.forEach((route) => {
260
+ expandOptionals(route.path).forEach((path) => {
261
+ newRoutes.push({
262
+ ...route,
263
+ path
264
+ });
265
+ });
266
+ });
267
+ return newRoutes;
268
+ };
241
269
  var createNavigate = (routes, pathname, setPathname, setHashAndSearch) => {
242
270
  return (path, options) => {
243
271
  let newPath = path;
@@ -253,9 +281,7 @@ var createNavigate = (routes, pathname, setPathname, setHashAndSearch) => {
253
281
  } else {
254
282
  history.pushState({}, "", newPath);
255
283
  }
256
- if (!isValidPath(routes, location.pathname)) {
257
- return;
258
- }
284
+ if (!isValidPath(routes, location.pathname)) ;
259
285
  setPathname(location.pathname);
260
286
  setHashAndSearch(getHashAndSearch());
261
287
  };
@@ -302,10 +328,10 @@ var Outlet = (props) => {
302
328
  }
303
329
  return component2;
304
330
  });
305
- const MemodComponent = createMemo(() => {
331
+ const MemoComponent = createMemo(() => {
306
332
  return component()();
307
333
  });
308
- return MemodComponent;
334
+ return MemoComponent;
309
335
  };
310
336
  var Route = (props) => {
311
337
  const childRoutes = children(() => props.children).toArray;
@@ -315,6 +341,17 @@ var Route = (props) => {
315
341
  }
316
342
  });
317
343
  };
344
+ var matchComponent = (name) => {
345
+ const context = useRouterContext();
346
+ const matched = () => context.matched();
347
+ const component = createMemo(() => {
348
+ const components = matched()?.route.components || matched()?.route.mergedComponents || {};
349
+ return components[name()];
350
+ });
351
+ return createMemo(() => {
352
+ return component();
353
+ });
354
+ };
318
355
  var _tmpl$ = /* @__PURE__ */ template(`<a sn-link>`);
319
356
  var A = (props) => {
320
357
  return (() => {
@@ -324,9 +361,19 @@ var A = (props) => {
324
361
  })();
325
362
  };
326
363
  var useMatch = (path) => {
327
- const context = useRouterContext();
328
- const matcher = createMemo(() => createMatcher(path()));
329
- return createMemo(() => matcher()(context.location.pathname));
364
+ const location2 = useLocation();
365
+ const matchers = createMemo(() => {
366
+ return expandOptionals(path()).map((path2) => createMatcher(path2));
367
+ });
368
+ return createMemo(() => {
369
+ for (let i = 0; i < matchers().length; i++) {
370
+ const matcher = matchers()[i];
371
+ const match = matcher(location2.pathname);
372
+ if (match) {
373
+ return match;
374
+ }
375
+ }
376
+ });
330
377
  };
331
378
 
332
- export { A, Navigate, Outlet, Route, Router, useLocation, useMatch, useNavigate, useParams, useSearchParams };
379
+ export { A, Navigate, Outlet, Route, Router, matchComponent, useLocation, useMatch, useNavigate, useParams, useSearchParams };
package/dist/index.jsx CHANGED
@@ -106,15 +106,31 @@ var isValidPath = (routes, pathname) => {
106
106
  });
107
107
  };
108
108
  var getHashAndSearch = () => location.hash + location.search;
109
+ function expandOptionals(pattern) {
110
+ let match = /(\/?\:[^\/]+)\?/.exec(pattern);
111
+ if (!match)
112
+ return [pattern];
113
+ let prefix = pattern.slice(0, match.index);
114
+ let suffix = pattern.slice(match.index + match[0].length);
115
+ const prefixes = [prefix, prefix += match[1]];
116
+ while (match = /^(\/\:[^\/]+)\?/.exec(suffix)) {
117
+ prefixes.push(prefix += match[1]);
118
+ suffix = suffix.slice(match[0].length);
119
+ }
120
+ return expandOptionals(suffix).reduce(
121
+ (results, expansion) => [...results, ...prefixes.map((p) => p + expansion)],
122
+ []
123
+ );
124
+ }
109
125
 
110
126
  // src/Router.tsx
111
127
  var RouterContext = createContext();
112
128
  function Router(props) {
113
- const childRoutes = children(() => props.children).toArray;
114
- const routes = createMemo2(() => flattenedRoutes(childRoutes()));
115
129
  if (!props.children) {
116
130
  throw new Error("Router: No children provided.");
117
131
  }
132
+ const childRoutes = children(() => props.children).toArray;
133
+ const routes = createMemo2(() => expandOptionalRoutes(flattenedRoutes(childRoutes())));
118
134
  const [pathname, setPathname] = createSignal(location.pathname);
119
135
  const [hashAndSearch, setHashAndSearch] = createSignal(getHashAndSearch());
120
136
  const [params, setParams] = createStore2({});
@@ -240,6 +256,15 @@ var flattenedRoute = (route) => {
240
256
  }
241
257
  return routes;
242
258
  };
259
+ var expandOptionalRoutes = (routes) => {
260
+ const newRoutes = [];
261
+ routes.forEach((route) => {
262
+ expandOptionals(route.path).forEach((path) => {
263
+ newRoutes.push({ ...route, path });
264
+ });
265
+ });
266
+ return newRoutes;
267
+ };
243
268
 
244
269
  // src/navigator.ts
245
270
  import { reconcile as reconcile3 } from "solid-js/store";
@@ -259,7 +284,6 @@ var createNavigate = (routes, pathname, setPathname, setHashAndSearch) => {
259
284
  history.pushState({}, "", newPath);
260
285
  }
261
286
  if (!isValidPath(routes, location.pathname)) {
262
- return;
263
287
  }
264
288
  setPathname(location.pathname);
265
289
  setHashAndSearch(getHashAndSearch());
@@ -310,14 +334,14 @@ var Outlet = (props) => {
310
334
  }
311
335
  return component2;
312
336
  });
313
- const MemodComponent = createMemo3(() => {
337
+ const MemoComponent = createMemo3(() => {
314
338
  return component()();
315
339
  });
316
- return <>{MemodComponent}</>;
340
+ return <>{MemoComponent}</>;
317
341
  };
318
342
 
319
343
  // src/Route.ts
320
- import { children as children2, mergeProps } from "solid-js";
344
+ import { children as children2, createMemo as createMemo4, mergeProps } from "solid-js";
321
345
  var Route = (props) => {
322
346
  const childRoutes = children2(() => props.children).toArray;
323
347
  return mergeProps(props, {
@@ -326,16 +350,37 @@ var Route = (props) => {
326
350
  }
327
351
  });
328
352
  };
353
+ var matchComponent = (name) => {
354
+ const context = useRouterContext();
355
+ const matched = () => context.matched();
356
+ const component = createMemo4(() => {
357
+ const components = matched()?.route.components || matched()?.route.mergedComponents || {};
358
+ return components[name()];
359
+ });
360
+ return createMemo4(() => {
361
+ return component();
362
+ });
363
+ };
329
364
 
330
365
  // src/Link.tsx
331
- import { createMemo as createMemo4 } from "solid-js";
366
+ import { createMemo as createMemo5 } from "solid-js";
332
367
  var A = (props) => {
333
368
  return <a sn-link {...props} />;
334
369
  };
335
370
  var useMatch = (path) => {
336
- const context = useRouterContext();
337
- const matcher = createMemo4(() => createMatcher(path()));
338
- return createMemo4(() => matcher()(context.location.pathname));
371
+ const location2 = useLocation();
372
+ const matchers = createMemo5(() => {
373
+ return expandOptionals(path()).map((path2) => createMatcher(path2));
374
+ });
375
+ return createMemo5(() => {
376
+ for (let i = 0; i < matchers().length; i++) {
377
+ const matcher = matchers()[i];
378
+ const match = matcher(location2.pathname);
379
+ if (match) {
380
+ return match;
381
+ }
382
+ }
383
+ });
339
384
  };
340
385
  export {
341
386
  A,
@@ -343,6 +388,7 @@ export {
343
388
  Outlet,
344
389
  Route,
345
390
  Router,
391
+ matchComponent,
346
392
  useLocation,
347
393
  useMatch,
348
394
  useNavigate,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "solid-navigator",
3
- "version": "0.2.4",
3
+ "version": "0.3.1",
4
4
  "description": "Solid Navigator is a library that is inspired by vue router and solid router.",
5
5
  "license": "MIT",
6
6
  "author": "SupertigerDev",