@tamagui/animations-reanimated 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,923 +1,976 @@
1
1
  import { getEffectiveAnimation, normalizeTransition } from "@tamagui/animation-helpers";
2
- import { getSplitStyles, hooks, isWeb, Text, useComposedRefs, useEvent, useIsomorphicLayoutEffect, useThemeWithState, View } from "@tamagui/core";
2
+ import { Text, View, createRefComponent, getSplitStyles, hooks, isWeb, useComposedRefs, useEvent, useIsomorphicLayoutEffect, useThemeWithState } from "@tamagui/core";
3
3
  import { ResetPresence, usePresence } from "@tamagui/use-presence";
4
4
  import normalizeColor from "@react-native/normalize-colors";
5
- import React, { forwardRef, useMemo, useRef } from "react";
5
+ import React, { useMemo, useRef } from "react";
6
6
  import Animated_, { cancelAnimation, runOnJS, runOnUI, useAnimatedReaction, useAnimatedStyle, useDerivedValue, useSharedValue, withDelay, withSpring, withTiming } from "react-native-reanimated";
7
7
  import { jsx } from "react/jsx-runtime";
8
- const getDefaultExport = module => {
9
- const mod = module;
10
- if (mod.__esModule || mod[Symbol.toStringTag] === "Module") {
11
- return mod.default || mod;
12
- }
13
- return mod;
8
+
9
+ const getDefaultExport = (module) => {
10
+ const mod = module;
11
+ if (mod.__esModule || mod[Symbol.toStringTag] === "Module") {
12
+ return mod.default || mod;
13
+ }
14
+ return mod;
14
15
  };
15
16
  const Animated = getDefaultExport(Animated_);
16
- const silenceAnimatedComponentDevCheck = style => {
17
- if (process.env.NODE_ENV !== "development" || isWeb || !style || typeof style !== "object") {
18
- return;
19
- }
20
- Object.defineProperty(style, "_requiresAnimatedComponent", {
21
- configurable: true,
22
- enumerable: false,
23
- value: true
24
- });
17
+ const silenceAnimatedComponentDevCheck = (style) => {
18
+ if (process.env.NODE_ENV !== "development" || isWeb || !style || typeof style !== "object") {
19
+ return;
20
+ }
21
+ Object.defineProperty(style, "_requiresAnimatedComponent", {
22
+ configurable: true,
23
+ enumerable: false,
24
+ value: true
25
+ });
25
26
  };
26
27
  const resolveDynamicValue = (value, isDark) => {
27
- if (value !== null && typeof value === "object" && "dynamic" in value && typeof value.dynamic === "object") {
28
- const dynamic = value.dynamic;
29
- return isDark ? dynamic.dark : dynamic.light;
30
- }
31
- return value;
28
+ if (value !== null && typeof value === "object" && "dynamic" in value && typeof value.dynamic === "object") {
29
+ const dynamic = value.dynamic;
30
+ return isDark ? dynamic.dark : dynamic.light;
31
+ }
32
+ return value;
32
33
  };
33
34
  const updateMapperState = isWeb ? (state, emitted) => {
34
- state.value.emitted = emitted;
35
+ state.value.emitted = emitted;
35
36
  } : (state, emitted) => {
36
- "worklet";
37
-
38
- if (!globalThis._WORKLET) return;
39
- state.modify(current => {
40
- current.emitted = emitted;
41
- return current;
42
- }, false);
37
+ "worklet";
38
+ if (!globalThis._WORKLET) return;
39
+ state.modify((current) => {
40
+ current.emitted = emitted;
41
+ return current;
42
+ }, false);
43
43
  };
44
- const cloneAnimationValue = value => {
45
- if (Array.isArray(value)) {
46
- return value.map(cloneAnimationValue);
47
- }
48
- if (value && typeof value === "object") {
49
- const next = {};
50
- for (const key in value) {
51
- next[key] = cloneAnimationValue(value[key]);
52
- }
53
- return next;
54
- }
55
- return value;
44
+ const cloneAnimationValue = (value) => {
45
+ if (Array.isArray(value)) {
46
+ return value.map(cloneAnimationValue);
47
+ }
48
+ if (value && typeof value === "object") {
49
+ const next = {};
50
+ for (const key in value) {
51
+ next[key] = cloneAnimationValue(value[key]);
52
+ }
53
+ return next;
54
+ }
55
+ return value;
56
56
  };
57
- const cloneStyleRecord = style => {
58
- const next = {};
59
- for (const key in style) {
60
- next[key] = cloneAnimationValue(style[key]);
61
- }
62
- return next;
57
+ const cloneStyleRecord = (style) => {
58
+ const next = {};
59
+ for (const key in style) {
60
+ next[key] = cloneAnimationValue(style[key]);
61
+ }
62
+ return next;
63
63
  };
64
- const cloneTransitionConfig = config => {
65
- return cloneAnimationValue(config);
64
+ const cloneTransitionConfig = (config) => {
65
+ return cloneAnimationValue(config);
66
66
  };
67
- const getAnimatedTransforms = value => {
68
- if (!Array.isArray(value)) return [];
69
- return value.filter(item => item !== null && typeof item === "object" && !Array.isArray(item));
67
+ const getAnimatedTransforms = (value) => {
68
+ if (!Array.isArray(value)) return [];
69
+ return value.filter((item) => item !== null && typeof item === "object" && !Array.isArray(item));
70
70
  };
71
71
  const getRemovedAnimatedKeys = (current, previous) => {
72
- const removedKeys = {};
73
- for (const key of previous) {
74
- if (!current.has(key)) removedKeys[key] = true;
75
- }
76
- return removedKeys;
72
+ const removedKeys = {};
73
+ for (const key of previous) {
74
+ if (!current.has(key)) removedKeys[key] = true;
75
+ }
76
+ return removedKeys;
77
77
  };
78
78
  const getImplicitDefault = (key, targetValue) => {
79
- "worklet";
80
-
81
- const value = key === "opacity" || key === "scale" || key === "scaleX" || key === "scaleY" ? 1 : 0;
82
- if (typeof targetValue !== "string") return value;
83
- let suffixIndex = 0;
84
- while (suffixIndex < targetValue.length) {
85
- const character = targetValue[suffixIndex];
86
- const code = character.charCodeAt(0);
87
- if (code >= 48 && code <= 57 || character === "." || character === "-" || character === "+") {
88
- suffixIndex++;
89
- } else {
90
- break;
91
- }
92
- }
93
- return suffixIndex > 0 ? `${value}${targetValue.slice(suffixIndex)}` : value;
79
+ "worklet";
80
+ const value = key === "opacity" || key === "scale" || key === "scaleX" || key === "scaleY" ? 1 : 0;
81
+ if (typeof targetValue !== "string") return value;
82
+ let suffixIndex = 0;
83
+ while (suffixIndex < targetValue.length) {
84
+ const character = targetValue[suffixIndex];
85
+ const code = character.charCodeAt(0);
86
+ if (code >= 48 && code <= 57 || character === "." || character === "-" || character === "+") {
87
+ suffixIndex++;
88
+ } else {
89
+ break;
90
+ }
91
+ }
92
+ return suffixIndex > 0 ? `${value}${targetValue.slice(suffixIndex)}` : value;
94
93
  };
95
94
  const COLOR_STYLE_KEYS = {
96
- backgroundColor: true,
97
- borderColor: true,
98
- borderLeftColor: true,
99
- borderRightColor: true,
100
- borderTopColor: true,
101
- borderBottomColor: true,
102
- color: true
95
+ backgroundColor: true,
96
+ borderColor: true,
97
+ borderLeftColor: true,
98
+ borderRightColor: true,
99
+ borderTopColor: true,
100
+ borderBottomColor: true,
101
+ color: true
103
102
  };
104
- const toReanimatedColor = value => {
105
- "worklet";
106
-
107
- if (typeof value === "number") {
108
- const color = value >>> 0;
109
- const alpha = (color >>> 24 & 255) / 255;
110
- const red = color >>> 16 & 255;
111
- const green = color >>> 8 & 255;
112
- const blue = color & 255;
113
- return `rgba(${red}, ${green}, ${blue}, ${alpha})`;
114
- }
115
- if (typeof value !== "string") return value;
116
- const trimmed = value.trim();
117
- if (trimmed === "transparent") return "rgba(0, 0, 0, 0)";
118
- return trimmed;
103
+ const toReanimatedColor = (value) => {
104
+ "worklet";
105
+ if (typeof value === "number") {
106
+ const color = value >>> 0;
107
+ const alpha = (color >>> 24 & 255) / 255;
108
+ const red = color >>> 16 & 255;
109
+ const green = color >>> 8 & 255;
110
+ const blue = color & 255;
111
+ return `rgba(${red}, ${green}, ${blue}, ${alpha})`;
112
+ }
113
+ if (typeof value !== "string") return value;
114
+ const trimmed = value.trim();
115
+ if (trimmed === "transparent") return "rgba(0, 0, 0, 0)";
116
+ return trimmed;
119
117
  };
120
- const isReanimatedColorHistory = value => {
121
- "worklet";
122
-
123
- const normalized = toReanimatedColor(value);
124
- return typeof normalized === "string" && normalized.startsWith("rgba(");
118
+ const isReanimatedColorHistory = (value) => {
119
+ "worklet";
120
+ const normalized = toReanimatedColor(value);
121
+ return typeof normalized === "string" && normalized.startsWith("rgba(");
125
122
  };
126
- const normalizeAnimationColor = value => {
127
- if (typeof value === "number") {
128
- return toReanimatedColor(value);
129
- }
130
- if (typeof value !== "string") return;
131
- const color = normalizeColor(value);
132
- if (color == null) return;
133
- const red = Math.round((color & 4278190080) >>> 24);
134
- const green = Math.round((color & 16711680) >>> 16);
135
- const blue = Math.round((color & 65280) >>> 8);
136
- const alpha = (color & 255) / 255;
137
- return `rgba(${red}, ${green}, ${blue}, ${alpha})`;
123
+ const normalizeAnimationColor = (value) => {
124
+ if (typeof value === "number") {
125
+ return toReanimatedColor(value);
126
+ }
127
+ if (typeof value !== "string") return;
128
+ const color = normalizeColor(value);
129
+ if (color == null) return;
130
+ const red = Math.round((color & 4278190080) >>> 24);
131
+ const green = Math.round((color & 16711680) >>> 16);
132
+ const blue = Math.round((color & 65280) >>> 8);
133
+ const alpha = (color & 255) / 255;
134
+ return `rgba(${red}, ${green}, ${blue}, ${alpha})`;
138
135
  };
139
136
  const buildSnapshot = (animated, statics, transforms, previousKeys, lastPainted) => {
140
- const snapshotAnimated = {};
141
- const snapshotStatics = cloneStyleRecord(statics);
142
- for (const key in snapshotStatics) {
143
- if (!COLOR_STYLE_KEYS[key]) continue;
144
- const normalized = normalizeAnimationColor(snapshotStatics[key]);
145
- if (normalized !== void 0) snapshotStatics[key] = normalized;
146
- }
147
- for (const key in animated) {
148
- if (key === "transform") continue;
149
- const value = animated[key];
150
- if (COLOR_STYLE_KEYS[key]) {
151
- const normalized = normalizeAnimationColor(value);
152
- if (normalized === void 0) {
153
- snapshotStatics[key] = cloneAnimationValue(value);
154
- continue;
155
- }
156
- snapshotAnimated[key] = normalized;
157
- } else {
158
- snapshotAnimated[key] = cloneAnimationValue(value);
159
- }
160
- }
161
- const snapshotTransforms = transforms.map(cloneStyleRecord);
162
- const keys = new Set(Object.keys(snapshotAnimated));
163
- for (const transform of snapshotTransforms) {
164
- const key = Object.keys(transform)[0];
165
- const value = key ? transform[key] : void 0;
166
- if (key && (typeof value === "number" || typeof value === "string")) {
167
- keys.add(`transform:${key}`);
168
- }
169
- }
170
- const seeds = {};
171
- for (const key of keys) {
172
- let value = lastPainted[key];
173
- if (typeof value !== "number" && typeof value !== "string") continue;
174
- if (value === "auto" || typeof value === "string" && value.startsWith("calc")) {
175
- continue;
176
- }
177
- if (COLOR_STYLE_KEYS[key]) value = normalizeAnimationColor(value);
178
- if (value !== void 0) seeds[key] = value;
179
- }
180
- const gatedKeys = {};
181
- for (const key of keys) gatedKeys[key] = true;
182
- const removedKeys = getRemovedAnimatedKeys(keys, previousKeys);
183
- const painted = {
184
- ...snapshotStatics,
185
- ...snapshotAnimated
186
- };
187
- const staticTransforms = getAnimatedTransforms(snapshotStatics.transform);
188
- delete painted.transform;
189
- for (const transform of staticTransforms) {
190
- const key = Object.keys(transform)[0];
191
- if (key) painted[`transform:${key}`] = transform[key];
192
- }
193
- for (const transform of snapshotTransforms) {
194
- const key = Object.keys(transform)[0];
195
- if (key) painted[`transform:${key}`] = transform[key];
196
- }
197
- return {
198
- value: {
199
- animated: snapshotAnimated,
200
- statics: snapshotStatics,
201
- transforms: snapshotTransforms,
202
- gatedKeys,
203
- seeds,
204
- removedKeys,
205
- removeTransform: Object.keys(removedKeys).some(key => key.startsWith("transform:")),
206
- clearValue: isWeb ? "" : null
207
- },
208
- painted,
209
- keys
210
- };
137
+ const snapshotAnimated = {};
138
+ const snapshotStatics = cloneStyleRecord(statics);
139
+ for (const key in snapshotStatics) {
140
+ if (!COLOR_STYLE_KEYS[key]) continue;
141
+ const normalized = normalizeAnimationColor(snapshotStatics[key]);
142
+ if (normalized !== void 0) snapshotStatics[key] = normalized;
143
+ }
144
+ for (const key in animated) {
145
+ if (key === "transform") continue;
146
+ const value = animated[key];
147
+ if (COLOR_STYLE_KEYS[key]) {
148
+ const normalized = normalizeAnimationColor(value);
149
+ if (normalized === void 0) {
150
+ snapshotStatics[key] = cloneAnimationValue(value);
151
+ continue;
152
+ }
153
+ snapshotAnimated[key] = normalized;
154
+ } else {
155
+ snapshotAnimated[key] = cloneAnimationValue(value);
156
+ }
157
+ }
158
+ const snapshotTransforms = transforms.map(cloneStyleRecord);
159
+ const keys = new Set(Object.keys(snapshotAnimated));
160
+ for (const transform of snapshotTransforms) {
161
+ const key = Object.keys(transform)[0];
162
+ const value = key ? transform[key] : void 0;
163
+ if (key && (typeof value === "number" || typeof value === "string")) {
164
+ keys.add(`transform:${key}`);
165
+ }
166
+ }
167
+ const seeds = {};
168
+ for (const key of keys) {
169
+ let value = lastPainted[key];
170
+ if (typeof value !== "number" && typeof value !== "string") continue;
171
+ if (value === "auto" || typeof value === "string" && value.startsWith("calc")) {
172
+ continue;
173
+ }
174
+ if (COLOR_STYLE_KEYS[key]) value = normalizeAnimationColor(value);
175
+ if (value !== void 0) seeds[key] = value;
176
+ }
177
+ const gatedKeys = {};
178
+ for (const key of keys) gatedKeys[key] = true;
179
+ const removedKeys = getRemovedAnimatedKeys(keys, previousKeys);
180
+ const painted = {
181
+ ...snapshotStatics,
182
+ ...snapshotAnimated
183
+ };
184
+ const staticTransforms = getAnimatedTransforms(snapshotStatics.transform);
185
+ delete painted.transform;
186
+ for (const transform of staticTransforms) {
187
+ const key = Object.keys(transform)[0];
188
+ if (key) painted[`transform:${key}`] = transform[key];
189
+ }
190
+ for (const transform of snapshotTransforms) {
191
+ const key = Object.keys(transform)[0];
192
+ if (key) painted[`transform:${key}`] = transform[key];
193
+ }
194
+ return {
195
+ value: {
196
+ animated: snapshotAnimated,
197
+ statics: snapshotStatics,
198
+ transforms: snapshotTransforms,
199
+ gatedKeys,
200
+ seeds,
201
+ removedKeys,
202
+ removeTransform: Object.keys(removedKeys).some((key) => key.startsWith("transform:")),
203
+ clearValue: isWeb ? "" : null
204
+ },
205
+ painted,
206
+ keys
207
+ };
211
208
  };
212
- const getGatedKeys = snapshot => Object.keys(snapshot.gatedKeys);
213
- const createReanimatedConfig = config => {
214
- "worklet";
215
-
216
- const next = {};
217
- const source = config;
218
- for (const key in source) {
219
- if (key === "type" || key === "delay") continue;
220
- const value = source[key];
221
- if (value !== void 0) {
222
- next[key] = value;
223
- }
224
- }
225
- return next;
209
+ const getGatedKeys = (snapshot) => Object.keys(snapshot.gatedKeys);
210
+ const createReanimatedConfig = (config) => {
211
+ "worklet";
212
+ const next = {};
213
+ const source = config;
214
+ for (const key in source) {
215
+ if (key === "type" || key === "delay") continue;
216
+ const value = source[key];
217
+ if (value !== void 0) {
218
+ next[key] = value;
219
+ }
220
+ }
221
+ return next;
226
222
  };
227
223
  const applyAnimation = (targetValue, config, callback, seedValue, validateStartAsColor = false) => {
228
- "worklet";
229
-
230
- const delay = config.delay;
231
- const reanimatedConfig = createReanimatedConfig(config);
232
- let animatedValue;
233
- if (config.type === "timing") {
234
- animatedValue = withTiming(targetValue, reanimatedConfig, callback);
235
- } else {
236
- animatedValue = withSpring(targetValue, reanimatedConfig, callback);
237
- }
238
- if (seedValue !== void 0 || validateStartAsColor) {
239
- const innerOnStart = animatedValue.onStart;
240
- animatedValue.onStart = (animation, value, timestamp, previousAnimation) => {
241
- "worklet";
242
-
243
- const startValue = validateStartAsColor ? isReanimatedColorHistory(value) ? toReanimatedColor(value) : seedValue ?? targetValue : seedValue;
244
- innerOnStart(animation, startValue, timestamp, previousAnimation);
245
- };
246
- }
247
- if (delay && delay > 0) {
248
- animatedValue = withDelay(delay, animatedValue);
249
- }
250
- return animatedValue;
224
+ "worklet";
225
+ const delay = config.delay;
226
+ const reanimatedConfig = createReanimatedConfig(config);
227
+ let animatedValue;
228
+ if (config.type === "timing") {
229
+ animatedValue = withTiming(targetValue, reanimatedConfig, callback);
230
+ } else {
231
+ animatedValue = withSpring(targetValue, reanimatedConfig, callback);
232
+ const innerOnFrame = animatedValue.onFrame;
233
+ animatedValue.onFrame = (animation, now) => {
234
+ "worklet";
235
+ return innerOnFrame(animation, now < animation.lastTimestamp ? animation.lastTimestamp : now);
236
+ };
237
+ }
238
+ if (seedValue !== void 0 || validateStartAsColor) {
239
+ const innerOnStart = animatedValue.onStart;
240
+ animatedValue.onStart = (animation, value, timestamp, previousAnimation) => {
241
+ "worklet";
242
+ const startValue = validateStartAsColor ? isReanimatedColorHistory(value) ? toReanimatedColor(value) : seedValue ?? targetValue : seedValue;
243
+ innerOnStart(animation, startValue, timestamp, previousAnimation);
244
+ };
245
+ }
246
+ if (delay && delay > 0) {
247
+ animatedValue = withDelay(delay, animatedValue);
248
+ }
249
+ return animatedValue;
251
250
  };
252
- const animateSnapshotValue = (key, implicitKey, targetValue, config, previouslyEmitted, seedValue, gated, currentlyExiting, exitCycleId, currentlyCompletingAnimation, didAnimateCycleId, markExitKeyDone, markDidAnimateKeyDone, validateStartAsColor = false) => {
253
- "worklet";
254
-
255
- const cycleGated = gated && (currentlyExiting || currentlyCompletingAnimation);
256
- if (!previouslyEmitted && seedValue === void 0 && !cycleGated) {
257
- return targetValue;
258
- }
259
- let callback;
260
- if (gated && currentlyExiting) {
261
- callback = finished => {
262
- "worklet";
263
-
264
- runOnJS(markExitKeyDone)(key, exitCycleId, finished ?? false);
265
- };
266
- } else if (gated && currentlyCompletingAnimation) {
267
- callback = finished => {
268
- "worklet";
269
-
270
- runOnJS(markDidAnimateKeyDone)(key, didAnimateCycleId, finished ?? false);
271
- };
272
- }
273
- return applyAnimation(targetValue, config, callback, previouslyEmitted ? void 0 : seedValue ?? getImplicitDefault(implicitKey, targetValue), validateStartAsColor);
251
+ const animateSnapshotValue = (key, implicitKey, targetValue, config, previouslyEmitted, seedValue, gated, currentlyExiting, exitCycleId, currentlyCompletingEnter, enterCycleId, currentlyCompletingUpdate, updateCycleId, markExitKeyDone, markEnterKeyDone, markUpdateKeyDone, validateStartAsColor = false) => {
252
+ "worklet";
253
+ const cycleGated = gated && (currentlyExiting || currentlyCompletingEnter || currentlyCompletingUpdate);
254
+ if (!previouslyEmitted && seedValue === void 0 && !cycleGated) {
255
+ return targetValue;
256
+ }
257
+ let callback;
258
+ if (gated && currentlyExiting) {
259
+ callback = (finished) => {
260
+ "worklet";
261
+ runOnJS(markExitKeyDone)(key, exitCycleId, finished ?? false);
262
+ };
263
+ } else if (gated && currentlyCompletingEnter) {
264
+ callback = () => {
265
+ "worklet";
266
+ runOnJS(markEnterKeyDone)(key, enterCycleId);
267
+ };
268
+ } else if (gated && currentlyCompletingUpdate) {
269
+ callback = (finished) => {
270
+ "worklet";
271
+ runOnJS(markUpdateKeyDone)(key, updateCycleId, finished ?? false);
272
+ };
273
+ }
274
+ return applyAnimation(targetValue, config, callback, previouslyEmitted ? void 0 : seedValue ?? getImplicitDefault(implicitKey, targetValue), validateStartAsColor);
274
275
  };
275
276
  const ANIMATABLE_PROPERTIES = {
276
- // Transform
277
- transform: true,
278
- // Opacity
279
- opacity: true,
280
- // Dimensions
281
- height: true,
282
- width: true,
283
- minWidth: true,
284
- minHeight: true,
285
- maxWidth: true,
286
- maxHeight: true,
287
- // Background
288
- backgroundColor: true,
289
- // Border colors
290
- borderColor: true,
291
- borderLeftColor: true,
292
- borderRightColor: true,
293
- borderTopColor: true,
294
- borderBottomColor: true,
295
- // Border radius
296
- borderRadius: true,
297
- borderTopLeftRadius: true,
298
- borderTopRightRadius: true,
299
- borderBottomLeftRadius: true,
300
- borderBottomRightRadius: true,
301
- // Border width
302
- borderWidth: true,
303
- borderLeftWidth: true,
304
- borderRightWidth: true,
305
- borderTopWidth: true,
306
- borderBottomWidth: true,
307
- // Text
308
- color: true,
309
- fontSize: true,
310
- fontWeight: true,
311
- lineHeight: true,
312
- letterSpacing: true,
313
- // Position
314
- left: true,
315
- right: true,
316
- top: true,
317
- bottom: true,
318
- // Margin
319
- margin: true,
320
- marginTop: true,
321
- marginBottom: true,
322
- marginLeft: true,
323
- marginRight: true,
324
- marginHorizontal: true,
325
- marginVertical: true,
326
- // Padding
327
- padding: true,
328
- paddingTop: true,
329
- paddingBottom: true,
330
- paddingLeft: true,
331
- paddingRight: true,
332
- paddingHorizontal: true,
333
- paddingVertical: true,
334
- // Flex/Gap
335
- gap: true,
336
- rowGap: true,
337
- columnGap: true,
338
- flex: true,
339
- flexGrow: true,
340
- flexShrink: true
277
+ transform: true,
278
+ opacity: true,
279
+ height: true,
280
+ width: true,
281
+ minWidth: true,
282
+ minHeight: true,
283
+ maxWidth: true,
284
+ maxHeight: true,
285
+ backgroundColor: true,
286
+ borderColor: true,
287
+ borderLeftColor: true,
288
+ borderRightColor: true,
289
+ borderTopColor: true,
290
+ borderBottomColor: true,
291
+ borderRadius: true,
292
+ borderTopLeftRadius: true,
293
+ borderTopRightRadius: true,
294
+ borderBottomLeftRadius: true,
295
+ borderBottomRightRadius: true,
296
+ borderWidth: true,
297
+ borderLeftWidth: true,
298
+ borderRightWidth: true,
299
+ borderTopWidth: true,
300
+ borderBottomWidth: true,
301
+ color: true,
302
+ fontSize: true,
303
+ fontWeight: true,
304
+ lineHeight: true,
305
+ letterSpacing: true,
306
+ left: true,
307
+ right: true,
308
+ top: true,
309
+ bottom: true,
310
+ margin: true,
311
+ marginTop: true,
312
+ marginBottom: true,
313
+ marginLeft: true,
314
+ marginRight: true,
315
+ marginHorizontal: true,
316
+ marginVertical: true,
317
+ padding: true,
318
+ paddingTop: true,
319
+ paddingBottom: true,
320
+ paddingLeft: true,
321
+ paddingRight: true,
322
+ paddingHorizontal: true,
323
+ paddingVertical: true,
324
+ gap: true,
325
+ rowGap: true,
326
+ columnGap: true,
327
+ flex: true,
328
+ flexGrow: true,
329
+ flexShrink: true
341
330
  };
342
331
  const canAnimateProperty = (key, value, animateOnly) => {
343
- if (!ANIMATABLE_PROPERTIES[key]) return false;
344
- if (value === "auto") return false;
345
- if (typeof value === "string" && value.startsWith("calc")) return false;
346
- if (animateOnly && !animateOnly.includes(key)) return false;
347
- return true;
332
+ if (!ANIMATABLE_PROPERTIES[key]) return false;
333
+ if (value === "auto") return false;
334
+ if (typeof value === "string" && value.startsWith("calc")) return false;
335
+ if (animateOnly && !animateOnly.includes(key)) return false;
336
+ return true;
348
337
  };
349
338
  const splitAnimationStyles = (style, isDark, disableAnimation, animateOnly) => {
350
- const animated = {};
351
- const statics = {};
352
- for (const key in style) {
353
- const value = resolveDynamicValue(style[key], isDark);
354
- if (value === void 0) continue;
355
- if (!disableAnimation && canAnimateProperty(key, value, animateOnly)) {
356
- animated[key] = cloneAnimationValue(value);
357
- } else {
358
- statics[key] = cloneAnimationValue(value);
359
- }
360
- }
361
- return {
362
- animated,
363
- statics
364
- };
339
+ const animated = {};
340
+ const statics = {};
341
+ for (const key in style) {
342
+ const value = resolveDynamicValue(style[key], isDark);
343
+ if (value === void 0) continue;
344
+ if (!disableAnimation && canAnimateProperty(key, value, animateOnly)) {
345
+ animated[key] = cloneAnimationValue(value);
346
+ } else {
347
+ statics[key] = cloneAnimationValue(value);
348
+ }
349
+ }
350
+ return {
351
+ animated,
352
+ statics
353
+ };
365
354
  };
366
355
  function createWebAnimatedComponent(defaultTag) {
367
- const isText = defaultTag === "span";
368
- const Component = Animated.createAnimatedComponent(forwardRef((propsIn, ref) => {
369
- const {
370
- forwardedRef,
371
- render = defaultTag,
372
- ...rest
373
- } = propsIn;
374
- const hostRef = useRef(null);
375
- const composedRefs = useComposedRefs(forwardedRef, ref, hostRef);
376
- const stateRef = useRef({
377
- get host() {
378
- return hostRef.current;
379
- }
380
- });
381
- const [, themeState] = useThemeWithState({});
382
- const result = getSplitStyles(rest, isText ? Text.staticConfig : View.staticConfig, themeState?.theme ?? {}, themeState?.name ?? "", {
383
- unmounted: false
384
- }, {
385
- isAnimated: false,
386
- noClass: true
387
- });
388
- const viewProps = result?.viewProps ?? {};
389
- const Element = render;
390
- const transformedProps = hooks.usePropsTransform?.(render, viewProps, stateRef, false);
391
- return /* @__PURE__ */jsx(Element, {
392
- ...transformedProps,
393
- ref: composedRefs
394
- });
395
- }));
396
- Component.acceptRenderProp = true;
397
- return Component;
356
+ const isText = defaultTag === "span";
357
+ const Component = Animated.createAnimatedComponent(createRefComponent((propsIn, ref) => {
358
+ const { forwardedRef, render = defaultTag, ...rest } = propsIn;
359
+ const hostRef = useRef(null);
360
+ const composedRefs = useComposedRefs(forwardedRef, ref, hostRef);
361
+ const stateRef = useRef({ get host() {
362
+ return hostRef.current;
363
+ } });
364
+ const [, themeState] = useThemeWithState({});
365
+ const result = getSplitStyles(rest, isText ? Text.staticConfig : View.staticConfig, themeState?.theme ?? {}, themeState?.name ?? "", { unmounted: false }, {
366
+ isAnimated: false,
367
+ noClass: true
368
+ });
369
+ const viewProps = result?.viewProps ?? {};
370
+ const Element = render;
371
+ const transformedProps = hooks.usePropsTransform?.(render, viewProps, stateRef, false);
372
+ const { nativeID, ...webProps } = transformedProps ?? viewProps;
373
+ return /* @__PURE__ */ jsx(Element, {
374
+ ...webProps,
375
+ ref: composedRefs
376
+ });
377
+ }));
378
+ Component.acceptRenderProp = true;
379
+ return Component;
398
380
  }
399
381
  const AnimatedView = createWebAnimatedComponent("div");
400
382
  const AnimatedText = createWebAnimatedComponent("span");
401
383
  function buildTransitionConfig(transition, animations, animationState, styleKeys) {
402
- const normalized = normalizeTransition(transition);
403
- const effectiveKey = getEffectiveAnimation(normalized, animationState);
404
- let base = cloneTransitionConfig(effectiveKey ? animations[effectiveKey] ?? {
405
- type: "spring"
406
- } : {
407
- type: "spring"
408
- });
409
- if (normalized.delay) {
410
- base = cloneTransitionConfig({
411
- ...base,
412
- delay: normalized.delay
413
- });
414
- }
415
- if (normalized.config) {
416
- base = cloneTransitionConfig({
417
- ...base,
418
- ...normalized.config
419
- });
420
- if (base.type !== "timing" && normalized.config.duration !== void 0 && normalized.config.damping === void 0 && normalized.config.stiffness === void 0 && normalized.config.mass === void 0) {
421
- base = cloneTransitionConfig({
422
- ...base,
423
- type: "timing"
424
- });
425
- }
426
- }
427
- const propertyConfigs = {};
428
- for (const key of styleKeys) {
429
- const propAnimation = normalized.properties[key];
430
- if (typeof propAnimation === "string") {
431
- propertyConfigs[key] = cloneTransitionConfig(animations[propAnimation] ?? base);
432
- } else if (propAnimation && typeof propAnimation === "object") {
433
- const configType = propAnimation.type;
434
- const baseForProp = configType ? animations[configType] ?? base : base;
435
- propertyConfigs[key] = cloneTransitionConfig({
436
- ...baseForProp,
437
- ...propAnimation
438
- });
439
- } else {
440
- propertyConfigs[key] = cloneTransitionConfig(base);
441
- }
442
- }
443
- return {
444
- baseConfig: base,
445
- propertyConfigs
446
- };
384
+ const normalized = normalizeTransition(transition);
385
+ const effectiveKey = getEffectiveAnimation(normalized, animationState);
386
+ let base = cloneTransitionConfig(effectiveKey ? animations[effectiveKey] ?? { type: "spring" } : { type: "spring" });
387
+ if (normalized.delay) {
388
+ base = cloneTransitionConfig({
389
+ ...base,
390
+ delay: normalized.delay
391
+ });
392
+ }
393
+ if (normalized.config) {
394
+ base = cloneTransitionConfig({
395
+ ...base,
396
+ ...normalized.config
397
+ });
398
+ if (base.type !== "timing" && normalized.config.duration !== void 0 && normalized.config.damping === void 0 && normalized.config.stiffness === void 0 && normalized.config.mass === void 0) {
399
+ base = cloneTransitionConfig({
400
+ ...base,
401
+ type: "timing"
402
+ });
403
+ }
404
+ }
405
+ const propertyConfigs = {};
406
+ for (const key of styleKeys) {
407
+ const propAnimation = normalized.properties[key];
408
+ if (typeof propAnimation === "string") {
409
+ propertyConfigs[key] = cloneTransitionConfig(animations[propAnimation] ?? base);
410
+ } else if (propAnimation && typeof propAnimation === "object") {
411
+ const configType = propAnimation.type;
412
+ const baseForProp = configType ? animations[configType] ?? base : base;
413
+ propertyConfigs[key] = cloneTransitionConfig({
414
+ ...baseForProp,
415
+ ...propAnimation
416
+ });
417
+ } else {
418
+ propertyConfigs[key] = cloneTransitionConfig(base);
419
+ }
420
+ }
421
+ return {
422
+ baseConfig: base,
423
+ propertyConfigs
424
+ };
447
425
  }
448
426
  function getStyleKeys(style) {
449
- const keys = new Set(Object.keys(style));
450
- if (style.transform && Array.isArray(style.transform)) {
451
- for (const t of style.transform) {
452
- if (t && typeof t === "object") {
453
- keys.add(Object.keys(t)[0]);
454
- }
455
- }
456
- }
457
- return keys;
427
+ const keys = new Set(Object.keys(style));
428
+ if (style.transform && Array.isArray(style.transform)) {
429
+ for (const t of style.transform) {
430
+ if (t && typeof t === "object") {
431
+ keys.add(Object.keys(t)[0]);
432
+ }
433
+ }
434
+ }
435
+ return keys;
458
436
  }
459
437
  function createAnimations(animationsConfig) {
460
- const animations = {};
461
- for (const key in animationsConfig) {
462
- animations[key] = cloneTransitionConfig({
463
- type: "spring",
464
- ...animationsConfig[key]
465
- });
466
- }
467
- return {
468
- needsCustomComponent: true,
469
- View: isWeb ? AnimatedView : Animated.View,
470
- Text: isWeb ? AnimatedText : Animated.Text,
471
- isReactNative: true,
472
- inputStyle: "value",
473
- outputStyle: "inline",
474
- avoidReRenders: true,
475
- animations,
476
- usePresence,
477
- ResetPresence,
478
- // =========================================================================
479
- // useAnimatedNumber - For imperative animated values
480
- // =========================================================================
481
- useAnimatedNumber(initial) {
482
- const sharedValue = useSharedValue(initial);
483
- return useMemo(() => ({
484
- getInstance() {
485
- "worklet";
486
-
487
- return sharedValue;
488
- },
489
- getValue() {
490
- "worklet";
491
-
492
- return sharedValue.value;
493
- },
494
- setValue(next, config = {
495
- type: "spring"
496
- }, onFinish) {
497
- if (config.type === "direct") {
498
- sharedValue.value = next;
499
- onFinish?.();
500
- } else {
501
- const cb = onFinish ? finished => {
502
- "worklet";
503
-
504
- if (finished !== false) {
505
- runOnJS(onFinish)();
506
- }
507
- } : void 0;
508
- const animationConfig = cloneTransitionConfig(config);
509
- if (isWeb) {
510
- sharedValue.value = applyAnimation(next, animationConfig, cb);
511
- } else {
512
- runOnUI((targetValue, animationConfig2) => {
513
- "worklet";
514
-
515
- sharedValue.value = applyAnimation(targetValue, animationConfig2, cb);
516
- })(next, animationConfig);
517
- }
518
- }
519
- },
520
- stop() {
521
- cancelAnimation(sharedValue);
522
- }
523
- }), [sharedValue]);
524
- },
525
- // =========================================================================
526
- // useAnimatedNumberReaction - React to animated value changes
527
- // =========================================================================
528
- useAnimatedNumberReaction({
529
- value
530
- }, onValue) {
531
- const instance = value.getInstance();
532
- return useAnimatedReaction(() => instance.value, (next, prev) => {
533
- if (prev !== next) {
534
- runOnJS(onValue)(next);
535
- }
536
- }, [onValue, instance]);
537
- },
538
- // =========================================================================
539
- // useAnimatedNumberStyle - Create animated styles from values
540
- // =========================================================================
541
- useAnimatedNumberStyle(val, getStyle) {
542
- const instance = val.getInstance();
543
- if (isWeb) {
544
- return useAnimatedStyle(() => {
545
- "worklet";
546
-
547
- return getStyle(instance.value);
548
- }, [instance, getStyle]);
549
- }
550
- const styleVal = useDerivedValue(() => {
551
- "worklet";
552
-
553
- return getStyle(instance.value);
554
- });
555
- const animatedStyle = useAnimatedStyle(() => {
556
- "worklet";
557
-
558
- return styleVal.value;
559
- });
560
- silenceAnimatedComponentDevCheck(animatedStyle);
561
- return animatedStyle;
562
- },
563
- useAnimatedNumbersStyle(vals, getStyle) {
564
- const instances = vals.map(v => v.getInstance());
565
- const animatedStyle = useAnimatedStyle(() => {
566
- "worklet";
567
-
568
- const currentValues = instances.map(inst => inst.value);
569
- return getStyle(...currentValues);
570
- }, isWeb ? [getStyle, ...instances] : void 0);
571
- silenceAnimatedComponentDevCheck(animatedStyle);
572
- return animatedStyle;
573
- },
574
- // =========================================================================
575
- // useAnimations - Main animation hook for components
576
- // =========================================================================
577
- useAnimations(animationProps) {
578
- const {
579
- props,
580
- presence,
581
- style,
582
- componentState,
583
- useStyleEmitter,
584
- themeName,
585
- stateRef,
586
- styleState,
587
- onDidAnimate
588
- } = animationProps;
589
- const isHydrating = componentState.unmounted === true;
590
- const isMounting = componentState.unmounted === "should-enter";
591
- const isEntering = !!componentState.unmounted;
592
- const isExiting = presence?.[0] === false;
593
- const wasEnteringRef = useRef(isEntering);
594
- const justFinishedEntering = wasEnteringRef.current && !isEntering;
595
- React.useEffect(() => {
596
- wasEnteringRef.current = isEntering;
597
- });
598
- const effectiveTransition = styleState?.effectiveTransition ?? props.transition;
599
- const normalized = normalizeTransition(effectiveTransition);
600
- const animationState = isExiting ? "exit" : isMounting || justFinishedEntering ? "enter" : "default";
601
- const animationKey = getEffectiveAnimation(normalized, animationState);
602
- const disableAnimation = isHydrating || !animationKey;
603
- const isDark = themeName?.startsWith("dark") || false;
604
- const sendExitComplete = presence?.[1];
605
- const onDidAnimateRef = useRef(onDidAnimate);
606
- useIsomorphicLayoutEffect(() => {
607
- onDidAnimateRef.current = onDidAnimate;
608
- }, [onDidAnimate]);
609
- const didAnimateCycleIdRef = useRef(0);
610
- const pendingDidAnimateKeysRef = useRef(/* @__PURE__ */new Set());
611
- const didAnimateCompletedRef = useRef(false);
612
- const isCompletingAnimationRef = useSharedValue(false);
613
- const didAnimateCycleIdShared = useSharedValue(0);
614
- const markDidAnimateKeyDone = useEvent((key, cycleId, finished) => {
615
- if (!finished || cycleId !== didAnimateCycleIdRef.current) return;
616
- if (didAnimateCompletedRef.current) return;
617
- pendingDidAnimateKeysRef.current.delete(key);
618
- if (pendingDidAnimateKeysRef.current.size === 0) {
619
- didAnimateCompletedRef.current = true;
620
- isCompletingAnimationRef.value = false;
621
- onDidAnimateRef.current?.();
622
- }
623
- });
624
- const exitCycleIdRef = useRef(0);
625
- const pendingExitKeysRef = useRef(/* @__PURE__ */new Set());
626
- const exitCompletedRef = useRef(false);
627
- const wasExitingRef = useRef(false);
628
- const justStartedExiting = isExiting && !wasExitingRef.current;
629
- const justStoppedExiting = !isExiting && wasExitingRef.current;
630
- const markExitKeyDone = useEvent((key, cycleId, finished) => {
631
- if (cycleId !== exitCycleIdRef.current) return;
632
- if (exitCompletedRef.current) return;
633
- pendingExitKeysRef.current.delete(key);
634
- if (pendingExitKeysRef.current.size === 0) {
635
- exitCompletedRef.current = true;
636
- sendExitComplete?.();
637
- }
638
- });
639
- const isExitingRef = useSharedValue(isExiting);
640
- const exitCycleIdShared = useSharedValue(exitCycleIdRef.current);
641
- if (justStartedExiting) {
642
- exitCycleIdRef.current++;
643
- exitCompletedRef.current = false;
644
- pendingExitKeysRef.current.clear();
645
- didAnimateCycleIdRef.current++;
646
- pendingDidAnimateKeysRef.current.clear();
647
- didAnimateCompletedRef.current = true;
648
- }
649
- if (justStoppedExiting) {
650
- exitCycleIdRef.current++;
651
- pendingExitKeysRef.current.clear();
652
- }
653
- useIsomorphicLayoutEffect(() => {
654
- isExitingRef.value = isExiting;
655
- exitCycleIdShared.value = exitCycleIdRef.current;
656
- if (justStartedExiting) {
657
- isCompletingAnimationRef.value = false;
658
- didAnimateCycleIdShared.value = didAnimateCycleIdRef.current;
659
- }
660
- }, [isExiting, exitCycleIdRef.current, justStartedExiting]);
661
- React.useEffect(() => {
662
- wasExitingRef.current = isExiting;
663
- });
664
- const committedRenderKeysRef = useRef(/* @__PURE__ */new Set());
665
- const lastPaintedRef = useRef({});
666
- const carryRef = useRef({});
667
- const {
668
- animatedStyles,
669
- staticStyles,
670
- nextCarry
671
- } = useMemo(() => {
672
- const animateOnly = props.animateOnly;
673
- const {
674
- animated,
675
- statics
676
- } = splitAnimationStyles(style, isDark, disableAnimation, animateOnly);
677
- const nextCarry2 = cloneStyleRecord(carryRef.current);
678
- for (const key in nextCarry2) {
679
- if (!(key in animated)) delete nextCarry2[key];
680
- }
681
- for (const key in animated) {
682
- if (!(key in nextCarry2)) {
683
- nextCarry2[key] = cloneAnimationValue(animated[key]);
684
- }
685
- statics[key] = nextCarry2[key];
686
- }
687
- return {
688
- animatedStyles: animated,
689
- staticStyles: statics,
690
- nextCarry: nextCarry2
691
- };
692
- }, [disableAnimation, style, isDark, props.animateOnly]);
693
- const renderSnapshot = useMemo(() => buildSnapshot(animatedStyles, staticStyles, getAnimatedTransforms(animatedStyles.transform), committedRenderKeysRef.current, lastPaintedRef.current), [animatedStyles, staticStyles]);
694
- const renderSnapshotRef = useSharedValue({
695
- animated: {},
696
- statics: {},
697
- transforms: [],
698
- gatedKeys: {},
699
- seeds: {},
700
- removedKeys: {},
701
- removeTransform: false,
702
- clearValue: isWeb ? "" : null
703
- });
704
- const emitterSnapshotRef = useSharedValue(null);
705
- const emitterKeysRef = useRef(null);
706
- useIsomorphicLayoutEffect(() => {
707
- carryRef.current = nextCarry;
708
- committedRenderKeysRef.current = renderSnapshot.keys;
709
- lastPaintedRef.current = renderSnapshot.painted;
710
- }, [nextCarry, renderSnapshot]);
711
- const pseudoActiveRef = useRef(false);
712
- const isExitingJSRef = useRef(false);
713
- isExitingJSRef.current = isExiting;
714
- const publishedSnapshotRef = useRef(null);
715
- useIsomorphicLayoutEffect(() => {
716
- const droppingLatch = (isExiting || !pseudoActiveRef.current) && emitterSnapshotRef.value !== null;
717
- const emitterKeys = droppingLatch ? emitterKeysRef.current : null;
718
- if (droppingLatch || publishedSnapshotRef.current !== renderSnapshot.value) {
719
- const removedKeys = emitterKeys ? {
720
- ...renderSnapshot.value.removedKeys,
721
- ...getRemovedAnimatedKeys(renderSnapshot.keys, emitterKeys)
722
- } : renderSnapshot.value.removedKeys;
723
- renderSnapshotRef.value = {
724
- ...renderSnapshot.value,
725
- removedKeys,
726
- removeTransform: Object.keys(removedKeys).some(key => key.startsWith("transform:"))
727
- };
728
- publishedSnapshotRef.current = renderSnapshot.value;
729
- }
730
- if (droppingLatch) {
731
- emitterSnapshotRef.value = null;
732
- emitterKeysRef.current = null;
733
- }
734
- });
735
- const {
736
- baseConfig,
737
- propertyConfigs
738
- } = useMemo(() => {
739
- if (isHydrating) {
740
- return {
741
- baseConfig: {
742
- type: "timing",
743
- duration: 0
744
- },
745
- propertyConfigs: {}
746
- };
747
- }
748
- return buildTransitionConfig(effectiveTransition, animations, animationState, getStyleKeys(animatedStyles));
749
- }, [isHydrating, effectiveTransition, animatedStyles, animationState]);
750
- const configRef = useSharedValue({
751
- baseConfig,
752
- propertyConfigs,
753
- disableAnimation,
754
- isHydrating
755
- });
756
- useIsomorphicLayoutEffect(() => {
757
- configRef.value = {
758
- baseConfig,
759
- propertyConfigs,
760
- disableAnimation,
761
- isHydrating
762
- };
763
- }, [baseConfig, propertyConfigs, disableAnimation, isHydrating]);
764
- useStyleEmitter?.((nextStyle, effectiveTransition2, pseudoActive) => {
765
- if (isExitingJSRef.current) return;
766
- pseudoActiveRef.current = pseudoActive === true;
767
- const animateOnly = props.animateOnly;
768
- const transitionToUse = effectiveTransition2 ?? props.transition;
769
- const {
770
- baseConfig: newBase,
771
- propertyConfigs: newPropertyConfigs
772
- } = buildTransitionConfig(transitionToUse, animations, animationState, getStyleKeys(nextStyle));
773
- configRef.value = {
774
- baseConfig: newBase,
775
- propertyConfigs: newPropertyConfigs,
776
- disableAnimation: configRef.value.disableAnimation,
777
- isHydrating: configRef.value.isHydrating
778
- };
779
- const previousKeys = emitterKeysRef.current ?? committedRenderKeysRef.current;
780
- const {
781
- animated,
782
- statics
783
- } = splitAnimationStyles(nextStyle, isDark, configRef.value.disableAnimation, animateOnly);
784
- const snapshot = buildSnapshot(animated, statics, getAnimatedTransforms(animated.transform), previousKeys, lastPaintedRef.current);
785
- emitterSnapshotRef.value = snapshot.value;
786
- emitterKeysRef.current = snapshot.keys;
787
- lastPaintedRef.current = snapshot.painted;
788
- if (process.env.NODE_ENV === "development" && props.debug && props.debug !== "profile") {
789
- console.info("[animations-reanimated] useStyleEmitter update", {
790
- animated,
791
- statics,
792
- transforms: snapshot.value.transforms
793
- });
794
- }
795
- });
796
- const exitKeysRegistered = useRef(false);
797
- if (justStartedExiting && sendExitComplete) {
798
- const exitKeys = getGatedKeys(renderSnapshot.value);
799
- pendingExitKeysRef.current = new Set(exitKeys);
800
- exitKeysRegistered.current = exitKeys.length > 0;
801
- }
802
- const previousDidAnimateStyleRef = useRef(null);
803
- const didAnimateStyle = onDidAnimate ? JSON.stringify(style) : null;
804
- const previousDidAnimateStyle = previousDidAnimateStyleRef.current;
805
- const shouldRegisterDidAnimate = didAnimateStyle !== null && previousDidAnimateStyle !== null && previousDidAnimateStyle !== didAnimateStyle && !isExiting && !isEntering && !justFinishedEntering;
806
- const didAnimateKeys = shouldRegisterDidAnimate ? getGatedKeys(renderSnapshot.value) : [];
807
- useIsomorphicLayoutEffect(() => {
808
- if (didAnimateStyle === null) {
809
- previousDidAnimateStyleRef.current = null;
810
- isCompletingAnimationRef.value = false;
811
- return;
812
- }
813
- const previousStyleStillCurrent = previousDidAnimateStyleRef.current === previousDidAnimateStyle;
814
- previousDidAnimateStyleRef.current = didAnimateStyle;
815
- if (!shouldRegisterDidAnimate || !previousStyleStillCurrent) return;
816
- const cycleId = ++didAnimateCycleIdRef.current;
817
- pendingDidAnimateKeysRef.current = new Set(didAnimateKeys);
818
- didAnimateCompletedRef.current = didAnimateKeys.length === 0;
819
- isCompletingAnimationRef.value = didAnimateKeys.length > 0;
820
- didAnimateCycleIdShared.value = cycleId;
821
- if (didAnimateKeys.length === 0) {
822
- onDidAnimateRef.current?.();
823
- }
824
- }, [didAnimateStyle, shouldRegisterDidAnimate]);
825
- React.useEffect(() => {
826
- if (!justStartedExiting || !sendExitComplete) return;
827
- if (!exitKeysRegistered.current && pendingExitKeysRef.current.size === 0) {
828
- if (!exitCompletedRef.current) {
829
- exitCompletedRef.current = true;
830
- sendExitComplete();
831
- }
832
- }
833
- }, [justStartedExiting, sendExitComplete]);
834
- const mapperStateRef = useSharedValue({
835
- emitted: {}
836
- });
837
- const animatedStyle = useAnimatedStyle(() => {
838
- "worklet";
839
-
840
- const mapperState = mapperStateRef.value;
841
- const config = configRef.value;
842
- if (config.disableAnimation || config.isHydrating) {
843
- updateMapperState(mapperStateRef, {});
844
- return {};
845
- }
846
- const previouslyEmitted = mapperState.emitted;
847
- const emitted = {};
848
- const result = {};
849
- const emitterSnapshot = emitterSnapshotRef.value;
850
- const snapshot = emitterSnapshot ?? renderSnapshotRef.value;
851
- const animatedValues = snapshot.animated;
852
- const staticValues = snapshot.statics;
853
- const currentlyExiting = isExitingRef.value;
854
- const currentCycleId = exitCycleIdShared.value;
855
- const currentlyCompletingAnimation = isCompletingAnimationRef.value;
856
- const currentDidAnimateCycleId = didAnimateCycleIdShared.value;
857
- for (const key in staticValues) {
858
- result[key] = staticValues[key];
859
- }
860
- for (const key in snapshot.removedKeys) {
861
- if (!key.startsWith("transform:") && !(key in staticValues)) {
862
- result[key] = snapshot.clearValue;
863
- }
864
- }
865
- for (const key in animatedValues) {
866
- if (key === "transform") continue;
867
- const targetValue = animatedValues[key];
868
- emitted[key] = true;
869
- if (typeof targetValue !== "number" && typeof targetValue !== "string") {
870
- result[key] = targetValue;
871
- continue;
872
- }
873
- result[key] = animateSnapshotValue(key, key, targetValue, config.propertyConfigs[key] ?? config.baseConfig, !!previouslyEmitted[key], snapshot.seeds[key], !!snapshot.gatedKeys[key], currentlyExiting, currentCycleId, currentlyCompletingAnimation, currentDidAnimateCycleId, markExitKeyDone, markDidAnimateKeyDone, !!COLOR_STYLE_KEYS[key]);
874
- }
875
- const transforms = snapshot.transforms;
876
- if (transforms.length > 0 || snapshot.removeTransform) {
877
- const validTransforms = [];
878
- for (const t of transforms) {
879
- if (!t) continue;
880
- const keys = Object.keys(t);
881
- if (keys.length === 0) continue;
882
- const transformKey = keys[0];
883
- const value = t[transformKey];
884
- if (typeof value === "number" || typeof value === "string") {
885
- const propConfig = config.propertyConfigs[transformKey] ?? config.baseConfig;
886
- const subKey = `transform:${transformKey}`;
887
- emitted[subKey] = true;
888
- validTransforms.push({
889
- [transformKey]: animateSnapshotValue(subKey, transformKey, value, propConfig, !!previouslyEmitted[subKey], snapshot.seeds[subKey], !!snapshot.gatedKeys[subKey], currentlyExiting, currentCycleId, currentlyCompletingAnimation, currentDidAnimateCycleId, markExitKeyDone, markDidAnimateKeyDone)
890
- });
891
- } else {
892
- validTransforms.push(t);
893
- }
894
- }
895
- if (validTransforms.length > 0 || !("transform" in staticValues)) {
896
- result.transform = validTransforms;
897
- }
898
- }
899
- updateMapperState(mapperStateRef, emitted);
900
- return result;
901
- }, isWeb ? [
902
- // pass SharedValues so the stable mapper watches them on web (no babel plugin)
903
- renderSnapshotRef, emitterSnapshotRef, configRef, isExitingRef, exitCycleIdShared, markExitKeyDone, isCompletingAnimationRef, didAnimateCycleIdShared, markDidAnimateKeyDone] : void 0);
904
- silenceAnimatedComponentDevCheck(animatedStyle);
905
- if (process.env.NODE_ENV === "development" && props.debug && props.debug !== "profile") {
906
- console.info("[animations-reanimated] useAnimations", {
907
- animationKey,
908
- componentState,
909
- isExiting,
910
- animatedStyles,
911
- staticStyles,
912
- baseConfig,
913
- propertyConfigs
914
- });
915
- }
916
- return {
917
- style: [staticStyles, animatedStyle]
918
- };
919
- }
920
- };
438
+ const animations = {};
439
+ for (const key in animationsConfig) {
440
+ animations[key] = cloneTransitionConfig({
441
+ type: "spring",
442
+ ...animationsConfig[key]
443
+ });
444
+ }
445
+ return {
446
+ needsCustomComponent: true,
447
+ View: isWeb ? AnimatedView : Animated.View,
448
+ Text: isWeb ? AnimatedText : Animated.Text,
449
+ isReactNative: true,
450
+ inputStyle: "value",
451
+ outputStyle: "inline",
452
+ avoidReRenders: true,
453
+ animations,
454
+ usePresence,
455
+ ResetPresence,
456
+ useAnimatedNumber(initial) {
457
+ const sharedValue = useSharedValue(initial);
458
+ return useMemo(() => ({
459
+ getInstance() {
460
+ "worklet";
461
+ return sharedValue;
462
+ },
463
+ getValue() {
464
+ "worklet";
465
+ return sharedValue.value;
466
+ },
467
+ setValue(next, config = { type: "spring" }, onFinish) {
468
+ if (config.type === "direct") {
469
+ sharedValue.value = next;
470
+ onFinish?.();
471
+ } else {
472
+ const cb = onFinish ? (finished) => {
473
+ "worklet";
474
+ if (finished !== false) {
475
+ runOnJS(onFinish)();
476
+ }
477
+ } : void 0;
478
+ const animationConfig = cloneTransitionConfig(config);
479
+ if (isWeb) {
480
+ sharedValue.value = applyAnimation(next, animationConfig, cb);
481
+ } else {
482
+ runOnUI((targetValue, animationConfig2) => {
483
+ "worklet";
484
+ sharedValue.value = applyAnimation(targetValue, animationConfig2, cb);
485
+ })(next, animationConfig);
486
+ }
487
+ }
488
+ },
489
+ stop() {
490
+ cancelAnimation(sharedValue);
491
+ }
492
+ }), [sharedValue]);
493
+ },
494
+ useAnimatedNumberReaction({ value }, onValue) {
495
+ const instance = value.getInstance();
496
+ return useAnimatedReaction(() => instance.value, (next, prev) => {
497
+ if (prev !== next) {
498
+ runOnJS(onValue)(next);
499
+ }
500
+ }, [onValue, instance]);
501
+ },
502
+ useAnimatedNumberStyle(val, getStyle) {
503
+ const instance = val.getInstance();
504
+ if (isWeb) {
505
+ return useAnimatedStyle(() => {
506
+ "worklet";
507
+ return getStyle(instance.value);
508
+ }, [instance, getStyle]);
509
+ }
510
+ const styleVal = useDerivedValue(() => {
511
+ "worklet";
512
+ return getStyle(instance.value);
513
+ });
514
+ const animatedStyle = useAnimatedStyle(() => {
515
+ "worklet";
516
+ return styleVal.value;
517
+ });
518
+ silenceAnimatedComponentDevCheck(animatedStyle);
519
+ return animatedStyle;
520
+ },
521
+ useAnimatedNumbersStyle(vals, getStyle) {
522
+ const instances = vals.map((v) => v.getInstance());
523
+ const animatedStyle = useAnimatedStyle(() => {
524
+ "worklet";
525
+ const currentValues = instances.map((inst) => inst.value);
526
+ return getStyle(...currentValues);
527
+ }, isWeb ? [getStyle, ...instances] : void 0);
528
+ silenceAnimatedComponentDevCheck(animatedStyle);
529
+ return animatedStyle;
530
+ },
531
+ useAnimations(animationProps) {
532
+ const { props, presence, style, componentState, useStyleEmitter, themeName, stateRef, styleState, onTransition } = animationProps;
533
+ const isHydrating = componentState.unmounted === true;
534
+ const isMounting = componentState.unmounted === "should-enter";
535
+ const isEntering = !!componentState.unmounted;
536
+ const isExiting = presence?.[0] === false;
537
+ const wasEnteringRef = useRef(isEntering);
538
+ const justFinishedEntering = wasEnteringRef.current && !isEntering;
539
+ React.useEffect(() => {
540
+ wasEnteringRef.current = isEntering;
541
+ });
542
+ const effectiveTransition = styleState?.effectiveTransition ?? props.transition;
543
+ const normalized = normalizeTransition(effectiveTransition);
544
+ const animationState = isExiting ? "exit" : isMounting || justFinishedEntering ? "enter" : "default";
545
+ const animationKey = getEffectiveAnimation(normalized, animationState);
546
+ const disableAnimation = isHydrating || !animationKey;
547
+ const isDark = themeName?.startsWith("dark") || false;
548
+ const sendExitComplete = presence?.[1];
549
+ const onTransitionRef = useRef(onTransition);
550
+ onTransitionRef.current = onTransition;
551
+ const emit = (phase, cause, finished) => {
552
+ onTransitionRef.current?.(phase === "end" ? {
553
+ phase,
554
+ cause,
555
+ finished
556
+ } : {
557
+ phase,
558
+ cause
559
+ });
560
+ };
561
+ const enterStartedRef = useRef(false);
562
+ const exitStartedRef = useRef(false);
563
+ const updateStartedRef = useRef(false);
564
+ const isExitingJSRef = useRef(false);
565
+ isExitingJSRef.current = isExiting;
566
+ const updateCycleIdRef = useRef(0);
567
+ const pendingUpdateKeysRef = useRef(/* @__PURE__ */ new Set());
568
+ const updateCompletedRef = useRef(false);
569
+ const isCompletingUpdateRef = useSharedValue(false);
570
+ const updateCycleIdShared = useSharedValue(0);
571
+ const markUpdateKeyDone = useEvent((key, cycleId, finished) => {
572
+ if (!finished || cycleId !== updateCycleIdRef.current) return;
573
+ if (updateCompletedRef.current) return;
574
+ pendingUpdateKeysRef.current.delete(key);
575
+ if (pendingUpdateKeysRef.current.size === 0) {
576
+ updateCompletedRef.current = true;
577
+ isCompletingUpdateRef.value = false;
578
+ if (updateStartedRef.current) {
579
+ updateStartedRef.current = false;
580
+ emit("end", "update", true);
581
+ }
582
+ }
583
+ });
584
+ const exitCycleIdRef = useRef(0);
585
+ const pendingExitKeysRef = useRef(/* @__PURE__ */ new Set());
586
+ const exitCompletedRef = useRef(false);
587
+ const wasExitingRef = useRef(false);
588
+ const justStartedExiting = isExiting && !wasExitingRef.current;
589
+ const justStoppedExiting = !isExiting && wasExitingRef.current;
590
+ const markExitKeyDone = useEvent((key, cycleId, finished) => {
591
+ if (cycleId !== exitCycleIdRef.current) return;
592
+ if (exitCompletedRef.current) return;
593
+ pendingExitKeysRef.current.delete(key);
594
+ if (pendingExitKeysRef.current.size === 0) {
595
+ exitCompletedRef.current = true;
596
+ if (exitStartedRef.current) {
597
+ exitStartedRef.current = false;
598
+ emit("end", "exit", true);
599
+ }
600
+ sendExitComplete?.();
601
+ }
602
+ });
603
+ const enterCycleIdRef = useRef(0);
604
+ const pendingEnterKeysRef = useRef(/* @__PURE__ */ new Set());
605
+ const enterCompletedRef = useRef(false);
606
+ const markEnterKeyDone = useEvent((key, cycleId) => {
607
+ if (cycleId !== enterCycleIdRef.current) return;
608
+ if (enterCompletedRef.current) return;
609
+ if (isExitingJSRef.current) return;
610
+ pendingEnterKeysRef.current.delete(key);
611
+ if (pendingEnterKeysRef.current.size === 0) {
612
+ enterCompletedRef.current = true;
613
+ if (enterStartedRef.current) {
614
+ enterStartedRef.current = false;
615
+ emit("end", "enter", true);
616
+ }
617
+ }
618
+ });
619
+ const isExitingRef = useSharedValue(isExiting);
620
+ const exitCycleIdShared = useSharedValue(exitCycleIdRef.current);
621
+ const isCompletingEnterRef = useSharedValue(false);
622
+ const enterCycleIdShared = useSharedValue(enterCycleIdRef.current);
623
+ if (justStartedExiting) {
624
+ exitCycleIdRef.current++;
625
+ exitCompletedRef.current = false;
626
+ pendingExitKeysRef.current.clear();
627
+ enterCycleIdRef.current++;
628
+ pendingEnterKeysRef.current.clear();
629
+ updateCycleIdRef.current++;
630
+ pendingUpdateKeysRef.current.clear();
631
+ updateCompletedRef.current = true;
632
+ }
633
+ if (justStoppedExiting) {
634
+ exitCycleIdRef.current++;
635
+ pendingExitKeysRef.current.clear();
636
+ }
637
+ useIsomorphicLayoutEffect(() => {
638
+ isExitingRef.value = isExiting;
639
+ exitCycleIdShared.value = exitCycleIdRef.current;
640
+ isCompletingEnterRef.value = !isExiting && justFinishedEntering && Boolean(onTransitionRef.current);
641
+ enterCycleIdShared.value = enterCycleIdRef.current;
642
+ if (justStartedExiting) {
643
+ isCompletingUpdateRef.value = false;
644
+ updateCycleIdShared.value = updateCycleIdRef.current;
645
+ }
646
+ }, [
647
+ isExiting,
648
+ justFinishedEntering,
649
+ exitCycleIdRef.current,
650
+ enterCycleIdRef.current,
651
+ justStartedExiting
652
+ ]);
653
+ useIsomorphicLayoutEffect(() => {
654
+ if (justStoppedExiting && exitStartedRef.current && !exitCompletedRef.current) {
655
+ exitStartedRef.current = false;
656
+ emit("end", "exit", false);
657
+ }
658
+ }, [justStoppedExiting]);
659
+ React.useEffect(() => {
660
+ wasExitingRef.current = isExiting;
661
+ });
662
+ const committedRenderKeysRef = useRef(/* @__PURE__ */ new Set());
663
+ const lastPaintedRef = useRef({});
664
+ const carryRef = useRef({});
665
+ const { animatedStyles, staticStyles, nextCarry } = useMemo(() => {
666
+ const animateOnly = props.animateOnly;
667
+ const { animated, statics } = splitAnimationStyles(style, isDark, disableAnimation, animateOnly);
668
+ const nextCarry2 = cloneStyleRecord(carryRef.current);
669
+ for (const key in nextCarry2) {
670
+ if (!(key in animated)) delete nextCarry2[key];
671
+ }
672
+ for (const key in animated) {
673
+ if (!(key in nextCarry2)) {
674
+ nextCarry2[key] = cloneAnimationValue(animated[key]);
675
+ }
676
+ statics[key] = nextCarry2[key];
677
+ }
678
+ return {
679
+ animatedStyles: animated,
680
+ staticStyles: statics,
681
+ nextCarry: nextCarry2
682
+ };
683
+ }, [
684
+ disableAnimation,
685
+ style,
686
+ isDark,
687
+ props.animateOnly
688
+ ]);
689
+ const renderSnapshot = useMemo(() => buildSnapshot(animatedStyles, staticStyles, getAnimatedTransforms(animatedStyles.transform), committedRenderKeysRef.current, lastPaintedRef.current), [animatedStyles, staticStyles]);
690
+ const renderSnapshotRef = useSharedValue({
691
+ animated: {},
692
+ statics: {},
693
+ transforms: [],
694
+ gatedKeys: {},
695
+ seeds: {},
696
+ removedKeys: {},
697
+ removeTransform: false,
698
+ clearValue: isWeb ? "" : null
699
+ });
700
+ const emitterSnapshotRef = useSharedValue(null);
701
+ const emitterKeysRef = useRef(null);
702
+ useIsomorphicLayoutEffect(() => {
703
+ carryRef.current = nextCarry;
704
+ committedRenderKeysRef.current = renderSnapshot.keys;
705
+ lastPaintedRef.current = renderSnapshot.painted;
706
+ }, [nextCarry, renderSnapshot]);
707
+ const pseudoActiveRef = useRef(false);
708
+ const publishedSnapshotRef = useRef(null);
709
+ useIsomorphicLayoutEffect(() => {
710
+ const renderChanged = publishedSnapshotRef.current !== renderSnapshot.value;
711
+ const droppingLatch = (isExiting || !pseudoActiveRef.current && publishedSnapshotRef.current !== null && renderChanged) && emitterSnapshotRef.value !== null;
712
+ const emitterKeys = droppingLatch ? emitterKeysRef.current : null;
713
+ if (droppingLatch || renderChanged) {
714
+ const removedKeys = emitterKeys ? {
715
+ ...renderSnapshot.value.removedKeys,
716
+ ...getRemovedAnimatedKeys(renderSnapshot.keys, emitterKeys)
717
+ } : renderSnapshot.value.removedKeys;
718
+ renderSnapshotRef.value = {
719
+ ...renderSnapshot.value,
720
+ removedKeys,
721
+ removeTransform: Object.keys(removedKeys).some((key) => key.startsWith("transform:"))
722
+ };
723
+ publishedSnapshotRef.current = renderSnapshot.value;
724
+ }
725
+ if (droppingLatch) {
726
+ emitterSnapshotRef.value = null;
727
+ emitterKeysRef.current = null;
728
+ }
729
+ });
730
+ const { baseConfig, propertyConfigs } = useMemo(() => {
731
+ if (isHydrating) {
732
+ return {
733
+ baseConfig: {
734
+ type: "timing",
735
+ duration: 0
736
+ },
737
+ propertyConfigs: {}
738
+ };
739
+ }
740
+ return buildTransitionConfig(effectiveTransition, animations, animationState, getStyleKeys(animatedStyles));
741
+ }, [
742
+ isHydrating,
743
+ effectiveTransition,
744
+ animatedStyles,
745
+ animationState
746
+ ]);
747
+ const configRef = useSharedValue({
748
+ baseConfig,
749
+ propertyConfigs,
750
+ disableAnimation,
751
+ isHydrating
752
+ });
753
+ useIsomorphicLayoutEffect(() => {
754
+ configRef.value = {
755
+ baseConfig,
756
+ propertyConfigs,
757
+ disableAnimation,
758
+ isHydrating
759
+ };
760
+ }, [
761
+ baseConfig,
762
+ propertyConfigs,
763
+ disableAnimation,
764
+ isHydrating
765
+ ]);
766
+ useStyleEmitter?.((nextStyle, effectiveTransition2, pseudoActive) => {
767
+ if (isExitingJSRef.current) return;
768
+ pseudoActiveRef.current = pseudoActive === true;
769
+ const animateOnly = props.animateOnly;
770
+ const transitionToUse = effectiveTransition2 ?? props.transition;
771
+ const { baseConfig: newBase, propertyConfigs: newPropertyConfigs } = buildTransitionConfig(transitionToUse, animations, animationState, getStyleKeys(nextStyle));
772
+ configRef.value = {
773
+ baseConfig: newBase,
774
+ propertyConfigs: newPropertyConfigs,
775
+ disableAnimation: configRef.value.disableAnimation,
776
+ isHydrating: configRef.value.isHydrating
777
+ };
778
+ const previousKeys = emitterKeysRef.current ?? committedRenderKeysRef.current;
779
+ const { animated, statics } = splitAnimationStyles(nextStyle, isDark, configRef.value.disableAnimation, animateOnly);
780
+ const snapshot = buildSnapshot(animated, statics, getAnimatedTransforms(animated.transform), previousKeys, lastPaintedRef.current);
781
+ emitterSnapshotRef.value = snapshot.value;
782
+ emitterKeysRef.current = snapshot.keys;
783
+ lastPaintedRef.current = snapshot.painted;
784
+ if (process.env.NODE_ENV === "development" && props.debug && props.debug !== "profile") {
785
+ console.info("[animations-reanimated] useStyleEmitter update", {
786
+ animated,
787
+ statics,
788
+ transforms: snapshot.value.transforms
789
+ });
790
+ }
791
+ });
792
+ const exitKeysRegistered = useRef(false);
793
+ const enterKeysRegistered = useRef(false);
794
+ if (!isExiting && justFinishedEntering && onTransition) {
795
+ const enterKeys = getGatedKeys(renderSnapshot.value);
796
+ enterCycleIdRef.current++;
797
+ enterCompletedRef.current = false;
798
+ pendingEnterKeysRef.current = new Set(enterKeys);
799
+ enterKeysRegistered.current = enterKeys.length > 0;
800
+ }
801
+ if (justStartedExiting && sendExitComplete) {
802
+ const exitKeys = getGatedKeys(renderSnapshot.value);
803
+ pendingExitKeysRef.current = new Set(exitKeys);
804
+ exitKeysRegistered.current = exitKeys.length > 0;
805
+ }
806
+ const previousUpdateStyleRef = useRef(null);
807
+ const updateStyle = onTransition ? JSON.stringify(style) : null;
808
+ const previousUpdateStyle = previousUpdateStyleRef.current;
809
+ const shouldRegisterUpdate = updateStyle !== null && previousUpdateStyle !== null && previousUpdateStyle !== updateStyle && !isExiting && !isEntering && !justFinishedEntering;
810
+ const updateKeys = shouldRegisterUpdate ? getGatedKeys(renderSnapshot.value) : [];
811
+ useIsomorphicLayoutEffect(() => {
812
+ if (updateStyle === null) {
813
+ previousUpdateStyleRef.current = null;
814
+ isCompletingUpdateRef.value = false;
815
+ return;
816
+ }
817
+ const previousStyleStillCurrent = previousUpdateStyleRef.current === previousUpdateStyle;
818
+ previousUpdateStyleRef.current = updateStyle;
819
+ if (!shouldRegisterUpdate || !previousStyleStillCurrent) return;
820
+ const cycleId = ++updateCycleIdRef.current;
821
+ pendingUpdateKeysRef.current = new Set(updateKeys);
822
+ updateCompletedRef.current = updateKeys.length === 0;
823
+ isCompletingUpdateRef.value = updateKeys.length > 0;
824
+ updateCycleIdShared.value = cycleId;
825
+ if (updateStartedRef.current) {
826
+ emit("end", "update", false);
827
+ }
828
+ updateStartedRef.current = true;
829
+ emit("start", "update");
830
+ if (updateKeys.length === 0) {
831
+ updateStartedRef.current = false;
832
+ emit("end", "update", true);
833
+ }
834
+ }, [updateStyle, shouldRegisterUpdate]);
835
+ React.useEffect(() => {
836
+ if (!justStartedExiting || !sendExitComplete) return;
837
+ if (enterStartedRef.current) {
838
+ enterStartedRef.current = false;
839
+ emit("end", "enter", false);
840
+ }
841
+ if (updateStartedRef.current) {
842
+ updateStartedRef.current = false;
843
+ emit("end", "update", false);
844
+ }
845
+ if (onTransitionRef.current && !exitStartedRef.current) {
846
+ exitStartedRef.current = true;
847
+ emit("start", "exit");
848
+ }
849
+ if (!exitKeysRegistered.current && pendingExitKeysRef.current.size === 0) {
850
+ if (!exitCompletedRef.current) {
851
+ exitCompletedRef.current = true;
852
+ if (exitStartedRef.current) {
853
+ exitStartedRef.current = false;
854
+ emit("end", "exit", true);
855
+ }
856
+ sendExitComplete();
857
+ }
858
+ }
859
+ }, [justStartedExiting, sendExitComplete]);
860
+ React.useEffect(() => {
861
+ if (isExiting || !justFinishedEntering || !onTransition) return;
862
+ if (!enterStartedRef.current) {
863
+ enterStartedRef.current = true;
864
+ emit("start", "enter");
865
+ }
866
+ if (!enterKeysRegistered.current && pendingEnterKeysRef.current.size === 0) {
867
+ if (!enterCompletedRef.current) {
868
+ enterCompletedRef.current = true;
869
+ if (enterStartedRef.current) {
870
+ enterStartedRef.current = false;
871
+ emit("end", "enter", true);
872
+ }
873
+ }
874
+ }
875
+ }, [
876
+ isExiting,
877
+ justFinishedEntering,
878
+ onTransition
879
+ ]);
880
+ const mapperStateRef = useSharedValue({ emitted: {} });
881
+ const animatedStyle = useAnimatedStyle(() => {
882
+ "worklet";
883
+ const mapperState = mapperStateRef.value;
884
+ const config = configRef.value;
885
+ if (config.disableAnimation || config.isHydrating) {
886
+ updateMapperState(mapperStateRef, {});
887
+ return {};
888
+ }
889
+ const previouslyEmitted = mapperState.emitted;
890
+ const emitted = {};
891
+ const result = {};
892
+ const emitterSnapshot = emitterSnapshotRef.value;
893
+ const snapshot = emitterSnapshot ?? renderSnapshotRef.value;
894
+ const animatedValues = snapshot.animated;
895
+ const staticValues = snapshot.statics;
896
+ const currentlyExiting = isExitingRef.value;
897
+ const currentCycleId = exitCycleIdShared.value;
898
+ const currentlyCompletingEnter = isCompletingEnterRef.value;
899
+ const currentEnterCycleId = enterCycleIdShared.value;
900
+ const currentlyCompletingUpdate = isCompletingUpdateRef.value;
901
+ const currentUpdateCycleId = updateCycleIdShared.value;
902
+ for (const key in staticValues) {
903
+ result[key] = staticValues[key];
904
+ }
905
+ for (const key in snapshot.removedKeys) {
906
+ if (!key.startsWith("transform:") && !(key in staticValues)) {
907
+ result[key] = snapshot.clearValue;
908
+ }
909
+ }
910
+ for (const key in animatedValues) {
911
+ if (key === "transform") continue;
912
+ const targetValue = animatedValues[key];
913
+ emitted[key] = true;
914
+ if (typeof targetValue !== "number" && typeof targetValue !== "string") {
915
+ result[key] = targetValue;
916
+ continue;
917
+ }
918
+ result[key] = animateSnapshotValue(key, key, targetValue, config.propertyConfigs[key] ?? config.baseConfig, !!previouslyEmitted[key], snapshot.seeds[key], !!snapshot.gatedKeys[key], currentlyExiting, currentCycleId, currentlyCompletingEnter, currentEnterCycleId, currentlyCompletingUpdate, currentUpdateCycleId, markExitKeyDone, markEnterKeyDone, markUpdateKeyDone, !!COLOR_STYLE_KEYS[key]);
919
+ }
920
+ const transforms = snapshot.transforms;
921
+ if (transforms.length > 0 || snapshot.removeTransform) {
922
+ const validTransforms = [];
923
+ for (const t of transforms) {
924
+ if (!t) continue;
925
+ const keys = Object.keys(t);
926
+ if (keys.length === 0) continue;
927
+ const transformKey = keys[0];
928
+ const value = t[transformKey];
929
+ if (typeof value === "number" || typeof value === "string") {
930
+ const propConfig = config.propertyConfigs[transformKey] ?? config.baseConfig;
931
+ const subKey = `transform:${transformKey}`;
932
+ emitted[subKey] = true;
933
+ validTransforms.push({ [transformKey]: animateSnapshotValue(subKey, transformKey, value, propConfig, !!previouslyEmitted[subKey], snapshot.seeds[subKey], !!snapshot.gatedKeys[subKey], currentlyExiting, currentCycleId, currentlyCompletingEnter, currentEnterCycleId, currentlyCompletingUpdate, currentUpdateCycleId, markExitKeyDone, markEnterKeyDone, markUpdateKeyDone) });
934
+ } else {
935
+ validTransforms.push(t);
936
+ }
937
+ }
938
+ if (validTransforms.length > 0 || !("transform" in staticValues)) {
939
+ result.transform = validTransforms;
940
+ }
941
+ }
942
+ updateMapperState(mapperStateRef, emitted);
943
+ return result;
944
+ }, isWeb ? [
945
+ renderSnapshotRef,
946
+ emitterSnapshotRef,
947
+ configRef,
948
+ isExitingRef,
949
+ exitCycleIdShared,
950
+ markExitKeyDone,
951
+ isCompletingEnterRef,
952
+ enterCycleIdShared,
953
+ markEnterKeyDone,
954
+ isCompletingUpdateRef,
955
+ updateCycleIdShared,
956
+ markUpdateKeyDone
957
+ ] : void 0);
958
+ silenceAnimatedComponentDevCheck(animatedStyle);
959
+ if (process.env.NODE_ENV === "development" && props.debug && props.debug !== "profile") {
960
+ console.info("[animations-reanimated] useAnimations", {
961
+ animationKey,
962
+ componentState,
963
+ isExiting,
964
+ animatedStyles,
965
+ staticStyles,
966
+ baseConfig,
967
+ propertyConfigs
968
+ });
969
+ }
970
+ return { style: [staticStyles, animatedStyle] };
971
+ }
972
+ };
921
973
  }
974
+
922
975
  export { createAnimations };
923
976
  //# sourceMappingURL=createAnimations.mjs.map