@rootnative/inertia 0.0.3 → 0.0.5
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 +92 -5
- package/README.md +9 -3
- package/dist/{chunk-OQV66TBQ.mjs → chunk-27MKBTSG.mjs} +1 -1
- package/dist/{chunk-3XTVY34H.js → chunk-27U6766G.js} +2 -2
- package/dist/{chunk-4PEHWDAZ.js → chunk-4NAMD62I.js} +7 -7
- package/dist/chunk-67GHRCF6.js +8 -0
- package/dist/{chunk-SGUHE5CX.mjs → chunk-COEJVWRZ.mjs} +1 -1
- package/dist/chunk-GPOMFIIU.js +8 -0
- package/dist/{chunk-BQQTHG2V.mjs → chunk-GTJ6VAH5.mjs} +1 -1
- package/dist/chunk-K63LXGKS.js +8 -0
- package/dist/{chunk-46P57VMY.mjs → chunk-OAUWLPQH.mjs} +1 -1
- package/dist/{chunk-7AOERN53.js → chunk-OBRGJAST.js} +3 -3
- package/dist/{chunk-RGNX6UZN.mjs → chunk-OW5XTGVN.mjs} +2 -2
- package/dist/{chunk-PTRF47DA.js → chunk-PM6CVGXJ.js} +11 -3
- package/dist/{chunk-W5MC3P4N.js → chunk-QQVDZKSD.js} +2 -2
- package/dist/{chunk-CY7Y64C3.mjs → chunk-REYL77RE.mjs} +11 -4
- package/dist/{chunk-CSODMRJ7.mjs → chunk-RIVVBABB.mjs} +597 -134
- package/dist/{chunk-BP3Y2SHQ.js → chunk-VQ5D35UA.js} +617 -152
- package/dist/{chunk-O22NXXCZ.mjs → chunk-XSK5MNUH.mjs} +1 -1
- package/dist/{chunk-R63GIUNU.mjs → chunk-Z3HCJ43H.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 +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +48 -169
- package/dist/index.mjs +17 -137
- 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-BQgLJeQG.d.mts} +85 -14
- package/dist/{types-G1dBU2IQ.d.ts → types-BQgLJeQG.d.ts} +85 -14
- package/dist/{useGesture-D1e4ixJo.d.ts → useGesture-B0_CzOUz.d.ts} +1 -1
- package/dist/{useGesture-RFY6kTL3.d.mts → useGesture-DfaTx-3t.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 +10 -0
- package/src/layout/measureWindow.ts +135 -0
- package/src/layout/sharedRegistry.ts +107 -18
- package/src/layout/useSharedLayout.ts +256 -91
- package/src/motion/createMotionComponent.tsx +497 -74
- package/src/motion/installCheck.ts +1 -1
- package/src/transitions/index.ts +1 -1
- package/src/transitions/resolveSequence.ts +12 -0
- package/src/types.ts +155 -12
- package/src/values/useColorTransition.ts +1 -1
- package/dist/chunk-FNVFV4EY.js +0 -8
- package/dist/chunk-FWQOXA43.js +0 -8
- package/dist/chunk-KBP4LR75.js +0 -8
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
var
|
|
3
|
+
var chunkOBRGJAST_js = require('./chunk-OBRGJAST.js');
|
|
4
|
+
var chunkPM6CVGXJ_js = require('./chunk-PM6CVGXJ.js');
|
|
5
5
|
var react = require('react');
|
|
6
6
|
var jsxRuntime = require('react/jsx-runtime');
|
|
7
7
|
var Animated = require('react-native-reanimated');
|
|
@@ -135,20 +135,189 @@ function PresenceItem({
|
|
|
135
135
|
);
|
|
136
136
|
return /* @__PURE__ */ jsxRuntime.jsx(PresenceContext.Provider, { value, children });
|
|
137
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
|
+
}
|
|
138
307
|
function resolveLayoutTransition(layout) {
|
|
139
308
|
if (!layout) return void 0;
|
|
140
309
|
const cfg = layout === true ? { type: "spring" } : layout;
|
|
141
310
|
if (cfg.type === "no-animation") return void 0;
|
|
142
311
|
if (cfg.type === "timing") {
|
|
143
312
|
let builder2 = Animated.LinearTransition.duration(cfg.duration ?? 300);
|
|
144
|
-
const easing =
|
|
313
|
+
const easing = chunkPM6CVGXJ_js.ensureWorkletEasing(cfg.easing);
|
|
145
314
|
if (easing) builder2 = builder2.easing(easing);
|
|
146
315
|
if (cfg.delay) builder2 = builder2.delay(cfg.delay);
|
|
147
316
|
return builder2;
|
|
148
317
|
}
|
|
149
318
|
const spring = cfg.type === "decay" ? { type: "spring" } : cfg;
|
|
150
|
-
const { stiffness, damping, mass } =
|
|
151
|
-
...
|
|
319
|
+
const { stiffness, damping, mass } = chunkPM6CVGXJ_js.springToReanimated({
|
|
320
|
+
...chunkPM6CVGXJ_js.DEFAULT_SPRING,
|
|
152
321
|
...spring
|
|
153
322
|
});
|
|
154
323
|
let builder = Animated.LinearTransition.springify().stiffness(stiffness).damping(damping).mass(mass);
|
|
@@ -168,72 +337,138 @@ function sweepExpired(at) {
|
|
|
168
337
|
if (entry.expiresAt < at) REGISTRY.delete(id);
|
|
169
338
|
}
|
|
170
339
|
}
|
|
171
|
-
function registerLayout(id, rect) {
|
|
340
|
+
function registerLayout(id, rect, remeasure, readStyles) {
|
|
172
341
|
const at = now();
|
|
173
342
|
sweepExpired(at);
|
|
174
|
-
REGISTRY.set(id, {
|
|
343
|
+
REGISTRY.set(id, {
|
|
344
|
+
rect,
|
|
345
|
+
expiresAt: at + SHARED_LAYOUT_TTL_MS,
|
|
346
|
+
remeasure,
|
|
347
|
+
readStyles
|
|
348
|
+
});
|
|
175
349
|
}
|
|
176
|
-
function releaseLayout(id, rect) {
|
|
350
|
+
function releaseLayout(id, rect, styles) {
|
|
177
351
|
const at = now();
|
|
178
352
|
sweepExpired(at);
|
|
179
|
-
REGISTRY.set(id, { rect, expiresAt: at + SHARED_LAYOUT_TTL_MS });
|
|
353
|
+
REGISTRY.set(id, { rect, expiresAt: at + SHARED_LAYOUT_TTL_MS, styles });
|
|
180
354
|
}
|
|
181
355
|
function consumeLayout(id) {
|
|
182
356
|
const entry = REGISTRY.get(id);
|
|
183
357
|
if (!entry) return void 0;
|
|
184
358
|
REGISTRY.delete(id);
|
|
185
359
|
if (entry.expiresAt < now()) return void 0;
|
|
186
|
-
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 };
|
|
187
401
|
}
|
|
188
402
|
function useSharedLayout(options) {
|
|
189
|
-
const {
|
|
403
|
+
const {
|
|
404
|
+
layoutId,
|
|
405
|
+
userRef,
|
|
406
|
+
transition,
|
|
407
|
+
shouldReduceMotion,
|
|
408
|
+
userOnLayout,
|
|
409
|
+
readStyles
|
|
410
|
+
} = options;
|
|
190
411
|
const dx = Animated.useSharedValue(0);
|
|
191
412
|
const dy = Animated.useSharedValue(0);
|
|
192
413
|
const sx = Animated.useSharedValue(1);
|
|
193
414
|
const sy = Animated.useSharedValue(1);
|
|
415
|
+
const snapshot = Animated.useSharedValue(null);
|
|
416
|
+
const carryProgress = Animated.useSharedValue(0);
|
|
194
417
|
const lastRectRef = react.useRef(null);
|
|
195
418
|
const consumedRef = react.useRef(false);
|
|
419
|
+
const nodeRef = react.useRef(null);
|
|
196
420
|
const transitionRef = react.useRef(transition);
|
|
197
421
|
transitionRef.current = transition;
|
|
198
422
|
const reducedMotionRef = react.useRef(shouldReduceMotion);
|
|
199
423
|
reducedMotionRef.current = shouldReduceMotion;
|
|
424
|
+
const readStylesRef = react.useRef(readStyles);
|
|
425
|
+
readStylesRef.current = readStyles;
|
|
200
426
|
const setRef = react.useCallback(
|
|
201
427
|
(node) => {
|
|
428
|
+
nodeRef.current = node;
|
|
202
429
|
if (typeof userRef === "function") userRef(node);
|
|
203
430
|
else if (userRef) userRef.current = node;
|
|
204
431
|
},
|
|
205
432
|
[userRef]
|
|
206
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
|
+
);
|
|
207
455
|
const onLayout = react.useCallback(
|
|
208
456
|
(event) => {
|
|
209
457
|
userOnLayout?.(event);
|
|
210
458
|
if (!layoutId) return;
|
|
211
459
|
const { x, y, width, height } = event.nativeEvent.layout;
|
|
212
|
-
const rect = { x, y, width, height };
|
|
213
|
-
lastRectRef.current = rect;
|
|
214
460
|
let source;
|
|
215
461
|
if (!consumedRef.current) {
|
|
216
462
|
consumedRef.current = true;
|
|
217
463
|
source = consumeLayout(layoutId);
|
|
218
464
|
}
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
dx,
|
|
225
|
-
dy,
|
|
226
|
-
sx,
|
|
227
|
-
sy,
|
|
228
|
-
transition: transitionRef.current,
|
|
229
|
-
shouldReduceMotion: reducedMotionRef.current
|
|
230
|
-
});
|
|
231
|
-
}
|
|
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);
|
|
232
470
|
},
|
|
233
|
-
|
|
234
|
-
// exhaustive-deps would flag them — including them is harmless and
|
|
235
|
-
// silences the warning.
|
|
236
|
-
[layoutId, userOnLayout, dx, dy, sx, sy]
|
|
471
|
+
[layoutId, userOnLayout, remeasure, snapshotStyles, startTransition]
|
|
237
472
|
);
|
|
238
473
|
react.useEffect(() => {
|
|
239
474
|
consumedRef.current = false;
|
|
@@ -243,18 +478,49 @@ function useSharedLayout(options) {
|
|
|
243
478
|
if (!layoutId) return;
|
|
244
479
|
const rect = lastRectRef.current;
|
|
245
480
|
if (!rect) return;
|
|
246
|
-
releaseLayout(layoutId, rect);
|
|
481
|
+
releaseLayout(layoutId, rect, snapshotStyles());
|
|
247
482
|
};
|
|
248
|
-
}, [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
|
+
);
|
|
249
496
|
return react.useMemo(
|
|
250
497
|
() => ({
|
|
251
498
|
flip: { dx, dy, sx, sy },
|
|
499
|
+
carry: { snapshot, progress: carryProgress },
|
|
252
500
|
setRef,
|
|
253
501
|
onLayout
|
|
254
502
|
}),
|
|
255
|
-
[dx, dy, sx, sy, setRef, onLayout]
|
|
503
|
+
[dx, dy, sx, sy, snapshot, carryProgress, setRef, onLayout]
|
|
256
504
|
);
|
|
257
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" ? { ...chunkPM6CVGXJ_js.DEFAULT_SPRING, ...transition } : { type: "spring", ...chunkPM6CVGXJ_js.DEFAULT_SPRING };
|
|
515
|
+
const springParams = chunkPM6CVGXJ_js.springToReanimated(springCfg);
|
|
516
|
+
return (from, to) => Animated.withSequence(
|
|
517
|
+
Animated.withTiming(from, { duration: 0 }),
|
|
518
|
+
Animated.withSpring(to, springParams)
|
|
519
|
+
);
|
|
520
|
+
}
|
|
521
|
+
function shouldSnap(transition, shouldReduceMotion) {
|
|
522
|
+
return shouldReduceMotion || transition?.type === "no-animation";
|
|
523
|
+
}
|
|
258
524
|
function applyFlip(args) {
|
|
259
525
|
const { source, target, dx, dy, sx, sy, transition, shouldReduceMotion } = args;
|
|
260
526
|
const sourceCenterX = source.x + source.width / 2;
|
|
@@ -265,58 +531,29 @@ function applyFlip(args) {
|
|
|
265
531
|
const deltaY = sourceCenterY - targetCenterY;
|
|
266
532
|
const scaleX = target.width > 0 ? source.width / target.width : 1;
|
|
267
533
|
const scaleY = target.height > 0 ? source.height / target.height : 1;
|
|
268
|
-
if (shouldReduceMotion) {
|
|
269
|
-
dx.value = 0;
|
|
270
|
-
dy.value = 0;
|
|
271
|
-
sx.value = 1;
|
|
272
|
-
sy.value = 1;
|
|
273
|
-
return;
|
|
274
|
-
}
|
|
275
|
-
if (transition?.type === "no-animation") {
|
|
534
|
+
if (shouldSnap(transition, shouldReduceMotion)) {
|
|
276
535
|
dx.value = 0;
|
|
277
536
|
dy.value = 0;
|
|
278
537
|
sx.value = 1;
|
|
279
538
|
sy.value = 1;
|
|
280
539
|
return;
|
|
281
540
|
}
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
Animated.withTiming(1, { duration })
|
|
295
|
-
);
|
|
296
|
-
sy.value = Animated.withSequence(
|
|
297
|
-
Animated.withTiming(scaleY, { duration: 0 }),
|
|
298
|
-
Animated.withTiming(1, { duration })
|
|
299
|
-
);
|
|
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;
|
|
300
553
|
return;
|
|
301
554
|
}
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
dx.value = Animated.withSequence(
|
|
305
|
-
Animated.withTiming(deltaX, { duration: 0 }),
|
|
306
|
-
Animated.withSpring(0, springParams)
|
|
307
|
-
);
|
|
308
|
-
dy.value = Animated.withSequence(
|
|
309
|
-
Animated.withTiming(deltaY, { duration: 0 }),
|
|
310
|
-
Animated.withSpring(0, springParams)
|
|
311
|
-
);
|
|
312
|
-
sx.value = Animated.withSequence(
|
|
313
|
-
Animated.withTiming(scaleX, { duration: 0 }),
|
|
314
|
-
Animated.withSpring(1, springParams)
|
|
315
|
-
);
|
|
316
|
-
sy.value = Animated.withSequence(
|
|
317
|
-
Animated.withTiming(scaleY, { duration: 0 }),
|
|
318
|
-
Animated.withSpring(1, springParams)
|
|
319
|
-
);
|
|
555
|
+
snapshot.value = styles;
|
|
556
|
+
progress.value = legBuilder(transition)(1, 0);
|
|
320
557
|
}
|
|
321
558
|
var alreadyChecked = false;
|
|
322
559
|
function ensureReanimatedInstalled() {
|
|
@@ -330,7 +567,7 @@ function ensureReanimatedInstalled() {
|
|
|
330
567
|
const major = parseInt(version.split(".")[0] ?? "0", 10);
|
|
331
568
|
if (major < 4) {
|
|
332
569
|
console.error(
|
|
333
|
-
`[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).`
|
|
334
571
|
);
|
|
335
572
|
return;
|
|
336
573
|
}
|
|
@@ -363,7 +600,79 @@ var NUMERIC_TOP_LEVEL_KEYS = [
|
|
|
363
600
|
"borderRadius",
|
|
364
601
|
"shadowOpacity",
|
|
365
602
|
"shadowRadius",
|
|
366
|
-
"elevation"
|
|
603
|
+
"elevation",
|
|
604
|
+
// ─── Added in 0.0.5 ──────────────────────────────────────────────────────
|
|
605
|
+
//
|
|
606
|
+
// Every key below rides the generic numeric path: one shared value, resolved
|
|
607
|
+
// on the JS thread, emitted by the worklet through the same `out[key] = v`
|
|
608
|
+
// branch as `opacity`. None needs a new interpolation mode, so the cost is
|
|
609
|
+
// the shared value plus a `DEFAULT_RESTING` entry.
|
|
610
|
+
//
|
|
611
|
+
// The load-bearing constraint is the resting default, not the plumbing. A
|
|
612
|
+
// key declared only in `gesture` / `exit` / a non-active variant rests at
|
|
613
|
+
// `DEFAULT_RESTING` unless the static `style` names it, and the animated
|
|
614
|
+
// style merges *after* `style` — so a non-identity default silently stomps
|
|
615
|
+
// the layout. That is the `0.0.3` P0 class, and it is why the sizing and
|
|
616
|
+
// spacing keys below default to `0` only in the sense RN itself does (an
|
|
617
|
+
// unset `padding` *is* 0); `minWidth`/`maxWidth`/`aspectRatio` are
|
|
618
|
+
// deliberately excluded — their "unset" is not a number, so no default can
|
|
619
|
+
// stand in for it without changing layout on activation.
|
|
620
|
+
//
|
|
621
|
+
// Per-corner radii. Animating one corner is common (a card expanding into a
|
|
622
|
+
// sheet keeps its top corners and squares off the bottom); `borderRadius`
|
|
623
|
+
// alone can't express it.
|
|
624
|
+
"borderTopLeftRadius",
|
|
625
|
+
"borderTopRightRadius",
|
|
626
|
+
"borderBottomLeftRadius",
|
|
627
|
+
"borderBottomRightRadius",
|
|
628
|
+
// Border widths. `borderWidth` is the common case; the per-edge keys matter
|
|
629
|
+
// for underline-style focus affordances (`borderBottomWidth` on a field).
|
|
630
|
+
"borderWidth",
|
|
631
|
+
"borderTopWidth",
|
|
632
|
+
"borderRightWidth",
|
|
633
|
+
"borderBottomWidth",
|
|
634
|
+
"borderLeftWidth",
|
|
635
|
+
// Absolute-position insets. Bread-and-butter for drawers, tooltips, and
|
|
636
|
+
// anything pinned to an edge that slides in.
|
|
637
|
+
"top",
|
|
638
|
+
"right",
|
|
639
|
+
"bottom",
|
|
640
|
+
"left",
|
|
641
|
+
// Spacing. Padding animates the box from the inside (a button growing its
|
|
642
|
+
// hit area on press); margin shifts it within its parent's flow.
|
|
643
|
+
"padding",
|
|
644
|
+
"paddingTop",
|
|
645
|
+
"paddingRight",
|
|
646
|
+
"paddingBottom",
|
|
647
|
+
"paddingLeft",
|
|
648
|
+
"paddingHorizontal",
|
|
649
|
+
"paddingVertical",
|
|
650
|
+
"margin",
|
|
651
|
+
"marginTop",
|
|
652
|
+
"marginRight",
|
|
653
|
+
"marginBottom",
|
|
654
|
+
"marginLeft",
|
|
655
|
+
"marginHorizontal",
|
|
656
|
+
"marginVertical",
|
|
657
|
+
// Flex sizing. `flex` / `flexGrow` interpolate the split between siblings —
|
|
658
|
+
// the idiomatic RN way to animate a pane resize without measuring.
|
|
659
|
+
"flex",
|
|
660
|
+
"flexGrow",
|
|
661
|
+
"flexShrink",
|
|
662
|
+
// Text metrics. `TextStyle`-only at the type level (`AnimateStyle<C>` gates
|
|
663
|
+
// them per primitive), but the runtime table is shared across primitives —
|
|
664
|
+
// an unused slot is one ref, same as `tintColor` has always been.
|
|
665
|
+
"fontSize",
|
|
666
|
+
"letterSpacing",
|
|
667
|
+
"lineHeight",
|
|
668
|
+
// Stacking. Integer-valued in practice, and interpolating it mid-flight is
|
|
669
|
+
// rarely what you want, but a `no-animation` transition on `zIndex` is the
|
|
670
|
+
// clean way to reorder at a step boundary in a sequence.
|
|
671
|
+
"zIndex",
|
|
672
|
+
// Gap. Row/column gaps animate a list's density without touching children.
|
|
673
|
+
"gap",
|
|
674
|
+
"rowGap",
|
|
675
|
+
"columnGap"
|
|
367
676
|
];
|
|
368
677
|
var COLOR_KEYS = [
|
|
369
678
|
"backgroundColor",
|
|
@@ -373,15 +682,28 @@ var COLOR_KEYS = [
|
|
|
373
682
|
"shadowColor"
|
|
374
683
|
];
|
|
375
684
|
var SHADOW_OFFSET_KEYS = ["shadowOffsetWidth", "shadowOffsetHeight"];
|
|
685
|
+
var STRUCTURED_KEYS = ["boxShadow"];
|
|
686
|
+
var SHARED_STYLE_KEYS = [
|
|
687
|
+
"opacity",
|
|
688
|
+
"borderRadius",
|
|
689
|
+
"backgroundColor",
|
|
690
|
+
"borderColor",
|
|
691
|
+
"color",
|
|
692
|
+
"tintColor"
|
|
693
|
+
];
|
|
376
694
|
var ALL_KEYS = [
|
|
377
695
|
...TRANSFORM_KEYS,
|
|
378
696
|
...NUMERIC_TOP_LEVEL_KEYS,
|
|
379
697
|
...COLOR_KEYS,
|
|
380
|
-
...SHADOW_OFFSET_KEYS
|
|
698
|
+
...SHADOW_OFFSET_KEYS,
|
|
699
|
+
...STRUCTURED_KEYS
|
|
381
700
|
];
|
|
382
701
|
var TRANSFORM_KEY_SET = new Set(TRANSFORM_KEYS);
|
|
383
702
|
var COLOR_KEY_SET = new Set(COLOR_KEYS);
|
|
384
703
|
var SHADOW_OFFSET_KEY_SET = new Set(SHADOW_OFFSET_KEYS);
|
|
704
|
+
var STRUCTURED_KEY_SET = new Set(STRUCTURED_KEYS);
|
|
705
|
+
var SHARED_STYLE_KEY_SET = new Set(SHARED_STYLE_KEYS);
|
|
706
|
+
var NO_BOX_SHADOW = Object.freeze([]);
|
|
385
707
|
var GESTURE_LAYER_NAMES = [
|
|
386
708
|
"hovered",
|
|
387
709
|
"focused",
|
|
@@ -406,6 +728,54 @@ var DEFAULT_RESTING = {
|
|
|
406
728
|
shadowOpacity: 0,
|
|
407
729
|
shadowRadius: 0,
|
|
408
730
|
elevation: 0,
|
|
731
|
+
// 0.0.5 keys. Every one of these is 0 because that is RN's own unset value
|
|
732
|
+
// for it — an element with no `paddingTop` has 0 padding, no `borderWidth`
|
|
733
|
+
// has none, no `top` is unpinned at 0 within its positioning context. So a
|
|
734
|
+
// key that reaches its resting default lands where the element already was.
|
|
735
|
+
//
|
|
736
|
+
// The exception worth naming: `flex` / `flexGrow` / `flexShrink` do NOT have
|
|
737
|
+
// 0 as a universal identity (`flexShrink` defaults to 1 on the web, and RN's
|
|
738
|
+
// own default differs by axis). They are still 0 here, because the style-scan
|
|
739
|
+
// in the resting pass reads the real value off the static `style` whenever it
|
|
740
|
+
// is declared — and a consumer animating flex without declaring it is asking
|
|
741
|
+
// for the from-0 growth, which is the readable interpretation.
|
|
742
|
+
borderTopLeftRadius: 0,
|
|
743
|
+
borderTopRightRadius: 0,
|
|
744
|
+
borderBottomLeftRadius: 0,
|
|
745
|
+
borderBottomRightRadius: 0,
|
|
746
|
+
borderWidth: 0,
|
|
747
|
+
borderTopWidth: 0,
|
|
748
|
+
borderRightWidth: 0,
|
|
749
|
+
borderBottomWidth: 0,
|
|
750
|
+
borderLeftWidth: 0,
|
|
751
|
+
top: 0,
|
|
752
|
+
right: 0,
|
|
753
|
+
bottom: 0,
|
|
754
|
+
left: 0,
|
|
755
|
+
padding: 0,
|
|
756
|
+
paddingTop: 0,
|
|
757
|
+
paddingRight: 0,
|
|
758
|
+
paddingBottom: 0,
|
|
759
|
+
paddingLeft: 0,
|
|
760
|
+
paddingHorizontal: 0,
|
|
761
|
+
paddingVertical: 0,
|
|
762
|
+
margin: 0,
|
|
763
|
+
marginTop: 0,
|
|
764
|
+
marginRight: 0,
|
|
765
|
+
marginBottom: 0,
|
|
766
|
+
marginLeft: 0,
|
|
767
|
+
marginHorizontal: 0,
|
|
768
|
+
marginVertical: 0,
|
|
769
|
+
flex: 0,
|
|
770
|
+
flexGrow: 0,
|
|
771
|
+
flexShrink: 0,
|
|
772
|
+
fontSize: 0,
|
|
773
|
+
letterSpacing: 0,
|
|
774
|
+
lineHeight: 0,
|
|
775
|
+
zIndex: 0,
|
|
776
|
+
gap: 0,
|
|
777
|
+
rowGap: 0,
|
|
778
|
+
columnGap: 0,
|
|
409
779
|
// 'transparent' is the only safe universal default for colors: it works as
|
|
410
780
|
// an initial seed for any color animation (no jarring opaque flash on mount
|
|
411
781
|
// when `initial` is omitted) and rgba(0,0,0,0) interpolates cleanly into
|
|
@@ -416,19 +786,20 @@ var DEFAULT_RESTING = {
|
|
|
416
786
|
tintColor: "transparent",
|
|
417
787
|
shadowColor: "transparent",
|
|
418
788
|
shadowOffsetWidth: 0,
|
|
419
|
-
shadowOffsetHeight: 0
|
|
789
|
+
shadowOffsetHeight: 0,
|
|
790
|
+
boxShadow: NO_BOX_SHADOW
|
|
420
791
|
};
|
|
421
792
|
function transitionFor(prop, transition) {
|
|
422
793
|
if (!transition) return void 0;
|
|
423
794
|
if (typeof transition === "string") return void 0;
|
|
424
|
-
if (
|
|
795
|
+
if (chunkPM6CVGXJ_js.isTopLevelTransition(transition)) return transition;
|
|
425
796
|
if (GESTURE_LAYER_NAME_SET.has(prop)) return void 0;
|
|
426
797
|
return transition[prop];
|
|
427
798
|
}
|
|
428
799
|
function gestureLayerTransitionFor(layer, transition) {
|
|
429
800
|
if (!transition) return void 0;
|
|
430
801
|
if (typeof transition === "string") return void 0;
|
|
431
|
-
if (
|
|
802
|
+
if (chunkPM6CVGXJ_js.isTopLevelTransition(transition)) return transition;
|
|
432
803
|
return transition[layer];
|
|
433
804
|
}
|
|
434
805
|
function createMotionComponent(Component) {
|
|
@@ -478,12 +849,12 @@ function createMotionComponent(Component) {
|
|
|
478
849
|
onLayout: userOnLayout,
|
|
479
850
|
...rest
|
|
480
851
|
} = props;
|
|
481
|
-
const namedTransitions =
|
|
482
|
-
const transition =
|
|
852
|
+
const namedTransitions = chunkOBRGJAST_js.useNamedTransitions();
|
|
853
|
+
const transition = chunkOBRGJAST_js.resolveNamedTransitionProp(
|
|
483
854
|
transitionProp,
|
|
484
855
|
namedTransitions
|
|
485
856
|
);
|
|
486
|
-
const layout = typeof layoutProp === "string" ?
|
|
857
|
+
const layout = typeof layoutProp === "string" ? chunkOBRGJAST_js.lookupNamedTransition(layoutProp, namedTransitions) : layoutProp;
|
|
487
858
|
if (__DEV__ && typeof style === "function") {
|
|
488
859
|
throw new Error(
|
|
489
860
|
"[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."
|
|
@@ -491,7 +862,7 @@ function createMotionComponent(Component) {
|
|
|
491
862
|
}
|
|
492
863
|
const presence = usePresence();
|
|
493
864
|
const isExiting = presence !== null && presence.isPresent === false;
|
|
494
|
-
const shouldReduceMotion =
|
|
865
|
+
const shouldReduceMotion = chunkOBRGJAST_js.useShouldReduceMotion();
|
|
495
866
|
const onAnimationEndRef = react.useRef(onAnimationEnd);
|
|
496
867
|
onAnimationEndRef.current = onAnimationEnd;
|
|
497
868
|
const variantKey = useControllerKey(controller);
|
|
@@ -507,6 +878,16 @@ function createMotionComponent(Component) {
|
|
|
507
878
|
const [focused, setFocused] = react.useState(false);
|
|
508
879
|
const [focusVisible, setFocusVisible] = react.useState(false);
|
|
509
880
|
const [hovered, setHovered] = react.useState(false);
|
|
881
|
+
const hasLayoutId = layoutId !== void 0;
|
|
882
|
+
let flatStyle;
|
|
883
|
+
let flatStyleRead = false;
|
|
884
|
+
const getFlatStyle = () => {
|
|
885
|
+
if (!flatStyleRead) {
|
|
886
|
+
flatStyleRead = true;
|
|
887
|
+
flatStyle = reactNative.StyleSheet.flatten(style);
|
|
888
|
+
}
|
|
889
|
+
return flatStyle;
|
|
890
|
+
};
|
|
510
891
|
const touched = /* @__PURE__ */ new Set();
|
|
511
892
|
collectTouchedKeys(touched, animateRecord);
|
|
512
893
|
if (initialRecord) collectTouchedKeys(touched, initialRecord);
|
|
@@ -528,9 +909,19 @@ function createMotionComponent(Component) {
|
|
|
528
909
|
}
|
|
529
910
|
}
|
|
530
911
|
if (exitRecord) collectTouchedKeys(touched, exitRecord);
|
|
912
|
+
if (hasLayoutId) {
|
|
913
|
+
const flat = getFlatStyle();
|
|
914
|
+
if (flat) {
|
|
915
|
+
for (const key of SHARED_STYLE_KEYS) {
|
|
916
|
+
if (touched.has(key)) continue;
|
|
917
|
+
if (styleValueFor(flat, key) !== void 0) touched.add(key);
|
|
918
|
+
}
|
|
919
|
+
}
|
|
920
|
+
}
|
|
531
921
|
const activeKeysRef = react.useRef(null);
|
|
532
922
|
const hasTransformRef = react.useRef(false);
|
|
533
923
|
const hasShadowOffsetRef = react.useRef(false);
|
|
924
|
+
const hasBoxShadowRef = react.useRef(false);
|
|
534
925
|
const prevActive = activeKeysRef.current;
|
|
535
926
|
let grew = prevActive === null;
|
|
536
927
|
if (!grew && prevActive) {
|
|
@@ -551,6 +942,15 @@ function createMotionComponent(Component) {
|
|
|
551
942
|
hasShadowOffsetRef.current = activeKeysRef.current.some(
|
|
552
943
|
(k) => SHADOW_OFFSET_KEY_SET.has(k)
|
|
553
944
|
);
|
|
945
|
+
hasBoxShadowRef.current = activeKeysRef.current.includes("boxShadow");
|
|
946
|
+
if (__DEV__ && hasBoxShadowRef.current && activeKeysRef.current.some(
|
|
947
|
+
(k) => k !== "boxShadow" && k.startsWith("shadow")
|
|
948
|
+
)) {
|
|
949
|
+
chunkPM6CVGXJ_js.warnOnce(
|
|
950
|
+
"boxShadow-with-native-shadow",
|
|
951
|
+
"[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."
|
|
952
|
+
);
|
|
953
|
+
}
|
|
554
954
|
}
|
|
555
955
|
const drivenNow = /* @__PURE__ */ new Set();
|
|
556
956
|
collectTouchedKeys(drivenNow, animateRecord);
|
|
@@ -561,17 +961,35 @@ function createMotionComponent(Component) {
|
|
|
561
961
|
const activeKeys = activeKeysRef.current;
|
|
562
962
|
const everDriven = everDrivenRef.current;
|
|
563
963
|
const styleResting = {};
|
|
964
|
+
let styleRestingShadow = null;
|
|
564
965
|
if (activeKeys.some((k) => !everDriven.has(k))) {
|
|
565
|
-
const flat =
|
|
966
|
+
const flat = getFlatStyle();
|
|
566
967
|
if (flat) {
|
|
567
968
|
for (const key of activeKeys) {
|
|
568
969
|
if (everDriven.has(key)) continue;
|
|
970
|
+
if (key === "boxShadow") {
|
|
971
|
+
const raw = flat.boxShadow;
|
|
972
|
+
if (raw !== void 0) {
|
|
973
|
+
styleRestingShadow = normalizeBoxShadow(raw);
|
|
974
|
+
styleResting.boxShadow = styleRestingShadow.layers;
|
|
975
|
+
}
|
|
976
|
+
continue;
|
|
977
|
+
}
|
|
569
978
|
const v = styleValueFor(flat, key);
|
|
570
979
|
if (v !== void 0) styleResting[key] = v;
|
|
571
980
|
}
|
|
572
981
|
}
|
|
573
982
|
}
|
|
983
|
+
const boxShadowSeedRef = react.useRef(null);
|
|
984
|
+
if (boxShadowSeedRef.current === null) {
|
|
985
|
+
const source = initial === false ? animateRecord.boxShadow : initialRecord?.boxShadow ?? animateRecord.boxShadow;
|
|
986
|
+
boxShadowSeedRef.current = source !== void 0 ? normalizeBoxShadow(source) : styleRestingShadow ?? {
|
|
987
|
+
layers: [...NO_BOX_SHADOW],
|
|
988
|
+
insets: null
|
|
989
|
+
};
|
|
990
|
+
}
|
|
574
991
|
const sharedValues = useAnimatableSharedValues((key) => {
|
|
992
|
+
if (key === "boxShadow") return boxShadowSeedRef.current.layers;
|
|
575
993
|
if (SHADOW_OFFSET_KEY_SET.has(key)) {
|
|
576
994
|
const axis = shadowOffsetAxisFor(key);
|
|
577
995
|
if (initial === false) {
|
|
@@ -588,11 +1006,17 @@ function createMotionComponent(Component) {
|
|
|
588
1006
|
}
|
|
589
1007
|
return initialRecord?.[key] ?? restValue(animateRecord[key]) ?? styleResting[key] ?? DEFAULT_RESTING[key];
|
|
590
1008
|
});
|
|
591
|
-
const
|
|
1009
|
+
const boxShadowInsets = Animated.useSharedValue(
|
|
1010
|
+
boxShadowSeedRef.current.insets
|
|
1011
|
+
);
|
|
1012
|
+
const styleRestingSig = chunkPM6CVGXJ_js.stableSig(styleResting);
|
|
592
1013
|
react.useEffect(() => {
|
|
593
1014
|
for (const key of activeKeysRef.current) {
|
|
594
1015
|
if (everDrivenRef.current.has(key)) continue;
|
|
595
1016
|
sharedValues[key].value = styleResting[key] ?? DEFAULT_RESTING[key];
|
|
1017
|
+
if (key === "boxShadow") {
|
|
1018
|
+
boxShadowInsets.value = styleRestingShadow?.insets ?? null;
|
|
1019
|
+
}
|
|
596
1020
|
}
|
|
597
1021
|
}, [styleRestingSig]);
|
|
598
1022
|
const pressedProgress = Animated.useSharedValue(0);
|
|
@@ -613,13 +1037,13 @@ function createMotionComponent(Component) {
|
|
|
613
1037
|
const gestureSV = Animated.useSharedValue(
|
|
614
1038
|
resolveGestureLayers(gesture)
|
|
615
1039
|
);
|
|
616
|
-
const gestureTargetsSig =
|
|
1040
|
+
const gestureTargetsSig = chunkPM6CVGXJ_js.stableSig(gesture);
|
|
617
1041
|
react.useEffect(() => {
|
|
618
1042
|
gestureSV.value = resolveGestureLayers(gesture);
|
|
619
1043
|
}, [gestureTargetsSig]);
|
|
620
1044
|
const baseRecord = isExiting && exitRecord ? { ...animateRecord, ...exitRecord } : animateRecord;
|
|
621
|
-
const baseSig =
|
|
622
|
-
const transitionSig =
|
|
1045
|
+
const baseSig = chunkPM6CVGXJ_js.stableSig(baseRecord) + (isExiting ? "|exit" : "") + (shouldReduceMotion ? "|rm" : "");
|
|
1046
|
+
const transitionSig = chunkPM6CVGXJ_js.stableSig(transition);
|
|
623
1047
|
const safeToRemoveRef = react.useRef(void 0);
|
|
624
1048
|
safeToRemoveRef.current = presence?.safeToRemove;
|
|
625
1049
|
react.useEffect(() => {
|
|
@@ -649,6 +1073,30 @@ function createMotionComponent(Component) {
|
|
|
649
1073
|
}
|
|
650
1074
|
const transformGroup = transformPending > 0 ? { remaining: transformPending } : void 0;
|
|
651
1075
|
for (const key of ALL_KEYS) {
|
|
1076
|
+
if (key === "boxShadow") {
|
|
1077
|
+
const shadowTarget = baseRecord.boxShadow;
|
|
1078
|
+
if (shadowTarget === void 0) continue;
|
|
1079
|
+
const cfg2 = configFor("boxShadow");
|
|
1080
|
+
if (isExiting && reachesTerminalPhase(cfg2)) pending++;
|
|
1081
|
+
driveBoxShadow(
|
|
1082
|
+
sharedValues.boxShadow,
|
|
1083
|
+
boxShadowInsets,
|
|
1084
|
+
shadowTarget,
|
|
1085
|
+
cfg2,
|
|
1086
|
+
makeKeyCallbackFactory(
|
|
1087
|
+
"boxShadow",
|
|
1088
|
+
sharedValues.boxShadow,
|
|
1089
|
+
// The declared target, not the padded one — the padding is an
|
|
1090
|
+
// implementation detail of getting Reanimated to interpolate.
|
|
1091
|
+
shadowTarget,
|
|
1092
|
+
onAnimationEndRef,
|
|
1093
|
+
{ stepCount: 1, totalIterations: totalIterationsOf(cfg2) },
|
|
1094
|
+
isExiting ? onSettle : void 0,
|
|
1095
|
+
void 0
|
|
1096
|
+
)
|
|
1097
|
+
);
|
|
1098
|
+
continue;
|
|
1099
|
+
}
|
|
652
1100
|
const target = SHADOW_OFFSET_KEY_SET.has(key) ? shadowOffsetAxisValue(
|
|
653
1101
|
baseRecord.shadowOffset,
|
|
654
1102
|
shadowOffsetAxisFor(key)
|
|
@@ -668,7 +1116,7 @@ function createMotionComponent(Component) {
|
|
|
668
1116
|
isExiting ? onSettle : void 0,
|
|
669
1117
|
TRANSFORM_KEY_SET.has(key) ? transformGroup : void 0
|
|
670
1118
|
);
|
|
671
|
-
sharedValues[key].value =
|
|
1119
|
+
sharedValues[key].value = chunkPM6CVGXJ_js.resolveAnimatableValue(
|
|
672
1120
|
target,
|
|
673
1121
|
cfg,
|
|
674
1122
|
factory
|
|
@@ -714,19 +1162,34 @@ function createMotionComponent(Component) {
|
|
|
714
1162
|
isExiting,
|
|
715
1163
|
shouldReduceMotion
|
|
716
1164
|
);
|
|
1165
|
+
const readSharedStyles = () => {
|
|
1166
|
+
if (!hasLayoutId) return void 0;
|
|
1167
|
+
const out = {};
|
|
1168
|
+
let any = false;
|
|
1169
|
+
for (const key of activeKeysRef.current) {
|
|
1170
|
+
if (!SHARED_STYLE_KEY_SET.has(key)) continue;
|
|
1171
|
+
const v = sharedValues[key].value;
|
|
1172
|
+
if (typeof v !== "number" && typeof v !== "string") continue;
|
|
1173
|
+
out[key] = v;
|
|
1174
|
+
any = true;
|
|
1175
|
+
}
|
|
1176
|
+
return any ? out : void 0;
|
|
1177
|
+
};
|
|
717
1178
|
const sharedLayout = useSharedLayout({
|
|
718
1179
|
layoutId,
|
|
719
1180
|
userRef: ref,
|
|
720
|
-
transition:
|
|
1181
|
+
transition: chunkPM6CVGXJ_js.isTopLevelTransition(transition) ? transition : void 0,
|
|
721
1182
|
shouldReduceMotion,
|
|
722
|
-
userOnLayout
|
|
1183
|
+
userOnLayout,
|
|
1184
|
+
readStyles: readSharedStyles
|
|
723
1185
|
});
|
|
724
1186
|
const flip = sharedLayout.flip;
|
|
725
|
-
const
|
|
1187
|
+
const carry = sharedLayout.carry;
|
|
726
1188
|
const animatedStyle = Animated.useAnimatedStyle(() => {
|
|
727
1189
|
const activeKeys2 = activeKeysRef.current;
|
|
728
1190
|
const hasTransform = hasTransformRef.current;
|
|
729
1191
|
const hasShadowOffset = hasShadowOffsetRef.current;
|
|
1192
|
+
const hasBoxShadow = hasBoxShadowRef.current;
|
|
730
1193
|
const out = {};
|
|
731
1194
|
const transform = [];
|
|
732
1195
|
let shadowOffsetW = 0;
|
|
@@ -735,12 +1198,15 @@ function createMotionComponent(Component) {
|
|
|
735
1198
|
const pf = focusedProgress.value;
|
|
736
1199
|
const pfv = focusVisibleProgress.value;
|
|
737
1200
|
const pp = pressedProgress.value;
|
|
1201
|
+
const carried = carry.snapshot.value;
|
|
1202
|
+
const pc = carry.progress.value;
|
|
738
1203
|
const layers = gestureSV.value;
|
|
739
1204
|
const hoveredLayer = layers ? layers.hovered : null;
|
|
740
1205
|
const focusedLayer = layers ? layers.focused : null;
|
|
741
1206
|
const focusVisibleLayer = layers ? layers.focusVisible : null;
|
|
742
1207
|
const pressedLayer = layers ? layers.pressed : null;
|
|
743
1208
|
for (const key of activeKeys2) {
|
|
1209
|
+
if (key === "boxShadow") continue;
|
|
744
1210
|
let v = sharedValues[key].value;
|
|
745
1211
|
const isColor = COLOR_KEY_SET.has(key);
|
|
746
1212
|
if (hoveredLayer && ph > 0 && hoveredLayer[key] !== void 0) {
|
|
@@ -759,6 +1225,12 @@ function createMotionComponent(Component) {
|
|
|
759
1225
|
const t = pressedLayer[key];
|
|
760
1226
|
v = isColor ? Animated.interpolateColor(pp, [0, 1], [v, t]) : v + (t - v) * pp;
|
|
761
1227
|
}
|
|
1228
|
+
if (carried !== null && pc > 0) {
|
|
1229
|
+
const s = carried[key];
|
|
1230
|
+
if (s !== void 0) {
|
|
1231
|
+
v = isColor ? Animated.interpolateColor(pc, [0, 1], [v, s]) : v + (s - v) * pc;
|
|
1232
|
+
}
|
|
1233
|
+
}
|
|
762
1234
|
if (TRANSFORM_KEY_SET.has(key)) {
|
|
763
1235
|
transform.push(
|
|
764
1236
|
ROTATION_KEYS.has(key) ? { [key]: `${v}deg` } : { [key]: v }
|
|
@@ -781,6 +1253,19 @@ function createMotionComponent(Component) {
|
|
|
781
1253
|
if (hasShadowOffset) {
|
|
782
1254
|
out.shadowOffset = { width: shadowOffsetW, height: shadowOffsetH };
|
|
783
1255
|
}
|
|
1256
|
+
if (hasBoxShadow) {
|
|
1257
|
+
const layers2 = sharedValues.boxShadow.value;
|
|
1258
|
+
const insets = boxShadowInsets.value;
|
|
1259
|
+
if (insets === null) {
|
|
1260
|
+
out.boxShadow = layers2;
|
|
1261
|
+
} else {
|
|
1262
|
+
const withInset = [];
|
|
1263
|
+
for (let i = 0; i < layers2.length; i++) {
|
|
1264
|
+
withInset.push({ ...layers2[i], inset: insets[i] });
|
|
1265
|
+
}
|
|
1266
|
+
out.boxShadow = withInset;
|
|
1267
|
+
}
|
|
1268
|
+
}
|
|
784
1269
|
return out;
|
|
785
1270
|
});
|
|
786
1271
|
const mergedStyle = react.useMemo(
|
|
@@ -795,7 +1280,7 @@ function createMotionComponent(Component) {
|
|
|
795
1280
|
setFocusVisible,
|
|
796
1281
|
setHovered
|
|
797
1282
|
);
|
|
798
|
-
const layoutSig =
|
|
1283
|
+
const layoutSig = chunkPM6CVGXJ_js.stableSig(layout);
|
|
799
1284
|
const layoutTransition = react.useMemo(
|
|
800
1285
|
() => shouldReduceMotion ? void 0 : resolveLayoutTransition(layout),
|
|
801
1286
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
@@ -843,60 +1328,15 @@ function hasMotionProps(props) {
|
|
|
843
1328
|
return false;
|
|
844
1329
|
}
|
|
845
1330
|
function useAnimatableSharedValues(init) {
|
|
846
|
-
const
|
|
847
|
-
const
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
const scaleY = Animated.useSharedValue(init("scaleY"));
|
|
851
|
-
const rotate = Animated.useSharedValue(init("rotate"));
|
|
852
|
-
const rotateX = Animated.useSharedValue(init("rotateX"));
|
|
853
|
-
const rotateY = Animated.useSharedValue(init("rotateY"));
|
|
854
|
-
const opacity = Animated.useSharedValue(init("opacity"));
|
|
855
|
-
const width = Animated.useSharedValue(init("width"));
|
|
856
|
-
const height = Animated.useSharedValue(init("height"));
|
|
857
|
-
const borderRadius = Animated.useSharedValue(init("borderRadius"));
|
|
858
|
-
const shadowOpacity = Animated.useSharedValue(init("shadowOpacity"));
|
|
859
|
-
const shadowRadius = Animated.useSharedValue(init("shadowRadius"));
|
|
860
|
-
const elevation = Animated.useSharedValue(init("elevation"));
|
|
861
|
-
const backgroundColor = Animated.useSharedValue(
|
|
862
|
-
init("backgroundColor")
|
|
863
|
-
);
|
|
864
|
-
const borderColor = Animated.useSharedValue(init("borderColor"));
|
|
865
|
-
const color = Animated.useSharedValue(init("color"));
|
|
866
|
-
const tintColor = Animated.useSharedValue(init("tintColor"));
|
|
867
|
-
const shadowColor = Animated.useSharedValue(init("shadowColor"));
|
|
868
|
-
const shadowOffsetWidth = Animated.useSharedValue(
|
|
869
|
-
init("shadowOffsetWidth")
|
|
870
|
-
);
|
|
871
|
-
const shadowOffsetHeight = Animated.useSharedValue(
|
|
872
|
-
init("shadowOffsetHeight")
|
|
873
|
-
);
|
|
1331
|
+
const entries = [];
|
|
1332
|
+
for (const key of ALL_KEYS) {
|
|
1333
|
+
entries.push([key, Animated.useSharedValue(init(key))]);
|
|
1334
|
+
}
|
|
874
1335
|
const ref = react.useRef(null);
|
|
875
1336
|
if (ref.current === null) {
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
scale,
|
|
880
|
-
scaleX,
|
|
881
|
-
scaleY,
|
|
882
|
-
rotate,
|
|
883
|
-
rotateX,
|
|
884
|
-
rotateY,
|
|
885
|
-
opacity,
|
|
886
|
-
width,
|
|
887
|
-
height,
|
|
888
|
-
borderRadius,
|
|
889
|
-
shadowOpacity,
|
|
890
|
-
shadowRadius,
|
|
891
|
-
elevation,
|
|
892
|
-
backgroundColor,
|
|
893
|
-
borderColor,
|
|
894
|
-
color,
|
|
895
|
-
tintColor,
|
|
896
|
-
shadowColor,
|
|
897
|
-
shadowOffsetWidth,
|
|
898
|
-
shadowOffsetHeight
|
|
899
|
-
};
|
|
1337
|
+
const map2 = {};
|
|
1338
|
+
for (const [key, sv] of entries) map2[key] = sv;
|
|
1339
|
+
ref.current = map2;
|
|
900
1340
|
}
|
|
901
1341
|
const map = ref.current;
|
|
902
1342
|
react.useEffect(
|
|
@@ -980,6 +1420,20 @@ function shadowOffsetAxisFor(key) {
|
|
|
980
1420
|
function shadowOffsetAxisValue(source, axis) {
|
|
981
1421
|
return source?.[axis];
|
|
982
1422
|
}
|
|
1423
|
+
function driveBoxShadow(slot, insetSlot, target, cfg, factory) {
|
|
1424
|
+
const currentLayers = Array.isArray(slot.value) ? slot.value : NO_BOX_SHADOW;
|
|
1425
|
+
const { from, to, insets } = prepareBoxShadowAnimation(
|
|
1426
|
+
{ layers: [...currentLayers], insets: insetSlot.value },
|
|
1427
|
+
target
|
|
1428
|
+
);
|
|
1429
|
+
insetSlot.value = insets;
|
|
1430
|
+
if (from.length !== currentLayers.length) slot.value = from;
|
|
1431
|
+
slot.value = chunkPM6CVGXJ_js.resolveTransition(
|
|
1432
|
+
cfg,
|
|
1433
|
+
to,
|
|
1434
|
+
factory?.("animation", void 0)
|
|
1435
|
+
);
|
|
1436
|
+
}
|
|
983
1437
|
function styleValueFor(flat, key) {
|
|
984
1438
|
if (SHADOW_OFFSET_KEY_SET.has(key)) {
|
|
985
1439
|
return shadowOffsetAxisValue(
|
|
@@ -1096,6 +1550,15 @@ function resolveGestureLayers(gesture) {
|
|
|
1096
1550
|
if (!subState) continue;
|
|
1097
1551
|
const resolved = {};
|
|
1098
1552
|
for (const key of ALL_KEYS) {
|
|
1553
|
+
if (STRUCTURED_KEY_SET.has(key)) {
|
|
1554
|
+
if (__DEV__ && subState[key] !== void 0) {
|
|
1555
|
+
chunkPM6CVGXJ_js.warnOnce(
|
|
1556
|
+
`gesture-structured-${layer}-${key}`,
|
|
1557
|
+
`[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\`.`
|
|
1558
|
+
);
|
|
1559
|
+
}
|
|
1560
|
+
continue;
|
|
1561
|
+
}
|
|
1099
1562
|
if (SHADOW_OFFSET_KEY_SET.has(key)) {
|
|
1100
1563
|
const axis = shadowOffsetAxisFor(key);
|
|
1101
1564
|
const so = subState.shadowOffset;
|
|
@@ -1113,7 +1576,7 @@ function resolveGestureLayers(gesture) {
|
|
|
1113
1576
|
return out;
|
|
1114
1577
|
}
|
|
1115
1578
|
function useGestureLayerProgress(progress, active, declared, layer, transition, isExiting, shouldReduceMotion) {
|
|
1116
|
-
const layerCfgSig =
|
|
1579
|
+
const layerCfgSig = chunkPM6CVGXJ_js.stableSig(gestureLayerTransitionFor(layer, transition));
|
|
1117
1580
|
react.useEffect(() => {
|
|
1118
1581
|
if (!declared) return;
|
|
1119
1582
|
if (isExiting) {
|
|
@@ -1122,7 +1585,7 @@ function useGestureLayerProgress(progress, active, declared, layer, transition,
|
|
|
1122
1585
|
}
|
|
1123
1586
|
const target = active ? 1 : 0;
|
|
1124
1587
|
const cfg = shouldReduceMotion ? { type: "no-animation" } : gestureLayerTransitionFor(layer, transition) ?? { type: "spring" };
|
|
1125
|
-
progress.value =
|
|
1588
|
+
progress.value = chunkPM6CVGXJ_js.resolveTransition(cfg, target);
|
|
1126
1589
|
}, [active, declared, isExiting, shouldReduceMotion, layerCfgSig]);
|
|
1127
1590
|
}
|
|
1128
1591
|
function useGestureHandlers(gesture, rest, setPressed, setFocused, setFocusVisible, setHovered) {
|
|
@@ -1146,7 +1609,7 @@ function useGestureHandlers(gesture, rest, setPressed, setFocused, setFocusVisib
|
|
|
1146
1609
|
if (gesture.focused || gesture.focusVisible) {
|
|
1147
1610
|
handlers.onFocus = compose(rest.onFocus, () => {
|
|
1148
1611
|
if (gesture.focused) setFocused(true);
|
|
1149
|
-
if (gesture.focusVisible &&
|
|
1612
|
+
if (gesture.focusVisible && chunkOBRGJAST_js.isFocusVisible()) setFocusVisible(true);
|
|
1150
1613
|
});
|
|
1151
1614
|
handlers.onBlur = compose(rest.onBlur, () => {
|
|
1152
1615
|
if (gesture.focused) setFocused(false);
|
|
@@ -1187,4 +1650,6 @@ function compose(user, ours) {
|
|
|
1187
1650
|
|
|
1188
1651
|
exports.Presence = Presence;
|
|
1189
1652
|
exports.createMotionComponent = createMotionComponent;
|
|
1653
|
+
exports.pairBoxShadowLayers = pairBoxShadowLayers;
|
|
1654
|
+
exports.resolveBoxShadowInput = resolveBoxShadowInput;
|
|
1190
1655
|
exports.usePresence = usePresence;
|