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