@ssgoi/solid 7.4.0 → 7.5.0-beta.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # @ssgoi/solid
2
2
 
3
- Solid and SolidStart bindings for SSGOI.
3
+ Native app-like page transitions for Solid and SolidStart. Make a web app, PWA or WebView app (Capacitor, Tauri, Ionic) feel like a native app without replacing your router.
4
4
 
5
5
  [![SSGOI live showcase](https://ssgoi.dev/readme.png)](https://ssgoi.dev)
6
6
 
@@ -12,15 +12,52 @@ npm install @ssgoi/solid
12
12
 
13
13
  Agent setup guide: https://ssgoi.dev/llms/solid.txt
14
14
 
15
- ## Router helpers
15
+ ## Layout boundary
16
16
 
17
- Install this framework package once; router helpers are optional subpaths.
18
- These router helpers are experimental APIs and may change.
17
+ Pass a reactive route getter to `<Ssgoi>` once (inside `<Router>`, see [Root](#root)),
18
+ then wrap routed content in `SsgoiLayoutBoundary`.
19
19
 
20
- | Router | Import | API |
21
- | ------------ | --------------------------- | -------------------- |
22
- | Solid Router | `@ssgoi/solid/solid-router` | `SsgoiRouteBoundary` |
23
- | SolidStart | `@ssgoi/solid/solidstart` | `SsgoiRouteBoundary` |
20
+ ```tsx
21
+ import { SsgoiLayoutBoundary } from "@ssgoi/solid";
22
+
23
+ export default function ProductsLayout(props) {
24
+ return (
25
+ <SsgoiLayoutBoundary as="section">
26
+ <div>{props.children}</div>
27
+ </SsgoiLayoutBoundary>
28
+ );
29
+ }
30
+ ```
31
+
32
+ Each boundary marks the current path with `data-ssgoi-transition`. Nest them
33
+ freely: depth is automatic. Declare which paths share a layout in
34
+ `config.layouts`; the scope matched at a boundary's depth keeps its DOM, and
35
+ past the declared scopes a boundary remounts on every path change (the default
36
+ without `layouts`).
37
+
38
+ ```ts
39
+ const TOP_LEVEL = ["/home", "/search", "/profile"];
40
+ const config = {
41
+ layouts: [
42
+ { paths: TOP_LEVEL }, // tabs share one depth-0 layout
43
+ {
44
+ paths: "/**",
45
+ except: TOP_LEVEL,
46
+ layouts: [{ paths: "/products/**" }], // depth-1 scope inside details
47
+ },
48
+ ],
49
+ transitions: [/* ... */],
50
+ };
51
+ ```
52
+
53
+ The first matching scope at each level wins. Single-segment captures (`*`,
54
+ `:id`, `[id]`) split instances, so `/projects/:id/**` keeps one layout per
55
+ project; `**` tails do not. `SsgoiLayoutBoundary` takes no SSGOI props (`as`
56
+ sets the element) and throws without `framework` on `<Ssgoi>`.
57
+
58
+ `SsgoiRouteBoundary` from `@ssgoi/solid/solid-router` and
59
+ `@ssgoi/solid/solidstart` is deprecated; use `SsgoiLayoutBoundary` with
60
+ `framework` instead.
24
61
 
25
62
  See the [framework guide](https://ssgoi.dev/docs/frameworks/solid) for wiring and limits.
26
63
 
@@ -29,7 +66,7 @@ See the [framework guide](https://ssgoi.dev/docs/frameworks/solid) for wiring an
29
66
  Use one `<Ssgoi>` around file routes.
30
67
 
31
68
  ```tsx
32
- import { Router } from "@solidjs/router";
69
+ import { Router, useLocation, type RouteSectionProps } from "@solidjs/router";
33
70
  import { FileRoutes } from "@solidjs/start/router";
34
71
  import { Ssgoi } from "@ssgoi/solid";
35
72
  import { drill } from "@ssgoi/solid/view-transitions";
@@ -38,15 +75,24 @@ const config = {
38
75
  transitions: [{ on: "/posts/**", except: "/posts", transition: drill() }],
39
76
  };
40
77
 
78
+ function Root(props: RouteSectionProps) {
79
+ const location = useLocation();
80
+
81
+ return (
82
+ <main class="relative z-0 min-h-dvh overflow-x-clip">
83
+ <Ssgoi
84
+ config={config}
85
+ framework={{ getRoute: () => ({ pathname: location.pathname }) }}
86
+ >
87
+ {props.children}
88
+ </Ssgoi>
89
+ </main>
90
+ );
91
+ }
92
+
41
93
  export default function App() {
42
94
  return (
43
- <Router
44
- root={(props) => (
45
- <main class="relative z-0 min-h-dvh overflow-x-clip">
46
- <Ssgoi config={config}>{props.children}</Ssgoi>
47
- </main>
48
- )}
49
- >
95
+ <Router root={Root}>
50
96
  <FileRoutes />
51
97
  </Router>
52
98
  );
package/dist/context.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("solid-js"),t=o.createContext(null),s=t.Provider,r=()=>{const e=o.useContext(t);if(!e)throw new Error("useSsgoi must be used within SsgoiProvider");return e};exports.SsgoiProvider=s;exports.useSsgoi=r;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("solid-js"),e=t.createContext(null),s=t.createContext(void 0),i=t.createContext(0),a=e.Provider,c=s.Provider,S=i.Provider,g=()=>t.useContext(s),d=()=>t.useContext(i),v=()=>{const o=t.useContext(e);if(!o)throw new Error("useSsgoi must be used within SsgoiProvider");return o},x=()=>{const o=t.useContext(e);if(!o)throw new Error("useSsgoiTransition must be used within <Ssgoi>");const[n,r]=t.createSignal(o.getTransitionState());return t.onCleanup(o.subscribe(u=>r(()=>u))),n};exports.SsgoiLayoutDepthProvider=S;exports.SsgoiLayoutProvider=c;exports.SsgoiProvider=a;exports.useLayoutDepth=d;exports.useSsgoi=v;exports.useSsgoiLayout=g;exports.useSsgoiTransition=x;
package/dist/context.d.ts CHANGED
@@ -1,3 +1,26 @@
1
- import { SsgoiContext } from './types';
1
+ import { Accessor } from 'solid-js';
2
+ import { SsgoiContext, SsgoiTransitionState } from './types';
3
+ /** Route state `<Ssgoi>` resolves once for every layout boundary below it. */
4
+ export interface SsgoiLayoutState {
5
+ routePath: string;
6
+ chain: string[];
7
+ }
2
8
  export declare const SsgoiProvider: import('solid-js').ContextProviderComponent<SsgoiContext | null>;
9
+ export declare const SsgoiLayoutProvider: import('solid-js').ContextProviderComponent<Accessor<SsgoiLayoutState | undefined> | undefined>;
10
+ /** Gives descendants of a layout boundary their depth. */
11
+ export declare const SsgoiLayoutDepthProvider: import('solid-js').ContextProviderComponent<number>;
12
+ /** Layout state of the nearest `<Ssgoi>`; undefined without a framework. */
13
+ export declare const useSsgoiLayout: () => Accessor<SsgoiLayoutState | undefined> | undefined;
14
+ /** Depth of the calling layout boundary: 0 unless inside another. */
15
+ export declare const useLayoutDepth: () => number;
3
16
  export declare const useSsgoi: () => SsgoiContext;
17
+ /**
18
+ * Signal of the provider's transition lifecycle: whether a page transition is
19
+ * preparing or playing, and which routes it joins.
20
+ *
21
+ * Use it to defer work that would fight the animation, such as a programmatic
22
+ * scroll on the arriving page, until the status returns to `"idle"`.
23
+ *
24
+ * Must be called under `<Ssgoi>`.
25
+ */
26
+ export declare const useSsgoiTransition: () => Accessor<SsgoiTransitionState>;
package/dist/context.js CHANGED
@@ -1,11 +1,22 @@
1
- import { createContext as e, useContext as r } from "solid-js";
2
- const t = e(null), n = t.Provider, i = () => {
3
- const o = r(t);
4
- if (!o)
1
+ import { createContext as e, useContext as o, createSignal as a, onCleanup as S } from "solid-js";
2
+ const s = e(null), n = e(void 0), i = e(0), d = s.Provider, v = n.Provider, x = i.Provider, h = () => o(n), P = () => o(i), p = () => {
3
+ const t = o(s);
4
+ if (!t)
5
5
  throw new Error("useSsgoi must be used within SsgoiProvider");
6
- return o;
6
+ return t;
7
+ }, w = () => {
8
+ const t = o(s);
9
+ if (!t)
10
+ throw new Error("useSsgoiTransition must be used within <Ssgoi>");
11
+ const [r, u] = a(t.getTransitionState());
12
+ return S(t.subscribe((c) => u(() => c))), r;
7
13
  };
8
14
  export {
9
- n as SsgoiProvider,
10
- i as useSsgoi
15
+ x as SsgoiLayoutDepthProvider,
16
+ v as SsgoiLayoutProvider,
17
+ d as SsgoiProvider,
18
+ P as useLayoutDepth,
19
+ p as useSsgoi,
20
+ h as useSsgoiLayout,
21
+ w as useSsgoiTransition
11
22
  };
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("@ssgoi/core/types"),o=require("./ssgoi.cjs"),i=require("./ssgoi-transition.cjs"),r=require("@ssgoi/core");exports.Ssgoi=o.Ssgoi;exports.SsgoiTransition=i.SsgoiTransition;Object.keys(t).forEach(e=>{e!=="default"&&!Object.prototype.hasOwnProperty.call(exports,e)&&Object.defineProperty(exports,e,{enumerable:!0,get:()=>t[e]})});Object.keys(r).forEach(e=>{e!=="default"&&!Object.prototype.hasOwnProperty.call(exports,e)&&Object.defineProperty(exports,e,{enumerable:!0,get:()=>r[e]})});
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("@ssgoi/core/types"),r=require("./ssgoi.cjs"),i=require("./context.cjs"),s=require("./layout-boundary.cjs"),n=require("./legacy/ssgoi-transition.cjs"),t=require("@ssgoi/core");exports.Ssgoi=r.Ssgoi;exports.useSsgoiTransition=i.useSsgoiTransition;exports.SsgoiLayoutBoundary=s.SsgoiLayoutBoundary;exports.SsgoiTransition=n.SsgoiTransition;Object.keys(o).forEach(e=>{e!=="default"&&!Object.prototype.hasOwnProperty.call(exports,e)&&Object.defineProperty(exports,e,{enumerable:!0,get:()=>o[e]})});Object.keys(t).forEach(e=>{e!=="default"&&!Object.prototype.hasOwnProperty.call(exports,e)&&Object.defineProperty(exports,e,{enumerable:!0,get:()=>t[e]})});
package/dist/index.d.ts CHANGED
@@ -1,5 +1,8 @@
1
1
  export * from './types';
2
2
  export { Ssgoi } from './ssgoi';
3
- /** @deprecated Set `data-ssgoi-transition` directly on an element inside `<Ssgoi>` instead. */
4
- export { SsgoiTransition } from './ssgoi-transition';
3
+ export { useSsgoiTransition } from './context';
4
+ export { SsgoiLayoutBoundary } from './layout-boundary';
5
+ export type { SsgoiLayoutBoundaryProps } from './layout-boundary';
6
+ /** @deprecated Will be removed in 8.0.0. */
7
+ export { SsgoiTransition } from './routers/ssgoi-transition';
5
8
  export * from '@ssgoi/core';
package/dist/index.js CHANGED
@@ -1,8 +1,12 @@
1
1
  export * from "@ssgoi/core/types";
2
- import { Ssgoi as e } from "./ssgoi.js";
3
- import { SsgoiTransition as i } from "./ssgoi-transition.js";
2
+ import { Ssgoi as i } from "./ssgoi.js";
3
+ import { useSsgoiTransition as s } from "./context.js";
4
+ import { SsgoiLayoutBoundary as m } from "./layout-boundary.js";
5
+ import { SsgoiTransition as x } from "./legacy/ssgoi-transition.js";
4
6
  export * from "@ssgoi/core";
5
7
  export {
6
- e as Ssgoi,
7
- i as SsgoiTransition
8
+ i as Ssgoi,
9
+ m as SsgoiLayoutBoundary,
10
+ x as SsgoiTransition,
11
+ s as useSsgoiTransition
8
12
  };
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("solid-js/web"),o=require("solid-js"),u=require("./context.cjs");function l(i){const[e,n]=o.splitProps(i,["children","as","state"]),a=o.createMemo(r=>{const s=e.state().key;return r?.key===s?r:{key:s}});return t.createComponent(o.Show,{get when(){return a()},keyed:!0,children:r=>t.createComponent(t.Dynamic,t.mergeProps({get component(){return e.as??"div"}},n,{get"data-ssgoi-transition"(){return e.state().id},get children(){return e.children}}))})}function d(){throw new Error("SSGOI: SsgoiLayoutBoundary requires a framework. Pass it to <Ssgoi framework={{ getRoute }}>.")}function g(i){const e=u.useSsgoiLayout();e?.()||d();const n=u.useLayoutDepth(),[a,r]=o.splitProps(i,["children"]),s=o.createMemo(()=>{const{routePath:c,chain:y}=e()??d();return{id:c,key:y[n]??c}});return t.createComponent(l,t.mergeProps(r,{state:s,get children(){return t.createComponent(u.SsgoiLayoutDepthProvider,{value:n+1,get children(){return a.children}})}}))}exports.RouteBoundary=l;exports.SsgoiLayoutBoundary=g;
@@ -0,0 +1,12 @@
1
+ import { Accessor, JSX } from 'solid-js';
2
+ export type SsgoiLayoutBoundaryProps = JSX.HTMLAttributes<HTMLElement> & {
3
+ as?: keyof JSX.IntrinsicElements;
4
+ };
5
+ /** Shared rendering; remounts its element whenever `state().key` changes. */
6
+ export declare function RouteBoundary(props: SsgoiLayoutBoundaryProps & {
7
+ state: Accessor<{
8
+ id: string;
9
+ key: string | number;
10
+ }>;
11
+ }): JSX.Element;
12
+ export declare function SsgoiLayoutBoundary(props: SsgoiLayoutBoundaryProps): JSX.Element;
@@ -0,0 +1,61 @@
1
+ import { createComponent as n, mergeProps as c, Dynamic as m } from "solid-js/web";
2
+ import { splitProps as d, createMemo as h, Show as g } from "solid-js";
3
+ import { useSsgoiLayout as y, useLayoutDepth as f, SsgoiLayoutDepthProvider as p } from "./context.js";
4
+ function k(i) {
5
+ const [t, r] = d(i, ["children", "as", "state"]), s = h((e) => {
6
+ const o = t.state().key;
7
+ return e?.key === o ? e : {
8
+ key: o
9
+ };
10
+ });
11
+ return n(g, {
12
+ get when() {
13
+ return s();
14
+ },
15
+ keyed: !0,
16
+ children: (e) => n(m, c({
17
+ get component() {
18
+ return t.as ?? "div";
19
+ }
20
+ }, r, {
21
+ get "data-ssgoi-transition"() {
22
+ return t.state().id;
23
+ },
24
+ get children() {
25
+ return t.children;
26
+ }
27
+ }))
28
+ });
29
+ }
30
+ function u() {
31
+ throw new Error("SSGOI: SsgoiLayoutBoundary requires a framework. Pass it to <Ssgoi framework={{ getRoute }}>.");
32
+ }
33
+ function P(i) {
34
+ const t = y();
35
+ t?.() || u();
36
+ const r = f(), [s, e] = d(i, ["children"]), o = h(() => {
37
+ const {
38
+ routePath: a,
39
+ chain: l
40
+ } = t() ?? u();
41
+ return {
42
+ id: a,
43
+ key: l[r] ?? a
44
+ };
45
+ });
46
+ return n(k, c(e, {
47
+ state: o,
48
+ get children() {
49
+ return n(p, {
50
+ value: r + 1,
51
+ get children() {
52
+ return s.children;
53
+ }
54
+ });
55
+ }
56
+ }));
57
+ }
58
+ export {
59
+ k as RouteBoundary,
60
+ P as SsgoiLayoutBoundary
61
+ };
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("solid-js/web"),a=require("solid-js"),l=require("../context.cjs"),u=t=>{const[e,o]=a.splitProps(t,["children","id","as","class"]),n=l.useSsgoi(),i=e.as||"div";return r.createComponent(r.Dynamic,r.mergeProps({component:i,ref(c){var s=n.refFor(e.id);typeof s=="function"&&s(c)},get"data-ssgoi-transition"(){return e.id},get class(){return e.class}},o,{get children(){return e.children}}))};exports.SsgoiTransition=u;
@@ -1,6 +1,6 @@
1
1
  import { createComponent as c, Dynamic as a, mergeProps as m } from "solid-js/web";
2
2
  import { splitProps as p } from "solid-js";
3
- import { useSsgoi as l } from "./context.js";
3
+ import { useSsgoi as l } from "../context.js";
4
4
  const u = (t) => {
5
5
  const [r, s] = p(t, ["children", "id", "as", "class"]), e = l(), n = r.as || "div";
6
6
  return c(a, m({
@@ -1,8 +1,10 @@
1
1
  import { JSX } from 'solid-js';
2
+ /** @deprecated Will be removed in 8.0.0. Declare layout scopes in `config.layouts` and use `SsgoiLayoutBoundary` from "@ssgoi/solid" instead. */
2
3
  export interface RouteBoundaryState {
3
4
  id: string;
4
5
  key?: string | number;
5
6
  }
7
+ /** @deprecated Will be removed in 8.0.0. Declare layout scopes in `config.layouts` and use `SsgoiLayoutBoundary` from "@ssgoi/solid" instead. */
6
8
  export type SsgoiRouteBoundaryProps = JSX.HTMLAttributes<HTMLElement> & {
7
9
  as?: keyof JSX.IntrinsicElements;
8
10
  routeKey?: string | number;
@@ -10,5 +12,8 @@ export type SsgoiRouteBoundaryProps = JSX.HTMLAttributes<HTMLElement> & {
10
12
  pathname: string;
11
13
  }) => RouteBoundaryState;
12
14
  };
13
- /** @experimental Solid Router integration, including SolidStart. The API may change. */
15
+ /**
16
+ * @experimental Solid Router integration, including SolidStart. The API may change.
17
+ * @deprecated Will be removed in 8.0.0. Use `SsgoiLayoutBoundary` from "@ssgoi/solid" with `<Ssgoi framework={{ getRoute: () => ({ pathname: location.pathname }) }}>` (`useLocation` from "@solidjs/router") instead.
18
+ */
14
19
  export declare function SsgoiRouteBoundary(props: SsgoiRouteBoundaryProps): JSX.Element;
@@ -1,3 +1,10 @@
1
- /** @experimental SolidStart integration through Solid Router. The API may change. */
1
+ /**
2
+ * @experimental SolidStart integration through Solid Router. The API may change.
3
+ * @deprecated Will be removed in 8.0.0. Use `SsgoiLayoutBoundary` from "@ssgoi/solid" with `<Ssgoi framework={{ getRoute: () => ({ pathname: location.pathname }) }}>` (`useLocation` from "@solidjs/router") instead.
4
+ */
2
5
  export { SsgoiRouteBoundary } from './solid-router';
3
- export type { SsgoiRouteBoundaryProps, RouteBoundaryState, } from './solid-router';
6
+ export type {
7
+ /** @deprecated Will be removed in 8.0.0. Declare layout scopes in `config.layouts` and use `SsgoiLayoutBoundary` from "@ssgoi/solid" instead. */
8
+ SsgoiRouteBoundaryProps,
9
+ /** @deprecated Will be removed in 8.0.0. Declare layout scopes in `config.layouts` and use `SsgoiLayoutBoundary` from "@ssgoi/solid" instead. */
10
+ RouteBoundaryState, } from './solid-router';
@@ -1,13 +1,11 @@
1
1
  import { JSX, ValidComponent } from 'solid-js';
2
+ /** @deprecated Will be removed in 8.0.0. */
2
3
  type SsgoiTransitionProps<T extends ValidComponent = "div"> = {
3
4
  children: JSX.Element;
4
5
  id: string;
5
6
  as?: T;
6
7
  class?: string;
7
8
  };
8
- /**
9
- * @deprecated Set `data-ssgoi-transition` directly on the page boundary
10
- * element inside `<Ssgoi>` instead.
11
- */
9
+ /** @deprecated Will be removed in 8.0.0. */
12
10
  export declare const SsgoiTransition: <T extends ValidComponent = "div">(props: SsgoiTransitionProps<T>) => JSX.Element;
13
11
  export {};
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("solid-js/web"),l=require("@solidjs/router"),r=require("solid-js");function m(a){const n=l.useLocation(),[e,u]=r.splitProps(a,["children","as","resolve","routeKey"]),i=r.createMemo(()=>e.resolve?.({pathname:n.pathname})??{id:n.pathname}),d=r.createMemo(o=>{const c=i(),s=e.routeKey??c.key??c.id;return o?.key===s?o:{key:s}});return t.createComponent(r.Show,{get when(){return d()},keyed:!0,children:o=>t.createComponent(t.Dynamic,t.mergeProps({get component(){return e.as??"div"}},u,{get"data-ssgoi-transition"(){return i().id},get children(){return e.children}}))})}exports.SsgoiRouteBoundary=m;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("solid-js/web"),i=require("@solidjs/router"),n=require("solid-js"),c=require("./layout-boundary.cjs");function d(u){const o=i.useLocation(),[t,s]=n.splitProps(u,["resolve","routeKey"]),a=n.createMemo(()=>{const e=t.resolve?.({pathname:o.pathname})??{id:o.pathname};return{id:e.id,key:t.routeKey??e.key??e.id}});return r.createComponent(c.RouteBoundary,r.mergeProps(s,{state:a}))}exports.SsgoiRouteBoundary=d;
@@ -1,2 +1 @@
1
- export * from './routers/solid-router'
2
1
  export {}
@@ -1,36 +1,23 @@
1
- import { createComponent as a, Dynamic as d, mergeProps as l } from "solid-js/web";
2
- import { useLocation as p } from "@solidjs/router";
3
- import { splitProps as h, createMemo as c, Show as y } from "solid-js";
4
- function v(s) {
5
- const r = p(), [e, m] = h(s, ["children", "as", "resolve", "routeKey"]), o = c(() => e.resolve?.({
6
- pathname: r.pathname
7
- }) ?? {
8
- id: r.pathname
9
- }), u = c((t) => {
10
- const n = o(), i = e.routeKey ?? n.key ?? n.id;
11
- return t?.key === i ? t : {
12
- key: i
1
+ import { createComponent as m, mergeProps as i } from "solid-js/web";
2
+ import { useLocation as s } from "@solidjs/router";
3
+ import { splitProps as p, createMemo as c } from "solid-js";
4
+ import { RouteBoundary as u } from "./layout-boundary.js";
5
+ function h(r) {
6
+ const e = s(), [t, n] = p(r, ["resolve", "routeKey"]), a = c(() => {
7
+ const o = t.resolve?.({
8
+ pathname: e.pathname
9
+ }) ?? {
10
+ id: e.pathname
11
+ };
12
+ return {
13
+ id: o.id,
14
+ key: t.routeKey ?? o.key ?? o.id
13
15
  };
14
16
  });
15
- return a(y, {
16
- get when() {
17
- return u();
18
- },
19
- keyed: !0,
20
- children: (t) => a(d, l({
21
- get component() {
22
- return e.as ?? "div";
23
- }
24
- }, m, {
25
- get "data-ssgoi-transition"() {
26
- return o().id;
27
- },
28
- get children() {
29
- return e.children;
30
- }
31
- }))
32
- });
17
+ return m(u, i(n, {
18
+ state: a
19
+ }));
33
20
  }
34
21
  export {
35
- v as SsgoiRouteBoundary
22
+ h as SsgoiRouteBoundary
36
23
  };
@@ -1,2 +1 @@
1
- export * from './routers/solidstart'
2
1
  export {}
package/dist/ssgoi.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("solid-js/web"),n=require("solid-js"),a=require("./context.cjs"),c=require("@ssgoi/core/internal");var l=o.template("<div data-ssgoi-root style=display:contents>");const u=r=>{let t;const i=n.createMemo(()=>c.createSggoiTransitionContext(r.config,{host:r.host}));return n.createEffect(()=>{if(!t)return;const e=c.observeSsgoiTransitions(t,i());n.onCleanup(e)}),o.createComponent(a.SsgoiProvider,{get value(){return i()},get children(){var e=l(),s=t;return typeof s=="function"?o.use(s,e):t=e,o.insert(e,()=>r.children),e}})};exports.Ssgoi=u;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("solid-js/web"),i=require("solid-js"),s=require("./context.cjs"),a=require("@ssgoi/core/internal");var l=r.template("<div data-ssgoi-root style=display:contents>");const g=t=>{let n;const c=i.createMemo(()=>a.createSggoiTransitionContext(t.config,{host:t.host})),u=i.createMemo(()=>{const e=t.framework?.getRoute();if(!e)return;const o=e.renderedPath??e.pathname;return{routePath:o,chain:a.resolveLayoutChain(t.config.layouts,o)}});return i.createEffect(()=>{if(!n)return;const e=a.observeSsgoiTransitions(n,c());i.onCleanup(e)}),r.createComponent(s.SsgoiProvider,{get value(){return c()},get children(){return r.createComponent(s.SsgoiLayoutProvider,{value:u,get children(){var e=l(),o=n;return typeof o=="function"?r.use(o,e):n=e,r.insert(e,()=>t.children),e}})}})};exports.Ssgoi=g;
package/dist/ssgoi.d.ts CHANGED
@@ -1,9 +1,10 @@
1
1
  import { JSX } from 'solid-js';
2
- import { SsgoiConfig } from './types';
2
+ import { SsgoiConfig, SsgoiFramework } from './types';
3
3
  import { HostAnimation } from '@ssgoi/core/internal';
4
4
  interface SsgoiProps {
5
5
  config: SsgoiConfig;
6
6
  host?: HostAnimation;
7
+ framework?: SsgoiFramework;
7
8
  children: JSX.Element;
8
9
  }
9
10
  export declare const Ssgoi: (props: SsgoiProps) => JSX.Element;
package/dist/ssgoi.js CHANGED
@@ -1,27 +1,40 @@
1
- import { createComponent as i, insert as a, template as s, use as c } from "solid-js/web";
2
- import { createMemo as l, createEffect as m, onCleanup as f } from "solid-js";
3
- import { SsgoiProvider as u } from "./context.js";
4
- import { createSggoiTransitionContext as g, observeSsgoiTransitions as p } from "@ssgoi/core/internal";
5
- var v = /* @__PURE__ */ s("<div data-ssgoi-root style=display:contents>");
6
- const y = (o) => {
7
- let e;
8
- const r = l(() => g(o.config, {
9
- host: o.host
10
- }));
11
- return m(() => {
12
- if (!e) return;
13
- const t = p(e, r());
14
- f(t);
15
- }), i(u, {
1
+ import { createComponent as i, insert as s, template as u, use as l } from "solid-js/web";
2
+ import { createMemo as a, createEffect as f, onCleanup as m } from "solid-js";
3
+ import { SsgoiProvider as g, SsgoiLayoutProvider as d } from "./context.js";
4
+ import { createSggoiTransitionContext as v, resolveLayoutChain as h, observeSsgoiTransitions as y } from "@ssgoi/core/internal";
5
+ var p = /* @__PURE__ */ u("<div data-ssgoi-root style=display:contents>");
6
+ const _ = (e) => {
7
+ let r;
8
+ const n = a(() => v(e.config, {
9
+ host: e.host
10
+ })), c = a(() => {
11
+ const t = e.framework?.getRoute();
12
+ if (!t) return;
13
+ const o = t.renderedPath ?? t.pathname;
14
+ return {
15
+ routePath: o,
16
+ chain: h(e.config.layouts, o)
17
+ };
18
+ });
19
+ return f(() => {
20
+ if (!r) return;
21
+ const t = y(r, n());
22
+ m(t);
23
+ }), i(g, {
16
24
  get value() {
17
- return r();
25
+ return n();
18
26
  },
19
27
  get children() {
20
- var t = v(), n = e;
21
- return typeof n == "function" ? c(n, t) : e = t, a(t, () => o.children), t;
28
+ return i(d, {
29
+ value: c,
30
+ get children() {
31
+ var t = p(), o = r;
32
+ return typeof o == "function" ? l(o, t) : r = t, s(t, () => e.children), t;
33
+ }
34
+ });
22
35
  }
23
36
  });
24
37
  };
25
38
  export {
26
- y as Ssgoi
39
+ _ as Ssgoi
27
40
  };
package/dist/types.d.ts CHANGED
@@ -1 +1,12 @@
1
1
  export * from '@ssgoi/core/types';
2
+ /**
3
+ * Router bridge for `<Ssgoi framework>`. `getRoute` must be reactive, e.g.
4
+ * `() => ({ pathname: location.pathname })` with `useLocation()` from Solid
5
+ * Router. `renderedPath`, when given, is the path the page content shows.
6
+ */
7
+ export interface SsgoiFramework {
8
+ getRoute: () => {
9
+ pathname: string;
10
+ renderedPath?: string;
11
+ };
12
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ssgoi/solid",
3
- "version": "7.4.0",
4
- "description": "Solid.js bindings for SSGOI - Native app-like page transitions for Solid applications",
3
+ "version": "7.5.0-beta.0",
4
+ "description": "Native app-like page transitions for Solid and SolidStart. Make a web app, PWA or WebView app feel native.",
5
5
  "private": false,
6
6
  "type": "module",
7
7
  "files": [
@@ -38,14 +38,14 @@
38
38
  "default": "./dist/view-transitions.js"
39
39
  },
40
40
  "./solidstart": {
41
- "solid": "./src/lib/routers/solidstart.ts",
41
+ "solid": "./src/lib/legacy/solidstart.ts",
42
42
  "types": "./dist/routers/solidstart.d.ts",
43
43
  "import": "./dist/solidstart.js",
44
44
  "require": "./dist/solidstart.cjs",
45
45
  "default": "./dist/solidstart.js"
46
46
  },
47
47
  "./solid-router": {
48
- "solid": "./src/lib/routers/solid-router.tsx",
48
+ "solid": "./src/lib/legacy/solid-router.tsx",
49
49
  "types": "./dist/routers/solid-router.d.ts",
50
50
  "import": "./dist/solid-router.js",
51
51
  "require": "./dist/solid-router.cjs",
@@ -53,13 +53,15 @@
53
53
  }
54
54
  },
55
55
  "dependencies": {
56
- "@ssgoi/core": "^7.4.0"
56
+ "@ssgoi/core": "^7.5.0-beta.0"
57
57
  },
58
58
  "devDependencies": {
59
59
  "@eslint/js": "^9.30.1",
60
+ "@solidjs/router": "^0.16.1",
60
61
  "@types/node": "^24.10.1",
61
62
  "eslint": "^9.30.1",
62
63
  "globals": "^16.3.0",
64
+ "jsdom": "^26.1.0",
63
65
  "rollup-plugin-preserve-directives": "^0.4.0",
64
66
  "solid-js": "^1.9.13",
65
67
  "typescript": "~5.9.3",
@@ -67,19 +69,37 @@
67
69
  "vite": "^7.2.4",
68
70
  "vite-plugin-dts": "^4.5.4",
69
71
  "vite-plugin-solid": "^2.11.10",
70
- "@solidjs/router": "^0.16.1"
72
+ "vitest": "^3.2.4"
71
73
  },
72
74
  "peerDependencies": {
73
- "solid-js": "^1.0.0",
74
- "@solidjs/router": "*"
75
+ "@solidjs/router": "*",
76
+ "solid-js": "^1.0.0"
75
77
  },
76
78
  "keywords": [
77
79
  "solid",
78
80
  "solidjs",
81
+ "solid-router",
82
+ "solidstart",
79
83
  "page-transition",
84
+ "page-transitions",
85
+ "route-transition",
86
+ "navigation-animation",
87
+ "native-app",
88
+ "app-like",
89
+ "mobile-web",
90
+ "webview",
91
+ "pwa",
92
+ "capacitor",
93
+ "react-native-webview",
94
+ "hybrid-app",
95
+ "view-transitions",
96
+ "view-transition-api-alternative",
97
+ "shared-element-transition",
98
+ "hero-transition",
99
+ "spring-physics",
100
+ "web-animations",
80
101
  "animation",
81
- "ssgoi",
82
- "spring-physics"
102
+ "ssgoi"
83
103
  ],
84
104
  "author": "MeurSyphus <tmdeoans@snu.ac.kr>",
85
105
  "license": "MIT",
@@ -109,6 +129,7 @@
109
129
  "watch": "vite build --watch",
110
130
  "lint": "eslint .",
111
131
  "preview": "vite preview",
112
- "package": "vite build"
132
+ "package": "vite build",
133
+ "test:run": "vitest run"
113
134
  }
114
135
  }
@@ -1,9 +1,34 @@
1
- import { createContext, useContext } from "solid-js";
2
- import type { SsgoiContext } from "./types";
1
+ import {
2
+ createContext,
3
+ createSignal,
4
+ onCleanup,
5
+ useContext,
6
+ type Accessor,
7
+ } from "solid-js";
8
+ import type { SsgoiContext, SsgoiTransitionState } from "./types";
9
+
10
+ /** Route state `<Ssgoi>` resolves once for every layout boundary below it. */
11
+ export interface SsgoiLayoutState {
12
+ routePath: string;
13
+ chain: string[];
14
+ }
3
15
 
4
16
  const SsgoiContextInstance = createContext<SsgoiContext | null>(null);
17
+ const SsgoiLayoutContext = createContext<
18
+ Accessor<SsgoiLayoutState | undefined> | undefined
19
+ >(undefined);
20
+ const SsgoiLayoutDepthContext = createContext(0);
5
21
 
6
22
  export const SsgoiProvider = SsgoiContextInstance.Provider;
23
+ export const SsgoiLayoutProvider = SsgoiLayoutContext.Provider;
24
+ /** Gives descendants of a layout boundary their depth. */
25
+ export const SsgoiLayoutDepthProvider = SsgoiLayoutDepthContext.Provider;
26
+
27
+ /** Layout state of the nearest `<Ssgoi>`; undefined without a framework. */
28
+ export const useSsgoiLayout = () => useContext(SsgoiLayoutContext);
29
+
30
+ /** Depth of the calling layout boundary: 0 unless inside another. */
31
+ export const useLayoutDepth = () => useContext(SsgoiLayoutDepthContext);
7
32
 
8
33
  export const useSsgoi = () => {
9
34
  const context = useContext(SsgoiContextInstance);
@@ -12,3 +37,24 @@ export const useSsgoi = () => {
12
37
  }
13
38
  return context;
14
39
  };
40
+
41
+ /**
42
+ * Signal of the provider's transition lifecycle: whether a page transition is
43
+ * preparing or playing, and which routes it joins.
44
+ *
45
+ * Use it to defer work that would fight the animation, such as a programmatic
46
+ * scroll on the arriving page, until the status returns to `"idle"`.
47
+ *
48
+ * Must be called under `<Ssgoi>`.
49
+ */
50
+ export const useSsgoiTransition = (): Accessor<SsgoiTransitionState> => {
51
+ const context = useContext(SsgoiContextInstance);
52
+ if (!context) {
53
+ throw new Error("useSsgoiTransition must be used within <Ssgoi>");
54
+ }
55
+ const [state, setState] = createSignal<SsgoiTransitionState>(
56
+ context.getTransitionState(),
57
+ );
58
+ onCleanup(context.subscribe((next) => setState(() => next)));
59
+ return state;
60
+ };
package/src/lib/index.ts CHANGED
@@ -1,5 +1,8 @@
1
1
  export * from "./types";
2
2
  export { Ssgoi } from "./ssgoi";
3
- /** @deprecated Set `data-ssgoi-transition` directly on an element inside `<Ssgoi>` instead. */
4
- export { SsgoiTransition } from "./ssgoi-transition";
3
+ export { useSsgoiTransition } from "./context";
4
+ export { SsgoiLayoutBoundary } from "./layout-boundary";
5
+ export type { SsgoiLayoutBoundaryProps } from "./layout-boundary";
6
+ /** @deprecated Will be removed in 8.0.0. */
7
+ export { SsgoiTransition } from "./legacy/ssgoi-transition";
5
8
  export * from "@ssgoi/core";
@@ -0,0 +1,72 @@
1
+ import {
2
+ createMemo,
3
+ Show,
4
+ splitProps,
5
+ type Accessor,
6
+ type JSX,
7
+ } from "solid-js";
8
+ import { Dynamic } from "solid-js/web";
9
+ import {
10
+ SsgoiLayoutDepthProvider,
11
+ useLayoutDepth,
12
+ useSsgoiLayout,
13
+ } from "./context";
14
+
15
+ export type SsgoiLayoutBoundaryProps = JSX.HTMLAttributes<HTMLElement> & {
16
+ as?: keyof JSX.IntrinsicElements;
17
+ };
18
+
19
+ /** Shared rendering; remounts its element whenever `state().key` changes. */
20
+ export function RouteBoundary(
21
+ props: SsgoiLayoutBoundaryProps & {
22
+ state: Accessor<{ id: string; key: string | number }>;
23
+ },
24
+ ) {
25
+ const [local, rest] = splitProps(props, ["children", "as", "state"]);
26
+ // Show uses truthiness. A token also supports valid keys such as 0 and "".
27
+ const lifetime = createMemo<{ key: string | number }>((previous) => {
28
+ const key = local.state().key;
29
+ return previous?.key === key ? previous : { key };
30
+ });
31
+
32
+ return (
33
+ <Show when={lifetime()} keyed>
34
+ {(_lifetime) => (
35
+ <Dynamic
36
+ component={local.as ?? "div"}
37
+ {...rest}
38
+ data-ssgoi-transition={local.state().id}
39
+ >
40
+ {local.children}
41
+ </Dynamic>
42
+ )}
43
+ </Show>
44
+ );
45
+ }
46
+
47
+ function throwMissingFramework(): never {
48
+ throw new Error(
49
+ "SSGOI: SsgoiLayoutBoundary requires a framework. Pass it to <Ssgoi framework={{ getRoute }}>.",
50
+ );
51
+ }
52
+
53
+ export function SsgoiLayoutBoundary(props: SsgoiLayoutBoundaryProps) {
54
+ const layout = useSsgoiLayout();
55
+ if (!layout?.()) throwMissingFramework();
56
+ const depth = useLayoutDepth();
57
+ const [local, rest] = splitProps(props, ["children"]);
58
+ // The config's layout scope at this depth keeps the DOM; past the declared
59
+ // scopes every route path remounts.
60
+ const state = createMemo(() => {
61
+ const { routePath, chain } = layout() ?? throwMissingFramework();
62
+ return { id: routePath, key: chain[depth] ?? routePath };
63
+ });
64
+
65
+ return (
66
+ <RouteBoundary {...rest} state={state}>
67
+ <SsgoiLayoutDepthProvider value={depth + 1}>
68
+ {local.children}
69
+ </SsgoiLayoutDepthProvider>
70
+ </RouteBoundary>
71
+ );
72
+ }
@@ -0,0 +1,33 @@
1
+ // TODO(8.0.0): remove this entry (deprecated in 7.5.0).
2
+ import { useLocation } from "@solidjs/router";
3
+ import { createMemo, splitProps, type JSX } from "solid-js";
4
+ import { RouteBoundary } from "../layout-boundary";
5
+
6
+ /** @deprecated Will be removed in 8.0.0. Declare layout scopes in `config.layouts` and use `SsgoiLayoutBoundary` from "@ssgoi/solid" instead. */
7
+ export interface RouteBoundaryState {
8
+ id: string;
9
+ key?: string | number;
10
+ }
11
+
12
+ /** @deprecated Will be removed in 8.0.0. Declare layout scopes in `config.layouts` and use `SsgoiLayoutBoundary` from "@ssgoi/solid" instead. */
13
+ export type SsgoiRouteBoundaryProps = JSX.HTMLAttributes<HTMLElement> & {
14
+ as?: keyof JSX.IntrinsicElements;
15
+ routeKey?: string | number;
16
+ resolve?: (location: { pathname: string }) => RouteBoundaryState;
17
+ };
18
+
19
+ /**
20
+ * @experimental Solid Router integration, including SolidStart. The API may change.
21
+ * @deprecated Will be removed in 8.0.0. Use `SsgoiLayoutBoundary` from "@ssgoi/solid" with `<Ssgoi framework={{ getRoute: () => ({ pathname: location.pathname }) }}>` (`useLocation` from "@solidjs/router") instead.
22
+ */
23
+ export function SsgoiRouteBoundary(props: SsgoiRouteBoundaryProps) {
24
+ const location = useLocation();
25
+ const [local, rest] = splitProps(props, ["resolve", "routeKey"]);
26
+ const state = createMemo(() => {
27
+ const current = local.resolve?.({ pathname: location.pathname }) ?? {
28
+ id: location.pathname,
29
+ };
30
+ return { id: current.id, key: local.routeKey ?? current.key ?? current.id };
31
+ });
32
+ return <RouteBoundary {...rest} state={state} />;
33
+ }
@@ -0,0 +1,12 @@
1
+ // TODO(8.0.0): remove this entry (deprecated in 7.5.0).
2
+ /**
3
+ * @experimental SolidStart integration through Solid Router. The API may change.
4
+ * @deprecated Will be removed in 8.0.0. Use `SsgoiLayoutBoundary` from "@ssgoi/solid" with `<Ssgoi framework={{ getRoute: () => ({ pathname: location.pathname }) }}>` (`useLocation` from "@solidjs/router") instead.
5
+ */
6
+ export { SsgoiRouteBoundary } from "./solid-router";
7
+ export type {
8
+ /** @deprecated Will be removed in 8.0.0. Declare layout scopes in `config.layouts` and use `SsgoiLayoutBoundary` from "@ssgoi/solid" instead. */
9
+ SsgoiRouteBoundaryProps,
10
+ /** @deprecated Will be removed in 8.0.0. Declare layout scopes in `config.layouts` and use `SsgoiLayoutBoundary` from "@ssgoi/solid" instead. */
11
+ RouteBoundaryState,
12
+ } from "./solid-router";
@@ -1,7 +1,9 @@
1
+ // TODO(8.0.0): remove this entry (deprecated in 7.5.0).
1
2
  import { splitProps, type JSX, type ValidComponent } from "solid-js";
2
3
  import { Dynamic } from "solid-js/web";
3
- import { useSsgoi } from "./context";
4
+ import { useSsgoi } from "../context";
4
5
 
6
+ /** @deprecated Will be removed in 8.0.0. */
5
7
  type SsgoiTransitionProps<T extends ValidComponent = "div"> = {
6
8
  children: JSX.Element;
7
9
  id: string;
@@ -9,10 +11,7 @@ type SsgoiTransitionProps<T extends ValidComponent = "div"> = {
9
11
  class?: string;
10
12
  };
11
13
 
12
- /**
13
- * @deprecated Set `data-ssgoi-transition` directly on the page boundary
14
- * element inside `<Ssgoi>` instead.
15
- */
14
+ /** @deprecated Will be removed in 8.0.0. */
16
15
  export const SsgoiTransition = <T extends ValidComponent = "div">(
17
16
  props: SsgoiTransitionProps<T>,
18
17
  ) => {
package/src/lib/ssgoi.tsx CHANGED
@@ -1,15 +1,17 @@
1
1
  import { createEffect, createMemo, onCleanup, type JSX } from "solid-js";
2
- import type { SsgoiConfig, SsgoiContext } from "./types";
3
- import { SsgoiProvider } from "./context";
2
+ import type { SsgoiConfig, SsgoiContext, SsgoiFramework } from "./types";
3
+ import { SsgoiLayoutProvider, SsgoiProvider } from "./context";
4
4
  import {
5
5
  createSggoiTransitionContext,
6
6
  observeSsgoiTransitions,
7
+ resolveLayoutChain,
7
8
  } from "@ssgoi/core/internal";
8
9
  import type { HostAnimation } from "@ssgoi/core/internal";
9
10
 
10
11
  interface SsgoiProps {
11
12
  config: SsgoiConfig;
12
13
  host?: HostAnimation;
14
+ framework?: SsgoiFramework;
13
15
  children: JSX.Element;
14
16
  }
15
17
 
@@ -19,6 +21,17 @@ export const Ssgoi = (props: SsgoiProps) => {
19
21
  createSggoiTransitionContext(props.config, { host: props.host }),
20
22
  );
21
23
 
24
+ // Resolve the route once; every SsgoiLayoutBoundary keys off this chain.
25
+ const layout = createMemo(() => {
26
+ const route = props.framework?.getRoute();
27
+ if (!route) return undefined;
28
+ const routePath = route.renderedPath ?? route.pathname;
29
+ return {
30
+ routePath,
31
+ chain: resolveLayoutChain(props.config.layouts, routePath),
32
+ };
33
+ });
34
+
22
35
  createEffect(() => {
23
36
  if (!root) return;
24
37
  const cleanup = observeSsgoiTransitions(root, contextValue());
@@ -27,9 +40,11 @@ export const Ssgoi = (props: SsgoiProps) => {
27
40
 
28
41
  return (
29
42
  <SsgoiProvider value={contextValue()}>
30
- <div ref={root} data-ssgoi-root="" style={{ display: "contents" }}>
31
- {props.children}
32
- </div>
43
+ <SsgoiLayoutProvider value={layout}>
44
+ <div ref={root} data-ssgoi-root="" style={{ display: "contents" }}>
45
+ {props.children}
46
+ </div>
47
+ </SsgoiLayoutProvider>
33
48
  </SsgoiProvider>
34
49
  );
35
50
  };
package/src/lib/types.ts CHANGED
@@ -1 +1,10 @@
1
1
  export * from "@ssgoi/core/types";
2
+
3
+ /**
4
+ * Router bridge for `<Ssgoi framework>`. `getRoute` must be reactive, e.g.
5
+ * `() => ({ pathname: location.pathname })` with `useLocation()` from Solid
6
+ * Router. `renderedPath`, when given, is the path the page content shows.
7
+ */
8
+ export interface SsgoiFramework {
9
+ getRoute: () => { pathname: string; renderedPath?: string };
10
+ }
@@ -1 +0,0 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("solid-js/web"),a=require("solid-js"),l=require("./context.cjs"),u=t=>{const[e,o]=a.splitProps(t,["children","id","as","class"]),n=l.useSsgoi(),i=e.as||"div";return r.createComponent(r.Dynamic,r.mergeProps({component:i,ref(c){var s=n.refFor(e.id);typeof s=="function"&&s(c)},get"data-ssgoi-transition"(){return e.id},get class(){return e.class}},o,{get children(){return e.children}}))};exports.SsgoiTransition=u;
@@ -1,51 +0,0 @@
1
- import { useLocation } from "@solidjs/router";
2
- import { createMemo, Show, splitProps, type JSX } from "solid-js";
3
- import { Dynamic } from "solid-js/web";
4
-
5
- export interface RouteBoundaryState {
6
- id: string;
7
- key?: string | number;
8
- }
9
-
10
- export type SsgoiRouteBoundaryProps = JSX.HTMLAttributes<HTMLElement> & {
11
- as?: keyof JSX.IntrinsicElements;
12
- routeKey?: string | number;
13
- resolve?: (location: { pathname: string }) => RouteBoundaryState;
14
- };
15
-
16
- /** @experimental Solid Router integration, including SolidStart. The API may change. */
17
- export function SsgoiRouteBoundary(props: SsgoiRouteBoundaryProps) {
18
- const location = useLocation();
19
- const [local, rest] = splitProps(props, [
20
- "children",
21
- "as",
22
- "resolve",
23
- "routeKey",
24
- ]);
25
- const boundary = createMemo(
26
- () =>
27
- local.resolve?.({ pathname: location.pathname }) ?? {
28
- id: location.pathname,
29
- },
30
- );
31
- // Show uses truthiness. A token also supports valid keys such as 0 and "".
32
- const lifetime = createMemo<{ key: string | number }>((previous) => {
33
- const current = boundary();
34
- const key = local.routeKey ?? current.key ?? current.id;
35
- return previous?.key === key ? previous : { key };
36
- });
37
-
38
- return (
39
- <Show when={lifetime()} keyed>
40
- {(_lifetime) => (
41
- <Dynamic
42
- component={local.as ?? "div"}
43
- {...rest}
44
- data-ssgoi-transition={boundary().id}
45
- >
46
- {local.children}
47
- </Dynamic>
48
- )}
49
- </Show>
50
- );
51
- }
@@ -1,6 +0,0 @@
1
- /** @experimental SolidStart integration through Solid Router. The API may change. */
2
- export { SsgoiRouteBoundary } from "./solid-router";
3
- export type {
4
- SsgoiRouteBoundaryProps,
5
- RouteBoundaryState,
6
- } from "./solid-router";