@tamagui/animations-reanimated 2.0.0-rc.4 → 2.0.0-rc.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/createAnimations.cjs +526 -320
- package/dist/cjs/createAnimations.native.js +634 -403
- package/dist/cjs/createAnimations.native.js.map +1 -1
- package/dist/cjs/index.cjs +7 -5
- package/dist/cjs/index.native.js +7 -5
- package/dist/cjs/index.native.js.map +1 -1
- package/dist/esm/createAnimations.mjs +499 -295
- package/dist/esm/createAnimations.mjs.map +1 -1
- package/dist/esm/createAnimations.native.js +607 -378
- package/dist/esm/createAnimations.native.js.map +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/index.js.map +1 -6
- package/package.json +10 -13
- package/src/createAnimations.tsx +410 -184
- package/types/createAnimations.d.ts.map +4 -4
- package/types/index.d.ts.map +2 -2
- package/dist/cjs/createAnimations.js +0 -376
- package/dist/cjs/createAnimations.js.map +0 -6
- package/dist/cjs/index.js +0 -15
- package/dist/cjs/index.js.map +0 -6
- package/dist/esm/createAnimations.js +0 -376
- package/dist/esm/createAnimations.js.map +0 -6
|
@@ -2,178 +2,259 @@ var __create = Object.create;
|
|
|
2
2
|
var __defProp = Object.defineProperty;
|
|
3
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __getProtoOf = Object.getPrototypeOf
|
|
6
|
-
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
7
|
var __export = (target, all) => {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
8
|
+
for (var name in all) __defProp(target, name, {
|
|
9
|
+
get: all[name],
|
|
10
|
+
enumerable: true
|
|
11
|
+
});
|
|
12
|
+
};
|
|
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, {
|
|
15
16
|
get: () => from[key],
|
|
16
17
|
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
17
18
|
});
|
|
18
|
-
|
|
19
|
-
|
|
19
|
+
}
|
|
20
|
+
return to;
|
|
21
|
+
};
|
|
20
22
|
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
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
|
|
30
|
+
}) : target, mod));
|
|
31
|
+
var __toCommonJS = mod => __copyProps(__defProp({}, "__esModule", {
|
|
32
|
+
value: true
|
|
33
|
+
}), mod);
|
|
32
34
|
var createAnimations_exports = {};
|
|
33
35
|
__export(createAnimations_exports, {
|
|
34
36
|
createAnimations: () => createAnimations
|
|
35
37
|
});
|
|
36
38
|
module.exports = __toCommonJS(createAnimations_exports);
|
|
37
|
-
var import_animation_helpers = require("@tamagui/animation-helpers")
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
39
|
+
var import_animation_helpers = require("@tamagui/animation-helpers");
|
|
40
|
+
var import_core = require("@tamagui/core");
|
|
41
|
+
var import_use_presence = require("@tamagui/use-presence");
|
|
42
|
+
var import_react = __toESM(require("react"), 1);
|
|
43
|
+
var import_react_native_reanimated = __toESM(require("react-native-reanimated"), 1);
|
|
44
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
43
45
|
const getDefaultExport = module2 => {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
46
|
+
const mod = module2;
|
|
47
|
+
if (mod.__esModule || mod[Symbol.toStringTag] === "Module") {
|
|
48
|
+
return mod.default || mod;
|
|
49
|
+
}
|
|
50
|
+
return mod;
|
|
51
|
+
};
|
|
52
|
+
const Animated = getDefaultExport(import_react_native_reanimated.default);
|
|
53
|
+
const resolveDynamicValue = (value, isDark) => {
|
|
54
|
+
if (value !== null && typeof value === "object" && "dynamic" in value && typeof value.dynamic === "object") {
|
|
55
|
+
const dynamic = value.dynamic;
|
|
56
|
+
return isDark ? dynamic.dark : dynamic.light;
|
|
57
|
+
}
|
|
58
|
+
return value;
|
|
59
|
+
};
|
|
60
|
+
const applyAnimation = (targetValue, config, callback) => {
|
|
61
|
+
"worklet";
|
|
57
62
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
63
|
+
const delay = config.delay;
|
|
64
|
+
let animatedValue;
|
|
65
|
+
if (config.type === "timing") {
|
|
66
|
+
animatedValue = (0, import_react_native_reanimated.withTiming)(targetValue, config, callback);
|
|
67
|
+
} else {
|
|
68
|
+
animatedValue = (0, import_react_native_reanimated.withSpring)(targetValue, config, callback);
|
|
69
|
+
}
|
|
70
|
+
if (delay && delay > 0) {
|
|
71
|
+
animatedValue = (0, import_react_native_reanimated.withDelay)(delay, animatedValue);
|
|
72
|
+
}
|
|
73
|
+
return animatedValue;
|
|
74
|
+
};
|
|
75
|
+
const ANIMATABLE_PROPERTIES = {
|
|
76
|
+
// Transform
|
|
77
|
+
transform: true,
|
|
78
|
+
// Opacity
|
|
79
|
+
opacity: true,
|
|
80
|
+
// Dimensions
|
|
81
|
+
height: true,
|
|
82
|
+
width: true,
|
|
83
|
+
minWidth: true,
|
|
84
|
+
minHeight: true,
|
|
85
|
+
maxWidth: true,
|
|
86
|
+
maxHeight: true,
|
|
87
|
+
// Background
|
|
88
|
+
backgroundColor: true,
|
|
89
|
+
// Border colors
|
|
90
|
+
borderColor: true,
|
|
91
|
+
borderLeftColor: true,
|
|
92
|
+
borderRightColor: true,
|
|
93
|
+
borderTopColor: true,
|
|
94
|
+
borderBottomColor: true,
|
|
95
|
+
// Border radius
|
|
96
|
+
borderRadius: true,
|
|
97
|
+
borderTopLeftRadius: true,
|
|
98
|
+
borderTopRightRadius: true,
|
|
99
|
+
borderBottomLeftRadius: true,
|
|
100
|
+
borderBottomRightRadius: true,
|
|
101
|
+
// Border width
|
|
102
|
+
borderWidth: true,
|
|
103
|
+
borderLeftWidth: true,
|
|
104
|
+
borderRightWidth: true,
|
|
105
|
+
borderTopWidth: true,
|
|
106
|
+
borderBottomWidth: true,
|
|
107
|
+
// Text
|
|
108
|
+
color: true,
|
|
109
|
+
fontSize: true,
|
|
110
|
+
fontWeight: true,
|
|
111
|
+
lineHeight: true,
|
|
112
|
+
letterSpacing: true,
|
|
113
|
+
// Position
|
|
114
|
+
left: true,
|
|
115
|
+
right: true,
|
|
116
|
+
top: true,
|
|
117
|
+
bottom: true,
|
|
118
|
+
// Margin
|
|
119
|
+
margin: true,
|
|
120
|
+
marginTop: true,
|
|
121
|
+
marginBottom: true,
|
|
122
|
+
marginLeft: true,
|
|
123
|
+
marginRight: true,
|
|
124
|
+
marginHorizontal: true,
|
|
125
|
+
marginVertical: true,
|
|
126
|
+
// Padding
|
|
127
|
+
padding: true,
|
|
128
|
+
paddingTop: true,
|
|
129
|
+
paddingBottom: true,
|
|
130
|
+
paddingLeft: true,
|
|
131
|
+
paddingRight: true,
|
|
132
|
+
paddingHorizontal: true,
|
|
133
|
+
paddingVertical: true,
|
|
134
|
+
// Flex/Gap
|
|
135
|
+
gap: true,
|
|
136
|
+
rowGap: true,
|
|
137
|
+
columnGap: true,
|
|
138
|
+
flex: true,
|
|
139
|
+
flexGrow: true,
|
|
140
|
+
flexShrink: true
|
|
141
|
+
};
|
|
142
|
+
const canAnimateProperty = (key, value, animateOnly) => {
|
|
143
|
+
if (!ANIMATABLE_PROPERTIES[key]) return false;
|
|
144
|
+
if (value === "auto") return false;
|
|
145
|
+
if (typeof value === "string" && value.startsWith("calc")) return false;
|
|
146
|
+
if (animateOnly && !animateOnly.includes(key)) return false;
|
|
147
|
+
return true;
|
|
148
|
+
};
|
|
130
149
|
function createWebAnimatedComponent(defaultTag) {
|
|
131
|
-
const isText = defaultTag === "span"
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
})
|
|
159
|
-
|
|
150
|
+
const isText = defaultTag === "span";
|
|
151
|
+
const Component = Animated.createAnimatedComponent((0, import_react.forwardRef)((propsIn, ref) => {
|
|
152
|
+
const {
|
|
153
|
+
forwardedRef,
|
|
154
|
+
render = defaultTag,
|
|
155
|
+
...rest
|
|
156
|
+
} = propsIn;
|
|
157
|
+
const hostRef = (0, import_react.useRef)(null);
|
|
158
|
+
const composedRefs = (0, import_core.useComposedRefs)(forwardedRef, ref, hostRef);
|
|
159
|
+
const stateRef = (0, import_react.useRef)({
|
|
160
|
+
get host() {
|
|
161
|
+
return hostRef.current;
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
const [, themeState] = (0, import_core.useThemeWithState)({});
|
|
165
|
+
const result = (0, import_core.getSplitStyles)(rest, isText ? import_core.Text.staticConfig : import_core.View.staticConfig, themeState?.theme ?? {}, themeState?.name ?? "", {
|
|
166
|
+
unmounted: false
|
|
167
|
+
}, {
|
|
168
|
+
isAnimated: false,
|
|
169
|
+
noClass: true
|
|
170
|
+
});
|
|
171
|
+
const viewProps = result?.viewProps ?? {};
|
|
172
|
+
const Element = render;
|
|
173
|
+
const transformedProps = import_core.hooks.usePropsTransform?.(render, viewProps, stateRef, false);
|
|
174
|
+
return /* @__PURE__ */(0, import_jsx_runtime.jsx)(Element, {
|
|
175
|
+
...transformedProps,
|
|
176
|
+
ref: composedRefs
|
|
177
|
+
});
|
|
178
|
+
}));
|
|
179
|
+
Component.acceptRenderProp = true;
|
|
180
|
+
return Component;
|
|
181
|
+
}
|
|
182
|
+
const AnimatedView = createWebAnimatedComponent("div");
|
|
183
|
+
const AnimatedText = createWebAnimatedComponent("span");
|
|
184
|
+
function buildTransitionConfig(transition, animations, animationState, styleKeys) {
|
|
185
|
+
const normalized = (0, import_animation_helpers.normalizeTransition)(transition);
|
|
186
|
+
const effectiveKey = (0, import_animation_helpers.getEffectiveAnimation)(normalized, animationState);
|
|
187
|
+
let base = effectiveKey ? animations[effectiveKey] ?? {
|
|
188
|
+
type: "spring"
|
|
189
|
+
} : {
|
|
190
|
+
type: "spring"
|
|
191
|
+
};
|
|
192
|
+
if (normalized.delay) {
|
|
193
|
+
base = {
|
|
194
|
+
...base,
|
|
195
|
+
delay: normalized.delay
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
if (normalized.config) {
|
|
199
|
+
base = {
|
|
200
|
+
...base,
|
|
201
|
+
...normalized.config
|
|
202
|
+
};
|
|
203
|
+
if (base.type !== "timing" && normalized.config.duration !== void 0 && normalized.config.damping === void 0 && normalized.config.stiffness === void 0 && normalized.config.mass === void 0) {
|
|
204
|
+
base = {
|
|
205
|
+
...base,
|
|
206
|
+
type: "timing"
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
const propertyConfigs = {};
|
|
211
|
+
for (const key of styleKeys) {
|
|
212
|
+
const propAnimation = normalized.properties[key];
|
|
213
|
+
if (typeof propAnimation === "string") {
|
|
214
|
+
propertyConfigs[key] = animations[propAnimation] ?? base;
|
|
215
|
+
} else if (propAnimation && typeof propAnimation === "object") {
|
|
216
|
+
const configType = propAnimation.type;
|
|
217
|
+
const baseForProp = configType ? animations[configType] ?? base : base;
|
|
218
|
+
propertyConfigs[key] = {
|
|
219
|
+
...baseForProp,
|
|
220
|
+
...propAnimation
|
|
221
|
+
};
|
|
222
|
+
} else {
|
|
223
|
+
propertyConfigs[key] = base;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
return {
|
|
227
|
+
baseConfig: base,
|
|
228
|
+
propertyConfigs
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
function getStyleKeys(style) {
|
|
232
|
+
const keys = new Set(Object.keys(style));
|
|
233
|
+
if (style.transform && Array.isArray(style.transform)) {
|
|
234
|
+
for (const t of style.transform) {
|
|
235
|
+
if (t && typeof t === "object") {
|
|
236
|
+
keys.add(Object.keys(t)[0]);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
return keys;
|
|
160
241
|
}
|
|
161
|
-
const AnimatedView = createWebAnimatedComponent("div"),
|
|
162
|
-
AnimatedText = createWebAnimatedComponent("span");
|
|
163
242
|
function createAnimations(animationsConfig) {
|
|
164
243
|
const animations = {};
|
|
165
|
-
for (const key in animationsConfig)
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
244
|
+
for (const key in animationsConfig) {
|
|
245
|
+
animations[key] = {
|
|
246
|
+
type: "spring",
|
|
247
|
+
...animationsConfig[key]
|
|
248
|
+
};
|
|
249
|
+
}
|
|
169
250
|
return {
|
|
251
|
+
needsCustomComponent: true,
|
|
170
252
|
View: import_core.isWeb ? AnimatedView : Animated.View,
|
|
171
253
|
Text: import_core.isWeb ? AnimatedText : Animated.Text,
|
|
172
|
-
isReactNative:
|
|
173
|
-
supportsCSS: !1,
|
|
254
|
+
isReactNative: true,
|
|
174
255
|
inputStyle: "value",
|
|
175
256
|
outputStyle: "inline",
|
|
176
|
-
avoidReRenders:
|
|
257
|
+
avoidReRenders: true,
|
|
177
258
|
animations,
|
|
178
259
|
usePresence: import_use_presence.usePresence,
|
|
179
260
|
ResetPresence: import_use_presence.ResetPresence,
|
|
@@ -196,18 +277,27 @@ function createAnimations(animationsConfig) {
|
|
|
196
277
|
setValue(next, config = {
|
|
197
278
|
type: "spring"
|
|
198
279
|
}, onFinish) {
|
|
199
|
-
"
|
|
280
|
+
if (config.type === "direct") {
|
|
281
|
+
sharedValue.value = next;
|
|
282
|
+
onFinish?.();
|
|
283
|
+
} else {
|
|
284
|
+
const cb = onFinish ? () => {
|
|
285
|
+
"worklet";
|
|
200
286
|
|
|
201
|
-
|
|
202
|
-
|
|
287
|
+
(0, import_react_native_reanimated.runOnJS)(onFinish)();
|
|
288
|
+
} : void 0;
|
|
289
|
+
if (import_core.isWeb) {
|
|
290
|
+
sharedValue.value = config.type === "spring" ? (0, import_react_native_reanimated.withSpring)(next, config, cb) : (0, import_react_native_reanimated.withTiming)(next, config, cb);
|
|
291
|
+
} else {
|
|
292
|
+
(0, import_react_native_reanimated.runOnUI)(() => {
|
|
293
|
+
"worklet";
|
|
203
294
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
295
|
+
sharedValue.value = config.type === "spring" ? (0, import_react_native_reanimated.withSpring)(next, config, cb) : (0, import_react_native_reanimated.withTiming)(next, config, cb);
|
|
296
|
+
})();
|
|
297
|
+
}
|
|
298
|
+
}
|
|
207
299
|
},
|
|
208
300
|
stop() {
|
|
209
|
-
"worklet";
|
|
210
|
-
|
|
211
301
|
(0, import_react_native_reanimated.cancelAnimation)(sharedValue);
|
|
212
302
|
}
|
|
213
303
|
}), [sharedValue]);
|
|
@@ -220,121 +310,161 @@ function createAnimations(animationsConfig) {
|
|
|
220
310
|
}, onValue) {
|
|
221
311
|
const instance = value.getInstance();
|
|
222
312
|
return (0, import_react_native_reanimated.useAnimatedReaction)(() => instance.value, (next, prev) => {
|
|
223
|
-
prev !== next
|
|
313
|
+
if (prev !== next) {
|
|
314
|
+
(0, import_react_native_reanimated.runOnJS)(onValue)(next);
|
|
315
|
+
}
|
|
224
316
|
}, [onValue, instance]);
|
|
225
317
|
},
|
|
226
318
|
// =========================================================================
|
|
227
319
|
// useAnimatedNumberStyle - Create animated styles from values
|
|
228
320
|
// =========================================================================
|
|
229
321
|
useAnimatedNumberStyle(val, getStyle) {
|
|
230
|
-
const instance = val.getInstance()
|
|
231
|
-
|
|
232
|
-
|
|
322
|
+
const instance = val.getInstance();
|
|
323
|
+
if (import_core.isWeb) {
|
|
324
|
+
return (0, import_react_native_reanimated.useAnimatedStyle)(() => {
|
|
325
|
+
"worklet";
|
|
326
|
+
|
|
327
|
+
return getStyle(instance.value);
|
|
328
|
+
}, [instance, getStyle]);
|
|
329
|
+
}
|
|
330
|
+
const styleVal = (0, import_react_native_reanimated.useDerivedValue)(() => {
|
|
331
|
+
"worklet";
|
|
332
|
+
|
|
333
|
+
return getStyle(instance.value);
|
|
334
|
+
});
|
|
335
|
+
return (0, import_react_native_reanimated.useAnimatedStyle)(() => {
|
|
336
|
+
"worklet";
|
|
337
|
+
|
|
338
|
+
return styleVal.value;
|
|
339
|
+
});
|
|
340
|
+
},
|
|
341
|
+
useAnimatedNumbersStyle(vals, getStyle) {
|
|
342
|
+
const instances = vals.map(v => v.getInstance());
|
|
343
|
+
return (0, import_react_native_reanimated.useAnimatedStyle)(() => {
|
|
344
|
+
"worklet";
|
|
345
|
+
|
|
346
|
+
const currentValues = instances.map(inst => inst.value);
|
|
347
|
+
return getStyle(...currentValues);
|
|
348
|
+
}, import_core.isWeb ? [getStyle, ...instances] : void 0);
|
|
233
349
|
},
|
|
234
350
|
// =========================================================================
|
|
235
351
|
// useAnimations - Main animation hook for components
|
|
236
352
|
// =========================================================================
|
|
237
353
|
useAnimations(animationProps) {
|
|
238
354
|
const {
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
355
|
+
props,
|
|
356
|
+
presence,
|
|
357
|
+
style,
|
|
358
|
+
componentState,
|
|
359
|
+
useStyleEmitter,
|
|
360
|
+
themeName,
|
|
361
|
+
stateRef,
|
|
362
|
+
styleState
|
|
363
|
+
} = animationProps;
|
|
364
|
+
const isHydrating = componentState.unmounted === true;
|
|
365
|
+
const isMounting = componentState.unmounted === "should-enter";
|
|
366
|
+
const isEntering = !!componentState.unmounted;
|
|
367
|
+
const isExiting = presence?.[0] === false;
|
|
368
|
+
const wasEnteringRef = (0, import_react.useRef)(isEntering);
|
|
369
|
+
const justFinishedEntering = wasEnteringRef.current && !isEntering;
|
|
252
370
|
import_react.default.useEffect(() => {
|
|
253
371
|
wasEnteringRef.current = isEntering;
|
|
254
372
|
});
|
|
255
|
-
const
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
373
|
+
const effectiveTransition = styleState?.effectiveTransition ?? props.transition;
|
|
374
|
+
const normalized = (0, import_animation_helpers.normalizeTransition)(effectiveTransition);
|
|
375
|
+
const animationState = isExiting ? "exit" : isMounting || justFinishedEntering ? "enter" : "default";
|
|
376
|
+
const animationKey = (0, import_animation_helpers.getEffectiveAnimation)(normalized, animationState);
|
|
377
|
+
const disableAnimation = isHydrating || !animationKey;
|
|
378
|
+
const isDark = themeName?.startsWith("dark") || false;
|
|
379
|
+
const sendExitComplete = presence?.[1];
|
|
380
|
+
const exitCycleIdRef = (0, import_react.useRef)(0);
|
|
381
|
+
const pendingExitKeysRef = (0, import_react.useRef)(/* @__PURE__ */new Set());
|
|
382
|
+
const exitCompletedRef = (0, import_react.useRef)(false);
|
|
383
|
+
const wasExitingRef = (0, import_react.useRef)(false);
|
|
384
|
+
const justStartedExiting = isExiting && !wasExitingRef.current;
|
|
385
|
+
const justStoppedExiting = !isExiting && wasExitingRef.current;
|
|
386
|
+
const markExitKeyDone = (0, import_core.useEvent)((key, cycleId, finished) => {
|
|
387
|
+
if (cycleId !== exitCycleIdRef.current) return;
|
|
388
|
+
if (exitCompletedRef.current) return;
|
|
389
|
+
pendingExitKeysRef.current.delete(key);
|
|
390
|
+
if (pendingExitKeysRef.current.size === 0) {
|
|
391
|
+
exitCompletedRef.current = true;
|
|
392
|
+
sendExitComplete?.();
|
|
393
|
+
}
|
|
394
|
+
});
|
|
395
|
+
const isExitingRef = (0, import_react_native_reanimated.useSharedValue)(isExiting);
|
|
396
|
+
const exitCycleIdShared = (0, import_react_native_reanimated.useSharedValue)(exitCycleIdRef.current);
|
|
397
|
+
if (justStartedExiting) {
|
|
398
|
+
exitCycleIdRef.current++;
|
|
399
|
+
exitCompletedRef.current = false;
|
|
400
|
+
pendingExitKeysRef.current.clear();
|
|
401
|
+
}
|
|
402
|
+
if (justStoppedExiting) {
|
|
403
|
+
exitCycleIdRef.current++;
|
|
404
|
+
pendingExitKeysRef.current.clear();
|
|
405
|
+
}
|
|
406
|
+
(0, import_core.useIsomorphicLayoutEffect)(() => {
|
|
407
|
+
isExitingRef.value = isExiting;
|
|
408
|
+
exitCycleIdShared.value = exitCycleIdRef.current;
|
|
409
|
+
}, [isExiting, exitCycleIdRef.current]);
|
|
410
|
+
import_react.default.useEffect(() => {
|
|
411
|
+
wasExitingRef.current = isExiting;
|
|
412
|
+
});
|
|
413
|
+
const animatedTargetsRef = (0, import_react_native_reanimated.useSharedValue)(null);
|
|
414
|
+
const staticTargetsRef = (0, import_react_native_reanimated.useSharedValue)(null);
|
|
415
|
+
const transformTargetsRef = (0, import_react_native_reanimated.useSharedValue)(null);
|
|
416
|
+
const {
|
|
417
|
+
animatedStyles,
|
|
418
|
+
staticStyles
|
|
419
|
+
} = (0, import_react.useMemo)(() => {
|
|
420
|
+
const animated = {};
|
|
421
|
+
const staticStyles2 = {};
|
|
422
|
+
const animateOnly = props.animateOnly;
|
|
423
|
+
for (const key in style) {
|
|
424
|
+
const rawValue = style[key];
|
|
425
|
+
const value = resolveDynamicValue(rawValue, isDark);
|
|
426
|
+
if (value === void 0) continue;
|
|
427
|
+
if (disableAnimation) {
|
|
428
|
+
staticStyles2[key] = value;
|
|
429
|
+
continue;
|
|
430
|
+
}
|
|
431
|
+
if (canAnimateProperty(key, value, animateOnly)) {
|
|
432
|
+
animated[key] = value;
|
|
433
|
+
} else {
|
|
434
|
+
staticStyles2[key] = value;
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
if (isMounting) {
|
|
438
|
+
for (const key in animated) {
|
|
439
|
+
staticStyles2[key] = animated[key];
|
|
282
440
|
}
|
|
283
|
-
|
|
441
|
+
}
|
|
442
|
+
return {
|
|
443
|
+
animatedStyles: animated,
|
|
444
|
+
staticStyles: staticStyles2
|
|
445
|
+
};
|
|
446
|
+
}, [disableAnimation, style, isDark, isMounting, props.animateOnly]);
|
|
447
|
+
const {
|
|
448
|
+
baseConfig,
|
|
449
|
+
propertyConfigs
|
|
450
|
+
} = (0, import_react.useMemo)(() => {
|
|
451
|
+
if (isHydrating) {
|
|
284
452
|
return {
|
|
285
|
-
animatedStyles: animated,
|
|
286
|
-
staticStyles: staticStyles2
|
|
287
|
-
};
|
|
288
|
-
}, [disableAnimation, style, isDark, isMounting, props.animateOnly]),
|
|
289
|
-
{
|
|
290
|
-
baseConfig,
|
|
291
|
-
propertyConfigs
|
|
292
|
-
} = (0, import_react.useMemo)(() => {
|
|
293
|
-
if (isHydrating) return {
|
|
294
453
|
baseConfig: {
|
|
295
454
|
type: "timing",
|
|
296
455
|
duration: 0
|
|
297
456
|
},
|
|
298
457
|
propertyConfigs: {}
|
|
299
458
|
};
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
delay: normalized2.delay
|
|
310
|
-
});
|
|
311
|
-
const overrides = {};
|
|
312
|
-
for (const key in normalized2.properties) {
|
|
313
|
-
const animationNameOrConfig = normalized2.properties[key];
|
|
314
|
-
if (typeof animationNameOrConfig == "string") overrides[key] = animations[animationNameOrConfig] ?? base;else if (animationNameOrConfig && typeof animationNameOrConfig == "object") {
|
|
315
|
-
const configType = animationNameOrConfig.type,
|
|
316
|
-
baseForProp = configType ? animations[configType] ?? base : base;
|
|
317
|
-
overrides[key] = {
|
|
318
|
-
...baseForProp,
|
|
319
|
-
...animationNameOrConfig
|
|
320
|
-
};
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
const configs = {},
|
|
324
|
-
allKeys = new Set(Object.keys(animatedStyles));
|
|
325
|
-
if (animatedStyles.transform && Array.isArray(animatedStyles.transform)) for (const t of animatedStyles.transform) allKeys.add(Object.keys(t)[0]);
|
|
326
|
-
for (const key of allKeys) configs[key] = overrides[key] ?? base;
|
|
327
|
-
return {
|
|
328
|
-
baseConfig: base,
|
|
329
|
-
propertyConfigs: configs
|
|
330
|
-
};
|
|
331
|
-
}, [isHydrating, props.transition, animatedStyles, animationState]),
|
|
332
|
-
configRef = (0, import_react_native_reanimated.useSharedValue)({
|
|
333
|
-
baseConfig,
|
|
334
|
-
propertyConfigs,
|
|
335
|
-
disableAnimation,
|
|
336
|
-
isHydrating
|
|
337
|
-
});
|
|
459
|
+
}
|
|
460
|
+
return buildTransitionConfig(props.transition, animations, animationState, getStyleKeys(animatedStyles));
|
|
461
|
+
}, [isHydrating, props.transition, animatedStyles, animationState]);
|
|
462
|
+
const configRef = (0, import_react_native_reanimated.useSharedValue)({
|
|
463
|
+
baseConfig,
|
|
464
|
+
propertyConfigs,
|
|
465
|
+
disableAnimation,
|
|
466
|
+
isHydrating
|
|
467
|
+
});
|
|
338
468
|
(0, import_core.useIsomorphicLayoutEffect)(() => {
|
|
339
469
|
configRef.set({
|
|
340
470
|
baseConfig,
|
|
@@ -342,68 +472,129 @@ function createAnimations(animationsConfig) {
|
|
|
342
472
|
disableAnimation,
|
|
343
473
|
isHydrating
|
|
344
474
|
});
|
|
345
|
-
}, [baseConfig, propertyConfigs, disableAnimation, isHydrating])
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
475
|
+
}, [baseConfig, propertyConfigs, disableAnimation, isHydrating]);
|
|
476
|
+
useStyleEmitter?.((nextStyle, effectiveTransition2) => {
|
|
477
|
+
const animateOnly = props.animateOnly;
|
|
478
|
+
const animated = {};
|
|
479
|
+
const statics = {};
|
|
480
|
+
const transforms = [];
|
|
481
|
+
const transitionToUse = effectiveTransition2 ?? props.transition;
|
|
482
|
+
const {
|
|
483
|
+
baseConfig: newBase,
|
|
484
|
+
propertyConfigs: newPropertyConfigs
|
|
485
|
+
} = buildTransitionConfig(transitionToUse, animations, animationState, getStyleKeys(nextStyle));
|
|
486
|
+
configRef.set({
|
|
487
|
+
baseConfig: newBase,
|
|
488
|
+
propertyConfigs: newPropertyConfigs,
|
|
489
|
+
disableAnimation: configRef.get().disableAnimation,
|
|
490
|
+
isHydrating: configRef.get().isHydrating
|
|
491
|
+
});
|
|
350
492
|
for (const key in nextStyle) {
|
|
351
|
-
const rawValue = nextStyle[key]
|
|
352
|
-
|
|
353
|
-
if (value
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
493
|
+
const rawValue = nextStyle[key];
|
|
494
|
+
const value = resolveDynamicValue(rawValue, isDark);
|
|
495
|
+
if (value == void 0) continue;
|
|
496
|
+
if (configRef.get().disableAnimation) {
|
|
497
|
+
statics[key] = value;
|
|
498
|
+
continue;
|
|
499
|
+
}
|
|
500
|
+
if (key === "transform" && Array.isArray(value)) {
|
|
501
|
+
for (const t of value) {
|
|
502
|
+
if (t && typeof t === "object") {
|
|
503
|
+
const tKey = Object.keys(t)[0];
|
|
504
|
+
const tVal = t[tKey];
|
|
505
|
+
if (typeof tVal === "number" || typeof tVal === "string") {
|
|
506
|
+
transforms.push(t);
|
|
507
|
+
}
|
|
508
|
+
}
|
|
357
509
|
}
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
510
|
+
continue;
|
|
511
|
+
}
|
|
512
|
+
if (canAnimateProperty(key, value, animateOnly)) {
|
|
513
|
+
animated[key] = value;
|
|
514
|
+
} else {
|
|
515
|
+
statics[key] = value;
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
animatedTargetsRef.set(animated);
|
|
519
|
+
staticTargetsRef.set(statics);
|
|
520
|
+
transformTargetsRef.set(transforms);
|
|
521
|
+
if (process.env.NODE_ENV === "development" && props.debug && props.debug !== "profile") {
|
|
522
|
+
console.info("[animations-reanimated] useStyleEmitter update", {
|
|
523
|
+
animated,
|
|
524
|
+
statics,
|
|
525
|
+
transforms
|
|
526
|
+
});
|
|
527
|
+
}
|
|
528
|
+
});
|
|
529
|
+
const exitKeysRegistered = (0, import_react.useRef)(false);
|
|
530
|
+
if (justStartedExiting && sendExitComplete) {
|
|
531
|
+
const exitKeys = [];
|
|
532
|
+
const animateOnly = props.animateOnly;
|
|
533
|
+
for (const key in animatedStyles) {
|
|
534
|
+
if (key === "transform") continue;
|
|
535
|
+
if (canAnimateProperty(key, animatedStyles[key], animateOnly)) {
|
|
536
|
+
exitKeys.push(key);
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
const transforms = animatedStyles.transform;
|
|
540
|
+
if (transforms && Array.isArray(transforms)) {
|
|
541
|
+
for (const t of transforms) {
|
|
542
|
+
if (!t) continue;
|
|
543
|
+
const tKey = Object.keys(t)[0];
|
|
544
|
+
if (tKey) {
|
|
545
|
+
if (animateOnly && !animateOnly.includes(tKey)) {
|
|
546
|
+
continue;
|
|
363
547
|
}
|
|
364
|
-
|
|
548
|
+
exitKeys.push(`transform:${tKey}`);
|
|
365
549
|
}
|
|
366
|
-
canAnimateProperty(key, value, animateOnly) ? animated[key] = value : statics[key] = value;
|
|
367
550
|
}
|
|
368
551
|
}
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
})) : exitProgress.set((0, import_react_native_reanimated.withSpring)(1, config, finished => {
|
|
382
|
-
"worklet";
|
|
383
|
-
|
|
384
|
-
finished && (0, import_react_native_reanimated.runOnJS)(sendExitComplete)();
|
|
385
|
-
})), () => {
|
|
386
|
-
(0, import_react_native_reanimated.cancelAnimation)(exitProgress);
|
|
387
|
-
};
|
|
388
|
-
}, [isExiting, sendExitComplete]);
|
|
552
|
+
pendingExitKeysRef.current = new Set(exitKeys);
|
|
553
|
+
exitKeysRegistered.current = exitKeys.length > 0;
|
|
554
|
+
}
|
|
555
|
+
import_react.default.useEffect(() => {
|
|
556
|
+
if (!justStartedExiting || !sendExitComplete) return;
|
|
557
|
+
if (!exitKeysRegistered.current && pendingExitKeysRef.current.size === 0) {
|
|
558
|
+
if (!exitCompletedRef.current) {
|
|
559
|
+
exitCompletedRef.current = true;
|
|
560
|
+
sendExitComplete();
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
}, [justStartedExiting, sendExitComplete]);
|
|
389
564
|
const animatedStyle = (0, import_react_native_reanimated.useAnimatedStyle)(() => {
|
|
390
565
|
"worklet";
|
|
391
566
|
|
|
392
|
-
if (disableAnimation || isHydrating)
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
567
|
+
if (disableAnimation || isHydrating) {
|
|
568
|
+
return {};
|
|
569
|
+
}
|
|
570
|
+
const result = {};
|
|
571
|
+
const config = configRef.get();
|
|
572
|
+
const emitterAnimated = animatedTargetsRef.value;
|
|
573
|
+
const emitterStatic = staticTargetsRef.value;
|
|
574
|
+
const emitterTransforms = transformTargetsRef.value;
|
|
575
|
+
const hasEmitterUpdates = emitterAnimated !== null;
|
|
576
|
+
const animatedValues = hasEmitterUpdates ? emitterAnimated : animatedStyles;
|
|
577
|
+
const staticValues = hasEmitterUpdates ? emitterStatic : {};
|
|
578
|
+
const currentlyExiting = isExitingRef.value;
|
|
579
|
+
const currentCycleId = exitCycleIdShared.value;
|
|
580
|
+
for (const key in staticValues) {
|
|
581
|
+
result[key] = staticValues[key];
|
|
582
|
+
}
|
|
402
583
|
for (const key in animatedValues) {
|
|
403
584
|
if (key === "transform") continue;
|
|
404
|
-
const targetValue = animatedValues[key]
|
|
405
|
-
|
|
406
|
-
|
|
585
|
+
const targetValue = animatedValues[key];
|
|
586
|
+
const propConfig = config.propertyConfigs[key] ?? config.baseConfig;
|
|
587
|
+
let callback;
|
|
588
|
+
if (currentlyExiting) {
|
|
589
|
+
const capturedKey = key;
|
|
590
|
+
const capturedCycleId = currentCycleId;
|
|
591
|
+
callback = finished => {
|
|
592
|
+
"worklet";
|
|
593
|
+
|
|
594
|
+
(0, import_react_native_reanimated.runOnJS)(markExitKeyDone)(capturedKey, capturedCycleId, finished ?? false);
|
|
595
|
+
};
|
|
596
|
+
}
|
|
597
|
+
result[key] = applyAnimation(targetValue, propConfig, callback);
|
|
407
598
|
}
|
|
408
599
|
const transforms = hasEmitterUpdates ? emitterTransforms : animatedStyles.transform;
|
|
409
600
|
if (transforms && Array.isArray(transforms)) {
|
|
@@ -413,30 +604,45 @@ function createAnimations(animationsConfig) {
|
|
|
413
604
|
const keys = Object.keys(t);
|
|
414
605
|
if (keys.length === 0) continue;
|
|
415
606
|
const value = t[keys[0]];
|
|
416
|
-
if (typeof value
|
|
417
|
-
const transformKey = Object.keys(t)[0]
|
|
418
|
-
|
|
419
|
-
|
|
607
|
+
if (typeof value === "number" || typeof value === "string") {
|
|
608
|
+
const transformKey = Object.keys(t)[0];
|
|
609
|
+
const targetValue = t[transformKey];
|
|
610
|
+
const propConfig = config.propertyConfigs[transformKey] ?? config.baseConfig;
|
|
611
|
+
let callback;
|
|
612
|
+
if (currentlyExiting) {
|
|
613
|
+
const capturedKey = `transform:${transformKey}`;
|
|
614
|
+
const capturedCycleId = currentCycleId;
|
|
615
|
+
callback = finished => {
|
|
616
|
+
"worklet";
|
|
617
|
+
|
|
618
|
+
(0, import_react_native_reanimated.runOnJS)(markExitKeyDone)(capturedKey, capturedCycleId, finished ?? false);
|
|
619
|
+
};
|
|
620
|
+
}
|
|
420
621
|
validTransforms.push({
|
|
421
|
-
[transformKey]: applyAnimation(targetValue, propConfig)
|
|
622
|
+
[transformKey]: applyAnimation(targetValue, propConfig, callback)
|
|
422
623
|
});
|
|
423
624
|
}
|
|
424
625
|
}
|
|
425
|
-
validTransforms.length > 0
|
|
626
|
+
if (validTransforms.length > 0) {
|
|
627
|
+
result.transform = validTransforms;
|
|
628
|
+
}
|
|
426
629
|
}
|
|
427
630
|
return result;
|
|
428
|
-
}, [animatedStyles, baseConfig, propertyConfigs, disableAnimation, isHydrating,
|
|
429
|
-
//
|
|
430
|
-
animatedTargetsRef, staticTargetsRef, transformTargetsRef]);
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
631
|
+
}, import_core.isWeb ? [animatedStyles, baseConfig, propertyConfigs, disableAnimation, isHydrating,
|
|
632
|
+
// pass SharedValues so the mapper watches them on web (no babel plugin)
|
|
633
|
+
animatedTargetsRef, staticTargetsRef, transformTargetsRef, isExitingRef, exitCycleIdShared, markExitKeyDone] : void 0);
|
|
634
|
+
if (process.env.NODE_ENV === "development" && props.debug && props.debug !== "profile") {
|
|
635
|
+
console.info("[animations-reanimated] useAnimations", {
|
|
636
|
+
animationKey,
|
|
637
|
+
componentState,
|
|
638
|
+
isExiting,
|
|
639
|
+
animatedStyles,
|
|
640
|
+
staticStyles,
|
|
641
|
+
baseConfig,
|
|
642
|
+
propertyConfigs
|
|
643
|
+
});
|
|
644
|
+
}
|
|
645
|
+
return {
|
|
440
646
|
style: [staticStyles, animatedStyle]
|
|
441
647
|
};
|
|
442
648
|
}
|