@pyreon/kinetic-presets 0.11.1 → 0.11.3
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/package.json +4 -3
- package/src/__tests__/factories.test.ts +263 -0
- package/src/__tests__/presets.test.ts +1065 -0
- package/src/__tests__/utils.test.ts +387 -0
- package/src/factories.ts +138 -0
- package/src/index.ts +137 -0
- package/src/presets.ts +825 -0
- package/src/types.ts +62 -0
- package/src/utils.ts +81 -0
|
@@ -0,0 +1,1065 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest"
|
|
2
|
+
import {
|
|
3
|
+
backInDown,
|
|
4
|
+
backInLeft,
|
|
5
|
+
backInRight,
|
|
6
|
+
backInUp,
|
|
7
|
+
blurIn,
|
|
8
|
+
blurInDown,
|
|
9
|
+
blurInLeft,
|
|
10
|
+
blurInRight,
|
|
11
|
+
blurInUp,
|
|
12
|
+
blurScale,
|
|
13
|
+
bounceIn,
|
|
14
|
+
bounceInDown,
|
|
15
|
+
bounceInLeft,
|
|
16
|
+
bounceInRight,
|
|
17
|
+
bounceInUp,
|
|
18
|
+
clipBottom,
|
|
19
|
+
clipCenter,
|
|
20
|
+
clipCircle,
|
|
21
|
+
clipCorner,
|
|
22
|
+
clipDiamond,
|
|
23
|
+
clipLeft,
|
|
24
|
+
clipRight,
|
|
25
|
+
clipTop,
|
|
26
|
+
drop,
|
|
27
|
+
expandX,
|
|
28
|
+
expandY,
|
|
29
|
+
fade,
|
|
30
|
+
fadeDown,
|
|
31
|
+
fadeDownBig,
|
|
32
|
+
fadeDownLeft,
|
|
33
|
+
fadeDownRight,
|
|
34
|
+
fadeLeft,
|
|
35
|
+
fadeLeftBig,
|
|
36
|
+
fadeRight,
|
|
37
|
+
fadeRightBig,
|
|
38
|
+
fadeScale,
|
|
39
|
+
fadeUp,
|
|
40
|
+
fadeUpBig,
|
|
41
|
+
fadeUpLeft,
|
|
42
|
+
fadeUpRight,
|
|
43
|
+
flipDiagonal,
|
|
44
|
+
flipDiagonalReverse,
|
|
45
|
+
flipX,
|
|
46
|
+
flipXReverse,
|
|
47
|
+
flipY,
|
|
48
|
+
flipYReverse,
|
|
49
|
+
floatDown,
|
|
50
|
+
floatLeft,
|
|
51
|
+
floatRight,
|
|
52
|
+
floatUp,
|
|
53
|
+
flyInDown,
|
|
54
|
+
flyInLeft,
|
|
55
|
+
flyInRight,
|
|
56
|
+
flyInUp,
|
|
57
|
+
lightSpeedInLeft,
|
|
58
|
+
lightSpeedInRight,
|
|
59
|
+
newspaperIn,
|
|
60
|
+
perspectiveDown,
|
|
61
|
+
perspectiveLeft,
|
|
62
|
+
perspectiveRight,
|
|
63
|
+
perspectiveUp,
|
|
64
|
+
popIn,
|
|
65
|
+
presets,
|
|
66
|
+
puffIn,
|
|
67
|
+
puffOut,
|
|
68
|
+
pushInLeft,
|
|
69
|
+
pushInRight,
|
|
70
|
+
rise,
|
|
71
|
+
rollInLeft,
|
|
72
|
+
rollInRight,
|
|
73
|
+
rotateIn,
|
|
74
|
+
rotateInDown,
|
|
75
|
+
rotateInReverse,
|
|
76
|
+
rotateInUp,
|
|
77
|
+
rubberIn,
|
|
78
|
+
scaleDown,
|
|
79
|
+
scaleIn,
|
|
80
|
+
scaleInDown,
|
|
81
|
+
scaleInLeft,
|
|
82
|
+
scaleInRight,
|
|
83
|
+
scaleInUp,
|
|
84
|
+
scaleOut,
|
|
85
|
+
scaleRotateIn,
|
|
86
|
+
scaleUp,
|
|
87
|
+
skewIn,
|
|
88
|
+
skewInReverse,
|
|
89
|
+
skewInY,
|
|
90
|
+
skewInYReverse,
|
|
91
|
+
slideDown,
|
|
92
|
+
slideDownBig,
|
|
93
|
+
slideLeft,
|
|
94
|
+
slideLeftBig,
|
|
95
|
+
slideRight,
|
|
96
|
+
slideRightBig,
|
|
97
|
+
slideUp,
|
|
98
|
+
slideUpBig,
|
|
99
|
+
slitHorizontal,
|
|
100
|
+
slitVertical,
|
|
101
|
+
spinIn,
|
|
102
|
+
spinInReverse,
|
|
103
|
+
springIn,
|
|
104
|
+
squishX,
|
|
105
|
+
squishY,
|
|
106
|
+
swingInBottom,
|
|
107
|
+
swingInLeft,
|
|
108
|
+
swingInRight,
|
|
109
|
+
swingInTop,
|
|
110
|
+
swirlIn,
|
|
111
|
+
swirlInReverse,
|
|
112
|
+
tiltInDown,
|
|
113
|
+
tiltInLeft,
|
|
114
|
+
tiltInRight,
|
|
115
|
+
tiltInUp,
|
|
116
|
+
zoomIn,
|
|
117
|
+
zoomInDown,
|
|
118
|
+
zoomInLeft,
|
|
119
|
+
zoomInRight,
|
|
120
|
+
zoomInUp,
|
|
121
|
+
zoomOut,
|
|
122
|
+
zoomOutDown,
|
|
123
|
+
zoomOutLeft,
|
|
124
|
+
zoomOutRight,
|
|
125
|
+
zoomOutUp,
|
|
126
|
+
} from "../index"
|
|
127
|
+
import type { Preset } from "../types"
|
|
128
|
+
|
|
129
|
+
// ─── Helpers ────────────────────────────────────────────────────────
|
|
130
|
+
|
|
131
|
+
const assertPresetShape = (preset: Preset) => {
|
|
132
|
+
expect(preset.enterStyle).toBeDefined()
|
|
133
|
+
expect(preset.enterToStyle).toBeDefined()
|
|
134
|
+
expect(preset.enterTransition).toBeDefined()
|
|
135
|
+
expect(preset.leaveStyle).toBeDefined()
|
|
136
|
+
expect(preset.leaveToStyle).toBeDefined()
|
|
137
|
+
expect(preset.leaveTransition).toBeDefined()
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const assertSymmetric = (preset: Preset) => {
|
|
141
|
+
// In a symmetric preset, enterStyle === leaveToStyle and enterToStyle === leaveStyle
|
|
142
|
+
expect(preset.enterStyle).toEqual(preset.leaveToStyle)
|
|
143
|
+
expect(preset.enterToStyle).toEqual(preset.leaveStyle)
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// ─── Preset count ───────────────────────────────────────────────────
|
|
147
|
+
|
|
148
|
+
describe("presets — count", () => {
|
|
149
|
+
it("exports 122 presets in the presets object", () => {
|
|
150
|
+
expect(Object.keys(presets)).toHaveLength(122)
|
|
151
|
+
})
|
|
152
|
+
})
|
|
153
|
+
|
|
154
|
+
// ─── All presets have correct shape ─────────────────────────────────
|
|
155
|
+
|
|
156
|
+
describe("presets — shape", () => {
|
|
157
|
+
const allPresets = Object.entries(presets)
|
|
158
|
+
|
|
159
|
+
it.each(allPresets)("%s has required style+transition fields", (_, preset) => {
|
|
160
|
+
assertPresetShape(preset)
|
|
161
|
+
})
|
|
162
|
+
|
|
163
|
+
it.each(allPresets)("%s is symmetric (leave reverses enter)", (_, preset) => {
|
|
164
|
+
assertSymmetric(preset)
|
|
165
|
+
})
|
|
166
|
+
|
|
167
|
+
it.each(allPresets)("%s has enter transition string", (_, preset) => {
|
|
168
|
+
expect(preset.enterTransition).toMatch(/\d+m?s/)
|
|
169
|
+
})
|
|
170
|
+
|
|
171
|
+
it.each(allPresets)("%s has leave transition string", (_, preset) => {
|
|
172
|
+
expect(preset.leaveTransition).toMatch(/\d+m?s/)
|
|
173
|
+
})
|
|
174
|
+
})
|
|
175
|
+
|
|
176
|
+
// ─── Fades ──────────────────────────────────────────────────────────
|
|
177
|
+
|
|
178
|
+
describe("presets — fades", () => {
|
|
179
|
+
it("fade is pure opacity", () => {
|
|
180
|
+
expect(fade.enterStyle).toEqual({ opacity: 0 })
|
|
181
|
+
expect(fade.enterToStyle).toEqual({ opacity: 1 })
|
|
182
|
+
})
|
|
183
|
+
|
|
184
|
+
it("fadeUp translates from 16px below", () => {
|
|
185
|
+
expect(fadeUp.enterStyle).toEqual({
|
|
186
|
+
opacity: 0,
|
|
187
|
+
transform: "translateY(16px)",
|
|
188
|
+
})
|
|
189
|
+
})
|
|
190
|
+
|
|
191
|
+
it("fadeDown translates from 16px above", () => {
|
|
192
|
+
expect(fadeDown.enterStyle).toEqual({
|
|
193
|
+
opacity: 0,
|
|
194
|
+
transform: "translateY(-16px)",
|
|
195
|
+
})
|
|
196
|
+
})
|
|
197
|
+
|
|
198
|
+
it("fadeLeft translates from 16px right", () => {
|
|
199
|
+
expect(fadeLeft.enterStyle).toEqual({
|
|
200
|
+
opacity: 0,
|
|
201
|
+
transform: "translateX(16px)",
|
|
202
|
+
})
|
|
203
|
+
})
|
|
204
|
+
|
|
205
|
+
it("fadeRight translates from 16px left", () => {
|
|
206
|
+
expect(fadeRight.enterStyle).toEqual({
|
|
207
|
+
opacity: 0,
|
|
208
|
+
transform: "translateX(-16px)",
|
|
209
|
+
})
|
|
210
|
+
})
|
|
211
|
+
|
|
212
|
+
it("big variants use 48px distance", () => {
|
|
213
|
+
expect(fadeUpBig.enterStyle).toEqual({
|
|
214
|
+
opacity: 0,
|
|
215
|
+
transform: "translateY(48px)",
|
|
216
|
+
})
|
|
217
|
+
expect(fadeDownBig.enterStyle).toEqual({
|
|
218
|
+
opacity: 0,
|
|
219
|
+
transform: "translateY(-48px)",
|
|
220
|
+
})
|
|
221
|
+
expect(fadeLeftBig.enterStyle).toEqual({
|
|
222
|
+
opacity: 0,
|
|
223
|
+
transform: "translateX(48px)",
|
|
224
|
+
})
|
|
225
|
+
expect(fadeRightBig.enterStyle).toEqual({
|
|
226
|
+
opacity: 0,
|
|
227
|
+
transform: "translateX(-48px)",
|
|
228
|
+
})
|
|
229
|
+
})
|
|
230
|
+
|
|
231
|
+
it("fadeScale uses scale(0.95)", () => {
|
|
232
|
+
expect(fadeScale.enterStyle).toEqual({
|
|
233
|
+
opacity: 0,
|
|
234
|
+
transform: "scale(0.95)",
|
|
235
|
+
})
|
|
236
|
+
})
|
|
237
|
+
})
|
|
238
|
+
|
|
239
|
+
// ─── Slides ─────────────────────────────────────────────────────────
|
|
240
|
+
|
|
241
|
+
describe("presets — slides", () => {
|
|
242
|
+
it("slideUp translates from 16px below", () => {
|
|
243
|
+
expect(slideUp.enterStyle).toEqual({
|
|
244
|
+
opacity: 0,
|
|
245
|
+
transform: "translateY(16px)",
|
|
246
|
+
})
|
|
247
|
+
})
|
|
248
|
+
|
|
249
|
+
it("slideDown translates from 16px above", () => {
|
|
250
|
+
expect(slideDown.enterStyle).toEqual({
|
|
251
|
+
opacity: 0,
|
|
252
|
+
transform: "translateY(-16px)",
|
|
253
|
+
})
|
|
254
|
+
})
|
|
255
|
+
|
|
256
|
+
it("slideLeft translates from 16px right", () => {
|
|
257
|
+
expect(slideLeft.enterStyle).toEqual({
|
|
258
|
+
opacity: 0,
|
|
259
|
+
transform: "translateX(16px)",
|
|
260
|
+
})
|
|
261
|
+
})
|
|
262
|
+
|
|
263
|
+
it("slideRight translates from 16px left", () => {
|
|
264
|
+
expect(slideRight.enterStyle).toEqual({
|
|
265
|
+
opacity: 0,
|
|
266
|
+
transform: "translateX(-16px)",
|
|
267
|
+
})
|
|
268
|
+
})
|
|
269
|
+
|
|
270
|
+
it("big variants use 48px", () => {
|
|
271
|
+
expect(slideUpBig.enterStyle).toEqual({
|
|
272
|
+
opacity: 0,
|
|
273
|
+
transform: "translateY(48px)",
|
|
274
|
+
})
|
|
275
|
+
expect(slideDownBig.enterStyle).toEqual({
|
|
276
|
+
opacity: 0,
|
|
277
|
+
transform: "translateY(-48px)",
|
|
278
|
+
})
|
|
279
|
+
expect(slideLeftBig.enterStyle).toEqual({
|
|
280
|
+
opacity: 0,
|
|
281
|
+
transform: "translateX(48px)",
|
|
282
|
+
})
|
|
283
|
+
expect(slideRightBig.enterStyle).toEqual({
|
|
284
|
+
opacity: 0,
|
|
285
|
+
transform: "translateX(-48px)",
|
|
286
|
+
})
|
|
287
|
+
})
|
|
288
|
+
})
|
|
289
|
+
|
|
290
|
+
// ─── Scales ─────────────────────────────────────────────────────────
|
|
291
|
+
|
|
292
|
+
describe("presets — scales", () => {
|
|
293
|
+
it("scaleIn from 0.9", () => {
|
|
294
|
+
expect(scaleIn.enterStyle).toEqual({
|
|
295
|
+
opacity: 0,
|
|
296
|
+
transform: "scale(0.9)",
|
|
297
|
+
})
|
|
298
|
+
})
|
|
299
|
+
|
|
300
|
+
it("scaleOut from 1.1", () => {
|
|
301
|
+
expect(scaleOut.enterStyle).toEqual({
|
|
302
|
+
opacity: 0,
|
|
303
|
+
transform: "scale(1.1)",
|
|
304
|
+
})
|
|
305
|
+
})
|
|
306
|
+
|
|
307
|
+
it("scaleUp from 0.5 (dramatic)", () => {
|
|
308
|
+
expect(scaleUp.enterStyle).toEqual({
|
|
309
|
+
opacity: 0,
|
|
310
|
+
transform: "scale(0.5)",
|
|
311
|
+
})
|
|
312
|
+
})
|
|
313
|
+
|
|
314
|
+
it("scaleDown from 1.5 (dramatic)", () => {
|
|
315
|
+
expect(scaleDown.enterStyle).toEqual({
|
|
316
|
+
opacity: 0,
|
|
317
|
+
transform: "scale(1.5)",
|
|
318
|
+
})
|
|
319
|
+
})
|
|
320
|
+
|
|
321
|
+
it("directional scales combine scale + translate", () => {
|
|
322
|
+
expect(scaleInUp.enterStyle).toEqual({
|
|
323
|
+
opacity: 0,
|
|
324
|
+
transform: "scale(0.9) translateY(16px)",
|
|
325
|
+
})
|
|
326
|
+
expect(scaleInDown.enterStyle).toEqual({
|
|
327
|
+
opacity: 0,
|
|
328
|
+
transform: "scale(0.9) translateY(-16px)",
|
|
329
|
+
})
|
|
330
|
+
expect(scaleInLeft.enterStyle).toEqual({
|
|
331
|
+
opacity: 0,
|
|
332
|
+
transform: "scale(0.9) translateX(16px)",
|
|
333
|
+
})
|
|
334
|
+
expect(scaleInRight.enterStyle).toEqual({
|
|
335
|
+
opacity: 0,
|
|
336
|
+
transform: "scale(0.9) translateX(-16px)",
|
|
337
|
+
})
|
|
338
|
+
})
|
|
339
|
+
})
|
|
340
|
+
|
|
341
|
+
// ─── Zooms ──────────────────────────────────────────────────────────
|
|
342
|
+
|
|
343
|
+
describe("presets — zooms", () => {
|
|
344
|
+
it("zoomIn starts at scale(0)", () => {
|
|
345
|
+
expect(zoomIn.enterStyle).toEqual({
|
|
346
|
+
opacity: 0,
|
|
347
|
+
transform: "scale(0)",
|
|
348
|
+
})
|
|
349
|
+
})
|
|
350
|
+
|
|
351
|
+
it("zoomOut starts at scale(2)", () => {
|
|
352
|
+
expect(zoomOut.enterStyle).toEqual({
|
|
353
|
+
opacity: 0,
|
|
354
|
+
transform: "scale(2)",
|
|
355
|
+
})
|
|
356
|
+
})
|
|
357
|
+
|
|
358
|
+
it("directional zooms use 48px and scale(0.5)", () => {
|
|
359
|
+
expect(zoomInUp.enterStyle).toEqual({
|
|
360
|
+
opacity: 0,
|
|
361
|
+
transform: "scale(0.5) translateY(48px)",
|
|
362
|
+
})
|
|
363
|
+
expect(zoomInDown.enterStyle).toEqual({
|
|
364
|
+
opacity: 0,
|
|
365
|
+
transform: "scale(0.5) translateY(-48px)",
|
|
366
|
+
})
|
|
367
|
+
expect(zoomInLeft.enterStyle).toEqual({
|
|
368
|
+
opacity: 0,
|
|
369
|
+
transform: "scale(0.5) translateX(48px)",
|
|
370
|
+
})
|
|
371
|
+
expect(zoomInRight.enterStyle).toEqual({
|
|
372
|
+
opacity: 0,
|
|
373
|
+
transform: "scale(0.5) translateX(-48px)",
|
|
374
|
+
})
|
|
375
|
+
})
|
|
376
|
+
|
|
377
|
+
it("zooms have longer duration (400ms)", () => {
|
|
378
|
+
expect(zoomIn.enterTransition).toContain("400ms")
|
|
379
|
+
})
|
|
380
|
+
})
|
|
381
|
+
|
|
382
|
+
// ─── Flips ──────────────────────────────────────────────────────────
|
|
383
|
+
|
|
384
|
+
describe("presets — flips", () => {
|
|
385
|
+
it("flipX uses perspective + rotateX", () => {
|
|
386
|
+
expect(flipX.enterStyle).toEqual({
|
|
387
|
+
opacity: 0,
|
|
388
|
+
transform: "perspective(600px) rotateX(90deg)",
|
|
389
|
+
})
|
|
390
|
+
expect(flipX.enterToStyle).toEqual({
|
|
391
|
+
opacity: 1,
|
|
392
|
+
transform: "perspective(600px) rotateX(0)",
|
|
393
|
+
})
|
|
394
|
+
})
|
|
395
|
+
|
|
396
|
+
it("flipY uses perspective + rotateY", () => {
|
|
397
|
+
expect(flipY.enterStyle).toEqual({
|
|
398
|
+
opacity: 0,
|
|
399
|
+
transform: "perspective(600px) rotateY(90deg)",
|
|
400
|
+
})
|
|
401
|
+
})
|
|
402
|
+
|
|
403
|
+
it("reverse variants use negative angles", () => {
|
|
404
|
+
expect(flipXReverse.enterStyle).toEqual({
|
|
405
|
+
opacity: 0,
|
|
406
|
+
transform: "perspective(600px) rotateX(-90deg)",
|
|
407
|
+
})
|
|
408
|
+
expect(flipYReverse.enterStyle).toEqual({
|
|
409
|
+
opacity: 0,
|
|
410
|
+
transform: "perspective(600px) rotateY(-90deg)",
|
|
411
|
+
})
|
|
412
|
+
})
|
|
413
|
+
})
|
|
414
|
+
|
|
415
|
+
// ─── Rotations ──────────────────────────────────────────────────────
|
|
416
|
+
|
|
417
|
+
describe("presets — rotations", () => {
|
|
418
|
+
it("rotateIn uses -15deg", () => {
|
|
419
|
+
expect(rotateIn.enterStyle).toEqual({
|
|
420
|
+
opacity: 0,
|
|
421
|
+
transform: "rotate(-15deg)",
|
|
422
|
+
})
|
|
423
|
+
})
|
|
424
|
+
|
|
425
|
+
it("rotateInReverse uses +15deg", () => {
|
|
426
|
+
expect(rotateInReverse.enterStyle).toEqual({
|
|
427
|
+
opacity: 0,
|
|
428
|
+
transform: "rotate(15deg)",
|
|
429
|
+
})
|
|
430
|
+
})
|
|
431
|
+
|
|
432
|
+
it("directional rotations combine rotate + translate", () => {
|
|
433
|
+
expect(rotateInUp.enterStyle).toEqual({
|
|
434
|
+
opacity: 0,
|
|
435
|
+
transform: "rotate(-5deg) translateY(16px)",
|
|
436
|
+
})
|
|
437
|
+
expect(rotateInDown.enterStyle).toEqual({
|
|
438
|
+
opacity: 0,
|
|
439
|
+
transform: "rotate(5deg) translateY(-16px)",
|
|
440
|
+
})
|
|
441
|
+
})
|
|
442
|
+
|
|
443
|
+
it("spins use 180deg", () => {
|
|
444
|
+
expect(spinIn.enterStyle).toEqual({
|
|
445
|
+
opacity: 0,
|
|
446
|
+
transform: "rotate(-180deg)",
|
|
447
|
+
})
|
|
448
|
+
expect(spinInReverse.enterStyle).toEqual({
|
|
449
|
+
opacity: 0,
|
|
450
|
+
transform: "rotate(180deg)",
|
|
451
|
+
})
|
|
452
|
+
})
|
|
453
|
+
})
|
|
454
|
+
|
|
455
|
+
// ─── Bounce / Spring ────────────────────────────────────────────────
|
|
456
|
+
|
|
457
|
+
describe("presets — bounce/spring", () => {
|
|
458
|
+
it("bounceIn uses bounce easing", () => {
|
|
459
|
+
expect(bounceIn.enterTransition).toContain("cubic-bezier(0.68, -0.55, 0.265, 1.55)")
|
|
460
|
+
})
|
|
461
|
+
|
|
462
|
+
it("all bounce variants use bounce easing", () => {
|
|
463
|
+
const bouncePresets = [bounceIn, bounceInUp, bounceInDown, bounceInLeft, bounceInRight]
|
|
464
|
+
for (const p of bouncePresets) {
|
|
465
|
+
expect(p.enterTransition).toContain("cubic-bezier(0.68, -0.55, 0.265, 1.55)")
|
|
466
|
+
}
|
|
467
|
+
})
|
|
468
|
+
|
|
469
|
+
it("springIn uses spring easing", () => {
|
|
470
|
+
expect(springIn.enterTransition).toContain("cubic-bezier(0.34, 1.56, 0.64, 1)")
|
|
471
|
+
})
|
|
472
|
+
|
|
473
|
+
it("bounceIn scales from 0.5", () => {
|
|
474
|
+
expect(bounceIn.enterStyle).toEqual({
|
|
475
|
+
opacity: 0,
|
|
476
|
+
transform: "scale(0.5)",
|
|
477
|
+
})
|
|
478
|
+
})
|
|
479
|
+
|
|
480
|
+
it("springIn scales from 0.8", () => {
|
|
481
|
+
expect(springIn.enterStyle).toEqual({
|
|
482
|
+
opacity: 0,
|
|
483
|
+
transform: "scale(0.8)",
|
|
484
|
+
})
|
|
485
|
+
})
|
|
486
|
+
})
|
|
487
|
+
|
|
488
|
+
// ─── Blur ───────────────────────────────────────────────────────────
|
|
489
|
+
|
|
490
|
+
describe("presets — blur", () => {
|
|
491
|
+
it("blurIn uses filter: blur(8px)", () => {
|
|
492
|
+
expect(blurIn.enterStyle).toEqual({
|
|
493
|
+
opacity: 0,
|
|
494
|
+
filter: "blur(8px)",
|
|
495
|
+
})
|
|
496
|
+
expect(blurIn.enterToStyle).toEqual({
|
|
497
|
+
opacity: 1,
|
|
498
|
+
filter: "blur(0px)",
|
|
499
|
+
})
|
|
500
|
+
})
|
|
501
|
+
|
|
502
|
+
it("directional blurs combine blur + translate", () => {
|
|
503
|
+
expect(blurInUp.enterStyle).toEqual({
|
|
504
|
+
opacity: 0,
|
|
505
|
+
filter: "blur(8px)",
|
|
506
|
+
transform: "translateY(16px)",
|
|
507
|
+
})
|
|
508
|
+
expect(blurInDown.enterStyle).toEqual({
|
|
509
|
+
opacity: 0,
|
|
510
|
+
filter: "blur(8px)",
|
|
511
|
+
transform: "translateY(-16px)",
|
|
512
|
+
})
|
|
513
|
+
})
|
|
514
|
+
|
|
515
|
+
it("blurScale combines blur + scale", () => {
|
|
516
|
+
expect(blurScale.enterStyle).toEqual({
|
|
517
|
+
opacity: 0,
|
|
518
|
+
filter: "blur(8px)",
|
|
519
|
+
transform: "scale(0.95)",
|
|
520
|
+
})
|
|
521
|
+
})
|
|
522
|
+
})
|
|
523
|
+
|
|
524
|
+
// ─── Clip Path ──────────────────────────────────────────────────────
|
|
525
|
+
|
|
526
|
+
describe("presets — clip path", () => {
|
|
527
|
+
it("clipTop reveals from top", () => {
|
|
528
|
+
expect(clipTop.enterStyle).toEqual({
|
|
529
|
+
clipPath: "inset(0 0 100% 0)",
|
|
530
|
+
})
|
|
531
|
+
expect(clipTop.enterToStyle).toEqual({
|
|
532
|
+
clipPath: "inset(0 0 0 0)",
|
|
533
|
+
})
|
|
534
|
+
})
|
|
535
|
+
|
|
536
|
+
it("clipBottom reveals from bottom", () => {
|
|
537
|
+
expect(clipBottom.enterStyle).toEqual({
|
|
538
|
+
clipPath: "inset(100% 0 0 0)",
|
|
539
|
+
})
|
|
540
|
+
})
|
|
541
|
+
|
|
542
|
+
it("clipLeft reveals from left", () => {
|
|
543
|
+
expect(clipLeft.enterStyle).toEqual({
|
|
544
|
+
clipPath: "inset(0 100% 0 0)",
|
|
545
|
+
})
|
|
546
|
+
})
|
|
547
|
+
|
|
548
|
+
it("clipRight reveals from right", () => {
|
|
549
|
+
expect(clipRight.enterStyle).toEqual({
|
|
550
|
+
clipPath: "inset(0 0 0 100%)",
|
|
551
|
+
})
|
|
552
|
+
})
|
|
553
|
+
|
|
554
|
+
it("clip presets do NOT include opacity (pure reveal)", () => {
|
|
555
|
+
const clips = [clipTop, clipBottom, clipLeft, clipRight]
|
|
556
|
+
for (const c of clips) {
|
|
557
|
+
expect(c.enterStyle).not.toHaveProperty("opacity")
|
|
558
|
+
}
|
|
559
|
+
})
|
|
560
|
+
})
|
|
561
|
+
|
|
562
|
+
// ─── Perspective ────────────────────────────────────────────────────
|
|
563
|
+
|
|
564
|
+
describe("presets — perspective", () => {
|
|
565
|
+
it("perspectiveUp tilts from above", () => {
|
|
566
|
+
expect(perspectiveUp.enterStyle).toEqual({
|
|
567
|
+
opacity: 0,
|
|
568
|
+
transform: "perspective(600px) rotateX(15deg)",
|
|
569
|
+
})
|
|
570
|
+
})
|
|
571
|
+
|
|
572
|
+
it("perspectiveDown tilts from below", () => {
|
|
573
|
+
expect(perspectiveDown.enterStyle).toEqual({
|
|
574
|
+
opacity: 0,
|
|
575
|
+
transform: "perspective(600px) rotateX(-15deg)",
|
|
576
|
+
})
|
|
577
|
+
})
|
|
578
|
+
|
|
579
|
+
it("perspectiveLeft tilts from left", () => {
|
|
580
|
+
expect(perspectiveLeft.enterStyle).toEqual({
|
|
581
|
+
opacity: 0,
|
|
582
|
+
transform: "perspective(600px) rotateY(-15deg)",
|
|
583
|
+
})
|
|
584
|
+
})
|
|
585
|
+
|
|
586
|
+
it("perspectiveRight tilts from right", () => {
|
|
587
|
+
expect(perspectiveRight.enterStyle).toEqual({
|
|
588
|
+
opacity: 0,
|
|
589
|
+
transform: "perspective(600px) rotateY(15deg)",
|
|
590
|
+
})
|
|
591
|
+
})
|
|
592
|
+
})
|
|
593
|
+
|
|
594
|
+
// ─── Expand / Skew / Drop / Rise ────────────────────────────────────
|
|
595
|
+
|
|
596
|
+
describe("presets — expand", () => {
|
|
597
|
+
it("expandX uses scaleX(0)", () => {
|
|
598
|
+
expect(expandX.enterStyle).toEqual({
|
|
599
|
+
opacity: 0,
|
|
600
|
+
transform: "scaleX(0)",
|
|
601
|
+
})
|
|
602
|
+
})
|
|
603
|
+
|
|
604
|
+
it("expandY uses scaleY(0)", () => {
|
|
605
|
+
expect(expandY.enterStyle).toEqual({
|
|
606
|
+
opacity: 0,
|
|
607
|
+
transform: "scaleY(0)",
|
|
608
|
+
})
|
|
609
|
+
})
|
|
610
|
+
})
|
|
611
|
+
|
|
612
|
+
describe("presets — skew", () => {
|
|
613
|
+
it("skewIn uses skewX(-5deg)", () => {
|
|
614
|
+
expect(skewIn.enterStyle).toEqual({
|
|
615
|
+
opacity: 0,
|
|
616
|
+
transform: "skewX(-5deg)",
|
|
617
|
+
})
|
|
618
|
+
})
|
|
619
|
+
|
|
620
|
+
it("skewInReverse uses skewX(5deg)", () => {
|
|
621
|
+
expect(skewInReverse.enterStyle).toEqual({
|
|
622
|
+
opacity: 0,
|
|
623
|
+
transform: "skewX(5deg)",
|
|
624
|
+
})
|
|
625
|
+
})
|
|
626
|
+
})
|
|
627
|
+
|
|
628
|
+
describe("presets — drop/rise", () => {
|
|
629
|
+
it("drop uses translateY(-100%)", () => {
|
|
630
|
+
expect(drop.enterStyle).toEqual({
|
|
631
|
+
opacity: 0,
|
|
632
|
+
transform: "translateY(-100%)",
|
|
633
|
+
})
|
|
634
|
+
})
|
|
635
|
+
|
|
636
|
+
it("rise uses translateY(100%)", () => {
|
|
637
|
+
expect(rise.enterStyle).toEqual({
|
|
638
|
+
opacity: 0,
|
|
639
|
+
transform: "translateY(100%)",
|
|
640
|
+
})
|
|
641
|
+
})
|
|
642
|
+
})
|
|
643
|
+
|
|
644
|
+
// ─── Diagonal fades ─────────────────────────────────────────────────
|
|
645
|
+
|
|
646
|
+
describe("presets — diagonal fades", () => {
|
|
647
|
+
it("fadeUpLeft translates from 16px diagonal", () => {
|
|
648
|
+
expect(fadeUpLeft.enterStyle).toEqual({
|
|
649
|
+
opacity: 0,
|
|
650
|
+
transform: "translate(16px, 16px)",
|
|
651
|
+
})
|
|
652
|
+
})
|
|
653
|
+
|
|
654
|
+
it("fadeUpRight translates from -16px x, 16px y", () => {
|
|
655
|
+
expect(fadeUpRight.enterStyle).toEqual({
|
|
656
|
+
opacity: 0,
|
|
657
|
+
transform: "translate(-16px, 16px)",
|
|
658
|
+
})
|
|
659
|
+
})
|
|
660
|
+
|
|
661
|
+
it("fadeDownLeft translates from 16px x, -16px y", () => {
|
|
662
|
+
expect(fadeDownLeft.enterStyle).toEqual({
|
|
663
|
+
opacity: 0,
|
|
664
|
+
transform: "translate(16px, -16px)",
|
|
665
|
+
})
|
|
666
|
+
})
|
|
667
|
+
|
|
668
|
+
it("fadeDownRight translates from -16px diagonal", () => {
|
|
669
|
+
expect(fadeDownRight.enterStyle).toEqual({
|
|
670
|
+
opacity: 0,
|
|
671
|
+
transform: "translate(-16px, -16px)",
|
|
672
|
+
})
|
|
673
|
+
})
|
|
674
|
+
})
|
|
675
|
+
|
|
676
|
+
// ─── Zoom out directional ───────────────────────────────────────────
|
|
677
|
+
|
|
678
|
+
describe("presets — zoom out directional", () => {
|
|
679
|
+
it("zoomOutUp uses scale(2) + translateY", () => {
|
|
680
|
+
expect(zoomOutUp.enterStyle).toEqual({
|
|
681
|
+
opacity: 0,
|
|
682
|
+
transform: "scale(2) translateY(48px)",
|
|
683
|
+
})
|
|
684
|
+
})
|
|
685
|
+
|
|
686
|
+
it("all zoom out variants have 400ms enter", () => {
|
|
687
|
+
for (const p of [zoomOutUp, zoomOutDown, zoomOutLeft, zoomOutRight]) {
|
|
688
|
+
expect(p.enterTransition).toContain("400ms")
|
|
689
|
+
}
|
|
690
|
+
})
|
|
691
|
+
})
|
|
692
|
+
|
|
693
|
+
// ─── Blur horizontal ────────────────────────────────────────────────
|
|
694
|
+
|
|
695
|
+
describe("presets — blur horizontal", () => {
|
|
696
|
+
it("blurInLeft combines blur + translateX", () => {
|
|
697
|
+
expect(blurInLeft.enterStyle).toEqual({
|
|
698
|
+
opacity: 0,
|
|
699
|
+
filter: "blur(8px)",
|
|
700
|
+
transform: "translateX(16px)",
|
|
701
|
+
})
|
|
702
|
+
})
|
|
703
|
+
|
|
704
|
+
it("blurInRight combines blur + translateX", () => {
|
|
705
|
+
expect(blurInRight.enterStyle).toEqual({
|
|
706
|
+
opacity: 0,
|
|
707
|
+
filter: "blur(8px)",
|
|
708
|
+
transform: "translateX(-16px)",
|
|
709
|
+
})
|
|
710
|
+
})
|
|
711
|
+
})
|
|
712
|
+
|
|
713
|
+
// ─── Skew Y ─────────────────────────────────────────────────────────
|
|
714
|
+
|
|
715
|
+
describe("presets — skew Y", () => {
|
|
716
|
+
it("skewInY uses skewY(-5deg)", () => {
|
|
717
|
+
expect(skewInY.enterStyle).toEqual({
|
|
718
|
+
opacity: 0,
|
|
719
|
+
transform: "skewY(-5deg)",
|
|
720
|
+
})
|
|
721
|
+
})
|
|
722
|
+
|
|
723
|
+
it("skewInYReverse uses skewY(5deg)", () => {
|
|
724
|
+
expect(skewInYReverse.enterStyle).toEqual({
|
|
725
|
+
opacity: 0,
|
|
726
|
+
transform: "skewY(5deg)",
|
|
727
|
+
})
|
|
728
|
+
})
|
|
729
|
+
})
|
|
730
|
+
|
|
731
|
+
// ─── Back ───────────────────────────────────────────────────────────
|
|
732
|
+
|
|
733
|
+
describe("presets — back", () => {
|
|
734
|
+
it("backInUp uses scale(0.7) + large translate", () => {
|
|
735
|
+
expect(backInUp.enterStyle).toEqual({
|
|
736
|
+
opacity: 0,
|
|
737
|
+
transform: "scale(0.7) translateY(80px)",
|
|
738
|
+
})
|
|
739
|
+
})
|
|
740
|
+
|
|
741
|
+
it("all back variants use 400ms enter", () => {
|
|
742
|
+
for (const p of [backInUp, backInDown, backInLeft, backInRight]) {
|
|
743
|
+
expect(p.enterTransition).toContain("400ms")
|
|
744
|
+
}
|
|
745
|
+
})
|
|
746
|
+
})
|
|
747
|
+
|
|
748
|
+
// ─── Light speed ────────────────────────────────────────────────────
|
|
749
|
+
|
|
750
|
+
describe("presets — light speed", () => {
|
|
751
|
+
it("lightSpeedInLeft uses translateX + skewX", () => {
|
|
752
|
+
expect(lightSpeedInLeft.enterStyle).toEqual({
|
|
753
|
+
opacity: 0,
|
|
754
|
+
transform: "translateX(100%) skewX(-30deg)",
|
|
755
|
+
})
|
|
756
|
+
})
|
|
757
|
+
|
|
758
|
+
it("lightSpeedInRight uses opposite direction", () => {
|
|
759
|
+
expect(lightSpeedInRight.enterStyle).toEqual({
|
|
760
|
+
opacity: 0,
|
|
761
|
+
transform: "translateX(-100%) skewX(30deg)",
|
|
762
|
+
})
|
|
763
|
+
})
|
|
764
|
+
})
|
|
765
|
+
|
|
766
|
+
// ─── Roll ───────────────────────────────────────────────────────────
|
|
767
|
+
|
|
768
|
+
describe("presets — roll", () => {
|
|
769
|
+
it("rollInLeft uses translateX + rotate", () => {
|
|
770
|
+
expect(rollInLeft.enterStyle).toEqual({
|
|
771
|
+
opacity: 0,
|
|
772
|
+
transform: "translateX(-100%) rotate(-120deg)",
|
|
773
|
+
})
|
|
774
|
+
})
|
|
775
|
+
|
|
776
|
+
it("rollInRight uses opposite direction", () => {
|
|
777
|
+
expect(rollInRight.enterStyle).toEqual({
|
|
778
|
+
opacity: 0,
|
|
779
|
+
transform: "translateX(100%) rotate(120deg)",
|
|
780
|
+
})
|
|
781
|
+
})
|
|
782
|
+
})
|
|
783
|
+
|
|
784
|
+
// ─── Clip path shapes ───────────────────────────────────────────────
|
|
785
|
+
|
|
786
|
+
describe("presets — clip path shapes", () => {
|
|
787
|
+
it("clipCircle uses circle()", () => {
|
|
788
|
+
expect(clipCircle.enterStyle).toEqual({
|
|
789
|
+
clipPath: "circle(0% at 50% 50%)",
|
|
790
|
+
})
|
|
791
|
+
})
|
|
792
|
+
|
|
793
|
+
it("clipCenter uses inset from center", () => {
|
|
794
|
+
expect(clipCenter.enterStyle).toEqual({
|
|
795
|
+
clipPath: "inset(50% 50% 50% 50%)",
|
|
796
|
+
})
|
|
797
|
+
})
|
|
798
|
+
|
|
799
|
+
it("clipDiamond uses polygon", () => {
|
|
800
|
+
expect(clipDiamond.enterStyle).toEqual({
|
|
801
|
+
clipPath: "polygon(50% 50%, 50% 50%, 50% 50%, 50% 50%)",
|
|
802
|
+
})
|
|
803
|
+
})
|
|
804
|
+
|
|
805
|
+
it("clipCorner expands from corner", () => {
|
|
806
|
+
expect(clipCorner.enterStyle).toEqual({
|
|
807
|
+
clipPath: "polygon(0 0, 0 0, 0 0, 0 0)",
|
|
808
|
+
})
|
|
809
|
+
})
|
|
810
|
+
|
|
811
|
+
it("shape clips do NOT include opacity", () => {
|
|
812
|
+
for (const c of [clipCircle, clipCenter, clipDiamond, clipCorner]) {
|
|
813
|
+
expect(c.enterStyle).not.toHaveProperty("opacity")
|
|
814
|
+
}
|
|
815
|
+
})
|
|
816
|
+
})
|
|
817
|
+
|
|
818
|
+
// ─── Puff ───────────────────────────────────────────────────────────
|
|
819
|
+
|
|
820
|
+
describe("presets — puff", () => {
|
|
821
|
+
it("puffIn uses blur + scale(1.5)", () => {
|
|
822
|
+
expect(puffIn.enterStyle).toEqual({
|
|
823
|
+
opacity: 0,
|
|
824
|
+
filter: "blur(4px)",
|
|
825
|
+
transform: "scale(1.5)",
|
|
826
|
+
})
|
|
827
|
+
})
|
|
828
|
+
|
|
829
|
+
it("puffOut uses blur + scale(0.5)", () => {
|
|
830
|
+
expect(puffOut.enterStyle).toEqual({
|
|
831
|
+
opacity: 0,
|
|
832
|
+
filter: "blur(4px)",
|
|
833
|
+
transform: "scale(0.5)",
|
|
834
|
+
})
|
|
835
|
+
})
|
|
836
|
+
})
|
|
837
|
+
|
|
838
|
+
// ─── Swing ──────────────────────────────────────────────────────────
|
|
839
|
+
|
|
840
|
+
describe("presets — swing", () => {
|
|
841
|
+
it("swingInTop uses rotateX with transformOrigin top", () => {
|
|
842
|
+
expect(swingInTop.enterStyle).toEqual({
|
|
843
|
+
opacity: 0,
|
|
844
|
+
transform: "perspective(600px) rotateX(-90deg)",
|
|
845
|
+
transformOrigin: "top",
|
|
846
|
+
})
|
|
847
|
+
})
|
|
848
|
+
|
|
849
|
+
it("swingInLeft uses rotateY with transformOrigin left", () => {
|
|
850
|
+
expect(swingInLeft.enterStyle).toEqual({
|
|
851
|
+
opacity: 0,
|
|
852
|
+
transform: "perspective(600px) rotateY(90deg)",
|
|
853
|
+
transformOrigin: "left",
|
|
854
|
+
})
|
|
855
|
+
})
|
|
856
|
+
|
|
857
|
+
it("all swing variants have 500ms enter", () => {
|
|
858
|
+
for (const p of [swingInTop, swingInBottom, swingInLeft, swingInRight]) {
|
|
859
|
+
expect(p.enterTransition).toContain("500ms")
|
|
860
|
+
}
|
|
861
|
+
})
|
|
862
|
+
})
|
|
863
|
+
|
|
864
|
+
// ─── Slit ───────────────────────────────────────────────────────────
|
|
865
|
+
|
|
866
|
+
describe("presets — slit", () => {
|
|
867
|
+
it("slitHorizontal uses rotateY + scaleX", () => {
|
|
868
|
+
expect(slitHorizontal.enterStyle).toEqual({
|
|
869
|
+
opacity: 0,
|
|
870
|
+
transform: "perspective(600px) rotateY(90deg) scaleX(0)",
|
|
871
|
+
})
|
|
872
|
+
})
|
|
873
|
+
|
|
874
|
+
it("slitVertical uses rotateX + scaleY", () => {
|
|
875
|
+
expect(slitVertical.enterStyle).toEqual({
|
|
876
|
+
opacity: 0,
|
|
877
|
+
transform: "perspective(600px) rotateX(90deg) scaleY(0)",
|
|
878
|
+
})
|
|
879
|
+
})
|
|
880
|
+
})
|
|
881
|
+
|
|
882
|
+
// ─── Swirl ──────────────────────────────────────────────────────────
|
|
883
|
+
|
|
884
|
+
describe("presets — swirl", () => {
|
|
885
|
+
it("swirlIn uses -540deg rotation + scale(0)", () => {
|
|
886
|
+
expect(swirlIn.enterStyle).toEqual({
|
|
887
|
+
opacity: 0,
|
|
888
|
+
transform: "rotate(-540deg) scale(0)",
|
|
889
|
+
})
|
|
890
|
+
})
|
|
891
|
+
|
|
892
|
+
it("swirlInReverse uses +540deg", () => {
|
|
893
|
+
expect(swirlInReverse.enterStyle).toEqual({
|
|
894
|
+
opacity: 0,
|
|
895
|
+
transform: "rotate(540deg) scale(0)",
|
|
896
|
+
})
|
|
897
|
+
})
|
|
898
|
+
})
|
|
899
|
+
|
|
900
|
+
// ─── Flip diagonal ─────────────────────────────────────────────────
|
|
901
|
+
|
|
902
|
+
describe("presets — flip diagonal", () => {
|
|
903
|
+
it("flipDiagonal uses rotate3d(1,1,0)", () => {
|
|
904
|
+
expect(flipDiagonal.enterStyle).toEqual({
|
|
905
|
+
opacity: 0,
|
|
906
|
+
transform: "perspective(600px) rotate3d(1, 1, 0, 90deg)",
|
|
907
|
+
})
|
|
908
|
+
})
|
|
909
|
+
|
|
910
|
+
it("flipDiagonalReverse uses rotate3d(1,-1,0)", () => {
|
|
911
|
+
expect(flipDiagonalReverse.enterStyle).toEqual({
|
|
912
|
+
opacity: 0,
|
|
913
|
+
transform: "perspective(600px) rotate3d(1, -1, 0, 90deg)",
|
|
914
|
+
})
|
|
915
|
+
})
|
|
916
|
+
})
|
|
917
|
+
|
|
918
|
+
// ─── Tilt ───────────────────────────────────────────────────────────
|
|
919
|
+
|
|
920
|
+
describe("presets — tilt", () => {
|
|
921
|
+
it("tiltInUp combines perspective rotateX + translateY", () => {
|
|
922
|
+
expect(tiltInUp.enterStyle).toEqual({
|
|
923
|
+
opacity: 0,
|
|
924
|
+
transform: "perspective(600px) rotateX(15deg) translateY(24px)",
|
|
925
|
+
})
|
|
926
|
+
})
|
|
927
|
+
|
|
928
|
+
it("tiltInDown combines perspective rotateX + negative translateY", () => {
|
|
929
|
+
expect(tiltInDown.enterStyle).toEqual({
|
|
930
|
+
opacity: 0,
|
|
931
|
+
transform: "perspective(600px) rotateX(-15deg) translateY(-24px)",
|
|
932
|
+
})
|
|
933
|
+
})
|
|
934
|
+
|
|
935
|
+
it("tiltInLeft combines perspective rotateY + translateX", () => {
|
|
936
|
+
expect(tiltInLeft.enterStyle).toEqual({
|
|
937
|
+
opacity: 0,
|
|
938
|
+
transform: "perspective(600px) rotateY(-15deg) translateX(24px)",
|
|
939
|
+
})
|
|
940
|
+
})
|
|
941
|
+
|
|
942
|
+
it("tiltInRight combines perspective rotateY + negative translateX", () => {
|
|
943
|
+
expect(tiltInRight.enterStyle).toEqual({
|
|
944
|
+
opacity: 0,
|
|
945
|
+
transform: "perspective(600px) rotateY(15deg) translateX(-24px)",
|
|
946
|
+
})
|
|
947
|
+
})
|
|
948
|
+
})
|
|
949
|
+
|
|
950
|
+
// ─── Fly ────────────────────────────────────────────────────────────
|
|
951
|
+
|
|
952
|
+
describe("presets — fly", () => {
|
|
953
|
+
it("flyInUp uses 100vh", () => {
|
|
954
|
+
expect(flyInUp.enterStyle).toEqual({
|
|
955
|
+
opacity: 0,
|
|
956
|
+
transform: "translateY(100vh)",
|
|
957
|
+
})
|
|
958
|
+
})
|
|
959
|
+
|
|
960
|
+
it("flyInDown uses -100vh", () => {
|
|
961
|
+
expect(flyInDown.enterStyle).toEqual({
|
|
962
|
+
opacity: 0,
|
|
963
|
+
transform: "translateY(-100vh)",
|
|
964
|
+
})
|
|
965
|
+
})
|
|
966
|
+
|
|
967
|
+
it("flyInLeft uses 100vw", () => {
|
|
968
|
+
expect(flyInLeft.enterStyle).toEqual({
|
|
969
|
+
opacity: 0,
|
|
970
|
+
transform: "translateX(100vw)",
|
|
971
|
+
})
|
|
972
|
+
})
|
|
973
|
+
|
|
974
|
+
it("flyInRight uses -100vw", () => {
|
|
975
|
+
expect(flyInRight.enterStyle).toEqual({
|
|
976
|
+
opacity: 0,
|
|
977
|
+
transform: "translateX(-100vw)",
|
|
978
|
+
})
|
|
979
|
+
})
|
|
980
|
+
})
|
|
981
|
+
|
|
982
|
+
// ─── Pop / Rubber / Squish ──────────────────────────────────────────
|
|
983
|
+
|
|
984
|
+
describe("presets — pop/rubber/squish", () => {
|
|
985
|
+
it("popIn uses spring easing + scale(0.3)", () => {
|
|
986
|
+
expect(popIn.enterStyle).toEqual({
|
|
987
|
+
opacity: 0,
|
|
988
|
+
transform: "scale(0.3)",
|
|
989
|
+
})
|
|
990
|
+
expect(popIn.enterTransition).toContain("cubic-bezier(0.34, 1.56, 0.64, 1)")
|
|
991
|
+
})
|
|
992
|
+
|
|
993
|
+
it("rubberIn uses elastic easing", () => {
|
|
994
|
+
expect(rubberIn.enterTransition).toContain("cubic-bezier(0.175, 0.885, 0.32, 1.275)")
|
|
995
|
+
})
|
|
996
|
+
|
|
997
|
+
it("squishX uses non-uniform scale", () => {
|
|
998
|
+
expect(squishX.enterStyle).toEqual({
|
|
999
|
+
opacity: 0,
|
|
1000
|
+
transform: "scaleX(1.4) scaleY(0.6)",
|
|
1001
|
+
})
|
|
1002
|
+
})
|
|
1003
|
+
|
|
1004
|
+
it("squishY uses non-uniform scale (inverted)", () => {
|
|
1005
|
+
expect(squishY.enterStyle).toEqual({
|
|
1006
|
+
opacity: 0,
|
|
1007
|
+
transform: "scaleX(0.6) scaleY(1.4)",
|
|
1008
|
+
})
|
|
1009
|
+
})
|
|
1010
|
+
})
|
|
1011
|
+
|
|
1012
|
+
// ─── Scale rotate / newspaper ───────────────────────────────────────
|
|
1013
|
+
|
|
1014
|
+
describe("presets — scaleRotate/newspaper", () => {
|
|
1015
|
+
it("scaleRotateIn uses scale(0) + rotate(-180deg)", () => {
|
|
1016
|
+
expect(scaleRotateIn.enterStyle).toEqual({
|
|
1017
|
+
opacity: 0,
|
|
1018
|
+
transform: "scale(0) rotate(-180deg)",
|
|
1019
|
+
})
|
|
1020
|
+
})
|
|
1021
|
+
|
|
1022
|
+
it("newspaperIn uses scale(0) + rotate(-720deg)", () => {
|
|
1023
|
+
expect(newspaperIn.enterStyle).toEqual({
|
|
1024
|
+
opacity: 0,
|
|
1025
|
+
transform: "scale(0) rotate(-720deg)",
|
|
1026
|
+
})
|
|
1027
|
+
expect(newspaperIn.enterTransition).toContain("700ms")
|
|
1028
|
+
})
|
|
1029
|
+
})
|
|
1030
|
+
|
|
1031
|
+
// ─── Float ──────────────────────────────────────────────────────────
|
|
1032
|
+
|
|
1033
|
+
describe("presets — float", () => {
|
|
1034
|
+
it("floatUp uses premium easing + translateY + scale", () => {
|
|
1035
|
+
expect(floatUp.enterStyle).toEqual({
|
|
1036
|
+
opacity: 0,
|
|
1037
|
+
transform: "translateY(32px) scale(0.97)",
|
|
1038
|
+
})
|
|
1039
|
+
expect(floatUp.enterTransition).toContain("cubic-bezier(0.23, 1, 0.32, 1)")
|
|
1040
|
+
})
|
|
1041
|
+
|
|
1042
|
+
it("all float variants use premium easing", () => {
|
|
1043
|
+
for (const p of [floatUp, floatDown, floatLeft, floatRight]) {
|
|
1044
|
+
expect(p.enterTransition).toContain("cubic-bezier(0.23, 1, 0.32, 1)")
|
|
1045
|
+
}
|
|
1046
|
+
})
|
|
1047
|
+
})
|
|
1048
|
+
|
|
1049
|
+
// ─── Push ───────────────────────────────────────────────────────────
|
|
1050
|
+
|
|
1051
|
+
describe("presets — push", () => {
|
|
1052
|
+
it("pushInLeft uses translateX(-48px) + scale(0.9)", () => {
|
|
1053
|
+
expect(pushInLeft.enterStyle).toEqual({
|
|
1054
|
+
opacity: 0,
|
|
1055
|
+
transform: "translateX(-48px) scale(0.9)",
|
|
1056
|
+
})
|
|
1057
|
+
})
|
|
1058
|
+
|
|
1059
|
+
it("pushInRight uses translateX(48px) + scale(0.9)", () => {
|
|
1060
|
+
expect(pushInRight.enterStyle).toEqual({
|
|
1061
|
+
opacity: 0,
|
|
1062
|
+
transform: "translateX(48px) scale(0.9)",
|
|
1063
|
+
})
|
|
1064
|
+
})
|
|
1065
|
+
})
|