@mxweb/router 1.0.0 → 1.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/CHANGELOG.md +13 -0
- package/dist/index.d.ts +33 -18
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,18 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.1.0] - 2024-12-29
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
|
|
12
|
+
- Changed `Route` component API from `element` prop to `children` pattern
|
|
13
|
+
- Route now automatically injects `navigation` prop into child components
|
|
14
|
+
- Added `"use client"` directive for Next.js App Router compatibility
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
|
|
18
|
+
- `PropsWithoutNavigation` utility type for route children components
|
|
19
|
+
|
|
8
20
|
## [1.0.0] - 2024-12-27
|
|
9
21
|
|
|
10
22
|
### Added
|
|
@@ -21,4 +33,5 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
21
33
|
- TypeScript support with full type definitions
|
|
22
34
|
- JSDoc documentation for all public APIs
|
|
23
35
|
|
|
36
|
+
[1.1.0]: https://github.com/mxwebio/mxweb-router/releases/tag/v1.1.0
|
|
24
37
|
[1.0.0]: https://github.com/mxwebio/mxweb-router/releases/tag/v1.0.0
|
package/dist/index.d.ts
CHANGED
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
*
|
|
16
16
|
* return (
|
|
17
17
|
* <Router basename="/my-feature" adapter={nextRouter}>
|
|
18
|
-
* <Route index
|
|
19
|
-
* <Route path="settings"
|
|
18
|
+
* <Route index><HomePage /></Route>
|
|
19
|
+
* <Route path="settings"><SettingsPage /></Route>
|
|
20
20
|
* <Link href="/settings">Go to Settings</Link>
|
|
21
21
|
* </Router>
|
|
22
22
|
* );
|
|
@@ -27,8 +27,8 @@
|
|
|
27
27
|
* function StandaloneApp() {
|
|
28
28
|
* return (
|
|
29
29
|
* <Router basename="/app">
|
|
30
|
-
* <Route index
|
|
31
|
-
* <Route path="about"
|
|
30
|
+
* <Route index><HomePage /></Route>
|
|
31
|
+
* <Route path="about"><AboutPage /></Route>
|
|
32
32
|
* </Router>
|
|
33
33
|
* );
|
|
34
34
|
* }
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
* @packageDocumentation
|
|
37
37
|
* @module @mxweb/router
|
|
38
38
|
*/
|
|
39
|
-
import React, { AnchorHTMLAttributes,
|
|
39
|
+
import React, { AnchorHTMLAttributes, MouseEventHandler, PropsWithChildren, ReactElement, ReactNode, Ref } from "react";
|
|
40
40
|
import { LiteralObject } from "@mxweb/utils";
|
|
41
41
|
/**
|
|
42
42
|
* Navigation interface for routing operations within the adhoc app.
|
|
@@ -77,28 +77,37 @@ export interface RouteNavigation {
|
|
|
77
77
|
export type PropsWithNavigation<Props = {}> = Props & {
|
|
78
78
|
navigation: RouteNavigation;
|
|
79
79
|
};
|
|
80
|
+
/**
|
|
81
|
+
* Utility type that removes navigation prop from component props.
|
|
82
|
+
* Use this type for route children components before navigation is injected.
|
|
83
|
+
*
|
|
84
|
+
* @typeParam Props - The base props type for the component
|
|
85
|
+
*/
|
|
86
|
+
export type PropsWithoutNavigation<Props = {}> = Omit<Props, "navigation">;
|
|
80
87
|
interface RouteIndex {
|
|
81
88
|
index: true;
|
|
82
89
|
path?: never;
|
|
83
|
-
|
|
90
|
+
children: ReactElement<PropsWithoutNavigation>;
|
|
84
91
|
}
|
|
85
92
|
interface RoutePath<Pathname extends string = string> {
|
|
86
93
|
index?: never;
|
|
87
94
|
path: Pathname;
|
|
88
|
-
|
|
95
|
+
children: ReactElement<PropsWithoutNavigation>;
|
|
89
96
|
}
|
|
90
97
|
/**
|
|
91
98
|
* Props for the Route component. Can be either an index route or a path-based route.
|
|
99
|
+
* The Route component accepts children instead of an element prop and automatically
|
|
100
|
+
* injects the navigation prop into the child component.
|
|
92
101
|
*
|
|
93
102
|
* @typeParam Pathname - The type of the path string for type-safe routing
|
|
94
103
|
*
|
|
95
104
|
* @example
|
|
96
105
|
* ```tsx
|
|
97
106
|
* // Index route (matches the basename exactly)
|
|
98
|
-
* <Route index
|
|
107
|
+
* <Route index><HomePage /></Route>
|
|
99
108
|
*
|
|
100
109
|
* // Path-based route
|
|
101
|
-
* <Route path="settings"
|
|
110
|
+
* <Route path="settings"><SettingsPage /></Route>
|
|
102
111
|
* ```
|
|
103
112
|
*/
|
|
104
113
|
export type RouteProps<Pathname extends string = string> = RouteIndex | RoutePath<Pathname>;
|
|
@@ -265,8 +274,8 @@ export interface RouterProps<Basename extends string = string> {
|
|
|
265
274
|
*
|
|
266
275
|
* return (
|
|
267
276
|
* <Router basename="/my-feature" adapter={nextRouter}>
|
|
268
|
-
* <Route index
|
|
269
|
-
* <Route path="settings"
|
|
277
|
+
* <Route index><HomePage /></Route>
|
|
278
|
+
* <Route path="settings"><SettingsPage /></Route>
|
|
270
279
|
* </Router>
|
|
271
280
|
* );
|
|
272
281
|
* }
|
|
@@ -278,8 +287,8 @@ export interface RouterProps<Basename extends string = string> {
|
|
|
278
287
|
* function StandaloneApp() {
|
|
279
288
|
* return (
|
|
280
289
|
* <Router basename="/app">
|
|
281
|
-
* <Route index
|
|
282
|
-
* <Route path="about"
|
|
290
|
+
* <Route index><HomePage /></Route>
|
|
291
|
+
* <Route path="about"><AboutPage /></Route>
|
|
283
292
|
* </Router>
|
|
284
293
|
* );
|
|
285
294
|
* }
|
|
@@ -287,21 +296,27 @@ export interface RouterProps<Basename extends string = string> {
|
|
|
287
296
|
*/
|
|
288
297
|
export declare function Router<Basename extends string = string>(props: PropsWithChildren<RouterProps<Basename>>): React.JSX.Element;
|
|
289
298
|
/**
|
|
290
|
-
* A route component that renders its
|
|
299
|
+
* A route component that renders its children when the current path matches.
|
|
300
|
+
* Automatically injects the `navigation` prop into the child component.
|
|
291
301
|
*
|
|
292
302
|
* @typeParam Pathname - The type of the path string for type-safe routing
|
|
293
303
|
*
|
|
294
304
|
* @example
|
|
295
305
|
* ```tsx
|
|
296
306
|
* // Index route - matches when pathname is empty or "/"
|
|
297
|
-
* <Route index
|
|
307
|
+
* <Route index><HomePage /></Route>
|
|
298
308
|
*
|
|
299
309
|
* // Path route - matches when pathname starts with "settings"
|
|
300
|
-
* <Route path="settings"
|
|
310
|
+
* <Route path="settings"><SettingsPage /></Route>
|
|
301
311
|
*
|
|
302
312
|
* // Nested route example
|
|
303
|
-
* <Route path="users"
|
|
304
|
-
* <Route path="users/profile"
|
|
313
|
+
* <Route path="users"><UsersPage /></Route>
|
|
314
|
+
* <Route path="users/profile"><UserProfilePage /></Route>
|
|
315
|
+
*
|
|
316
|
+
* // Child component receives navigation prop automatically
|
|
317
|
+
* function SettingsPage({ navigation }: PropsWithNavigation) {
|
|
318
|
+
* return <button onClick={() => navigation.pop()}>Go Back</button>;
|
|
319
|
+
* }
|
|
305
320
|
* ```
|
|
306
321
|
*/
|
|
307
322
|
export declare function Route<Pathname extends string = string>(props: RouteProps<Pathname>): React.JSX.Element | null;
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var t=require("react"),e=require("@mxweb/store"),a=require("@mxweb/react-hooks"),s=require("@mxweb/utils");function r(t){return t&&t.__esModule?t:{default:t}}var i=r(t);class n{constructor(t,e=null){this.routerState=t,this.adapter=e}getFullPath(t){return[this.routerState.basename,t].join("/").replace(/\/\/+/g,"/")}isNextAdapter(t){return s.hasOwnProperty(t,"back")&&"function"==typeof t.back}isV5Adapter(t){return s.hasOwnProperty(t,"go")&&"function"==typeof t.go}isV6Adapter(t){return"function"==typeof t}push(t,e={}){if(this.adapter)if(this.isV6Adapter(this.adapter))this.adapter(this.getFullPath(t),{state:e});else{if(this.isNextAdapter(this.adapter)){const a=s.hasOwnProperty(e,"scroll")?{scroll:e.scroll}:void 0;return void this.adapter.push(this.getFullPath(t),a)}this.isV5Adapter(this.adapter)&&this.adapter.push(this.getFullPath(t),e)}else s.isBrowser()&&(window.history.pushState(e,"",this.getFullPath(t)),window.dispatchEvent(new PopStateEvent("popstate")))}replace(t,e={}){if(this.adapter)if(this.isV6Adapter(this.adapter))this.adapter(this.getFullPath(t),{replace:!0,state:e});else{if(this.isNextAdapter(this.adapter)){const a=s.hasOwnProperty(e,"scroll")?{scroll:e.scroll}:void 0;return void this.adapter.replace(this.getFullPath(t),a)}this.isV5Adapter(this.adapter)&&this.adapter.replace(this.getFullPath(t),e)}else s.isBrowser()&&(window.history.replaceState(e,"",this.getFullPath(t)),window.dispatchEvent(new PopStateEvent("popstate")))}pop(t=-1){this.adapter?this.isV6Adapter(this.adapter)?this.adapter(t):this.isNextAdapter(this.adapter)?-1===t?this.adapter.back():1===t&&this.adapter.forward?this.adapter.forward():s.isBrowser()&&window.history.go(t):this.isV5Adapter(this.adapter)&&this.adapter.go(t):s.isBrowser()&&window.history.go(t)}setAdapter(t){return this.adapter=t,this}setState(t){return this.routerState=t,this}}class o extends e.StoreBase{constructor(){super({basename:"",pathname:"",fullpath:""}),this.navigation=new n(this.getState())}setState(t){return super.setState(t),this.navigation.setState(this.getState()),this}setAdapter(t){return this.navigation.setAdapter(t),this}getNavigation(){return{push:this.navigation.push.bind(this.navigation),replace:this.navigation.replace.bind(this.navigation),pop:this.navigation.pop.bind(this.navigation)}}isIndex(t){return s.isNullish(t)||""===t||"/"===t}isIndexPath(){const{basename:t,pathname:e}=this.getState();return!!this.isIndex(e)||(e===t||e===`${t}/`)}isIndexRoute(t){return s.hasOwnProperty(t,"index")&&!0===t.index}isPathRoute(t){return s.hasOwnProperty(t,"path")}isMatch(t,e){return`${e}/`.startsWith(`${t.replace(/^\//,"")}/`)}snapshot(t=""){if(!s.isBrowser())return{basename:t,fullpath:"",pathname:""};const e=window.location.pathname;let a=e;const r=t.startsWith("/")?t:`/${t}`;return r&&"/"!==r&&e.startsWith(r)?a=e.slice(r.length).replace(/^\//,""):e.startsWith("/")&&(a=e.slice(1)),{basename:r,fullpath:e,pathname:a}}}const h=new o,
|
|
1
|
+
"use strict";var t=require("react"),e=require("@mxweb/store"),a=require("@mxweb/react-hooks"),s=require("@mxweb/utils");function r(t){return t&&t.__esModule?t:{default:t}}var i=r(t);class n{constructor(t,e=null){this.routerState=t,this.adapter=e}getFullPath(t){return[this.routerState.basename,t].join("/").replace(/\/\/+/g,"/")}isNextAdapter(t){return s.hasOwnProperty(t,"back")&&"function"==typeof t.back}isV5Adapter(t){return s.hasOwnProperty(t,"go")&&"function"==typeof t.go}isV6Adapter(t){return"function"==typeof t}push(t,e={}){if(this.adapter)if(this.isV6Adapter(this.adapter))this.adapter(this.getFullPath(t),{state:e});else{if(this.isNextAdapter(this.adapter)){const a=s.hasOwnProperty(e,"scroll")?{scroll:e.scroll}:void 0;return void this.adapter.push(this.getFullPath(t),a)}this.isV5Adapter(this.adapter)&&this.adapter.push(this.getFullPath(t),e)}else s.isBrowser()&&(window.history.pushState(e,"",this.getFullPath(t)),window.dispatchEvent(new PopStateEvent("popstate")))}replace(t,e={}){if(this.adapter)if(this.isV6Adapter(this.adapter))this.adapter(this.getFullPath(t),{replace:!0,state:e});else{if(this.isNextAdapter(this.adapter)){const a=s.hasOwnProperty(e,"scroll")?{scroll:e.scroll}:void 0;return void this.adapter.replace(this.getFullPath(t),a)}this.isV5Adapter(this.adapter)&&this.adapter.replace(this.getFullPath(t),e)}else s.isBrowser()&&(window.history.replaceState(e,"",this.getFullPath(t)),window.dispatchEvent(new PopStateEvent("popstate")))}pop(t=-1){this.adapter?this.isV6Adapter(this.adapter)?this.adapter(t):this.isNextAdapter(this.adapter)?-1===t?this.adapter.back():1===t&&this.adapter.forward?this.adapter.forward():s.isBrowser()&&window.history.go(t):this.isV5Adapter(this.adapter)&&this.adapter.go(t):s.isBrowser()&&window.history.go(t)}setAdapter(t){return this.adapter=t,this}setState(t){return this.routerState=t,this}}class o extends e.StoreBase{constructor(){super({basename:"",pathname:"",fullpath:""}),this.navigation=new n(this.getState())}setState(t){return super.setState(t),this.navigation.setState(this.getState()),this}setAdapter(t){return this.navigation.setAdapter(t),this}getNavigation(){return{push:this.navigation.push.bind(this.navigation),replace:this.navigation.replace.bind(this.navigation),pop:this.navigation.pop.bind(this.navigation)}}isIndex(t){return s.isNullish(t)||""===t||"/"===t}isIndexPath(){const{basename:t,pathname:e}=this.getState();return!!this.isIndex(e)||(e===t||e===`${t}/`)}isIndexRoute(t){return s.hasOwnProperty(t,"index")&&!0===t.index}isPathRoute(t){return s.hasOwnProperty(t,"path")}isMatch(t,e){return`${e}/`.startsWith(`${t.replace(/^\//,"")}/`)}snapshot(t=""){if(!s.isBrowser())return{basename:t,fullpath:"",pathname:""};const e=window.location.pathname;let a=e;const r=t.startsWith("/")?t:`/${t}`;return r&&"/"!==r&&e.startsWith(r)?a=e.slice(r.length).replace(/^\//,""):e.startsWith("/")&&(a=e.slice(1)),{basename:r,fullpath:e,pathname:a}}}const h=new o,l=t.createContext(null);function p(){const e=t.useContext(l),a=e??h.getState(),s=h.getNavigation();return{state:a,navigation:s,push:(t,e)=>s.push(t,e),replace:(t,e)=>s.replace(t,e),pop:t=>s.pop(t),isIndexPath:()=>h.isIndexPath()}}const u=t.forwardRef((e,s)=>{const{href:r,replace:n=!1,state:o,asChild:h=!1}=e,{push:l,replace:u}=p(),d=t=>{t.metaKey||t.ctrlKey||t.shiftKey||t.altKey||0!==t.button||(t.preventDefault(),n?u(r,o):l(r,o))};if(h){const i=t.Children.only(e.children);if(!t.isValidElement(i))return null;const n=i.props;return t.cloneElement(i,{href:r,ref:a.combineRefs(s,n.ref),onClick:a.combineEvents(n.onClick,d)})}const{onClick:c,children:f,...g}=e;return i.default.createElement("a",{...g,ref:s,href:r,onClick:t=>{c?.(t),d(t)}},f)});u.displayName="Link",exports.Link=u,exports.Route=function(e){const{children:a}=e,{state:{pathname:s},navigation:r,isIndexPath:n}=p();return h.isIndexRoute(e)?n()?t.isValidElement(a)?t.cloneElement(a,{...a.props,navigation:r}):i.default.createElement(i.default.Fragment,null,a):null:h.isPathRoute(e)&&h.isMatch(e.path,s)?t.isValidElement(a)?t.cloneElement(a,{...a.props,navigation:r}):i.default.createElement(i.default.Fragment,null,a):null},exports.Router=function(e){const{basename:a="/",adapter:r=null,children:n}=e,[o,p]=t.useState(()=>(r&&h.setAdapter(r),h.setState(h.snapshot(a)).getState()));return t.useEffect(()=>{const t=h.onStateChange(()=>{p(t=>{const e=h.getState();return s.isEqualPrimitive(t,e)?t:e})});return h.setState(h.snapshot(a)),t},[a]),t.useEffect(()=>{r&&h.setAdapter(r)},[r]),i.default.createElement(l.Provider,{value:o},n)},exports.useRouter=p;
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import t,{createContext as e,forwardRef as a,Children as s,isValidElement as i,cloneElement as r,useContext as n,useState as h,useEffect as o}from"react";import{StoreBase as p}from"@mxweb/store";import{combineEvents as l,combineRefs as d}from"@mxweb/react-hooks";import{isNullish as u,hasOwnProperty as c,isBrowser as g,isEqualPrimitive as f}from"@mxweb/utils";class m{constructor(t,e=null){this.routerState=t,this.adapter=e}getFullPath(t){return[this.routerState.basename,t].join("/").replace(/\/\/+/g,"/")}isNextAdapter(t){return c(t,"back")&&"function"==typeof t.back}isV5Adapter(t){return c(t,"go")&&"function"==typeof t.go}isV6Adapter(t){return"function"==typeof t}push(t,e={}){if(this.adapter)if(this.isV6Adapter(this.adapter))this.adapter(this.getFullPath(t),{state:e});else{if(this.isNextAdapter(this.adapter)){const a=c(e,"scroll")?{scroll:e.scroll}:void 0;return void this.adapter.push(this.getFullPath(t),a)}this.isV5Adapter(this.adapter)&&this.adapter.push(this.getFullPath(t),e)}else g()&&(window.history.pushState(e,"",this.getFullPath(t)),window.dispatchEvent(new PopStateEvent("popstate")))}replace(t,e={}){if(this.adapter)if(this.isV6Adapter(this.adapter))this.adapter(this.getFullPath(t),{replace:!0,state:e});else{if(this.isNextAdapter(this.adapter)){const a=c(e,"scroll")?{scroll:e.scroll}:void 0;return void this.adapter.replace(this.getFullPath(t),a)}this.isV5Adapter(this.adapter)&&this.adapter.replace(this.getFullPath(t),e)}else g()&&(window.history.replaceState(e,"",this.getFullPath(t)),window.dispatchEvent(new PopStateEvent("popstate")))}pop(t=-1){this.adapter?this.isV6Adapter(this.adapter)?this.adapter(t):this.isNextAdapter(this.adapter)?-1===t?this.adapter.back():1===t&&this.adapter.forward?this.adapter.forward():g()&&window.history.go(t):this.isV5Adapter(this.adapter)&&this.adapter.go(t):g()&&window.history.go(t)}setAdapter(t){return this.adapter=t,this}setState(t){return this.routerState=t,this}}const v=new class extends p{constructor(){super({basename:"",pathname:"",fullpath:""}),this.navigation=new m(this.getState())}setState(t){return super.setState(t),this.navigation.setState(this.getState()),this}setAdapter(t){return this.navigation.setAdapter(t),this}getNavigation(){return{push:this.navigation.push.bind(this.navigation),replace:this.navigation.replace.bind(this.navigation),pop:this.navigation.pop.bind(this.navigation)}}isIndex(t){return u(t)||""===t||"/"===t}isIndexPath(){const{basename:t,pathname:e}=this.getState();return!!this.isIndex(e)||(e===t||e===`${t}/`)}isIndexRoute(t){return c(t,"index")&&!0===t.index}isPathRoute(t){return c(t,"path")}isMatch(t,e){return`${e}/`.startsWith(`${t.replace(/^\//,"")}/`)}snapshot(t=""){if(!g())return{basename:t,fullpath:"",pathname:""};const e=window.location.pathname;let a=e;const s=t.startsWith("/")?t:`/${t}`;return s&&"/"!==s&&e.startsWith(s)?a=e.slice(s.length).replace(/^\//,""):e.startsWith("/")&&(a=e.slice(1)),{basename:s,fullpath:e,pathname:a}}},w=e(null);function S(){const t=n(w),e=t??v.getState(),a=v.getNavigation();return{state:e,navigation:a,push:(t,e)=>a.push(t,e),replace:(t,e)=>a.replace(t,e),pop:t=>a.pop(t),isIndexPath:()=>v.isIndexPath()}}function x(e){const{basename:a="/",adapter:s=null,children:i}=e,[r,n]=h(()=>(s&&v.setAdapter(s),v.setState(v.snapshot(a)).getState()));return o(()=>{const t=v.onStateChange(()=>{n(t=>{const e=v.getState();return f(t,e)?t:e})});return v.setState(v.snapshot(a)),t},[a]),o(()=>{s&&v.setAdapter(s)},[s]),t.createElement(w.Provider,{value:r},i)}function P(e){const{
|
|
1
|
+
import t,{createContext as e,forwardRef as a,Children as s,isValidElement as i,cloneElement as r,useContext as n,useState as h,useEffect as o}from"react";import{StoreBase as p}from"@mxweb/store";import{combineEvents as l,combineRefs as d}from"@mxweb/react-hooks";import{isNullish as u,hasOwnProperty as c,isBrowser as g,isEqualPrimitive as f}from"@mxweb/utils";class m{constructor(t,e=null){this.routerState=t,this.adapter=e}getFullPath(t){return[this.routerState.basename,t].join("/").replace(/\/\/+/g,"/")}isNextAdapter(t){return c(t,"back")&&"function"==typeof t.back}isV5Adapter(t){return c(t,"go")&&"function"==typeof t.go}isV6Adapter(t){return"function"==typeof t}push(t,e={}){if(this.adapter)if(this.isV6Adapter(this.adapter))this.adapter(this.getFullPath(t),{state:e});else{if(this.isNextAdapter(this.adapter)){const a=c(e,"scroll")?{scroll:e.scroll}:void 0;return void this.adapter.push(this.getFullPath(t),a)}this.isV5Adapter(this.adapter)&&this.adapter.push(this.getFullPath(t),e)}else g()&&(window.history.pushState(e,"",this.getFullPath(t)),window.dispatchEvent(new PopStateEvent("popstate")))}replace(t,e={}){if(this.adapter)if(this.isV6Adapter(this.adapter))this.adapter(this.getFullPath(t),{replace:!0,state:e});else{if(this.isNextAdapter(this.adapter)){const a=c(e,"scroll")?{scroll:e.scroll}:void 0;return void this.adapter.replace(this.getFullPath(t),a)}this.isV5Adapter(this.adapter)&&this.adapter.replace(this.getFullPath(t),e)}else g()&&(window.history.replaceState(e,"",this.getFullPath(t)),window.dispatchEvent(new PopStateEvent("popstate")))}pop(t=-1){this.adapter?this.isV6Adapter(this.adapter)?this.adapter(t):this.isNextAdapter(this.adapter)?-1===t?this.adapter.back():1===t&&this.adapter.forward?this.adapter.forward():g()&&window.history.go(t):this.isV5Adapter(this.adapter)&&this.adapter.go(t):g()&&window.history.go(t)}setAdapter(t){return this.adapter=t,this}setState(t){return this.routerState=t,this}}const v=new class extends p{constructor(){super({basename:"",pathname:"",fullpath:""}),this.navigation=new m(this.getState())}setState(t){return super.setState(t),this.navigation.setState(this.getState()),this}setAdapter(t){return this.navigation.setAdapter(t),this}getNavigation(){return{push:this.navigation.push.bind(this.navigation),replace:this.navigation.replace.bind(this.navigation),pop:this.navigation.pop.bind(this.navigation)}}isIndex(t){return u(t)||""===t||"/"===t}isIndexPath(){const{basename:t,pathname:e}=this.getState();return!!this.isIndex(e)||(e===t||e===`${t}/`)}isIndexRoute(t){return c(t,"index")&&!0===t.index}isPathRoute(t){return c(t,"path")}isMatch(t,e){return`${e}/`.startsWith(`${t.replace(/^\//,"")}/`)}snapshot(t=""){if(!g())return{basename:t,fullpath:"",pathname:""};const e=window.location.pathname;let a=e;const s=t.startsWith("/")?t:`/${t}`;return s&&"/"!==s&&e.startsWith(s)?a=e.slice(s.length).replace(/^\//,""):e.startsWith("/")&&(a=e.slice(1)),{basename:s,fullpath:e,pathname:a}}},w=e(null);function S(){const t=n(w),e=t??v.getState(),a=v.getNavigation();return{state:e,navigation:a,push:(t,e)=>a.push(t,e),replace:(t,e)=>a.replace(t,e),pop:t=>a.pop(t),isIndexPath:()=>v.isIndexPath()}}function x(e){const{basename:a="/",adapter:s=null,children:i}=e,[r,n]=h(()=>(s&&v.setAdapter(s),v.setState(v.snapshot(a)).getState()));return o(()=>{const t=v.onStateChange(()=>{n(t=>{const e=v.getState();return f(t,e)?t:e})});return v.setState(v.snapshot(a)),t},[a]),o(()=>{s&&v.setAdapter(s)},[s]),t.createElement(w.Provider,{value:r},i)}function P(e){const{children:a}=e,{state:{pathname:s},navigation:n,isIndexPath:h}=S();return v.isIndexRoute(e)?h()?i(a)?r(a,{...a.props,navigation:n}):t.createElement(t.Fragment,null,a):null:v.isPathRoute(e)&&v.isMatch(e.path,s)?i(a)?r(a,{...a.props,navigation:n}):t.createElement(t.Fragment,null,a):null}const A=a((e,a)=>{const{href:n,replace:h=!1,state:o,asChild:p=!1}=e,{push:u,replace:c}=S(),g=t=>{t.metaKey||t.ctrlKey||t.shiftKey||t.altKey||0!==t.button||(t.preventDefault(),h?c(n,o):u(n,o))};if(p){const t=s.only(e.children);if(!i(t))return null;const h=t.props;return r(t,{href:n,ref:d(a,h.ref),onClick:l(h.onClick,g)})}const{onClick:f,children:m,...v}=e;return t.createElement("a",{...v,ref:a,href:n,onClick:t=>{f?.(t),g(t)}},m)});A.displayName="Link";export{A as Link,P as Route,x as Router,S as useRouter};
|