@ssgoi/react 3.2.2 → 4.0.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.
Files changed (36) hide show
  1. package/README.md +162 -57
  2. package/dist/core/dist/types.cjs +1 -1
  3. package/dist/core/dist/types.js +7 -7
  4. package/dist/index.d.ts +2 -5
  5. package/dist/lib/index.d.ts +5 -0
  6. package/dist/lib/presets/index.d.ts +1 -0
  7. package/dist/{transition.d.ts → lib/transition.d.ts} +3 -1
  8. package/dist/lib/transitions/index.d.ts +1 -0
  9. package/dist/lib/types.d.ts +1 -0
  10. package/dist/lib/view-transitions/index.d.ts +1 -0
  11. package/dist/presets/index.d.ts +2 -1
  12. package/dist/react/src/lib/transition.cjs +1 -1
  13. package/dist/react/src/lib/transition.js +12 -3
  14. package/dist/transitions/index.d.ts +2 -1
  15. package/dist/types.d.ts +2 -1
  16. package/dist/unplugin/esbuild.cjs +1 -0
  17. package/dist/unplugin/esbuild.d.ts +2 -0
  18. package/dist/unplugin/esbuild.js +5 -0
  19. package/dist/unplugin/index.cjs +1 -0
  20. package/dist/unplugin/index.d.ts +14 -0
  21. package/dist/unplugin/index.js +116 -0
  22. package/dist/unplugin/rollup.cjs +1 -0
  23. package/dist/unplugin/rollup.d.ts +2 -0
  24. package/dist/unplugin/rollup.js +5 -0
  25. package/dist/unplugin/vite.cjs +1 -0
  26. package/dist/unplugin/vite.d.ts +2 -0
  27. package/dist/unplugin/vite.js +5 -0
  28. package/dist/unplugin/webpack.cjs +1 -0
  29. package/dist/unplugin/webpack.d.ts +2 -0
  30. package/dist/unplugin/webpack.js +5 -0
  31. package/dist/view-transitions/index.d.ts +2 -1
  32. package/package.json +36 -2
  33. /package/dist/{context.d.ts → lib/context.d.ts} +0 -0
  34. /package/dist/{ssgoi-transition.d.ts → lib/ssgoi-transition.d.ts} +0 -0
  35. /package/dist/{ssgoi.d.ts → lib/ssgoi.d.ts} +0 -0
  36. /package/dist/{transition-scope.d.ts → lib/transition-scope.d.ts} +0 -0
package/README.md CHANGED
@@ -33,15 +33,13 @@ pnpm add @ssgoi/react
33
33
  ### 1. Wrap your app
34
34
 
35
35
  ```tsx
36
- import { Ssgoi } from '@ssgoi/react';
37
- import { fade } from '@ssgoi/react/view-transitions';
36
+ import { Ssgoi } from "@ssgoi/react";
37
+ import { fade } from "@ssgoi/react/view-transitions";
38
38
 
39
39
  export default function App() {
40
40
  return (
41
41
  <Ssgoi config={{ defaultTransition: fade() }}>
42
- <div style={{ position: 'relative' }}>
43
- {/* Your app */}
44
- </div>
42
+ <div style={{ position: "relative" }}>{/* Your app */}</div>
45
43
  </Ssgoi>
46
44
  );
47
45
  }
@@ -50,7 +48,7 @@ export default function App() {
50
48
  ### 2. Wrap your pages
51
49
 
52
50
  ```tsx
53
- import { SsgoiTransition } from '@ssgoi/react';
51
+ import { SsgoiTransition } from "@ssgoi/react";
54
52
 
55
53
  export default function HomePage() {
56
54
  return (
@@ -74,16 +72,20 @@ Define different transitions for different routes:
74
72
  const config = {
75
73
  transitions: [
76
74
  // Scroll between tabs
77
- { from: '/home', to: '/about', transition: scroll({ direction: 'up' }) },
78
- { from: '/about', to: '/home', transition: scroll({ direction: 'down' }) },
79
-
75
+ { from: "/home", to: "/about", transition: scroll({ direction: "up" }) },
76
+ { from: "/about", to: "/home", transition: scroll({ direction: "down" }) },
77
+
80
78
  // Drill in when entering details
81
- { from: '/products', to: '/products/*', transition: drill({ direction: 'enter' }) },
82
-
79
+ {
80
+ from: "/products",
81
+ to: "/products/*",
82
+ transition: drill({ direction: "enter" }),
83
+ },
84
+
83
85
  // Pinterest-style image transitions
84
- { from: '/gallery', to: '/photo/*', transition: pinterest() }
86
+ { from: "/gallery", to: "/photo/*", transition: pinterest() },
85
87
  ],
86
- defaultTransition: fade()
88
+ defaultTransition: fade(),
87
89
  };
88
90
  ```
89
91
 
@@ -94,7 +96,7 @@ Automatically create bidirectional transitions:
94
96
  ```tsx
95
97
  {
96
98
  from: '/home',
97
- to: '/about',
99
+ to: '/about',
98
100
  transition: scroll({ direction: 'up' }),
99
101
  symmetric: true // Automatically creates reverse transition
100
102
  }
@@ -105,37 +107,138 @@ Automatically create bidirectional transitions:
105
107
  Animate specific elements during mount/unmount:
106
108
 
107
109
  ```tsx
108
- import { transition } from '@ssgoi/react';
109
- import { fadeIn, slideUp } from '@ssgoi/react/transitions';
110
+ import { transition } from "@ssgoi/react";
111
+ import { fade, slide } from "@ssgoi/react/transitions";
110
112
 
111
113
  function Card() {
112
114
  return (
113
- <div ref={transition({
114
- key: 'card',
115
- in: fadeIn(),
116
- out: slideUp()
117
- })}>
115
+ <div
116
+ ref={transition({
117
+ key: "card",
118
+ in: fade(),
119
+ out: slide({ direction: "up" }),
120
+ })}
121
+ >
118
122
  <h2>Animated Card</h2>
119
123
  </div>
120
124
  );
121
125
  }
122
126
  ```
123
127
 
128
+ ### Auto Key Plugin
129
+
130
+ The Auto Key Plugin automatically generates unique keys for your transitions based on the file location (`file:line:column`), eliminating the need to manually provide keys.
131
+
132
+ **Benefits:**
133
+
134
+ - **Automatic Key Generation**: No need to manually specify `key` in `transition()` calls
135
+ - **Collision-Free**: Keys are based on exact code location
136
+ - **Cleaner Code**: Less boilerplate in your components
137
+
138
+ **⚠️ Important**: For list items rendered with `.map()`, just use JSX key prop - the plugin automatically appends it to generate unique keys.
139
+
140
+ #### Setup with Next.js
141
+
142
+ ```tsx
143
+ // next.config.ts
144
+ import type { NextConfig } from "next";
145
+ import SsgoiAutoKey from "@ssgoi/react/unplugin/webpack";
146
+
147
+ const nextConfig: NextConfig = {
148
+ webpack: (config) => {
149
+ config.plugins.push(SsgoiAutoKey());
150
+ return config;
151
+ },
152
+ };
153
+
154
+ export default nextConfig;
155
+ ```
156
+
157
+ #### Setup with Vite
158
+
159
+ ```ts
160
+ // vite.config.ts
161
+ import { defineConfig } from "vite";
162
+ import react from "@vitejs/plugin-react";
163
+ import SsgoiAutoKey from "@ssgoi/react/unplugin/vite";
164
+
165
+ export default defineConfig({
166
+ plugins: [react(), SsgoiAutoKey()],
167
+ });
168
+ ```
169
+
170
+ #### Usage Examples
171
+
172
+ **WITH Auto Key Plugin (Recommended):**
173
+
174
+ ```tsx
175
+ import { transition } from "@ssgoi/react";
176
+ import { fade, slide } from "@ssgoi/react/transitions";
177
+
178
+ function SimpleCard() {
179
+ return (
180
+ <div ref={transition(fade())}>
181
+ <h2>Fades in on mount</h2>
182
+ </div>
183
+ );
184
+ }
185
+ ```
186
+
187
+ **WITHOUT Auto Key Plugin:**
188
+
189
+ ```tsx
190
+ // Explicit key required for transition state tracking
191
+ function Card() {
192
+ return (
193
+ <div
194
+ ref={transition({
195
+ key: "my-card",
196
+ ...fade(),
197
+ })}
198
+ >
199
+ <h2>Animated Card</h2>
200
+ </div>
201
+ );
202
+ }
203
+ ```
204
+
205
+ **List Items:**
206
+
207
+ ```tsx
208
+ // In .map() lists, just use JSX key - the plugin appends it automatically
209
+ function List() {
210
+ return (
211
+ <ul>
212
+ {items.map((item) => (
213
+ <li
214
+ key={item.id} // JSX key is enough - plugin generates file:line:col:${key}
215
+ ref={transition(fade())}
216
+ >
217
+ {item.name}
218
+ </li>
219
+ ))}
220
+ </ul>
221
+ );
222
+ }
223
+ ```
224
+
124
225
  ## Next.js App Router Example
125
226
 
126
227
  ```tsx
127
228
  // app/layout.tsx
128
- import { Ssgoi } from '@ssgoi/react';
129
- import { scroll } from '@ssgoi/react/view-transitions';
229
+ import { Ssgoi } from "@ssgoi/react";
230
+ import { scroll } from "@ssgoi/react/view-transitions";
130
231
 
131
232
  export default function RootLayout({ children }) {
132
233
  return (
133
234
  <html>
134
235
  <body>
135
- <Ssgoi config={{
136
- defaultTransition: scroll({ direction: 'up' })
137
- }}>
138
- <div style={{ position: 'relative', minHeight: '100vh' }}>
236
+ <Ssgoi
237
+ config={{
238
+ defaultTransition: scroll({ direction: "up" }),
239
+ }}
240
+ >
241
+ <div style={{ position: "relative", minHeight: "100vh" }}>
139
242
  {children}
140
243
  </div>
141
244
  </Ssgoi>
@@ -145,14 +248,10 @@ export default function RootLayout({ children }) {
145
248
  }
146
249
 
147
250
  // app/page.tsx
148
- import { SsgoiTransition } from '@ssgoi/react';
251
+ import { SsgoiTransition } from "@ssgoi/react";
149
252
 
150
253
  export default function Page() {
151
- return (
152
- <SsgoiTransition id="/">
153
- {/* Your page content */}
154
- </SsgoiTransition>
155
- );
254
+ return <SsgoiTransition id="/">{/* Your page content */}</SsgoiTransition>;
156
255
  }
157
256
  ```
158
257
 
@@ -161,26 +260,25 @@ export default function Page() {
161
260
  ### Components
162
261
 
163
262
  #### `<Ssgoi>`
263
+
164
264
  The provider component that manages transition context.
165
265
 
166
266
  ```tsx
167
- <Ssgoi config={ssgoiConfig}>
168
- {children}
169
- </Ssgoi>
267
+ <Ssgoi config={ssgoiConfig}>{children}</Ssgoi>
170
268
  ```
171
269
 
172
270
  #### `<SsgoiTransition>`
271
+
173
272
  Wrapper component for pages that should transition.
174
273
 
175
274
  ```tsx
176
- <SsgoiTransition id="/page-id">
177
- {children}
178
- </SsgoiTransition>
275
+ <SsgoiTransition id="/page-id">{children}</SsgoiTransition>
179
276
  ```
180
277
 
181
278
  ### Hooks
182
279
 
183
280
  #### `useTransition()`
281
+
184
282
  Access transition state and controls.
185
283
 
186
284
  ```tsx
@@ -190,14 +288,17 @@ const { isTransitioning, direction } = useTransition();
190
288
  ### Functions
191
289
 
192
290
  #### `transition()`
291
+
193
292
  Apply transitions to individual elements.
194
293
 
195
294
  ```tsx
196
- <div ref={transition({
197
- key: 'unique-key',
198
- in: fadeIn(),
199
- out: fadeOut()
200
- })}>
295
+ <div
296
+ ref={transition({
297
+ key: "unique-key",
298
+ in: fade(),
299
+ out: fade(),
300
+ })}
301
+ >
201
302
  Content
202
303
  </div>
203
304
  ```
@@ -205,6 +306,7 @@ Apply transitions to individual elements.
205
306
  ## Built-in Transitions
206
307
 
207
308
  ### Page Transitions (`@ssgoi/react/view-transitions`)
309
+
208
310
  - `fade()` - Smooth opacity transition
209
311
  - `scroll()` - Vertical scrolling (up/down)
210
312
  - `drill()` - Drill in/out effect (enter/exit)
@@ -212,12 +314,14 @@ Apply transitions to individual elements.
212
314
  - `pinterest()` - Pinterest-style expand effect
213
315
 
214
316
  ### Element Transitions (`@ssgoi/react/transitions`)
215
- - `fadeIn()` / `fadeOut()`
216
- - `slideUp()` / `slideDown()` / `slideLeft()` / `slideRight()`
217
- - `scaleIn()` / `scaleOut()`
218
- - `bounce()`
219
- - `blur()`
220
- - `rotate()`
317
+
318
+ - `fade()` - Fade in/out
319
+ - `scale()` - Scale in/out
320
+ - `slide()` - Slide (direction: up/down/left/right)
321
+ - `rotate()` - Rotate
322
+ - `bounce()` - Bounce
323
+ - `blur()` - Blur
324
+ - `fly()` - Fly (custom x, y position)
221
325
 
222
326
  ## Spring Physics Configuration
223
327
 
@@ -225,12 +329,12 @@ All transitions use spring physics for natural motion:
225
329
 
226
330
  ```tsx
227
331
  slide({
228
- direction: 'left',
332
+ direction: "left",
229
333
  spring: {
230
- stiffness: 300, // 1-1000, higher = faster
231
- damping: 30 // 0-100, higher = less oscillation
232
- }
233
- })
334
+ stiffness: 300, // 1-1000, higher = faster
335
+ damping: 30, // 0-100, higher = less oscillation
336
+ },
337
+ });
234
338
  ```
235
339
 
236
340
  ## TypeScript Support
@@ -238,7 +342,7 @@ slide({
238
342
  SSGOI is written in TypeScript and provides full type definitions:
239
343
 
240
344
  ```tsx
241
- import type { SsgoiConfig, TransitionConfig } from '@ssgoi/react';
345
+ import type { SsgoiConfig, TransitionConfig } from "@ssgoi/react";
242
346
 
243
347
  const config: SsgoiConfig = {
244
348
  // Full type safety
@@ -262,6 +366,7 @@ const config: SsgoiConfig = {
262
366
  ## Documentation
263
367
 
264
368
  Visit [https://ssgoi.dev](https://ssgoi.dev) for:
369
+
265
370
  - Complete API reference
266
371
  - Interactive examples
267
372
  - Advanced patterns
@@ -273,4 +378,4 @@ We welcome contributions! Please see our [contributing guide](https://github.com
273
378
 
274
379
  ## License
275
380
 
276
- MIT © [MeurSyphus](https://github.com/meursyphus)
381
+ MIT © [MeurSyphus](https://github.com/meursyphus)
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function h(e){return("tick"in e||"css"in e)&&!("springs"in e)}function s(e){return"springs"in e}function o(e){return"css"in e&&typeof e.css=="function"}function a(e){return"tick"in e&&typeof e.tick=="function"}function c(e){if(o(e)&&a(e))throw new Error("SingleSpringConfig cannot have both 'tick' and 'css' defined. Use one or the other.")}function l(e){if(e.tick&&e.css)throw new Error("SpringItem cannot have both 'tick' and 'css' defined. Use one or the other.")}async function m(e){const n=await e;return s(n)?(n.springs.forEach(l),n):(c(n),{prepare:n.prepare,wait:n.wait,onStart:n.onStart,onEnd:n.onEnd,springs:[{spring:n.spring,tick:n.tick,css:n.css}],schedule:"parallel"})}function S(e,n){const u=e.schedule??"parallel",f=e.springs.map(r=>{let t;switch(u){case"parallel":t=0;break;case"sequential":t=1;break;case"stagger":t=Math.max(0,Math.min(1,r.offset??0));break;default:t=0}const{css:i,offset:w,...g}=r,d=i?typeof i=="function"?n?{element:n,style:i}:void 0:{element:i.element,style:i.style}:void 0;return{...g,css:d,normalizedOffset:t}}),{schedule:k,...p}=e;return{...p,springs:f}}exports.isCssAnimation=o;exports.isMultiSpring=s;exports.isSingleSpring=h;exports.isTickAnimation=a;exports.normalizeMultiSpringSchedule=S;exports.normalizeToMultiSpring=m;exports.validateAnimationMode=c;exports.validateSpringItem=l;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function h(e){return("tick"in e||"css"in e)&&!("springs"in e)}function r(e){return"springs"in e}function o(e){return"css"in e&&typeof e.css=="function"}function c(e){return"tick"in e&&typeof e.tick=="function"}function a(e){if(o(e)&&c(e))throw new Error("SingleSpringConfig cannot have both 'tick' and 'css' defined. Use one or the other.")}function l(e){if(e.tick&&e.css)throw new Error("SpringItem cannot have both 'tick' and 'css' defined. Use one or the other.")}async function m(e){const t=await e;return r(t)?(t.springs.forEach(l),t):(a(t),{prepare:t.prepare,wait:t.wait,onStart:t.onStart,onEnd:t.onEnd,springs:[{physics:t.physics,tick:t.tick,css:t.css}],schedule:"parallel"})}function S(e,t){const u=e.schedule??"parallel",f=e.springs.map(s=>{let n;switch(u){case"parallel":n=0;break;case"sequential":n=1;break;case"stagger":n=Math.max(0,Math.min(1,s.offset??0));break;default:n=0}const{css:i,offset:y,...d}=s,g=i?typeof i=="function"?t?{element:t,style:i}:void 0:{element:i.element,style:i.style}:void 0;return{...d,css:g,normalizedOffset:n}}),{schedule:k,...p}=e;return{...p,springs:f}}exports.isCssAnimation=o;exports.isMultiSpring=r;exports.isSingleSpring=h;exports.isTickAnimation=c;exports.normalizeMultiSpringSchedule=S;exports.normalizeToMultiSpring=m;exports.validateAnimationMode=a;exports.validateSpringItem=l;
@@ -10,7 +10,7 @@ function p(n) {
10
10
  function u(n) {
11
11
  return "tick" in n && typeof n.tick == "function";
12
12
  }
13
- function g(n) {
13
+ function h(n) {
14
14
  if (p(n) && u(n))
15
15
  throw new Error(
16
16
  "SingleSpringConfig cannot have both 'tick' and 'css' defined. Use one or the other."
@@ -24,14 +24,14 @@ function d(n) {
24
24
  }
25
25
  async function S(n) {
26
26
  const e = await n;
27
- return f(e) ? (e.springs.forEach(d), e) : (g(e), {
27
+ return f(e) ? (e.springs.forEach(d), e) : (h(e), {
28
28
  prepare: e.prepare,
29
29
  wait: e.wait,
30
30
  onStart: e.onStart,
31
31
  onEnd: e.onEnd,
32
32
  springs: [
33
33
  {
34
- spring: e.spring,
34
+ physics: e.physics,
35
35
  tick: e.tick,
36
36
  css: e.css
37
37
  }
@@ -39,7 +39,7 @@ async function S(n) {
39
39
  schedule: "parallel"
40
40
  });
41
41
  }
42
- function w(n, e) {
42
+ function y(n, e) {
43
43
  const r = n.schedule ?? "parallel", a = n.springs.map(
44
44
  (s) => {
45
45
  let t;
@@ -59,7 +59,7 @@ function w(n, e) {
59
59
  const { css: i, offset: m, ...c } = s, l = i ? typeof i == "function" ? e ? { element: e, style: i } : void 0 : { element: i.element, style: i.style } : void 0;
60
60
  return { ...c, css: l, normalizedOffset: t };
61
61
  }
62
- ), { schedule: h, ...o } = n;
62
+ ), { schedule: g, ...o } = n;
63
63
  return {
64
64
  ...o,
65
65
  springs: a
@@ -70,8 +70,8 @@ export {
70
70
  f as isMultiSpring,
71
71
  k as isSingleSpring,
72
72
  u as isTickAnimation,
73
- w as normalizeMultiSpringSchedule,
73
+ y as normalizeMultiSpringSchedule,
74
74
  S as normalizeToMultiSpring,
75
- g as validateAnimationMode,
75
+ h as validateAnimationMode,
76
76
  d as validateSpringItem
77
77
  };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,2 @@
1
- export { transition } from './transition';
2
- export * from './types';
3
- export { Ssgoi } from './ssgoi';
4
- export { SsgoiTransition } from './ssgoi-transition';
5
- export { TransitionScope } from './transition-scope';
1
+ export * from './lib/index'
2
+ export {}
@@ -0,0 +1,5 @@
1
+ export { transition } from './transition';
2
+ export * from './types';
3
+ export { Ssgoi } from './ssgoi';
4
+ export { SsgoiTransition } from './ssgoi-transition';
5
+ export { TransitionScope } from './transition-scope';
@@ -0,0 +1 @@
1
+ export * from '@ssgoi/core/presets';
@@ -2,7 +2,6 @@ import { Transition, TransitionKey, TransitionScope } from '@ssgoi/core';
2
2
  type TransitionOptions = Transition<undefined> & {
3
3
  key?: TransitionKey;
4
4
  scope?: TransitionScope;
5
- ref?: object;
6
5
  };
7
6
  /**
8
7
  * React ref callback for element transitions
@@ -13,6 +12,9 @@ type TransitionOptions = Transition<undefined> & {
13
12
  * The returned ref callback has a stable reference (cached by key),
14
13
  * so it won't cause unnecessary re-renders when used with React refs.
15
14
  *
15
+ * Note: key is optional in the type signature because it can be auto-injected
16
+ * by babel-plugin-ssgoi at build time. However, it is required at runtime.
17
+ *
16
18
  * @example
17
19
  * ```tsx
18
20
  * <div ref={transition({
@@ -0,0 +1 @@
1
+ export * from '@ssgoi/core/transitions';
@@ -0,0 +1 @@
1
+ export * from '@ssgoi/core/types';
@@ -0,0 +1 @@
1
+ export * from '@ssgoi/core/view-transitions';
@@ -1 +1,2 @@
1
- export * from '@ssgoi/core/presets';
1
+ export * from '../lib/presets/index'
2
+ export {}
@@ -1,2 +1,2 @@
1
1
  "use client";
2
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("@ssgoi/core"),e=t=>r.transition(t,"auto");exports.transition=e;
2
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("@ssgoi/core"),t=e=>{if(!e.key)throw new Error("[ssgoi] transition() requires a 'key' property. Either provide it manually or use plugin for auto-injection. import plugin from @ssgoi/react/unplugin/webpack; see: https://ssgoi.dev/en/docs/core-concepts/react-plugin");return r.transition(e,"auto")};exports.transition=t;
@@ -1,6 +1,15 @@
1
1
  "use client";
2
- import { transition as n } from "@ssgoi/core";
3
- const r = (t) => n(t, "auto");
2
+ import { transition as t } from "@ssgoi/core";
3
+ const o = (r) => {
4
+ if (!r.key)
5
+ throw new Error(
6
+ "[ssgoi] transition() requires a 'key' property. Either provide it manually or use plugin for auto-injection. import plugin from @ssgoi/react/unplugin/webpack; see: https://ssgoi.dev/en/docs/core-concepts/react-plugin"
7
+ );
8
+ return t(
9
+ r,
10
+ "auto"
11
+ );
12
+ };
4
13
  export {
5
- r as transition
14
+ o as transition
6
15
  };
@@ -1 +1,2 @@
1
- export * from '@ssgoi/core/transitions';
1
+ export * from '../lib/transitions/index'
2
+ export {}
package/dist/types.d.ts CHANGED
@@ -1 +1,2 @@
1
- export * from '@ssgoi/core/types';
1
+ export * from './lib/types'
2
+ export {}
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("./index.cjs"),u=e.unplugin.esbuild;exports.default=u;
@@ -0,0 +1,2 @@
1
+ declare const _default: (options?: import('./index').SsgoiAutoKeyOptions | undefined) => import('esbuild').Plugin;
2
+ export default _default;
@@ -0,0 +1,5 @@
1
+ import { unplugin as u } from "./index.js";
2
+ const i = u.esbuild;
3
+ export {
4
+ i as default
5
+ };
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const S=require("unplugin"),j=require("@babel/core"),P={include:[".tsx",".jsx"],exclude:[/node_modules/]};function h(){return function({types:e}){return{name:"babel-plugin-ssgoi-auto-key",visitor:{CallExpression(r,l){const n=r.node.callee;if(!e.isIdentifier(n)||n.name!=="transition"||r.node._ssgoiProcessed)return;r.node._ssgoiProcessed=!0;const a=r.node.arguments;if(a.length===0)return;const s=a[0];if(e.isObjectExpression(s)&&s.properties.length>=2&&e.isSpreadElement(s.properties[0])&&e.isObjectProperty(s.properties[s.properties.length-1])&&e.isIdentifier(s.properties[s.properties.length-1].key)&&s.properties[s.properties.length-1].key.name==="key")return;const d=l.filename||"unknown",x=d.split("/").pop()||d,m=r.node.loc,b=m?.start?.line??0,k=m?.start?.column??0,c=`${x}:${b}:${k}`;let u=null;const p=r.findParent(i=>i.isJSXElement()||i.isJSXFragment());if(p&&e.isJSXElement(p.node)){const i=p.node.openingElement.attributes.find(t=>e.isJSXAttribute(t)&&e.isJSXIdentifier(t.name)&&t.name.name==="key");i&&(e.isJSXExpressionContainer(i.value)?e.isJSXEmptyExpression(i.value.expression)||(u=i.value.expression):e.isStringLiteral(i.value)&&(u=i.value))}let f;u?f=e.templateLiteral([e.templateElement({raw:`${c}:`,cooked:`${c}:`}),e.templateElement({raw:"",cooked:""},!0)],[u]):f=e.stringLiteral(c);const g=e.objectProperty(e.identifier("key"),f);if(e.isObjectExpression(s)){if(s.properties.some(t=>e.isObjectProperty(t)&&e.isIdentifier(t.key)&&t.key.name==="key"))return;s.properties.push(g)}else e.isExpression(s)&&!e.isSpreadElement(s)&&(a[0]=e.objectExpression([e.spreadElement(s),g]))}}}}}function y(o,e){return e.include.some(n=>o.endsWith(n))?!e.exclude.some(n=>typeof n=="string"?o.includes(n):n.test(o)):!1}const v=o=>{const e={...P,...o};return{name:"unplugin-ssgoi-auto-key",enforce:"pre",transformInclude(r){return y(r,e)},transform(r,l){if(!y(l,e))return null;try{const n=j.transformSync(r,{filename:l,plugins:[h()],parserOpts:{plugins:["jsx","typescript"]},generatorOpts:{retainLines:!0},sourceMaps:!0,configFile:!1,babelrc:!1});if(n&&n.code)return{code:n.code,map:n.map}}catch(n){console.error(`[unplugin-ssgoi-auto-key] Error transforming ${l}:`,n)}return null}}},E=S.createUnplugin(v);exports.default=E;exports.unplugin=E;
@@ -0,0 +1,14 @@
1
+ export interface SsgoiAutoKeyOptions {
2
+ /**
3
+ * File extensions to process
4
+ * @default ['.tsx', '.jsx']
5
+ */
6
+ include?: string[];
7
+ /**
8
+ * File patterns to exclude
9
+ * @default [/node_modules/]
10
+ */
11
+ exclude?: (string | RegExp)[];
12
+ }
13
+ export declare const unplugin: import('unplugin').UnpluginInstance<SsgoiAutoKeyOptions | undefined, boolean>;
14
+ export default unplugin;
@@ -0,0 +1,116 @@
1
+ import { createUnplugin as b } from "unplugin";
2
+ import { transformSync as S } from "@babel/core";
3
+ const j = {
4
+ include: [".tsx", ".jsx"],
5
+ exclude: [/node_modules/]
6
+ };
7
+ function P() {
8
+ return function({
9
+ types: e
10
+ }) {
11
+ return {
12
+ name: "babel-plugin-ssgoi-auto-key",
13
+ visitor: {
14
+ CallExpression(r, l) {
15
+ const n = r.node.callee;
16
+ if (!e.isIdentifier(n) || n.name !== "transition" || r.node._ssgoiProcessed)
17
+ return;
18
+ r.node._ssgoiProcessed = !0;
19
+ const a = r.node.arguments;
20
+ if (a.length === 0)
21
+ return;
22
+ const s = a[0];
23
+ if (e.isObjectExpression(s) && s.properties.length >= 2 && e.isSpreadElement(s.properties[0]) && e.isObjectProperty(
24
+ s.properties[s.properties.length - 1]
25
+ ) && e.isIdentifier(
26
+ s.properties[s.properties.length - 1].key
27
+ ) && s.properties[s.properties.length - 1].key.name === "key")
28
+ return;
29
+ const m = l.filename || "unknown", x = m.split("/").pop() || m, d = r.node.loc, E = d?.start?.line ?? 0, k = d?.start?.column ?? 0, c = `${x}:${E}:${k}`;
30
+ let u = null;
31
+ const p = r.findParent(
32
+ (i) => i.isJSXElement() || i.isJSXFragment()
33
+ );
34
+ if (p && e.isJSXElement(p.node)) {
35
+ const i = p.node.openingElement.attributes.find(
36
+ (t) => e.isJSXAttribute(t) && e.isJSXIdentifier(t.name) && t.name.name === "key"
37
+ );
38
+ i && (e.isJSXExpressionContainer(i.value) ? e.isJSXEmptyExpression(i.value.expression) || (u = i.value.expression) : e.isStringLiteral(i.value) && (u = i.value));
39
+ }
40
+ let f;
41
+ u ? f = e.templateLiteral(
42
+ [
43
+ e.templateElement({
44
+ raw: `${c}:`,
45
+ cooked: `${c}:`
46
+ }),
47
+ e.templateElement({ raw: "", cooked: "" }, !0)
48
+ ],
49
+ [u]
50
+ ) : f = e.stringLiteral(c);
51
+ const g = e.objectProperty(e.identifier("key"), f);
52
+ if (e.isObjectExpression(s)) {
53
+ if (s.properties.some(
54
+ (t) => e.isObjectProperty(t) && e.isIdentifier(t.key) && t.key.name === "key"
55
+ ))
56
+ return;
57
+ s.properties.push(g);
58
+ } else e.isExpression(s) && !e.isSpreadElement(s) && (a[0] = e.objectExpression([
59
+ e.spreadElement(s),
60
+ g
61
+ ]));
62
+ }
63
+ }
64
+ };
65
+ };
66
+ }
67
+ function y(o, e) {
68
+ return e.include.some((n) => o.endsWith(n)) ? !e.exclude.some((n) => typeof n == "string" ? o.includes(n) : n.test(o)) : !1;
69
+ }
70
+ const h = (o) => {
71
+ const e = {
72
+ ...j,
73
+ ...o
74
+ };
75
+ return {
76
+ name: "unplugin-ssgoi-auto-key",
77
+ enforce: "pre",
78
+ transformInclude(r) {
79
+ return y(r, e);
80
+ },
81
+ transform(r, l) {
82
+ if (!y(l, e))
83
+ return null;
84
+ try {
85
+ const n = S(r, {
86
+ filename: l,
87
+ plugins: [P()],
88
+ parserOpts: {
89
+ plugins: ["jsx", "typescript"]
90
+ },
91
+ generatorOpts: {
92
+ retainLines: !0
93
+ },
94
+ sourceMaps: !0,
95
+ configFile: !1,
96
+ babelrc: !1
97
+ });
98
+ if (n && n.code)
99
+ return {
100
+ code: n.code,
101
+ map: n.map
102
+ };
103
+ } catch (n) {
104
+ console.error(
105
+ `[unplugin-ssgoi-auto-key] Error transforming ${l}:`,
106
+ n
107
+ );
108
+ }
109
+ return null;
110
+ }
111
+ };
112
+ }, X = /* @__PURE__ */ b(h);
113
+ export {
114
+ X as default,
115
+ X as unplugin
116
+ };
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("./index.cjs"),u=e.unplugin.rollup;exports.default=u;
@@ -0,0 +1,2 @@
1
+ declare const _default: (options?: import('./index').SsgoiAutoKeyOptions | undefined) => import('rollup').Plugin<any> | import('rollup').Plugin<any>[];
2
+ export default _default;
@@ -0,0 +1,5 @@
1
+ import { unplugin as l } from "./index.js";
2
+ const p = l.rollup;
3
+ export {
4
+ p as default
5
+ };
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("./index.cjs"),t=e.unplugin.vite;exports.default=t;
@@ -0,0 +1,2 @@
1
+ declare const _default: (options?: import('./index').SsgoiAutoKeyOptions | undefined) => import('vite').Plugin<any> | import('vite').Plugin<any>[];
2
+ export default _default;
@@ -0,0 +1,5 @@
1
+ import { unplugin as t } from "./index.js";
2
+ const i = t.vite;
3
+ export {
4
+ i as default
5
+ };
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("./index.cjs"),u=e.unplugin.webpack;exports.default=u;
@@ -0,0 +1,2 @@
1
+ declare const _default: (options?: import('./index').SsgoiAutoKeyOptions | undefined) => import('webpack').WebpackPluginInstance;
2
+ export default _default;
@@ -0,0 +1,5 @@
1
+ import { unplugin as p } from "./index.js";
2
+ const e = p.webpack;
3
+ export {
4
+ e as default
5
+ };
@@ -1 +1,2 @@
1
- export * from '@ssgoi/core/view-transitions';
1
+ export * from '../lib/view-transitions/index'
2
+ export {}
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "@ssgoi/react",
3
- "version": "3.2.2",
3
+ "version": "4.0.0",
4
4
  "description": "React bindings for SSGOI - Native app-like page transitions for React applications",
5
5
  "private": false,
6
6
  "type": "module",
7
7
  "files": [
8
8
  "dist",
9
+ "plugin",
9
10
  "!dist/**/*.test.*",
10
11
  "!dist/**/*.spec.*"
11
12
  ],
@@ -42,12 +43,45 @@
42
43
  "import": "./dist/presets/index.js",
43
44
  "require": "./dist/presets/index.cjs",
44
45
  "default": "./dist/presets/index.js"
46
+ },
47
+ "./unplugin": {
48
+ "types": "./dist/unplugin/index.d.ts",
49
+ "import": "./dist/unplugin/index.js",
50
+ "require": "./dist/unplugin/index.cjs",
51
+ "default": "./dist/unplugin/index.js"
52
+ },
53
+ "./unplugin/webpack": {
54
+ "types": "./dist/unplugin/webpack.d.ts",
55
+ "import": "./dist/unplugin/webpack.js",
56
+ "require": "./dist/unplugin/webpack.cjs",
57
+ "default": "./dist/unplugin/webpack.js"
58
+ },
59
+ "./unplugin/vite": {
60
+ "types": "./dist/unplugin/vite.d.ts",
61
+ "import": "./dist/unplugin/vite.js",
62
+ "require": "./dist/unplugin/vite.cjs",
63
+ "default": "./dist/unplugin/vite.js"
64
+ },
65
+ "./unplugin/rollup": {
66
+ "types": "./dist/unplugin/rollup.d.ts",
67
+ "import": "./dist/unplugin/rollup.js",
68
+ "require": "./dist/unplugin/rollup.cjs",
69
+ "default": "./dist/unplugin/rollup.js"
70
+ },
71
+ "./unplugin/esbuild": {
72
+ "types": "./dist/unplugin/esbuild.d.ts",
73
+ "import": "./dist/unplugin/esbuild.js",
74
+ "require": "./dist/unplugin/esbuild.cjs",
75
+ "default": "./dist/unplugin/esbuild.js"
45
76
  }
46
77
  },
47
78
  "dependencies": {
48
- "@ssgoi/core": "^3.2.2"
79
+ "unplugin": "^2.3.2",
80
+ "@babel/core": "^7.26.10",
81
+ "@ssgoi/core": "^4.0.0"
49
82
  },
50
83
  "devDependencies": {
84
+ "@types/babel__core": "^7.20.5",
51
85
  "@eslint/js": "^9.30.1",
52
86
  "@types/react": "^19.1.8",
53
87
  "@types/react-dom": "^19.1.6",
File without changes
File without changes