@virentia/router-react 0.1.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/LICENSE +21 -0
- package/README.md +94 -0
- package/dist/index.cjs +189 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +99 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.mts +99 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +178 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +51 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Virentia
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# @virentia/router-react
|
|
2
|
+
|
|
3
|
+
React bindings for Virentia Router.
|
|
4
|
+
|
|
5
|
+
Keep routing state in `@virentia/router`; use this package at the rendering boundary. Route views are mapped to route objects, links open typed routes, and outlets render nested route trees.
|
|
6
|
+
|
|
7
|
+
## Links
|
|
8
|
+
|
|
9
|
+
- Documentation: [movpushmov.dev/virentia/router/react](https://movpushmov.dev/virentia/router/react)
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
```sh
|
|
14
|
+
pnpm add @virentia/router-react @virentia/router @virentia/react react
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Install `history` in applications that use the bundled `historyAdapter` from `@virentia/router`.
|
|
18
|
+
|
|
19
|
+
```sh
|
|
20
|
+
pnpm add history
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## RouterProvider
|
|
24
|
+
|
|
25
|
+
```tsx
|
|
26
|
+
import { scope } from "@virentia/core";
|
|
27
|
+
import { ScopeProvider } from "@virentia/react";
|
|
28
|
+
import { createMemoryHistory } from "history";
|
|
29
|
+
import { createRoute, createRouter, historyAdapter } from "@virentia/router";
|
|
30
|
+
import { createRouteView, createRoutesView, Link, RouterProvider } from "@virentia/router-react";
|
|
31
|
+
|
|
32
|
+
const homeRoute = createRoute({ path: "/" });
|
|
33
|
+
const profileRoute = createRoute({ path: "/profile/:id" });
|
|
34
|
+
|
|
35
|
+
const router = createRouter({
|
|
36
|
+
routes: [homeRoute, profileRoute],
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
const history = historyAdapter(createMemoryHistory());
|
|
40
|
+
const appScope = scope();
|
|
41
|
+
|
|
42
|
+
function HomePage() {
|
|
43
|
+
return (
|
|
44
|
+
<Link to={profileRoute} params={{ id: "42" }}>
|
|
45
|
+
Profile
|
|
46
|
+
</Link>
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function ProfilePage() {
|
|
51
|
+
return <h1>Profile</h1>;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const RoutesView = createRoutesView({
|
|
55
|
+
routes: [
|
|
56
|
+
createRouteView({ route: homeRoute, view: HomePage }),
|
|
57
|
+
createRouteView({ route: profileRoute, view: ProfilePage }),
|
|
58
|
+
],
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
export function App() {
|
|
62
|
+
return (
|
|
63
|
+
<ScopeProvider scope={appScope}>
|
|
64
|
+
<RouterProvider router={router} history={history}>
|
|
65
|
+
<RoutesView />
|
|
66
|
+
</RouterProvider>
|
|
67
|
+
</ScopeProvider>
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Lazy route views
|
|
73
|
+
|
|
74
|
+
`createLazyRouteView` connects React lazy rendering with router preloading. Opening the route waits for the same dynamic import that renders the page.
|
|
75
|
+
|
|
76
|
+
```tsx
|
|
77
|
+
import { createLazyRouteView } from "@virentia/router-react";
|
|
78
|
+
import { profileRoute } from "./routes";
|
|
79
|
+
import { Spinner } from "./spinner";
|
|
80
|
+
|
|
81
|
+
export const profileView = createLazyRouteView({
|
|
82
|
+
route: profileRoute,
|
|
83
|
+
view: () => import("./profile-page"),
|
|
84
|
+
fallback: Spinner,
|
|
85
|
+
});
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Main API
|
|
89
|
+
|
|
90
|
+
`RouterProvider`, `createRouteView`, `createLazyRouteView`, `createRoutesView`, `Link`, `Outlet`, `withLayout`, `useRouter`, `useLink`, `useIsOpened`, `useOpenedViews`.
|
|
91
|
+
|
|
92
|
+
## License
|
|
93
|
+
|
|
94
|
+
MIT © 2026 movpushmov
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
let react = require("react");
|
|
3
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
4
|
+
let _virentia_router = require("@virentia/router");
|
|
5
|
+
let _virentia_react = require("@virentia/react");
|
|
6
|
+
//#region lib/create-lazy-route-view.tsx
|
|
7
|
+
function createLazyRouteView(props) {
|
|
8
|
+
const { fallback: Fallback, layout: Layout, view: importView } = props;
|
|
9
|
+
const LazyView = (0, react.lazy)(importView);
|
|
10
|
+
props.route.internal?.setAsyncImport(importView);
|
|
11
|
+
const routeView = {
|
|
12
|
+
route: props.route,
|
|
13
|
+
view: function LazyRouteView() {
|
|
14
|
+
const content = /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react.Suspense, {
|
|
15
|
+
fallback: Fallback ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Fallback, {}) : null,
|
|
16
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LazyView, {})
|
|
17
|
+
});
|
|
18
|
+
return Layout ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Layout, { children: content }) : content;
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
if (props.children !== void 0) routeView.children = props.children;
|
|
22
|
+
return routeView;
|
|
23
|
+
}
|
|
24
|
+
//#endregion
|
|
25
|
+
//#region lib/create-route-view.tsx
|
|
26
|
+
function createRouteView(props) {
|
|
27
|
+
const { children, layout: Layout, view: View } = props;
|
|
28
|
+
const view = Layout ? function RouteViewWithLayout() {
|
|
29
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Layout, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(View, {}) });
|
|
30
|
+
} : View;
|
|
31
|
+
const routeView = {
|
|
32
|
+
route: props.route,
|
|
33
|
+
view
|
|
34
|
+
};
|
|
35
|
+
if (children !== void 0) routeView.children = children;
|
|
36
|
+
return routeView;
|
|
37
|
+
}
|
|
38
|
+
//#endregion
|
|
39
|
+
//#region lib/context.ts
|
|
40
|
+
const RouterContext = (0, react.createContext)(null);
|
|
41
|
+
const OutletContext = (0, react.createContext)(null);
|
|
42
|
+
//#endregion
|
|
43
|
+
//#region lib/use-is-opened.ts
|
|
44
|
+
function useIsOpened(route) {
|
|
45
|
+
if (_virentia_router.is.router(route)) return (0, _virentia_react.useUnit)(route.activeRoutes).length > 0;
|
|
46
|
+
return (0, _virentia_react.useUnit)(route.isOpened);
|
|
47
|
+
}
|
|
48
|
+
//#endregion
|
|
49
|
+
//#region lib/use-opened-views.ts
|
|
50
|
+
function useOpenedViews(routes) {
|
|
51
|
+
const visibilities = routes.map((view) => useIsOpened(view.route));
|
|
52
|
+
return (0, react.useMemo)(() => {
|
|
53
|
+
const opened = routes.filter((_view, index) => visibilities[index]);
|
|
54
|
+
return opened.reduce((result, view) => result.filter((candidate) => {
|
|
55
|
+
if (_virentia_router.is.router(view.route) || _virentia_router.is.router(candidate.route)) return true;
|
|
56
|
+
const parent = "parent" in view.route ? view.route.parent : void 0;
|
|
57
|
+
return candidate.route !== parent;
|
|
58
|
+
}), opened);
|
|
59
|
+
}, [routes, ...visibilities]);
|
|
60
|
+
}
|
|
61
|
+
//#endregion
|
|
62
|
+
//#region lib/create-routes-view.tsx
|
|
63
|
+
function createRoutesView({ otherwise: Otherwise, routes }) {
|
|
64
|
+
return function RoutesView() {
|
|
65
|
+
const openedView = useOpenedViews(routes).at(-1);
|
|
66
|
+
if (!openedView) return Otherwise ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Otherwise, {}) : null;
|
|
67
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(OutletContext.Provider, {
|
|
68
|
+
value: { children: openedView.children ?? [] },
|
|
69
|
+
children: (0, react.createElement)(openedView.view)
|
|
70
|
+
});
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
//#endregion
|
|
74
|
+
//#region lib/use-router.ts
|
|
75
|
+
function useRouter() {
|
|
76
|
+
const router = (0, react.useContext)(RouterContext);
|
|
77
|
+
if (!router) throw new Error("[useRouter] Router is not provided. Wrap the tree with RouterProvider.");
|
|
78
|
+
return router;
|
|
79
|
+
}
|
|
80
|
+
//#endregion
|
|
81
|
+
//#region lib/use-link.ts
|
|
82
|
+
function useLink(to, params, query) {
|
|
83
|
+
const router = useRouter();
|
|
84
|
+
const open = (0, _virentia_react.useUnit)(to.open);
|
|
85
|
+
const target = router.knownRoutes.find(({ route }) => route === to);
|
|
86
|
+
if (!target) throw new Error("[useLink] Route not found. Pass it to createRouter first.");
|
|
87
|
+
return {
|
|
88
|
+
path: (0, react.useMemo)(() => {
|
|
89
|
+
return `${target.build(params ?? void 0)}${stringifyQuery(query)}`;
|
|
90
|
+
}, [
|
|
91
|
+
params,
|
|
92
|
+
query,
|
|
93
|
+
target
|
|
94
|
+
]),
|
|
95
|
+
open
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
function stringifyQuery(query) {
|
|
99
|
+
if (!query) return "";
|
|
100
|
+
const params = new URLSearchParams();
|
|
101
|
+
for (const [key, value] of Object.entries(query)) {
|
|
102
|
+
if (Array.isArray(value)) {
|
|
103
|
+
for (const item of value) if (item != null) params.append(key, item);
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
if (value != null) params.set(key, value);
|
|
107
|
+
}
|
|
108
|
+
const search = params.toString();
|
|
109
|
+
return search ? `?${search}` : "";
|
|
110
|
+
}
|
|
111
|
+
//#endregion
|
|
112
|
+
//#region lib/link.tsx
|
|
113
|
+
const Link = (0, react.forwardRef)((props, ref) => {
|
|
114
|
+
const { onClick, params, query, replace, target, to, ...anchorProps } = props;
|
|
115
|
+
const link = useLink(to, params, query);
|
|
116
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
|
|
117
|
+
...anchorProps,
|
|
118
|
+
ref,
|
|
119
|
+
href: link.path,
|
|
120
|
+
target,
|
|
121
|
+
onClick: (event) => {
|
|
122
|
+
onClick?.(event);
|
|
123
|
+
if (shouldIgnoreClick(event, target)) return;
|
|
124
|
+
event.preventDefault();
|
|
125
|
+
link.open({
|
|
126
|
+
...params === void 0 ? {} : { params },
|
|
127
|
+
query,
|
|
128
|
+
replace
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
function shouldIgnoreClick(event, target) {
|
|
134
|
+
return event.defaultPrevented || target !== void 0 && target !== "_self" || event.metaKey || event.altKey || event.ctrlKey || event.shiftKey;
|
|
135
|
+
}
|
|
136
|
+
//#endregion
|
|
137
|
+
//#region lib/outlet.tsx
|
|
138
|
+
function Outlet() {
|
|
139
|
+
const openedView = useOpenedViews((0, react.useContext)(OutletContext)?.children ?? []).at(-1);
|
|
140
|
+
return openedView ? (0, react.createElement)(openedView.view) : null;
|
|
141
|
+
}
|
|
142
|
+
//#endregion
|
|
143
|
+
//#region lib/router-provider.tsx
|
|
144
|
+
function RouterProvider({ children, history, router }) {
|
|
145
|
+
const setHistory = (0, _virentia_react.useUnit)(router.setHistory);
|
|
146
|
+
const dispose = (0, _virentia_react.useUnit)(router.dispose);
|
|
147
|
+
(0, react.useEffect)(() => {
|
|
148
|
+
if (!history) return;
|
|
149
|
+
setHistory(history);
|
|
150
|
+
return () => {
|
|
151
|
+
dispose();
|
|
152
|
+
};
|
|
153
|
+
}, [
|
|
154
|
+
dispose,
|
|
155
|
+
history,
|
|
156
|
+
setHistory
|
|
157
|
+
]);
|
|
158
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RouterContext.Provider, {
|
|
159
|
+
value: router,
|
|
160
|
+
children
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
//#endregion
|
|
164
|
+
//#region lib/with-layout.tsx
|
|
165
|
+
function withLayout(layout, views) {
|
|
166
|
+
const Layout = layout;
|
|
167
|
+
return views.map(({ children, route, view }) => {
|
|
168
|
+
const routeView = {
|
|
169
|
+
route,
|
|
170
|
+
view: () => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Layout, { children: (0, react.createElement)(view) })
|
|
171
|
+
};
|
|
172
|
+
if (children !== void 0) routeView.children = children;
|
|
173
|
+
return routeView;
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
//#endregion
|
|
177
|
+
exports.Link = Link;
|
|
178
|
+
exports.Outlet = Outlet;
|
|
179
|
+
exports.RouterProvider = RouterProvider;
|
|
180
|
+
exports.createLazyRouteView = createLazyRouteView;
|
|
181
|
+
exports.createRouteView = createRouteView;
|
|
182
|
+
exports.createRoutesView = createRoutesView;
|
|
183
|
+
exports.useIsOpened = useIsOpened;
|
|
184
|
+
exports.useLink = useLink;
|
|
185
|
+
exports.useOpenedViews = useOpenedViews;
|
|
186
|
+
exports.useRouter = useRouter;
|
|
187
|
+
exports.withLayout = withLayout;
|
|
188
|
+
|
|
189
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["Suspense","is","is"],"sources":["../lib/create-lazy-route-view.tsx","../lib/create-route-view.tsx","../lib/context.ts","../lib/use-is-opened.ts","../lib/use-opened-views.ts","../lib/create-routes-view.tsx","../lib/use-router.ts","../lib/use-link.ts","../lib/link.tsx","../lib/outlet.tsx","../lib/router-provider.tsx","../lib/with-layout.tsx"],"sourcesContent":["import { lazy, Suspense } from \"react\";\nimport type { AsyncBundleImport } from \"@virentia/router\";\nimport type { CreateLazyRouteViewProps, RouteView } from \"./types\";\n\nexport function createLazyRouteView<T extends object | void = void>(\n props: CreateLazyRouteViewProps<T>,\n): RouteView {\n const { fallback: Fallback, layout: Layout, view: importView } = props;\n const LazyView = lazy(importView);\n const internalRoute = props.route as {\n internal?: { setAsyncImport(value: AsyncBundleImport): void };\n };\n\n internalRoute.internal?.setAsyncImport(importView as AsyncBundleImport);\n\n const view = function LazyRouteView() {\n const content = (\n <Suspense fallback={Fallback ? <Fallback /> : null}>\n <LazyView />\n </Suspense>\n );\n\n return Layout ? <Layout>{content}</Layout> : content;\n };\n\n const routeView: RouteView = {\n route: props.route,\n view\n };\n\n if (props.children !== undefined) {\n routeView.children = props.children;\n }\n\n return routeView;\n}\n","import type { CreateRouteViewProps, RouteView } from \"./types\";\n\nexport function createRouteView<T extends object | void = void>(\n props: CreateRouteViewProps<T>,\n): RouteView {\n const { children, layout: Layout, view: View } = props;\n\n const view = Layout\n ? function RouteViewWithLayout() {\n return (\n <Layout>\n <View />\n </Layout>\n );\n }\n : View;\n\n const routeView: RouteView = {\n route: props.route,\n view\n };\n\n if (children !== undefined) {\n routeView.children = children;\n }\n\n return routeView;\n}\n","import { createContext } from \"react\";\nimport type { RouteView } from \"./types\";\nimport type { Router } from \"@virentia/router\";\n\nexport const RouterContext = createContext<Router | null>(null);\nexport const OutletContext = createContext<{ children: RouteView[] } | null>(null);\n","import { useUnit } from \"@virentia/react\";\nimport type { Route, Router, VirtualRoute } from \"@virentia/router\";\nimport { is } from \"@virentia/router\";\n\nexport function useIsOpened(route: Route<any> | Router | VirtualRoute<any, any>): boolean {\n if (is.router(route)) {\n return useUnit(route.activeRoutes).length > 0;\n }\n\n return useUnit(route.isOpened);\n}\n","import { useMemo } from \"react\";\nimport { is } from \"@virentia/router\";\nimport type { RouteView } from \"./types\";\nimport { useIsOpened } from \"./use-is-opened\";\n\nexport function useOpenedViews(routes: RouteView[]): RouteView[] {\n const visibilities = routes.map((view) => useIsOpened(view.route));\n\n return useMemo(() => {\n const opened = routes.filter((_view, index) => visibilities[index]);\n\n return opened.reduce(\n (result, view) =>\n result.filter((candidate) => {\n if (is.router(view.route) || is.router(candidate.route)) {\n return true;\n }\n\n const parent = \"parent\" in view.route ? view.route.parent : undefined;\n\n return candidate.route !== parent;\n }),\n opened,\n );\n }, [routes, ...visibilities]);\n}\n","import { createElement } from \"react\";\nimport { OutletContext } from \"./context\";\nimport type { CreateRoutesViewProps } from \"./types\";\nimport { useOpenedViews } from \"./use-opened-views\";\n\nexport function createRoutesView({ otherwise: Otherwise, routes }: CreateRoutesViewProps) {\n return function RoutesView() {\n const openedView = useOpenedViews(routes).at(-1);\n\n if (!openedView) {\n return Otherwise ? <Otherwise /> : null;\n }\n\n return (\n <OutletContext.Provider value={{ children: openedView.children ?? [] }}>\n {createElement(openedView.view)}\n </OutletContext.Provider>\n );\n };\n}\n","import { useContext } from \"react\";\nimport { RouterContext } from \"./context\";\n\nexport function useRouter() {\n const router = useContext(RouterContext);\n\n if (!router) {\n throw new Error(\"[useRouter] Router is not provided. Wrap the tree with RouterProvider.\");\n }\n\n return router;\n}\n","import { useMemo } from \"react\";\nimport { useUnit } from \"@virentia/react\";\nimport type { Query, Route } from \"@virentia/router\";\nimport { useRouter } from \"./use-router\";\n\nexport function useLink<T extends object | void = void>(\n to: Route<T>,\n params?: T,\n query?: Query,\n) {\n const router = useRouter();\n const open = useUnit(to.open);\n const target = router.knownRoutes.find(({ route }) => route === to);\n\n if (!target) {\n throw new Error(\"[useLink] Route not found. Pass it to createRouter first.\");\n }\n\n const path = useMemo(() => {\n const pathname = target.build(params ?? undefined);\n const search = stringifyQuery(query);\n\n return `${pathname}${search}`;\n }, [params, query, target]);\n\n return {\n path,\n open\n };\n}\n\nfunction stringifyQuery(query: Query | undefined): string {\n if (!query) {\n return \"\";\n }\n\n const params = new URLSearchParams();\n\n for (const [key, value] of Object.entries(query)) {\n if (Array.isArray(value)) {\n for (const item of value) {\n if (item != null) {\n params.append(key, item);\n }\n }\n\n continue;\n }\n\n if (value != null) {\n params.set(key, value);\n }\n }\n\n const search = params.toString();\n\n return search ? `?${search}` : \"\";\n}\n","import { forwardRef, type ForwardedRef, type MouseEvent, type ReactNode } from \"react\";\nimport type { RouteOpenedPayload } from \"@virentia/router\";\nimport type { LinkProps } from \"./types\";\nimport { useLink } from \"./use-link\";\n\ntype ForwardedLink = <Params extends object | void = void>(\n props: LinkProps<Params> & { ref?: ForwardedRef<HTMLAnchorElement> },\n) => ReactNode;\n\nexport const Link: ForwardedLink = forwardRef<HTMLAnchorElement, LinkProps<any>>(\n (props, ref) => {\n const { onClick, params, query, replace, target, to, ...anchorProps } = props;\n const link = useLink(to, params, query);\n\n return (\n <a\n {...anchorProps}\n ref={ref}\n href={link.path}\n target={target}\n onClick={(event) => {\n onClick?.(event);\n\n if (shouldIgnoreClick(event, target)) {\n return;\n }\n\n event.preventDefault();\n\n void link.open({\n ...(params === undefined ? {} : { params }),\n query,\n replace\n } as RouteOpenedPayload<any>);\n }}\n />\n );\n },\n) as ForwardedLink;\n\nfunction shouldIgnoreClick(event: MouseEvent<HTMLAnchorElement>, target: string | undefined) {\n return (\n event.defaultPrevented ||\n (target !== undefined && target !== \"_self\") ||\n event.metaKey ||\n event.altKey ||\n event.ctrlKey ||\n event.shiftKey\n );\n}\n","import { createElement, useContext } from \"react\";\nimport { OutletContext } from \"./context\";\nimport { useOpenedViews } from \"./use-opened-views\";\n\nexport function Outlet() {\n const outlet = useContext(OutletContext);\n const openedView = useOpenedViews(outlet?.children ?? []).at(-1);\n\n return openedView ? createElement(openedView.view) : null;\n}\n","import { useEffect, type ReactNode } from \"react\";\nimport { useUnit } from \"@virentia/react\";\nimport type { Router, RouterAdapter } from \"@virentia/router\";\nimport { RouterContext } from \"./context\";\n\ninterface RouterProviderProps {\n children?: ReactNode;\n router: Router;\n history?: RouterAdapter;\n}\n\nexport function RouterProvider({ children, history, router }: RouterProviderProps): ReactNode {\n const setHistory = useUnit(router.setHistory);\n const dispose = useUnit(router.dispose);\n\n useEffect(() => {\n if (!history) {\n return;\n }\n\n void setHistory(history);\n\n return () => {\n void dispose();\n };\n }, [dispose, history, setHistory]);\n\n return <RouterContext.Provider value={router}>{children}</RouterContext.Provider>;\n}\n","import { createElement, type ComponentType, type ReactNode } from \"react\";\nimport type { RouteView } from \"./types\";\n\nexport function withLayout(\n layout: ComponentType<{ children: ReactNode }>,\n views: RouteView[],\n): RouteView[] {\n const Layout = layout;\n\n return views.map(({ children, route, view }) => {\n const routeView: RouteView = {\n route,\n view: () => <Layout>{createElement(view)}</Layout>\n };\n\n if (children !== undefined) {\n routeView.children = children;\n }\n\n return routeView;\n });\n}\n"],"mappings":"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"}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import * as _$_virentia_router0 from "@virentia/router";
|
|
2
|
+
import { OpenPayloadBase, Query, Route, Router, RouterAdapter, VirtualRoute } from "@virentia/router";
|
|
3
|
+
import * as _$react from "react";
|
|
4
|
+
import { AnchorHTMLAttributes, ComponentType, ForwardedRef, ReactNode } from "react";
|
|
5
|
+
import * as _$react_jsx_runtime0 from "react/jsx-runtime";
|
|
6
|
+
import * as _$_virentia_core0 from "@virentia/core";
|
|
7
|
+
import * as _$_virentia_react0 from "@virentia/react";
|
|
8
|
+
|
|
9
|
+
//#region lib/types.d.ts
|
|
10
|
+
type LayoutComponent = ComponentType<{
|
|
11
|
+
children: ReactNode;
|
|
12
|
+
}>;
|
|
13
|
+
interface RouteView {
|
|
14
|
+
route: Route<any> | Router | VirtualRoute<any, any>;
|
|
15
|
+
view: ComponentType;
|
|
16
|
+
children?: RouteView[];
|
|
17
|
+
}
|
|
18
|
+
interface CreateRouteViewProps<T extends object | void = void> {
|
|
19
|
+
route: Route<T> | Router | VirtualRoute<any, any>;
|
|
20
|
+
view: ComponentType;
|
|
21
|
+
layout?: LayoutComponent;
|
|
22
|
+
children?: RouteView[];
|
|
23
|
+
}
|
|
24
|
+
interface CreateLazyRouteViewProps<T extends object | void = void> extends Omit<CreateRouteViewProps<T>, "view"> {
|
|
25
|
+
view: () => Promise<{
|
|
26
|
+
default: ComponentType;
|
|
27
|
+
}>;
|
|
28
|
+
fallback?: ComponentType;
|
|
29
|
+
}
|
|
30
|
+
interface CreateRoutesViewProps {
|
|
31
|
+
routes: RouteView[];
|
|
32
|
+
otherwise?: ComponentType;
|
|
33
|
+
}
|
|
34
|
+
type AnchorProps = Omit<AnchorHTMLAttributes<HTMLAnchorElement>, "href">;
|
|
35
|
+
type BaseLinkProps<Params extends object | void = void> = {
|
|
36
|
+
to: Route<Params>;
|
|
37
|
+
children?: ReactNode;
|
|
38
|
+
} & AnchorProps & OpenPayloadBase;
|
|
39
|
+
type LinkProps<Params extends object | void = void> = Params extends Record<string, never> | void | undefined ? BaseLinkProps<Params> & {
|
|
40
|
+
params?: Params;
|
|
41
|
+
} : BaseLinkProps<Params> & {
|
|
42
|
+
params: Params;
|
|
43
|
+
};
|
|
44
|
+
//#endregion
|
|
45
|
+
//#region lib/create-lazy-route-view.d.ts
|
|
46
|
+
declare function createLazyRouteView<T extends object | void = void>(props: CreateLazyRouteViewProps<T>): RouteView;
|
|
47
|
+
//#endregion
|
|
48
|
+
//#region lib/create-route-view.d.ts
|
|
49
|
+
declare function createRouteView<T extends object | void = void>(props: CreateRouteViewProps<T>): RouteView;
|
|
50
|
+
//#endregion
|
|
51
|
+
//#region lib/create-routes-view.d.ts
|
|
52
|
+
declare function createRoutesView({
|
|
53
|
+
otherwise: Otherwise,
|
|
54
|
+
routes
|
|
55
|
+
}: CreateRoutesViewProps): () => _$react_jsx_runtime0.JSX.Element | null;
|
|
56
|
+
//#endregion
|
|
57
|
+
//#region lib/link.d.ts
|
|
58
|
+
type ForwardedLink = <Params extends object | void = void>(props: LinkProps<Params> & {
|
|
59
|
+
ref?: ForwardedRef<HTMLAnchorElement>;
|
|
60
|
+
}) => ReactNode;
|
|
61
|
+
declare const Link: ForwardedLink;
|
|
62
|
+
//#endregion
|
|
63
|
+
//#region lib/outlet.d.ts
|
|
64
|
+
declare function Outlet(): _$react.ReactElement<{}, string | _$react.JSXElementConstructor<any>> | null;
|
|
65
|
+
//#endregion
|
|
66
|
+
//#region lib/router-provider.d.ts
|
|
67
|
+
interface RouterProviderProps {
|
|
68
|
+
children?: ReactNode;
|
|
69
|
+
router: Router;
|
|
70
|
+
history?: RouterAdapter;
|
|
71
|
+
}
|
|
72
|
+
declare function RouterProvider({
|
|
73
|
+
children,
|
|
74
|
+
history,
|
|
75
|
+
router
|
|
76
|
+
}: RouterProviderProps): ReactNode;
|
|
77
|
+
//#endregion
|
|
78
|
+
//#region lib/use-is-opened.d.ts
|
|
79
|
+
declare function useIsOpened(route: Route<any> | Router | VirtualRoute<any, any>): boolean;
|
|
80
|
+
//#endregion
|
|
81
|
+
//#region lib/use-link.d.ts
|
|
82
|
+
declare function useLink<T extends object | void = void>(to: Route<T>, params?: T, query?: Query): {
|
|
83
|
+
path: string;
|
|
84
|
+
open: _$_virentia_react0.UnitValue<_$_virentia_core0.EventCallable<_$_virentia_router0.RouteOpenedPayload<T>>>;
|
|
85
|
+
};
|
|
86
|
+
//#endregion
|
|
87
|
+
//#region lib/use-opened-views.d.ts
|
|
88
|
+
declare function useOpenedViews(routes: RouteView[]): RouteView[];
|
|
89
|
+
//#endregion
|
|
90
|
+
//#region lib/use-router.d.ts
|
|
91
|
+
declare function useRouter(): _$_virentia_router0.Router;
|
|
92
|
+
//#endregion
|
|
93
|
+
//#region lib/with-layout.d.ts
|
|
94
|
+
declare function withLayout(layout: ComponentType<{
|
|
95
|
+
children: ReactNode;
|
|
96
|
+
}>, views: RouteView[]): RouteView[];
|
|
97
|
+
//#endregion
|
|
98
|
+
export { CreateLazyRouteViewProps, CreateRouteViewProps, CreateRoutesViewProps, LayoutComponent, Link, LinkProps, Outlet, RouteView, RouterProvider, createLazyRouteView, createRouteView, createRoutesView, useIsOpened, useLink, useOpenedViews, useRouter, withLayout };
|
|
99
|
+
//# sourceMappingURL=index.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.cts","names":[],"sources":["../lib/types.ts","../lib/create-lazy-route-view.tsx","../lib/create-route-view.tsx","../lib/create-routes-view.tsx","../lib/link.tsx","../lib/outlet.tsx","../lib/router-provider.tsx","../lib/use-is-opened.ts","../lib/use-link.ts","../lib/use-opened-views.ts","../lib/use-router.ts","../lib/with-layout.tsx"],"mappings":";;;;;;;;;KAGY,eAAA,GAAkB,aAAA;EAAgB,QAAA,EAAU,SAAA;AAAA;AAAA,UAEvC,SAAA;EACf,KAAA,EAAO,KAAA,QAAa,MAAA,GAAS,YAAA;EAC7B,IAAA,EAAM,aAAA;EACN,QAAA,GAAW,SAAA;AAAA;AAAA,UAGI,oBAAA;EACf,KAAA,EAAO,KAAA,CAAM,CAAA,IAAK,MAAA,GAAS,YAAA;EAC3B,IAAA,EAAM,aAAA;EACN,MAAA,GAAS,eAAA;EACT,QAAA,GAAW,SAAA;AAAA;AAAA,UAGI,wBAAA,yCACP,IAAA,CAAK,oBAAA,CAAqB,CAAA;EAClC,IAAA,QAAY,OAAA;IAAU,OAAA,EAAS,aAAA;EAAA;EAC/B,QAAA,GAAW,aAAA;AAAA;AAAA,UAGI,qBAAA;EACf,MAAA,EAAQ,SAAA;EACR,SAAA,GAAY,aAAA;AAAA;AAAA,KAGT,WAAA,GAAc,IAAA,CAAK,oBAAA,CAAqB,iBAAA;AAAA,KAExC,aAAA;EACH,EAAA,EAAI,KAAA,CAAM,MAAA;EACV,QAAA,GAAW,SAAA;AAAA,IACT,WAAA,GACF,eAAA;AAAA,KAEU,SAAA,wCAAiD,MAAA,SACzD,MAAA,qCAGA,aAAA,CAAc,MAAA;EAAY,MAAA,GAAS,MAAA;AAAA,IACnC,aAAA,CAAc,MAAA;EAAY,MAAA,EAAQ,MAAA;AAAA;;;iBCtCtB,mBAAA,gCAAA,CACd,KAAA,EAAO,wBAAA,CAAyB,CAAA,IAC/B,SAAA;;;iBCJa,eAAA,gCAAA,CACd,KAAA,EAAO,oBAAA,CAAqB,CAAA,IAC3B,SAAA;;;iBCCa,gBAAA,CAAA;EAAmB,SAAA,EAAW,SAAA;EAAW;AAAA,GAAU,qBAAA,SAAqB,oBAAA,CAAA,GAAA,CAAA,OAAA;;;KCAnF,aAAA,yCACH,KAAA,EAAO,SAAA,CAAU,MAAA;EAAY,GAAA,GAAM,YAAA,CAAa,iBAAA;AAAA,MAC7C,SAAA;AAAA,cAEQ,IAAA,EAAM,aAAA;;;iBCLH,MAAA,CAAA,GAAM,OAAA,CAAA,YAAA,cAAA,OAAA,CAAA,qBAAA;;;UCCZ,mBAAA;EACR,QAAA,GAAW,SAAA;EACX,MAAA,EAAQ,MAAA;EACR,OAAA,GAAU,aAAA;AAAA;AAAA,iBAGI,cAAA,CAAA;EAAiB,QAAA;EAAU,OAAA;EAAS;AAAA,GAAU,mBAAA,GAAsB,SAAA;;;iBCPpE,WAAA,CAAY,KAAA,EAAO,KAAA,QAAa,MAAA,GAAS,YAAA;;;iBCCzC,OAAA,gCAAA,CACd,EAAA,EAAI,KAAA,CAAM,CAAA,GACV,MAAA,GAAS,CAAA,EACT,KAAA,GAAQ,KAAA;;;;;;iBCHM,cAAA,CAAe,MAAA,EAAQ,SAAA,KAAc,SAAA;;;iBCFrC,SAAA,CAAA,GAAS,mBAAA,CAAA,MAAA;;;iBCAT,UAAA,CACd,MAAA,EAAQ,aAAA;EAAgB,QAAA,EAAU,SAAA;AAAA,IAClC,KAAA,EAAO,SAAA,KACN,SAAA"}
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import * as _$react from "react";
|
|
2
|
+
import { AnchorHTMLAttributes, ComponentType, ForwardedRef, ReactNode } from "react";
|
|
3
|
+
import * as _$react_jsx_runtime0 from "react/jsx-runtime";
|
|
4
|
+
import * as _$_virentia_router0 from "@virentia/router";
|
|
5
|
+
import { OpenPayloadBase, Query, Route, Router, RouterAdapter, VirtualRoute } from "@virentia/router";
|
|
6
|
+
import * as _$_virentia_react0 from "@virentia/react";
|
|
7
|
+
import * as _$_virentia_core0 from "@virentia/core";
|
|
8
|
+
|
|
9
|
+
//#region lib/types.d.ts
|
|
10
|
+
type LayoutComponent = ComponentType<{
|
|
11
|
+
children: ReactNode;
|
|
12
|
+
}>;
|
|
13
|
+
interface RouteView {
|
|
14
|
+
route: Route<any> | Router | VirtualRoute<any, any>;
|
|
15
|
+
view: ComponentType;
|
|
16
|
+
children?: RouteView[];
|
|
17
|
+
}
|
|
18
|
+
interface CreateRouteViewProps<T extends object | void = void> {
|
|
19
|
+
route: Route<T> | Router | VirtualRoute<any, any>;
|
|
20
|
+
view: ComponentType;
|
|
21
|
+
layout?: LayoutComponent;
|
|
22
|
+
children?: RouteView[];
|
|
23
|
+
}
|
|
24
|
+
interface CreateLazyRouteViewProps<T extends object | void = void> extends Omit<CreateRouteViewProps<T>, "view"> {
|
|
25
|
+
view: () => Promise<{
|
|
26
|
+
default: ComponentType;
|
|
27
|
+
}>;
|
|
28
|
+
fallback?: ComponentType;
|
|
29
|
+
}
|
|
30
|
+
interface CreateRoutesViewProps {
|
|
31
|
+
routes: RouteView[];
|
|
32
|
+
otherwise?: ComponentType;
|
|
33
|
+
}
|
|
34
|
+
type AnchorProps = Omit<AnchorHTMLAttributes<HTMLAnchorElement>, "href">;
|
|
35
|
+
type BaseLinkProps<Params extends object | void = void> = {
|
|
36
|
+
to: Route<Params>;
|
|
37
|
+
children?: ReactNode;
|
|
38
|
+
} & AnchorProps & OpenPayloadBase;
|
|
39
|
+
type LinkProps<Params extends object | void = void> = Params extends Record<string, never> | void | undefined ? BaseLinkProps<Params> & {
|
|
40
|
+
params?: Params;
|
|
41
|
+
} : BaseLinkProps<Params> & {
|
|
42
|
+
params: Params;
|
|
43
|
+
};
|
|
44
|
+
//#endregion
|
|
45
|
+
//#region lib/create-lazy-route-view.d.ts
|
|
46
|
+
declare function createLazyRouteView<T extends object | void = void>(props: CreateLazyRouteViewProps<T>): RouteView;
|
|
47
|
+
//#endregion
|
|
48
|
+
//#region lib/create-route-view.d.ts
|
|
49
|
+
declare function createRouteView<T extends object | void = void>(props: CreateRouteViewProps<T>): RouteView;
|
|
50
|
+
//#endregion
|
|
51
|
+
//#region lib/create-routes-view.d.ts
|
|
52
|
+
declare function createRoutesView({
|
|
53
|
+
otherwise: Otherwise,
|
|
54
|
+
routes
|
|
55
|
+
}: CreateRoutesViewProps): () => _$react_jsx_runtime0.JSX.Element | null;
|
|
56
|
+
//#endregion
|
|
57
|
+
//#region lib/link.d.ts
|
|
58
|
+
type ForwardedLink = <Params extends object | void = void>(props: LinkProps<Params> & {
|
|
59
|
+
ref?: ForwardedRef<HTMLAnchorElement>;
|
|
60
|
+
}) => ReactNode;
|
|
61
|
+
declare const Link: ForwardedLink;
|
|
62
|
+
//#endregion
|
|
63
|
+
//#region lib/outlet.d.ts
|
|
64
|
+
declare function Outlet(): _$react.ReactElement<{}, string | _$react.JSXElementConstructor<any>> | null;
|
|
65
|
+
//#endregion
|
|
66
|
+
//#region lib/router-provider.d.ts
|
|
67
|
+
interface RouterProviderProps {
|
|
68
|
+
children?: ReactNode;
|
|
69
|
+
router: Router;
|
|
70
|
+
history?: RouterAdapter;
|
|
71
|
+
}
|
|
72
|
+
declare function RouterProvider({
|
|
73
|
+
children,
|
|
74
|
+
history,
|
|
75
|
+
router
|
|
76
|
+
}: RouterProviderProps): ReactNode;
|
|
77
|
+
//#endregion
|
|
78
|
+
//#region lib/use-is-opened.d.ts
|
|
79
|
+
declare function useIsOpened(route: Route<any> | Router | VirtualRoute<any, any>): boolean;
|
|
80
|
+
//#endregion
|
|
81
|
+
//#region lib/use-link.d.ts
|
|
82
|
+
declare function useLink<T extends object | void = void>(to: Route<T>, params?: T, query?: Query): {
|
|
83
|
+
path: string;
|
|
84
|
+
open: _$_virentia_react0.UnitValue<_$_virentia_core0.EventCallable<_$_virentia_router0.RouteOpenedPayload<T>>>;
|
|
85
|
+
};
|
|
86
|
+
//#endregion
|
|
87
|
+
//#region lib/use-opened-views.d.ts
|
|
88
|
+
declare function useOpenedViews(routes: RouteView[]): RouteView[];
|
|
89
|
+
//#endregion
|
|
90
|
+
//#region lib/use-router.d.ts
|
|
91
|
+
declare function useRouter(): _$_virentia_router0.Router;
|
|
92
|
+
//#endregion
|
|
93
|
+
//#region lib/with-layout.d.ts
|
|
94
|
+
declare function withLayout(layout: ComponentType<{
|
|
95
|
+
children: ReactNode;
|
|
96
|
+
}>, views: RouteView[]): RouteView[];
|
|
97
|
+
//#endregion
|
|
98
|
+
export { CreateLazyRouteViewProps, CreateRouteViewProps, CreateRoutesViewProps, LayoutComponent, Link, LinkProps, Outlet, RouteView, RouterProvider, createLazyRouteView, createRouteView, createRoutesView, useIsOpened, useLink, useOpenedViews, useRouter, withLayout };
|
|
99
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../lib/types.ts","../lib/create-lazy-route-view.tsx","../lib/create-route-view.tsx","../lib/create-routes-view.tsx","../lib/link.tsx","../lib/outlet.tsx","../lib/router-provider.tsx","../lib/use-is-opened.ts","../lib/use-link.ts","../lib/use-opened-views.ts","../lib/use-router.ts","../lib/with-layout.tsx"],"mappings":";;;;;;;;;KAGY,eAAA,GAAkB,aAAA;EAAgB,QAAA,EAAU,SAAA;AAAA;AAAA,UAEvC,SAAA;EACf,KAAA,EAAO,KAAA,QAAa,MAAA,GAAS,YAAA;EAC7B,IAAA,EAAM,aAAA;EACN,QAAA,GAAW,SAAA;AAAA;AAAA,UAGI,oBAAA;EACf,KAAA,EAAO,KAAA,CAAM,CAAA,IAAK,MAAA,GAAS,YAAA;EAC3B,IAAA,EAAM,aAAA;EACN,MAAA,GAAS,eAAA;EACT,QAAA,GAAW,SAAA;AAAA;AAAA,UAGI,wBAAA,yCACP,IAAA,CAAK,oBAAA,CAAqB,CAAA;EAClC,IAAA,QAAY,OAAA;IAAU,OAAA,EAAS,aAAA;EAAA;EAC/B,QAAA,GAAW,aAAA;AAAA;AAAA,UAGI,qBAAA;EACf,MAAA,EAAQ,SAAA;EACR,SAAA,GAAY,aAAA;AAAA;AAAA,KAGT,WAAA,GAAc,IAAA,CAAK,oBAAA,CAAqB,iBAAA;AAAA,KAExC,aAAA;EACH,EAAA,EAAI,KAAA,CAAM,MAAA;EACV,QAAA,GAAW,SAAA;AAAA,IACT,WAAA,GACF,eAAA;AAAA,KAEU,SAAA,wCAAiD,MAAA,SACzD,MAAA,qCAGA,aAAA,CAAc,MAAA;EAAY,MAAA,GAAS,MAAA;AAAA,IACnC,aAAA,CAAc,MAAA;EAAY,MAAA,EAAQ,MAAA;AAAA;;;iBCtCtB,mBAAA,gCAAA,CACd,KAAA,EAAO,wBAAA,CAAyB,CAAA,IAC/B,SAAA;;;iBCJa,eAAA,gCAAA,CACd,KAAA,EAAO,oBAAA,CAAqB,CAAA,IAC3B,SAAA;;;iBCCa,gBAAA,CAAA;EAAmB,SAAA,EAAW,SAAA;EAAW;AAAA,GAAU,qBAAA,SAAqB,oBAAA,CAAA,GAAA,CAAA,OAAA;;;KCAnF,aAAA,yCACH,KAAA,EAAO,SAAA,CAAU,MAAA;EAAY,GAAA,GAAM,YAAA,CAAa,iBAAA;AAAA,MAC7C,SAAA;AAAA,cAEQ,IAAA,EAAM,aAAA;;;iBCLH,MAAA,CAAA,GAAM,OAAA,CAAA,YAAA,cAAA,OAAA,CAAA,qBAAA;;;UCCZ,mBAAA;EACR,QAAA,GAAW,SAAA;EACX,MAAA,EAAQ,MAAA;EACR,OAAA,GAAU,aAAA;AAAA;AAAA,iBAGI,cAAA,CAAA;EAAiB,QAAA;EAAU,OAAA;EAAS;AAAA,GAAU,mBAAA,GAAsB,SAAA;;;iBCPpE,WAAA,CAAY,KAAA,EAAO,KAAA,QAAa,MAAA,GAAS,YAAA;;;iBCCzC,OAAA,gCAAA,CACd,EAAA,EAAI,KAAA,CAAM,CAAA,GACV,MAAA,GAAS,CAAA,EACT,KAAA,GAAQ,KAAA;;;;;;iBCHM,cAAA,CAAe,MAAA,EAAQ,SAAA,KAAc,SAAA;;;iBCFrC,SAAA,CAAA,GAAS,mBAAA,CAAA,MAAA;;;iBCAT,UAAA,CACd,MAAA,EAAQ,aAAA;EAAgB,QAAA,EAAU,SAAA;AAAA,IAClC,KAAA,EAAO,SAAA,KACN,SAAA"}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { Suspense, createContext, createElement, forwardRef, lazy, useContext, useEffect, useMemo } from "react";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { is } from "@virentia/router";
|
|
4
|
+
import { useUnit } from "@virentia/react";
|
|
5
|
+
//#region lib/create-lazy-route-view.tsx
|
|
6
|
+
function createLazyRouteView(props) {
|
|
7
|
+
const { fallback: Fallback, layout: Layout, view: importView } = props;
|
|
8
|
+
const LazyView = lazy(importView);
|
|
9
|
+
props.route.internal?.setAsyncImport(importView);
|
|
10
|
+
const routeView = {
|
|
11
|
+
route: props.route,
|
|
12
|
+
view: function LazyRouteView() {
|
|
13
|
+
const content = /* @__PURE__ */ jsx(Suspense, {
|
|
14
|
+
fallback: Fallback ? /* @__PURE__ */ jsx(Fallback, {}) : null,
|
|
15
|
+
children: /* @__PURE__ */ jsx(LazyView, {})
|
|
16
|
+
});
|
|
17
|
+
return Layout ? /* @__PURE__ */ jsx(Layout, { children: content }) : content;
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
if (props.children !== void 0) routeView.children = props.children;
|
|
21
|
+
return routeView;
|
|
22
|
+
}
|
|
23
|
+
//#endregion
|
|
24
|
+
//#region lib/create-route-view.tsx
|
|
25
|
+
function createRouteView(props) {
|
|
26
|
+
const { children, layout: Layout, view: View } = props;
|
|
27
|
+
const view = Layout ? function RouteViewWithLayout() {
|
|
28
|
+
return /* @__PURE__ */ jsx(Layout, { children: /* @__PURE__ */ jsx(View, {}) });
|
|
29
|
+
} : View;
|
|
30
|
+
const routeView = {
|
|
31
|
+
route: props.route,
|
|
32
|
+
view
|
|
33
|
+
};
|
|
34
|
+
if (children !== void 0) routeView.children = children;
|
|
35
|
+
return routeView;
|
|
36
|
+
}
|
|
37
|
+
//#endregion
|
|
38
|
+
//#region lib/context.ts
|
|
39
|
+
const RouterContext = createContext(null);
|
|
40
|
+
const OutletContext = createContext(null);
|
|
41
|
+
//#endregion
|
|
42
|
+
//#region lib/use-is-opened.ts
|
|
43
|
+
function useIsOpened(route) {
|
|
44
|
+
if (is.router(route)) return useUnit(route.activeRoutes).length > 0;
|
|
45
|
+
return useUnit(route.isOpened);
|
|
46
|
+
}
|
|
47
|
+
//#endregion
|
|
48
|
+
//#region lib/use-opened-views.ts
|
|
49
|
+
function useOpenedViews(routes) {
|
|
50
|
+
const visibilities = routes.map((view) => useIsOpened(view.route));
|
|
51
|
+
return useMemo(() => {
|
|
52
|
+
const opened = routes.filter((_view, index) => visibilities[index]);
|
|
53
|
+
return opened.reduce((result, view) => result.filter((candidate) => {
|
|
54
|
+
if (is.router(view.route) || is.router(candidate.route)) return true;
|
|
55
|
+
const parent = "parent" in view.route ? view.route.parent : void 0;
|
|
56
|
+
return candidate.route !== parent;
|
|
57
|
+
}), opened);
|
|
58
|
+
}, [routes, ...visibilities]);
|
|
59
|
+
}
|
|
60
|
+
//#endregion
|
|
61
|
+
//#region lib/create-routes-view.tsx
|
|
62
|
+
function createRoutesView({ otherwise: Otherwise, routes }) {
|
|
63
|
+
return function RoutesView() {
|
|
64
|
+
const openedView = useOpenedViews(routes).at(-1);
|
|
65
|
+
if (!openedView) return Otherwise ? /* @__PURE__ */ jsx(Otherwise, {}) : null;
|
|
66
|
+
return /* @__PURE__ */ jsx(OutletContext.Provider, {
|
|
67
|
+
value: { children: openedView.children ?? [] },
|
|
68
|
+
children: createElement(openedView.view)
|
|
69
|
+
});
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
//#endregion
|
|
73
|
+
//#region lib/use-router.ts
|
|
74
|
+
function useRouter() {
|
|
75
|
+
const router = useContext(RouterContext);
|
|
76
|
+
if (!router) throw new Error("[useRouter] Router is not provided. Wrap the tree with RouterProvider.");
|
|
77
|
+
return router;
|
|
78
|
+
}
|
|
79
|
+
//#endregion
|
|
80
|
+
//#region lib/use-link.ts
|
|
81
|
+
function useLink(to, params, query) {
|
|
82
|
+
const router = useRouter();
|
|
83
|
+
const open = useUnit(to.open);
|
|
84
|
+
const target = router.knownRoutes.find(({ route }) => route === to);
|
|
85
|
+
if (!target) throw new Error("[useLink] Route not found. Pass it to createRouter first.");
|
|
86
|
+
return {
|
|
87
|
+
path: useMemo(() => {
|
|
88
|
+
return `${target.build(params ?? void 0)}${stringifyQuery(query)}`;
|
|
89
|
+
}, [
|
|
90
|
+
params,
|
|
91
|
+
query,
|
|
92
|
+
target
|
|
93
|
+
]),
|
|
94
|
+
open
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
function stringifyQuery(query) {
|
|
98
|
+
if (!query) return "";
|
|
99
|
+
const params = new URLSearchParams();
|
|
100
|
+
for (const [key, value] of Object.entries(query)) {
|
|
101
|
+
if (Array.isArray(value)) {
|
|
102
|
+
for (const item of value) if (item != null) params.append(key, item);
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
if (value != null) params.set(key, value);
|
|
106
|
+
}
|
|
107
|
+
const search = params.toString();
|
|
108
|
+
return search ? `?${search}` : "";
|
|
109
|
+
}
|
|
110
|
+
//#endregion
|
|
111
|
+
//#region lib/link.tsx
|
|
112
|
+
const Link = forwardRef((props, ref) => {
|
|
113
|
+
const { onClick, params, query, replace, target, to, ...anchorProps } = props;
|
|
114
|
+
const link = useLink(to, params, query);
|
|
115
|
+
return /* @__PURE__ */ jsx("a", {
|
|
116
|
+
...anchorProps,
|
|
117
|
+
ref,
|
|
118
|
+
href: link.path,
|
|
119
|
+
target,
|
|
120
|
+
onClick: (event) => {
|
|
121
|
+
onClick?.(event);
|
|
122
|
+
if (shouldIgnoreClick(event, target)) return;
|
|
123
|
+
event.preventDefault();
|
|
124
|
+
link.open({
|
|
125
|
+
...params === void 0 ? {} : { params },
|
|
126
|
+
query,
|
|
127
|
+
replace
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
function shouldIgnoreClick(event, target) {
|
|
133
|
+
return event.defaultPrevented || target !== void 0 && target !== "_self" || event.metaKey || event.altKey || event.ctrlKey || event.shiftKey;
|
|
134
|
+
}
|
|
135
|
+
//#endregion
|
|
136
|
+
//#region lib/outlet.tsx
|
|
137
|
+
function Outlet() {
|
|
138
|
+
const openedView = useOpenedViews(useContext(OutletContext)?.children ?? []).at(-1);
|
|
139
|
+
return openedView ? createElement(openedView.view) : null;
|
|
140
|
+
}
|
|
141
|
+
//#endregion
|
|
142
|
+
//#region lib/router-provider.tsx
|
|
143
|
+
function RouterProvider({ children, history, router }) {
|
|
144
|
+
const setHistory = useUnit(router.setHistory);
|
|
145
|
+
const dispose = useUnit(router.dispose);
|
|
146
|
+
useEffect(() => {
|
|
147
|
+
if (!history) return;
|
|
148
|
+
setHistory(history);
|
|
149
|
+
return () => {
|
|
150
|
+
dispose();
|
|
151
|
+
};
|
|
152
|
+
}, [
|
|
153
|
+
dispose,
|
|
154
|
+
history,
|
|
155
|
+
setHistory
|
|
156
|
+
]);
|
|
157
|
+
return /* @__PURE__ */ jsx(RouterContext.Provider, {
|
|
158
|
+
value: router,
|
|
159
|
+
children
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
//#endregion
|
|
163
|
+
//#region lib/with-layout.tsx
|
|
164
|
+
function withLayout(layout, views) {
|
|
165
|
+
const Layout = layout;
|
|
166
|
+
return views.map(({ children, route, view }) => {
|
|
167
|
+
const routeView = {
|
|
168
|
+
route,
|
|
169
|
+
view: () => /* @__PURE__ */ jsx(Layout, { children: createElement(view) })
|
|
170
|
+
};
|
|
171
|
+
if (children !== void 0) routeView.children = children;
|
|
172
|
+
return routeView;
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
//#endregion
|
|
176
|
+
export { Link, Outlet, RouterProvider, createLazyRouteView, createRouteView, createRoutesView, useIsOpened, useLink, useOpenedViews, useRouter, withLayout };
|
|
177
|
+
|
|
178
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../lib/create-lazy-route-view.tsx","../lib/create-route-view.tsx","../lib/context.ts","../lib/use-is-opened.ts","../lib/use-opened-views.ts","../lib/create-routes-view.tsx","../lib/use-router.ts","../lib/use-link.ts","../lib/link.tsx","../lib/outlet.tsx","../lib/router-provider.tsx","../lib/with-layout.tsx"],"sourcesContent":["import { lazy, Suspense } from \"react\";\nimport type { AsyncBundleImport } from \"@virentia/router\";\nimport type { CreateLazyRouteViewProps, RouteView } from \"./types\";\n\nexport function createLazyRouteView<T extends object | void = void>(\n props: CreateLazyRouteViewProps<T>,\n): RouteView {\n const { fallback: Fallback, layout: Layout, view: importView } = props;\n const LazyView = lazy(importView);\n const internalRoute = props.route as {\n internal?: { setAsyncImport(value: AsyncBundleImport): void };\n };\n\n internalRoute.internal?.setAsyncImport(importView as AsyncBundleImport);\n\n const view = function LazyRouteView() {\n const content = (\n <Suspense fallback={Fallback ? <Fallback /> : null}>\n <LazyView />\n </Suspense>\n );\n\n return Layout ? <Layout>{content}</Layout> : content;\n };\n\n const routeView: RouteView = {\n route: props.route,\n view\n };\n\n if (props.children !== undefined) {\n routeView.children = props.children;\n }\n\n return routeView;\n}\n","import type { CreateRouteViewProps, RouteView } from \"./types\";\n\nexport function createRouteView<T extends object | void = void>(\n props: CreateRouteViewProps<T>,\n): RouteView {\n const { children, layout: Layout, view: View } = props;\n\n const view = Layout\n ? function RouteViewWithLayout() {\n return (\n <Layout>\n <View />\n </Layout>\n );\n }\n : View;\n\n const routeView: RouteView = {\n route: props.route,\n view\n };\n\n if (children !== undefined) {\n routeView.children = children;\n }\n\n return routeView;\n}\n","import { createContext } from \"react\";\nimport type { RouteView } from \"./types\";\nimport type { Router } from \"@virentia/router\";\n\nexport const RouterContext = createContext<Router | null>(null);\nexport const OutletContext = createContext<{ children: RouteView[] } | null>(null);\n","import { useUnit } from \"@virentia/react\";\nimport type { Route, Router, VirtualRoute } from \"@virentia/router\";\nimport { is } from \"@virentia/router\";\n\nexport function useIsOpened(route: Route<any> | Router | VirtualRoute<any, any>): boolean {\n if (is.router(route)) {\n return useUnit(route.activeRoutes).length > 0;\n }\n\n return useUnit(route.isOpened);\n}\n","import { useMemo } from \"react\";\nimport { is } from \"@virentia/router\";\nimport type { RouteView } from \"./types\";\nimport { useIsOpened } from \"./use-is-opened\";\n\nexport function useOpenedViews(routes: RouteView[]): RouteView[] {\n const visibilities = routes.map((view) => useIsOpened(view.route));\n\n return useMemo(() => {\n const opened = routes.filter((_view, index) => visibilities[index]);\n\n return opened.reduce(\n (result, view) =>\n result.filter((candidate) => {\n if (is.router(view.route) || is.router(candidate.route)) {\n return true;\n }\n\n const parent = \"parent\" in view.route ? view.route.parent : undefined;\n\n return candidate.route !== parent;\n }),\n opened,\n );\n }, [routes, ...visibilities]);\n}\n","import { createElement } from \"react\";\nimport { OutletContext } from \"./context\";\nimport type { CreateRoutesViewProps } from \"./types\";\nimport { useOpenedViews } from \"./use-opened-views\";\n\nexport function createRoutesView({ otherwise: Otherwise, routes }: CreateRoutesViewProps) {\n return function RoutesView() {\n const openedView = useOpenedViews(routes).at(-1);\n\n if (!openedView) {\n return Otherwise ? <Otherwise /> : null;\n }\n\n return (\n <OutletContext.Provider value={{ children: openedView.children ?? [] }}>\n {createElement(openedView.view)}\n </OutletContext.Provider>\n );\n };\n}\n","import { useContext } from \"react\";\nimport { RouterContext } from \"./context\";\n\nexport function useRouter() {\n const router = useContext(RouterContext);\n\n if (!router) {\n throw new Error(\"[useRouter] Router is not provided. Wrap the tree with RouterProvider.\");\n }\n\n return router;\n}\n","import { useMemo } from \"react\";\nimport { useUnit } from \"@virentia/react\";\nimport type { Query, Route } from \"@virentia/router\";\nimport { useRouter } from \"./use-router\";\n\nexport function useLink<T extends object | void = void>(\n to: Route<T>,\n params?: T,\n query?: Query,\n) {\n const router = useRouter();\n const open = useUnit(to.open);\n const target = router.knownRoutes.find(({ route }) => route === to);\n\n if (!target) {\n throw new Error(\"[useLink] Route not found. Pass it to createRouter first.\");\n }\n\n const path = useMemo(() => {\n const pathname = target.build(params ?? undefined);\n const search = stringifyQuery(query);\n\n return `${pathname}${search}`;\n }, [params, query, target]);\n\n return {\n path,\n open\n };\n}\n\nfunction stringifyQuery(query: Query | undefined): string {\n if (!query) {\n return \"\";\n }\n\n const params = new URLSearchParams();\n\n for (const [key, value] of Object.entries(query)) {\n if (Array.isArray(value)) {\n for (const item of value) {\n if (item != null) {\n params.append(key, item);\n }\n }\n\n continue;\n }\n\n if (value != null) {\n params.set(key, value);\n }\n }\n\n const search = params.toString();\n\n return search ? `?${search}` : \"\";\n}\n","import { forwardRef, type ForwardedRef, type MouseEvent, type ReactNode } from \"react\";\nimport type { RouteOpenedPayload } from \"@virentia/router\";\nimport type { LinkProps } from \"./types\";\nimport { useLink } from \"./use-link\";\n\ntype ForwardedLink = <Params extends object | void = void>(\n props: LinkProps<Params> & { ref?: ForwardedRef<HTMLAnchorElement> },\n) => ReactNode;\n\nexport const Link: ForwardedLink = forwardRef<HTMLAnchorElement, LinkProps<any>>(\n (props, ref) => {\n const { onClick, params, query, replace, target, to, ...anchorProps } = props;\n const link = useLink(to, params, query);\n\n return (\n <a\n {...anchorProps}\n ref={ref}\n href={link.path}\n target={target}\n onClick={(event) => {\n onClick?.(event);\n\n if (shouldIgnoreClick(event, target)) {\n return;\n }\n\n event.preventDefault();\n\n void link.open({\n ...(params === undefined ? {} : { params }),\n query,\n replace\n } as RouteOpenedPayload<any>);\n }}\n />\n );\n },\n) as ForwardedLink;\n\nfunction shouldIgnoreClick(event: MouseEvent<HTMLAnchorElement>, target: string | undefined) {\n return (\n event.defaultPrevented ||\n (target !== undefined && target !== \"_self\") ||\n event.metaKey ||\n event.altKey ||\n event.ctrlKey ||\n event.shiftKey\n );\n}\n","import { createElement, useContext } from \"react\";\nimport { OutletContext } from \"./context\";\nimport { useOpenedViews } from \"./use-opened-views\";\n\nexport function Outlet() {\n const outlet = useContext(OutletContext);\n const openedView = useOpenedViews(outlet?.children ?? []).at(-1);\n\n return openedView ? createElement(openedView.view) : null;\n}\n","import { useEffect, type ReactNode } from \"react\";\nimport { useUnit } from \"@virentia/react\";\nimport type { Router, RouterAdapter } from \"@virentia/router\";\nimport { RouterContext } from \"./context\";\n\ninterface RouterProviderProps {\n children?: ReactNode;\n router: Router;\n history?: RouterAdapter;\n}\n\nexport function RouterProvider({ children, history, router }: RouterProviderProps): ReactNode {\n const setHistory = useUnit(router.setHistory);\n const dispose = useUnit(router.dispose);\n\n useEffect(() => {\n if (!history) {\n return;\n }\n\n void setHistory(history);\n\n return () => {\n void dispose();\n };\n }, [dispose, history, setHistory]);\n\n return <RouterContext.Provider value={router}>{children}</RouterContext.Provider>;\n}\n","import { createElement, type ComponentType, type ReactNode } from \"react\";\nimport type { RouteView } from \"./types\";\n\nexport function withLayout(\n layout: ComponentType<{ children: ReactNode }>,\n views: RouteView[],\n): RouteView[] {\n const Layout = layout;\n\n return views.map(({ children, route, view }) => {\n const routeView: RouteView = {\n route,\n view: () => <Layout>{createElement(view)}</Layout>\n };\n\n if (children !== undefined) {\n routeView.children = children;\n }\n\n return routeView;\n });\n}\n"],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@virentia/router-react",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "React bindings for Virentia Router",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/virentia-labs/router.git",
|
|
10
|
+
"directory": "packages/react"
|
|
11
|
+
},
|
|
12
|
+
"main": "./dist/index.cjs",
|
|
13
|
+
"module": "./dist/index.mjs",
|
|
14
|
+
"types": "./dist/index.d.mts",
|
|
15
|
+
"exports": {
|
|
16
|
+
".": {
|
|
17
|
+
"types": "./dist/index.d.mts",
|
|
18
|
+
"import": "./dist/index.mjs",
|
|
19
|
+
"require": "./dist/index.cjs"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"files": [
|
|
23
|
+
"dist"
|
|
24
|
+
],
|
|
25
|
+
"publishConfig": {
|
|
26
|
+
"access": "public"
|
|
27
|
+
},
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"@virentia/router": "0.1.0"
|
|
30
|
+
},
|
|
31
|
+
"peerDependencies": {
|
|
32
|
+
"@virentia/react": ">=0.1.1",
|
|
33
|
+
"react": ">=18"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@types/react": "^19.2.7",
|
|
37
|
+
"@types/react-dom": "^19.2.3",
|
|
38
|
+
"@testing-library/react": "^16.3.0",
|
|
39
|
+
"@virentia/core": "^0.1.1",
|
|
40
|
+
"@virentia/react": "^0.1.1",
|
|
41
|
+
"happy-dom": "^20.0.10",
|
|
42
|
+
"history": "^5.3.0",
|
|
43
|
+
"react": "^19.2.1",
|
|
44
|
+
"react-dom": "^19.2.1",
|
|
45
|
+
"vitest": "^4.0.18"
|
|
46
|
+
},
|
|
47
|
+
"scripts": {
|
|
48
|
+
"build": "tsdown",
|
|
49
|
+
"test": "vitest run"
|
|
50
|
+
}
|
|
51
|
+
}
|