path-router-red 0.4.0
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/README.md +427 -0
- package/dist/PathRouter/Container/ModalsContainer.d.ts +17 -0
- package/dist/PathRouter/Container/ModalsContainer.d.ts.map +1 -0
- package/dist/PathRouter/Container/ModalsContainer.js +39 -0
- package/dist/PathRouter/Container/ModalsContainer.js.map +1 -0
- package/dist/PathRouter/Container/RouterContainer.d.ts +16 -0
- package/dist/PathRouter/Container/RouterContainer.d.ts.map +1 -0
- package/dist/PathRouter/Container/RouterContainer.js +20 -0
- package/dist/PathRouter/Container/RouterContainer.js.map +1 -0
- package/dist/PathRouter/Container/index.d.ts +2 -0
- package/dist/PathRouter/Container/index.d.ts.map +1 -0
- package/dist/PathRouter/Container/index.js +18 -0
- package/dist/PathRouter/Container/index.js.map +1 -0
- package/dist/PathRouter/NavLink/NavLink.d.ts +40 -0
- package/dist/PathRouter/NavLink/NavLink.d.ts.map +1 -0
- package/dist/PathRouter/NavLink/NavLink.js +67 -0
- package/dist/PathRouter/NavLink/NavLink.js.map +1 -0
- package/dist/PathRouter/NavLink/index.d.ts +3 -0
- package/dist/PathRouter/NavLink/index.d.ts.map +1 -0
- package/dist/PathRouter/NavLink/index.js +6 -0
- package/dist/PathRouter/NavLink/index.js.map +1 -0
- package/dist/PathRouter/Provider/PathProvider.d.ts +10 -0
- package/dist/PathRouter/Provider/PathProvider.d.ts.map +1 -0
- package/dist/PathRouter/Provider/PathProvider.js +158 -0
- package/dist/PathRouter/Provider/PathProvider.js.map +1 -0
- package/dist/PathRouter/Provider/context.d.ts +3 -0
- package/dist/PathRouter/Provider/context.d.ts.map +1 -0
- package/dist/PathRouter/Provider/context.js +34 -0
- package/dist/PathRouter/Provider/context.js.map +1 -0
- package/dist/PathRouter/Provider/index.d.ts +3 -0
- package/dist/PathRouter/Provider/index.d.ts.map +1 -0
- package/dist/PathRouter/Provider/index.js +19 -0
- package/dist/PathRouter/Provider/index.js.map +1 -0
- package/dist/PathRouter/Provider/usePath.d.ts +15 -0
- package/dist/PathRouter/Provider/usePath.d.ts.map +1 -0
- package/dist/PathRouter/Provider/usePath.js +22 -0
- package/dist/PathRouter/Provider/usePath.js.map +1 -0
- package/dist/PathRouter/createPathRouter.d.ts +52 -0
- package/dist/PathRouter/createPathRouter.d.ts.map +1 -0
- package/dist/PathRouter/createPathRouter.js +72 -0
- package/dist/PathRouter/createPathRouter.js.map +1 -0
- package/dist/PathRouter/index.d.ts +41 -0
- package/dist/PathRouter/index.d.ts.map +1 -0
- package/dist/PathRouter/index.js +49 -0
- package/dist/PathRouter/index.js.map +1 -0
- package/dist/PathRouter/types.d.ts +91 -0
- package/dist/PathRouter/types.d.ts.map +1 -0
- package/dist/PathRouter/types.js +3 -0
- package/dist/PathRouter/types.js.map +1 -0
- package/dist/PathRouter/utils/clearSlash.d.ts +8 -0
- package/dist/PathRouter/utils/clearSlash.d.ts.map +1 -0
- package/dist/PathRouter/utils/clearSlash.js +21 -0
- package/dist/PathRouter/utils/clearSlash.js.map +1 -0
- package/dist/PathRouter/utils/createRoute.d.ts +16 -0
- package/dist/PathRouter/utils/createRoute.d.ts.map +1 -0
- package/dist/PathRouter/utils/createRoute.js +36 -0
- package/dist/PathRouter/utils/createRoute.js.map +1 -0
- package/dist/PathRouter/utils/index.d.ts +5 -0
- package/dist/PathRouter/utils/index.d.ts.map +1 -0
- package/dist/PathRouter/utils/index.js +21 -0
- package/dist/PathRouter/utils/index.js.map +1 -0
- package/dist/PathRouter/utils/parseSearch.d.ts +4 -0
- package/dist/PathRouter/utils/parseSearch.d.ts.map +1 -0
- package/dist/PathRouter/utils/parseSearch.js +15 -0
- package/dist/PathRouter/utils/parseSearch.js.map +1 -0
- package/dist/PathRouter/utils/setters.d.ts +9 -0
- package/dist/PathRouter/utils/setters.d.ts.map +1 -0
- package/dist/PathRouter/utils/setters.js +25 -0
- package/dist/PathRouter/utils/setters.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/package.json +32 -0
- package/src/PathRouter/Container/ModalsContainer.tsx +92 -0
- package/src/PathRouter/Container/RouterContainer.tsx +66 -0
- package/src/PathRouter/Container/index.ts +1 -0
- package/src/PathRouter/NavLink/NavLink.tsx +146 -0
- package/src/PathRouter/NavLink/index.ts +2 -0
- package/src/PathRouter/Provider/PathProvider.tsx +220 -0
- package/src/PathRouter/Provider/context.ts +33 -0
- package/src/PathRouter/Provider/index.ts +2 -0
- package/src/PathRouter/Provider/usePath.ts +21 -0
- package/src/PathRouter/createPathRouter.tsx +104 -0
- package/src/PathRouter/index.ts +79 -0
- package/src/PathRouter/readme.md +427 -0
- package/src/PathRouter/types.ts +139 -0
- package/src/PathRouter/utils/clearSlash.ts +16 -0
- package/src/PathRouter/utils/createRoute.ts +53 -0
- package/src/PathRouter/utils/index.ts +4 -0
- package/src/PathRouter/utils/parseSearch.ts +15 -0
- package/src/PathRouter/utils/setters.ts +8 -0
- package/src/index.ts +1 -0
- package/tsconfig.json +19 -0
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import type { ComponentType, LazyExoticComponent, ReactNode, RefAttributes } from "react";
|
|
2
|
+
import type { Location, NavigateOptions } from "react-router-dom";
|
|
3
|
+
export type NestedKeyOf<ObjectType extends object, StopKey extends string> = {
|
|
4
|
+
[Key in keyof ObjectType & (string | number)]: ObjectType[Key] extends object ? Key extends StopKey ? never : `${Key}` | `${Key}/${NestedKeyOf<ObjectType[Key], StopKey>}` : `${Key}`;
|
|
5
|
+
}[keyof ObjectType & (string | number)];
|
|
6
|
+
export type PageData = {
|
|
7
|
+
component?: ComponentType<any> | LazyExoticComponent<ComponentType<any>>;
|
|
8
|
+
redirect?: string;
|
|
9
|
+
} & Record<string, any>;
|
|
10
|
+
export interface ModalProps {
|
|
11
|
+
onClose: () => void;
|
|
12
|
+
}
|
|
13
|
+
export interface ModalData {
|
|
14
|
+
component?: ComponentType<ModalProps> | LazyExoticComponent<ComponentType<ModalProps>>;
|
|
15
|
+
}
|
|
16
|
+
export interface PageContent {
|
|
17
|
+
data?: PageData;
|
|
18
|
+
}
|
|
19
|
+
export interface BreadCrumbsPage {
|
|
20
|
+
[path: string]: ExtendedPage;
|
|
21
|
+
}
|
|
22
|
+
export type ExtendedPage = BreadCrumbsPage | PageContent;
|
|
23
|
+
export interface PagesRoute {
|
|
24
|
+
[path: string]: ExtendedPage;
|
|
25
|
+
}
|
|
26
|
+
export type ModalRoutes = Record<string, ModalData>;
|
|
27
|
+
export interface RouterConfig<P extends PagesRoute = PagesRoute, M extends ModalRoutes = ModalRoutes> {
|
|
28
|
+
pages: P;
|
|
29
|
+
modals?: M;
|
|
30
|
+
}
|
|
31
|
+
/** Extract typed page paths from a user config. */
|
|
32
|
+
export type PathNamesOf<C extends RouterConfig<any, any>> = C extends RouterConfig<infer P, any> ? NestedKeyOf<P, "data"> : string;
|
|
33
|
+
/** Extract typed modal names from a user config. */
|
|
34
|
+
export type ModalNamesOf<C extends RouterConfig<any, any>> = C extends RouterConfig<any, infer M> ? Extract<keyof M, string> : string;
|
|
35
|
+
export type SearchParams = Record<string, string[]>;
|
|
36
|
+
export interface SearchParamsState {
|
|
37
|
+
[key: string]: string | string[];
|
|
38
|
+
}
|
|
39
|
+
export interface ModalState {
|
|
40
|
+
path: string;
|
|
41
|
+
name?: string;
|
|
42
|
+
breadCrumbs: string[];
|
|
43
|
+
isOpen: boolean;
|
|
44
|
+
}
|
|
45
|
+
export interface PathContextType<C extends RouterConfig<any, any> = RouterConfig<any, any>> {
|
|
46
|
+
page: {
|
|
47
|
+
path: string;
|
|
48
|
+
navigate: (path: PathNamesOf<C>, options?: NavigateOptions) => void;
|
|
49
|
+
isHavePrevHistory: boolean;
|
|
50
|
+
};
|
|
51
|
+
modal: {
|
|
52
|
+
open: (name: ModalNamesOf<C>, breadCrumbs?: string[]) => void;
|
|
53
|
+
close: () => void;
|
|
54
|
+
/** Full modal path including modal name, e.g. "test/sub" */
|
|
55
|
+
path: string;
|
|
56
|
+
name?: string;
|
|
57
|
+
/** Sub-crumbs without modal name */
|
|
58
|
+
breadCrumbs: string[];
|
|
59
|
+
isOpen: boolean;
|
|
60
|
+
};
|
|
61
|
+
searchParams: {
|
|
62
|
+
params: SearchParams;
|
|
63
|
+
/** Merge: string -> set; array -> append */
|
|
64
|
+
change: (searchParams: SearchParamsState) => void;
|
|
65
|
+
/** Replace fully: each key is set to provided value(s) */
|
|
66
|
+
set: (searchParams: SearchParamsState) => void;
|
|
67
|
+
delete: (key: string) => void;
|
|
68
|
+
clear: () => void;
|
|
69
|
+
};
|
|
70
|
+
defaultLocation: Location;
|
|
71
|
+
}
|
|
72
|
+
export interface ModalWrapperRef {
|
|
73
|
+
handleCloseWithAnimation: () => void;
|
|
74
|
+
}
|
|
75
|
+
export interface ModalWrapperProps {
|
|
76
|
+
modalName?: string;
|
|
77
|
+
isOpen: boolean;
|
|
78
|
+
onClose: () => void;
|
|
79
|
+
children?: ReactNode;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Wrapper plugin component.
|
|
83
|
+
*
|
|
84
|
+
* Accepts both a `forwardRef`-wrapped component (the container will call
|
|
85
|
+
* `ref.current.handleCloseWithAnimation()` when available) and a plain
|
|
86
|
+
* function component that simply ignores the ref. `RefAttributes` keeps
|
|
87
|
+
* `ref` as an optional prop, so any `ComponentType<ModalWrapperProps>`
|
|
88
|
+
* structurally satisfies this signature in React 19.
|
|
89
|
+
*/
|
|
90
|
+
export type ModalWrapperComponent = ComponentType<ModalWrapperProps & RefAttributes<ModalWrapperRef>>;
|
|
91
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/PathRouter/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/PathRouter/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Normalize path:
|
|
3
|
+
* - collapse internal "//" sequences to a single "/"
|
|
4
|
+
* - guarantee a single leading "/"
|
|
5
|
+
* - strip trailing "/" (root "/" stays as "/")
|
|
6
|
+
*/
|
|
7
|
+
export declare const clearSlash: (path: string) => string;
|
|
8
|
+
//# sourceMappingURL=clearSlash.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clearSlash.d.ts","sourceRoot":"","sources":["../../../src/PathRouter/utils/clearSlash.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,eAAO,MAAM,UAAU,GAAI,MAAM,MAAM,KAAG,MASzC,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.clearSlash = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Normalize path:
|
|
6
|
+
* - collapse internal "//" sequences to a single "/"
|
|
7
|
+
* - guarantee a single leading "/"
|
|
8
|
+
* - strip trailing "/" (root "/" stays as "/")
|
|
9
|
+
*/
|
|
10
|
+
const clearSlash = (path) => {
|
|
11
|
+
if (!path)
|
|
12
|
+
return "/";
|
|
13
|
+
let p = path.replace(/\/{2,}/g, "/");
|
|
14
|
+
if (!p.startsWith("/"))
|
|
15
|
+
p = "/" + p;
|
|
16
|
+
if (p.length > 1 && p.endsWith("/"))
|
|
17
|
+
p = p.replace(/\/+$/, "");
|
|
18
|
+
return p;
|
|
19
|
+
};
|
|
20
|
+
exports.clearSlash = clearSlash;
|
|
21
|
+
//# sourceMappingURL=clearSlash.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clearSlash.js","sourceRoot":"","sources":["../../../src/PathRouter/utils/clearSlash.ts"],"names":[],"mappings":";;;AAAA;;;;;GAKG;AACI,MAAM,UAAU,GAAG,CAAC,IAAY,EAAU,EAAE;IACjD,IAAI,CAAC,IAAI;QAAE,OAAO,GAAG,CAAC;IAEtB,IAAI,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;IAErC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC;IACpC,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAE/D,OAAO,CAAC,CAAC;AACX,CAAC,CAAC;AATW,QAAA,UAAU,cASrB"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type PageData, type RouterConfig } from "../types";
|
|
2
|
+
/**
|
|
3
|
+
* Flatten a nested page config into a list of `{ pathName, data }`,
|
|
4
|
+
* and produce a flat list for modals as well.
|
|
5
|
+
*/
|
|
6
|
+
export declare const createRoute: (config: RouterConfig<any, any>) => {
|
|
7
|
+
pages: {
|
|
8
|
+
pathName: string;
|
|
9
|
+
data: PageData;
|
|
10
|
+
}[];
|
|
11
|
+
modals: {
|
|
12
|
+
pathName: string;
|
|
13
|
+
data: import("../types").ModalData;
|
|
14
|
+
}[];
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=createRoute.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createRoute.d.ts","sourceRoot":"","sources":["../../../src/PathRouter/utils/createRoute.ts"],"names":[],"mappings":"AAAA,OAAO,EAGN,KAAK,QAAQ,EAEb,KAAK,YAAY,EACjB,MAAM,UAAU,CAAC;AAKlB;;;GAGG;AACH,eAAO,MAAM,WAAW,GAAI,QAAQ,YAAY,CAAC,GAAG,EAAE,GAAG,CAAC;;kBACzB,MAAM;cAAQ,QAAQ;;;;;;CAoCtD,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createRoute = void 0;
|
|
4
|
+
const objectIsEmpty = (obj) => Object.keys(obj).length === 0;
|
|
5
|
+
/**
|
|
6
|
+
* Flatten a nested page config into a list of `{ pathName, data }`,
|
|
7
|
+
* and produce a flat list for modals as well.
|
|
8
|
+
*/
|
|
9
|
+
const createRoute = (config) => {
|
|
10
|
+
const pagesRoutes = [];
|
|
11
|
+
const walk = (route, currentPath) => {
|
|
12
|
+
Object.entries(route).forEach(([pathName, content]) => {
|
|
13
|
+
if (content?.data) {
|
|
14
|
+
pagesRoutes.push({
|
|
15
|
+
pathName: currentPath + pathName,
|
|
16
|
+
data: { ...content.data },
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
if (content &&
|
|
20
|
+
!objectIsEmpty(content) &&
|
|
21
|
+
!content.component &&
|
|
22
|
+
!content.redirect) {
|
|
23
|
+
const newPath = currentPath + pathName;
|
|
24
|
+
walk(content, newPath + (newPath[newPath.length - 1] !== "/" ? "/" : ""));
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
};
|
|
28
|
+
walk(config.pages, "");
|
|
29
|
+
const modalsList = Object.entries((config.modals || {})).map(([pathName, data]) => ({ pathName, data }));
|
|
30
|
+
return {
|
|
31
|
+
pages: pagesRoutes,
|
|
32
|
+
modals: modalsList,
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
exports.createRoute = createRoute;
|
|
36
|
+
//# sourceMappingURL=createRoute.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createRoute.js","sourceRoot":"","sources":["../../../src/PathRouter/utils/createRoute.ts"],"names":[],"mappings":";;;AAQA,MAAM,aAAa,GAAG,CAAC,GAAwB,EAAE,EAAE,CACjD,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC;AAEhC;;;GAGG;AACI,MAAM,WAAW,GAAG,CAAC,MAA8B,EAAE,EAAE;IAC5D,MAAM,WAAW,GAA2C,EAAE,CAAC;IAE/D,MAAM,IAAI,GAAG,CAAC,KAAgC,EAAE,WAAmB,EAAE,EAAE;QACrE,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE,OAAO,CAAgB,EAAE,EAAE;YACnE,IAAI,OAAO,EAAE,IAAI,EAAE,CAAC;gBAClB,WAAW,CAAC,IAAI,CAAC;oBACf,QAAQ,EAAE,WAAW,GAAG,QAAQ;oBAChC,IAAI,EAAE,EAAE,GAAG,OAAO,CAAC,IAAI,EAAc;iBACtC,CAAC,CAAC;YACL,CAAC;YAED,IACE,OAAO;gBACP,CAAC,aAAa,CAAC,OAAO,CAAC;gBACvB,CAAC,OAAO,CAAC,SAAS;gBAClB,CAAC,OAAO,CAAC,QAAQ,EACjB,CAAC;gBACD,MAAM,OAAO,GAAG,WAAW,GAAG,QAAQ,CAAC;gBACvC,IAAI,CACF,OAAO,EACP,OAAO,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAC3D,CAAC;YACJ,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;IAEF,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAEvB,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,CAC/B,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAAgB,CACrC,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAElD,OAAO;QACL,KAAK,EAAE,WAAW;QAClB,MAAM,EAAE,UAAU;KACnB,CAAC;AACJ,CAAC,CAAC;AArCW,QAAA,WAAW,eAqCtB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/PathRouter/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./clearSlash"), exports);
|
|
18
|
+
__exportStar(require("./parseSearch"), exports);
|
|
19
|
+
__exportStar(require("./setters"), exports);
|
|
20
|
+
__exportStar(require("./createRoute"), exports);
|
|
21
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/PathRouter/utils/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,+CAA6B;AAC7B,gDAA8B;AAC9B,4CAA0B;AAC1B,gDAA8B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parseSearch.d.ts","sourceRoot":"","sources":["../../../src/PathRouter/utils/parseSearch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAElD,eAAO,MAAM,iBAAiB,GAC5B,cAAc,iBAAiB,EAC/B,UAAU,QAAQ,oBASnB,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseSearchParams = void 0;
|
|
4
|
+
const parseSearchParams = (searchParams, location) => {
|
|
5
|
+
const params = new URLSearchParams(location.search);
|
|
6
|
+
Object.entries(searchParams).forEach(([key, values]) => {
|
|
7
|
+
if (typeof values === "string")
|
|
8
|
+
params.set(key, values);
|
|
9
|
+
else
|
|
10
|
+
values.forEach((value) => params.append(key, value));
|
|
11
|
+
});
|
|
12
|
+
return params;
|
|
13
|
+
};
|
|
14
|
+
exports.parseSearchParams = parseSearchParams;
|
|
15
|
+
//# sourceMappingURL=parseSearch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parseSearch.js","sourceRoot":"","sources":["../../../src/PathRouter/utils/parseSearch.ts"],"names":[],"mappings":";;;AAGO,MAAM,iBAAiB,GAAG,CAC/B,YAA+B,EAC/B,QAAkB,EAClB,EAAE;IACF,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACpD,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,EAAE;QACrD,IAAI,OAAO,MAAM,KAAK,QAAQ;YAAE,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;;YACnD,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AAXW,QAAA,iBAAiB,qBAW5B"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ModalData, PageData } from "../types";
|
|
2
|
+
export * from "./createRoute";
|
|
3
|
+
/** Wrap a page descriptor so the route tree can detect leaves via `data`. */
|
|
4
|
+
export declare const setPage: <const T extends PageData>(data: T) => {
|
|
5
|
+
data: T;
|
|
6
|
+
};
|
|
7
|
+
/** Identity helper that gives nice inference for modal descriptors. */
|
|
8
|
+
export declare const setModal: <const T extends ModalData>(data: T) => T;
|
|
9
|
+
//# sourceMappingURL=setters.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setters.d.ts","sourceRoot":"","sources":["../../../src/PathRouter/utils/setters.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACpD,cAAc,eAAe,CAAC;AAE9B,6EAA6E;AAC7E,eAAO,MAAM,OAAO,GAAI,KAAK,CAAC,CAAC,SAAS,QAAQ,EAAE,MAAM,CAAC;;CAAe,CAAC;AAEzE,uEAAuE;AACvE,eAAO,MAAM,QAAQ,GAAI,KAAK,CAAC,CAAC,SAAS,SAAS,EAAE,MAAM,CAAC,KAAG,CAAS,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.setModal = exports.setPage = void 0;
|
|
18
|
+
__exportStar(require("./createRoute"), exports);
|
|
19
|
+
/** Wrap a page descriptor so the route tree can detect leaves via `data`. */
|
|
20
|
+
const setPage = (data) => ({ data });
|
|
21
|
+
exports.setPage = setPage;
|
|
22
|
+
/** Identity helper that gives nice inference for modal descriptors. */
|
|
23
|
+
const setModal = (data) => data;
|
|
24
|
+
exports.setModal = setModal;
|
|
25
|
+
//# sourceMappingURL=setters.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setters.js","sourceRoot":"","sources":["../../../src/PathRouter/utils/setters.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AACA,gDAA8B;AAE9B,6EAA6E;AACtE,MAAM,OAAO,GAAG,CAA2B,IAAO,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;AAA5D,QAAA,OAAO,WAAqD;AAEzE,uEAAuE;AAChE,MAAM,QAAQ,GAAG,CAA4B,IAAO,EAAK,EAAE,CAAC,IAAI,CAAC;AAA3D,QAAA,QAAQ,YAAmD"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./PathRouter"), exports);
|
|
18
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,+CAA6B"}
|
package/package.json
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "path-router-red",
|
|
3
|
+
"version": "0.4.0",
|
|
4
|
+
"private": false,
|
|
5
|
+
"description": "Type-safe routing layer",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"scripts": {
|
|
9
|
+
"build": "tsc"
|
|
10
|
+
},
|
|
11
|
+
"keywords": [],
|
|
12
|
+
"author": "RED_TR",
|
|
13
|
+
"license": "ISC",
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "https://github.com/tterryrice-beep/path-router.git"
|
|
17
|
+
},
|
|
18
|
+
"bugs": {
|
|
19
|
+
"url": "https://github.com/tterryrice-beep/path-router/issues"
|
|
20
|
+
},
|
|
21
|
+
"homepage": "https://github.com/tterryrice-beep/path-router#readme",
|
|
22
|
+
"devDependencies": {
|
|
23
|
+
"@types/events": "^3.0.3",
|
|
24
|
+
"@types/react": "^19.2.17",
|
|
25
|
+
"typescript": "^6.0.3"
|
|
26
|
+
},
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"events": "^3.3.0",
|
|
29
|
+
"react": "^19.2.7",
|
|
30
|
+
"react-router-dom": "^7.18.0"
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import React, { Fragment, Suspense, useEffect, useRef } from "react";
|
|
2
|
+
import { Routes, Route, Navigate } from "react-router-dom";
|
|
3
|
+
|
|
4
|
+
import { usePath } from "../Provider/usePath";
|
|
5
|
+
import { clearSlash } from "../utils/clearSlash";
|
|
6
|
+
import type {
|
|
7
|
+
ModalData,
|
|
8
|
+
ModalWrapperComponent,
|
|
9
|
+
ModalWrapperRef,
|
|
10
|
+
} from "../types";
|
|
11
|
+
|
|
12
|
+
export interface ModalContainerProps {
|
|
13
|
+
paths: { pathName: string; data: ModalData }[];
|
|
14
|
+
/**
|
|
15
|
+
* Optional wrapper around the modal contents (e.g. an animated popup).
|
|
16
|
+
* If omitted, the modal component is rendered directly.
|
|
17
|
+
*/
|
|
18
|
+
ModalWrapper?: ModalWrapperComponent;
|
|
19
|
+
/** Fallback shown by `Suspense` while a lazy modal is loading. */
|
|
20
|
+
fallback?: React.ReactNode;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export const ModalsContainer: React.FC<ModalContainerProps> = ({
|
|
24
|
+
paths,
|
|
25
|
+
ModalWrapper,
|
|
26
|
+
fallback = null,
|
|
27
|
+
}) => {
|
|
28
|
+
const { page, modal } = usePath();
|
|
29
|
+
const { name: modalName, isOpen, close } = modal;
|
|
30
|
+
const modalRef = useRef<ModalWrapperRef | null>(null);
|
|
31
|
+
|
|
32
|
+
const hasMatchingComponent =
|
|
33
|
+
!!modalName &&
|
|
34
|
+
paths.some(
|
|
35
|
+
({ pathName, data }) => pathName === modalName && !!data.component,
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
if (isOpen && !hasMatchingComponent) {
|
|
40
|
+
close();
|
|
41
|
+
}
|
|
42
|
+
}, [isOpen, hasMatchingComponent, close]);
|
|
43
|
+
|
|
44
|
+
if (!modalName) return null;
|
|
45
|
+
|
|
46
|
+
const routesLocation = clearSlash(`${page.path}/${modalName}`);
|
|
47
|
+
|
|
48
|
+
const handleClose = () =>
|
|
49
|
+
modalRef.current?.handleCloseWithAnimation
|
|
50
|
+
? modalRef.current.handleCloseWithAnimation()
|
|
51
|
+
: close();
|
|
52
|
+
|
|
53
|
+
const content = (
|
|
54
|
+
<Suspense fallback={fallback}>
|
|
55
|
+
<Routes location={routesLocation}>
|
|
56
|
+
{paths.map(({ pathName, data }, i) => {
|
|
57
|
+
const { component: Component } = data;
|
|
58
|
+
if (!Component) {
|
|
59
|
+
return (
|
|
60
|
+
<Route
|
|
61
|
+
key={`modals/${pathName}_${i}`}
|
|
62
|
+
path={clearSlash(`${page.path}/${pathName}`)}
|
|
63
|
+
element={<Navigate to="/" replace />}
|
|
64
|
+
/>
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
return (
|
|
68
|
+
<Route
|
|
69
|
+
key={`modals/${pathName}_${i}`}
|
|
70
|
+
path={clearSlash(`${page.path}/${pathName}`)}
|
|
71
|
+
element={<Component onClose={handleClose} />}
|
|
72
|
+
/>
|
|
73
|
+
);
|
|
74
|
+
})}
|
|
75
|
+
</Routes>
|
|
76
|
+
</Suspense>
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
if (!ModalWrapper) {
|
|
80
|
+
return isOpen ? <Fragment>{content}</Fragment> : null;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return (
|
|
84
|
+
<ModalWrapper
|
|
85
|
+
ref={modalRef}
|
|
86
|
+
modalName={modalName}
|
|
87
|
+
isOpen={isOpen}
|
|
88
|
+
onClose={close}>
|
|
89
|
+
{content}
|
|
90
|
+
</ModalWrapper>
|
|
91
|
+
);
|
|
92
|
+
};
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import React, { type ReactNode, Suspense, useMemo } from "react";
|
|
2
|
+
import { Routes as Switch, Route, Navigate } from "react-router-dom";
|
|
3
|
+
|
|
4
|
+
import { usePath } from "../Provider/usePath";
|
|
5
|
+
import { createRoute } from "../utils/createRoute";
|
|
6
|
+
|
|
7
|
+
import { ModalsContainer } from "./ModalsContainer";
|
|
8
|
+
import type { ModalWrapperComponent, RouterConfig } from "../types";
|
|
9
|
+
|
|
10
|
+
export interface PathRouterProps<C extends RouterConfig<any, any>> {
|
|
11
|
+
/** Pages + modals tree built with `setPage` / `setModal`. */
|
|
12
|
+
config: C;
|
|
13
|
+
/**
|
|
14
|
+
* Optional component used to wrap modal content (animated popup, etc.).
|
|
15
|
+
* The package will pass it `{ modalName, isOpen, onClose, children }`
|
|
16
|
+
* and read `handleCloseWithAnimation()` from its forwarded ref.
|
|
17
|
+
*/
|
|
18
|
+
ModalWrapper?: ModalWrapperComponent;
|
|
19
|
+
/** Suspense fallback shown while pages / modals are loading. */
|
|
20
|
+
fallback?: ReactNode;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export const PathRouterContainer = <C extends RouterConfig<any, any>>({
|
|
24
|
+
config,
|
|
25
|
+
ModalWrapper,
|
|
26
|
+
fallback = null,
|
|
27
|
+
}: PathRouterProps<C>) => {
|
|
28
|
+
const { modal } = usePath();
|
|
29
|
+
|
|
30
|
+
const { pages, modals } = useMemo(() => createRoute(config), [config]);
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<>
|
|
34
|
+
<Suspense fallback={fallback}>
|
|
35
|
+
<Switch>
|
|
36
|
+
{pages.map(({ pathName, data }, i) => {
|
|
37
|
+
const { component: Component, redirect } = data;
|
|
38
|
+
const isRedirect = Boolean(!Component || redirect);
|
|
39
|
+
|
|
40
|
+
return (
|
|
41
|
+
<Route
|
|
42
|
+
key={`routes/${pathName}_${i}`}
|
|
43
|
+
path={pathName}
|
|
44
|
+
element={
|
|
45
|
+
!isRedirect && Component ? (
|
|
46
|
+
<Component />
|
|
47
|
+
) : (
|
|
48
|
+
<Navigate to={redirect || "/"} replace />
|
|
49
|
+
)
|
|
50
|
+
}
|
|
51
|
+
/>
|
|
52
|
+
);
|
|
53
|
+
})}
|
|
54
|
+
</Switch>
|
|
55
|
+
</Suspense>
|
|
56
|
+
|
|
57
|
+
{modal.isOpen && (
|
|
58
|
+
<ModalsContainer
|
|
59
|
+
paths={modals}
|
|
60
|
+
ModalWrapper={ModalWrapper}
|
|
61
|
+
fallback={fallback}
|
|
62
|
+
/>
|
|
63
|
+
)}
|
|
64
|
+
</>
|
|
65
|
+
);
|
|
66
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./RouterContainer";
|