@rootnative/inertia 0.0.2 → 0.0.4
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/CHANGELOG.md +63 -5
- package/README.md +5 -3
- package/dist/{chunk-ZN3PNGHQ.mjs → chunk-4ASOELLA.mjs} +1 -1
- package/dist/{chunk-LYMLQ6WQ.mjs → chunk-55W7BNO2.mjs} +604 -106
- package/dist/chunk-5SRD2WCO.js +8 -0
- package/dist/{chunk-PTRF47DA.js → chunk-7A6WTXNK.js} +10 -3
- package/dist/{chunk-NKA6XR77.js → chunk-CENTULW6.js} +2 -2
- package/dist/{chunk-4PEHWDAZ.js → chunk-D5KAHWMC.js} +7 -7
- package/dist/{chunk-2DHKV2XY.mjs → chunk-J5Q46OPW.mjs} +1 -1
- package/dist/{chunk-RGNX6UZN.mjs → chunk-K3CLP74S.mjs} +2 -2
- package/dist/{chunk-IWLU3VDE.js → chunk-MYE5NMXW.js} +623 -123
- package/dist/{chunk-HFDZAHWP.mjs → chunk-NAOXQJ7U.mjs} +1 -1
- package/dist/{chunk-R63GIUNU.mjs → chunk-QKC3APP4.mjs} +1 -1
- package/dist/{chunk-V6BTXHZK.mjs → chunk-RF7J5FRM.mjs} +1 -1
- package/dist/{chunk-CY7Y64C3.mjs → chunk-TU2XFPAK.mjs} +10 -4
- package/dist/chunk-TVFNJ25Z.js +8 -0
- package/dist/chunk-VLDIFL3F.js +8 -0
- package/dist/{chunk-7AOERN53.js → chunk-WVRCKOPO.js} +3 -3
- package/dist/{chunk-TUYHTHVV.js → chunk-XMEVPEMH.js} +2 -2
- package/dist/{chunk-TUMNV4P7.mjs → chunk-YKGY22SB.mjs} +1 -1
- package/dist/gestureLayer/index.d.mts +2 -2
- package/dist/gestureLayer/index.d.ts +2 -2
- package/dist/gestureLayer/index.js +10 -10
- package/dist/gestureLayer/index.mjs +3 -3
- package/dist/index.d.mts +14 -12
- package/dist/index.d.ts +14 -12
- package/dist/index.js +68 -176
- package/dist/index.mjs +40 -147
- package/dist/motion/Image.d.mts +1 -1
- package/dist/motion/Image.d.ts +1 -1
- package/dist/motion/Image.js +5 -5
- package/dist/motion/Image.mjs +4 -4
- package/dist/motion/Pressable.d.mts +1 -1
- package/dist/motion/Pressable.d.ts +1 -1
- package/dist/motion/Pressable.js +5 -5
- package/dist/motion/Pressable.mjs +4 -4
- package/dist/motion/ScrollView.d.mts +1 -1
- package/dist/motion/ScrollView.d.ts +1 -1
- package/dist/motion/ScrollView.js +5 -5
- package/dist/motion/ScrollView.mjs +4 -4
- package/dist/motion/Text.d.mts +1 -1
- package/dist/motion/Text.d.ts +1 -1
- package/dist/motion/Text.js +5 -5
- package/dist/motion/Text.mjs +4 -4
- package/dist/motion/View.d.mts +1 -1
- package/dist/motion/View.d.ts +1 -1
- package/dist/motion/View.js +5 -5
- package/dist/motion/View.mjs +4 -4
- package/dist/touch/index.d.mts +1 -1
- package/dist/touch/index.d.ts +1 -1
- package/dist/touch/index.js +3 -3
- package/dist/touch/index.mjs +1 -1
- package/dist/{types-G1dBU2IQ.d.mts → types-37pN82yh.d.mts} +49 -14
- package/dist/{types-G1dBU2IQ.d.ts → types-37pN82yh.d.ts} +49 -14
- package/dist/{useGesture-D1e4ixJo.d.ts → useGesture-Cl4uzZIr.d.ts} +1 -1
- package/dist/{useGesture-RFY6kTL3.d.mts → useGesture-_IKkS8Dv.d.mts} +1 -1
- package/llms.txt +3 -1
- package/package.json +1 -1
- package/src/index.ts +2 -1
- package/src/internal/boxShadow.ts +177 -6
- package/src/internal/nonWorkletWarning.ts +4 -6
- package/src/internal/warnOnce.ts +28 -0
- package/src/layout/index.ts +11 -0
- package/src/layout/measureWindow.ts +135 -0
- package/src/layout/sharedRegistry.ts +156 -18
- package/src/layout/useSharedLayout.ts +256 -91
- package/src/motion/createMotionComponent.tsx +550 -55
- package/src/motion/installCheck.ts +1 -1
- package/src/presence/Presence.tsx +73 -10
- package/src/transitions/index.ts +1 -1
- package/src/types.ts +52 -12
- package/src/values/useAnimator.ts +25 -14
- package/src/values/useColorCascade.ts +34 -16
- package/src/values/useColorTransition.ts +1 -1
- package/dist/chunk-34Q4UM6V.js +0 -8
- package/dist/chunk-KYJROYCG.js +0 -8
- package/dist/chunk-X5J5M3K3.js +0 -8
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
var
|
|
3
|
+
var chunkWVRCKOPO_js = require('./chunk-WVRCKOPO.js');
|
|
4
|
+
var chunk7A6WTXNK_js = require('./chunk-7A6WTXNK.js');
|
|
5
5
|
var react = require('react');
|
|
6
6
|
var jsxRuntime = require('react/jsx-runtime');
|
|
7
7
|
var Animated = require('react-native-reanimated');
|
|
8
|
+
var reactNative = require('react-native');
|
|
8
9
|
|
|
9
10
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
10
11
|
|
|
@@ -35,6 +36,8 @@ function Presence({ children }) {
|
|
|
35
36
|
() => /* @__PURE__ */ new Map()
|
|
36
37
|
);
|
|
37
38
|
const prevIncomingRef = react.useRef(incoming);
|
|
39
|
+
const orderRef = react.useRef([]);
|
|
40
|
+
let pendingExiting = null;
|
|
38
41
|
if (prevIncomingRef.current !== incoming) {
|
|
39
42
|
const prev = prevIncomingRef.current;
|
|
40
43
|
prevIncomingRef.current = incoming;
|
|
@@ -56,8 +59,12 @@ function Presence({ children }) {
|
|
|
56
59
|
ensureMutable().delete(key);
|
|
57
60
|
}
|
|
58
61
|
}
|
|
59
|
-
if (next)
|
|
62
|
+
if (next) {
|
|
63
|
+
pendingExiting = next;
|
|
64
|
+
setExiting(next);
|
|
65
|
+
}
|
|
60
66
|
}
|
|
67
|
+
const activeExiting = pendingExiting ?? exiting;
|
|
61
68
|
const handleRemove = react.useCallback((key) => {
|
|
62
69
|
setExiting((prev) => {
|
|
63
70
|
if (!prev.has(key)) return prev;
|
|
@@ -66,19 +73,42 @@ function Presence({ children }) {
|
|
|
66
73
|
return next;
|
|
67
74
|
});
|
|
68
75
|
}, []);
|
|
69
|
-
const
|
|
76
|
+
const byKey = /* @__PURE__ */ new Map();
|
|
77
|
+
const presentKeys = /* @__PURE__ */ new Set();
|
|
78
|
+
const order = [];
|
|
70
79
|
for (const el of incoming) {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
});
|
|
80
|
+
const key = el.key;
|
|
81
|
+
byKey.set(key, el);
|
|
82
|
+
presentKeys.add(key);
|
|
83
|
+
order.push(key);
|
|
76
84
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
85
|
+
const prevOrder = orderRef.current;
|
|
86
|
+
for (let i = 0; i < prevOrder.length; i++) {
|
|
87
|
+
const key = prevOrder[i];
|
|
88
|
+
const departing = activeExiting.get(key);
|
|
89
|
+
if (!departing || byKey.has(key)) continue;
|
|
90
|
+
let insertAt = 0;
|
|
91
|
+
for (let j = i - 1; j >= 0; j--) {
|
|
92
|
+
const anchor = order.indexOf(prevOrder[j]);
|
|
93
|
+
if (anchor !== -1) {
|
|
94
|
+
insertAt = anchor + 1;
|
|
95
|
+
break;
|
|
96
|
+
}
|
|
80
97
|
}
|
|
98
|
+
byKey.set(key, departing);
|
|
99
|
+
order.splice(insertAt, 0, key);
|
|
81
100
|
}
|
|
101
|
+
for (const [key, el] of activeExiting) {
|
|
102
|
+
if (byKey.has(key)) continue;
|
|
103
|
+
byKey.set(key, el);
|
|
104
|
+
order.push(key);
|
|
105
|
+
}
|
|
106
|
+
orderRef.current = order;
|
|
107
|
+
const renderList = order.map((key) => ({
|
|
108
|
+
key,
|
|
109
|
+
element: byKey.get(key),
|
|
110
|
+
isPresent: presentKeys.has(key)
|
|
111
|
+
}));
|
|
82
112
|
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: renderList.map(({ key, element, isPresent }) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
83
113
|
PresenceItem,
|
|
84
114
|
{
|
|
@@ -105,20 +135,189 @@ function PresenceItem({
|
|
|
105
135
|
);
|
|
106
136
|
return /* @__PURE__ */ jsxRuntime.jsx(PresenceContext.Provider, { value, children });
|
|
107
137
|
}
|
|
138
|
+
|
|
139
|
+
// src/internal/boxShadow.ts
|
|
140
|
+
var LENGTH = /^[+-]?(\d+\.?\d*|\.\d+)(px)?$/i;
|
|
141
|
+
var UNIT_LIKE = /^[+-]?(\d+\.?\d*|\.\d+)[a-z%]+$/i;
|
|
142
|
+
function invalid(input, reason) {
|
|
143
|
+
return new Error(
|
|
144
|
+
`[inertia] parseBoxShadow: ${reason} in ${JSON.stringify(input)}. Expected CSS box-shadow syntax with px lengths: '[inset] <offset-x> <offset-y> [blur] [spread] [color], ...'`
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
function splitLayers(input) {
|
|
148
|
+
const layers = [];
|
|
149
|
+
let depth = 0;
|
|
150
|
+
let start = 0;
|
|
151
|
+
for (let i = 0; i < input.length; i++) {
|
|
152
|
+
const ch = input[i];
|
|
153
|
+
if (ch === "(") depth++;
|
|
154
|
+
else if (ch === ")") depth--;
|
|
155
|
+
else if (ch === "," && depth === 0) {
|
|
156
|
+
layers.push(input.slice(start, i));
|
|
157
|
+
start = i + 1;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
layers.push(input.slice(start));
|
|
161
|
+
return layers;
|
|
162
|
+
}
|
|
163
|
+
function tokenize(layer) {
|
|
164
|
+
const tokens = [];
|
|
165
|
+
let depth = 0;
|
|
166
|
+
let current = "";
|
|
167
|
+
for (const ch of layer) {
|
|
168
|
+
if (ch === "(") depth++;
|
|
169
|
+
else if (ch === ")") depth--;
|
|
170
|
+
if (depth === 0 && /\s/.test(ch)) {
|
|
171
|
+
if (current) tokens.push(current);
|
|
172
|
+
current = "";
|
|
173
|
+
} else {
|
|
174
|
+
current += ch;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
if (current) tokens.push(current);
|
|
178
|
+
return tokens;
|
|
179
|
+
}
|
|
180
|
+
function parseBoxShadow(input) {
|
|
181
|
+
const trimmed = input.trim();
|
|
182
|
+
if (trimmed === "") throw invalid(input, "empty string");
|
|
183
|
+
if (trimmed.toLowerCase() === "none") return [];
|
|
184
|
+
return splitLayers(trimmed).map((layerString) => {
|
|
185
|
+
const tokens = tokenize(layerString.trim());
|
|
186
|
+
if (tokens.length === 0) throw invalid(input, "empty layer");
|
|
187
|
+
const lengths = [];
|
|
188
|
+
let color;
|
|
189
|
+
let inset = false;
|
|
190
|
+
for (const token of tokens) {
|
|
191
|
+
if (token.toLowerCase() === "inset") {
|
|
192
|
+
if (inset) throw invalid(input, "duplicate 'inset'");
|
|
193
|
+
inset = true;
|
|
194
|
+
} else if (LENGTH.test(token)) {
|
|
195
|
+
lengths.push(parseFloat(token));
|
|
196
|
+
} else if (UNIT_LIKE.test(token)) {
|
|
197
|
+
throw invalid(input, `unsupported unit in ${JSON.stringify(token)}`);
|
|
198
|
+
} else {
|
|
199
|
+
if (color !== void 0) throw invalid(input, "multiple colors");
|
|
200
|
+
color = token;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
if (lengths.length < 2 || lengths.length > 4) {
|
|
204
|
+
throw invalid(input, `expected 2-4 lengths, got ${lengths.length}`);
|
|
205
|
+
}
|
|
206
|
+
const [offsetX = 0, offsetY = 0, blurRadius = 0, spreadDistance = 0] = lengths;
|
|
207
|
+
if (blurRadius < 0) throw invalid(input, "negative blur radius");
|
|
208
|
+
return {
|
|
209
|
+
offsetX,
|
|
210
|
+
offsetY,
|
|
211
|
+
blurRadius,
|
|
212
|
+
spreadDistance,
|
|
213
|
+
color: color ?? "black",
|
|
214
|
+
inset
|
|
215
|
+
};
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
function resolveBoxShadowInput(input) {
|
|
219
|
+
if (input === void 0) return [];
|
|
220
|
+
if (typeof input === "string") return parseBoxShadow(input);
|
|
221
|
+
return input.map((layer) => ({
|
|
222
|
+
offsetX: coerceLength(layer.offsetX, "offsetX"),
|
|
223
|
+
offsetY: coerceLength(layer.offsetY, "offsetY"),
|
|
224
|
+
blurRadius: coerceLength(layer.blurRadius, "blurRadius"),
|
|
225
|
+
spreadDistance: coerceLength(layer.spreadDistance, "spreadDistance"),
|
|
226
|
+
color: layer.color ?? "black",
|
|
227
|
+
inset: layer.inset ?? false
|
|
228
|
+
}));
|
|
229
|
+
}
|
|
230
|
+
function pairBoxShadowLayers(from, to) {
|
|
231
|
+
const count = Math.max(from.length, to.length);
|
|
232
|
+
const pairs = [];
|
|
233
|
+
for (let i = 0; i < count; i++) {
|
|
234
|
+
const a = from[i];
|
|
235
|
+
const b = to[i];
|
|
236
|
+
const fromLayer = a ?? invisibleLayer(b.inset);
|
|
237
|
+
const toLayer = b ?? invisibleLayer(a.inset);
|
|
238
|
+
if (fromLayer.inset !== toLayer.inset) {
|
|
239
|
+
throw new Error(
|
|
240
|
+
`[inertia] useShadow: boxShadow layer ${i} is 'inset' on one side but not the other \u2014 inset cannot be interpolated. Give both sides the same inset-ness (pad with a transparent layer if needed).`
|
|
241
|
+
);
|
|
242
|
+
}
|
|
243
|
+
pairs.push({ from: fromLayer, to: toLayer });
|
|
244
|
+
}
|
|
245
|
+
return pairs;
|
|
246
|
+
}
|
|
247
|
+
function invisibleLayer(inset) {
|
|
248
|
+
return {
|
|
249
|
+
offsetX: 0,
|
|
250
|
+
offsetY: 0,
|
|
251
|
+
blurRadius: 0,
|
|
252
|
+
spreadDistance: 0,
|
|
253
|
+
color: "transparent",
|
|
254
|
+
inset
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
function coerceLength(value, field) {
|
|
258
|
+
if (value === void 0) return 0;
|
|
259
|
+
if (typeof value === "number") return value;
|
|
260
|
+
const trimmed = typeof value === "string" ? value.trim() : "";
|
|
261
|
+
if (!LENGTH.test(trimmed)) {
|
|
262
|
+
throw new Error(
|
|
263
|
+
`[inertia] boxShadow: ${field} must be a number or a px length, got ${JSON.stringify(value)}.`
|
|
264
|
+
);
|
|
265
|
+
}
|
|
266
|
+
return parseFloat(trimmed);
|
|
267
|
+
}
|
|
268
|
+
function strip(layer) {
|
|
269
|
+
const { inset: _inset, ...rest } = layer;
|
|
270
|
+
return rest;
|
|
271
|
+
}
|
|
272
|
+
function markInset(insets, i, count) {
|
|
273
|
+
const list = insets ?? new Array(count).fill(false);
|
|
274
|
+
list[i] = true;
|
|
275
|
+
return list;
|
|
276
|
+
}
|
|
277
|
+
function normalizeBoxShadow(input) {
|
|
278
|
+
const resolved = resolveBoxShadowInput(input);
|
|
279
|
+
const layers = [];
|
|
280
|
+
let insets = null;
|
|
281
|
+
for (let i = 0; i < resolved.length; i++) {
|
|
282
|
+
const layer = resolved[i];
|
|
283
|
+
layers.push(strip(layer));
|
|
284
|
+
if (layer.inset) insets = markInset(insets, i, resolved.length);
|
|
285
|
+
}
|
|
286
|
+
return { layers, insets };
|
|
287
|
+
}
|
|
288
|
+
function prepareBoxShadowAnimation(current, target) {
|
|
289
|
+
const pairs = pairBoxShadowLayers(
|
|
290
|
+
current.layers.map((layer, i) => ({
|
|
291
|
+
...layer,
|
|
292
|
+
inset: current.insets?.[i] ?? false
|
|
293
|
+
})),
|
|
294
|
+
resolveBoxShadowInput(target)
|
|
295
|
+
);
|
|
296
|
+
const from = [];
|
|
297
|
+
const to = [];
|
|
298
|
+
let insets = null;
|
|
299
|
+
for (let i = 0; i < pairs.length; i++) {
|
|
300
|
+
const pair = pairs[i];
|
|
301
|
+
from.push(strip(pair.from));
|
|
302
|
+
to.push(strip(pair.to));
|
|
303
|
+
if (pair.to.inset) insets = markInset(insets, i, pairs.length);
|
|
304
|
+
}
|
|
305
|
+
return { from, to, insets };
|
|
306
|
+
}
|
|
108
307
|
function resolveLayoutTransition(layout) {
|
|
109
308
|
if (!layout) return void 0;
|
|
110
309
|
const cfg = layout === true ? { type: "spring" } : layout;
|
|
111
310
|
if (cfg.type === "no-animation") return void 0;
|
|
112
311
|
if (cfg.type === "timing") {
|
|
113
312
|
let builder2 = Animated.LinearTransition.duration(cfg.duration ?? 300);
|
|
114
|
-
const easing =
|
|
313
|
+
const easing = chunk7A6WTXNK_js.ensureWorkletEasing(cfg.easing);
|
|
115
314
|
if (easing) builder2 = builder2.easing(easing);
|
|
116
315
|
if (cfg.delay) builder2 = builder2.delay(cfg.delay);
|
|
117
316
|
return builder2;
|
|
118
317
|
}
|
|
119
318
|
const spring = cfg.type === "decay" ? { type: "spring" } : cfg;
|
|
120
|
-
const { stiffness, damping, mass } =
|
|
121
|
-
...
|
|
319
|
+
const { stiffness, damping, mass } = chunk7A6WTXNK_js.springToReanimated({
|
|
320
|
+
...chunk7A6WTXNK_js.DEFAULT_SPRING,
|
|
122
321
|
...spring
|
|
123
322
|
});
|
|
124
323
|
let builder = Animated.LinearTransition.springify().stiffness(stiffness).damping(damping).mass(mass);
|
|
@@ -130,68 +329,146 @@ function resolveLayoutTransition(layout) {
|
|
|
130
329
|
var REGISTRY = /* @__PURE__ */ new Map();
|
|
131
330
|
var SHARED_LAYOUT_TTL_MS = 1e3;
|
|
132
331
|
var now = () => Date.now();
|
|
133
|
-
|
|
134
|
-
|
|
332
|
+
var lastSweep = 0;
|
|
333
|
+
function sweepExpired(at) {
|
|
334
|
+
if (at - lastSweep < SHARED_LAYOUT_TTL_MS) return;
|
|
335
|
+
lastSweep = at;
|
|
336
|
+
for (const [id, entry] of REGISTRY) {
|
|
337
|
+
if (entry.expiresAt < at) REGISTRY.delete(id);
|
|
338
|
+
}
|
|
135
339
|
}
|
|
136
|
-
function
|
|
137
|
-
|
|
340
|
+
function registerLayout(id, rect, remeasure, readStyles) {
|
|
341
|
+
const at = now();
|
|
342
|
+
sweepExpired(at);
|
|
343
|
+
REGISTRY.set(id, {
|
|
344
|
+
rect,
|
|
345
|
+
expiresAt: at + SHARED_LAYOUT_TTL_MS,
|
|
346
|
+
remeasure,
|
|
347
|
+
readStyles
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
function releaseLayout(id, rect, styles) {
|
|
351
|
+
const at = now();
|
|
352
|
+
sweepExpired(at);
|
|
353
|
+
REGISTRY.set(id, { rect, expiresAt: at + SHARED_LAYOUT_TTL_MS, styles });
|
|
138
354
|
}
|
|
139
355
|
function consumeLayout(id) {
|
|
140
356
|
const entry = REGISTRY.get(id);
|
|
141
357
|
if (!entry) return void 0;
|
|
142
358
|
REGISTRY.delete(id);
|
|
143
359
|
if (entry.expiresAt < now()) return void 0;
|
|
144
|
-
return
|
|
360
|
+
return {
|
|
361
|
+
rect: entry.rect,
|
|
362
|
+
remeasure: entry.remeasure,
|
|
363
|
+
styles: entry.styles,
|
|
364
|
+
readStyles: entry.readStyles
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
// src/layout/measureWindow.ts
|
|
369
|
+
var defaultMeasurer = (node) => {
|
|
370
|
+
const measure = node?.measureInWindow;
|
|
371
|
+
if (typeof measure !== "function") return void 0;
|
|
372
|
+
let result;
|
|
373
|
+
let returned = false;
|
|
374
|
+
try {
|
|
375
|
+
measure.call(node, (x, y, width, height) => {
|
|
376
|
+
if (returned) return;
|
|
377
|
+
result = { x, y, width, height };
|
|
378
|
+
});
|
|
379
|
+
} catch {
|
|
380
|
+
returned = true;
|
|
381
|
+
return void 0;
|
|
382
|
+
}
|
|
383
|
+
returned = true;
|
|
384
|
+
return result;
|
|
385
|
+
};
|
|
386
|
+
var measurer = defaultMeasurer;
|
|
387
|
+
function usable(rect) {
|
|
388
|
+
const { x, y, width, height } = rect;
|
|
389
|
+
for (const v of [x, y, width, height]) {
|
|
390
|
+
if (typeof v !== "number" || !Number.isFinite(v)) return false;
|
|
391
|
+
}
|
|
392
|
+
return width !== 0 || height !== 0;
|
|
393
|
+
}
|
|
394
|
+
function measureWindowRect(node) {
|
|
395
|
+
const measured = measurer(node);
|
|
396
|
+
if (!measured || !usable(measured)) return void 0;
|
|
397
|
+
return toSharedRect(measured, "window");
|
|
398
|
+
}
|
|
399
|
+
function toSharedRect(rect, space) {
|
|
400
|
+
return { ...rect, space };
|
|
145
401
|
}
|
|
146
402
|
function useSharedLayout(options) {
|
|
147
|
-
const {
|
|
403
|
+
const {
|
|
404
|
+
layoutId,
|
|
405
|
+
userRef,
|
|
406
|
+
transition,
|
|
407
|
+
shouldReduceMotion,
|
|
408
|
+
userOnLayout,
|
|
409
|
+
readStyles
|
|
410
|
+
} = options;
|
|
148
411
|
const dx = Animated.useSharedValue(0);
|
|
149
412
|
const dy = Animated.useSharedValue(0);
|
|
150
413
|
const sx = Animated.useSharedValue(1);
|
|
151
414
|
const sy = Animated.useSharedValue(1);
|
|
415
|
+
const snapshot = Animated.useSharedValue(null);
|
|
416
|
+
const carryProgress = Animated.useSharedValue(0);
|
|
152
417
|
const lastRectRef = react.useRef(null);
|
|
153
418
|
const consumedRef = react.useRef(false);
|
|
419
|
+
const nodeRef = react.useRef(null);
|
|
154
420
|
const transitionRef = react.useRef(transition);
|
|
155
421
|
transitionRef.current = transition;
|
|
156
422
|
const reducedMotionRef = react.useRef(shouldReduceMotion);
|
|
157
423
|
reducedMotionRef.current = shouldReduceMotion;
|
|
424
|
+
const readStylesRef = react.useRef(readStyles);
|
|
425
|
+
readStylesRef.current = readStyles;
|
|
158
426
|
const setRef = react.useCallback(
|
|
159
427
|
(node) => {
|
|
428
|
+
nodeRef.current = node;
|
|
160
429
|
if (typeof userRef === "function") userRef(node);
|
|
161
430
|
else if (userRef) userRef.current = node;
|
|
162
431
|
},
|
|
163
432
|
[userRef]
|
|
164
433
|
);
|
|
434
|
+
const remeasure = react.useCallback(() => measureWindowRect(nodeRef.current), []);
|
|
435
|
+
const snapshotStyles = react.useCallback(() => readStylesRef.current?.(), []);
|
|
436
|
+
const startTransition = react.useCallback(
|
|
437
|
+
(source, sourceRect, target) => {
|
|
438
|
+
if (sourceRect.space !== target.space) return;
|
|
439
|
+
const shared = {
|
|
440
|
+
transition: transitionRef.current,
|
|
441
|
+
shouldReduceMotion: reducedMotionRef.current
|
|
442
|
+
};
|
|
443
|
+
applyFlip({ source: sourceRect, target, dx, dy, sx, sy, ...shared });
|
|
444
|
+
applyStyleCarry({
|
|
445
|
+
snapshot,
|
|
446
|
+
progress: carryProgress,
|
|
447
|
+
// Prefer a live read for the same reason the rect is re-measured: a
|
|
448
|
+
// still-mounted source may have moved on since its last layout.
|
|
449
|
+
styles: source.readStyles?.() ?? source.styles,
|
|
450
|
+
...shared
|
|
451
|
+
});
|
|
452
|
+
},
|
|
453
|
+
[dx, dy, sx, sy, snapshot, carryProgress]
|
|
454
|
+
);
|
|
165
455
|
const onLayout = react.useCallback(
|
|
166
456
|
(event) => {
|
|
167
457
|
userOnLayout?.(event);
|
|
168
458
|
if (!layoutId) return;
|
|
169
459
|
const { x, y, width, height } = event.nativeEvent.layout;
|
|
170
|
-
const rect = { x, y, width, height };
|
|
171
|
-
lastRectRef.current = rect;
|
|
172
460
|
let source;
|
|
173
461
|
if (!consumedRef.current) {
|
|
174
462
|
consumedRef.current = true;
|
|
175
463
|
source = consumeLayout(layoutId);
|
|
176
464
|
}
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
dx,
|
|
183
|
-
dy,
|
|
184
|
-
sx,
|
|
185
|
-
sy,
|
|
186
|
-
transition: transitionRef.current,
|
|
187
|
-
shouldReduceMotion: reducedMotionRef.current
|
|
188
|
-
});
|
|
189
|
-
}
|
|
465
|
+
const rect = measureWindowRect(nodeRef.current) ?? { x, y, width, height, space: "parent" };
|
|
466
|
+
lastRectRef.current = rect;
|
|
467
|
+
registerLayout(layoutId, rect, remeasure, snapshotStyles);
|
|
468
|
+
if (!source) return;
|
|
469
|
+
startTransition(source, source.remeasure?.() ?? source.rect, rect);
|
|
190
470
|
},
|
|
191
|
-
|
|
192
|
-
// exhaustive-deps would flag them — including them is harmless and
|
|
193
|
-
// silences the warning.
|
|
194
|
-
[layoutId, userOnLayout, dx, dy, sx, sy]
|
|
471
|
+
[layoutId, userOnLayout, remeasure, snapshotStyles, startTransition]
|
|
195
472
|
);
|
|
196
473
|
react.useEffect(() => {
|
|
197
474
|
consumedRef.current = false;
|
|
@@ -201,18 +478,49 @@ function useSharedLayout(options) {
|
|
|
201
478
|
if (!layoutId) return;
|
|
202
479
|
const rect = lastRectRef.current;
|
|
203
480
|
if (!rect) return;
|
|
204
|
-
releaseLayout(layoutId, rect);
|
|
481
|
+
releaseLayout(layoutId, rect, snapshotStyles());
|
|
205
482
|
};
|
|
206
|
-
}, [layoutId]);
|
|
483
|
+
}, [layoutId, snapshotStyles]);
|
|
484
|
+
react.useEffect(
|
|
485
|
+
() => () => {
|
|
486
|
+
Animated.cancelAnimation(dx);
|
|
487
|
+
Animated.cancelAnimation(dy);
|
|
488
|
+
Animated.cancelAnimation(sx);
|
|
489
|
+
Animated.cancelAnimation(sy);
|
|
490
|
+
Animated.cancelAnimation(carryProgress);
|
|
491
|
+
},
|
|
492
|
+
// The FLIP shared values are identity-stable per hook instance.
|
|
493
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
494
|
+
[]
|
|
495
|
+
);
|
|
207
496
|
return react.useMemo(
|
|
208
497
|
() => ({
|
|
209
498
|
flip: { dx, dy, sx, sy },
|
|
499
|
+
carry: { snapshot, progress: carryProgress },
|
|
210
500
|
setRef,
|
|
211
501
|
onLayout
|
|
212
502
|
}),
|
|
213
|
-
[dx, dy, sx, sy, setRef, onLayout]
|
|
503
|
+
[dx, dy, sx, sy, snapshot, carryProgress, setRef, onLayout]
|
|
504
|
+
);
|
|
505
|
+
}
|
|
506
|
+
function legBuilder(transition) {
|
|
507
|
+
if (transition?.type === "timing") {
|
|
508
|
+
const duration = transition.duration ?? 300;
|
|
509
|
+
return (from, to) => Animated.withSequence(
|
|
510
|
+
Animated.withTiming(from, { duration: 0 }),
|
|
511
|
+
Animated.withTiming(to, { duration })
|
|
512
|
+
);
|
|
513
|
+
}
|
|
514
|
+
const springCfg = transition?.type === "spring" ? { ...chunk7A6WTXNK_js.DEFAULT_SPRING, ...transition } : { type: "spring", ...chunk7A6WTXNK_js.DEFAULT_SPRING };
|
|
515
|
+
const springParams = chunk7A6WTXNK_js.springToReanimated(springCfg);
|
|
516
|
+
return (from, to) => Animated.withSequence(
|
|
517
|
+
Animated.withTiming(from, { duration: 0 }),
|
|
518
|
+
Animated.withSpring(to, springParams)
|
|
214
519
|
);
|
|
215
520
|
}
|
|
521
|
+
function shouldSnap(transition, shouldReduceMotion) {
|
|
522
|
+
return shouldReduceMotion || transition?.type === "no-animation";
|
|
523
|
+
}
|
|
216
524
|
function applyFlip(args) {
|
|
217
525
|
const { source, target, dx, dy, sx, sy, transition, shouldReduceMotion } = args;
|
|
218
526
|
const sourceCenterX = source.x + source.width / 2;
|
|
@@ -223,58 +531,29 @@ function applyFlip(args) {
|
|
|
223
531
|
const deltaY = sourceCenterY - targetCenterY;
|
|
224
532
|
const scaleX = target.width > 0 ? source.width / target.width : 1;
|
|
225
533
|
const scaleY = target.height > 0 ? source.height / target.height : 1;
|
|
226
|
-
if (shouldReduceMotion) {
|
|
534
|
+
if (shouldSnap(transition, shouldReduceMotion)) {
|
|
227
535
|
dx.value = 0;
|
|
228
536
|
dy.value = 0;
|
|
229
537
|
sx.value = 1;
|
|
230
538
|
sy.value = 1;
|
|
231
539
|
return;
|
|
232
540
|
}
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
);
|
|
246
|
-
dy.value = Animated.withSequence(
|
|
247
|
-
Animated.withTiming(deltaY, { duration: 0 }),
|
|
248
|
-
Animated.withTiming(0, { duration })
|
|
249
|
-
);
|
|
250
|
-
sx.value = Animated.withSequence(
|
|
251
|
-
Animated.withTiming(scaleX, { duration: 0 }),
|
|
252
|
-
Animated.withTiming(1, { duration })
|
|
253
|
-
);
|
|
254
|
-
sy.value = Animated.withSequence(
|
|
255
|
-
Animated.withTiming(scaleY, { duration: 0 }),
|
|
256
|
-
Animated.withTiming(1, { duration })
|
|
257
|
-
);
|
|
541
|
+
const leg = legBuilder(transition);
|
|
542
|
+
dx.value = leg(deltaX, 0);
|
|
543
|
+
dy.value = leg(deltaY, 0);
|
|
544
|
+
sx.value = leg(scaleX, 1);
|
|
545
|
+
sy.value = leg(scaleY, 1);
|
|
546
|
+
}
|
|
547
|
+
function applyStyleCarry(args) {
|
|
548
|
+
const { snapshot, progress, styles, transition, shouldReduceMotion } = args;
|
|
549
|
+
if (!styles) return;
|
|
550
|
+
if (shouldSnap(transition, shouldReduceMotion)) {
|
|
551
|
+
snapshot.value = null;
|
|
552
|
+
progress.value = 0;
|
|
258
553
|
return;
|
|
259
554
|
}
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
dx.value = Animated.withSequence(
|
|
263
|
-
Animated.withTiming(deltaX, { duration: 0 }),
|
|
264
|
-
Animated.withSpring(0, springParams)
|
|
265
|
-
);
|
|
266
|
-
dy.value = Animated.withSequence(
|
|
267
|
-
Animated.withTiming(deltaY, { duration: 0 }),
|
|
268
|
-
Animated.withSpring(0, springParams)
|
|
269
|
-
);
|
|
270
|
-
sx.value = Animated.withSequence(
|
|
271
|
-
Animated.withTiming(scaleX, { duration: 0 }),
|
|
272
|
-
Animated.withSpring(1, springParams)
|
|
273
|
-
);
|
|
274
|
-
sy.value = Animated.withSequence(
|
|
275
|
-
Animated.withTiming(scaleY, { duration: 0 }),
|
|
276
|
-
Animated.withSpring(1, springParams)
|
|
277
|
-
);
|
|
555
|
+
snapshot.value = styles;
|
|
556
|
+
progress.value = legBuilder(transition)(1, 0);
|
|
278
557
|
}
|
|
279
558
|
var alreadyChecked = false;
|
|
280
559
|
function ensureReanimatedInstalled() {
|
|
@@ -288,7 +567,7 @@ function ensureReanimatedInstalled() {
|
|
|
288
567
|
const major = parseInt(version.split(".")[0] ?? "0", 10);
|
|
289
568
|
if (major < 4) {
|
|
290
569
|
console.error(
|
|
291
|
-
`[inertia] react-native-reanimated
|
|
570
|
+
`[inertia] react-native-reanimated ${version} is installed, but @rootnative/inertia requires 4.0.0 or later. Upgrade with \`pnpm add react-native-reanimated@^4\` (or your package manager's equivalent).`
|
|
292
571
|
);
|
|
293
572
|
return;
|
|
294
573
|
}
|
|
@@ -331,15 +610,28 @@ var COLOR_KEYS = [
|
|
|
331
610
|
"shadowColor"
|
|
332
611
|
];
|
|
333
612
|
var SHADOW_OFFSET_KEYS = ["shadowOffsetWidth", "shadowOffsetHeight"];
|
|
613
|
+
var STRUCTURED_KEYS = ["boxShadow"];
|
|
614
|
+
var SHARED_STYLE_KEYS = [
|
|
615
|
+
"opacity",
|
|
616
|
+
"borderRadius",
|
|
617
|
+
"backgroundColor",
|
|
618
|
+
"borderColor",
|
|
619
|
+
"color",
|
|
620
|
+
"tintColor"
|
|
621
|
+
];
|
|
334
622
|
var ALL_KEYS = [
|
|
335
623
|
...TRANSFORM_KEYS,
|
|
336
624
|
...NUMERIC_TOP_LEVEL_KEYS,
|
|
337
625
|
...COLOR_KEYS,
|
|
338
|
-
...SHADOW_OFFSET_KEYS
|
|
626
|
+
...SHADOW_OFFSET_KEYS,
|
|
627
|
+
...STRUCTURED_KEYS
|
|
339
628
|
];
|
|
340
629
|
var TRANSFORM_KEY_SET = new Set(TRANSFORM_KEYS);
|
|
341
630
|
var COLOR_KEY_SET = new Set(COLOR_KEYS);
|
|
342
631
|
var SHADOW_OFFSET_KEY_SET = new Set(SHADOW_OFFSET_KEYS);
|
|
632
|
+
var STRUCTURED_KEY_SET = new Set(STRUCTURED_KEYS);
|
|
633
|
+
var SHARED_STYLE_KEY_SET = new Set(SHARED_STYLE_KEYS);
|
|
634
|
+
var NO_BOX_SHADOW = Object.freeze([]);
|
|
343
635
|
var GESTURE_LAYER_NAMES = [
|
|
344
636
|
"hovered",
|
|
345
637
|
"focused",
|
|
@@ -374,19 +666,20 @@ var DEFAULT_RESTING = {
|
|
|
374
666
|
tintColor: "transparent",
|
|
375
667
|
shadowColor: "transparent",
|
|
376
668
|
shadowOffsetWidth: 0,
|
|
377
|
-
shadowOffsetHeight: 0
|
|
669
|
+
shadowOffsetHeight: 0,
|
|
670
|
+
boxShadow: NO_BOX_SHADOW
|
|
378
671
|
};
|
|
379
672
|
function transitionFor(prop, transition) {
|
|
380
673
|
if (!transition) return void 0;
|
|
381
674
|
if (typeof transition === "string") return void 0;
|
|
382
|
-
if (
|
|
675
|
+
if (chunk7A6WTXNK_js.isTopLevelTransition(transition)) return transition;
|
|
383
676
|
if (GESTURE_LAYER_NAME_SET.has(prop)) return void 0;
|
|
384
677
|
return transition[prop];
|
|
385
678
|
}
|
|
386
679
|
function gestureLayerTransitionFor(layer, transition) {
|
|
387
680
|
if (!transition) return void 0;
|
|
388
681
|
if (typeof transition === "string") return void 0;
|
|
389
|
-
if (
|
|
682
|
+
if (chunk7A6WTXNK_js.isTopLevelTransition(transition)) return transition;
|
|
390
683
|
return transition[layer];
|
|
391
684
|
}
|
|
392
685
|
function createMotionComponent(Component) {
|
|
@@ -436,12 +729,12 @@ function createMotionComponent(Component) {
|
|
|
436
729
|
onLayout: userOnLayout,
|
|
437
730
|
...rest
|
|
438
731
|
} = props;
|
|
439
|
-
const namedTransitions =
|
|
440
|
-
const transition =
|
|
732
|
+
const namedTransitions = chunkWVRCKOPO_js.useNamedTransitions();
|
|
733
|
+
const transition = chunkWVRCKOPO_js.resolveNamedTransitionProp(
|
|
441
734
|
transitionProp,
|
|
442
735
|
namedTransitions
|
|
443
736
|
);
|
|
444
|
-
const layout = typeof layoutProp === "string" ?
|
|
737
|
+
const layout = typeof layoutProp === "string" ? chunkWVRCKOPO_js.lookupNamedTransition(layoutProp, namedTransitions) : layoutProp;
|
|
445
738
|
if (__DEV__ && typeof style === "function") {
|
|
446
739
|
throw new Error(
|
|
447
740
|
"[inertia] `style` must be a style object or array of style objects, not a function. The function-form `style={(state) => ...}` Pressable API is not supported \u2014 use `gesture.pressed` (or `gesture.focused`, etc.) to drive state-dependent styling instead."
|
|
@@ -449,7 +742,7 @@ function createMotionComponent(Component) {
|
|
|
449
742
|
}
|
|
450
743
|
const presence = usePresence();
|
|
451
744
|
const isExiting = presence !== null && presence.isPresent === false;
|
|
452
|
-
const shouldReduceMotion =
|
|
745
|
+
const shouldReduceMotion = chunkWVRCKOPO_js.useShouldReduceMotion();
|
|
453
746
|
const onAnimationEndRef = react.useRef(onAnimationEnd);
|
|
454
747
|
onAnimationEndRef.current = onAnimationEnd;
|
|
455
748
|
const variantKey = useControllerKey(controller);
|
|
@@ -465,6 +758,16 @@ function createMotionComponent(Component) {
|
|
|
465
758
|
const [focused, setFocused] = react.useState(false);
|
|
466
759
|
const [focusVisible, setFocusVisible] = react.useState(false);
|
|
467
760
|
const [hovered, setHovered] = react.useState(false);
|
|
761
|
+
const hasLayoutId = layoutId !== void 0;
|
|
762
|
+
let flatStyle;
|
|
763
|
+
let flatStyleRead = false;
|
|
764
|
+
const getFlatStyle = () => {
|
|
765
|
+
if (!flatStyleRead) {
|
|
766
|
+
flatStyleRead = true;
|
|
767
|
+
flatStyle = reactNative.StyleSheet.flatten(style);
|
|
768
|
+
}
|
|
769
|
+
return flatStyle;
|
|
770
|
+
};
|
|
468
771
|
const touched = /* @__PURE__ */ new Set();
|
|
469
772
|
collectTouchedKeys(touched, animateRecord);
|
|
470
773
|
if (initialRecord) collectTouchedKeys(touched, initialRecord);
|
|
@@ -486,9 +789,19 @@ function createMotionComponent(Component) {
|
|
|
486
789
|
}
|
|
487
790
|
}
|
|
488
791
|
if (exitRecord) collectTouchedKeys(touched, exitRecord);
|
|
792
|
+
if (hasLayoutId) {
|
|
793
|
+
const flat = getFlatStyle();
|
|
794
|
+
if (flat) {
|
|
795
|
+
for (const key of SHARED_STYLE_KEYS) {
|
|
796
|
+
if (touched.has(key)) continue;
|
|
797
|
+
if (styleValueFor(flat, key) !== void 0) touched.add(key);
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
}
|
|
489
801
|
const activeKeysRef = react.useRef(null);
|
|
490
802
|
const hasTransformRef = react.useRef(false);
|
|
491
803
|
const hasShadowOffsetRef = react.useRef(false);
|
|
804
|
+
const hasBoxShadowRef = react.useRef(false);
|
|
492
805
|
const prevActive = activeKeysRef.current;
|
|
493
806
|
let grew = prevActive === null;
|
|
494
807
|
if (!grew && prevActive) {
|
|
@@ -509,24 +822,83 @@ function createMotionComponent(Component) {
|
|
|
509
822
|
hasShadowOffsetRef.current = activeKeysRef.current.some(
|
|
510
823
|
(k) => SHADOW_OFFSET_KEY_SET.has(k)
|
|
511
824
|
);
|
|
825
|
+
hasBoxShadowRef.current = activeKeysRef.current.includes("boxShadow");
|
|
826
|
+
if (__DEV__ && hasBoxShadowRef.current && activeKeysRef.current.some(
|
|
827
|
+
(k) => k !== "boxShadow" && k.startsWith("shadow")
|
|
828
|
+
)) {
|
|
829
|
+
chunk7A6WTXNK_js.warnOnce(
|
|
830
|
+
"boxShadow-with-native-shadow",
|
|
831
|
+
"[inertia] `boxShadow` is animated alongside the native `shadow*` keys on the same element, which applies two shadow systems at once. Pick one: `boxShadow` for the cross-platform CSS form, or the native `shadow*` keys."
|
|
832
|
+
);
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
const drivenNow = /* @__PURE__ */ new Set();
|
|
836
|
+
collectTouchedKeys(drivenNow, animateRecord);
|
|
837
|
+
if (initialRecord) collectTouchedKeys(drivenNow, initialRecord);
|
|
838
|
+
if (isExiting && exitRecord) collectTouchedKeys(drivenNow, exitRecord);
|
|
839
|
+
const everDrivenRef = react.useRef(/* @__PURE__ */ new Set());
|
|
840
|
+
for (const k of drivenNow) everDrivenRef.current.add(k);
|
|
841
|
+
const activeKeys = activeKeysRef.current;
|
|
842
|
+
const everDriven = everDrivenRef.current;
|
|
843
|
+
const styleResting = {};
|
|
844
|
+
let styleRestingShadow = null;
|
|
845
|
+
if (activeKeys.some((k) => !everDriven.has(k))) {
|
|
846
|
+
const flat = getFlatStyle();
|
|
847
|
+
if (flat) {
|
|
848
|
+
for (const key of activeKeys) {
|
|
849
|
+
if (everDriven.has(key)) continue;
|
|
850
|
+
if (key === "boxShadow") {
|
|
851
|
+
const raw = flat.boxShadow;
|
|
852
|
+
if (raw !== void 0) {
|
|
853
|
+
styleRestingShadow = normalizeBoxShadow(raw);
|
|
854
|
+
styleResting.boxShadow = styleRestingShadow.layers;
|
|
855
|
+
}
|
|
856
|
+
continue;
|
|
857
|
+
}
|
|
858
|
+
const v = styleValueFor(flat, key);
|
|
859
|
+
if (v !== void 0) styleResting[key] = v;
|
|
860
|
+
}
|
|
861
|
+
}
|
|
862
|
+
}
|
|
863
|
+
const boxShadowSeedRef = react.useRef(null);
|
|
864
|
+
if (boxShadowSeedRef.current === null) {
|
|
865
|
+
const source = initial === false ? animateRecord.boxShadow : initialRecord?.boxShadow ?? animateRecord.boxShadow;
|
|
866
|
+
boxShadowSeedRef.current = source !== void 0 ? normalizeBoxShadow(source) : styleRestingShadow ?? {
|
|
867
|
+
layers: [...NO_BOX_SHADOW],
|
|
868
|
+
insets: null
|
|
869
|
+
};
|
|
512
870
|
}
|
|
513
871
|
const sharedValues = useAnimatableSharedValues((key) => {
|
|
872
|
+
if (key === "boxShadow") return boxShadowSeedRef.current.layers;
|
|
514
873
|
if (SHADOW_OFFSET_KEY_SET.has(key)) {
|
|
515
874
|
const axis = shadowOffsetAxisFor(key);
|
|
516
875
|
if (initial === false) {
|
|
517
|
-
return shadowOffsetAxisValue(animateRecord.shadowOffset, axis) ?? DEFAULT_RESTING[key];
|
|
876
|
+
return shadowOffsetAxisValue(animateRecord.shadowOffset, axis) ?? styleResting[key] ?? DEFAULT_RESTING[key];
|
|
518
877
|
}
|
|
519
878
|
return shadowOffsetAxisValue(
|
|
520
879
|
initialRecord?.shadowOffset,
|
|
521
880
|
axis
|
|
522
|
-
) ?? shadowOffsetAxisValue(animateRecord.shadowOffset, axis) ?? DEFAULT_RESTING[key];
|
|
881
|
+
) ?? shadowOffsetAxisValue(animateRecord.shadowOffset, axis) ?? styleResting[key] ?? DEFAULT_RESTING[key];
|
|
523
882
|
}
|
|
524
883
|
if (initial === false) {
|
|
525
884
|
const a = animateRecord[key];
|
|
526
|
-
return restValue(a) ?? DEFAULT_RESTING[key];
|
|
885
|
+
return restValue(a) ?? styleResting[key] ?? DEFAULT_RESTING[key];
|
|
527
886
|
}
|
|
528
|
-
return initialRecord?.[key] ?? restValue(animateRecord[key]) ?? DEFAULT_RESTING[key];
|
|
887
|
+
return initialRecord?.[key] ?? restValue(animateRecord[key]) ?? styleResting[key] ?? DEFAULT_RESTING[key];
|
|
529
888
|
});
|
|
889
|
+
const boxShadowInsets = Animated.useSharedValue(
|
|
890
|
+
boxShadowSeedRef.current.insets
|
|
891
|
+
);
|
|
892
|
+
const styleRestingSig = chunk7A6WTXNK_js.stableSig(styleResting);
|
|
893
|
+
react.useEffect(() => {
|
|
894
|
+
for (const key of activeKeysRef.current) {
|
|
895
|
+
if (everDrivenRef.current.has(key)) continue;
|
|
896
|
+
sharedValues[key].value = styleResting[key] ?? DEFAULT_RESTING[key];
|
|
897
|
+
if (key === "boxShadow") {
|
|
898
|
+
boxShadowInsets.value = styleRestingShadow?.insets ?? null;
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
}, [styleRestingSig]);
|
|
530
902
|
const pressedProgress = Animated.useSharedValue(0);
|
|
531
903
|
const focusedProgress = Animated.useSharedValue(0);
|
|
532
904
|
const focusVisibleProgress = Animated.useSharedValue(0);
|
|
@@ -545,13 +917,13 @@ function createMotionComponent(Component) {
|
|
|
545
917
|
const gestureSV = Animated.useSharedValue(
|
|
546
918
|
resolveGestureLayers(gesture)
|
|
547
919
|
);
|
|
548
|
-
const gestureTargetsSig =
|
|
920
|
+
const gestureTargetsSig = chunk7A6WTXNK_js.stableSig(gesture);
|
|
549
921
|
react.useEffect(() => {
|
|
550
922
|
gestureSV.value = resolveGestureLayers(gesture);
|
|
551
923
|
}, [gestureTargetsSig]);
|
|
552
924
|
const baseRecord = isExiting && exitRecord ? { ...animateRecord, ...exitRecord } : animateRecord;
|
|
553
|
-
const baseSig =
|
|
554
|
-
const transitionSig =
|
|
925
|
+
const baseSig = chunk7A6WTXNK_js.stableSig(baseRecord) + (isExiting ? "|exit" : "") + (shouldReduceMotion ? "|rm" : "");
|
|
926
|
+
const transitionSig = chunk7A6WTXNK_js.stableSig(transition);
|
|
555
927
|
const safeToRemoveRef = react.useRef(void 0);
|
|
556
928
|
safeToRemoveRef.current = presence?.safeToRemove;
|
|
557
929
|
react.useEffect(() => {
|
|
@@ -569,24 +941,49 @@ function createMotionComponent(Component) {
|
|
|
569
941
|
if (isExiting) safeToRemoveRef.current?.();
|
|
570
942
|
}
|
|
571
943
|
};
|
|
944
|
+
const configFor = (key) => shouldReduceMotion ? { type: "no-animation" } : transitionFor(
|
|
945
|
+
SHADOW_OFFSET_KEY_SET.has(key) ? "shadowOffset" : key,
|
|
946
|
+
transition
|
|
947
|
+
);
|
|
572
948
|
let transformPending = 0;
|
|
573
949
|
for (const k of ALL_KEYS) {
|
|
574
|
-
if (TRANSFORM_KEY_SET.has(k)
|
|
575
|
-
|
|
576
|
-
|
|
950
|
+
if (!TRANSFORM_KEY_SET.has(k) || baseRecord[k] === void 0) continue;
|
|
951
|
+
if (!reachesTerminalPhase(configFor(k))) continue;
|
|
952
|
+
transformPending++;
|
|
577
953
|
}
|
|
578
954
|
const transformGroup = transformPending > 0 ? { remaining: transformPending } : void 0;
|
|
579
955
|
for (const key of ALL_KEYS) {
|
|
956
|
+
if (key === "boxShadow") {
|
|
957
|
+
const shadowTarget = baseRecord.boxShadow;
|
|
958
|
+
if (shadowTarget === void 0) continue;
|
|
959
|
+
const cfg2 = configFor("boxShadow");
|
|
960
|
+
if (isExiting && reachesTerminalPhase(cfg2)) pending++;
|
|
961
|
+
driveBoxShadow(
|
|
962
|
+
sharedValues.boxShadow,
|
|
963
|
+
boxShadowInsets,
|
|
964
|
+
shadowTarget,
|
|
965
|
+
cfg2,
|
|
966
|
+
makeKeyCallbackFactory(
|
|
967
|
+
"boxShadow",
|
|
968
|
+
sharedValues.boxShadow,
|
|
969
|
+
// The declared target, not the padded one — the padding is an
|
|
970
|
+
// implementation detail of getting Reanimated to interpolate.
|
|
971
|
+
shadowTarget,
|
|
972
|
+
onAnimationEndRef,
|
|
973
|
+
{ stepCount: 1, totalIterations: totalIterationsOf(cfg2) },
|
|
974
|
+
isExiting ? onSettle : void 0,
|
|
975
|
+
void 0
|
|
976
|
+
)
|
|
977
|
+
);
|
|
978
|
+
continue;
|
|
979
|
+
}
|
|
580
980
|
const target = SHADOW_OFFSET_KEY_SET.has(key) ? shadowOffsetAxisValue(
|
|
581
981
|
baseRecord.shadowOffset,
|
|
582
982
|
shadowOffsetAxisFor(key)
|
|
583
983
|
) : baseRecord[key];
|
|
584
984
|
if (target === void 0) continue;
|
|
585
|
-
const cfg =
|
|
586
|
-
|
|
587
|
-
transition
|
|
588
|
-
);
|
|
589
|
-
if (isExiting) pending++;
|
|
985
|
+
const cfg = configFor(key);
|
|
986
|
+
if (isExiting && reachesTerminalPhase(cfg)) pending++;
|
|
590
987
|
const factory = makeKeyCallbackFactory(
|
|
591
988
|
key,
|
|
592
989
|
sharedValues[key],
|
|
@@ -599,7 +996,7 @@ function createMotionComponent(Component) {
|
|
|
599
996
|
isExiting ? onSettle : void 0,
|
|
600
997
|
TRANSFORM_KEY_SET.has(key) ? transformGroup : void 0
|
|
601
998
|
);
|
|
602
|
-
sharedValues[key].value =
|
|
999
|
+
sharedValues[key].value = chunk7A6WTXNK_js.resolveAnimatableValue(
|
|
603
1000
|
target,
|
|
604
1001
|
cfg,
|
|
605
1002
|
factory
|
|
@@ -645,19 +1042,34 @@ function createMotionComponent(Component) {
|
|
|
645
1042
|
isExiting,
|
|
646
1043
|
shouldReduceMotion
|
|
647
1044
|
);
|
|
1045
|
+
const readSharedStyles = () => {
|
|
1046
|
+
if (!hasLayoutId) return void 0;
|
|
1047
|
+
const out = {};
|
|
1048
|
+
let any = false;
|
|
1049
|
+
for (const key of activeKeysRef.current) {
|
|
1050
|
+
if (!SHARED_STYLE_KEY_SET.has(key)) continue;
|
|
1051
|
+
const v = sharedValues[key].value;
|
|
1052
|
+
if (typeof v !== "number" && typeof v !== "string") continue;
|
|
1053
|
+
out[key] = v;
|
|
1054
|
+
any = true;
|
|
1055
|
+
}
|
|
1056
|
+
return any ? out : void 0;
|
|
1057
|
+
};
|
|
648
1058
|
const sharedLayout = useSharedLayout({
|
|
649
1059
|
layoutId,
|
|
650
1060
|
userRef: ref,
|
|
651
|
-
transition:
|
|
1061
|
+
transition: chunk7A6WTXNK_js.isTopLevelTransition(transition) ? transition : void 0,
|
|
652
1062
|
shouldReduceMotion,
|
|
653
|
-
userOnLayout
|
|
1063
|
+
userOnLayout,
|
|
1064
|
+
readStyles: readSharedStyles
|
|
654
1065
|
});
|
|
655
1066
|
const flip = sharedLayout.flip;
|
|
656
|
-
const
|
|
1067
|
+
const carry = sharedLayout.carry;
|
|
657
1068
|
const animatedStyle = Animated.useAnimatedStyle(() => {
|
|
658
|
-
const
|
|
1069
|
+
const activeKeys2 = activeKeysRef.current;
|
|
659
1070
|
const hasTransform = hasTransformRef.current;
|
|
660
1071
|
const hasShadowOffset = hasShadowOffsetRef.current;
|
|
1072
|
+
const hasBoxShadow = hasBoxShadowRef.current;
|
|
661
1073
|
const out = {};
|
|
662
1074
|
const transform = [];
|
|
663
1075
|
let shadowOffsetW = 0;
|
|
@@ -666,12 +1078,15 @@ function createMotionComponent(Component) {
|
|
|
666
1078
|
const pf = focusedProgress.value;
|
|
667
1079
|
const pfv = focusVisibleProgress.value;
|
|
668
1080
|
const pp = pressedProgress.value;
|
|
1081
|
+
const carried = carry.snapshot.value;
|
|
1082
|
+
const pc = carry.progress.value;
|
|
669
1083
|
const layers = gestureSV.value;
|
|
670
1084
|
const hoveredLayer = layers ? layers.hovered : null;
|
|
671
1085
|
const focusedLayer = layers ? layers.focused : null;
|
|
672
1086
|
const focusVisibleLayer = layers ? layers.focusVisible : null;
|
|
673
1087
|
const pressedLayer = layers ? layers.pressed : null;
|
|
674
|
-
for (const key of
|
|
1088
|
+
for (const key of activeKeys2) {
|
|
1089
|
+
if (key === "boxShadow") continue;
|
|
675
1090
|
let v = sharedValues[key].value;
|
|
676
1091
|
const isColor = COLOR_KEY_SET.has(key);
|
|
677
1092
|
if (hoveredLayer && ph > 0 && hoveredLayer[key] !== void 0) {
|
|
@@ -690,6 +1105,12 @@ function createMotionComponent(Component) {
|
|
|
690
1105
|
const t = pressedLayer[key];
|
|
691
1106
|
v = isColor ? Animated.interpolateColor(pp, [0, 1], [v, t]) : v + (t - v) * pp;
|
|
692
1107
|
}
|
|
1108
|
+
if (carried !== null && pc > 0) {
|
|
1109
|
+
const s = carried[key];
|
|
1110
|
+
if (s !== void 0) {
|
|
1111
|
+
v = isColor ? Animated.interpolateColor(pc, [0, 1], [v, s]) : v + (s - v) * pc;
|
|
1112
|
+
}
|
|
1113
|
+
}
|
|
693
1114
|
if (TRANSFORM_KEY_SET.has(key)) {
|
|
694
1115
|
transform.push(
|
|
695
1116
|
ROTATION_KEYS.has(key) ? { [key]: `${v}deg` } : { [key]: v }
|
|
@@ -712,6 +1133,19 @@ function createMotionComponent(Component) {
|
|
|
712
1133
|
if (hasShadowOffset) {
|
|
713
1134
|
out.shadowOffset = { width: shadowOffsetW, height: shadowOffsetH };
|
|
714
1135
|
}
|
|
1136
|
+
if (hasBoxShadow) {
|
|
1137
|
+
const layers2 = sharedValues.boxShadow.value;
|
|
1138
|
+
const insets = boxShadowInsets.value;
|
|
1139
|
+
if (insets === null) {
|
|
1140
|
+
out.boxShadow = layers2;
|
|
1141
|
+
} else {
|
|
1142
|
+
const withInset = [];
|
|
1143
|
+
for (let i = 0; i < layers2.length; i++) {
|
|
1144
|
+
withInset.push({ ...layers2[i], inset: insets[i] });
|
|
1145
|
+
}
|
|
1146
|
+
out.boxShadow = withInset;
|
|
1147
|
+
}
|
|
1148
|
+
}
|
|
715
1149
|
return out;
|
|
716
1150
|
});
|
|
717
1151
|
const mergedStyle = react.useMemo(
|
|
@@ -726,7 +1160,7 @@ function createMotionComponent(Component) {
|
|
|
726
1160
|
setFocusVisible,
|
|
727
1161
|
setHovered
|
|
728
1162
|
);
|
|
729
|
-
const layoutSig =
|
|
1163
|
+
const layoutSig = chunk7A6WTXNK_js.stableSig(layout);
|
|
730
1164
|
const layoutTransition = react.useMemo(
|
|
731
1165
|
() => shouldReduceMotion ? void 0 : resolveLayoutTransition(layout),
|
|
732
1166
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
@@ -786,7 +1220,9 @@ function useAnimatableSharedValues(init) {
|
|
|
786
1220
|
const width = Animated.useSharedValue(init("width"));
|
|
787
1221
|
const height = Animated.useSharedValue(init("height"));
|
|
788
1222
|
const borderRadius = Animated.useSharedValue(init("borderRadius"));
|
|
789
|
-
const shadowOpacity = Animated.useSharedValue(
|
|
1223
|
+
const shadowOpacity = Animated.useSharedValue(
|
|
1224
|
+
init("shadowOpacity")
|
|
1225
|
+
);
|
|
790
1226
|
const shadowRadius = Animated.useSharedValue(init("shadowRadius"));
|
|
791
1227
|
const elevation = Animated.useSharedValue(init("elevation"));
|
|
792
1228
|
const backgroundColor = Animated.useSharedValue(
|
|
@@ -802,6 +1238,7 @@ function useAnimatableSharedValues(init) {
|
|
|
802
1238
|
const shadowOffsetHeight = Animated.useSharedValue(
|
|
803
1239
|
init("shadowOffsetHeight")
|
|
804
1240
|
);
|
|
1241
|
+
const boxShadow = Animated.useSharedValue(init("boxShadow"));
|
|
805
1242
|
const ref = react.useRef(null);
|
|
806
1243
|
if (ref.current === null) {
|
|
807
1244
|
ref.current = {
|
|
@@ -826,7 +1263,8 @@ function useAnimatableSharedValues(init) {
|
|
|
826
1263
|
tintColor,
|
|
827
1264
|
shadowColor,
|
|
828
1265
|
shadowOffsetWidth,
|
|
829
|
-
shadowOffsetHeight
|
|
1266
|
+
shadowOffsetHeight,
|
|
1267
|
+
boxShadow
|
|
830
1268
|
};
|
|
831
1269
|
}
|
|
832
1270
|
const map = ref.current;
|
|
@@ -911,6 +1349,54 @@ function shadowOffsetAxisFor(key) {
|
|
|
911
1349
|
function shadowOffsetAxisValue(source, axis) {
|
|
912
1350
|
return source?.[axis];
|
|
913
1351
|
}
|
|
1352
|
+
function driveBoxShadow(slot, insetSlot, target, cfg, factory) {
|
|
1353
|
+
const currentLayers = Array.isArray(slot.value) ? slot.value : NO_BOX_SHADOW;
|
|
1354
|
+
const { from, to, insets } = prepareBoxShadowAnimation(
|
|
1355
|
+
{ layers: [...currentLayers], insets: insetSlot.value },
|
|
1356
|
+
target
|
|
1357
|
+
);
|
|
1358
|
+
insetSlot.value = insets;
|
|
1359
|
+
if (from.length !== currentLayers.length) slot.value = from;
|
|
1360
|
+
slot.value = chunk7A6WTXNK_js.resolveTransition(
|
|
1361
|
+
cfg,
|
|
1362
|
+
to,
|
|
1363
|
+
factory?.("animation", void 0)
|
|
1364
|
+
);
|
|
1365
|
+
}
|
|
1366
|
+
function styleValueFor(flat, key) {
|
|
1367
|
+
if (SHADOW_OFFSET_KEY_SET.has(key)) {
|
|
1368
|
+
return shadowOffsetAxisValue(
|
|
1369
|
+
flat.shadowOffset,
|
|
1370
|
+
shadowOffsetAxisFor(key)
|
|
1371
|
+
);
|
|
1372
|
+
}
|
|
1373
|
+
if (TRANSFORM_KEY_SET.has(key)) {
|
|
1374
|
+
const list = flat.transform;
|
|
1375
|
+
if (!Array.isArray(list)) return void 0;
|
|
1376
|
+
for (const entry of list) {
|
|
1377
|
+
if (!entry || typeof entry !== "object") continue;
|
|
1378
|
+
const v2 = entry[key];
|
|
1379
|
+
if (v2 === void 0) continue;
|
|
1380
|
+
if (ROTATION_KEYS.has(key)) return parseAngleDegrees(v2);
|
|
1381
|
+
return typeof v2 === "number" ? v2 : void 0;
|
|
1382
|
+
}
|
|
1383
|
+
return void 0;
|
|
1384
|
+
}
|
|
1385
|
+
const v = flat[key];
|
|
1386
|
+
if (COLOR_KEY_SET.has(key)) {
|
|
1387
|
+
return typeof v === "string" || typeof v === "number" ? v : void 0;
|
|
1388
|
+
}
|
|
1389
|
+
return typeof v === "number" ? v : void 0;
|
|
1390
|
+
}
|
|
1391
|
+
function parseAngleDegrees(v) {
|
|
1392
|
+
if (typeof v === "number") return v;
|
|
1393
|
+
if (typeof v !== "string") return void 0;
|
|
1394
|
+
const deg = /^(-?\d*\.?\d+)deg$/.exec(v);
|
|
1395
|
+
if (deg) return Number(deg[1]);
|
|
1396
|
+
const rad = /^(-?\d*\.?\d+)rad$/.exec(v);
|
|
1397
|
+
if (rad) return Number(rad[1]) * 180 / Math.PI;
|
|
1398
|
+
return void 0;
|
|
1399
|
+
}
|
|
914
1400
|
function collectTouchedKeys(touched, record) {
|
|
915
1401
|
for (const k of ALL_KEYS) {
|
|
916
1402
|
if (k in record) touched.add(k);
|
|
@@ -934,6 +1420,9 @@ function totalIterationsOf(cfg) {
|
|
|
934
1420
|
if (r.count === "infinite") return Number.POSITIVE_INFINITY;
|
|
935
1421
|
return r.count;
|
|
936
1422
|
}
|
|
1423
|
+
function reachesTerminalPhase(cfg) {
|
|
1424
|
+
return Number.isFinite(totalIterationsOf(cfg));
|
|
1425
|
+
}
|
|
937
1426
|
function targetEndValue(v) {
|
|
938
1427
|
if (v === void 0) return void 0;
|
|
939
1428
|
if (typeof v === "number" || typeof v === "string") return v;
|
|
@@ -990,6 +1479,15 @@ function resolveGestureLayers(gesture) {
|
|
|
990
1479
|
if (!subState) continue;
|
|
991
1480
|
const resolved = {};
|
|
992
1481
|
for (const key of ALL_KEYS) {
|
|
1482
|
+
if (STRUCTURED_KEY_SET.has(key)) {
|
|
1483
|
+
if (__DEV__ && subState[key] !== void 0) {
|
|
1484
|
+
chunk7A6WTXNK_js.warnOnce(
|
|
1485
|
+
`gesture-structured-${layer}-${key}`,
|
|
1486
|
+
`[inertia] \`${key}\` is not supported inside \`gesture.${layer}\` and will be ignored. Drive it from \`animate\` (optionally via a variant keyed off the same state), or interpolate it yourself with \`useShadow\`.`
|
|
1487
|
+
);
|
|
1488
|
+
}
|
|
1489
|
+
continue;
|
|
1490
|
+
}
|
|
993
1491
|
if (SHADOW_OFFSET_KEY_SET.has(key)) {
|
|
994
1492
|
const axis = shadowOffsetAxisFor(key);
|
|
995
1493
|
const so = subState.shadowOffset;
|
|
@@ -1007,7 +1505,7 @@ function resolveGestureLayers(gesture) {
|
|
|
1007
1505
|
return out;
|
|
1008
1506
|
}
|
|
1009
1507
|
function useGestureLayerProgress(progress, active, declared, layer, transition, isExiting, shouldReduceMotion) {
|
|
1010
|
-
const layerCfgSig =
|
|
1508
|
+
const layerCfgSig = chunk7A6WTXNK_js.stableSig(gestureLayerTransitionFor(layer, transition));
|
|
1011
1509
|
react.useEffect(() => {
|
|
1012
1510
|
if (!declared) return;
|
|
1013
1511
|
if (isExiting) {
|
|
@@ -1016,7 +1514,7 @@ function useGestureLayerProgress(progress, active, declared, layer, transition,
|
|
|
1016
1514
|
}
|
|
1017
1515
|
const target = active ? 1 : 0;
|
|
1018
1516
|
const cfg = shouldReduceMotion ? { type: "no-animation" } : gestureLayerTransitionFor(layer, transition) ?? { type: "spring" };
|
|
1019
|
-
progress.value =
|
|
1517
|
+
progress.value = chunk7A6WTXNK_js.resolveTransition(cfg, target);
|
|
1020
1518
|
}, [active, declared, isExiting, shouldReduceMotion, layerCfgSig]);
|
|
1021
1519
|
}
|
|
1022
1520
|
function useGestureHandlers(gesture, rest, setPressed, setFocused, setFocusVisible, setHovered) {
|
|
@@ -1040,7 +1538,7 @@ function useGestureHandlers(gesture, rest, setPressed, setFocused, setFocusVisib
|
|
|
1040
1538
|
if (gesture.focused || gesture.focusVisible) {
|
|
1041
1539
|
handlers.onFocus = compose(rest.onFocus, () => {
|
|
1042
1540
|
if (gesture.focused) setFocused(true);
|
|
1043
|
-
if (gesture.focusVisible &&
|
|
1541
|
+
if (gesture.focusVisible && chunkWVRCKOPO_js.isFocusVisible()) setFocusVisible(true);
|
|
1044
1542
|
});
|
|
1045
1543
|
handlers.onBlur = compose(rest.onBlur, () => {
|
|
1046
1544
|
if (gesture.focused) setFocused(false);
|
|
@@ -1081,4 +1579,6 @@ function compose(user, ours) {
|
|
|
1081
1579
|
|
|
1082
1580
|
exports.Presence = Presence;
|
|
1083
1581
|
exports.createMotionComponent = createMotionComponent;
|
|
1582
|
+
exports.pairBoxShadowLayers = pairBoxShadowLayers;
|
|
1583
|
+
exports.resolveBoxShadowInput = resolveBoxShadowInput;
|
|
1084
1584
|
exports.usePresence = usePresence;
|