@tamagui/animations-motion 2.7.7 → 3.0.0-beta.643.1

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,3 +1,4 @@
1
+
1
2
  var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -5,36 +6,29 @@ var __getOwnPropNames = Object.getOwnPropertyNames;
5
6
  var __getProtoOf = Object.getPrototypeOf;
6
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
7
8
  var __export = (target, all) => {
8
- for (var name in all) __defProp(target, name, {
9
- get: all[name],
10
- enumerable: true
11
- });
9
+ for (var name in all) __defProp(target, name, {
10
+ get: all[name],
11
+ enumerable: true
12
+ });
12
13
  };
13
14
  var __copyProps = (to, from, except, desc) => {
14
- if (from && typeof from === "object" || typeof from === "function") {
15
- for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
16
- get: () => from[key],
17
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
18
- });
19
- }
20
- return to;
15
+ if (from && typeof from === "object" || typeof from === "function") {
16
+ for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
17
+ get: () => from[key],
18
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
19
+ });
20
+ }
21
+ return to;
21
22
  };
22
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
23
- // If the importer is in node compatibility mode or this is not an ESM
24
- // file that has been converted to a CommonJS file using a Babel-
25
- // compatible transform (i.e. "__esModule" has not been set), then set
26
- // "default" to the CommonJS "module.exports" for node compatibility.
27
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
28
- value: mod,
29
- enumerable: true
23
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
24
+ value: mod,
25
+ enumerable: true
30
26
  }) : target, mod));
31
- var __toCommonJS = mod => __copyProps(__defProp({}, "__esModule", {
32
- value: true
33
- }), mod);
27
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
34
28
  var createAnimations_exports = {};
35
29
  __export(createAnimations_exports, {
36
- createAnimations: () => createAnimations,
37
- disableAnimationProps: () => disableAnimationProps
30
+ createAnimations: () => createAnimations,
31
+ disableAnimationProps: () => disableAnimationProps
38
32
  });
39
33
  module.exports = __toCommonJS(createAnimations_exports);
40
34
  var import_animation_helpers = require("@tamagui/animation-helpers");
@@ -45,790 +39,931 @@ var import_react2 = __toESM(require("react"), 1);
45
39
  var import_jsx_runtime = require("react/jsx-runtime");
46
40
  const isServer = typeof window === "undefined";
47
41
  function useAnimateSSRSafe() {
48
- if (isServer) {
49
- return [(0, import_react2.useRef)(null), () => {}];
50
- }
51
- return (0, import_react.useAnimate)();
42
+ if (isServer) {
43
+ return [(0, import_react2.useRef)(null), (() => {})];
44
+ }
45
+ return (0, import_react.useAnimate)();
52
46
  }
53
- const MotionValueStrategy = /* @__PURE__ */new WeakMap();
54
- const PendingMotionOnFinish = /* @__PURE__ */new WeakMap();
47
+ const asStyleRecord = (style) => style && typeof style === "object" && !Array.isArray(style) ? style : {};
48
+ function assignInlineStyles(node, styles) {
49
+ for (const key in styles) {
50
+ node.style[key] = (0, import_web.normalizeValueWithProperty)(styles[key], key);
51
+ }
52
+ }
53
+ const MotionValueStrategy = /* @__PURE__ */ new WeakMap();
54
+ const PendingMotionOnFinish = /* @__PURE__ */ new WeakMap();
55
55
  function settlePendingMotionOnFinish(mv, controls) {
56
- const onFinish = PendingMotionOnFinish.get(mv);
57
- if (!onFinish) return;
58
- PendingMotionOnFinish.delete(mv);
59
- controls.then(() => onFinish()).catch(() => onFinish());
56
+ const onFinish = PendingMotionOnFinish.get(mv);
57
+ if (!onFinish) return;
58
+ PendingMotionOnFinish.delete(mv);
59
+ controls.then(() => onFinish()).catch(() => onFinish());
60
60
  }
61
- const PopperPositionAnims = /* @__PURE__ */new WeakMap();
61
+ const PopperPositionAnims = /* @__PURE__ */ new WeakMap();
62
62
  function parseTranslate(transform) {
63
- if (!transform || transform === "none") return {
64
- x: 0,
65
- y: 0
66
- };
67
- try {
68
- const m = new DOMMatrixReadOnly(transform);
69
- if (!m.is2D || m.a !== 1 || m.b !== 0 || m.c !== 0 || m.d !== 1) return null;
70
- return {
71
- x: m.e,
72
- y: m.f
73
- };
74
- } catch {
75
- return null;
76
- }
63
+ if (!transform || transform === "none") return {
64
+ x: 0,
65
+ y: 0
66
+ };
67
+ try {
68
+ const m = new DOMMatrixReadOnly(transform);
69
+ if (!m.is2D || m.a !== 1 || m.b !== 0 || m.c !== 0 || m.d !== 1) return null;
70
+ return {
71
+ x: m.e,
72
+ y: m.f
73
+ };
74
+ } catch {
75
+ return null;
76
+ }
77
77
  }
78
78
  function createAnimations(animations) {
79
- let isHydratingGlobal;
80
- const hydratingComponents = /* @__PURE__ */new Set();
81
- return {
82
- View: MotionView,
83
- Text: MotionText,
84
- isReactNative: false,
85
- inputStyle: "css",
86
- outputStyle: "inline",
87
- avoidReRenders: true,
88
- animations,
89
- usePresence: import_use_presence.usePresence,
90
- ResetPresence: import_use_presence.ResetPresence,
91
- onMount() {
92
- isHydratingGlobal = false;
93
- hydratingComponents.forEach(cb => cb());
94
- },
95
- useAnimations: animationProps => {
96
- if (isHydratingGlobal === void 0 && !(0, import_web.getConfig)().settings.disableSSR) {
97
- isHydratingGlobal = true;
98
- }
99
- const {
100
- props,
101
- style,
102
- componentState,
103
- stateRef,
104
- useStyleEmitter,
105
- presence,
106
- styleProps
107
- } = animationProps;
108
- const animationKey = Array.isArray(props.transition) ? props.transition[0] : props.transition;
109
- const isComponentHydrating = componentState.unmounted === true;
110
- const isMounting = componentState.unmounted === "should-enter";
111
- const isEntering = !!componentState.unmounted;
112
- const isExiting = presence?.[0] === false;
113
- const sendExitComplete = presence?.[1];
114
- const refs = (0, import_react2.useRef)(null);
115
- if (!refs.current) {
116
- refs.current = {
117
- isFirstRender: true,
118
- lastDoAnimate: null,
119
- lastDontAnimate: null,
120
- controls: null,
121
- lastAnimateAt: 0,
122
- disposed: false,
123
- wasExiting: false,
124
- isExiting: false,
125
- sendExitComplete: void 0,
126
- animationState: "default",
127
- frozenExitTarget: null,
128
- exitCompleteScheduled: false,
129
- wasEntering: false,
130
- wasDisabled: false,
131
- wasNoClass: !!styleProps.noClass
132
- };
133
- }
134
- const justFinishedEntering = refs.current.wasEntering && !isEntering;
135
- (0, import_react2.useEffect)(() => {
136
- refs.current.wasEntering = isEntering;
137
- });
138
- const animationState = isExiting ? "exit" : isMounting || justFinishedEntering ? "enter" : "default";
139
- const disableAnimation = isComponentHydrating || isMounting || !animationKey;
140
- const [scope, animate] = useAnimateSSRSafe();
141
- refs.current.isExiting = isExiting;
142
- refs.current.sendExitComplete = sendExitComplete;
143
- refs.current.animationState = animationState;
144
- const justStartedExiting = isExiting && !refs.current.wasExiting;
145
- const justStoppedExiting = !isExiting && refs.current.wasExiting;
146
- if (justStartedExiting || justStoppedExiting) {
147
- refs.current.frozenExitTarget = null;
148
- refs.current.exitCompleteScheduled = false;
149
- }
150
- (0, import_react2.useEffect)(() => {
151
- refs.current.wasExiting = isExiting;
152
- });
153
- const {
154
- dontAnimate = {},
155
- doAnimate,
156
- animationOptions
157
- } = getMotionAnimatedProps(props, style, disableAnimation, animationState);
158
- const [firstRenderStyle] = (0, import_react2.useState)(style);
159
- if (refs.current.isFirstRender) {
160
- refs.current.lastDontAnimate = firstRenderStyle;
161
- }
162
- const [isHydrating, setIsHydrating] = (0, import_react2.useState)(isHydratingGlobal);
163
- (0, import_react2.useLayoutEffect)(() => {
164
- if (isHydratingGlobal) {
165
- hydratingComponents.add(() => {
166
- setIsHydrating(false);
167
- });
168
- }
169
- return () => {
170
- refs.current.disposed = true;
171
- };
172
- }, []);
173
- const flushAnimation = ({
174
- doAnimate: doAnimateRaw = {},
175
- animationOptions: passedOptions = {},
176
- dontAnimate: dontAnimate2
177
- }) => {
178
- let startedControls = null;
179
- const isCurrentlyExiting = refs.current.isExiting;
180
- const currentSendExitComplete = refs.current.sendExitComplete;
181
- let doAnimate2 = doAnimateRaw;
182
- if (isCurrentlyExiting && refs.current.frozenExitTarget) {
183
- doAnimate2 = refs.current.frozenExitTarget;
184
- }
185
- const animationOptions2 = isCurrentlyExiting && currentSendExitComplete ? getAnimationOptions(props.transition ?? null, "exit") : passedOptions;
186
- try {
187
- const node = stateRef.current.host;
188
- if (refs.current.isFirstRender) {
189
- refs.current.lastDontAnimate = null;
190
- refs.current.lastDoAnimate = null;
191
- }
192
- if (process.env.NODE_ENV === "development") {
193
- if (props["debug"] && props["debug"] !== "profile") {
194
- console.groupCollapsed(`[motion] animate (${JSON.stringify(getDiff(refs.current.lastDoAnimate, doAnimate2), null, 2)})`);
195
- console.info({
196
- props,
197
- componentState,
198
- doAnimate: doAnimate2,
199
- dontAnimate: dontAnimate2,
200
- animationOptions: animationOptions2,
201
- animationProps,
202
- lastDoAnimate: {
203
- ...refs.current.lastDoAnimate
204
- },
205
- lastDontAnimate: {
206
- ...refs.current.lastDontAnimate
207
- },
208
- isExiting,
209
- style,
210
- node
211
- });
212
- console.groupCollapsed(`trace >`);
213
- console.trace();
214
- console.groupEnd();
215
- console.groupEnd();
216
- }
217
- }
218
- if (!(node instanceof HTMLElement)) {
219
- return;
220
- }
221
- const prevDont = refs.current.lastDontAnimate;
222
- if (dontAnimate2) {
223
- if (prevDont) {
224
- removeRemovedStyles(prevDont, dontAnimate2, node, doAnimate2);
225
- const changed = getDiff(prevDont, dontAnimate2);
226
- if (changed) {
227
- Object.assign(node.style, changed);
228
- }
229
- } else {
230
- Object.assign(node.style, dontAnimate2);
231
- }
232
- }
233
- if (doAnimate2) {
234
- if (prevDont) {
235
- for (const key in prevDont) {
236
- if (key in doAnimate2) {
237
- node.style[key] = prevDont[key];
238
- if (refs.current.lastDoAnimate) {
239
- refs.current.lastDoAnimate[key] = prevDont[key];
240
- }
241
- }
242
- }
243
- }
244
- const lastAnimated = refs.current.lastDoAnimate;
245
- if (lastAnimated) {
246
- removeRemovedStyles(lastAnimated, doAnimate2, node, dontAnimate2);
247
- }
248
- const diff = getDiff(refs.current.lastDoAnimate, doAnimate2);
249
- if (diff) {
250
- if (isCurrentlyExiting && !refs.current.frozenExitTarget) {
251
- refs.current.frozenExitTarget = {
252
- ...doAnimate2
253
- };
254
- }
255
- const isPopperPosition = node.hasAttribute("data-popper-animate-position");
256
- let popperHandledTransform = false;
257
- if (isPopperPosition && !isCurrentlyExiting && typeof diff.transform === "string") {
258
- const target = parseTranslate(diff.transform);
259
- if (target) {
260
- let entry = PopperPositionAnims.get(node);
261
- if (!entry) {
262
- let seed = target;
263
- try {
264
- seed = parseTranslate(getComputedStyle(node).transform) ?? target;
265
- } catch {}
266
- const x = (0, import_react.motionValue)(seed.x);
267
- const y = (0, import_react.motionValue)(seed.y);
268
- const write = () => {
269
- node.style.transform = `translate3d(${x.get()}px, ${y.get()}px, 0)`;
270
- };
271
- x.on("change", write);
272
- y.on("change", write);
273
- entry = {
274
- x,
275
- y,
276
- stop: null
277
- };
278
- PopperPositionAnims.set(node, entry);
279
- }
280
- if (!entry.stop) {
281
- try {
282
- const live = parseTranslate(getComputedStyle(node).transform);
283
- if (live) {
284
- entry.x.jump(live.x);
285
- entry.y.jump(live.y);
286
- }
287
- } catch {}
288
- }
289
- for (const anim of node.getAnimations()) {
290
- try {
291
- const kf = anim.effect?.getKeyframes?.();
292
- if (kf?.some(k => "transform" in k)) {
293
- anim.cancel();
294
- }
295
- } catch {}
296
- }
297
- const opts = animationOptions2;
298
- const positionTransition = opts.transform ?? opts.default ?? animationOptions2;
299
- const cx = (0, import_react.animate)(entry.x, target.x, positionTransition);
300
- const cy = (0, import_react.animate)(entry.y, target.y, positionTransition);
301
- entry.stop = () => {
302
- cx.stop();
303
- cy.stop();
304
- };
305
- popperHandledTransform = true;
306
- }
307
- }
308
- if (isCurrentlyExiting) {
309
- const entry = PopperPositionAnims.get(node);
310
- if (entry?.stop) {
311
- entry.stop();
312
- entry.stop = null;
313
- }
314
- }
315
- let midFlightValues = null;
316
- if (refs.current.controls) {
317
- try {
318
- const computed = getComputedStyle(node);
319
- midFlightValues = {};
320
- for (const key in diff) {
321
- const val = computed[key];
322
- if (val !== void 0 && val !== "") {
323
- midFlightValues[key] = val;
324
- }
325
- }
326
- } catch {}
327
- if (isCurrentlyExiting) {
328
- refs.current.controls.stop();
329
- }
330
- if (midFlightValues) {
331
- for (const key in midFlightValues) {
332
- if (key === "transform" && popperHandledTransform) continue;
333
- node.style[key] = midFlightValues[key];
334
- }
335
- }
336
- if (isPopperPosition && !popperHandledTransform) {
337
- const anims = node.getAnimations();
338
- for (const anim of anims) {
339
- anim.cancel();
340
- }
341
- }
342
- }
343
- const fixedDiff = fixTransparentColors(diff, refs.current.lastDoAnimate, doAnimate2);
344
- let waapiDiff = fixedDiff;
345
- if (popperHandledTransform && "transform" in waapiDiff) {
346
- waapiDiff = {
347
- ...waapiDiff
348
- };
349
- delete waapiDiff.transform;
350
- }
351
- if ((isPopperPosition || isCurrentlyExiting) && midFlightValues?.transform && waapiDiff.transform) {
352
- waapiDiff.transform = [midFlightValues.transform, waapiDiff.transform];
353
- }
354
- if (Object.keys(waapiDiff).length > 0) {
355
- startedControls = animate(scope.current, waapiDiff, animationOptions2);
356
- refs.current.controls = startedControls;
357
- }
358
- refs.current.lastAnimateAt = Date.now();
359
- }
360
- }
361
- refs.current.lastDontAnimate = dontAnimate2 ? {
362
- ...dontAnimate2
363
- } : {};
364
- refs.current.lastDoAnimate = doAnimate2 ? {
365
- ...doAnimate2
366
- } : {};
367
- } finally {
368
- if (isCurrentlyExiting && currentSendExitComplete) {
369
- if (startedControls) {
370
- refs.current.exitCompleteScheduled = true;
371
- startedControls.finished.then(() => {
372
- if (refs.current.isExiting) {
373
- currentSendExitComplete();
374
- }
375
- }).catch(() => {
376
- if (refs.current.isExiting) {
377
- currentSendExitComplete();
378
- }
379
- });
380
- } else if (!refs.current.exitCompleteScheduled) {
381
- currentSendExitComplete();
382
- }
383
- }
384
- }
385
- };
386
- useStyleEmitter?.((nextStyle, effectiveTransition) => {
387
- const animationProps2 = getMotionAnimatedProps(props, nextStyle, disableAnimation, refs.current.animationState, effectiveTransition);
388
- flushAnimation(animationProps2);
389
- });
390
- (0, import_web.useIsomorphicLayoutEffect)(() => {
391
- if (refs.current.isFirstRender) {
392
- refs.current.isFirstRender = false;
393
- refs.current.wasDisabled = disableAnimation;
394
- if (isHydrating) {
395
- if (doAnimate && Object.keys(doAnimate).length > 0) {
396
- refs.current.lastDoAnimate = {
397
- ...doAnimate
398
- };
399
- } else {
400
- refs.current.lastDoAnimate = dontAnimate ? {
401
- ...dontAnimate
402
- } : {};
403
- }
404
- refs.current.lastDontAnimate = dontAnimate ? {
405
- ...dontAnimate
406
- } : {};
407
- refs.current.lastAnimateAt = Date.now();
408
- return;
409
- }
410
- refs.current.lastDontAnimate = dontAnimate ? {
411
- ...dontAnimate
412
- } : {};
413
- refs.current.lastDoAnimate = doAnimate ? {
414
- ...doAnimate
415
- } : {};
416
- return;
417
- }
418
- const justEnabled = refs.current.wasDisabled && !disableAnimation;
419
- refs.current.wasDisabled = disableAnimation;
420
- const justStrippedClasses = !refs.current.wasNoClass && !!styleProps.noClass;
421
- refs.current.wasNoClass = !!styleProps.noClass;
422
- if ((justEnabled || justStrippedClasses) && animationState !== "enter") {
423
- const node = stateRef.current.host;
424
- if (node instanceof HTMLElement) {
425
- if (dontAnimate) Object.assign(node.style, dontAnimate);
426
- if (doAnimate) Object.assign(node.style, doAnimate);
427
- const entry = PopperPositionAnims.get(node);
428
- if (entry) {
429
- const target = parseTranslate(doAnimate?.transform ?? dontAnimate?.transform);
430
- if (target) {
431
- entry.stop?.();
432
- entry.stop = null;
433
- entry.x.jump(target.x);
434
- entry.y.jump(target.y);
435
- }
436
- }
437
- }
438
- refs.current.lastDontAnimate = dontAnimate ? {
439
- ...dontAnimate
440
- } : {};
441
- refs.current.lastDoAnimate = doAnimate ? {
442
- ...doAnimate
443
- } : {};
444
- return;
445
- }
446
- flushAnimation({
447
- doAnimate,
448
- dontAnimate,
449
- animationOptions
450
- });
451
- }, [style, isExiting, disableAnimation, styleProps.noClass]);
452
- if (process.env.NODE_ENV === "development") {
453
- if (props["debug"] && props["debug"] !== "profile") {
454
- console.groupCollapsed(`[motion] render`);
455
- console.info({
456
- style,
457
- doAnimate,
458
- dontAnimate,
459
- scope,
460
- animationOptions,
461
- isExiting,
462
- isFirstRender: refs.current.isFirstRender,
463
- animationProps
464
- });
465
- console.groupEnd();
466
- }
467
- }
468
- return {
469
- style: firstRenderStyle,
470
- ref: scope,
471
- render: "div"
472
- };
473
- },
474
- useAnimatedNumber(initial) {
475
- const motionValue2 = (0, import_react.useMotionValue)(initial);
476
- return import_react2.default.useMemo(() => ({
477
- getInstance() {
478
- return motionValue2;
479
- },
480
- getValue() {
481
- return motionValue2.get();
482
- },
483
- setValue(next, config = {
484
- type: "spring"
485
- }, onFinish) {
486
- if (config.type === "direct") {
487
- MotionValueStrategy.set(motionValue2, {
488
- type: "direct"
489
- });
490
- motionValue2.set(next);
491
- onFinish?.();
492
- return;
493
- }
494
- MotionValueStrategy.set(motionValue2, config);
495
- if (onFinish) {
496
- const prior = PendingMotionOnFinish.get(motionValue2);
497
- if (prior) {
498
- PendingMotionOnFinish.delete(motionValue2);
499
- prior();
500
- }
501
- PendingMotionOnFinish.set(motionValue2, onFinish);
502
- }
503
- motionValue2.set(next);
504
- },
505
- stop() {
506
- motionValue2.stop();
507
- }
508
- }), [motionValue2]);
509
- },
510
- useAnimatedNumberReaction({
511
- value
512
- }, onValue) {
513
- const instance = value.getInstance();
514
- (0, import_react.useMotionValueEvent)(instance, "change", onValue);
515
- },
516
- useAnimatedNumberStyle(val, getStyleProp) {
517
- const motionValue2 = val.getInstance();
518
- const getStyleRef = (0, import_react2.useRef)(getStyleProp);
519
- getStyleRef.current = getStyleProp;
520
- return (0, import_react2.useMemo)(() => {
521
- return {
522
- getStyle: cur => {
523
- return getStyleRef.current(cur);
524
- },
525
- motionValue: motionValue2
526
- };
527
- }, []);
528
- },
529
- useAnimatedNumbersStyle(vals, getStyleProp) {
530
- const motionValues = vals.map(v => v.getInstance());
531
- const getStyleRef = (0, import_react2.useRef)(getStyleProp);
532
- getStyleRef.current = getStyleProp;
533
- return (0, import_react2.useMemo)(() => {
534
- return {
535
- getStyle: (...currentValues) => getStyleRef.current(...currentValues),
536
- motionValues
537
- };
538
- }, []);
539
- }
540
- };
541
- function getMotionAnimatedProps(props, style, disable, animationState = "default", transitionOverride) {
542
- if (disable) {
543
- return {
544
- dontAnimate: style
545
- };
546
- }
547
- const animationOptions = getAnimationOptions(transitionOverride ?? props.transition ?? null, animationState);
548
- let dontAnimate;
549
- let doAnimate;
550
- const animateOnly = props.animateOnly;
551
- for (const key in style) {
552
- const value = style[key];
553
- if (disableAnimationProps.has(key) || animateOnly && !animateOnly.includes(key)) {
554
- dontAnimate ||= {};
555
- dontAnimate[key] = value;
556
- } else {
557
- doAnimate ||= {};
558
- doAnimate[key] = value;
559
- }
560
- }
561
- return {
562
- dontAnimate,
563
- doAnimate,
564
- animationOptions
565
- };
566
- }
567
- function getAnimationOptions(transitionProp, animationState = "default") {
568
- const normalized = (0, import_animation_helpers.normalizeTransition)(transitionProp);
569
- let effectiveKey = (0, import_animation_helpers.getEffectiveAnimation)(normalized, animationState);
570
- if (!effectiveKey && animationState === "default") {
571
- effectiveKey = normalized.enter || normalized.exit || null;
572
- }
573
- const globalConfigOverride = normalized.config ? {
574
- ...normalized.config
575
- } : void 0;
576
- if (!effectiveKey && Object.keys(normalized.properties).length === 0 && !globalConfigOverride) {
577
- return {};
578
- }
579
- const defaultConfig = effectiveKey ? withInferredType(animations[effectiveKey]) : null;
580
- const delay = normalized.delay;
581
- const result = {};
582
- if (defaultConfig) {
583
- Object.assign(result, defaultConfig);
584
- }
585
- if (globalConfigOverride) {
586
- Object.assign(result, globalConfigOverride);
587
- if (result.type === void 0 && result.duration !== void 0 && result.damping === void 0 && result.stiffness === void 0 && result.mass === void 0) {
588
- result.type = "tween";
589
- }
590
- }
591
- if (delay) {
592
- result.delay = delay;
593
- }
594
- if (defaultConfig || globalConfigOverride || delay) {
595
- result.default = {
596
- ...defaultConfig,
597
- ...globalConfigOverride,
598
- ...(delay ? {
599
- delay
600
- } : null)
601
- };
602
- }
603
- for (const [propName, animationNameOrConfig] of Object.entries(normalized.properties)) {
604
- if (typeof animationNameOrConfig === "string") {
605
- result[propName] = withInferredType(animations[animationNameOrConfig]);
606
- } else if (animationNameOrConfig && typeof animationNameOrConfig === "object") {
607
- const baseConfig = animationNameOrConfig.type ? withInferredType(animations[animationNameOrConfig.type]) : defaultConfig;
608
- result[propName] = {
609
- ...baseConfig,
610
- ...animationNameOrConfig
611
- };
612
- }
613
- }
614
- convertMsToS(result);
615
- convertMsToS(result.default);
616
- for (const key in result) {
617
- if (key !== "default" && typeof result[key] === "object") {
618
- convertMsToS(result[key]);
619
- }
620
- }
621
- return result;
622
- }
79
+ let isHydratingGlobal;
80
+ const hydratingComponents = /* @__PURE__ */ new Set();
81
+ return {
82
+ View: MotionView,
83
+ Text: MotionText,
84
+ isReactNative: false,
85
+ inputStyle: "css",
86
+ outputStyle: "inline",
87
+ avoidReRenders: true,
88
+ animations,
89
+ usePresence: import_use_presence.usePresence,
90
+ ResetPresence: import_use_presence.ResetPresence,
91
+ onMount() {
92
+ isHydratingGlobal = false;
93
+ hydratingComponents.forEach((cb) => cb());
94
+ },
95
+ useAnimations: (animationProps) => {
96
+ if (isHydratingGlobal === void 0 && !(0, import_web.getConfig)().settings.disableSSR) {
97
+ isHydratingGlobal = true;
98
+ }
99
+ const { props, style, componentState, stateRef, useStyleEmitter, presence, onTransition, styleProps } = animationProps;
100
+ const animationKey = Array.isArray(props.transition) ? props.transition[0] : props.transition;
101
+ const isComponentHydrating = componentState.unmounted === true;
102
+ const isMounting = componentState.unmounted === "should-enter";
103
+ const isEntering = !!componentState.unmounted;
104
+ const isExiting = presence?.[0] === false;
105
+ const sendExitComplete = presence?.[1];
106
+ const refs = (0, import_react2.useRef)(null);
107
+ if (!refs.current) {
108
+ refs.current = {
109
+ isFirstRender: true,
110
+ lastDoAnimate: null,
111
+ lastDontAnimate: null,
112
+ controls: null,
113
+ lastAnimateAt: 0,
114
+ disposed: false,
115
+ wasExiting: false,
116
+ isExiting: false,
117
+ sendExitComplete: void 0,
118
+ animationState: "default",
119
+ frozenExitTarget: null,
120
+ exitCompleteScheduled: false,
121
+ enterCompleteScheduled: false,
122
+ disableAnimation: true,
123
+ wasEntering: false,
124
+ wasDisabled: false,
125
+ onTransition: void 0,
126
+ enterStarted: false,
127
+ exitStarted: false,
128
+ updateInFlight: false,
129
+ updateControls: null,
130
+ wasNoClass: !!styleProps.noClass
131
+ };
132
+ }
133
+ const emit = (phase, cause, finished) => {
134
+ refs.current.onTransition?.(phase === "end" ? {
135
+ phase,
136
+ cause,
137
+ finished
138
+ } : {
139
+ phase,
140
+ cause
141
+ });
142
+ };
143
+ const justFinishedEntering = refs.current.wasEntering && !isEntering;
144
+ (0, import_react2.useEffect)(() => {
145
+ refs.current.wasEntering = isEntering;
146
+ });
147
+ const animationState = isExiting ? "exit" : isMounting || justFinishedEntering ? "enter" : "default";
148
+ const disableAnimation = isComponentHydrating || isMounting || !animationKey;
149
+ const [scope] = useAnimateSSRSafe();
150
+ refs.current.isExiting = isExiting;
151
+ refs.current.sendExitComplete = sendExitComplete;
152
+ refs.current.animationState = animationState;
153
+ refs.current.disableAnimation = disableAnimation;
154
+ refs.current.onTransition = onTransition;
155
+ const justStartedExiting = isExiting && !refs.current.wasExiting;
156
+ const justStoppedExiting = !isExiting && refs.current.wasExiting;
157
+ if (justStartedExiting || justStoppedExiting) {
158
+ refs.current.frozenExitTarget = null;
159
+ refs.current.exitCompleteScheduled = false;
160
+ refs.current.enterCompleteScheduled = false;
161
+ }
162
+ (0, import_react2.useEffect)(() => {
163
+ refs.current.wasExiting = isExiting;
164
+ });
165
+ (0, import_web.useIsomorphicLayoutEffect)(() => {
166
+ if (justStoppedExiting && refs.current.exitStarted) {
167
+ refs.current.exitStarted = false;
168
+ emit("end", "exit", false);
169
+ }
170
+ }, [justStoppedExiting]);
171
+ const { dontAnimate = {}, doAnimate, animationOptions } = getMotionAnimatedProps(props, style, disableAnimation, animationState);
172
+ const [firstRenderStyle] = (0, import_react2.useState)(style);
173
+ if (refs.current.isFirstRender) {
174
+ refs.current.lastDontAnimate = firstRenderStyle;
175
+ }
176
+ const [isHydrating, setIsHydrating] = (0, import_react2.useState)(isHydratingGlobal);
177
+ (0, import_react2.useLayoutEffect)(() => {
178
+ if (isHydratingGlobal) {
179
+ hydratingComponents.add(() => {
180
+ setIsHydrating(false);
181
+ });
182
+ }
183
+ return () => {
184
+ refs.current.disposed = true;
185
+ };
186
+ }, []);
187
+ const flushAnimation = ({ doAnimate: doAnimateRaw = {}, animationOptions: passedOptions = {}, dontAnimate: dontAnimate2 }) => {
188
+ let startedControls = null;
189
+ const isCurrentlyExiting = refs.current.isExiting;
190
+ const currentSendExitComplete = refs.current.sendExitComplete;
191
+ const currentAnimationState = refs.current.animationState;
192
+ let doAnimate2 = doAnimateRaw;
193
+ if (isCurrentlyExiting && refs.current.frozenExitTarget) {
194
+ doAnimate2 = refs.current.frozenExitTarget;
195
+ }
196
+ const animationOptions2 = isCurrentlyExiting && currentSendExitComplete ? getAnimationOptions(props.transition ?? null, "exit") : passedOptions;
197
+ try {
198
+ const node = stateRef.current.host;
199
+ if (refs.current.isFirstRender) {
200
+ refs.current.lastDontAnimate = null;
201
+ refs.current.lastDoAnimate = null;
202
+ }
203
+ if (process.env.NODE_ENV === "development") {
204
+ if (props["debug"] && props["debug"] !== "profile") {
205
+ console.groupCollapsed(`[motion] animate (${JSON.stringify(getDiff(refs.current.lastDoAnimate, doAnimate2), null, 2)})`);
206
+ console.info({
207
+ props,
208
+ componentState,
209
+ doAnimate: doAnimate2,
210
+ dontAnimate: dontAnimate2,
211
+ animationOptions: animationOptions2,
212
+ animationProps,
213
+ lastDoAnimate: { ...refs.current.lastDoAnimate },
214
+ lastDontAnimate: { ...refs.current.lastDontAnimate },
215
+ isExiting,
216
+ style,
217
+ node
218
+ });
219
+ console.groupCollapsed(`trace >`);
220
+ console.trace();
221
+ console.groupEnd();
222
+ console.groupEnd();
223
+ }
224
+ }
225
+ if (!(node instanceof HTMLElement)) {
226
+ return;
227
+ }
228
+ const prevDont = refs.current.lastDontAnimate;
229
+ if (dontAnimate2) {
230
+ if (prevDont) {
231
+ removeRemovedStyles(prevDont, dontAnimate2, node, doAnimate2);
232
+ const changed = getDiff(prevDont, dontAnimate2);
233
+ if (changed) {
234
+ assignInlineStyles(node, changed);
235
+ }
236
+ } else {
237
+ assignInlineStyles(node, dontAnimate2);
238
+ }
239
+ }
240
+ if (doAnimate2) {
241
+ if (prevDont) {
242
+ for (const key in prevDont) {
243
+ if (key in doAnimate2) {
244
+ node.style[key] = (0, import_web.normalizeValueWithProperty)(prevDont[key], key);
245
+ if (refs.current.lastDoAnimate) {
246
+ refs.current.lastDoAnimate[key] = prevDont[key];
247
+ }
248
+ }
249
+ }
250
+ }
251
+ const lastAnimated = refs.current.lastDoAnimate;
252
+ if (lastAnimated) {
253
+ removeRemovedStyles(lastAnimated, doAnimate2, node, dontAnimate2);
254
+ }
255
+ const diff = getDiff(refs.current.lastDoAnimate, doAnimate2);
256
+ if (diff) {
257
+ if (isCurrentlyExiting && !refs.current.frozenExitTarget) {
258
+ refs.current.frozenExitTarget = { ...doAnimate2 };
259
+ }
260
+ const isPopperPosition = node.hasAttribute("data-popper-animate-position");
261
+ let popperHandledTransform = false;
262
+ if (isPopperPosition && !isCurrentlyExiting && typeof diff.transform === "string") {
263
+ const target = parseTranslate(diff.transform);
264
+ if (target) {
265
+ let entry = PopperPositionAnims.get(node);
266
+ if (!entry) {
267
+ let seed = target;
268
+ try {
269
+ seed = parseTranslate(getComputedStyle(node).transform) ?? target;
270
+ } catch {}
271
+ const x = (0, import_react.motionValue)(seed.x);
272
+ const y = (0, import_react.motionValue)(seed.y);
273
+ const write = () => {
274
+ node.style.transform = `translate3d(${x.get()}px, ${y.get()}px, 0)`;
275
+ };
276
+ x.on("change", write);
277
+ y.on("change", write);
278
+ entry = {
279
+ x,
280
+ y,
281
+ stop: null
282
+ };
283
+ PopperPositionAnims.set(node, entry);
284
+ }
285
+ if (!entry.stop) {
286
+ try {
287
+ const live = parseTranslate(getComputedStyle(node).transform);
288
+ if (live) {
289
+ entry.x.jump(live.x);
290
+ entry.y.jump(live.y);
291
+ }
292
+ } catch {}
293
+ }
294
+ for (const anim of node.getAnimations()) {
295
+ try {
296
+ const kf = anim.effect?.getKeyframes?.();
297
+ if (kf?.some((k) => "transform" in k)) {
298
+ anim.cancel();
299
+ }
300
+ } catch {}
301
+ }
302
+ const opts = animationOptions2;
303
+ const positionTransition = opts.transform ?? opts.default ?? animationOptions2;
304
+ const cx = (0, import_react.animate)(entry.x, target.x, positionTransition);
305
+ const cy = (0, import_react.animate)(entry.y, target.y, positionTransition);
306
+ entry.stop = () => {
307
+ cx.stop();
308
+ cy.stop();
309
+ };
310
+ popperHandledTransform = true;
311
+ }
312
+ }
313
+ if (isCurrentlyExiting) {
314
+ const entry = PopperPositionAnims.get(node);
315
+ if (entry?.stop) {
316
+ entry.stop();
317
+ entry.stop = null;
318
+ }
319
+ }
320
+ let midFlightValues = null;
321
+ if (refs.current.controls) {
322
+ try {
323
+ const computed = getComputedStyle(node);
324
+ midFlightValues = {};
325
+ for (const key in diff) {
326
+ const val = computed[key];
327
+ if (val !== void 0 && val !== "") {
328
+ midFlightValues[key] = val;
329
+ }
330
+ }
331
+ } catch {}
332
+ if (isCurrentlyExiting) {
333
+ refs.current.controls.stop();
334
+ }
335
+ if (midFlightValues) {
336
+ for (const key in midFlightValues) {
337
+ if (key === "transform" && popperHandledTransform) continue;
338
+ node.style[key] = midFlightValues[key];
339
+ }
340
+ }
341
+ if (isPopperPosition && !popperHandledTransform) {
342
+ const anims = node.getAnimations();
343
+ for (const anim of anims) {
344
+ anim.cancel();
345
+ }
346
+ }
347
+ }
348
+ const fixedDiff = fixTransparentColors(diff, refs.current.lastDoAnimate, doAnimate2);
349
+ let waapiDiff = Object.fromEntries(Object.entries(fixedDiff).map(([key, value]) => [key, Array.isArray(value) ? value.map((item) => (0, import_web.normalizeValueWithProperty)(item, key)) : (0, import_web.normalizeValueWithProperty)(value, key)]));
350
+ if (popperHandledTransform && "transform" in waapiDiff) {
351
+ waapiDiff = { ...waapiDiff };
352
+ delete waapiDiff.transform;
353
+ }
354
+ if ((isPopperPosition || isCurrentlyExiting) && midFlightValues?.transform && waapiDiff.transform) {
355
+ waapiDiff.transform = [midFlightValues.transform, waapiDiff.transform];
356
+ }
357
+ if (Object.keys(waapiDiff).length > 0) {
358
+ startedControls = (0, import_react.animate)(node, waapiDiff, animationOptions2);
359
+ refs.current.controls = startedControls;
360
+ }
361
+ refs.current.lastAnimateAt = Date.now();
362
+ }
363
+ }
364
+ refs.current.lastDontAnimate = dontAnimate2 ? { ...dontAnimate2 } : {};
365
+ refs.current.lastDoAnimate = doAnimate2 ? { ...doAnimate2 } : {};
366
+ } finally {
367
+ if (isCurrentlyExiting && currentSendExitComplete) {
368
+ if (refs.current.enterStarted) {
369
+ refs.current.enterStarted = false;
370
+ emit("end", "enter", false);
371
+ }
372
+ if (startedControls) {
373
+ if (!refs.current.exitStarted) {
374
+ refs.current.exitStarted = true;
375
+ emit("start", "exit");
376
+ }
377
+ refs.current.exitCompleteScheduled = true;
378
+ const complete = (finished) => {
379
+ if (!refs.current.isExiting) return;
380
+ if (refs.current.exitStarted) {
381
+ refs.current.exitStarted = false;
382
+ emit("end", "exit", finished);
383
+ }
384
+ currentSendExitComplete();
385
+ };
386
+ startedControls.finished.then(() => complete(true)).catch(() => complete(false));
387
+ } else if (!refs.current.exitCompleteScheduled) {
388
+ emit("start", "exit");
389
+ emit("end", "exit", true);
390
+ currentSendExitComplete();
391
+ }
392
+ } else if (currentAnimationState === "enter") {
393
+ if (startedControls) {
394
+ if (!refs.current.enterStarted) {
395
+ refs.current.enterStarted = true;
396
+ emit("start", "enter");
397
+ }
398
+ refs.current.enterCompleteScheduled = true;
399
+ const complete = (finished) => {
400
+ if (refs.current.disposed || refs.current.animationState !== "enter") return;
401
+ if (refs.current.enterStarted) {
402
+ refs.current.enterStarted = false;
403
+ emit("end", "enter", finished);
404
+ }
405
+ };
406
+ startedControls.finished.then(() => complete(true)).catch(() => complete(false));
407
+ } else if (!refs.current.enterCompleteScheduled && !refs.current.disableAnimation) {
408
+ emit("start", "enter");
409
+ emit("end", "enter", true);
410
+ }
411
+ } else if (startedControls) {
412
+ const controls = startedControls;
413
+ if (refs.current.updateInFlight) {
414
+ emit("end", "update", false);
415
+ }
416
+ refs.current.updateInFlight = true;
417
+ refs.current.updateControls = controls;
418
+ emit("start", "update");
419
+ const settle = (finished) => {
420
+ if (refs.current.updateControls !== controls) return;
421
+ refs.current.updateInFlight = false;
422
+ refs.current.updateControls = null;
423
+ emit("end", "update", finished);
424
+ };
425
+ controls.finished.then(() => settle(true)).catch(() => settle(false));
426
+ }
427
+ }
428
+ };
429
+ useStyleEmitter?.((nextStyle, effectiveTransition) => {
430
+ const animationProps2 = getMotionAnimatedProps(props, nextStyle, disableAnimation, refs.current.animationState, effectiveTransition);
431
+ flushAnimation(animationProps2);
432
+ });
433
+ (0, import_web.useIsomorphicLayoutEffect)(() => {
434
+ if (refs.current.isFirstRender) {
435
+ refs.current.isFirstRender = false;
436
+ refs.current.wasDisabled = disableAnimation;
437
+ if (isHydrating) {
438
+ if (doAnimate && Object.keys(doAnimate).length > 0) {
439
+ refs.current.lastDoAnimate = { ...doAnimate };
440
+ } else {
441
+ refs.current.lastDoAnimate = dontAnimate ? { ...dontAnimate } : {};
442
+ }
443
+ refs.current.lastDontAnimate = dontAnimate ? { ...dontAnimate } : {};
444
+ refs.current.lastAnimateAt = Date.now();
445
+ return;
446
+ }
447
+ refs.current.lastDontAnimate = dontAnimate ? { ...dontAnimate } : {};
448
+ refs.current.lastDoAnimate = doAnimate ? { ...doAnimate } : {};
449
+ return;
450
+ }
451
+ const justEnabled = refs.current.wasDisabled && !disableAnimation;
452
+ refs.current.wasDisabled = disableAnimation;
453
+ const justStrippedClasses = !refs.current.wasNoClass && !!styleProps.noClass;
454
+ refs.current.wasNoClass = !!styleProps.noClass;
455
+ if ((justEnabled || justStrippedClasses) && animationState !== "enter") {
456
+ const node = stateRef.current.host;
457
+ if (node instanceof HTMLElement) {
458
+ if (dontAnimate) assignInlineStyles(node, dontAnimate);
459
+ if (doAnimate) assignInlineStyles(node, doAnimate);
460
+ const entry = PopperPositionAnims.get(node);
461
+ if (entry) {
462
+ const target = parseTranslate(doAnimate?.transform ?? dontAnimate?.transform);
463
+ if (target) {
464
+ entry.stop?.();
465
+ entry.stop = null;
466
+ entry.x.jump(target.x);
467
+ entry.y.jump(target.y);
468
+ }
469
+ }
470
+ }
471
+ refs.current.lastDontAnimate = dontAnimate ? { ...dontAnimate } : {};
472
+ refs.current.lastDoAnimate = doAnimate ? { ...doAnimate } : {};
473
+ return;
474
+ }
475
+ flushAnimation({
476
+ doAnimate,
477
+ dontAnimate,
478
+ animationOptions
479
+ });
480
+ }, [
481
+ style,
482
+ isExiting,
483
+ disableAnimation,
484
+ styleProps.noClass
485
+ ]);
486
+ if (process.env.NODE_ENV === "development") {
487
+ if (props["debug"] && props["debug"] !== "profile") {
488
+ console.groupCollapsed(`[motion] render`);
489
+ console.info({
490
+ style,
491
+ doAnimate,
492
+ dontAnimate,
493
+ scope,
494
+ animationOptions,
495
+ isExiting,
496
+ isFirstRender: refs.current.isFirstRender,
497
+ animationProps
498
+ });
499
+ console.groupEnd();
500
+ }
501
+ }
502
+ return {
503
+ style: firstRenderStyle,
504
+ ref: scope,
505
+ render: "div"
506
+ };
507
+ },
508
+ useAnimatedNumber(initial) {
509
+ const motionValue2 = (0, import_react.useMotionValue)(initial);
510
+ return import_react2.default.useMemo(() => ({
511
+ getInstance() {
512
+ return motionValue2;
513
+ },
514
+ getValue() {
515
+ return motionValue2.get();
516
+ },
517
+ setValue(next, config = { type: "spring" }, onFinish) {
518
+ if (config.type === "direct") {
519
+ MotionValueStrategy.set(motionValue2, { type: "direct" });
520
+ motionValue2.set(next);
521
+ onFinish?.();
522
+ return;
523
+ }
524
+ MotionValueStrategy.set(motionValue2, config);
525
+ if (onFinish) {
526
+ const prior = PendingMotionOnFinish.get(motionValue2);
527
+ if (prior) {
528
+ PendingMotionOnFinish.delete(motionValue2);
529
+ prior();
530
+ }
531
+ PendingMotionOnFinish.set(motionValue2, onFinish);
532
+ }
533
+ motionValue2.set(next);
534
+ },
535
+ stop() {
536
+ motionValue2.stop();
537
+ }
538
+ }), [motionValue2]);
539
+ },
540
+ useAnimatedNumberReaction({ value }, onValue) {
541
+ const instance = value.getInstance();
542
+ (0, import_react.useMotionValueEvent)(instance, "change", onValue);
543
+ },
544
+ useAnimatedNumberStyle(val, getStyleProp) {
545
+ const motionValue2 = val.getInstance();
546
+ const getStyleRef = (0, import_react2.useRef)(getStyleProp);
547
+ getStyleRef.current = getStyleProp;
548
+ return (0, import_react2.useMemo)(() => {
549
+ return {
550
+ getStyle: (cur) => {
551
+ return getStyleRef.current(cur);
552
+ },
553
+ motionValue: motionValue2
554
+ };
555
+ }, []);
556
+ },
557
+ useAnimatedNumbersStyle(vals, getStyleProp) {
558
+ const motionValues = vals.map((v) => v.getInstance());
559
+ const getStyleRef = (0, import_react2.useRef)(getStyleProp);
560
+ getStyleRef.current = getStyleProp;
561
+ return (0, import_react2.useMemo)(() => {
562
+ return {
563
+ getStyle: (...currentValues) => getStyleRef.current(...currentValues),
564
+ motionValues
565
+ };
566
+ }, []);
567
+ }
568
+ };
569
+ function getMotionAnimatedProps(props, style, disable, animationState = "default", transitionOverride) {
570
+ if (disable) {
571
+ return { dontAnimate: style };
572
+ }
573
+ const animationOptions = getAnimationOptions(transitionOverride ?? props.transition ?? null, animationState);
574
+ let dontAnimate;
575
+ let doAnimate;
576
+ const animateOnly = props.animateOnly;
577
+ for (const key in style) {
578
+ const value = style[key];
579
+ if (disableAnimationProps.has(key) || animateOnly && !animateOnly.includes(key)) {
580
+ dontAnimate ||= {};
581
+ dontAnimate[key] = value;
582
+ } else {
583
+ doAnimate ||= {};
584
+ doAnimate[key] = value;
585
+ }
586
+ }
587
+ return {
588
+ dontAnimate,
589
+ doAnimate,
590
+ animationOptions
591
+ };
592
+ }
593
+ function getAnimationOptions(transitionProp, animationState = "default") {
594
+ const normalized = (0, import_animation_helpers.normalizeTransition)(transitionProp);
595
+ let effectiveKey = (0, import_animation_helpers.getEffectiveAnimation)(normalized, animationState);
596
+ if (!effectiveKey && animationState === "default") {
597
+ effectiveKey = normalized.enter || normalized.exit || null;
598
+ }
599
+ const globalConfigOverride = normalized.config ? { ...normalized.config } : void 0;
600
+ if (!effectiveKey && Object.keys(normalized.properties).length === 0 && !globalConfigOverride) {
601
+ return {};
602
+ }
603
+ const defaultConfig = effectiveKey ? withInferredType(animations[effectiveKey]) : null;
604
+ const delay = normalized.delay;
605
+ const result = {};
606
+ if (defaultConfig) {
607
+ Object.assign(result, defaultConfig);
608
+ }
609
+ if (globalConfigOverride) {
610
+ Object.assign(result, globalConfigOverride);
611
+ if (result.type === void 0 && result.duration !== void 0 && result.damping === void 0 && result.stiffness === void 0 && result.mass === void 0) {
612
+ result.type = "tween";
613
+ }
614
+ }
615
+ if (delay) {
616
+ result.delay = delay;
617
+ }
618
+ if (defaultConfig || globalConfigOverride || delay) {
619
+ result.default = {
620
+ ...defaultConfig,
621
+ ...globalConfigOverride,
622
+ ...delay ? { delay } : null
623
+ };
624
+ }
625
+ for (const [propName, animationNameOrConfig] of Object.entries(normalized.properties)) {
626
+ if (typeof animationNameOrConfig === "string") {
627
+ result[propName] = withInferredType(animations[animationNameOrConfig]);
628
+ } else if (animationNameOrConfig && typeof animationNameOrConfig === "object") {
629
+ const baseConfig = animationNameOrConfig.type ? withInferredType(animations[animationNameOrConfig.type]) : defaultConfig;
630
+ result[propName] = {
631
+ ...baseConfig,
632
+ ...animationNameOrConfig
633
+ };
634
+ }
635
+ }
636
+ convertMsToS(result);
637
+ convertMsToS(result.default);
638
+ for (const key in result) {
639
+ if (key !== "default" && typeof result[key] === "object") {
640
+ convertMsToS(result[key]);
641
+ }
642
+ }
643
+ return result;
644
+ }
623
645
  }
624
646
  function withInferredType(config) {
625
- if (!config) {
626
- return {
627
- type: "spring"
628
- };
629
- }
630
- const isTimingBased = config.duration !== void 0 && config.damping === void 0 && config.stiffness === void 0 && config.mass === void 0;
631
- return {
632
- type: isTimingBased ? "tween" : "spring",
633
- ...config
634
- };
647
+ if (!config) {
648
+ return { type: "spring" };
649
+ }
650
+ const isTimingBased = config.duration !== void 0 && config.damping === void 0 && config.stiffness === void 0 && config.mass === void 0;
651
+ return {
652
+ type: isTimingBased ? "tween" : "spring",
653
+ ...config
654
+ };
635
655
  }
636
656
  function convertMsToS(config) {
637
- if (!config) return;
638
- if (typeof config.delay === "number") config.delay = config.delay / 1e3;
639
- if (typeof config.duration === "number") {
640
- const isTimingBased = config.type === "tween" || config.type === void 0 && config.damping === void 0 && config.stiffness === void 0 && config.mass === void 0;
641
- if (isTimingBased) {
642
- config.duration = config.duration / 1e3;
643
- }
644
- }
657
+ if (!config) return;
658
+ if (typeof config.delay === "number") config.delay = config.delay / 1e3;
659
+ if (typeof config.duration === "number") {
660
+ const isTimingBased = config.type === "tween" || config.type === void 0 && config.damping === void 0 && config.stiffness === void 0 && config.mass === void 0;
661
+ if (isTimingBased) {
662
+ config.duration = config.duration / 1e3;
663
+ }
664
+ }
645
665
  }
646
666
  function removeRemovedStyles(prev, next, node, dontClearIfIn) {
647
- for (const key in prev) {
648
- if (!(key in next)) {
649
- if (dontClearIfIn && key in dontClearIfIn) {
650
- continue;
651
- }
652
- node.style[key] = "";
653
- }
654
- }
667
+ for (const key in prev) {
668
+ if (!(key in next)) {
669
+ if (dontClearIfIn && key in dontClearIfIn) {
670
+ continue;
671
+ }
672
+ node.style[key] = "";
673
+ }
674
+ }
675
+ }
676
+ const disableAnimationProps = /* @__PURE__ */ new Set([
677
+ "alignContent",
678
+ "alignItems",
679
+ "boxSizing",
680
+ "contain",
681
+ "containerType",
682
+ "display",
683
+ "flexBasis",
684
+ "flexDirection",
685
+ "fontFamily",
686
+ "justifyContent",
687
+ "overflow",
688
+ "overflowX",
689
+ "overflowY",
690
+ "pointerEvents",
691
+ "position",
692
+ "textWrap",
693
+ "userSelect"
694
+ ]);
695
+ function motionPropsEqual(a, b) {
696
+ for (const key in a) {
697
+ if (!(key in b)) return false;
698
+ }
699
+ for (const key in b) {
700
+ if (key === "children") continue;
701
+ const av = a[key];
702
+ const bv = b[key];
703
+ if (typeof bv === "function" && typeof av === "function") continue;
704
+ if (!Object.is(av, bv)) return false;
705
+ }
706
+ return true;
707
+ }
708
+ function motionStylesEqual(a, b) {
709
+ if (a.length !== b.length) return false;
710
+ for (let i = 0; i < a.length; i++) {
711
+ const sa = a[i];
712
+ const sb = b[i];
713
+ if (sa === sb) continue;
714
+ if (!sa || !sb) return false;
715
+ let aCount = 0;
716
+ for (const key in sa) {
717
+ aCount++;
718
+ if (!Object.is(sa[key], sb[key])) return false;
719
+ }
720
+ let bCount = 0;
721
+ for (const _key in sb) {
722
+ bCount++;
723
+ }
724
+ if (aCount !== bCount) return false;
725
+ }
726
+ return true;
655
727
  }
656
- const disableAnimationProps = /* @__PURE__ */new Set(["alignContent", "alignItems", "boxSizing", "contain", "containerType", "display", "flexBasis", "flexDirection", "fontFamily", "justifyContent", "overflow", "overflowX", "overflowY", "pointerEvents", "position", "textWrap", "userSelect"]);
657
728
  const MotionView = createMotionView("div");
658
729
  const MotionText = createMotionView("span");
730
+ const transformAliases = {
731
+ x: "translateX",
732
+ y: "translateY",
733
+ scale: "scale",
734
+ scaleX: "scaleX",
735
+ scaleY: "scaleY",
736
+ rotate: "rotate",
737
+ rotateX: "rotateX",
738
+ rotateY: "rotateY",
739
+ rotateZ: "rotateZ",
740
+ skewX: "skewX",
741
+ skewY: "skewY"
742
+ };
743
+ function compileAnimatedStyle(initialSource, initialResolved) {
744
+ const shorthands = (0, import_web.getConfig)().shorthands;
745
+ const entries = Object.keys(initialSource).map((source) => ({
746
+ source,
747
+ target: shorthands?.[source] ?? source,
748
+ tokenValue: typeof initialSource[source] === "string" && initialResolved[shorthands?.[source] ?? source] !== initialSource[source] ? initialResolved[shorthands?.[source] ?? source] : void 0
749
+ }));
750
+ return (sourceStyle) => {
751
+ const resolved = {};
752
+ const transforms = [];
753
+ for (const entry of entries) {
754
+ const value = sourceStyle[entry.source];
755
+ if (value === void 0) continue;
756
+ if (entry.source === "transform" && Array.isArray(value)) {
757
+ resolved.transform = (0, import_web.transformsToString)(value);
758
+ } else if (entry.source in transformAliases) {
759
+ transforms.push({ [transformAliases[entry.source]]: value });
760
+ } else {
761
+ resolved[entry.target] = entry.tokenValue ?? (0, import_web.normalizeValueWithProperty)(value, entry.target);
762
+ }
763
+ }
764
+ if (transforms.length) resolved.transform = (0, import_web.transformsToString)(transforms);
765
+ return resolved;
766
+ };
767
+ }
659
768
  function createMotionView(defaultTag) {
660
- const isText = defaultTag === "span";
661
- const Component = (0, import_react2.forwardRef)((propsIn, ref) => {
662
- const {
663
- forwardedRef,
664
- animation,
665
- render = defaultTag,
666
- style,
667
- ...propsRest
668
- } = propsIn;
669
- const [scope, animate] = useAnimateSSRSafe();
670
- const hostRef = (0, import_react2.useRef)(null);
671
- const seededNode = (0, import_react2.useRef)(null);
672
- const seededInCurrentFrame = (0, import_react2.useRef)(false);
673
- const queuedAnimationFrames = (0, import_react2.useRef)(/* @__PURE__ */new WeakMap());
674
- const composedRefs = (0, import_web.useComposedRefs)(forwardedRef, ref, hostRef, scope);
675
- const stateRef = (0, import_react2.useRef)(null);
676
- if (!stateRef.current) {
677
- stateRef.current = {
678
- get host() {
679
- return hostRef.current;
680
- }
681
- };
682
- }
683
- const [_, state] = (0, import_web.useThemeWithState)({});
684
- const styles = Array.isArray(style) ? style : [style];
685
- const [animatedStyle, nonAnimatedStyles] = (() => {
686
- let animatedStyle2;
687
- const nonAnimatedStyles2 = [];
688
- for (const style2 of styles) {
689
- if (style2.getStyle) {
690
- animatedStyle2 = style2;
691
- } else {
692
- nonAnimatedStyles2.push(style2);
693
- }
694
- }
695
- return [animatedStyle2, nonAnimatedStyles2];
696
- })();
697
- function getProps(props2) {
698
- const out = (0, import_web.getSplitStyles)(props2, isText ? import_web.Text.staticConfig : import_web.View.staticConfig, state?.theme, state?.name, {
699
- unmounted: false
700
- }, {
701
- isAnimated: false,
702
- noClass: true,
703
- resolveValues: "auto"
704
- });
705
- if (!out) {
706
- return {};
707
- }
708
- if (out.viewProps.style) {
709
- (0, import_web.fixStyles)(out.viewProps.style);
710
- (0, import_web.styleToCSS)(out.viewProps.style);
711
- }
712
- return out.viewProps;
713
- }
714
- const props = getProps({
715
- ...propsRest,
716
- style: nonAnimatedStyles
717
- });
718
- const Element = render || "div";
719
- const transformedProps = import_web.hooks.usePropsTransform?.(render, props, stateRef, false);
720
- (0, import_web.useIsomorphicLayoutEffect)(() => {
721
- if (!animatedStyle) return;
722
- const node = hostRef.current;
723
- if (node instanceof HTMLElement && seededNode.current !== node) {
724
- const currentStyle = animatedStyle.motionValues ? animatedStyle.getStyle(...animatedStyle.motionValues.map(value => value.get())) : animatedStyle.motionValue ? animatedStyle.getStyle(animatedStyle.motionValue.get()) : null;
725
- const webStyle = currentStyle && getProps({
726
- style: currentStyle
727
- }).style;
728
- if (webStyle) {
729
- Object.assign(node.style, webStyle);
730
- seededNode.current = node;
731
- seededInCurrentFrame.current = true;
732
- requestAnimationFrame(() => {
733
- if (seededNode.current === node) {
734
- seededInCurrentFrame.current = false;
735
- }
736
- });
737
- }
738
- }
739
- const toTransition = animationConfig => animationConfig?.type === "timing" ? {
740
- type: "tween",
741
- duration: (animationConfig?.duration || 0) / 1e3
742
- } : animationConfig?.type === "direct" ? {
743
- type: "tween",
744
- duration: 0
745
- } : {
746
- type: "spring",
747
- ...animationConfig
748
- };
749
- const animateNodeTo = (nextStyle, transition, mv) => {
750
- if (!(node instanceof HTMLElement) || hostRef.current !== node) return;
751
- const webStyle = getProps({
752
- style: nextStyle
753
- }).style;
754
- if (!webStyle) return;
755
- settlePendingMotionOnFinish(mv, animate(node, webStyle, transition));
756
- };
757
- const animateChangedValue = (nextStyle, transition, mv) => {
758
- if (seededInCurrentFrame.current && seededNode.current === node) {
759
- const queuedFrame = queuedAnimationFrames.current.get(mv);
760
- if (queuedFrame !== void 0) {
761
- cancelAnimationFrame(queuedFrame);
762
- }
763
- const frame = requestAnimationFrame(() => {
764
- if (queuedAnimationFrames.current.get(mv) !== frame) return;
765
- queuedAnimationFrames.current.delete(mv);
766
- if (hostRef.current === node) {
767
- animateNodeTo(nextStyle, transition, mv);
768
- } else {
769
- const onFinish = PendingMotionOnFinish.get(mv);
770
- PendingMotionOnFinish.delete(mv);
771
- onFinish?.();
772
- }
773
- });
774
- queuedAnimationFrames.current.set(mv, frame);
775
- return;
776
- }
777
- animateNodeTo(nextStyle, transition, mv);
778
- };
779
- if (animatedStyle.motionValues) {
780
- const mvs = animatedStyle.motionValues;
781
- const styleForAll = () => animatedStyle.getStyle(...mvs.map(v => v.get()));
782
- const unsubs = mvs.map(mv => mv.on("change", () => animateChangedValue(styleForAll(), toTransition(MotionValueStrategy.get(mv)), mv)));
783
- return () => unsubs.forEach(fn => fn());
784
- }
785
- const motionValue2 = animatedStyle.motionValue;
786
- if (!motionValue2) return;
787
- return motionValue2.on("change", value => animateChangedValue(animatedStyle.getStyle(value), toTransition(MotionValueStrategy.get(motionValue2)), motionValue2));
788
- }, [animatedStyle]);
789
- return /* @__PURE__ */(0, import_jsx_runtime.jsx)(Element, {
790
- ...transformedProps,
791
- ref: composedRefs
792
- });
793
- });
794
- Component["acceptRenderProp"] = true;
795
- return Component;
769
+ const isText = defaultTag === "span";
770
+ const Component = (0, import_web.createRefComponent)((propsIn, ref) => {
771
+ const { forwardedRef, animation, render = defaultTag, style, ...propsRest } = propsIn;
772
+ const [scope, animate] = useAnimateSSRSafe();
773
+ const hostRef = (0, import_react2.useRef)(null);
774
+ const seededNode = (0, import_react2.useRef)(null);
775
+ const seededInCurrentFrame = (0, import_react2.useRef)(false);
776
+ const queuedAnimationFrames = (0, import_react2.useRef)(/* @__PURE__ */ new WeakMap());
777
+ const composedRefs = (0, import_web.useComposedRefs)(forwardedRef, ref, hostRef, scope);
778
+ const stateRef = (0, import_react2.useRef)(null);
779
+ if (!stateRef.current) {
780
+ stateRef.current = { get host() {
781
+ return hostRef.current;
782
+ } };
783
+ }
784
+ const [_, state] = (0, import_web.useThemeWithState)({});
785
+ const styles = Array.isArray(style) ? style : [style];
786
+ const [animatedStyle, nonAnimatedStyles] = (() => {
787
+ let animatedStyle2;
788
+ const nonAnimatedStyles2 = [];
789
+ for (const style2 of styles) {
790
+ if (style2.getStyle) {
791
+ animatedStyle2 = style2;
792
+ } else {
793
+ nonAnimatedStyles2.push(style2);
794
+ }
795
+ }
796
+ return [animatedStyle2, nonAnimatedStyles2];
797
+ })();
798
+ function getProps(props2) {
799
+ if (process.env.NODE_ENV === "development" && propsIn.debug === "profile" && typeof performance !== "undefined") {
800
+ performance.mark("tamagui-motion-style-split");
801
+ }
802
+ const out = (0, import_web.getSplitStyles)(props2, isText ? import_web.Text.staticConfig : import_web.View.staticConfig, state?.theme, state?.name, { unmounted: false }, {
803
+ isAnimated: false,
804
+ noClass: true,
805
+ resolveValues: "auto"
806
+ });
807
+ if (!out) {
808
+ return {};
809
+ }
810
+ if (out.viewProps.style) {
811
+ (0, import_web.fixStyles)(out.viewProps.style);
812
+ (0, import_web.styleToCSS)(out.viewProps.style);
813
+ }
814
+ return out.viewProps;
815
+ }
816
+ const resolvedAnimatedStyle = (0, import_react2.useMemo)(() => {
817
+ if (!animatedStyle) return null;
818
+ const currentValues = animatedStyle.motionValues ? animatedStyle.motionValues.map((value) => value.get()) : animatedStyle.motionValue ? [animatedStyle.motionValue.get()] : [];
819
+ const initialSource = animatedStyle.getStyle(...currentValues);
820
+ const initialResolved = asStyleRecord(getProps({ style: initialSource }).style);
821
+ return {
822
+ initial: initialResolved,
823
+ resolve: compileAnimatedStyle(initialSource, initialResolved)
824
+ };
825
+ }, [
826
+ animatedStyle,
827
+ state?.theme,
828
+ state?.name
829
+ ]);
830
+ const memoRef = (0, import_react2.useRef)(null);
831
+ let props;
832
+ const cached = memoRef.current;
833
+ if (cached && cached.theme === state?.theme && cached.themeName === state?.name && motionStylesEqual(cached.styles, nonAnimatedStyles) && motionPropsEqual(cached.propsRest, propsRest)) {
834
+ props = { ...cached.result };
835
+ for (const key in propsRest) {
836
+ const val = propsRest[key];
837
+ if (key === "children" || typeof val === "function") {
838
+ props[key] = val;
839
+ }
840
+ }
841
+ } else {
842
+ props = getProps({
843
+ ...propsRest,
844
+ style: nonAnimatedStyles
845
+ });
846
+ memoRef.current = {
847
+ propsRest,
848
+ styles: nonAnimatedStyles,
849
+ theme: state?.theme,
850
+ themeName: state?.name,
851
+ result: props
852
+ };
853
+ }
854
+ if (resolvedAnimatedStyle) {
855
+ props = {
856
+ ...props,
857
+ style: {
858
+ ...asStyleRecord(props.style),
859
+ ...resolvedAnimatedStyle.initial
860
+ }
861
+ };
862
+ }
863
+ const Element = render || "div";
864
+ const transformedProps = import_web.hooks.usePropsTransform?.(render, props, stateRef, false);
865
+ (0, import_web.useIsomorphicLayoutEffect)(() => {
866
+ if (!animatedStyle) return;
867
+ const node = hostRef.current;
868
+ if (node instanceof HTMLElement && seededNode.current !== node) {
869
+ const currentStyle = animatedStyle.motionValues ? animatedStyle.getStyle(...animatedStyle.motionValues.map((value) => value.get())) : animatedStyle.motionValue ? animatedStyle.getStyle(animatedStyle.motionValue.get()) : null;
870
+ const webStyle = currentStyle && resolvedAnimatedStyle?.resolve(currentStyle);
871
+ if (webStyle) {
872
+ assignInlineStyles(node, webStyle);
873
+ seededNode.current = node;
874
+ seededInCurrentFrame.current = true;
875
+ requestAnimationFrame(() => {
876
+ if (seededNode.current === node) seededInCurrentFrame.current = false;
877
+ });
878
+ }
879
+ }
880
+ const toTransition = (animationConfig) => animationConfig?.type === "timing" ? {
881
+ type: "tween",
882
+ duration: (animationConfig.duration || 0) / 1e3
883
+ } : animationConfig?.type === "direct" ? {
884
+ type: "tween",
885
+ duration: 0
886
+ } : {
887
+ type: "spring",
888
+ ...animationConfig
889
+ };
890
+ const animateNodeTo = (nextStyle, transition, motionValue3) => {
891
+ if (!(node instanceof HTMLElement) || hostRef.current !== node) return;
892
+ const webStyle = resolvedAnimatedStyle?.resolve(nextStyle);
893
+ if (!webStyle) return;
894
+ settlePendingMotionOnFinish(motionValue3, animate(node, webStyle, transition));
895
+ };
896
+ const animateChangedValue = (nextStyle, transition, motionValue3) => {
897
+ if (seededInCurrentFrame.current && seededNode.current === node) {
898
+ const queuedFrame = queuedAnimationFrames.current.get(motionValue3);
899
+ if (queuedFrame !== void 0) cancelAnimationFrame(queuedFrame);
900
+ const frame = requestAnimationFrame(() => {
901
+ if (queuedAnimationFrames.current.get(motionValue3) !== frame) return;
902
+ queuedAnimationFrames.current.delete(motionValue3);
903
+ if (hostRef.current === node) {
904
+ animateNodeTo(nextStyle, transition, motionValue3);
905
+ } else {
906
+ const onFinish = PendingMotionOnFinish.get(motionValue3);
907
+ PendingMotionOnFinish.delete(motionValue3);
908
+ onFinish?.();
909
+ }
910
+ });
911
+ queuedAnimationFrames.current.set(motionValue3, frame);
912
+ return;
913
+ }
914
+ animateNodeTo(nextStyle, transition, motionValue3);
915
+ };
916
+ if (animatedStyle.motionValues) {
917
+ const mvs = animatedStyle.motionValues;
918
+ const styleForAll = () => animatedStyle.getStyle(...mvs.map((value) => value.get()));
919
+ const unsubs = mvs.map((mv) => mv.on("change", () => animateChangedValue(styleForAll(), toTransition(MotionValueStrategy.get(mv)), mv)));
920
+ return () => unsubs.forEach((fn) => fn());
921
+ }
922
+ const motionValue2 = animatedStyle.motionValue;
923
+ if (!motionValue2) return;
924
+ return motionValue2.on("change", (value) => animateChangedValue(animatedStyle.getStyle(value), toTransition(MotionValueStrategy.get(motionValue2)), motionValue2));
925
+ }, [animatedStyle, resolvedAnimatedStyle]);
926
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Element, {
927
+ ...transformedProps,
928
+ ref: composedRefs
929
+ });
930
+ });
931
+ Component["acceptRenderProp"] = true;
932
+ return Component;
796
933
  }
797
934
  function getDiff(previous, next) {
798
- if (!previous) {
799
- return next;
800
- }
801
- let diff = null;
802
- for (const key in next) {
803
- if (next[key] !== previous[key]) {
804
- diff ||= {};
805
- diff[key] = next[key];
806
- }
807
- }
808
- return diff;
935
+ if (!previous) {
936
+ return next;
937
+ }
938
+ let diff = null;
939
+ for (const key in next) {
940
+ if (next[key] !== previous[key]) {
941
+ diff ||= {};
942
+ diff[key] = next[key];
943
+ }
944
+ }
945
+ return diff;
809
946
  }
810
947
  function fixTransparentColors(diff, previous, next) {
811
- let result = diff;
812
- for (const key in diff) {
813
- if (diff[key] === "transparent") {
814
- let fixed = "rgba(0, 0, 0, 0)";
815
- const candidates = [previous?.[key], next?.[key]];
816
- for (const candidate of candidates) {
817
- if (typeof candidate === "string" && candidate !== "transparent") {
818
- const rgbaMatch = candidate.match(/^rgba?\(([^,]+),\s*([^,]+),\s*([^,)]+)/);
819
- if (rgbaMatch) {
820
- fixed = `rgba(${rgbaMatch[1]}, ${rgbaMatch[2]}, ${rgbaMatch[3]}, 0)`;
821
- break;
822
- }
823
- }
824
- }
825
- if (result === diff) {
826
- result = {
827
- ...diff
828
- };
829
- }
830
- result[key] = fixed;
831
- }
832
- }
833
- return result;
834
- }
948
+ let result = diff;
949
+ for (const key in diff) {
950
+ if (diff[key] === "transparent") {
951
+ let fixed = "rgba(0, 0, 0, 0)";
952
+ const candidates = [previous?.[key], next?.[key]];
953
+ for (const candidate of candidates) {
954
+ if (typeof candidate === "string" && candidate !== "transparent") {
955
+ const rgbaMatch = candidate.match(/^rgba?\(([^,]+),\s*([^,]+),\s*([^,)]+)/);
956
+ if (rgbaMatch) {
957
+ fixed = `rgba(${rgbaMatch[1]}, ${rgbaMatch[2]}, ${rgbaMatch[3]}, 0)`;
958
+ break;
959
+ }
960
+ }
961
+ }
962
+ if (result === diff) {
963
+ result = { ...diff };
964
+ }
965
+ result[key] = fixed;
966
+ }
967
+ }
968
+ return result;
969
+ }