@real-router/react 0.18.0 → 0.20.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 +15 -3
- package/dist/cjs/{Link-DQaD7Qrc.js → Link-CFGcNhCQ.js} +2 -2
- package/dist/cjs/Link-CFGcNhCQ.js.map +1 -0
- package/dist/cjs/RouterProvider-BFSblUxR.d.ts +26 -0
- package/dist/cjs/RouterProvider-BFSblUxR.d.ts.map +1 -0
- package/dist/cjs/RouterProvider-BOWw6Z_i.js +2 -0
- package/dist/cjs/RouterProvider-BOWw6Z_i.js.map +1 -0
- package/dist/cjs/index.d.ts +19 -3
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +1 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/ink.js +1 -1
- package/dist/cjs/ink.js.map +1 -1
- package/dist/cjs/legacy.d.ts +1 -1
- package/dist/cjs/legacy.js +1 -1
- package/dist/esm/{Link-yrIwhFgp.mjs → Link-coFvvMgW.mjs} +2 -2
- package/dist/esm/Link-coFvvMgW.mjs.map +1 -0
- package/dist/esm/RouterProvider-Cx0t2IIF.mjs +2 -0
- package/dist/esm/RouterProvider-Cx0t2IIF.mjs.map +1 -0
- package/dist/esm/RouterProvider-EtbwzAgd.d.mts +26 -0
- package/dist/esm/RouterProvider-EtbwzAgd.d.mts.map +1 -0
- package/dist/esm/index.d.mts +19 -3
- package/dist/esm/index.d.mts.map +1 -1
- package/dist/esm/index.mjs +1 -1
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/ink.mjs +1 -1
- package/dist/esm/ink.mjs.map +1 -1
- package/dist/esm/legacy.d.mts +1 -1
- package/dist/esm/legacy.mjs +1 -1
- package/package.json +3 -3
- package/src/RouterProvider.tsx +31 -1
- package/src/components/InkLink.tsx +1 -1
- package/src/components/Link.tsx +1 -1
- package/src/components/modern/RouteView/RouteView.tsx +7 -2
- package/src/components/modern/RouteView/components.tsx +7 -1
- package/src/components/modern/RouteView/helpers.tsx +141 -52
- package/src/components/modern/RouteView/index.ts +1 -0
- package/src/components/modern/RouteView/types.ts +13 -1
- package/src/index.ts +1 -0
- package/dist/cjs/Link-DQaD7Qrc.js.map +0 -1
- package/dist/cjs/RouterProvider-BOdfon42.js +0 -2
- package/dist/cjs/RouterProvider-BOdfon42.js.map +0 -1
- package/dist/cjs/RouterProvider-njdco5Ra.d.ts +0 -17
- package/dist/cjs/RouterProvider-njdco5Ra.d.ts.map +0 -1
- package/dist/esm/Link-yrIwhFgp.mjs.map +0 -1
- package/dist/esm/RouterProvider-CiPZI0V5.mjs +0 -2
- package/dist/esm/RouterProvider-CiPZI0V5.mjs.map +0 -1
- package/dist/esm/RouterProvider-DgB4lIQr.d.mts +0 -17
- package/dist/esm/RouterProvider-DgB4lIQr.d.mts.map +0 -1
package/README.md
CHANGED
|
@@ -289,18 +289,30 @@ Enable screen reader announcements for route changes:
|
|
|
289
289
|
|
|
290
290
|
When enabled, a visually hidden `aria-live` region announces each navigation. Focus moves to the first `<h1>` on the new page. See [Accessibility guide](https://github.com/greydragon888/real-router/wiki/Accessibility) for details.
|
|
291
291
|
|
|
292
|
+
## Scroll Restoration
|
|
293
|
+
|
|
294
|
+
Opt-in preservation of scroll position across navigations:
|
|
295
|
+
|
|
296
|
+
```tsx
|
|
297
|
+
<RouterProvider router={router} scrollRestoration={{ mode: "restore" }}>
|
|
298
|
+
{/* Your app */}
|
|
299
|
+
</RouterProvider>
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
Restores scroll on back/forward, scrolls to top (or `#hash`) on push. Three modes: `"restore"` (default), `"top"`, `"manual"`. Custom containers via `scrollContainer: () => HTMLElement | null`. Lifecycle tied to the provider — created on mount, destroyed on unmount. See [Scroll Restoration guide](https://github.com/greydragon888/real-router/wiki/Scroll-Restoration) for details.
|
|
303
|
+
|
|
292
304
|
## Documentation
|
|
293
305
|
|
|
294
306
|
Full documentation: [Wiki](https://github.com/greydragon888/real-router/wiki)
|
|
295
307
|
|
|
296
|
-
- [RouterProvider](https://github.com/greydragon888/real-router/wiki/RouterProvider) · [RouteView](https://github.com/greydragon888/real-router/wiki/RouteView) · [RouterErrorBoundary](https://github.com/greydragon888/real-router/wiki/RouterErrorBoundary) · [Link](https://github.com/greydragon888/real-router/wiki/Link)
|
|
308
|
+
- [RouterProvider](https://github.com/greydragon888/real-router/wiki/RouterProvider) · [RouteView](https://github.com/greydragon888/real-router/wiki/RouteView) · [RouterErrorBoundary](https://github.com/greydragon888/real-router/wiki/RouterErrorBoundary) · [Link](https://github.com/greydragon888/real-router/wiki/Link) · [Scroll Restoration](https://github.com/greydragon888/real-router/wiki/Scroll-Restoration)
|
|
297
309
|
- [useRouter](https://github.com/greydragon888/real-router/wiki/useRouter) · [useRoute](https://github.com/greydragon888/real-router/wiki/useRoute) · [useRouteNode](https://github.com/greydragon888/real-router/wiki/useRouteNode) · [useNavigator](https://github.com/greydragon888/real-router/wiki/useNavigator) · [useRouteUtils](https://github.com/greydragon888/real-router/wiki/useRouteUtils) · [useRouterTransition](https://github.com/greydragon888/real-router/wiki/useRouterTransition)
|
|
298
310
|
|
|
299
311
|
## Examples
|
|
300
312
|
|
|
301
|
-
14 runnable examples — each is a standalone Vite app. Run: `cd examples/react/basic && pnpm dev`
|
|
313
|
+
14 runnable examples — each is a standalone Vite app. Run: `cd examples/web/react/basic && pnpm dev`
|
|
302
314
|
|
|
303
|
-
[basic](../../examples/react/basic) · [nested-routes](../../examples/react/nested-routes) · [auth-guards](../../examples/react/auth-guards) · [data-loading](../../examples/react/data-loading) · [lazy-loading](../../examples/react/lazy-loading) · [async-guards](../../examples/react/async-guards) · [hash-routing](../../examples/react/hash-routing) · [persistent-params](../../examples/react/persistent-params) · [error-handling](../../examples/react/error-handling) · [dynamic-routes](../../examples/react/dynamic-routes) · [keep-alive](../../examples/react/keep-alive) · [legacy-entry](../../examples/react/legacy-entry) · [hmr](../../examples/react/hmr) · [combined](../../examples/react/combined)
|
|
315
|
+
[basic](../../examples/web/react/basic) · [nested-routes](../../examples/web/react/nested-routes) · [auth-guards](../../examples/web/react/auth-guards) · [data-loading](../../examples/web/react/data-loading) · [lazy-loading](../../examples/web/react/lazy-loading) · [async-guards](../../examples/web/react/async-guards) · [hash-routing](../../examples/web/react/hash-routing) · [persistent-params](../../examples/web/react/persistent-params) · [error-handling](../../examples/web/react/error-handling) · [dynamic-routes](../../examples/web/react/dynamic-routes) · [keep-alive](../../examples/web/react/keep-alive) · [legacy-entry](../../examples/web/react/legacy-entry) · [hmr](../../examples/web/react/hmr) · [combined](../../examples/web/react/combined)
|
|
304
316
|
|
|
305
317
|
## Related Packages
|
|
306
318
|
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require(`./RouterProvider-
|
|
2
|
-
//# sourceMappingURL=Link-
|
|
1
|
+
const e=require(`./RouterProvider-BOWw6Z_i.js`);let t=require(`react`),n=require(`react/jsx-runtime`);function r(t,n){return t.routeName===n.routeName&&t.className===n.className&&t.activeClassName===n.activeClassName&&t.activeStrict===n.activeStrict&&t.ignoreQueryParams===n.ignoreQueryParams&&t.onClick===n.onClick&&t.target===n.target&&t.style===n.style&&t.children===n.children&&e.u(t.routeParams,n.routeParams)&&e.u(t.routeOptions,n.routeOptions)}const i=(0,t.memo)(({routeName:r,routeParams:i=e.p,routeOptions:a=e.f,className:o,activeClassName:s=`active`,activeStrict:c=!1,ignoreQueryParams:l=!0,onClick:u,target:d,children:f,...p})=>{let m=e.h(),h=e.s(r,i,c,l),g=(0,t.useMemo)(()=>e.l(m,r,i),[m,r,i]),_=(0,t.useCallback)(t=>{u&&(u(t),t.defaultPrevented)||!e.d(t.nativeEvent)||d===`_blank`||(t.preventDefault(),m.navigate(r,i,a).catch(()=>{}))},[u,d,m,r,i,a]),v=e.c(h,s,o);return(0,n.jsx)(`a`,{...p,href:g,className:v,onClick:_,children:f})},r);i.displayName=`Link`,Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return i}});
|
|
2
|
+
//# sourceMappingURL=Link-CFGcNhCQ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Link-CFGcNhCQ.js","names":["shallowEqual","EMPTY_PARAMS","EMPTY_OPTIONS","useRouter","useIsActiveRoute","buildHref","shouldNavigate","buildActiveClassName"],"sources":["../../src/components/Link.tsx"],"sourcesContent":["import { memo, useCallback, useMemo } from \"react\";\n\nimport { EMPTY_PARAMS, EMPTY_OPTIONS } from \"../constants\";\nimport {\n shouldNavigate,\n buildHref,\n buildActiveClassName,\n shallowEqual,\n} from \"../dom-utils\";\nimport { useIsActiveRoute } from \"../hooks/useIsActiveRoute\";\nimport { useRouter } from \"../hooks/useRouter\";\n\nimport type { LinkProps } from \"../types\";\nimport type { FC, MouseEvent } from \"react\";\n\nfunction areLinkPropsEqual(\n prev: Readonly<LinkProps>,\n next: Readonly<LinkProps>,\n): boolean {\n return (\n prev.routeName === next.routeName &&\n prev.className === next.className &&\n prev.activeClassName === next.activeClassName &&\n prev.activeStrict === next.activeStrict &&\n prev.ignoreQueryParams === next.ignoreQueryParams &&\n prev.onClick === next.onClick &&\n prev.target === next.target &&\n prev.style === next.style &&\n prev.children === next.children &&\n shallowEqual(prev.routeParams, next.routeParams) &&\n shallowEqual(prev.routeOptions, next.routeOptions)\n );\n}\n\nconst LinkImpl: FC<LinkProps> = ({\n routeName,\n routeParams = EMPTY_PARAMS,\n routeOptions = EMPTY_OPTIONS,\n className,\n activeClassName = \"active\",\n activeStrict = false,\n ignoreQueryParams = true,\n onClick,\n target,\n children,\n ...props\n}) => {\n // memo + areLinkPropsEqual guarantees that on bail-out the component does\n // not render; on render, routeParams/routeOptions either changed reference\n // (true change) or comparator failed (e.g., BigInt fallback to identity),\n // so they're safe to use directly in hook deps.\n\n const router = useRouter();\n\n const isActive = useIsActiveRoute(\n routeName,\n routeParams,\n activeStrict,\n ignoreQueryParams,\n );\n\n const href = useMemo(\n () => buildHref(router, routeName, routeParams),\n [router, routeName, routeParams],\n );\n\n const handleClick = useCallback(\n (evt: MouseEvent<HTMLAnchorElement>) => {\n if (onClick) {\n onClick(evt);\n\n if (evt.defaultPrevented) {\n return;\n }\n }\n\n if (!shouldNavigate(evt.nativeEvent) || target === \"_blank\") {\n return;\n }\n\n evt.preventDefault();\n router.navigate(routeName, routeParams, routeOptions).catch(() => {});\n },\n [onClick, target, router, routeName, routeParams, routeOptions],\n );\n\n const finalClassName = buildActiveClassName(\n isActive,\n activeClassName,\n className,\n );\n\n return (\n <a {...props} href={href} className={finalClassName} onClick={handleClick}>\n {children}\n </a>\n );\n};\n\nexport const Link: FC<LinkProps> = memo(LinkImpl, areLinkPropsEqual);\n\nLink.displayName = \"Link\";\n"],"mappings":"sGAeA,SAAS,EACP,EACA,EACS,CACT,OACE,EAAK,YAAc,EAAK,WACxB,EAAK,YAAc,EAAK,WACxB,EAAK,kBAAoB,EAAK,iBAC9B,EAAK,eAAiB,EAAK,cAC3B,EAAK,oBAAsB,EAAK,mBAChC,EAAK,UAAY,EAAK,SACtB,EAAK,SAAW,EAAK,QACrB,EAAK,QAAU,EAAK,OACpB,EAAK,WAAa,EAAK,UACvBA,EAAAA,EAAa,EAAK,YAAa,EAAK,YAAY,EAChDA,EAAAA,EAAa,EAAK,aAAc,EAAK,aAAa,CAqEtD,MAAa,GAAA,EAAA,EAAA,OAjEoB,CAC/B,YACA,cAAcC,EAAAA,EACd,eAAeC,EAAAA,EACf,YACA,kBAAkB,SAClB,eAAe,GACf,oBAAoB,GACpB,UACA,SACA,WACA,GAAG,KACC,CAMJ,IAAM,EAASC,EAAAA,GAAW,CAEpB,EAAWC,EAAAA,EACf,EACA,EACA,EACA,EACD,CAEK,GAAA,EAAA,EAAA,aACEC,EAAAA,EAAU,EAAQ,EAAW,EAAY,CAC/C,CAAC,EAAQ,EAAW,EAAY,CACjC,CAEK,GAAA,EAAA,EAAA,aACH,GAAuC,CAClC,IACF,EAAQ,EAAI,CAER,EAAI,mBAKN,CAACC,EAAAA,EAAe,EAAI,YAAY,EAAI,IAAW,WAInD,EAAI,gBAAgB,CACpB,EAAO,SAAS,EAAW,EAAa,EAAa,CAAC,UAAY,GAAG,GAEvE,CAAC,EAAS,EAAQ,EAAQ,EAAW,EAAa,EAAa,CAChE,CAEK,EAAiBC,EAAAA,EACrB,EACA,EACA,EACD,CAED,OACE,EAAA,EAAA,KAAC,IAAD,CAAG,GAAI,EAAa,OAAM,UAAW,EAAgB,QAAS,EAC3D,WACC,CAAA,EAI0C,EAAkB,CAEpE,EAAK,YAAc"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { l as LinkProps } from "./useRouterTransition-BlTJ1uz3.js";
|
|
2
|
+
import { FC, ReactNode } from "react";
|
|
3
|
+
import { Params, Router, State } from "@real-router/core";
|
|
4
|
+
|
|
5
|
+
//#region src/components/Link.d.ts
|
|
6
|
+
declare const Link: FC<LinkProps>;
|
|
7
|
+
//#endregion
|
|
8
|
+
//#region ../../shared/dom-utils/scroll-restore.d.ts
|
|
9
|
+
type ScrollRestorationMode = "restore" | "top" | "manual";
|
|
10
|
+
interface ScrollRestorationOptions {
|
|
11
|
+
mode?: ScrollRestorationMode | undefined;
|
|
12
|
+
anchorScrolling?: boolean | undefined;
|
|
13
|
+
scrollContainer?: (() => HTMLElement | null) | undefined;
|
|
14
|
+
}
|
|
15
|
+
//#endregion
|
|
16
|
+
//#region src/RouterProvider.d.ts
|
|
17
|
+
interface RouteProviderProps {
|
|
18
|
+
router: Router;
|
|
19
|
+
children: ReactNode;
|
|
20
|
+
announceNavigation?: boolean;
|
|
21
|
+
scrollRestoration?: ScrollRestorationOptions;
|
|
22
|
+
}
|
|
23
|
+
declare const RouterProvider: FC<RouteProviderProps>;
|
|
24
|
+
//#endregion
|
|
25
|
+
export { Link as n, RouterProvider as t };
|
|
26
|
+
//# sourceMappingURL=RouterProvider-BFSblUxR.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RouterProvider-BFSblUxR.d.ts","names":[],"sources":["../../src/components/Link.tsx","../../../../shared/dom-utils/scroll-restore.ts","../../src/RouterProvider.tsx"],"mappings":";;;;;cAmGa,IAAA,EAAM,EAAA,CAAG,SAAA;;;KCzFV,qBAAA;AAAA,UAEK,wBAAA;EACf,IAAA,GAAO,qBAAA;EACP,eAAA;EACA,eAAA,UAAyB,WAAA;AAAA;;;UCJV,kBAAA;EACf,MAAA,EAAQ,MAAA;EACR,QAAA,EAAU,SAAA;EACV,kBAAA;EACA,iBAAA,GAAoB,wBAAA;AAAA;AAAA,cAGT,cAAA,EAAgB,EAAA,CAAG,kBAAA"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
let e=require(`react`),t=require(`@real-router/core`),n=require(`@real-router/route-utils`),r=require(`react/jsx-runtime`),i=require(`@real-router/sources`),a=require(`@real-router/core/api`);const o=(0,e.createContext)(null),s=(0,e.createContext)(null),c=(0,e.createContext)(null),l=()=>{let t=(0,e.useContext)(s);if(!t)throw Error(`useRouter must be used within a RouterProvider`);return t};function u(n){let r=l(),a=(0,e.useMemo)(()=>(0,i.createRouteNodeSource)(r,n),[r,n]),o=(0,e.useSyncExternalStore)(a.subscribe,a.getSnapshot,a.getSnapshot),s=(0,t.getNavigator)(r);return(0,e.useMemo)(()=>({navigator:s,route:o.route,previousRoute:o.previousRoute}),[s,o])}const d=Object.freeze({}),f=Object.freeze({}),p=`data-real-router-announcer`;function m(e,t){let n=t?.prefix??`Navigated to `,r=t?.getAnnouncementText,i=!0,a=!1,o=!1,s=``,c=null,l,u=h(),d=(e,t)=>{s=e,clearTimeout(l),u.textContent=e,l=setTimeout(()=>{u.textContent=``,s=``},7e3),v(t)},f=setTimeout(()=>{if(a=!0,c!==null&&!o){let e=c;c=null,d(e,document.querySelector(`h1`))}},100),p=e.subscribe(({route:e})=>{if(i){i=!1;return}requestAnimationFrame(()=>{requestAnimationFrame(()=>{if(o)return;let t=document.querySelector(`h1`),i=_(e,n,r,t);if(!(!i||i===s)){if(!a){c=i;return}d(i,t)}})})});return{destroy(){o=!0,p(),clearTimeout(l),clearTimeout(f),g()}}}function h(){let e=document.querySelector(`[${p}]`);if(e)return e;let t=document.createElement(`div`);return t.setAttribute(`style`,`position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);clip-path:inset(50%);white-space:nowrap;border:0`),t.setAttribute(`aria-live`,`assertive`),t.setAttribute(`aria-atomic`,`true`),t.setAttribute(p,``),document.body.prepend(t),t}function g(){document.querySelector(`[${p}]`)?.remove()}function _(e,t,n,r){if(n)return n(e);let i=r?.textContent.trim()??``,a=e.name.startsWith(`@@`)?``:e.name;return`${t}${i||document.title||a||globalThis.location.pathname}`}function v(e){e&&(e.hasAttribute(`tabindex`)||e.setAttribute(`tabindex`,`-1`),e.focus({preventScroll:!0}))}const y=`real-router:scroll`,b=Object.freeze({destroy:()=>{}});function x(e,t){if(globalThis.window===void 0)return b;let n=t?.mode??`restore`;if(n===`manual`)return b;let r=t?.anchorScrolling??!0,i=t?.scrollContainer,a=history.scrollRestoration;try{history.scrollRestoration=`manual`}catch{}let o=()=>{let e=i?.();return e?e.scrollTop:globalThis.scrollY},s=e=>{let t=i?.();t?t.scrollTop=e:globalThis.scrollTo(0,e)},c=()=>{let e=globalThis.location.hash;if(r&&e.length>1){let t;try{t=decodeURIComponent(e.slice(1))}catch{t=e.slice(1)}let n=document.getElementById(t);if(n){n.scrollIntoView();return}}s(0)},l=!1,u=e.subscribe(({route:e,previousRoute:t})=>{let r=e.context.navigation;t&&w(S(t),o()),requestAnimationFrame(()=>{if(!l){if(n===`top`||!r){c();return}if(r.navigationType!==`replace`){if(r.direction===`back`||r.navigationType===`traverse`||r.navigationType===`reload`){s(C()[S(e)]??0);return}c()}}})}),d=()=>{let t=e.getState();t&&w(S(t),o())};return globalThis.addEventListener(`pagehide`,d),{destroy:()=>{if(!l){l=!0,u(),globalThis.removeEventListener(`pagehide`,d);try{history.scrollRestoration=a}catch{}}}}}function S(e){return`${e.name}:${T(e.params)}`}function C(){try{let e=sessionStorage.getItem(y);return e?JSON.parse(e):{}}catch{return{}}}function w(e,t){try{let n=C();n[e]=t,sessionStorage.setItem(y,JSON.stringify(n))}catch{}}function T(e){return JSON.stringify(e,E)}function E(e,t){if(typeof t==`object`&&t&&!Array.isArray(t)){let e={},n=Object.keys(t).sort((e,t)=>e.localeCompare(t));for(let r of n)e[r]=t[r];return e}return t}function D(e){return e.button===0&&!e.metaKey&&!e.altKey&&!e.ctrlKey&&!e.shiftKey}function O(e,t,n){try{let r=e.buildUrl;if(r){let e=r(t,n);if(e!==void 0)return e}return e.buildPath(t,n)}catch{console.error(`[real-router] Route "${t}" is not defined. The element will render without an href attribute.`);return}}function k(e){return e?e.match(/\S+/g)??[]:[]}function A(e,t,n){if(e&&t){let e=k(t);if(e.length===0)return n??void 0;if(!n)return e.join(` `);let r=k(n),i=new Set(r);for(let t of e)i.has(t)||(i.add(t),r.push(t));return r.join(` `)}return n??void 0}function j(e,t){if(Object.is(e,t))return!0;if(!e||!t)return!1;let n=Object.keys(e);if(n.length!==Object.keys(t).length)return!1;let r=e,i=t;for(let e of n)if(!Object.is(r[e],i[e]))return!1;return!0}function M(t,n,r=!1,a=!0){let o=(0,i.createActiveRouteSource)(l(),t,n,{strict:r,ignoreQueryParams:a});return(0,e.useSyncExternalStore)(o.subscribe,o.getSnapshot,o.getSnapshot)}function N({children:t,fallback:n,onError:a}){let o=(0,i.createDismissableError)(l()),s=(0,e.useSyncExternalStore)(o.subscribe,o.getSnapshot,o.getSnapshot),c=(0,e.useRef)(a);return c.current=a,(0,e.useEffect)(()=>{s.error&&c.current?.(s.error,s.toRoute,s.fromRoute)},[s.version]),(0,r.jsxs)(r.Fragment,{children:[t,s.error?n(s.error,s.resetError):null]})}const P=()=>{let t=(0,e.useContext)(c);if(!t)throw Error(`useNavigator must be used within a RouterProvider`);return t},F=()=>(0,n.getRouteUtils)((0,a.getPluginApi)(l()).getTree()),I=()=>{let t=(0,e.useContext)(o);if(!t)throw Error(`useRoute must be used within a RouteProvider`);return t};function L(){let t=(0,i.getTransitionSource)(l());return(0,e.useSyncExternalStore)(t.subscribe,t.getSnapshot,t.getSnapshot)}const R=({router:n,children:a,announceNavigation:l,scrollRestoration:u})=>{(0,e.useEffect)(()=>{if(!l)return;let e=m(n);return()=>{e.destroy()}},[l,n]);let d=u?.mode,f=u?.anchorScrolling,p=u!==void 0;(0,e.useEffect)(()=>{if(!p)return;let e=x(n,{mode:d,anchorScrolling:f,scrollContainer:u.scrollContainer});return()=>{e.destroy()}},[n,p,d,f]);let h=(0,e.useMemo)(()=>(0,t.getNavigator)(n),[n]),g=(0,e.useMemo)(()=>(0,i.createRouteSource)(n),[n]),_=(0,e.useSyncExternalStore)(g.subscribe,g.getSnapshot,g.getSnapshot),v=(0,e.useMemo)(()=>({navigator:h,route:_.route,previousRoute:_.previousRoute}),[h,_]);return(0,r.jsx)(s.Provider,{value:n,children:(0,r.jsx)(c.Provider,{value:h,children:(0,r.jsx)(o.Provider,{value:v,children:a})})})};Object.defineProperty(exports,`a`,{enumerable:!0,get:function(){return P}}),Object.defineProperty(exports,`c`,{enumerable:!0,get:function(){return A}}),Object.defineProperty(exports,`d`,{enumerable:!0,get:function(){return D}}),Object.defineProperty(exports,`f`,{enumerable:!0,get:function(){return f}}),Object.defineProperty(exports,`h`,{enumerable:!0,get:function(){return l}}),Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return F}}),Object.defineProperty(exports,`l`,{enumerable:!0,get:function(){return O}}),Object.defineProperty(exports,`m`,{enumerable:!0,get:function(){return u}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return L}}),Object.defineProperty(exports,`o`,{enumerable:!0,get:function(){return N}}),Object.defineProperty(exports,`p`,{enumerable:!0,get:function(){return d}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return I}}),Object.defineProperty(exports,`s`,{enumerable:!0,get:function(){return M}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return R}}),Object.defineProperty(exports,`u`,{enumerable:!0,get:function(){return j}});
|
|
2
|
+
//# sourceMappingURL=RouterProvider-BOWw6Z_i.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RouterProvider-BOWw6Z_i.js","names":[],"sources":["../../src/context.ts","../../src/hooks/useRouter.tsx","../../src/hooks/useRouteNode.tsx","../../src/constants.ts","../../../../shared/dom-utils/route-announcer.ts","../../../../shared/dom-utils/scroll-restore.ts","../../../../shared/dom-utils/link-utils.ts","../../src/hooks/useIsActiveRoute.tsx","../../src/components/RouterErrorBoundary.tsx","../../src/hooks/useNavigator.tsx","../../src/hooks/useRouteUtils.tsx","../../src/hooks/useRoute.tsx","../../src/hooks/useRouterTransition.tsx","../../src/RouterProvider.tsx"],"sourcesContent":["// packages/react/src/context.ts\n\nimport { createContext } from \"react\";\n\nimport type { RouteContext as RouteContextType } from \"./types\";\nimport type { Router, Navigator } from \"@real-router/core\";\n\nexport const RouteContext = createContext<RouteContextType | null>(null);\n\nexport const RouterContext = createContext<Router | null>(null);\n\nexport const NavigatorContext = createContext<Navigator | null>(null);\n","// packages/react/src/hooks/useRouter.tsx\n\nimport { useContext } from \"react\";\n\nimport { RouterContext } from \"../context\";\n\nimport type { Router } from \"@real-router/core\";\n\nexport const useRouter = (): Router => {\n const router = useContext(RouterContext);\n\n if (!router) {\n throw new Error(\"useRouter must be used within a RouterProvider\");\n }\n\n return router;\n};\n","import { getNavigator } from \"@real-router/core\";\nimport { createRouteNodeSource } from \"@real-router/sources\";\nimport { useMemo, useSyncExternalStore } from \"react\";\n\nimport { useRouter } from \"./useRouter\";\n\nimport type { RouteContext } from \"../types\";\n\nexport function useRouteNode(nodeName: string): RouteContext {\n const router = useRouter();\n\n const store = useMemo(\n () => createRouteNodeSource(router, nodeName),\n [router, nodeName],\n );\n\n // Use snapshot reference directly. createRouteNodeSource via stabilizeState\n // returns the SAME snapshot when the node-relevant state did not change,\n // so memoization on `[navigator, snapshot]` preserves identity for consumers.\n const snapshot = useSyncExternalStore(\n store.subscribe,\n store.getSnapshot,\n store.getSnapshot, // SSR: router returns same state on server and client\n );\n\n // getNavigator is WeakMap-cached in core; additional useMemo is redundant.\n const navigator = getNavigator(router);\n\n return useMemo(\n (): RouteContext => ({\n navigator,\n route: snapshot.route,\n previousRoute: snapshot.previousRoute,\n }),\n [navigator, snapshot],\n );\n}\n","// packages/react/src/constants.ts\n\n/**\n * Stable empty object for default params\n */\nexport const EMPTY_PARAMS = Object.freeze({});\n\n/**\n * Stable empty options object\n */\nexport const EMPTY_OPTIONS = Object.freeze({});\n","import type { Router, State } from \"@real-router/core\";\n\nconst CLEAR_DELAY = 7000;\nconst SAFARI_READY_DELAY = 100;\nconst ANNOUNCER_ATTR = \"data-real-router-announcer\";\nconst INTERNAL_ROUTE_PREFIX = \"@@\";\nconst VISUALLY_HIDDEN =\n \"position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);clip-path:inset(50%);white-space:nowrap;border:0\";\n\nexport interface RouteAnnouncerOptions {\n prefix?: string;\n getAnnouncementText?: (route: State) => string;\n}\n\nexport function createRouteAnnouncer(\n router: Router,\n options?: RouteAnnouncerOptions,\n): { destroy: () => void } {\n const prefix = options?.prefix ?? \"Navigated to \";\n const getCustomText = options?.getAnnouncementText;\n\n let isInitialNavigation = true;\n let isReady = false;\n let isDestroyed = false;\n let lastAnnouncedText = \"\";\n let pendingText: string | null = null;\n let clearTimeoutId: ReturnType<typeof setTimeout> | undefined;\n\n const announcer = getOrCreateAnnouncer();\n\n const doAnnounce = (text: string, h1: HTMLElement | null): void => {\n lastAnnouncedText = text;\n clearTimeout(clearTimeoutId);\n announcer.textContent = text;\n clearTimeoutId = setTimeout(() => {\n announcer.textContent = \"\";\n lastAnnouncedText = \"\";\n }, CLEAR_DELAY);\n\n manageFocus(h1);\n };\n\n // Safari-ready delay: announcing before VoiceOver wires up the aria-live region\n // causes the first announcement to be silently dropped. Wait SAFARI_READY_DELAY ms\n // before marking the announcer \"ready\" — any navigation during that window is\n // buffered in pendingText and flushed once the delay expires.\n const safariTimeoutId = setTimeout(() => {\n isReady = true;\n\n if (pendingText !== null && !isDestroyed) {\n const text = pendingText;\n\n pendingText = null;\n doAnnounce(text, document.querySelector<HTMLElement>(\"h1\"));\n }\n }, SAFARI_READY_DELAY);\n\n const unsubscribe = router.subscribe(({ route }) => {\n if (isInitialNavigation) {\n isInitialNavigation = false;\n\n return;\n }\n\n // Double rAF: waits for two paint frames so the incoming route's DOM\n // (including the new <h1>) is fully rendered before resolveText reads it.\n // Single rAF fires before the new route's template has been attached,\n // which would cause resolveText to pick up the OLD h1 or fall back to\n // document.title / route.name prematurely.\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n if (isDestroyed) {\n return;\n }\n\n const h1 = document.querySelector<HTMLElement>(\"h1\");\n const text = resolveText(route, prefix, getCustomText, h1);\n\n if (!text || text === lastAnnouncedText) {\n return;\n }\n\n if (!isReady) {\n // Defer announcement until Safari-ready window elapses (see safariTimeoutId).\n pendingText = text;\n\n return;\n }\n\n doAnnounce(text, h1);\n });\n });\n });\n\n return {\n destroy() {\n isDestroyed = true;\n unsubscribe();\n clearTimeout(clearTimeoutId);\n clearTimeout(safariTimeoutId);\n removeAnnouncer();\n },\n };\n}\n\nfunction getOrCreateAnnouncer(): HTMLElement {\n const existing = document.querySelector<HTMLElement>(`[${ANNOUNCER_ATTR}]`);\n\n if (existing) {\n return existing;\n }\n\n const element = document.createElement(\"div\");\n\n element.setAttribute(\"style\", VISUALLY_HIDDEN);\n element.setAttribute(\"aria-live\", \"assertive\");\n element.setAttribute(\"aria-atomic\", \"true\");\n element.setAttribute(ANNOUNCER_ATTR, \"\");\n\n document.body.prepend(element);\n\n return element;\n}\n\nfunction removeAnnouncer(): void {\n document.querySelector(`[${ANNOUNCER_ATTR}]`)?.remove();\n}\n\nfunction resolveText(\n route: State,\n prefix: string,\n getCustomText: ((route: State) => string) | undefined,\n h1: HTMLElement | null,\n): string {\n if (getCustomText) {\n return getCustomText(route);\n }\n\n const h1Text = h1?.textContent.trim() ?? \"\";\n const routeName = route.name.startsWith(INTERNAL_ROUTE_PREFIX)\n ? \"\"\n : route.name;\n const rawText =\n h1Text || document.title || routeName || globalThis.location.pathname;\n\n return `${prefix}${rawText}`;\n}\n\nfunction manageFocus(h1: HTMLElement | null): void {\n if (!h1) {\n return;\n }\n\n if (!h1.hasAttribute(\"tabindex\")) {\n h1.setAttribute(\"tabindex\", \"-1\");\n }\n\n h1.focus({ preventScroll: true });\n}\n","import type { Router, State } from \"@real-router/core\";\n\nconst STORAGE_KEY = \"real-router:scroll\";\n\nconst NOOP_INSTANCE: { destroy: () => void } = Object.freeze({\n destroy: () => {\n /* no-op */\n },\n});\n\nexport type ScrollRestorationMode = \"restore\" | \"top\" | \"manual\";\n\nexport interface ScrollRestorationOptions {\n mode?: ScrollRestorationMode | undefined;\n anchorScrolling?: boolean | undefined;\n scrollContainer?: (() => HTMLElement | null) | undefined;\n}\n\ninterface NavigationContext {\n direction?: \"forward\" | \"back\" | \"unknown\";\n navigationType?: \"push\" | \"replace\" | \"traverse\" | \"reload\";\n}\n\nexport function createScrollRestoration(\n router: Router,\n options?: ScrollRestorationOptions,\n): { destroy: () => void } {\n if (typeof globalThis.window === \"undefined\") {\n return NOOP_INSTANCE;\n }\n\n const mode = options?.mode ?? \"restore\";\n\n // mode \"manual\" = utility does nothing. Don't flip history.scrollRestoration,\n // don't subscribe, don't register pagehide — leave the browser's native\n // auto-restore intact for the app to override if it wants to.\n if (mode === \"manual\") {\n return NOOP_INSTANCE;\n }\n\n const anchorEnabled = options?.anchorScrolling ?? true;\n const getContainer = options?.scrollContainer;\n\n const prevScrollRestoration = history.scrollRestoration;\n\n try {\n history.scrollRestoration = \"manual\";\n } catch {\n // Ignore — some embedded contexts may reject the assignment.\n }\n\n // Resolve the container lazily on every event so containers mounted AFTER\n // the provider still get correct scroll handling. Falls back to window when\n // the getter is absent or returns null (pre-mount).\n const readPos = (): number => {\n const element = getContainer?.();\n\n return element ? element.scrollTop : globalThis.scrollY;\n };\n\n const writePos = (top: number): void => {\n const element = getContainer?.();\n\n if (element) {\n element.scrollTop = top;\n } else {\n globalThis.scrollTo(0, top);\n }\n };\n\n const scrollToHashOrTop = (): void => {\n const hash = globalThis.location.hash;\n\n if (anchorEnabled && hash.length > 1) {\n // location.hash is percent-encoded; ids in the DOM are the raw string.\n // Decode for the match. Fall back to the raw slice if the hash contains\n // a malformed escape sequence (decodeURIComponent throws on those).\n let id: string;\n\n try {\n id = decodeURIComponent(hash.slice(1));\n } catch {\n id = hash.slice(1);\n }\n\n // eslint-disable-next-line unicorn/prefer-query-selector -- ids may contain CSS-unsafe chars\n const element = document.getElementById(id);\n\n if (element) {\n element.scrollIntoView();\n\n return;\n }\n }\n\n writePos(0);\n };\n\n let destroyed = false;\n\n const unsubscribe = router.subscribe(({ route, previousRoute }) => {\n const nav = (route.context as { navigation?: NavigationContext })\n .navigation;\n\n // Browsers dispatch reload as the initial navigation after refresh, so\n // previousRoute is undefined and capture is naturally skipped. The\n // pre-refresh position was already persisted via pagehide.\n if (previousRoute) {\n putPos(keyOf(previousRoute), readPos());\n }\n\n // Single rAF so DOM is committed before we read anchors / write scroll.\n // Guard against destroy() racing with the callback.\n requestAnimationFrame(() => {\n if (destroyed) {\n return;\n }\n\n if (mode === \"top\" || !nav) {\n scrollToHashOrTop();\n\n return;\n }\n\n if (nav.navigationType === \"replace\") {\n return;\n }\n\n if (\n nav.direction === \"back\" ||\n nav.navigationType === \"traverse\" ||\n nav.navigationType === \"reload\"\n ) {\n writePos(loadStore()[keyOf(route)] ?? 0);\n\n return;\n }\n\n scrollToHashOrTop();\n });\n });\n\n const onPageHide = (): void => {\n const current = router.getState();\n\n if (current) {\n putPos(keyOf(current), readPos());\n }\n };\n\n globalThis.addEventListener(\"pagehide\", onPageHide);\n\n return {\n destroy: () => {\n if (destroyed) {\n return;\n }\n\n destroyed = true;\n unsubscribe();\n globalThis.removeEventListener(\"pagehide\", onPageHide);\n\n try {\n history.scrollRestoration = prevScrollRestoration;\n } catch {\n // Ignore.\n }\n },\n };\n}\n\nfunction keyOf(state: State): string {\n return `${state.name}:${canonicalJson(state.params)}`;\n}\n\nfunction loadStore(): Record<string, number> {\n try {\n const raw = sessionStorage.getItem(STORAGE_KEY);\n\n return raw ? (JSON.parse(raw) as Record<string, number>) : {};\n } catch {\n return {};\n }\n}\n\nfunction putPos(key: string, pos: number): void {\n try {\n const store = loadStore();\n\n store[key] = pos;\n sessionStorage.setItem(STORAGE_KEY, JSON.stringify(store));\n } catch {\n // Ignore quota / security errors.\n }\n}\n\nfunction canonicalJson(value: unknown): string {\n return JSON.stringify(value, canonicalReplacer);\n}\n\nfunction canonicalReplacer(_key: string, val: unknown): unknown {\n if (val !== null && typeof val === \"object\" && !Array.isArray(val)) {\n const sorted: Record<string, unknown> = {};\n // eslint-disable-next-line unicorn/no-array-sort -- ng-packagr uses pre-ES2023 lib; toSorted unavailable\n const keys = Object.keys(val as Record<string, unknown>).sort(\n (left: string, right: string) => left.localeCompare(right),\n );\n\n for (const key of keys) {\n sorted[key] = (val as Record<string, unknown>)[key];\n }\n\n return sorted;\n }\n\n return val;\n}\n","import type { Router, Params } from \"@real-router/core\";\n\nexport function shouldNavigate(evt: MouseEvent): boolean {\n return (\n evt.button === 0 &&\n !evt.metaKey &&\n !evt.altKey &&\n !evt.ctrlKey &&\n !evt.shiftKey\n );\n}\n\ntype BuildUrlFn = (name: string, params: Params) => string | undefined;\n\nexport function buildHref(\n router: Router,\n routeName: string,\n routeParams: Params,\n): string | undefined {\n try {\n const buildUrl = router.buildUrl as BuildUrlFn | undefined;\n\n if (buildUrl) {\n const url = buildUrl(routeName, routeParams);\n\n if (url !== undefined) {\n return url;\n }\n }\n\n return router.buildPath(routeName, routeParams);\n } catch {\n console.error(\n `[real-router] Route \"${routeName}\" is not defined. The element will render without an href attribute.`,\n );\n\n return undefined;\n }\n}\n\nfunction parseTokens(value: string | undefined): string[] {\n return value ? (value.match(/\\S+/g) ?? []) : [];\n}\n\nexport function buildActiveClassName(\n isActive: boolean,\n activeClassName: string | undefined,\n baseClassName: string | undefined,\n): string | undefined {\n if (isActive && activeClassName) {\n const activeTokens = parseTokens(activeClassName);\n\n if (activeTokens.length === 0) {\n return baseClassName ?? undefined;\n }\n if (!baseClassName) {\n return activeTokens.join(\" \");\n }\n\n const baseTokens = parseTokens(baseClassName);\n const seen = new Set(baseTokens);\n\n for (const token of activeTokens) {\n if (!seen.has(token)) {\n seen.add(token);\n baseTokens.push(token);\n }\n }\n\n return baseTokens.join(\" \");\n }\n\n return baseClassName ?? undefined;\n}\n\nexport function shallowEqual(\n prev: object | undefined,\n next: object | undefined,\n): boolean {\n if (Object.is(prev, next)) {\n return true;\n }\n if (!prev || !next) {\n return false;\n }\n\n const prevKeys = Object.keys(prev);\n\n if (prevKeys.length !== Object.keys(next).length) {\n return false;\n }\n\n const prevRecord = prev as Record<string, unknown>;\n const nextRecord = next as Record<string, unknown>;\n\n for (const key of prevKeys) {\n if (!Object.is(prevRecord[key], nextRecord[key])) {\n return false;\n }\n }\n\n return true;\n}\n\nexport function applyLinkA11y(element: HTMLElement | null | undefined): void {\n if (!element) {\n return;\n }\n if (\n element instanceof HTMLAnchorElement ||\n element instanceof HTMLButtonElement\n ) {\n return;\n }\n if (!element.hasAttribute(\"role\")) {\n element.setAttribute(\"role\", \"link\");\n }\n if (!element.hasAttribute(\"tabindex\")) {\n element.setAttribute(\"tabindex\", \"0\");\n }\n}\n","import { createActiveRouteSource } from \"@real-router/sources\";\nimport { useSyncExternalStore } from \"react\";\n\nimport { useRouter } from \"./useRouter\";\n\nimport type { Params } from \"@real-router/core\";\n\nexport function useIsActiveRoute(\n routeName: string,\n params?: Params,\n strict = false,\n ignoreQueryParams = true,\n): boolean {\n const router = useRouter();\n\n // createActiveRouteSource is per-router + canonical-args cached in\n // @real-router/sources, so passing params by reference is safe — equivalent\n // param shapes hit the same cache entry regardless of key order.\n const store = createActiveRouteSource(router, routeName, params, {\n strict,\n ignoreQueryParams,\n });\n\n return useSyncExternalStore(\n store.subscribe,\n store.getSnapshot,\n store.getSnapshot,\n );\n}\n","import { createDismissableError } from \"@real-router/sources\";\nimport { useEffect, useRef, useSyncExternalStore } from \"react\";\n\nimport { useRouter } from \"../hooks/useRouter\";\n\nimport type { RouterError, State } from \"@real-router/core\";\nimport type { ReactNode, JSX } from \"react\";\n\nexport interface RouterErrorBoundaryProps {\n readonly children: ReactNode;\n readonly fallback: (error: RouterError, resetError: () => void) => ReactNode;\n readonly onError?: (\n error: RouterError,\n toRoute: State | null,\n fromRoute: State | null,\n ) => void;\n}\n\nexport function RouterErrorBoundary({\n children,\n fallback,\n onError,\n}: RouterErrorBoundaryProps): JSX.Element {\n const router = useRouter();\n const store = createDismissableError(router);\n const snapshot = useSyncExternalStore(\n store.subscribe,\n store.getSnapshot,\n store.getSnapshot,\n );\n\n const onErrorRef = useRef(onError);\n\n // eslint-disable-next-line @eslint-react/refs -- \"latest ref\" pattern: sync callback to ref to avoid effect re-runs\n onErrorRef.current = onError;\n\n useEffect(() => {\n if (snapshot.error) {\n onErrorRef.current?.(\n snapshot.error,\n snapshot.toRoute,\n snapshot.fromRoute,\n );\n }\n // eslint-disable-next-line @eslint-react/exhaustive-deps -- onError tracked via ref, snapshot fields accessed inside callback\n }, [snapshot.version]);\n\n return (\n <>\n {children}\n {snapshot.error ? fallback(snapshot.error, snapshot.resetError) : null}\n </>\n );\n}\n","// packages/react/src/hooks/useNavigator.tsx\n\nimport { useContext } from \"react\";\n\nimport { NavigatorContext } from \"../context\";\n\nimport type { Navigator } from \"@real-router/core\";\n\nexport const useNavigator = (): Navigator => {\n const navigator = useContext(NavigatorContext);\n\n if (!navigator) {\n throw new Error(\"useNavigator must be used within a RouterProvider\");\n }\n\n return navigator;\n};\n","import { getPluginApi } from \"@real-router/core/api\";\nimport { getRouteUtils } from \"@real-router/route-utils\";\n\nimport { useRouter } from \"./useRouter\";\n\nimport type { RouteUtils } from \"@real-router/route-utils\";\n\n/**\n * Returns a pre-computed {@link RouteUtils} instance for the current router.\n *\n * `getRouteUtils` is WeakMap-cached per `RouteTreeNode` inside\n * `@real-router/route-utils`, so the same router always returns the same\n * `RouteUtils` instance across renders — no local cache needed in the adapter.\n *\n * @returns RouteUtils instance with pre-computed chains and siblings\n *\n * @example\n * ```tsx\n * const utils = useRouteUtils();\n *\n * utils.getChain(\"users.profile\");\n * // → [\"users\", \"users.profile\"]\n *\n * utils.getSiblings(\"users\");\n * // → [\"admin\"]\n *\n * utils.isDescendantOf(\"users.profile\", \"users\");\n * // → true\n * ```\n */\nexport const useRouteUtils = (): RouteUtils => {\n const router = useRouter();\n\n return getRouteUtils(getPluginApi(router).getTree());\n};\n","// packages/react/src/hooks/useRoute.tsx\n\nimport { useContext } from \"react\";\n\nimport { RouteContext } from \"../context\";\n\nimport type { RouteContext as RouteContextType } from \"../types\";\nimport type { Params } from \"@real-router/core\";\n\nexport const useRoute = <P extends Params = Params>(): RouteContextType<P> => {\n const routeContext = useContext(RouteContext);\n\n if (!routeContext) {\n throw new Error(\"useRoute must be used within a RouteProvider\");\n }\n\n return routeContext as RouteContextType<P>;\n};\n","import { getTransitionSource } from \"@real-router/sources\";\nimport { useSyncExternalStore } from \"react\";\n\nimport { useRouter } from \"./useRouter\";\n\nimport type { RouterTransitionSnapshot } from \"@real-router/sources\";\n\nexport function useRouterTransition(): RouterTransitionSnapshot {\n const router = useRouter();\n const store = getTransitionSource(router);\n\n return useSyncExternalStore(\n store.subscribe,\n store.getSnapshot,\n store.getSnapshot,\n );\n}\n","import { getNavigator } from \"@real-router/core\";\nimport { createRouteSource } from \"@real-router/sources\";\nimport { useEffect, useMemo, useSyncExternalStore } from \"react\";\n\nimport { NavigatorContext, RouteContext, RouterContext } from \"./context\";\nimport { createRouteAnnouncer, createScrollRestoration } from \"./dom-utils\";\n\nimport type { ScrollRestorationOptions } from \"./dom-utils\";\nimport type { Router } from \"@real-router/core\";\nimport type { FC, ReactNode } from \"react\";\n\nexport interface RouteProviderProps {\n router: Router;\n children: ReactNode;\n announceNavigation?: boolean;\n scrollRestoration?: ScrollRestorationOptions;\n}\n\nexport const RouterProvider: FC<RouteProviderProps> = ({\n router,\n children,\n announceNavigation,\n scrollRestoration,\n}) => {\n useEffect(() => {\n if (!announceNavigation) {\n return;\n }\n\n const announcer = createRouteAnnouncer(router);\n\n return () => {\n announcer.destroy();\n };\n }, [announceNavigation, router]);\n\n // Primitive deps so inline `{ mode: \"restore\" }` doesn't thrash on every\n // render. scrollContainer is a getter invoked lazily on every event inside\n // the utility — swapping its reference doesn't change the resolved element,\n // so we intentionally omit it from deps to keep inline getters stable.\n const srMode = scrollRestoration?.mode;\n const srAnchor = scrollRestoration?.anchorScrolling;\n const srEnabled = scrollRestoration !== undefined;\n\n useEffect(() => {\n if (!srEnabled) {\n return;\n }\n\n const sr = createScrollRestoration(router, {\n mode: srMode,\n anchorScrolling: srAnchor,\n // srEnabled check above guarantees scrollRestoration is defined.\n scrollContainer: scrollRestoration.scrollContainer,\n });\n\n return () => {\n sr.destroy();\n };\n // scrollRestoration (for scrollContainer) omitted — see comment above.\n // eslint-disable-next-line @eslint-react/exhaustive-deps\n }, [router, srEnabled, srMode, srAnchor]);\n\n const navigator = useMemo(() => getNavigator(router), [router]);\n\n // useSyncExternalStore manages the router subscription lifecycle:\n // subscribe connects to router on first listener, unsubscribes on last.\n // This is Strict Mode safe — no useEffect cleanup needed.\n const store = useMemo(() => createRouteSource(router), [router]);\n // Use snapshot reference directly. createRouteSource via stabilizeState\n // returns the SAME snapshot reference when route.path is unchanged, so\n // useMemo below sees stable deps for idempotent navigations and\n // RouteContext consumers do not re-render.\n const snapshot = useSyncExternalStore(\n store.subscribe,\n store.getSnapshot,\n store.getSnapshot, // SSR: router returns same state on server and client\n );\n\n const routeContextValue = useMemo(\n () => ({\n navigator,\n route: snapshot.route,\n previousRoute: snapshot.previousRoute,\n }),\n [navigator, snapshot],\n );\n\n return (\n <RouterContext.Provider value={router}>\n <NavigatorContext.Provider value={navigator}>\n <RouteContext.Provider value={routeContextValue}>\n {children}\n </RouteContext.Provider>\n </NavigatorContext.Provider>\n </RouterContext.Provider>\n );\n};\n"],"mappings":"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"}
|
package/dist/cjs/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { a as useNavigator, c as RouterErrorBoundaryProps, i as useRouteUtils, l as LinkProps, n as useRouteNode, o as useRouter, r as useRoute, s as RouterErrorBoundary, t as useRouterTransition } from "./useRouterTransition-BlTJ1uz3.js";
|
|
2
|
-
import { n as Link, t as RouterProvider } from "./RouterProvider-
|
|
2
|
+
import { n as Link, t as RouterProvider } from "./RouterProvider-BFSblUxR.js";
|
|
3
3
|
import { ReactElement, ReactNode } from "react";
|
|
4
4
|
import { Navigator } from "@real-router/core";
|
|
5
5
|
import { RouterTransitionSnapshot } from "@real-router/sources";
|
|
@@ -8,7 +8,7 @@ import { RouterTransitionSnapshot } from "@real-router/sources";
|
|
|
8
8
|
interface RouteViewProps {
|
|
9
9
|
/** Route tree node name to subscribe to. "" for root. */
|
|
10
10
|
readonly nodeName: string;
|
|
11
|
-
/** <RouteView.Match
|
|
11
|
+
/** <RouteView.Match>, <RouteView.Self>, and <RouteView.NotFound> elements. */
|
|
12
12
|
readonly children: ReactNode;
|
|
13
13
|
}
|
|
14
14
|
interface MatchProps {
|
|
@@ -23,6 +23,17 @@ interface MatchProps {
|
|
|
23
23
|
/** Content to render when matched. */
|
|
24
24
|
readonly children: ReactNode;
|
|
25
25
|
}
|
|
26
|
+
interface SelfProps {
|
|
27
|
+
/**
|
|
28
|
+
* Fallback content to show while children are suspended.
|
|
29
|
+
*
|
|
30
|
+
* Symmetric with `<RouteView.Match fallback>` — wraps children in
|
|
31
|
+
* `<Suspense>` when defined.
|
|
32
|
+
*/
|
|
33
|
+
readonly fallback?: ReactNode;
|
|
34
|
+
/** Content to render when the active route name equals the parent RouteView's nodeName. */
|
|
35
|
+
readonly children: ReactNode;
|
|
36
|
+
}
|
|
26
37
|
interface NotFoundProps {
|
|
27
38
|
/** Content to render on UNKNOWN_ROUTE. */
|
|
28
39
|
readonly children: ReactNode;
|
|
@@ -33,6 +44,10 @@ declare function Match(_props: MatchProps): null;
|
|
|
33
44
|
declare namespace Match {
|
|
34
45
|
var displayName: string;
|
|
35
46
|
}
|
|
47
|
+
declare function Self(_props: SelfProps): null;
|
|
48
|
+
declare namespace Self {
|
|
49
|
+
var displayName: string;
|
|
50
|
+
}
|
|
36
51
|
declare function NotFound(_props: NotFoundProps): null;
|
|
37
52
|
declare namespace NotFound {
|
|
38
53
|
var displayName: string;
|
|
@@ -48,8 +63,9 @@ declare namespace RouteViewRoot {
|
|
|
48
63
|
}
|
|
49
64
|
declare const RouteView: typeof RouteViewRoot & {
|
|
50
65
|
Match: typeof Match;
|
|
66
|
+
Self: typeof Self;
|
|
51
67
|
NotFound: typeof NotFound;
|
|
52
68
|
};
|
|
53
69
|
//#endregion
|
|
54
|
-
export { Link, type LinkProps, type Navigator, RouteView, type MatchProps as RouteViewMatchProps, type NotFoundProps as RouteViewNotFoundProps, type RouteViewProps, RouterErrorBoundary, type RouterErrorBoundaryProps, RouterProvider, type RouterTransitionSnapshot, useNavigator, useRoute, useRouteNode, useRouteUtils, useRouter, useRouterTransition };
|
|
70
|
+
export { Link, type LinkProps, type Navigator, RouteView, type MatchProps as RouteViewMatchProps, type NotFoundProps as RouteViewNotFoundProps, type RouteViewProps, type SelfProps as RouteViewSelfProps, RouterErrorBoundary, type RouterErrorBoundaryProps, RouterProvider, type RouterTransitionSnapshot, useNavigator, useRoute, useRouteNode, useRouteUtils, useRouter, useRouterTransition };
|
|
55
71
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/cjs/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/components/modern/RouteView/types.ts","../../src/components/modern/RouteView/components.tsx","../../src/components/modern/RouteView/RouteView.tsx"],"mappings":";;;;;;;UAEiB,cAAA;;WAEN,QAAA;;WAEA,QAAA,EAAU,SAAA;AAAA;AAAA,UAGJ,UAAA;EAPc;EAAA,SASpB,OAAA;EALmB;EAAA,SAOnB,KAAA;EAPA;EAAA,SASA,SAAA;EATmB;EAAA,SAWnB,QAAA,GAAW,SAAA;EARL;EAAA,SAUN,QAAA,EAAU,SAAA;AAAA;AAAA,UAGJ,
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/components/modern/RouteView/types.ts","../../src/components/modern/RouteView/components.tsx","../../src/components/modern/RouteView/RouteView.tsx"],"mappings":";;;;;;;UAEiB,cAAA;;WAEN,QAAA;;WAEA,QAAA,EAAU,SAAA;AAAA;AAAA,UAGJ,UAAA;EAPc;EAAA,SASpB,OAAA;EALmB;EAAA,SAOnB,KAAA;EAPA;EAAA,SASA,SAAA;EATmB;EAAA,SAWnB,QAAA,GAAW,SAAA;EARL;EAAA,SAUN,QAAA,EAAU,SAAA;AAAA;AAAA,UAGJ,SAAA;EAXN;;;;;;EAAA,SAkBA,QAAA,GAAW,SAAA;EAVQ;EAAA,SAYnB,QAAA,EAAU,SAAA;AAAA;AAAA,UAGJ,aAAA;;WAEN,QAAA,EAAU,SAAA;AAAA;;;iBClCL,KAAA,CAAM,MAAA,EAAQ,UAAA;AAAA,kBAAd,KAAA;EAAA,IAAK,WAAA;AAAA;AAAA,iBAML,IAAA,CAAK,MAAA,EAAQ,SAAA;AAAA,kBAAb,IAAA;EAAA,IAAI,WAAA;AAAA;AAAA,iBAMJ,QAAA,CAAS,MAAA,EAAQ,aAAA;AAAA,kBAAjB,QAAA;EAAA,IAAQ,WAAA;AAAA;;;iBCLf,aAAA,CAAA;EACP,QAAA;EACA;AAAA,GACC,QAAA,CAAS,cAAA,IAAkB,YAAA;AAAA,kBAHrB,aAAA;EAAA,IAAa,WAAA;AAAA;AAAA,cA0CT,SAAA,SAAS,aAAA"}
|
package/dist/cjs/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./RouterProvider-
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./RouterProvider-BOWw6Z_i.js`),t=require(`./Link-CFGcNhCQ.js`);let n=require(`react`),r=require(`@real-router/core`),i=require(`@real-router/route-utils`),a=require(`react/jsx-runtime`);function o(e){return null}o.displayName=`RouteView.Match`;function s(e){return null}s.displayName=`RouteView.Self`;function c(e){return null}c.displayName=`RouteView.NotFound`;function l(e,t,n){return t===``?!1:n?e===t:(0,i.startsWithSegment)(e,t)}function u(e,t){for(let r of n.Children.toArray(e))(0,n.isValidElement)(r)&&(r.type===o||r.type===s||r.type===c?t.push(r):u(r.props.children,t))}function d(e,t,r,i,o){let s=o===void 0?e:(0,a.jsx)(n.Suspense,{fallback:o,children:e});return r?(0,a.jsx)(n.Activity,{mode:i,children:s},t):(0,a.jsx)(n.Fragment,{children:s},t)}function f(e,t){return e.type===c?(t.notFoundChildren=e.props.children,!0):e.type===s?(t.selfFound||=(t.selfChildren=e.props.children,t.selfFallback=e.props.fallback,!0),!0):!1}function p(e,t,n,r,i){let{segment:a,exact:o=!1,keepAlive:s=!1,fallback:c}=e.props,u=n?`${n}.${a}`:a;return!i&&l(t,u,o)?(r.add(u),{rendered:d(e.props.children,u,s,`visible`,c),matched:!0}):s&&r.has(u)?{rendered:d(e.props.children,u,s,`hidden`,c),matched:!1}:{rendered:null,matched:!1}}function m(e,t,i,o){if(o.selfFound&&t===i){e.push(d(o.selfChildren,`__route-view-self__`,!1,`visible`,o.selfFallback));return}t===r.UNKNOWN_ROUTE&&o.notFoundChildren!==null&&e.push((0,a.jsx)(n.Fragment,{children:o.notFoundChildren},`__route-view-not-found__`))}function h(e,t,n,r){let i={selfChildren:null,selfFallback:void 0,selfFound:!1,notFoundChildren:null},a=!1,o=[];for(let s of e){if(f(s,i))continue;let e=p(s,t,n,r,a);e.matched&&(a=!0),e.rendered!==null&&o.push(e.rendered)}return a||m(o,t,n,i),{rendered:o,activeMatchFound:a}}function g({nodeName:t,children:r}){let{route:i}=e.m(t),o=(0,n.useRef)(null);o.current??=new Set;let s=(0,n.useMemo)(()=>{let e=[];return u(r,e),e},[r]);if(!i)return null;let{rendered:c}=h(s,i.name,t,o.current);return c.length>0?(0,a.jsx)(a.Fragment,{children:c}):null}g.displayName=`RouteView`;const _=Object.assign(g,{Match:o,Self:s,NotFound:c});exports.Link=t.t,exports.RouteView=_,exports.RouterErrorBoundary=e.o,exports.RouterProvider=e.t,exports.useNavigator=e.a,exports.useRoute=e.r,exports.useRouteNode=e.m,exports.useRouteUtils=e.i,exports.useRouter=e.h,exports.useRouterTransition=e.n;
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/dist/cjs/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["Children","Suspense","Activity","Fragment","UNKNOWN_ROUTE","useRouteNode"],"sources":["../../src/components/modern/RouteView/components.tsx","../../src/components/modern/RouteView/helpers.tsx","../../src/components/modern/RouteView/RouteView.tsx"],"sourcesContent":["import type { MatchProps, NotFoundProps } from \"./types\";\n\nexport function Match(_props: MatchProps): null {\n return null;\n}\n\nMatch.displayName = \"RouteView.Match\";\n\nexport function NotFound(_props: NotFoundProps): null {\n return null;\n}\n\nNotFound.displayName = \"RouteView.NotFound\";\n","import { UNKNOWN_ROUTE } from \"@real-router/core\";\nimport { startsWithSegment } from \"@real-router/route-utils\";\nimport { Activity, Children, Fragment, Suspense, isValidElement } from \"react\";\n\nimport { Match, NotFound } from \"./components\";\n\nimport type { MatchProps, NotFoundProps } from \"./types\";\nimport type { ReactElement, ReactNode } from \"react\";\n\nfunction isSegmentMatch(\n routeName: string,\n fullSegmentName: string,\n exact: boolean,\n): boolean {\n if (fullSegmentName === \"\") {\n return false;\n }\n\n if (exact) {\n return routeName === fullSegmentName;\n }\n\n return startsWithSegment(routeName, fullSegmentName);\n}\n\nexport function collectElements(\n children: ReactNode,\n result: ReactElement[],\n): void {\n // eslint-disable-next-line @eslint-react/no-children-to-array\n for (const child of Children.toArray(children)) {\n if (!isValidElement(child)) {\n continue;\n }\n\n if (child.type === Match || child.type === NotFound) {\n result.push(child);\n } else {\n collectElements(\n (child.props as { readonly children: ReactNode }).children,\n result,\n );\n }\n }\n}\n\nfunction renderMatchElement(\n matchChildren: ReactNode,\n fullSegmentName: string,\n keepAlive: boolean,\n mode: \"visible\" | \"hidden\",\n fallback?: ReactNode,\n): ReactElement {\n const content =\n fallback === undefined ? (\n matchChildren\n ) : (\n <Suspense fallback={fallback}>{matchChildren}</Suspense>\n );\n\n if (keepAlive) {\n return (\n <Activity mode={mode} key={fullSegmentName}>\n {content}\n </Activity>\n );\n }\n\n return <Fragment key={fullSegmentName}>{content}</Fragment>;\n}\n\nexport function buildRenderList(\n elements: ReactElement[],\n routeName: string,\n nodeName: string,\n hasBeenActivated: Set<string>,\n): { rendered: ReactElement[]; activeMatchFound: boolean } {\n let notFoundChildren: ReactNode = null;\n let activeMatchFound = false;\n const rendered: ReactElement[] = [];\n\n for (const child of elements) {\n if (child.type === NotFound) {\n notFoundChildren = (child.props as NotFoundProps).children;\n continue;\n }\n\n const {\n segment,\n exact = false,\n keepAlive = false,\n fallback,\n } = child.props as MatchProps;\n const fullSegmentName = nodeName ? `${nodeName}.${segment}` : segment;\n const isActive =\n !activeMatchFound && isSegmentMatch(routeName, fullSegmentName, exact);\n\n if (isActive) {\n activeMatchFound = true;\n hasBeenActivated.add(fullSegmentName);\n rendered.push(\n renderMatchElement(\n (child.props as MatchProps).children,\n fullSegmentName,\n keepAlive,\n \"visible\",\n fallback,\n ),\n );\n } else if (keepAlive && hasBeenActivated.has(fullSegmentName)) {\n rendered.push(\n renderMatchElement(\n (child.props as MatchProps).children,\n fullSegmentName,\n keepAlive,\n \"hidden\",\n fallback,\n ),\n );\n }\n }\n\n if (\n !activeMatchFound &&\n routeName === UNKNOWN_ROUTE &&\n notFoundChildren !== null\n ) {\n rendered.push(\n <Fragment key=\"__route-view-not-found__\">{notFoundChildren}</Fragment>,\n );\n }\n\n return { rendered, activeMatchFound };\n}\n","import { useMemo, useRef } from \"react\";\n\nimport { Match, NotFound } from \"./components\";\nimport { buildRenderList, collectElements } from \"./helpers\";\nimport { useRouteNode } from \"../../../hooks/useRouteNode\";\n\nimport type { RouteViewProps } from \"./types\";\nimport type { ReactElement } from \"react\";\n\nfunction RouteViewRoot({\n nodeName,\n children,\n}: Readonly<RouteViewProps>): ReactElement | null {\n const { route } = useRouteNode(nodeName);\n const hasBeenActivatedRef = useRef<Set<string> | null>(null);\n\n // eslint-disable-next-line @eslint-react/refs -- lazy init: assign once when null to avoid `new Set()` allocation on every render\n hasBeenActivatedRef.current ??= new Set();\n\n // Skip the Children.toArray + collectElements traversal when children\n // reference is unchanged. children only changes when the parent re-renders\n // with a new ReactNode, so this caches the steady-state.\n const elements = useMemo(() => {\n const collected: ReactElement[] = [];\n\n collectElements(children, collected);\n\n return collected;\n }, [children]);\n\n if (!route) {\n return null;\n }\n\n const { rendered } = buildRenderList(\n elements,\n route.name,\n nodeName,\n // eslint-disable-next-line @eslint-react/refs -- stable Set ref read for keepAlive tracking (never reassigned)\n hasBeenActivatedRef.current,\n );\n\n if (rendered.length > 0) {\n return <>{rendered}</>;\n }\n\n return null;\n}\n\nRouteViewRoot.displayName = \"RouteView\";\n\nexport const RouteView = Object.assign(RouteViewRoot, { Match, NotFound });\n\nexport type {\n RouteViewProps,\n MatchProps as RouteViewMatchProps,\n NotFoundProps as RouteViewNotFoundProps,\n} from \"./types\";\n"],"mappings":"8QAEA,SAAgB,EAAM,EAA0B,CAC9C,OAAO,KAGT,EAAM,YAAc,kBAEpB,SAAgB,EAAS,EAA6B,CACpD,OAAO,KAGT,EAAS,YAAc,qBCHvB,SAAS,EACP,EACA,EACA,EACS,CAST,OARI,IAAoB,GACf,GAGL,EACK,IAAc,GAGvB,EAAA,EAAA,mBAAyB,EAAW,EAAgB,CAGtD,SAAgB,EACd,EACA,EACM,CAEN,IAAK,IAAM,KAASA,EAAAA,SAAS,QAAQ,EAAS,EACxC,EAAA,EAAA,gBAAgB,EAAM,GAItB,EAAM,OAAS,GAAS,EAAM,OAAS,EACzC,EAAO,KAAK,EAAM,CAElB,EACG,EAAM,MAA2C,SAClD,EACD,EAKP,SAAS,EACP,EACA,EACA,EACA,EACA,EACc,CACd,IAAM,EACJ,IAAa,IAAA,GACX,GAEA,EAAA,EAAA,KAACC,EAAAA,SAAD,CAAoB,oBAAW,EAAyB,CAAA,CAW5D,OARI,GAEA,EAAA,EAAA,KAACC,EAAAA,SAAD,CAAgB,gBACb,EACQ,CAFgB,EAEhB,EAIR,EAAA,EAAA,KAACC,EAAAA,SAAD,CAAA,SAAiC,EAAmB,CAArC,EAAqC,CAG7D,SAAgB,EACd,EACA,EACA,EACA,EACyD,CACzD,IAAI,EAA8B,KAC9B,EAAmB,GACjB,EAA2B,EAAE,CAEnC,IAAK,IAAM,KAAS,EAAU,CAC5B,GAAI,EAAM,OAAS,EAAU,CAC3B,EAAoB,EAAM,MAAwB,SAClD,SAGF,GAAM,CACJ,UACA,QAAQ,GACR,YAAY,GACZ,YACE,EAAM,MACJ,EAAkB,EAAW,GAAG,EAAS,GAAG,IAAY,EAE5D,CAAC,GAAoB,EAAe,EAAW,EAAiB,EAAM,EAGtE,EAAmB,GACnB,EAAiB,IAAI,EAAgB,CACrC,EAAS,KACP,EACG,EAAM,MAAqB,SAC5B,EACA,EACA,UACA,EACD,CACF,EACQ,GAAa,EAAiB,IAAI,EAAgB,EAC3D,EAAS,KACP,EACG,EAAM,MAAqB,SAC5B,EACA,EACA,SACA,EACD,CACF,CAcL,MATE,CAAC,GACD,IAAcC,EAAAA,eACd,IAAqB,MAErB,EAAS,MACP,EAAA,EAAA,KAACD,EAAAA,SAAD,CAAA,SAA0C,EAA4B,CAAxD,2BAAwD,CACvE,CAGI,CAAE,WAAU,mBAAkB,CC3HvC,SAAS,EAAc,CACrB,WACA,YACgD,CAChD,GAAM,CAAE,SAAUE,EAAAA,EAAa,EAAS,CAClC,GAAA,EAAA,EAAA,QAAiD,KAAK,CAG5D,EAAoB,UAAY,IAAI,IAKpC,IAAM,GAAA,EAAA,EAAA,aAAyB,CAC7B,IAAM,EAA4B,EAAE,CAIpC,OAFA,EAAgB,EAAU,EAAU,CAE7B,GACN,CAAC,EAAS,CAAC,CAEd,GAAI,CAAC,EACH,OAAO,KAGT,GAAM,CAAE,YAAa,EACnB,EACA,EAAM,KACN,EAEA,EAAoB,QACrB,CAMD,OAJI,EAAS,OAAS,GACb,EAAA,EAAA,KAAA,EAAA,SAAA,CAAA,SAAG,EAAY,CAAA,CAGjB,KAGT,EAAc,YAAc,YAE5B,MAAa,EAAY,OAAO,OAAO,EAAe,CAAE,QAAO,WAAU,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["Children","Suspense","Activity","Fragment","UNKNOWN_ROUTE","useRouteNode"],"sources":["../../src/components/modern/RouteView/components.tsx","../../src/components/modern/RouteView/helpers.tsx","../../src/components/modern/RouteView/RouteView.tsx"],"sourcesContent":["import type { MatchProps, NotFoundProps, SelfProps } from \"./types\";\n\nexport function Match(_props: MatchProps): null {\n return null;\n}\n\nMatch.displayName = \"RouteView.Match\";\n\nexport function Self(_props: SelfProps): null {\n return null;\n}\n\nSelf.displayName = \"RouteView.Self\";\n\nexport function NotFound(_props: NotFoundProps): null {\n return null;\n}\n\nNotFound.displayName = \"RouteView.NotFound\";\n","import { UNKNOWN_ROUTE } from \"@real-router/core\";\nimport { startsWithSegment } from \"@real-router/route-utils\";\nimport { Activity, Children, Fragment, Suspense, isValidElement } from \"react\";\n\nimport { Match, NotFound, Self } from \"./components\";\n\nimport type { MatchProps, NotFoundProps, SelfProps } from \"./types\";\nimport type { ReactElement, ReactNode } from \"react\";\n\ninterface FallbackSlots {\n selfChildren: ReactNode;\n selfFallback: ReactNode | undefined;\n selfFound: boolean;\n notFoundChildren: ReactNode;\n}\n\nfunction isSegmentMatch(\n routeName: string,\n fullSegmentName: string,\n exact: boolean,\n): boolean {\n if (fullSegmentName === \"\") {\n return false;\n }\n\n if (exact) {\n return routeName === fullSegmentName;\n }\n\n return startsWithSegment(routeName, fullSegmentName);\n}\n\nexport function collectElements(\n children: ReactNode,\n result: ReactElement[],\n): void {\n // eslint-disable-next-line @eslint-react/no-children-to-array\n for (const child of Children.toArray(children)) {\n if (!isValidElement(child)) {\n continue;\n }\n\n if (\n child.type === Match ||\n child.type === Self ||\n child.type === NotFound\n ) {\n result.push(child);\n } else {\n collectElements(\n (child.props as { readonly children: ReactNode }).children,\n result,\n );\n }\n }\n}\n\nfunction renderSlotElement(\n slotChildren: ReactNode,\n key: string,\n keepAlive: boolean,\n mode: \"visible\" | \"hidden\",\n fallback?: ReactNode,\n): ReactElement {\n const content =\n fallback === undefined ? (\n slotChildren\n ) : (\n <Suspense fallback={fallback}>{slotChildren}</Suspense>\n );\n\n if (keepAlive) {\n return (\n <Activity mode={mode} key={key}>\n {content}\n </Activity>\n );\n }\n\n return <Fragment key={key}>{content}</Fragment>;\n}\n\nfunction recordFallback(child: ReactElement, slots: FallbackSlots): boolean {\n if (child.type === NotFound) {\n slots.notFoundChildren = (child.props as NotFoundProps).children;\n\n return true;\n }\n\n if (child.type === Self) {\n // First-wins: subsequent <Self> elements are ignored, mirroring NotFound.\n if (!slots.selfFound) {\n slots.selfChildren = (child.props as SelfProps).children;\n slots.selfFallback = (child.props as SelfProps).fallback;\n slots.selfFound = true;\n }\n\n return true;\n }\n\n return false;\n}\n\nfunction processMatch(\n child: ReactElement,\n routeName: string,\n nodeName: string,\n hasBeenActivated: Set<string>,\n alreadyActive: boolean,\n): { rendered: ReactElement | null; matched: boolean } {\n const {\n segment,\n exact = false,\n keepAlive = false,\n fallback,\n } = child.props as MatchProps;\n const fullSegmentName = nodeName ? `${nodeName}.${segment}` : segment;\n const isActive =\n !alreadyActive && isSegmentMatch(routeName, fullSegmentName, exact);\n\n if (isActive) {\n hasBeenActivated.add(fullSegmentName);\n\n return {\n rendered: renderSlotElement(\n (child.props as MatchProps).children,\n fullSegmentName,\n keepAlive,\n \"visible\",\n fallback,\n ),\n matched: true,\n };\n }\n\n if (keepAlive && hasBeenActivated.has(fullSegmentName)) {\n return {\n rendered: renderSlotElement(\n (child.props as MatchProps).children,\n fullSegmentName,\n keepAlive,\n \"hidden\",\n fallback,\n ),\n matched: false,\n };\n }\n\n return { rendered: null, matched: false };\n}\n\nfunction appendFallback(\n rendered: ReactElement[],\n routeName: string,\n nodeName: string,\n slots: FallbackSlots,\n): void {\n if (slots.selfFound && routeName === nodeName) {\n rendered.push(\n renderSlotElement(\n slots.selfChildren,\n \"__route-view-self__\",\n false,\n \"visible\",\n slots.selfFallback,\n ),\n );\n\n return;\n }\n\n if (routeName === UNKNOWN_ROUTE && slots.notFoundChildren !== null) {\n rendered.push(\n <Fragment key=\"__route-view-not-found__\">\n {slots.notFoundChildren}\n </Fragment>,\n );\n }\n}\n\nexport function buildRenderList(\n elements: ReactElement[],\n routeName: string,\n nodeName: string,\n hasBeenActivated: Set<string>,\n): { rendered: ReactElement[]; activeMatchFound: boolean } {\n const slots: FallbackSlots = {\n selfChildren: null,\n selfFallback: undefined,\n selfFound: false,\n notFoundChildren: null,\n };\n let activeMatchFound = false;\n const rendered: ReactElement[] = [];\n\n for (const child of elements) {\n if (recordFallback(child, slots)) {\n continue;\n }\n\n const result = processMatch(\n child,\n routeName,\n nodeName,\n hasBeenActivated,\n activeMatchFound,\n );\n\n if (result.matched) {\n activeMatchFound = true;\n }\n\n if (result.rendered !== null) {\n rendered.push(result.rendered);\n }\n }\n\n if (!activeMatchFound) {\n appendFallback(rendered, routeName, nodeName, slots);\n }\n\n return { rendered, activeMatchFound };\n}\n","import { useMemo, useRef } from \"react\";\n\nimport { Match, NotFound, Self } from \"./components\";\nimport { buildRenderList, collectElements } from \"./helpers\";\nimport { useRouteNode } from \"../../../hooks/useRouteNode\";\n\nimport type { RouteViewProps } from \"./types\";\nimport type { ReactElement } from \"react\";\n\nfunction RouteViewRoot({\n nodeName,\n children,\n}: Readonly<RouteViewProps>): ReactElement | null {\n const { route } = useRouteNode(nodeName);\n const hasBeenActivatedRef = useRef<Set<string> | null>(null);\n\n // eslint-disable-next-line @eslint-react/refs -- lazy init: assign once when null to avoid `new Set()` allocation on every render\n hasBeenActivatedRef.current ??= new Set();\n\n // Skip the Children.toArray + collectElements traversal when children\n // reference is unchanged. children only changes when the parent re-renders\n // with a new ReactNode, so this caches the steady-state.\n const elements = useMemo(() => {\n const collected: ReactElement[] = [];\n\n collectElements(children, collected);\n\n return collected;\n }, [children]);\n\n if (!route) {\n return null;\n }\n\n const { rendered } = buildRenderList(\n elements,\n route.name,\n nodeName,\n // eslint-disable-next-line @eslint-react/refs -- stable Set ref read for keepAlive tracking (never reassigned)\n hasBeenActivatedRef.current,\n );\n\n if (rendered.length > 0) {\n return <>{rendered}</>;\n }\n\n return null;\n}\n\nRouteViewRoot.displayName = \"RouteView\";\n\nexport const RouteView = Object.assign(RouteViewRoot, {\n Match,\n Self,\n NotFound,\n});\n\nexport type {\n RouteViewProps,\n MatchProps as RouteViewMatchProps,\n SelfProps as RouteViewSelfProps,\n NotFoundProps as RouteViewNotFoundProps,\n} from \"./types\";\n"],"mappings":"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"}
|
package/dist/cjs/ink.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./RouterProvider-
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./RouterProvider-BOWw6Z_i.js`);let t=require(`react`),n=require(`react/jsx-runtime`),r=require(`ink`);function i(t,n){return t.routeName===n.routeName&&t.activeStrict===n.activeStrict&&t.ignoreQueryParams===n.ignoreQueryParams&&t.color===n.color&&t.activeColor===n.activeColor&&t.focusColor===n.focusColor&&t.inverse===n.inverse&&t.activeInverse===n.activeInverse&&t.focusInverse===n.focusInverse&&t.id===n.id&&t.autoFocus===n.autoFocus&&t.onSelect===n.onSelect&&t.children===n.children&&e.u(t.routeParams,n.routeParams)&&e.u(t.routeOptions,n.routeOptions)}const a=(0,t.memo)(({routeName:i,routeParams:a=e.p,routeOptions:o=e.f,activeStrict:s=!1,ignoreQueryParams:c=!0,color:l,activeColor:u,focusColor:d,inverse:f,activeInverse:p,focusInverse:m,id:h,autoFocus:g,onSelect:_,children:v})=>{let y=e.h(),{isFocused:b}=(0,r.useFocus)({...h!==void 0&&{id:h},...g!==void 0&&{autoFocus:g}}),x=e.s(i,a,s,c),S=(0,t.useCallback)(()=>{_?.(),y.navigate(i,a,o).catch(()=>{})},[_,y,i,a,o]);(0,r.useInput)((e,t)=>{t.return&&S()},{isActive:b});let C=l;b?C=d??u??l:x&&(C=u??l);let w=f;b?w=m??p??f:x&&(w=p??f);let T={};return C!==void 0&&(T.color=C),w!==void 0&&(T.inverse=w),(0,n.jsx)(r.Text,{...T,children:v})},i);a.displayName=`InkLink`;const o=({router:t,children:r})=>(0,n.jsx)(e.t,{router:t,children:r});exports.InkLink=a,exports.InkRouterProvider=o,exports.RouterErrorBoundary=e.o,exports.useNavigator=e.a,exports.useRoute=e.r,exports.useRouteNode=e.m,exports.useRouteUtils=e.i,exports.useRouter=e.h,exports.useRouterTransition=e.n;
|
|
2
2
|
//# sourceMappingURL=ink.js.map
|
package/dist/cjs/ink.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ink.js","names":["shallowEqual","EMPTY_PARAMS","EMPTY_OPTIONS","useRouter","useIsActiveRoute","Text","RouterProvider"],"sources":["../../src/components/InkLink.tsx","../../src/components/InkRouterProvider.tsx"],"sourcesContent":["import { Text, useFocus, useInput } from \"ink\";\nimport { memo, useCallback } from \"react\";\n\nimport { EMPTY_OPTIONS, EMPTY_PARAMS } from \"../constants\";\nimport { shallowEqual } from \"../dom-utils
|
|
1
|
+
{"version":3,"file":"ink.js","names":["shallowEqual","EMPTY_PARAMS","EMPTY_OPTIONS","useRouter","useIsActiveRoute","Text","RouterProvider"],"sources":["../../src/components/InkLink.tsx","../../src/components/InkRouterProvider.tsx"],"sourcesContent":["import { Text, useFocus, useInput } from \"ink\";\nimport { memo, useCallback } from \"react\";\n\nimport { EMPTY_OPTIONS, EMPTY_PARAMS } from \"../constants\";\nimport { shallowEqual } from \"../dom-utils\";\nimport { useIsActiveRoute } from \"../hooks/useIsActiveRoute\";\nimport { useRouter } from \"../hooks/useRouter\";\n\nimport type { InkLinkProps } from \"../ink-types\";\nimport type { FC } from \"react\";\n\nfunction areInkLinkPropsEqual(\n prev: Readonly<InkLinkProps>,\n next: Readonly<InkLinkProps>,\n): boolean {\n return (\n prev.routeName === next.routeName &&\n prev.activeStrict === next.activeStrict &&\n prev.ignoreQueryParams === next.ignoreQueryParams &&\n prev.color === next.color &&\n prev.activeColor === next.activeColor &&\n prev.focusColor === next.focusColor &&\n prev.inverse === next.inverse &&\n prev.activeInverse === next.activeInverse &&\n prev.focusInverse === next.focusInverse &&\n prev.id === next.id &&\n prev.autoFocus === next.autoFocus &&\n prev.onSelect === next.onSelect &&\n prev.children === next.children &&\n shallowEqual(prev.routeParams, next.routeParams) &&\n shallowEqual(prev.routeOptions, next.routeOptions)\n );\n}\n\nconst InkLinkImpl: FC<InkLinkProps> = ({\n routeName,\n routeParams = EMPTY_PARAMS,\n routeOptions = EMPTY_OPTIONS,\n activeStrict = false,\n ignoreQueryParams = true,\n color,\n activeColor,\n focusColor,\n inverse,\n activeInverse,\n focusInverse,\n id,\n autoFocus,\n onSelect,\n children,\n}) => {\n const router = useRouter();\n const { isFocused } = useFocus({\n ...(id !== undefined && { id }),\n ...(autoFocus !== undefined && { autoFocus }),\n });\n const isRouteActive = useIsActiveRoute(\n routeName,\n routeParams,\n activeStrict,\n ignoreQueryParams,\n );\n\n const activate = useCallback(() => {\n onSelect?.();\n router.navigate(routeName, routeParams, routeOptions).catch(() => {});\n }, [onSelect, router, routeName, routeParams, routeOptions]);\n\n useInput(\n (_input, key) => {\n if (key.return) {\n activate();\n }\n },\n { isActive: isFocused },\n );\n\n let finalColor = color;\n\n if (isFocused) {\n finalColor = focusColor ?? activeColor ?? color;\n } else if (isRouteActive) {\n finalColor = activeColor ?? color;\n }\n\n let finalInverse = inverse;\n\n if (isFocused) {\n finalInverse = focusInverse ?? activeInverse ?? inverse;\n } else if (isRouteActive) {\n finalInverse = activeInverse ?? inverse;\n }\n\n const textProps: { color?: string; inverse?: boolean } = {};\n\n if (finalColor !== undefined) {\n textProps.color = finalColor;\n }\n\n if (finalInverse !== undefined) {\n textProps.inverse = finalInverse;\n }\n\n return <Text {...textProps}>{children}</Text>;\n};\n\nexport const InkLink: FC<InkLinkProps> = memo(\n InkLinkImpl,\n areInkLinkPropsEqual,\n);\n\nInkLink.displayName = \"InkLink\";\n","import { RouterProvider } from \"../RouterProvider\";\n\nimport type { InkRouterProviderProps } from \"../ink-types\";\nimport type { FC } from \"react\";\n\nexport const InkRouterProvider: FC<InkRouterProviderProps> = ({\n router,\n children,\n}) => <RouterProvider router={router}>{children}</RouterProvider>;\n"],"mappings":"0LAWA,SAAS,EACP,EACA,EACS,CACT,OACE,EAAK,YAAc,EAAK,WACxB,EAAK,eAAiB,EAAK,cAC3B,EAAK,oBAAsB,EAAK,mBAChC,EAAK,QAAU,EAAK,OACpB,EAAK,cAAgB,EAAK,aAC1B,EAAK,aAAe,EAAK,YACzB,EAAK,UAAY,EAAK,SACtB,EAAK,gBAAkB,EAAK,eAC5B,EAAK,eAAiB,EAAK,cAC3B,EAAK,KAAO,EAAK,IACjB,EAAK,YAAc,EAAK,WACxB,EAAK,WAAa,EAAK,UACvB,EAAK,WAAa,EAAK,UACvBA,EAAAA,EAAa,EAAK,YAAa,EAAK,YAAY,EAChDA,EAAAA,EAAa,EAAK,aAAc,EAAK,aAAa,CA4EtD,MAAa,GAAA,EAAA,EAAA,OAxE0B,CACrC,YACA,cAAcC,EAAAA,EACd,eAAeC,EAAAA,EACf,eAAe,GACf,oBAAoB,GACpB,QACA,cACA,aACA,UACA,gBACA,eACA,KACA,YACA,WACA,cACI,CACJ,IAAM,EAASC,EAAAA,GAAW,CACpB,CAAE,cAAA,EAAA,EAAA,UAAuB,CAC7B,GAAI,IAAO,IAAA,IAAa,CAAE,KAAI,CAC9B,GAAI,IAAc,IAAA,IAAa,CAAE,YAAW,CAC7C,CAAC,CACI,EAAgBC,EAAAA,EACpB,EACA,EACA,EACA,EACD,CAEK,GAAA,EAAA,EAAA,iBAA6B,CACjC,KAAY,CACZ,EAAO,SAAS,EAAW,EAAa,EAAa,CAAC,UAAY,GAAG,EACpE,CAAC,EAAU,EAAQ,EAAW,EAAa,EAAa,CAAC,EAE5D,EAAA,EAAA,WACG,EAAQ,IAAQ,CACX,EAAI,QACN,GAAU,EAGd,CAAE,SAAU,EAAW,CACxB,CAED,IAAI,EAAa,EAEb,EACF,EAAa,GAAc,GAAe,EACjC,IACT,EAAa,GAAe,GAG9B,IAAI,EAAe,EAEf,EACF,EAAe,GAAgB,GAAiB,EACvC,IACT,EAAe,GAAiB,GAGlC,IAAM,EAAmD,EAAE,CAU3D,OARI,IAAe,IAAA,KACjB,EAAU,MAAQ,GAGhB,IAAiB,IAAA,KACnB,EAAU,QAAU,IAGf,EAAA,EAAA,KAACC,EAAAA,KAAD,CAAM,GAAI,EAAY,WAAgB,CAAA,EAK7C,EACD,CAED,EAAQ,YAAc,UC1GtB,MAAa,GAAiD,CAC5D,SACA,eACI,EAAA,EAAA,KAACC,EAAAA,EAAD,CAAwB,SAAS,WAA0B,CAAA"}
|
package/dist/cjs/legacy.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { a as useNavigator, c as RouterErrorBoundaryProps, i as useRouteUtils, l as LinkProps, n as useRouteNode, o as useRouter, r as useRoute, s as RouterErrorBoundary, t as useRouterTransition } from "./useRouterTransition-BlTJ1uz3.js";
|
|
2
|
-
import { n as Link, t as RouterProvider } from "./RouterProvider-
|
|
2
|
+
import { n as Link, t as RouterProvider } from "./RouterProvider-BFSblUxR.js";
|
|
3
3
|
import { Navigator } from "@real-router/core";
|
|
4
4
|
import { RouterTransitionSnapshot } from "@real-router/sources";
|
|
5
5
|
export { Link, type LinkProps, type Navigator, RouterErrorBoundary, type RouterErrorBoundaryProps, RouterProvider, type RouterTransitionSnapshot, useNavigator, useRoute, useRouteNode, useRouteUtils, useRouter, useRouterTransition };
|
package/dist/cjs/legacy.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./RouterProvider-
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./RouterProvider-BOWw6Z_i.js`),t=require(`./Link-CFGcNhCQ.js`);exports.Link=t.t,exports.RouterErrorBoundary=e.o,exports.RouterProvider=e.t,exports.useNavigator=e.a,exports.useRoute=e.r,exports.useRouteNode=e.m,exports.useRouteUtils=e.i,exports.useRouter=e.h,exports.useRouterTransition=e.n;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{c as e,d as t,f as n,h as r,l as i,p as a,s as o,u as s}from"./RouterProvider-
|
|
2
|
-
//# sourceMappingURL=Link-
|
|
1
|
+
import{c as e,d as t,f as n,h as r,l as i,p as a,s as o,u as s}from"./RouterProvider-Cx0t2IIF.mjs";import{memo as c,useCallback as l,useMemo as u}from"react";import{jsx as d}from"react/jsx-runtime";function f(e,t){return e.routeName===t.routeName&&e.className===t.className&&e.activeClassName===t.activeClassName&&e.activeStrict===t.activeStrict&&e.ignoreQueryParams===t.ignoreQueryParams&&e.onClick===t.onClick&&e.target===t.target&&e.style===t.style&&e.children===t.children&&s(e.routeParams,t.routeParams)&&s(e.routeOptions,t.routeOptions)}const p=c(({routeName:s,routeParams:c=a,routeOptions:f=n,className:p,activeClassName:m=`active`,activeStrict:h=!1,ignoreQueryParams:g=!0,onClick:_,target:v,children:y,...b})=>{let x=r(),S=o(s,c,h,g),C=u(()=>i(x,s,c),[x,s,c]),w=l(e=>{_&&(_(e),e.defaultPrevented)||!t(e.nativeEvent)||v===`_blank`||(e.preventDefault(),x.navigate(s,c,f).catch(()=>{}))},[_,v,x,s,c,f]),T=e(S,m,p);return d(`a`,{...b,href:C,className:T,onClick:w,children:y})},f);p.displayName=`Link`;export{p as t};
|
|
2
|
+
//# sourceMappingURL=Link-coFvvMgW.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Link-coFvvMgW.mjs","names":[],"sources":["../../src/components/Link.tsx"],"sourcesContent":["import { memo, useCallback, useMemo } from \"react\";\n\nimport { EMPTY_PARAMS, EMPTY_OPTIONS } from \"../constants\";\nimport {\n shouldNavigate,\n buildHref,\n buildActiveClassName,\n shallowEqual,\n} from \"../dom-utils\";\nimport { useIsActiveRoute } from \"../hooks/useIsActiveRoute\";\nimport { useRouter } from \"../hooks/useRouter\";\n\nimport type { LinkProps } from \"../types\";\nimport type { FC, MouseEvent } from \"react\";\n\nfunction areLinkPropsEqual(\n prev: Readonly<LinkProps>,\n next: Readonly<LinkProps>,\n): boolean {\n return (\n prev.routeName === next.routeName &&\n prev.className === next.className &&\n prev.activeClassName === next.activeClassName &&\n prev.activeStrict === next.activeStrict &&\n prev.ignoreQueryParams === next.ignoreQueryParams &&\n prev.onClick === next.onClick &&\n prev.target === next.target &&\n prev.style === next.style &&\n prev.children === next.children &&\n shallowEqual(prev.routeParams, next.routeParams) &&\n shallowEqual(prev.routeOptions, next.routeOptions)\n );\n}\n\nconst LinkImpl: FC<LinkProps> = ({\n routeName,\n routeParams = EMPTY_PARAMS,\n routeOptions = EMPTY_OPTIONS,\n className,\n activeClassName = \"active\",\n activeStrict = false,\n ignoreQueryParams = true,\n onClick,\n target,\n children,\n ...props\n}) => {\n // memo + areLinkPropsEqual guarantees that on bail-out the component does\n // not render; on render, routeParams/routeOptions either changed reference\n // (true change) or comparator failed (e.g., BigInt fallback to identity),\n // so they're safe to use directly in hook deps.\n\n const router = useRouter();\n\n const isActive = useIsActiveRoute(\n routeName,\n routeParams,\n activeStrict,\n ignoreQueryParams,\n );\n\n const href = useMemo(\n () => buildHref(router, routeName, routeParams),\n [router, routeName, routeParams],\n );\n\n const handleClick = useCallback(\n (evt: MouseEvent<HTMLAnchorElement>) => {\n if (onClick) {\n onClick(evt);\n\n if (evt.defaultPrevented) {\n return;\n }\n }\n\n if (!shouldNavigate(evt.nativeEvent) || target === \"_blank\") {\n return;\n }\n\n evt.preventDefault();\n router.navigate(routeName, routeParams, routeOptions).catch(() => {});\n },\n [onClick, target, router, routeName, routeParams, routeOptions],\n );\n\n const finalClassName = buildActiveClassName(\n isActive,\n activeClassName,\n className,\n );\n\n return (\n <a {...props} href={href} className={finalClassName} onClick={handleClick}>\n {children}\n </a>\n );\n};\n\nexport const Link: FC<LinkProps> = memo(LinkImpl, areLinkPropsEqual);\n\nLink.displayName = \"Link\";\n"],"mappings":"sMAeA,SAAS,EACP,EACA,EACS,CACT,OACE,EAAK,YAAc,EAAK,WACxB,EAAK,YAAc,EAAK,WACxB,EAAK,kBAAoB,EAAK,iBAC9B,EAAK,eAAiB,EAAK,cAC3B,EAAK,oBAAsB,EAAK,mBAChC,EAAK,UAAY,EAAK,SACtB,EAAK,SAAW,EAAK,QACrB,EAAK,QAAU,EAAK,OACpB,EAAK,WAAa,EAAK,UACvB,EAAa,EAAK,YAAa,EAAK,YAAY,EAChD,EAAa,EAAK,aAAc,EAAK,aAAa,CAqEtD,MAAa,EAAsB,GAjEF,CAC/B,YACA,cAAc,EACd,eAAe,EACf,YACA,kBAAkB,SAClB,eAAe,GACf,oBAAoB,GACpB,UACA,SACA,WACA,GAAG,KACC,CAMJ,IAAM,EAAS,GAAW,CAEpB,EAAW,EACf,EACA,EACA,EACA,EACD,CAEK,EAAO,MACL,EAAU,EAAQ,EAAW,EAAY,CAC/C,CAAC,EAAQ,EAAW,EAAY,CACjC,CAEK,EAAc,EACjB,GAAuC,CAClC,IACF,EAAQ,EAAI,CAER,EAAI,mBAKN,CAAC,EAAe,EAAI,YAAY,EAAI,IAAW,WAInD,EAAI,gBAAgB,CACpB,EAAO,SAAS,EAAW,EAAa,EAAa,CAAC,UAAY,GAAG,GAEvE,CAAC,EAAS,EAAQ,EAAQ,EAAW,EAAa,EAAa,CAChE,CAEK,EAAiB,EACrB,EACA,EACA,EACD,CAED,OACE,EAAC,IAAD,CAAG,GAAI,EAAa,OAAM,UAAW,EAAgB,QAAS,EAC3D,WACC,CAAA,EAI0C,EAAkB,CAEpE,EAAK,YAAc"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{createContext as e,useContext as t,useEffect as n,useMemo as r,useRef as i,useSyncExternalStore as a}from"react";import{getNavigator as o}from"@real-router/core";import{getRouteUtils as s}from"@real-router/route-utils";import{Fragment as c,jsx as l,jsxs as u}from"react/jsx-runtime";import{createActiveRouteSource as d,createDismissableError as f,createRouteNodeSource as p,createRouteSource as m,getTransitionSource as h}from"@real-router/sources";import{getPluginApi as g}from"@real-router/core/api";const _=e(null),v=e(null),y=e(null),b=()=>{let e=t(v);if(!e)throw Error(`useRouter must be used within a RouterProvider`);return e};function x(e){let t=b(),n=r(()=>p(t,e),[t,e]),i=a(n.subscribe,n.getSnapshot,n.getSnapshot),s=o(t);return r(()=>({navigator:s,route:i.route,previousRoute:i.previousRoute}),[s,i])}const S=Object.freeze({}),C=Object.freeze({}),w=`data-real-router-announcer`;function T(e,t){let n=t?.prefix??`Navigated to `,r=t?.getAnnouncementText,i=!0,a=!1,o=!1,s=``,c=null,l,u=E(),d=(e,t)=>{s=e,clearTimeout(l),u.textContent=e,l=setTimeout(()=>{u.textContent=``,s=``},7e3),k(t)},f=setTimeout(()=>{if(a=!0,c!==null&&!o){let e=c;c=null,d(e,document.querySelector(`h1`))}},100),p=e.subscribe(({route:e})=>{if(i){i=!1;return}requestAnimationFrame(()=>{requestAnimationFrame(()=>{if(o)return;let t=document.querySelector(`h1`),i=O(e,n,r,t);if(!(!i||i===s)){if(!a){c=i;return}d(i,t)}})})});return{destroy(){o=!0,p(),clearTimeout(l),clearTimeout(f),D()}}}function E(){let e=document.querySelector(`[${w}]`);if(e)return e;let t=document.createElement(`div`);return t.setAttribute(`style`,`position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);clip-path:inset(50%);white-space:nowrap;border:0`),t.setAttribute(`aria-live`,`assertive`),t.setAttribute(`aria-atomic`,`true`),t.setAttribute(w,``),document.body.prepend(t),t}function D(){document.querySelector(`[${w}]`)?.remove()}function O(e,t,n,r){if(n)return n(e);let i=r?.textContent.trim()??``,a=e.name.startsWith(`@@`)?``:e.name;return`${t}${i||document.title||a||globalThis.location.pathname}`}function k(e){e&&(e.hasAttribute(`tabindex`)||e.setAttribute(`tabindex`,`-1`),e.focus({preventScroll:!0}))}const A=`real-router:scroll`,j=Object.freeze({destroy:()=>{}});function M(e,t){if(globalThis.window===void 0)return j;let n=t?.mode??`restore`;if(n===`manual`)return j;let r=t?.anchorScrolling??!0,i=t?.scrollContainer,a=history.scrollRestoration;try{history.scrollRestoration=`manual`}catch{}let o=()=>{let e=i?.();return e?e.scrollTop:globalThis.scrollY},s=e=>{let t=i?.();t?t.scrollTop=e:globalThis.scrollTo(0,e)},c=()=>{let e=globalThis.location.hash;if(r&&e.length>1){let t;try{t=decodeURIComponent(e.slice(1))}catch{t=e.slice(1)}let n=document.getElementById(t);if(n){n.scrollIntoView();return}}s(0)},l=!1,u=e.subscribe(({route:e,previousRoute:t})=>{let r=e.context.navigation;t&&F(N(t),o()),requestAnimationFrame(()=>{if(!l){if(n===`top`||!r){c();return}if(r.navigationType!==`replace`){if(r.direction===`back`||r.navigationType===`traverse`||r.navigationType===`reload`){s(P()[N(e)]??0);return}c()}}})}),d=()=>{let t=e.getState();t&&F(N(t),o())};return globalThis.addEventListener(`pagehide`,d),{destroy:()=>{if(!l){l=!0,u(),globalThis.removeEventListener(`pagehide`,d);try{history.scrollRestoration=a}catch{}}}}}function N(e){return`${e.name}:${I(e.params)}`}function P(){try{let e=sessionStorage.getItem(A);return e?JSON.parse(e):{}}catch{return{}}}function F(e,t){try{let n=P();n[e]=t,sessionStorage.setItem(A,JSON.stringify(n))}catch{}}function I(e){return JSON.stringify(e,L)}function L(e,t){if(typeof t==`object`&&t&&!Array.isArray(t)){let e={},n=Object.keys(t).sort((e,t)=>e.localeCompare(t));for(let r of n)e[r]=t[r];return e}return t}function R(e){return e.button===0&&!e.metaKey&&!e.altKey&&!e.ctrlKey&&!e.shiftKey}function z(e,t,n){try{let r=e.buildUrl;if(r){let e=r(t,n);if(e!==void 0)return e}return e.buildPath(t,n)}catch{console.error(`[real-router] Route "${t}" is not defined. The element will render without an href attribute.`);return}}function B(e){return e?e.match(/\S+/g)??[]:[]}function V(e,t,n){if(e&&t){let e=B(t);if(e.length===0)return n??void 0;if(!n)return e.join(` `);let r=B(n),i=new Set(r);for(let t of e)i.has(t)||(i.add(t),r.push(t));return r.join(` `)}return n??void 0}function H(e,t){if(Object.is(e,t))return!0;if(!e||!t)return!1;let n=Object.keys(e);if(n.length!==Object.keys(t).length)return!1;let r=e,i=t;for(let e of n)if(!Object.is(r[e],i[e]))return!1;return!0}function U(e,t,n=!1,r=!0){let i=d(b(),e,t,{strict:n,ignoreQueryParams:r});return a(i.subscribe,i.getSnapshot,i.getSnapshot)}function W({children:e,fallback:t,onError:r}){let o=f(b()),s=a(o.subscribe,o.getSnapshot,o.getSnapshot),l=i(r);return l.current=r,n(()=>{s.error&&l.current?.(s.error,s.toRoute,s.fromRoute)},[s.version]),u(c,{children:[e,s.error?t(s.error,s.resetError):null]})}const G=()=>{let e=t(y);if(!e)throw Error(`useNavigator must be used within a RouterProvider`);return e},K=()=>s(g(b()).getTree()),q=()=>{let e=t(_);if(!e)throw Error(`useRoute must be used within a RouteProvider`);return e};function J(){let e=h(b());return a(e.subscribe,e.getSnapshot,e.getSnapshot)}const Y=({router:e,children:t,announceNavigation:i,scrollRestoration:s})=>{n(()=>{if(!i)return;let t=T(e);return()=>{t.destroy()}},[i,e]);let c=s?.mode,u=s?.anchorScrolling,d=s!==void 0;n(()=>{if(!d)return;let t=M(e,{mode:c,anchorScrolling:u,scrollContainer:s.scrollContainer});return()=>{t.destroy()}},[e,d,c,u]);let f=r(()=>o(e),[e]),p=r(()=>m(e),[e]),h=a(p.subscribe,p.getSnapshot,p.getSnapshot),g=r(()=>({navigator:f,route:h.route,previousRoute:h.previousRoute}),[f,h]);return l(v.Provider,{value:e,children:l(y.Provider,{value:f,children:l(_.Provider,{value:g,children:t})})})};export{G as a,V as c,R as d,C as f,b as h,K as i,z as l,x as m,J as n,W as o,S as p,q as r,U as s,Y as t,H as u};
|
|
2
|
+
//# sourceMappingURL=RouterProvider-Cx0t2IIF.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RouterProvider-Cx0t2IIF.mjs","names":[],"sources":["../../src/context.ts","../../src/hooks/useRouter.tsx","../../src/hooks/useRouteNode.tsx","../../src/constants.ts","../../../../shared/dom-utils/route-announcer.ts","../../../../shared/dom-utils/scroll-restore.ts","../../../../shared/dom-utils/link-utils.ts","../../src/hooks/useIsActiveRoute.tsx","../../src/components/RouterErrorBoundary.tsx","../../src/hooks/useNavigator.tsx","../../src/hooks/useRouteUtils.tsx","../../src/hooks/useRoute.tsx","../../src/hooks/useRouterTransition.tsx","../../src/RouterProvider.tsx"],"sourcesContent":["// packages/react/src/context.ts\n\nimport { createContext } from \"react\";\n\nimport type { RouteContext as RouteContextType } from \"./types\";\nimport type { Router, Navigator } from \"@real-router/core\";\n\nexport const RouteContext = createContext<RouteContextType | null>(null);\n\nexport const RouterContext = createContext<Router | null>(null);\n\nexport const NavigatorContext = createContext<Navigator | null>(null);\n","// packages/react/src/hooks/useRouter.tsx\n\nimport { useContext } from \"react\";\n\nimport { RouterContext } from \"../context\";\n\nimport type { Router } from \"@real-router/core\";\n\nexport const useRouter = (): Router => {\n const router = useContext(RouterContext);\n\n if (!router) {\n throw new Error(\"useRouter must be used within a RouterProvider\");\n }\n\n return router;\n};\n","import { getNavigator } from \"@real-router/core\";\nimport { createRouteNodeSource } from \"@real-router/sources\";\nimport { useMemo, useSyncExternalStore } from \"react\";\n\nimport { useRouter } from \"./useRouter\";\n\nimport type { RouteContext } from \"../types\";\n\nexport function useRouteNode(nodeName: string): RouteContext {\n const router = useRouter();\n\n const store = useMemo(\n () => createRouteNodeSource(router, nodeName),\n [router, nodeName],\n );\n\n // Use snapshot reference directly. createRouteNodeSource via stabilizeState\n // returns the SAME snapshot when the node-relevant state did not change,\n // so memoization on `[navigator, snapshot]` preserves identity for consumers.\n const snapshot = useSyncExternalStore(\n store.subscribe,\n store.getSnapshot,\n store.getSnapshot, // SSR: router returns same state on server and client\n );\n\n // getNavigator is WeakMap-cached in core; additional useMemo is redundant.\n const navigator = getNavigator(router);\n\n return useMemo(\n (): RouteContext => ({\n navigator,\n route: snapshot.route,\n previousRoute: snapshot.previousRoute,\n }),\n [navigator, snapshot],\n );\n}\n","// packages/react/src/constants.ts\n\n/**\n * Stable empty object for default params\n */\nexport const EMPTY_PARAMS = Object.freeze({});\n\n/**\n * Stable empty options object\n */\nexport const EMPTY_OPTIONS = Object.freeze({});\n","import type { Router, State } from \"@real-router/core\";\n\nconst CLEAR_DELAY = 7000;\nconst SAFARI_READY_DELAY = 100;\nconst ANNOUNCER_ATTR = \"data-real-router-announcer\";\nconst INTERNAL_ROUTE_PREFIX = \"@@\";\nconst VISUALLY_HIDDEN =\n \"position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);clip-path:inset(50%);white-space:nowrap;border:0\";\n\nexport interface RouteAnnouncerOptions {\n prefix?: string;\n getAnnouncementText?: (route: State) => string;\n}\n\nexport function createRouteAnnouncer(\n router: Router,\n options?: RouteAnnouncerOptions,\n): { destroy: () => void } {\n const prefix = options?.prefix ?? \"Navigated to \";\n const getCustomText = options?.getAnnouncementText;\n\n let isInitialNavigation = true;\n let isReady = false;\n let isDestroyed = false;\n let lastAnnouncedText = \"\";\n let pendingText: string | null = null;\n let clearTimeoutId: ReturnType<typeof setTimeout> | undefined;\n\n const announcer = getOrCreateAnnouncer();\n\n const doAnnounce = (text: string, h1: HTMLElement | null): void => {\n lastAnnouncedText = text;\n clearTimeout(clearTimeoutId);\n announcer.textContent = text;\n clearTimeoutId = setTimeout(() => {\n announcer.textContent = \"\";\n lastAnnouncedText = \"\";\n }, CLEAR_DELAY);\n\n manageFocus(h1);\n };\n\n // Safari-ready delay: announcing before VoiceOver wires up the aria-live region\n // causes the first announcement to be silently dropped. Wait SAFARI_READY_DELAY ms\n // before marking the announcer \"ready\" — any navigation during that window is\n // buffered in pendingText and flushed once the delay expires.\n const safariTimeoutId = setTimeout(() => {\n isReady = true;\n\n if (pendingText !== null && !isDestroyed) {\n const text = pendingText;\n\n pendingText = null;\n doAnnounce(text, document.querySelector<HTMLElement>(\"h1\"));\n }\n }, SAFARI_READY_DELAY);\n\n const unsubscribe = router.subscribe(({ route }) => {\n if (isInitialNavigation) {\n isInitialNavigation = false;\n\n return;\n }\n\n // Double rAF: waits for two paint frames so the incoming route's DOM\n // (including the new <h1>) is fully rendered before resolveText reads it.\n // Single rAF fires before the new route's template has been attached,\n // which would cause resolveText to pick up the OLD h1 or fall back to\n // document.title / route.name prematurely.\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n if (isDestroyed) {\n return;\n }\n\n const h1 = document.querySelector<HTMLElement>(\"h1\");\n const text = resolveText(route, prefix, getCustomText, h1);\n\n if (!text || text === lastAnnouncedText) {\n return;\n }\n\n if (!isReady) {\n // Defer announcement until Safari-ready window elapses (see safariTimeoutId).\n pendingText = text;\n\n return;\n }\n\n doAnnounce(text, h1);\n });\n });\n });\n\n return {\n destroy() {\n isDestroyed = true;\n unsubscribe();\n clearTimeout(clearTimeoutId);\n clearTimeout(safariTimeoutId);\n removeAnnouncer();\n },\n };\n}\n\nfunction getOrCreateAnnouncer(): HTMLElement {\n const existing = document.querySelector<HTMLElement>(`[${ANNOUNCER_ATTR}]`);\n\n if (existing) {\n return existing;\n }\n\n const element = document.createElement(\"div\");\n\n element.setAttribute(\"style\", VISUALLY_HIDDEN);\n element.setAttribute(\"aria-live\", \"assertive\");\n element.setAttribute(\"aria-atomic\", \"true\");\n element.setAttribute(ANNOUNCER_ATTR, \"\");\n\n document.body.prepend(element);\n\n return element;\n}\n\nfunction removeAnnouncer(): void {\n document.querySelector(`[${ANNOUNCER_ATTR}]`)?.remove();\n}\n\nfunction resolveText(\n route: State,\n prefix: string,\n getCustomText: ((route: State) => string) | undefined,\n h1: HTMLElement | null,\n): string {\n if (getCustomText) {\n return getCustomText(route);\n }\n\n const h1Text = h1?.textContent.trim() ?? \"\";\n const routeName = route.name.startsWith(INTERNAL_ROUTE_PREFIX)\n ? \"\"\n : route.name;\n const rawText =\n h1Text || document.title || routeName || globalThis.location.pathname;\n\n return `${prefix}${rawText}`;\n}\n\nfunction manageFocus(h1: HTMLElement | null): void {\n if (!h1) {\n return;\n }\n\n if (!h1.hasAttribute(\"tabindex\")) {\n h1.setAttribute(\"tabindex\", \"-1\");\n }\n\n h1.focus({ preventScroll: true });\n}\n","import type { Router, State } from \"@real-router/core\";\n\nconst STORAGE_KEY = \"real-router:scroll\";\n\nconst NOOP_INSTANCE: { destroy: () => void } = Object.freeze({\n destroy: () => {\n /* no-op */\n },\n});\n\nexport type ScrollRestorationMode = \"restore\" | \"top\" | \"manual\";\n\nexport interface ScrollRestorationOptions {\n mode?: ScrollRestorationMode | undefined;\n anchorScrolling?: boolean | undefined;\n scrollContainer?: (() => HTMLElement | null) | undefined;\n}\n\ninterface NavigationContext {\n direction?: \"forward\" | \"back\" | \"unknown\";\n navigationType?: \"push\" | \"replace\" | \"traverse\" | \"reload\";\n}\n\nexport function createScrollRestoration(\n router: Router,\n options?: ScrollRestorationOptions,\n): { destroy: () => void } {\n if (typeof globalThis.window === \"undefined\") {\n return NOOP_INSTANCE;\n }\n\n const mode = options?.mode ?? \"restore\";\n\n // mode \"manual\" = utility does nothing. Don't flip history.scrollRestoration,\n // don't subscribe, don't register pagehide — leave the browser's native\n // auto-restore intact for the app to override if it wants to.\n if (mode === \"manual\") {\n return NOOP_INSTANCE;\n }\n\n const anchorEnabled = options?.anchorScrolling ?? true;\n const getContainer = options?.scrollContainer;\n\n const prevScrollRestoration = history.scrollRestoration;\n\n try {\n history.scrollRestoration = \"manual\";\n } catch {\n // Ignore — some embedded contexts may reject the assignment.\n }\n\n // Resolve the container lazily on every event so containers mounted AFTER\n // the provider still get correct scroll handling. Falls back to window when\n // the getter is absent or returns null (pre-mount).\n const readPos = (): number => {\n const element = getContainer?.();\n\n return element ? element.scrollTop : globalThis.scrollY;\n };\n\n const writePos = (top: number): void => {\n const element = getContainer?.();\n\n if (element) {\n element.scrollTop = top;\n } else {\n globalThis.scrollTo(0, top);\n }\n };\n\n const scrollToHashOrTop = (): void => {\n const hash = globalThis.location.hash;\n\n if (anchorEnabled && hash.length > 1) {\n // location.hash is percent-encoded; ids in the DOM are the raw string.\n // Decode for the match. Fall back to the raw slice if the hash contains\n // a malformed escape sequence (decodeURIComponent throws on those).\n let id: string;\n\n try {\n id = decodeURIComponent(hash.slice(1));\n } catch {\n id = hash.slice(1);\n }\n\n // eslint-disable-next-line unicorn/prefer-query-selector -- ids may contain CSS-unsafe chars\n const element = document.getElementById(id);\n\n if (element) {\n element.scrollIntoView();\n\n return;\n }\n }\n\n writePos(0);\n };\n\n let destroyed = false;\n\n const unsubscribe = router.subscribe(({ route, previousRoute }) => {\n const nav = (route.context as { navigation?: NavigationContext })\n .navigation;\n\n // Browsers dispatch reload as the initial navigation after refresh, so\n // previousRoute is undefined and capture is naturally skipped. The\n // pre-refresh position was already persisted via pagehide.\n if (previousRoute) {\n putPos(keyOf(previousRoute), readPos());\n }\n\n // Single rAF so DOM is committed before we read anchors / write scroll.\n // Guard against destroy() racing with the callback.\n requestAnimationFrame(() => {\n if (destroyed) {\n return;\n }\n\n if (mode === \"top\" || !nav) {\n scrollToHashOrTop();\n\n return;\n }\n\n if (nav.navigationType === \"replace\") {\n return;\n }\n\n if (\n nav.direction === \"back\" ||\n nav.navigationType === \"traverse\" ||\n nav.navigationType === \"reload\"\n ) {\n writePos(loadStore()[keyOf(route)] ?? 0);\n\n return;\n }\n\n scrollToHashOrTop();\n });\n });\n\n const onPageHide = (): void => {\n const current = router.getState();\n\n if (current) {\n putPos(keyOf(current), readPos());\n }\n };\n\n globalThis.addEventListener(\"pagehide\", onPageHide);\n\n return {\n destroy: () => {\n if (destroyed) {\n return;\n }\n\n destroyed = true;\n unsubscribe();\n globalThis.removeEventListener(\"pagehide\", onPageHide);\n\n try {\n history.scrollRestoration = prevScrollRestoration;\n } catch {\n // Ignore.\n }\n },\n };\n}\n\nfunction keyOf(state: State): string {\n return `${state.name}:${canonicalJson(state.params)}`;\n}\n\nfunction loadStore(): Record<string, number> {\n try {\n const raw = sessionStorage.getItem(STORAGE_KEY);\n\n return raw ? (JSON.parse(raw) as Record<string, number>) : {};\n } catch {\n return {};\n }\n}\n\nfunction putPos(key: string, pos: number): void {\n try {\n const store = loadStore();\n\n store[key] = pos;\n sessionStorage.setItem(STORAGE_KEY, JSON.stringify(store));\n } catch {\n // Ignore quota / security errors.\n }\n}\n\nfunction canonicalJson(value: unknown): string {\n return JSON.stringify(value, canonicalReplacer);\n}\n\nfunction canonicalReplacer(_key: string, val: unknown): unknown {\n if (val !== null && typeof val === \"object\" && !Array.isArray(val)) {\n const sorted: Record<string, unknown> = {};\n // eslint-disable-next-line unicorn/no-array-sort -- ng-packagr uses pre-ES2023 lib; toSorted unavailable\n const keys = Object.keys(val as Record<string, unknown>).sort(\n (left: string, right: string) => left.localeCompare(right),\n );\n\n for (const key of keys) {\n sorted[key] = (val as Record<string, unknown>)[key];\n }\n\n return sorted;\n }\n\n return val;\n}\n","import type { Router, Params } from \"@real-router/core\";\n\nexport function shouldNavigate(evt: MouseEvent): boolean {\n return (\n evt.button === 0 &&\n !evt.metaKey &&\n !evt.altKey &&\n !evt.ctrlKey &&\n !evt.shiftKey\n );\n}\n\ntype BuildUrlFn = (name: string, params: Params) => string | undefined;\n\nexport function buildHref(\n router: Router,\n routeName: string,\n routeParams: Params,\n): string | undefined {\n try {\n const buildUrl = router.buildUrl as BuildUrlFn | undefined;\n\n if (buildUrl) {\n const url = buildUrl(routeName, routeParams);\n\n if (url !== undefined) {\n return url;\n }\n }\n\n return router.buildPath(routeName, routeParams);\n } catch {\n console.error(\n `[real-router] Route \"${routeName}\" is not defined. The element will render without an href attribute.`,\n );\n\n return undefined;\n }\n}\n\nfunction parseTokens(value: string | undefined): string[] {\n return value ? (value.match(/\\S+/g) ?? []) : [];\n}\n\nexport function buildActiveClassName(\n isActive: boolean,\n activeClassName: string | undefined,\n baseClassName: string | undefined,\n): string | undefined {\n if (isActive && activeClassName) {\n const activeTokens = parseTokens(activeClassName);\n\n if (activeTokens.length === 0) {\n return baseClassName ?? undefined;\n }\n if (!baseClassName) {\n return activeTokens.join(\" \");\n }\n\n const baseTokens = parseTokens(baseClassName);\n const seen = new Set(baseTokens);\n\n for (const token of activeTokens) {\n if (!seen.has(token)) {\n seen.add(token);\n baseTokens.push(token);\n }\n }\n\n return baseTokens.join(\" \");\n }\n\n return baseClassName ?? undefined;\n}\n\nexport function shallowEqual(\n prev: object | undefined,\n next: object | undefined,\n): boolean {\n if (Object.is(prev, next)) {\n return true;\n }\n if (!prev || !next) {\n return false;\n }\n\n const prevKeys = Object.keys(prev);\n\n if (prevKeys.length !== Object.keys(next).length) {\n return false;\n }\n\n const prevRecord = prev as Record<string, unknown>;\n const nextRecord = next as Record<string, unknown>;\n\n for (const key of prevKeys) {\n if (!Object.is(prevRecord[key], nextRecord[key])) {\n return false;\n }\n }\n\n return true;\n}\n\nexport function applyLinkA11y(element: HTMLElement | null | undefined): void {\n if (!element) {\n return;\n }\n if (\n element instanceof HTMLAnchorElement ||\n element instanceof HTMLButtonElement\n ) {\n return;\n }\n if (!element.hasAttribute(\"role\")) {\n element.setAttribute(\"role\", \"link\");\n }\n if (!element.hasAttribute(\"tabindex\")) {\n element.setAttribute(\"tabindex\", \"0\");\n }\n}\n","import { createActiveRouteSource } from \"@real-router/sources\";\nimport { useSyncExternalStore } from \"react\";\n\nimport { useRouter } from \"./useRouter\";\n\nimport type { Params } from \"@real-router/core\";\n\nexport function useIsActiveRoute(\n routeName: string,\n params?: Params,\n strict = false,\n ignoreQueryParams = true,\n): boolean {\n const router = useRouter();\n\n // createActiveRouteSource is per-router + canonical-args cached in\n // @real-router/sources, so passing params by reference is safe — equivalent\n // param shapes hit the same cache entry regardless of key order.\n const store = createActiveRouteSource(router, routeName, params, {\n strict,\n ignoreQueryParams,\n });\n\n return useSyncExternalStore(\n store.subscribe,\n store.getSnapshot,\n store.getSnapshot,\n );\n}\n","import { createDismissableError } from \"@real-router/sources\";\nimport { useEffect, useRef, useSyncExternalStore } from \"react\";\n\nimport { useRouter } from \"../hooks/useRouter\";\n\nimport type { RouterError, State } from \"@real-router/core\";\nimport type { ReactNode, JSX } from \"react\";\n\nexport interface RouterErrorBoundaryProps {\n readonly children: ReactNode;\n readonly fallback: (error: RouterError, resetError: () => void) => ReactNode;\n readonly onError?: (\n error: RouterError,\n toRoute: State | null,\n fromRoute: State | null,\n ) => void;\n}\n\nexport function RouterErrorBoundary({\n children,\n fallback,\n onError,\n}: RouterErrorBoundaryProps): JSX.Element {\n const router = useRouter();\n const store = createDismissableError(router);\n const snapshot = useSyncExternalStore(\n store.subscribe,\n store.getSnapshot,\n store.getSnapshot,\n );\n\n const onErrorRef = useRef(onError);\n\n // eslint-disable-next-line @eslint-react/refs -- \"latest ref\" pattern: sync callback to ref to avoid effect re-runs\n onErrorRef.current = onError;\n\n useEffect(() => {\n if (snapshot.error) {\n onErrorRef.current?.(\n snapshot.error,\n snapshot.toRoute,\n snapshot.fromRoute,\n );\n }\n // eslint-disable-next-line @eslint-react/exhaustive-deps -- onError tracked via ref, snapshot fields accessed inside callback\n }, [snapshot.version]);\n\n return (\n <>\n {children}\n {snapshot.error ? fallback(snapshot.error, snapshot.resetError) : null}\n </>\n );\n}\n","// packages/react/src/hooks/useNavigator.tsx\n\nimport { useContext } from \"react\";\n\nimport { NavigatorContext } from \"../context\";\n\nimport type { Navigator } from \"@real-router/core\";\n\nexport const useNavigator = (): Navigator => {\n const navigator = useContext(NavigatorContext);\n\n if (!navigator) {\n throw new Error(\"useNavigator must be used within a RouterProvider\");\n }\n\n return navigator;\n};\n","import { getPluginApi } from \"@real-router/core/api\";\nimport { getRouteUtils } from \"@real-router/route-utils\";\n\nimport { useRouter } from \"./useRouter\";\n\nimport type { RouteUtils } from \"@real-router/route-utils\";\n\n/**\n * Returns a pre-computed {@link RouteUtils} instance for the current router.\n *\n * `getRouteUtils` is WeakMap-cached per `RouteTreeNode` inside\n * `@real-router/route-utils`, so the same router always returns the same\n * `RouteUtils` instance across renders — no local cache needed in the adapter.\n *\n * @returns RouteUtils instance with pre-computed chains and siblings\n *\n * @example\n * ```tsx\n * const utils = useRouteUtils();\n *\n * utils.getChain(\"users.profile\");\n * // → [\"users\", \"users.profile\"]\n *\n * utils.getSiblings(\"users\");\n * // → [\"admin\"]\n *\n * utils.isDescendantOf(\"users.profile\", \"users\");\n * // → true\n * ```\n */\nexport const useRouteUtils = (): RouteUtils => {\n const router = useRouter();\n\n return getRouteUtils(getPluginApi(router).getTree());\n};\n","// packages/react/src/hooks/useRoute.tsx\n\nimport { useContext } from \"react\";\n\nimport { RouteContext } from \"../context\";\n\nimport type { RouteContext as RouteContextType } from \"../types\";\nimport type { Params } from \"@real-router/core\";\n\nexport const useRoute = <P extends Params = Params>(): RouteContextType<P> => {\n const routeContext = useContext(RouteContext);\n\n if (!routeContext) {\n throw new Error(\"useRoute must be used within a RouteProvider\");\n }\n\n return routeContext as RouteContextType<P>;\n};\n","import { getTransitionSource } from \"@real-router/sources\";\nimport { useSyncExternalStore } from \"react\";\n\nimport { useRouter } from \"./useRouter\";\n\nimport type { RouterTransitionSnapshot } from \"@real-router/sources\";\n\nexport function useRouterTransition(): RouterTransitionSnapshot {\n const router = useRouter();\n const store = getTransitionSource(router);\n\n return useSyncExternalStore(\n store.subscribe,\n store.getSnapshot,\n store.getSnapshot,\n );\n}\n","import { getNavigator } from \"@real-router/core\";\nimport { createRouteSource } from \"@real-router/sources\";\nimport { useEffect, useMemo, useSyncExternalStore } from \"react\";\n\nimport { NavigatorContext, RouteContext, RouterContext } from \"./context\";\nimport { createRouteAnnouncer, createScrollRestoration } from \"./dom-utils\";\n\nimport type { ScrollRestorationOptions } from \"./dom-utils\";\nimport type { Router } from \"@real-router/core\";\nimport type { FC, ReactNode } from \"react\";\n\nexport interface RouteProviderProps {\n router: Router;\n children: ReactNode;\n announceNavigation?: boolean;\n scrollRestoration?: ScrollRestorationOptions;\n}\n\nexport const RouterProvider: FC<RouteProviderProps> = ({\n router,\n children,\n announceNavigation,\n scrollRestoration,\n}) => {\n useEffect(() => {\n if (!announceNavigation) {\n return;\n }\n\n const announcer = createRouteAnnouncer(router);\n\n return () => {\n announcer.destroy();\n };\n }, [announceNavigation, router]);\n\n // Primitive deps so inline `{ mode: \"restore\" }` doesn't thrash on every\n // render. scrollContainer is a getter invoked lazily on every event inside\n // the utility — swapping its reference doesn't change the resolved element,\n // so we intentionally omit it from deps to keep inline getters stable.\n const srMode = scrollRestoration?.mode;\n const srAnchor = scrollRestoration?.anchorScrolling;\n const srEnabled = scrollRestoration !== undefined;\n\n useEffect(() => {\n if (!srEnabled) {\n return;\n }\n\n const sr = createScrollRestoration(router, {\n mode: srMode,\n anchorScrolling: srAnchor,\n // srEnabled check above guarantees scrollRestoration is defined.\n scrollContainer: scrollRestoration.scrollContainer,\n });\n\n return () => {\n sr.destroy();\n };\n // scrollRestoration (for scrollContainer) omitted — see comment above.\n // eslint-disable-next-line @eslint-react/exhaustive-deps\n }, [router, srEnabled, srMode, srAnchor]);\n\n const navigator = useMemo(() => getNavigator(router), [router]);\n\n // useSyncExternalStore manages the router subscription lifecycle:\n // subscribe connects to router on first listener, unsubscribes on last.\n // This is Strict Mode safe — no useEffect cleanup needed.\n const store = useMemo(() => createRouteSource(router), [router]);\n // Use snapshot reference directly. createRouteSource via stabilizeState\n // returns the SAME snapshot reference when route.path is unchanged, so\n // useMemo below sees stable deps for idempotent navigations and\n // RouteContext consumers do not re-render.\n const snapshot = useSyncExternalStore(\n store.subscribe,\n store.getSnapshot,\n store.getSnapshot, // SSR: router returns same state on server and client\n );\n\n const routeContextValue = useMemo(\n () => ({\n navigator,\n route: snapshot.route,\n previousRoute: snapshot.previousRoute,\n }),\n [navigator, snapshot],\n );\n\n return (\n <RouterContext.Provider value={router}>\n <NavigatorContext.Provider value={navigator}>\n <RouteContext.Provider value={routeContextValue}>\n {children}\n </RouteContext.Provider>\n </NavigatorContext.Provider>\n </RouterContext.Provider>\n );\n};\n"],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { l as LinkProps } from "./useRouterTransition-CFlgAEy7.mjs";
|
|
2
|
+
import { FC, ReactNode } from "react";
|
|
3
|
+
import { Params, Router, State } from "@real-router/core";
|
|
4
|
+
|
|
5
|
+
//#region src/components/Link.d.ts
|
|
6
|
+
declare const Link: FC<LinkProps>;
|
|
7
|
+
//#endregion
|
|
8
|
+
//#region ../../shared/dom-utils/scroll-restore.d.ts
|
|
9
|
+
type ScrollRestorationMode = "restore" | "top" | "manual";
|
|
10
|
+
interface ScrollRestorationOptions {
|
|
11
|
+
mode?: ScrollRestorationMode | undefined;
|
|
12
|
+
anchorScrolling?: boolean | undefined;
|
|
13
|
+
scrollContainer?: (() => HTMLElement | null) | undefined;
|
|
14
|
+
}
|
|
15
|
+
//#endregion
|
|
16
|
+
//#region src/RouterProvider.d.ts
|
|
17
|
+
interface RouteProviderProps {
|
|
18
|
+
router: Router;
|
|
19
|
+
children: ReactNode;
|
|
20
|
+
announceNavigation?: boolean;
|
|
21
|
+
scrollRestoration?: ScrollRestorationOptions;
|
|
22
|
+
}
|
|
23
|
+
declare const RouterProvider: FC<RouteProviderProps>;
|
|
24
|
+
//#endregion
|
|
25
|
+
export { Link as n, RouterProvider as t };
|
|
26
|
+
//# sourceMappingURL=RouterProvider-EtbwzAgd.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RouterProvider-EtbwzAgd.d.mts","names":[],"sources":["../../src/components/Link.tsx","../../../../shared/dom-utils/scroll-restore.ts","../../src/RouterProvider.tsx"],"mappings":";;;;;cAmGa,IAAA,EAAM,EAAA,CAAG,SAAA;;;KCzFV,qBAAA;AAAA,UAEK,wBAAA;EACf,IAAA,GAAO,qBAAA;EACP,eAAA;EACA,eAAA,UAAyB,WAAA;AAAA;;;UCJV,kBAAA;EACf,MAAA,EAAQ,MAAA;EACR,QAAA,EAAU,SAAA;EACV,kBAAA;EACA,iBAAA,GAAoB,wBAAA;AAAA;AAAA,cAGT,cAAA,EAAgB,EAAA,CAAG,kBAAA"}
|
package/dist/esm/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { a as useNavigator, c as RouterErrorBoundaryProps, i as useRouteUtils, l as LinkProps, n as useRouteNode, o as useRouter, r as useRoute, s as RouterErrorBoundary, t as useRouterTransition } from "./useRouterTransition-CFlgAEy7.mjs";
|
|
2
|
-
import { n as Link, t as RouterProvider } from "./RouterProvider-
|
|
2
|
+
import { n as Link, t as RouterProvider } from "./RouterProvider-EtbwzAgd.mjs";
|
|
3
3
|
import { ReactElement, ReactNode } from "react";
|
|
4
4
|
import { Navigator } from "@real-router/core";
|
|
5
5
|
import { RouterTransitionSnapshot } from "@real-router/sources";
|
|
@@ -8,7 +8,7 @@ import { RouterTransitionSnapshot } from "@real-router/sources";
|
|
|
8
8
|
interface RouteViewProps {
|
|
9
9
|
/** Route tree node name to subscribe to. "" for root. */
|
|
10
10
|
readonly nodeName: string;
|
|
11
|
-
/** <RouteView.Match
|
|
11
|
+
/** <RouteView.Match>, <RouteView.Self>, and <RouteView.NotFound> elements. */
|
|
12
12
|
readonly children: ReactNode;
|
|
13
13
|
}
|
|
14
14
|
interface MatchProps {
|
|
@@ -23,6 +23,17 @@ interface MatchProps {
|
|
|
23
23
|
/** Content to render when matched. */
|
|
24
24
|
readonly children: ReactNode;
|
|
25
25
|
}
|
|
26
|
+
interface SelfProps {
|
|
27
|
+
/**
|
|
28
|
+
* Fallback content to show while children are suspended.
|
|
29
|
+
*
|
|
30
|
+
* Symmetric with `<RouteView.Match fallback>` — wraps children in
|
|
31
|
+
* `<Suspense>` when defined.
|
|
32
|
+
*/
|
|
33
|
+
readonly fallback?: ReactNode;
|
|
34
|
+
/** Content to render when the active route name equals the parent RouteView's nodeName. */
|
|
35
|
+
readonly children: ReactNode;
|
|
36
|
+
}
|
|
26
37
|
interface NotFoundProps {
|
|
27
38
|
/** Content to render on UNKNOWN_ROUTE. */
|
|
28
39
|
readonly children: ReactNode;
|
|
@@ -33,6 +44,10 @@ declare function Match(_props: MatchProps): null;
|
|
|
33
44
|
declare namespace Match {
|
|
34
45
|
var displayName: string;
|
|
35
46
|
}
|
|
47
|
+
declare function Self(_props: SelfProps): null;
|
|
48
|
+
declare namespace Self {
|
|
49
|
+
var displayName: string;
|
|
50
|
+
}
|
|
36
51
|
declare function NotFound(_props: NotFoundProps): null;
|
|
37
52
|
declare namespace NotFound {
|
|
38
53
|
var displayName: string;
|
|
@@ -48,8 +63,9 @@ declare namespace RouteViewRoot {
|
|
|
48
63
|
}
|
|
49
64
|
declare const RouteView: typeof RouteViewRoot & {
|
|
50
65
|
Match: typeof Match;
|
|
66
|
+
Self: typeof Self;
|
|
51
67
|
NotFound: typeof NotFound;
|
|
52
68
|
};
|
|
53
69
|
//#endregion
|
|
54
|
-
export { Link, type LinkProps, type Navigator, RouteView, type MatchProps as RouteViewMatchProps, type NotFoundProps as RouteViewNotFoundProps, type RouteViewProps, RouterErrorBoundary, type RouterErrorBoundaryProps, RouterProvider, type RouterTransitionSnapshot, useNavigator, useRoute, useRouteNode, useRouteUtils, useRouter, useRouterTransition };
|
|
70
|
+
export { Link, type LinkProps, type Navigator, RouteView, type MatchProps as RouteViewMatchProps, type NotFoundProps as RouteViewNotFoundProps, type RouteViewProps, type SelfProps as RouteViewSelfProps, RouterErrorBoundary, type RouterErrorBoundaryProps, RouterProvider, type RouterTransitionSnapshot, useNavigator, useRoute, useRouteNode, useRouteUtils, useRouter, useRouterTransition };
|
|
55
71
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/esm/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/components/modern/RouteView/types.ts","../../src/components/modern/RouteView/components.tsx","../../src/components/modern/RouteView/RouteView.tsx"],"mappings":";;;;;;;UAEiB,cAAA;;WAEN,QAAA;;WAEA,QAAA,EAAU,SAAA;AAAA;AAAA,UAGJ,UAAA;EAPc;EAAA,SASpB,OAAA;EALmB;EAAA,SAOnB,KAAA;EAPA;EAAA,SASA,SAAA;EATmB;EAAA,SAWnB,QAAA,GAAW,SAAA;EARL;EAAA,SAUN,QAAA,EAAU,SAAA;AAAA;AAAA,UAGJ,
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/components/modern/RouteView/types.ts","../../src/components/modern/RouteView/components.tsx","../../src/components/modern/RouteView/RouteView.tsx"],"mappings":";;;;;;;UAEiB,cAAA;;WAEN,QAAA;;WAEA,QAAA,EAAU,SAAA;AAAA;AAAA,UAGJ,UAAA;EAPc;EAAA,SASpB,OAAA;EALmB;EAAA,SAOnB,KAAA;EAPA;EAAA,SASA,SAAA;EATmB;EAAA,SAWnB,QAAA,GAAW,SAAA;EARL;EAAA,SAUN,QAAA,EAAU,SAAA;AAAA;AAAA,UAGJ,SAAA;EAXN;;;;;;EAAA,SAkBA,QAAA,GAAW,SAAA;EAVQ;EAAA,SAYnB,QAAA,EAAU,SAAA;AAAA;AAAA,UAGJ,aAAA;;WAEN,QAAA,EAAU,SAAA;AAAA;;;iBClCL,KAAA,CAAM,MAAA,EAAQ,UAAA;AAAA,kBAAd,KAAA;EAAA,IAAK,WAAA;AAAA;AAAA,iBAML,IAAA,CAAK,MAAA,EAAQ,SAAA;AAAA,kBAAb,IAAA;EAAA,IAAI,WAAA;AAAA;AAAA,iBAMJ,QAAA,CAAS,MAAA,EAAQ,aAAA;AAAA,kBAAjB,QAAA;EAAA,IAAQ,WAAA;AAAA;;;iBCLf,aAAA,CAAA;EACP,QAAA;EACA;AAAA,GACC,QAAA,CAAS,cAAA,IAAkB,YAAA;AAAA,kBAHrB,aAAA;EAAA,IAAa,WAAA;AAAA;AAAA,cA0CT,SAAA,SAAS,aAAA"}
|