@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/index.mjs
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import { Image, Pressable, ScrollView, Text, View, Platform } from 'react-native';
|
|
2
2
|
import { createContext, forwardRef, useRef, useState, useEffect, useMemo, useContext, Children, isValidElement, useCallback } 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, Fragment } 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
|
};
|
|
@@ -279,6 +284,40 @@ function mergeTransition(base, override) {
|
|
|
279
284
|
}
|
|
280
285
|
return { ...base ?? { type: "spring" }, ...override };
|
|
281
286
|
}
|
|
287
|
+
|
|
288
|
+
// src/motion/installCheck.ts
|
|
289
|
+
var alreadyChecked = false;
|
|
290
|
+
function ensureReanimatedInstalled() {
|
|
291
|
+
if (!__DEV__ || alreadyChecked) return;
|
|
292
|
+
if (typeof process !== "undefined" && process.env?.NODE_ENV === "test") {
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
alreadyChecked = true;
|
|
296
|
+
let version;
|
|
297
|
+
try {
|
|
298
|
+
const pkg = __require("react-native-reanimated/package.json");
|
|
299
|
+
version = pkg.version;
|
|
300
|
+
} catch {
|
|
301
|
+
}
|
|
302
|
+
if (version) {
|
|
303
|
+
const major = parseInt(version.split(".")[0] ?? "0", 10);
|
|
304
|
+
if (major < 4) {
|
|
305
|
+
console.error(
|
|
306
|
+
`[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).`
|
|
307
|
+
);
|
|
308
|
+
return;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
const probe = function probe2() {
|
|
312
|
+
"worklet";
|
|
313
|
+
return 0;
|
|
314
|
+
};
|
|
315
|
+
if (typeof probe.__workletHash !== "number") {
|
|
316
|
+
console.error(
|
|
317
|
+
`[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\`.`
|
|
318
|
+
);
|
|
319
|
+
}
|
|
320
|
+
}
|
|
282
321
|
var TRANSFORM_KEYS = [
|
|
283
322
|
"translateX",
|
|
284
323
|
"translateY",
|
|
@@ -305,6 +344,14 @@ var ALL_KEYS = [
|
|
|
305
344
|
...COLOR_KEYS
|
|
306
345
|
];
|
|
307
346
|
var TRANSFORM_KEY_SET = new Set(TRANSFORM_KEYS);
|
|
347
|
+
var COLOR_KEY_SET = new Set(COLOR_KEYS);
|
|
348
|
+
var GESTURE_LAYER_NAMES = [
|
|
349
|
+
"hovered",
|
|
350
|
+
"focused",
|
|
351
|
+
"focusVisible",
|
|
352
|
+
"pressed"
|
|
353
|
+
];
|
|
354
|
+
var GESTURE_LAYER_NAME_SET = new Set(GESTURE_LAYER_NAMES);
|
|
308
355
|
var EXITING_POINTER_EVENTS_STYLE = { pointerEvents: "none" };
|
|
309
356
|
var DEFAULT_RESTING = {
|
|
310
357
|
translateX: 0,
|
|
@@ -350,10 +397,18 @@ function isTopLevelTransition(t) {
|
|
|
350
397
|
function transitionFor(prop, transition) {
|
|
351
398
|
if (!transition) return void 0;
|
|
352
399
|
if (isTopLevelTransition(transition)) return transition;
|
|
400
|
+
if (GESTURE_LAYER_NAME_SET.has(prop)) return void 0;
|
|
353
401
|
return transition[prop];
|
|
354
402
|
}
|
|
403
|
+
function gestureLayerTransitionFor(layer, transition) {
|
|
404
|
+
if (!transition) return void 0;
|
|
405
|
+
if (isTopLevelTransition(transition)) return transition;
|
|
406
|
+
return transition[layer];
|
|
407
|
+
}
|
|
355
408
|
function createMotionComponent(Component) {
|
|
409
|
+
ensureReanimatedInstalled();
|
|
356
410
|
const AnimatedComponent = Animated.createAnimatedComponent(
|
|
411
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
357
412
|
Component
|
|
358
413
|
);
|
|
359
414
|
const Motion2 = forwardRef(function Motion3(props, ref) {
|
|
@@ -432,13 +487,19 @@ function createMotionComponent(Component) {
|
|
|
432
487
|
}
|
|
433
488
|
return initialRecord?.[key] ?? restValue(animateRecord[key]) ?? DEFAULT_RESTING[key];
|
|
434
489
|
});
|
|
435
|
-
const
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
490
|
+
const pressedProgress = useSharedValue(0);
|
|
491
|
+
const focusedProgress = useSharedValue(0);
|
|
492
|
+
const focusVisibleProgress = useSharedValue(0);
|
|
493
|
+
const hoveredProgress = useSharedValue(0);
|
|
494
|
+
const gestureSV = useSharedValue(
|
|
495
|
+
resolveGestureLayers(gesture)
|
|
496
|
+
);
|
|
497
|
+
const gestureTargetsSig = stableSig(gesture);
|
|
498
|
+
useEffect(() => {
|
|
499
|
+
gestureSV.value = resolveGestureLayers(gesture);
|
|
500
|
+
}, [gestureTargetsSig]);
|
|
501
|
+
const baseRecord = isExiting && exitRecord ? { ...animateRecord, ...exitRecord } : animateRecord;
|
|
502
|
+
const baseSig = stableSig(baseRecord) + (isExiting ? "|exit" : "") + (shouldReduceMotion ? "|rm" : "");
|
|
442
503
|
const transitionSig = stableSig(transition);
|
|
443
504
|
const safeToRemoveRef = useRef(void 0);
|
|
444
505
|
safeToRemoveRef.current = presence?.safeToRemove;
|
|
@@ -459,13 +520,13 @@ function createMotionComponent(Component) {
|
|
|
459
520
|
};
|
|
460
521
|
let transformPending = 0;
|
|
461
522
|
for (const k of ALL_KEYS) {
|
|
462
|
-
if (TRANSFORM_KEY_SET.has(k) &&
|
|
523
|
+
if (TRANSFORM_KEY_SET.has(k) && baseRecord[k] !== void 0) {
|
|
463
524
|
transformPending++;
|
|
464
525
|
}
|
|
465
526
|
}
|
|
466
527
|
const transformGroup = transformPending > 0 ? { remaining: transformPending } : void 0;
|
|
467
528
|
for (const key of ALL_KEYS) {
|
|
468
|
-
const target =
|
|
529
|
+
const target = baseRecord[key];
|
|
469
530
|
if (target === void 0) continue;
|
|
470
531
|
const cfg = shouldReduceMotion ? { type: "no-animation" } : transitionFor(key, transition);
|
|
471
532
|
if (isExiting) pending++;
|
|
@@ -490,14 +551,76 @@ function createMotionComponent(Component) {
|
|
|
490
551
|
if (isExiting && pending === 0) {
|
|
491
552
|
safeToRemoveRef.current?.();
|
|
492
553
|
}
|
|
493
|
-
}, [
|
|
554
|
+
}, [baseSig, transitionSig]);
|
|
555
|
+
useGestureLayerProgress(
|
|
556
|
+
pressedProgress,
|
|
557
|
+
pressed,
|
|
558
|
+
gesture?.pressed != null,
|
|
559
|
+
"pressed",
|
|
560
|
+
transition,
|
|
561
|
+
isExiting,
|
|
562
|
+
shouldReduceMotion
|
|
563
|
+
);
|
|
564
|
+
useGestureLayerProgress(
|
|
565
|
+
focusedProgress,
|
|
566
|
+
focused,
|
|
567
|
+
gesture?.focused != null,
|
|
568
|
+
"focused",
|
|
569
|
+
transition,
|
|
570
|
+
isExiting,
|
|
571
|
+
shouldReduceMotion
|
|
572
|
+
);
|
|
573
|
+
useGestureLayerProgress(
|
|
574
|
+
focusVisibleProgress,
|
|
575
|
+
focusVisible,
|
|
576
|
+
gesture?.focusVisible != null,
|
|
577
|
+
"focusVisible",
|
|
578
|
+
transition,
|
|
579
|
+
isExiting,
|
|
580
|
+
shouldReduceMotion
|
|
581
|
+
);
|
|
582
|
+
useGestureLayerProgress(
|
|
583
|
+
hoveredProgress,
|
|
584
|
+
hovered,
|
|
585
|
+
gesture?.hovered != null,
|
|
586
|
+
"hovered",
|
|
587
|
+
transition,
|
|
588
|
+
isExiting,
|
|
589
|
+
shouldReduceMotion
|
|
590
|
+
);
|
|
494
591
|
const animatedStyle = useAnimatedStyle(() => {
|
|
495
592
|
const activeKeys = activeKeysRef.current;
|
|
496
593
|
const hasTransform = hasTransformRef.current;
|
|
497
594
|
const out = {};
|
|
498
595
|
const transform = [];
|
|
596
|
+
const ph = hoveredProgress.value;
|
|
597
|
+
const pf = focusedProgress.value;
|
|
598
|
+
const pfv = focusVisibleProgress.value;
|
|
599
|
+
const pp = pressedProgress.value;
|
|
600
|
+
const layers = gestureSV.value;
|
|
601
|
+
const hoveredLayer = layers ? layers.hovered : null;
|
|
602
|
+
const focusedLayer = layers ? layers.focused : null;
|
|
603
|
+
const focusVisibleLayer = layers ? layers.focusVisible : null;
|
|
604
|
+
const pressedLayer = layers ? layers.pressed : null;
|
|
499
605
|
for (const key of activeKeys) {
|
|
500
|
-
|
|
606
|
+
let v = sharedValues[key].value;
|
|
607
|
+
const isColor = COLOR_KEY_SET.has(key);
|
|
608
|
+
if (hoveredLayer && ph > 0 && hoveredLayer[key] !== void 0) {
|
|
609
|
+
const t = hoveredLayer[key];
|
|
610
|
+
v = isColor ? interpolateColor(ph, [0, 1], [v, t]) : v + (t - v) * ph;
|
|
611
|
+
}
|
|
612
|
+
if (focusedLayer && pf > 0 && focusedLayer[key] !== void 0) {
|
|
613
|
+
const t = focusedLayer[key];
|
|
614
|
+
v = isColor ? interpolateColor(pf, [0, 1], [v, t]) : v + (t - v) * pf;
|
|
615
|
+
}
|
|
616
|
+
if (focusVisibleLayer && pfv > 0 && focusVisibleLayer[key] !== void 0) {
|
|
617
|
+
const t = focusVisibleLayer[key];
|
|
618
|
+
v = isColor ? interpolateColor(pfv, [0, 1], [v, t]) : v + (t - v) * pfv;
|
|
619
|
+
}
|
|
620
|
+
if (pressedLayer && pp > 0 && pressedLayer[key] !== void 0) {
|
|
621
|
+
const t = pressedLayer[key];
|
|
622
|
+
v = isColor ? interpolateColor(pp, [0, 1], [v, t]) : v + (t - v) * pp;
|
|
623
|
+
}
|
|
501
624
|
if (TRANSFORM_KEY_SET.has(key)) {
|
|
502
625
|
transform.push(
|
|
503
626
|
key === "rotate" ? { rotate: `${v}deg` } : { [key]: v }
|
|
@@ -716,52 +839,41 @@ function stableStringify(v) {
|
|
|
716
839
|
const keys = Object.keys(obj).sort();
|
|
717
840
|
return "{" + keys.map((k) => JSON.stringify(k) + ":" + stableStringify(obj[k])).join(",") + "}";
|
|
718
841
|
}
|
|
719
|
-
function
|
|
720
|
-
if (!gesture) return
|
|
721
|
-
const
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
if (!sub) continue;
|
|
732
|
-
for (const k of ALL_KEYS) {
|
|
733
|
-
if (k in sub && !(k in merged)) {
|
|
734
|
-
merged[k] = DEFAULT_RESTING[k];
|
|
735
|
-
}
|
|
842
|
+
function resolveGestureLayers(gesture) {
|
|
843
|
+
if (!gesture) return null;
|
|
844
|
+
const out = {};
|
|
845
|
+
for (const layer of GESTURE_LAYER_NAMES) {
|
|
846
|
+
const subState = gesture[layer];
|
|
847
|
+
if (!subState) continue;
|
|
848
|
+
const resolved = {};
|
|
849
|
+
for (const key of ALL_KEYS) {
|
|
850
|
+
const raw = subState[key];
|
|
851
|
+
if (raw === void 0) continue;
|
|
852
|
+
const t = targetEndValue(raw);
|
|
853
|
+
if (t !== void 0) resolved[key] = t;
|
|
736
854
|
}
|
|
855
|
+
out[layer] = resolved;
|
|
737
856
|
}
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
merged,
|
|
753
|
-
gesture.focusVisible
|
|
754
|
-
);
|
|
755
|
-
}
|
|
756
|
-
if (active.pressed && gesture.pressed) {
|
|
757
|
-
Object.assign(
|
|
758
|
-
merged,
|
|
759
|
-
gesture.pressed
|
|
760
|
-
);
|
|
761
|
-
}
|
|
762
|
-
return merged;
|
|
857
|
+
return out;
|
|
858
|
+
}
|
|
859
|
+
function useGestureLayerProgress(progress, active, declared, layer, transition, isExiting, shouldReduceMotion) {
|
|
860
|
+
const layerCfgSig = stableSig(gestureLayerTransitionFor(layer, transition));
|
|
861
|
+
useEffect(() => {
|
|
862
|
+
if (!declared) return;
|
|
863
|
+
if (isExiting) {
|
|
864
|
+
progress.value = 0;
|
|
865
|
+
return;
|
|
866
|
+
}
|
|
867
|
+
const target = active ? 1 : 0;
|
|
868
|
+
const cfg = shouldReduceMotion ? { type: "no-animation" } : gestureLayerTransitionFor(layer, transition) ?? { type: "spring" };
|
|
869
|
+
progress.value = resolveTransition(cfg, target);
|
|
870
|
+
}, [active, declared, isExiting, shouldReduceMotion, layerCfgSig]);
|
|
763
871
|
}
|
|
764
872
|
function useGestureHandlers(gesture, rest, setPressed, setFocused, setFocusVisible, setHovered) {
|
|
873
|
+
const hasPressed = gesture?.pressed ? 1 : 0;
|
|
874
|
+
const hasFocused = gesture?.focused ? 1 : 0;
|
|
875
|
+
const hasFocusVisible = gesture?.focusVisible ? 1 : 0;
|
|
876
|
+
const hasHovered = gesture?.hovered ? 1 : 0;
|
|
765
877
|
return useMemo(() => {
|
|
766
878
|
if (!gesture) return {};
|
|
767
879
|
const handlers = {};
|
|
@@ -794,10 +906,10 @@ function useGestureHandlers(gesture, rest, setPressed, setFocused, setFocusVisib
|
|
|
794
906
|
}
|
|
795
907
|
return handlers;
|
|
796
908
|
}, [
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
909
|
+
hasPressed,
|
|
910
|
+
hasFocused,
|
|
911
|
+
hasFocusVisible,
|
|
912
|
+
hasHovered,
|
|
801
913
|
rest.onTouchStart,
|
|
802
914
|
rest.onTouchEnd,
|
|
803
915
|
rest.onTouchCancel,
|