@ssgoi/react 4.1.0 → 4.2.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.
@@ -1,10 +1,9 @@
1
- import { ReactNode, ElementType, CSSProperties } from 'react';
1
+ import { ReactNode, ElementType } from 'react';
2
2
  type SsgoiTransitionProps<T extends ElementType = "div"> = {
3
3
  children: ReactNode;
4
4
  id: string;
5
5
  as?: T;
6
6
  className?: string;
7
- style?: CSSProperties;
8
7
  };
9
- export declare const SsgoiTransition: <T extends ElementType = "div">({ children, id, as, className, style, ...rest }: SsgoiTransitionProps<T>) => import("react/jsx-runtime").JSX.Element;
8
+ export declare const SsgoiTransition: <T extends ElementType = "div">({ children, id, as, className, ...rest }: SsgoiTransitionProps<T>) => import("react/jsx-runtime").JSX.Element;
10
9
  export {};
@@ -4,11 +4,12 @@ interface SsgoiProps {
4
4
  config: SsgoiConfig;
5
5
  children: ReactNode;
6
6
  /**
7
- * Function to get current pathname
8
- * Used to determine initial style and navigation detection
9
- * @example Next.js: () => usePathname()
7
+ * Hook to get current pathname (e.g., Next.js usePathname)
8
+ * @example
9
+ * import { usePathname } from 'next/navigation';
10
+ * <Ssgoi config={config} usePathname={usePathname}>
10
11
  */
11
- getPathname?: () => string;
12
+ usePathname?: () => string;
12
13
  }
13
14
  export declare const Ssgoi: React.FC<SsgoiProps>;
14
15
  export {};
@@ -1,6 +1,13 @@
1
1
  import { CSSProperties } from 'react';
2
2
  import { SsgoiContext } from '@ssgoi/core/types';
3
3
  export * from '@ssgoi/core/types';
4
+ /**
5
+ * Navigation info containing from/to paths
6
+ */
7
+ export type NavigationInfo = {
8
+ from: string | null;
9
+ to: string;
10
+ };
4
11
  /**
5
12
  * React-specific context type with style control
6
13
  */
@@ -9,7 +16,8 @@ export type ReactSsgoiContext = {
9
16
  getTransition: SsgoiContext;
10
17
  /**
11
18
  * Get initial style for an element
12
- * Returns { visibility: "hidden" } if transition is configured, {} otherwise
19
+ * Returns { visibility: "hidden" } on first call if transition is configured, {} otherwise
20
+ * Subsequent calls always return {} to prevent re-hiding on rerender
13
21
  */
14
- getInitialStyle: (path: string) => CSSProperties;
22
+ getInitialStyle: () => CSSProperties;
15
23
  };
@@ -0,0 +1,10 @@
1
+ import { CSSProperties } from 'react';
2
+ /**
3
+ * Combines multiple ref callbacks into one
4
+ */
5
+ export declare function combineRefs<T>(...refs: Array<((el: T | null) => void) | null | undefined>): (el: T | null) => void;
6
+ /**
7
+ * Forks style from element.style based on initialStyle keys
8
+ * Returns the current DOM style values for keys that were in initialStyle
9
+ */
10
+ export declare function forkStyleFromElement(element: HTMLElement, initialStyle: CSSProperties): CSSProperties;
@@ -1,2 +1,2 @@
1
1
  "use client";
2
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const g=require("react/jsx-runtime"),l=require("./transition.cjs"),S=require("./context.cjs"),y=({children:n,id:t,as:i,className:e,style:o,...s})=>{const{getTransition:r,getInitialStyle:a}=S.useSsgoi(),c=i||"div",u=a(t);return g.jsx(c,{ref:l.transition(r(t)),"data-ssgoi-transition":t,className:e,style:{...o,...u},...s,children:n})};exports.SsgoiTransition=y;
2
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const d=require("react/jsx-runtime"),r=require("react"),q=require("./transition.cjs"),b=require("./context.cjs"),o=require("./utils.cjs"),T=({children:c,id:i,as:u,className:l,...f})=>{const{getTransition:a,getInitialStyle:R}=b.useSsgoi(),S=u||"div",t=r.useRef(null),s=r.useRef(!0),e=r.useRef(null);e.current===null&&(e.current=R());let n;s.current?n=e.current:t.current&&e.current&&(n=o.forkStyleFromElement(t.current,e.current));const g=q.transition(a(i)),m=o.combineRefs(y=>{t.current=y,s.current=!1},g);return d.jsx(S,{ref:m,"data-ssgoi-transition":i,className:l,style:n,...f,children:c})};exports.SsgoiTransition=T;
@@ -1,28 +1,38 @@
1
1
  "use client";
2
- import { jsx as l } from "react/jsx-runtime";
3
- import { transition as p } from "./transition.js";
4
- import { useSsgoi as c } from "./context.js";
5
- const u = ({
6
- children: o,
7
- id: t,
8
- as: i,
9
- className: n,
10
- style: s,
11
- ...r
2
+ import { jsx as g } from "react/jsx-runtime";
3
+ import { useRef as n } from "react";
4
+ import { transition as y } from "./transition.js";
5
+ import { useSsgoi as d } from "./context.js";
6
+ import { forkStyleFromElement as b, combineRefs as x } from "./utils.js";
7
+ const C = ({
8
+ children: s,
9
+ id: o,
10
+ as: c,
11
+ className: f,
12
+ ...l
12
13
  }) => {
13
- const { getTransition: e, getInitialStyle: a } = c(), m = i || "div", g = a(t);
14
- return /* @__PURE__ */ l(
15
- m,
14
+ const { getTransition: u, getInitialStyle: m } = d(), a = c || "div", r = n(null), i = n(!0), t = n(null);
15
+ t.current === null && (t.current = m());
16
+ let e;
17
+ i.current ? e = t.current : r.current && t.current && (e = b(
18
+ r.current,
19
+ t.current
20
+ ));
21
+ const R = y(u(o)), p = x((S) => {
22
+ r.current = S, i.current = !1;
23
+ }, R);
24
+ return /* @__PURE__ */ g(
25
+ a,
16
26
  {
17
- ref: p(e(t)),
18
- "data-ssgoi-transition": t,
19
- className: n,
20
- style: { ...s, ...g },
21
- ...r,
22
- children: o
27
+ ref: p,
28
+ "data-ssgoi-transition": o,
29
+ className: f,
30
+ style: e,
31
+ ...l,
32
+ children: s
23
33
  }
24
34
  );
25
35
  };
26
36
  export {
27
- u as SsgoiTransition
37
+ C as SsgoiTransition
28
38
  };
@@ -1,2 +1,2 @@
1
1
  "use client";
2
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const f=require("react/jsx-runtime"),n=require("react"),g=require("./context.cjs"),i=require("@ssgoi/core"),d=require("./create-pathname-detector.cjs"),m=n.memo(({config:o,children:c,getPathname:e})=>{const t=n.useRef(null),s=n.useMemo(()=>{const{getTransition:u,hasMatchingTransition:a}=i.createSggoiTransitionContext(o,{outFirst:!1,createNavigationDetector:e?()=>d.createPathnameDetector(e):i.createAnyOrderDetector});return{getTransition:u,getInitialStyle:l=>{if(!e)return{};const r=e();if(!t.current||t.current===r)return t.current=r,{};const S=t.current;return t.current=r,a(S,l)?{visibility:"hidden"}:{}}}},[o,e]);return f.jsx(g.SsgoiProvider,{value:s,children:c})});exports.Ssgoi=m;
2
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("react/jsx-runtime"),o=require("react"),v=require("./context.cjs"),s=require("@ssgoi/core");function R(t){const n=o.useRef(null),e=o.useRef(null);t!==null&&n.current!==t&&(e.current=n.current,n.current=t);const r=o.useRef({from:null,to:""});return t!==null&&(r.current={from:e.current,to:t}),o.useCallback(()=>r.current,[])}function S(t){return{trigger(){},get(n){const{from:e,to:r}=t();return!e||!r||e===r?Promise.resolve(null):Promise.resolve({from:e,to:r})}}}const y=o.memo(({config:t,children:n,usePathname:e})=>{const r=e?.()??null,i=R(r),l=o.useMemo(()=>{const{getTransition:g,hasMatchingTransition:f}=s.createSggoiTransitionContext(t,{createNavigationDetector:e?()=>S(i):s.createAnyOrderDetector});return{getTransition:g,getInitialStyle:()=>{if(!e)return{};const{from:u,to:c}=i();return!u||u===c?{}:f(u,c)?{visibility:"hidden"}:{}}}},[t,e,i]);return a.jsx(v.SsgoiProvider,{value:l,children:n})});exports.Ssgoi=y;
@@ -1,36 +1,43 @@
1
1
  "use client";
2
- import { jsx as m } from "react/jsx-runtime";
3
- import f, { useRef as l, useMemo as p } from "react";
4
- import { SsgoiProvider as v } from "./context.js";
5
- import { createSggoiTransitionContext as S, createAnyOrderDetector as d } from "@ssgoi/core";
6
- import { createPathnameDetector as g } from "./create-pathname-detector.js";
7
- const I = f.memo(
8
- ({ config: o, children: n, getPathname: r }) => {
9
- const t = l(null), i = p(() => {
10
- const { getTransition: c, hasMatchingTransition: s } = S(o, {
11
- // React uses MutationObserver for unmount detection,
12
- // so OUT and IN can arrive in any order
13
- outFirst: !1,
14
- // Use pathname-based detector when getPathname is provided,
15
- // otherwise use default any-order detector for React
16
- createNavigationDetector: r ? () => g(r) : d
2
+ import { jsx as g } from "react/jsx-runtime";
3
+ import a, { useMemo as m, useRef as c, useCallback as v } from "react";
4
+ import { SsgoiProvider as y } from "./context.js";
5
+ import { createSggoiTransitionContext as R, createAnyOrderDetector as S } from "@ssgoi/core";
6
+ function d(t) {
7
+ const n = c(null), r = c(null);
8
+ t !== null && n.current !== t && (r.current = n.current, n.current = t);
9
+ const e = c({ from: null, to: "" });
10
+ return t !== null && (e.current = { from: r.current, to: t }), v(() => e.current, []);
11
+ }
12
+ function p(t) {
13
+ return {
14
+ trigger() {
15
+ },
16
+ get(n) {
17
+ const { from: r, to: e } = t();
18
+ return !r || !e || r === e ? Promise.resolve(null) : Promise.resolve({ from: r, to: e });
19
+ }
20
+ };
21
+ }
22
+ const C = a.memo(
23
+ ({ config: t, children: n, usePathname: r }) => {
24
+ const e = r?.() ?? null, o = d(e), l = m(() => {
25
+ const { getTransition: s, hasMatchingTransition: f } = R(t, {
26
+ createNavigationDetector: r ? () => p(o) : S
17
27
  });
18
28
  return {
19
- getTransition: c,
20
- getInitialStyle: (u) => {
29
+ getTransition: s,
30
+ getInitialStyle: () => {
21
31
  if (!r)
22
32
  return {};
23
- const e = r();
24
- if (!t.current || t.current === e)
25
- return t.current = e, {};
26
- const a = t.current;
27
- return t.current = e, s(a, u) ? { visibility: "hidden" } : {};
33
+ const { from: i, to: u } = o();
34
+ return !i || i === u ? {} : f(i, u) ? { visibility: "hidden" } : {};
28
35
  }
29
36
  };
30
- }, [o, r]);
31
- return /* @__PURE__ */ m(v, { value: i, children: n });
37
+ }, [t, r, o]);
38
+ return /* @__PURE__ */ g(y, { value: l, children: n });
32
39
  }
33
40
  );
34
41
  export {
35
- I as Ssgoi
42
+ C as Ssgoi
36
43
  };
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function f(...t){return o=>{t.forEach(e=>e?.(o))}}function c(t,o){const e={};for(const n of Object.keys(o)){const r=t.style[n];r&&(e[n]=r)}return e}exports.combineRefs=f;exports.forkStyleFromElement=c;
@@ -0,0 +1,17 @@
1
+ function f(...o) {
2
+ return (t) => {
3
+ o.forEach((e) => e?.(t));
4
+ };
5
+ }
6
+ function c(o, t) {
7
+ const e = {};
8
+ for (const n of Object.keys(t)) {
9
+ const r = o.style[n];
10
+ r && (e[n] = r);
11
+ }
12
+ return e;
13
+ }
14
+ export {
15
+ f as combineRefs,
16
+ c as forkStyleFromElement
17
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ssgoi/react",
3
- "version": "4.1.0",
3
+ "version": "4.2.0",
4
4
  "description": "React bindings for SSGOI - Native app-like page transitions for React applications",
5
5
  "private": false,
6
6
  "type": "module",
@@ -1,6 +0,0 @@
1
- import { NavigationDetector } from '@ssgoi/core';
2
- /**
3
- * Creates a NavigationDetector based on pathname changes
4
- * Uses getPathname() to detect navigation without relying on IN/OUT callbacks
5
- */
6
- export declare function createPathnameDetector(getPathname: () => string): NavigationDetector;
@@ -1 +0,0 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function s(o){let e=null,t=null,r=!1,l=!1;return{trigger(){},get(u){const n=o();if(!t||r&&l){if(!e||e===n)return e=n,Promise.resolve(null);t={from:e,to:n},r=!1,l=!1}u==="out"?r=!0:l=!0;const a=t;return r&&l&&(e=n,t=null),Promise.resolve(a)}}}exports.createPathnameDetector=s;
@@ -1,24 +0,0 @@
1
- function s(u) {
2
- let e = null, t = null, r = !1, l = !1;
3
- return {
4
- trigger() {
5
- },
6
- get(o) {
7
- const n = u();
8
- if (!t || r && l) {
9
- if (!e || e === n)
10
- return e = n, Promise.resolve(null);
11
- t = {
12
- from: e,
13
- to: n
14
- }, r = !1, l = !1;
15
- }
16
- o === "out" ? r = !0 : l = !0;
17
- const a = t;
18
- return r && l && (e = n, t = null), Promise.resolve(a);
19
- }
20
- };
21
- }
22
- export {
23
- s as createPathnameDetector
24
- };