@onlynative/inertia 0.0.1-alpha.2 → 0.0.1-alpha.3
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/README.md +29 -2
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +170 -58
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +171 -59
- package/dist/index.mjs.map +1 -1
- package/dist/motion/Image.d.mts +1 -1
- package/dist/motion/Image.d.ts +1 -1
- package/dist/motion/Image.js +170 -58
- package/dist/motion/Image.js.map +1 -1
- package/dist/motion/Image.mjs +171 -59
- package/dist/motion/Image.mjs.map +1 -1
- package/dist/motion/Pressable.d.mts +1 -1
- package/dist/motion/Pressable.d.ts +1 -1
- package/dist/motion/Pressable.js +170 -58
- package/dist/motion/Pressable.js.map +1 -1
- package/dist/motion/Pressable.mjs +171 -59
- package/dist/motion/Pressable.mjs.map +1 -1
- package/dist/motion/ScrollView.d.mts +1 -1
- package/dist/motion/ScrollView.d.ts +1 -1
- package/dist/motion/ScrollView.js +170 -58
- package/dist/motion/ScrollView.js.map +1 -1
- package/dist/motion/ScrollView.mjs +171 -59
- package/dist/motion/ScrollView.mjs.map +1 -1
- package/dist/motion/Text.d.mts +1 -1
- package/dist/motion/Text.d.ts +1 -1
- package/dist/motion/Text.js +170 -58
- package/dist/motion/Text.js.map +1 -1
- package/dist/motion/Text.mjs +171 -59
- package/dist/motion/Text.mjs.map +1 -1
- package/dist/motion/View.d.mts +1 -1
- package/dist/motion/View.d.ts +1 -1
- package/dist/motion/View.js +170 -58
- package/dist/motion/View.js.map +1 -1
- package/dist/motion/View.mjs +171 -59
- package/dist/motion/View.mjs.map +1 -1
- package/dist/{types-DeZZzE_e.d.mts → types-DAhX3fC2.d.mts} +40 -16
- package/dist/{types-DeZZzE_e.d.ts → types-DAhX3fC2.d.ts} +40 -16
- package/llms.txt +25 -2
- package/package.json +1 -1
- package/src/motion/createMotionComponent.tsx +258 -97
- package/src/motion/installCheck.ts +69 -0
- package/src/types.ts +44 -16
package/dist/motion/Image.mjs
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import { Image, Platform } from 'react-native';
|
|
2
2
|
import { createContext, forwardRef, useRef, useState, useEffect, useMemo, useContext } from 'react';
|
|
3
|
-
import Animated, { useAnimatedStyle,
|
|
3
|
+
import Animated, { useSharedValue, useAnimatedStyle, interpolateColor, useReducedMotion, withSequence, runOnJS, withRepeat, withDelay, withDecay, withTiming, Easing, withSpring, isWorkletFunction } from 'react-native-reanimated';
|
|
4
4
|
import { jsx } from 'react/jsx-runtime';
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
7
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
8
|
+
}) : x)(function(x) {
|
|
9
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
10
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
11
|
+
});
|
|
7
12
|
var DEFAULT_MOTION_CONFIG = {
|
|
8
13
|
reducedMotion: "user"
|
|
9
14
|
};
|
|
@@ -178,6 +183,40 @@ function mergeTransition(base, override) {
|
|
|
178
183
|
}
|
|
179
184
|
return { ...base ?? { type: "spring" }, ...override };
|
|
180
185
|
}
|
|
186
|
+
|
|
187
|
+
// src/motion/installCheck.ts
|
|
188
|
+
var alreadyChecked = false;
|
|
189
|
+
function ensureReanimatedInstalled() {
|
|
190
|
+
if (!__DEV__ || alreadyChecked) return;
|
|
191
|
+
if (typeof process !== "undefined" && process.env?.NODE_ENV === "test") {
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
alreadyChecked = true;
|
|
195
|
+
let version;
|
|
196
|
+
try {
|
|
197
|
+
const pkg = __require("react-native-reanimated/package.json");
|
|
198
|
+
version = pkg.version;
|
|
199
|
+
} catch {
|
|
200
|
+
}
|
|
201
|
+
if (version) {
|
|
202
|
+
const major = parseInt(version.split(".")[0] ?? "0", 10);
|
|
203
|
+
if (major < 4) {
|
|
204
|
+
console.error(
|
|
205
|
+
`[inertia] react-native-reanimated v${version} is installed, but @onlynative/inertia requires v4.0.0 or later. Upgrade with \`pnpm add react-native-reanimated@^4\` (or your package manager's equivalent).`
|
|
206
|
+
);
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
const probe = function probe2() {
|
|
211
|
+
"worklet";
|
|
212
|
+
return 0;
|
|
213
|
+
};
|
|
214
|
+
if (typeof probe.__workletHash !== "number") {
|
|
215
|
+
console.error(
|
|
216
|
+
`[inertia] The Reanimated worklets babel plugin is not configured. Add \`'react-native-worklets/plugin'\` as the LAST entry in the \`plugins\` array of your \`babel.config.js\`, then restart Metro with a fresh cache: \`npx expo start -c\` or \`npx react-native start --reset-cache\`.`
|
|
217
|
+
);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
181
220
|
var TRANSFORM_KEYS = [
|
|
182
221
|
"translateX",
|
|
183
222
|
"translateY",
|
|
@@ -204,6 +243,14 @@ var ALL_KEYS = [
|
|
|
204
243
|
...COLOR_KEYS
|
|
205
244
|
];
|
|
206
245
|
var TRANSFORM_KEY_SET = new Set(TRANSFORM_KEYS);
|
|
246
|
+
var COLOR_KEY_SET = new Set(COLOR_KEYS);
|
|
247
|
+
var GESTURE_LAYER_NAMES = [
|
|
248
|
+
"hovered",
|
|
249
|
+
"focused",
|
|
250
|
+
"focusVisible",
|
|
251
|
+
"pressed"
|
|
252
|
+
];
|
|
253
|
+
var GESTURE_LAYER_NAME_SET = new Set(GESTURE_LAYER_NAMES);
|
|
207
254
|
var EXITING_POINTER_EVENTS_STYLE = { pointerEvents: "none" };
|
|
208
255
|
var DEFAULT_RESTING = {
|
|
209
256
|
translateX: 0,
|
|
@@ -249,10 +296,18 @@ function isTopLevelTransition(t) {
|
|
|
249
296
|
function transitionFor(prop, transition) {
|
|
250
297
|
if (!transition) return void 0;
|
|
251
298
|
if (isTopLevelTransition(transition)) return transition;
|
|
299
|
+
if (GESTURE_LAYER_NAME_SET.has(prop)) return void 0;
|
|
252
300
|
return transition[prop];
|
|
253
301
|
}
|
|
302
|
+
function gestureLayerTransitionFor(layer, transition) {
|
|
303
|
+
if (!transition) return void 0;
|
|
304
|
+
if (isTopLevelTransition(transition)) return transition;
|
|
305
|
+
return transition[layer];
|
|
306
|
+
}
|
|
254
307
|
function createMotionComponent(Component) {
|
|
308
|
+
ensureReanimatedInstalled();
|
|
255
309
|
const AnimatedComponent = Animated.createAnimatedComponent(
|
|
310
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
256
311
|
Component
|
|
257
312
|
);
|
|
258
313
|
const Motion = forwardRef(function Motion2(props, ref) {
|
|
@@ -331,13 +386,19 @@ function createMotionComponent(Component) {
|
|
|
331
386
|
}
|
|
332
387
|
return initialRecord?.[key] ?? restValue(animateRecord[key]) ?? DEFAULT_RESTING[key];
|
|
333
388
|
});
|
|
334
|
-
const
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
389
|
+
const pressedProgress = useSharedValue(0);
|
|
390
|
+
const focusedProgress = useSharedValue(0);
|
|
391
|
+
const focusVisibleProgress = useSharedValue(0);
|
|
392
|
+
const hoveredProgress = useSharedValue(0);
|
|
393
|
+
const gestureSV = useSharedValue(
|
|
394
|
+
resolveGestureLayers(gesture)
|
|
395
|
+
);
|
|
396
|
+
const gestureTargetsSig = stableSig(gesture);
|
|
397
|
+
useEffect(() => {
|
|
398
|
+
gestureSV.value = resolveGestureLayers(gesture);
|
|
399
|
+
}, [gestureTargetsSig]);
|
|
400
|
+
const baseRecord = isExiting && exitRecord ? { ...animateRecord, ...exitRecord } : animateRecord;
|
|
401
|
+
const baseSig = stableSig(baseRecord) + (isExiting ? "|exit" : "") + (shouldReduceMotion ? "|rm" : "");
|
|
341
402
|
const transitionSig = stableSig(transition);
|
|
342
403
|
const safeToRemoveRef = useRef(void 0);
|
|
343
404
|
safeToRemoveRef.current = presence?.safeToRemove;
|
|
@@ -358,13 +419,13 @@ function createMotionComponent(Component) {
|
|
|
358
419
|
};
|
|
359
420
|
let transformPending = 0;
|
|
360
421
|
for (const k of ALL_KEYS) {
|
|
361
|
-
if (TRANSFORM_KEY_SET.has(k) &&
|
|
422
|
+
if (TRANSFORM_KEY_SET.has(k) && baseRecord[k] !== void 0) {
|
|
362
423
|
transformPending++;
|
|
363
424
|
}
|
|
364
425
|
}
|
|
365
426
|
const transformGroup = transformPending > 0 ? { remaining: transformPending } : void 0;
|
|
366
427
|
for (const key of ALL_KEYS) {
|
|
367
|
-
const target =
|
|
428
|
+
const target = baseRecord[key];
|
|
368
429
|
if (target === void 0) continue;
|
|
369
430
|
const cfg = shouldReduceMotion ? { type: "no-animation" } : transitionFor(key, transition);
|
|
370
431
|
if (isExiting) pending++;
|
|
@@ -389,14 +450,76 @@ function createMotionComponent(Component) {
|
|
|
389
450
|
if (isExiting && pending === 0) {
|
|
390
451
|
safeToRemoveRef.current?.();
|
|
391
452
|
}
|
|
392
|
-
}, [
|
|
453
|
+
}, [baseSig, transitionSig]);
|
|
454
|
+
useGestureLayerProgress(
|
|
455
|
+
pressedProgress,
|
|
456
|
+
pressed,
|
|
457
|
+
gesture?.pressed != null,
|
|
458
|
+
"pressed",
|
|
459
|
+
transition,
|
|
460
|
+
isExiting,
|
|
461
|
+
shouldReduceMotion
|
|
462
|
+
);
|
|
463
|
+
useGestureLayerProgress(
|
|
464
|
+
focusedProgress,
|
|
465
|
+
focused,
|
|
466
|
+
gesture?.focused != null,
|
|
467
|
+
"focused",
|
|
468
|
+
transition,
|
|
469
|
+
isExiting,
|
|
470
|
+
shouldReduceMotion
|
|
471
|
+
);
|
|
472
|
+
useGestureLayerProgress(
|
|
473
|
+
focusVisibleProgress,
|
|
474
|
+
focusVisible,
|
|
475
|
+
gesture?.focusVisible != null,
|
|
476
|
+
"focusVisible",
|
|
477
|
+
transition,
|
|
478
|
+
isExiting,
|
|
479
|
+
shouldReduceMotion
|
|
480
|
+
);
|
|
481
|
+
useGestureLayerProgress(
|
|
482
|
+
hoveredProgress,
|
|
483
|
+
hovered,
|
|
484
|
+
gesture?.hovered != null,
|
|
485
|
+
"hovered",
|
|
486
|
+
transition,
|
|
487
|
+
isExiting,
|
|
488
|
+
shouldReduceMotion
|
|
489
|
+
);
|
|
393
490
|
const animatedStyle = useAnimatedStyle(() => {
|
|
394
491
|
const activeKeys = activeKeysRef.current;
|
|
395
492
|
const hasTransform = hasTransformRef.current;
|
|
396
493
|
const out = {};
|
|
397
494
|
const transform = [];
|
|
495
|
+
const ph = hoveredProgress.value;
|
|
496
|
+
const pf = focusedProgress.value;
|
|
497
|
+
const pfv = focusVisibleProgress.value;
|
|
498
|
+
const pp = pressedProgress.value;
|
|
499
|
+
const layers = gestureSV.value;
|
|
500
|
+
const hoveredLayer = layers ? layers.hovered : null;
|
|
501
|
+
const focusedLayer = layers ? layers.focused : null;
|
|
502
|
+
const focusVisibleLayer = layers ? layers.focusVisible : null;
|
|
503
|
+
const pressedLayer = layers ? layers.pressed : null;
|
|
398
504
|
for (const key of activeKeys) {
|
|
399
|
-
|
|
505
|
+
let v = sharedValues[key].value;
|
|
506
|
+
const isColor = COLOR_KEY_SET.has(key);
|
|
507
|
+
if (hoveredLayer && ph > 0 && hoveredLayer[key] !== void 0) {
|
|
508
|
+
const t = hoveredLayer[key];
|
|
509
|
+
v = isColor ? interpolateColor(ph, [0, 1], [v, t]) : v + (t - v) * ph;
|
|
510
|
+
}
|
|
511
|
+
if (focusedLayer && pf > 0 && focusedLayer[key] !== void 0) {
|
|
512
|
+
const t = focusedLayer[key];
|
|
513
|
+
v = isColor ? interpolateColor(pf, [0, 1], [v, t]) : v + (t - v) * pf;
|
|
514
|
+
}
|
|
515
|
+
if (focusVisibleLayer && pfv > 0 && focusVisibleLayer[key] !== void 0) {
|
|
516
|
+
const t = focusVisibleLayer[key];
|
|
517
|
+
v = isColor ? interpolateColor(pfv, [0, 1], [v, t]) : v + (t - v) * pfv;
|
|
518
|
+
}
|
|
519
|
+
if (pressedLayer && pp > 0 && pressedLayer[key] !== void 0) {
|
|
520
|
+
const t = pressedLayer[key];
|
|
521
|
+
v = isColor ? interpolateColor(pp, [0, 1], [v, t]) : v + (t - v) * pp;
|
|
522
|
+
}
|
|
400
523
|
if (TRANSFORM_KEY_SET.has(key)) {
|
|
401
524
|
transform.push(
|
|
402
525
|
key === "rotate" ? { rotate: `${v}deg` } : { [key]: v }
|
|
@@ -615,52 +738,41 @@ function stableStringify(v) {
|
|
|
615
738
|
const keys = Object.keys(obj).sort();
|
|
616
739
|
return "{" + keys.map((k) => JSON.stringify(k) + ":" + stableStringify(obj[k])).join(",") + "}";
|
|
617
740
|
}
|
|
618
|
-
function
|
|
619
|
-
if (!gesture) return
|
|
620
|
-
const
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
if (!sub) continue;
|
|
631
|
-
for (const k of ALL_KEYS) {
|
|
632
|
-
if (k in sub && !(k in merged)) {
|
|
633
|
-
merged[k] = DEFAULT_RESTING[k];
|
|
634
|
-
}
|
|
741
|
+
function resolveGestureLayers(gesture) {
|
|
742
|
+
if (!gesture) return null;
|
|
743
|
+
const out = {};
|
|
744
|
+
for (const layer of GESTURE_LAYER_NAMES) {
|
|
745
|
+
const subState = gesture[layer];
|
|
746
|
+
if (!subState) continue;
|
|
747
|
+
const resolved = {};
|
|
748
|
+
for (const key of ALL_KEYS) {
|
|
749
|
+
const raw = subState[key];
|
|
750
|
+
if (raw === void 0) continue;
|
|
751
|
+
const t = targetEndValue(raw);
|
|
752
|
+
if (t !== void 0) resolved[key] = t;
|
|
635
753
|
}
|
|
754
|
+
out[layer] = resolved;
|
|
636
755
|
}
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
merged,
|
|
652
|
-
gesture.focusVisible
|
|
653
|
-
);
|
|
654
|
-
}
|
|
655
|
-
if (active.pressed && gesture.pressed) {
|
|
656
|
-
Object.assign(
|
|
657
|
-
merged,
|
|
658
|
-
gesture.pressed
|
|
659
|
-
);
|
|
660
|
-
}
|
|
661
|
-
return merged;
|
|
756
|
+
return out;
|
|
757
|
+
}
|
|
758
|
+
function useGestureLayerProgress(progress, active, declared, layer, transition, isExiting, shouldReduceMotion) {
|
|
759
|
+
const layerCfgSig = stableSig(gestureLayerTransitionFor(layer, transition));
|
|
760
|
+
useEffect(() => {
|
|
761
|
+
if (!declared) return;
|
|
762
|
+
if (isExiting) {
|
|
763
|
+
progress.value = 0;
|
|
764
|
+
return;
|
|
765
|
+
}
|
|
766
|
+
const target = active ? 1 : 0;
|
|
767
|
+
const cfg = shouldReduceMotion ? { type: "no-animation" } : gestureLayerTransitionFor(layer, transition) ?? { type: "spring" };
|
|
768
|
+
progress.value = resolveTransition(cfg, target);
|
|
769
|
+
}, [active, declared, isExiting, shouldReduceMotion, layerCfgSig]);
|
|
662
770
|
}
|
|
663
771
|
function useGestureHandlers(gesture, rest, setPressed, setFocused, setFocusVisible, setHovered) {
|
|
772
|
+
const hasPressed = gesture?.pressed ? 1 : 0;
|
|
773
|
+
const hasFocused = gesture?.focused ? 1 : 0;
|
|
774
|
+
const hasFocusVisible = gesture?.focusVisible ? 1 : 0;
|
|
775
|
+
const hasHovered = gesture?.hovered ? 1 : 0;
|
|
664
776
|
return useMemo(() => {
|
|
665
777
|
if (!gesture) return {};
|
|
666
778
|
const handlers = {};
|
|
@@ -693,10 +805,10 @@ function useGestureHandlers(gesture, rest, setPressed, setFocused, setFocusVisib
|
|
|
693
805
|
}
|
|
694
806
|
return handlers;
|
|
695
807
|
}, [
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
808
|
+
hasPressed,
|
|
809
|
+
hasFocused,
|
|
810
|
+
hasFocusVisible,
|
|
811
|
+
hasHovered,
|
|
700
812
|
rest.onTouchStart,
|
|
701
813
|
rest.onTouchEnd,
|
|
702
814
|
rest.onTouchCancel,
|