@ssgoi/react 3.3.0 → 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.
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
|
|
37
|
-
import { fade } from
|
|
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:
|
|
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
|
|
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:
|
|
78
|
-
{ from:
|
|
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
|
-
{
|
|
82
|
-
|
|
79
|
+
{
|
|
80
|
+
from: "/products",
|
|
81
|
+
to: "/products/*",
|
|
82
|
+
transition: drill({ direction: "enter" }),
|
|
83
|
+
},
|
|
84
|
+
|
|
83
85
|
// Pinterest-style image transitions
|
|
84
|
-
{ from:
|
|
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,16 +107,18 @@ Automatically create bidirectional transitions:
|
|
|
105
107
|
Animate specific elements during mount/unmount:
|
|
106
108
|
|
|
107
109
|
```tsx
|
|
108
|
-
import { transition } from
|
|
109
|
-
import { fade, slide } from
|
|
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
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
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
|
);
|
|
@@ -126,11 +130,12 @@ function Card() {
|
|
|
126
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.
|
|
127
131
|
|
|
128
132
|
**Benefits:**
|
|
133
|
+
|
|
129
134
|
- **Automatic Key Generation**: No need to manually specify `key` in `transition()` calls
|
|
130
135
|
- **Collision-Free**: Keys are based on exact code location
|
|
131
136
|
- **Cleaner Code**: Less boilerplate in your components
|
|
132
137
|
|
|
133
|
-
**⚠️ Important**: For list items rendered with `.map()`,
|
|
138
|
+
**⚠️ Important**: For list items rendered with `.map()`, just use JSX key prop - the plugin automatically appends it to generate unique keys.
|
|
134
139
|
|
|
135
140
|
#### Setup with Next.js
|
|
136
141
|
|
|
@@ -153,8 +158,8 @@ export default nextConfig;
|
|
|
153
158
|
|
|
154
159
|
```ts
|
|
155
160
|
// vite.config.ts
|
|
156
|
-
import { defineConfig } from
|
|
157
|
-
import react from
|
|
161
|
+
import { defineConfig } from "vite";
|
|
162
|
+
import react from "@vitejs/plugin-react";
|
|
158
163
|
import SsgoiAutoKey from "@ssgoi/react/unplugin/vite";
|
|
159
164
|
|
|
160
165
|
export default defineConfig({
|
|
@@ -165,19 +170,11 @@ export default defineConfig({
|
|
|
165
170
|
#### Usage Examples
|
|
166
171
|
|
|
167
172
|
**WITH Auto Key Plugin (Recommended):**
|
|
168
|
-
```tsx
|
|
169
|
-
import { transition } from '@ssgoi/react';
|
|
170
|
-
import { fade, slide } from '@ssgoi/react/transitions';
|
|
171
173
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
<h2>Animated Card</h2>
|
|
176
|
-
</div>
|
|
177
|
-
);
|
|
178
|
-
}
|
|
174
|
+
```tsx
|
|
175
|
+
import { transition } from "@ssgoi/react";
|
|
176
|
+
import { fade, slide } from "@ssgoi/react/transitions";
|
|
179
177
|
|
|
180
|
-
// Even simpler with single transition
|
|
181
178
|
function SimpleCard() {
|
|
182
179
|
return (
|
|
183
180
|
<div ref={transition(fade())}>
|
|
@@ -188,35 +185,34 @@ function SimpleCard() {
|
|
|
188
185
|
```
|
|
189
186
|
|
|
190
187
|
**WITHOUT Auto Key Plugin:**
|
|
188
|
+
|
|
191
189
|
```tsx
|
|
192
190
|
// Explicit key required for transition state tracking
|
|
193
191
|
function Card() {
|
|
194
192
|
return (
|
|
195
|
-
<div
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
193
|
+
<div
|
|
194
|
+
ref={transition({
|
|
195
|
+
key: "my-card",
|
|
196
|
+
...fade(),
|
|
197
|
+
})}
|
|
198
|
+
>
|
|
200
199
|
<h2>Animated Card</h2>
|
|
201
200
|
</div>
|
|
202
201
|
);
|
|
203
202
|
}
|
|
204
203
|
```
|
|
205
204
|
|
|
206
|
-
**List Items
|
|
205
|
+
**List Items:**
|
|
206
|
+
|
|
207
207
|
```tsx
|
|
208
|
-
//
|
|
208
|
+
// In .map() lists, just use JSX key - the plugin appends it automatically
|
|
209
209
|
function List() {
|
|
210
210
|
return (
|
|
211
211
|
<ul>
|
|
212
212
|
{items.map((item) => (
|
|
213
213
|
<li
|
|
214
|
-
key={item.id}
|
|
215
|
-
ref={transition(
|
|
216
|
-
key: `list-item-${item.id}`,
|
|
217
|
-
in: fade(),
|
|
218
|
-
out: slide({ direction: 'up' })
|
|
219
|
-
})}
|
|
214
|
+
key={item.id} // JSX key is enough - plugin generates file:line:col:${key}
|
|
215
|
+
ref={transition(fade())}
|
|
220
216
|
>
|
|
221
217
|
{item.name}
|
|
222
218
|
</li>
|
|
@@ -230,17 +226,19 @@ function List() {
|
|
|
230
226
|
|
|
231
227
|
```tsx
|
|
232
228
|
// app/layout.tsx
|
|
233
|
-
import { Ssgoi } from
|
|
234
|
-
import { scroll } from
|
|
229
|
+
import { Ssgoi } from "@ssgoi/react";
|
|
230
|
+
import { scroll } from "@ssgoi/react/view-transitions";
|
|
235
231
|
|
|
236
232
|
export default function RootLayout({ children }) {
|
|
237
233
|
return (
|
|
238
234
|
<html>
|
|
239
235
|
<body>
|
|
240
|
-
<Ssgoi
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
236
|
+
<Ssgoi
|
|
237
|
+
config={{
|
|
238
|
+
defaultTransition: scroll({ direction: "up" }),
|
|
239
|
+
}}
|
|
240
|
+
>
|
|
241
|
+
<div style={{ position: "relative", minHeight: "100vh" }}>
|
|
244
242
|
{children}
|
|
245
243
|
</div>
|
|
246
244
|
</Ssgoi>
|
|
@@ -250,14 +248,10 @@ export default function RootLayout({ children }) {
|
|
|
250
248
|
}
|
|
251
249
|
|
|
252
250
|
// app/page.tsx
|
|
253
|
-
import { SsgoiTransition } from
|
|
251
|
+
import { SsgoiTransition } from "@ssgoi/react";
|
|
254
252
|
|
|
255
253
|
export default function Page() {
|
|
256
|
-
return
|
|
257
|
-
<SsgoiTransition id="/">
|
|
258
|
-
{/* Your page content */}
|
|
259
|
-
</SsgoiTransition>
|
|
260
|
-
);
|
|
254
|
+
return <SsgoiTransition id="/">{/* Your page content */}</SsgoiTransition>;
|
|
261
255
|
}
|
|
262
256
|
```
|
|
263
257
|
|
|
@@ -266,26 +260,25 @@ export default function Page() {
|
|
|
266
260
|
### Components
|
|
267
261
|
|
|
268
262
|
#### `<Ssgoi>`
|
|
263
|
+
|
|
269
264
|
The provider component that manages transition context.
|
|
270
265
|
|
|
271
266
|
```tsx
|
|
272
|
-
<Ssgoi config={ssgoiConfig}>
|
|
273
|
-
{children}
|
|
274
|
-
</Ssgoi>
|
|
267
|
+
<Ssgoi config={ssgoiConfig}>{children}</Ssgoi>
|
|
275
268
|
```
|
|
276
269
|
|
|
277
270
|
#### `<SsgoiTransition>`
|
|
271
|
+
|
|
278
272
|
Wrapper component for pages that should transition.
|
|
279
273
|
|
|
280
274
|
```tsx
|
|
281
|
-
<SsgoiTransition id="/page-id">
|
|
282
|
-
{children}
|
|
283
|
-
</SsgoiTransition>
|
|
275
|
+
<SsgoiTransition id="/page-id">{children}</SsgoiTransition>
|
|
284
276
|
```
|
|
285
277
|
|
|
286
278
|
### Hooks
|
|
287
279
|
|
|
288
280
|
#### `useTransition()`
|
|
281
|
+
|
|
289
282
|
Access transition state and controls.
|
|
290
283
|
|
|
291
284
|
```tsx
|
|
@@ -295,14 +288,17 @@ const { isTransitioning, direction } = useTransition();
|
|
|
295
288
|
### Functions
|
|
296
289
|
|
|
297
290
|
#### `transition()`
|
|
291
|
+
|
|
298
292
|
Apply transitions to individual elements.
|
|
299
293
|
|
|
300
294
|
```tsx
|
|
301
|
-
<div
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
295
|
+
<div
|
|
296
|
+
ref={transition({
|
|
297
|
+
key: "unique-key",
|
|
298
|
+
in: fade(),
|
|
299
|
+
out: fade(),
|
|
300
|
+
})}
|
|
301
|
+
>
|
|
306
302
|
Content
|
|
307
303
|
</div>
|
|
308
304
|
```
|
|
@@ -310,6 +306,7 @@ Apply transitions to individual elements.
|
|
|
310
306
|
## Built-in Transitions
|
|
311
307
|
|
|
312
308
|
### Page Transitions (`@ssgoi/react/view-transitions`)
|
|
309
|
+
|
|
313
310
|
- `fade()` - Smooth opacity transition
|
|
314
311
|
- `scroll()` - Vertical scrolling (up/down)
|
|
315
312
|
- `drill()` - Drill in/out effect (enter/exit)
|
|
@@ -317,6 +314,7 @@ Apply transitions to individual elements.
|
|
|
317
314
|
- `pinterest()` - Pinterest-style expand effect
|
|
318
315
|
|
|
319
316
|
### Element Transitions (`@ssgoi/react/transitions`)
|
|
317
|
+
|
|
320
318
|
- `fade()` - Fade in/out
|
|
321
319
|
- `scale()` - Scale in/out
|
|
322
320
|
- `slide()` - Slide (direction: up/down/left/right)
|
|
@@ -331,12 +329,12 @@ All transitions use spring physics for natural motion:
|
|
|
331
329
|
|
|
332
330
|
```tsx
|
|
333
331
|
slide({
|
|
334
|
-
direction:
|
|
332
|
+
direction: "left",
|
|
335
333
|
spring: {
|
|
336
|
-
stiffness: 300,
|
|
337
|
-
damping: 30
|
|
338
|
-
}
|
|
339
|
-
})
|
|
334
|
+
stiffness: 300, // 1-1000, higher = faster
|
|
335
|
+
damping: 30, // 0-100, higher = less oscillation
|
|
336
|
+
},
|
|
337
|
+
});
|
|
340
338
|
```
|
|
341
339
|
|
|
342
340
|
## TypeScript Support
|
|
@@ -344,7 +342,7 @@ slide({
|
|
|
344
342
|
SSGOI is written in TypeScript and provides full type definitions:
|
|
345
343
|
|
|
346
344
|
```tsx
|
|
347
|
-
import type { SsgoiConfig, TransitionConfig } from
|
|
345
|
+
import type { SsgoiConfig, TransitionConfig } from "@ssgoi/react";
|
|
348
346
|
|
|
349
347
|
const config: SsgoiConfig = {
|
|
350
348
|
// Full type safety
|
|
@@ -368,6 +366,7 @@ const config: SsgoiConfig = {
|
|
|
368
366
|
## Documentation
|
|
369
367
|
|
|
370
368
|
Visit [https://ssgoi.dev](https://ssgoi.dev) for:
|
|
369
|
+
|
|
371
370
|
- Complete API reference
|
|
372
371
|
- Interactive examples
|
|
373
372
|
- Advanced patterns
|
|
@@ -379,4 +378,4 @@ We welcome contributions! Please see our [contributing guide](https://github.com
|
|
|
379
378
|
|
|
380
379
|
## License
|
|
381
380
|
|
|
382
|
-
MIT © [MeurSyphus](https://github.com/meursyphus)
|
|
381
|
+
MIT © [MeurSyphus](https://github.com/meursyphus)
|
package/dist/core/dist/types.cjs
CHANGED
|
@@ -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
|
|
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;
|
package/dist/core/dist/types.js
CHANGED
|
@@ -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
|
|
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) : (
|
|
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
|
-
|
|
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
|
|
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:
|
|
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
|
-
|
|
73
|
+
y as normalizeMultiSpringSchedule,
|
|
74
74
|
S as normalizeToMultiSpring,
|
|
75
|
-
|
|
75
|
+
h as validateAnimationMode,
|
|
76
76
|
d as validateSpringItem
|
|
77
77
|
};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
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,11 +1,11 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { transition as
|
|
2
|
+
import { transition as t } from "@ssgoi/core";
|
|
3
3
|
const o = (r) => {
|
|
4
4
|
if (!r.key)
|
|
5
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; "
|
|
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
7
|
);
|
|
8
|
-
return
|
|
8
|
+
return t(
|
|
9
9
|
r,
|
|
10
10
|
"auto"
|
|
11
11
|
);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ssgoi/react",
|
|
3
|
-
"version": "
|
|
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",
|
|
@@ -78,7 +78,7 @@
|
|
|
78
78
|
"dependencies": {
|
|
79
79
|
"unplugin": "^2.3.2",
|
|
80
80
|
"@babel/core": "^7.26.10",
|
|
81
|
-
"@ssgoi/core": "^
|
|
81
|
+
"@ssgoi/core": "^4.0.0"
|
|
82
82
|
},
|
|
83
83
|
"devDependencies": {
|
|
84
84
|
"@types/babel__core": "^7.20.5",
|