@rootnative/inertia 0.0.9 → 0.0.10
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 +68 -1
- package/README.md +7 -7
- package/dist/applyBounds-BYGiHrYO.d.mts +18 -0
- package/dist/applyBounds-BYGiHrYO.d.ts +18 -0
- package/dist/{chunk-E3ALFSH2.js → chunk-2UGWAB6N.js} +78 -70
- package/dist/{chunk-ZBHQPVWE.js → chunk-3ZNHPT5Z.js} +2 -2
- package/dist/{chunk-IHVMNOS4.js → chunk-46766TBM.js} +2 -2
- package/dist/{chunk-MUT6BTZS.js → chunk-4EZ5DBL3.js} +10 -7
- package/dist/{chunk-MFAFB4K7.mjs → chunk-6FCATUMY.mjs} +8 -10
- package/dist/{chunk-6YIUETBF.mjs → chunk-7BH3CAO5.mjs} +1 -1
- package/dist/{chunk-JBK5ZLMH.mjs → chunk-CUHOCONB.mjs} +1 -1
- package/dist/{chunk-M4766VUV.mjs → chunk-DRA2K53O.mjs} +1 -1
- package/dist/{chunk-L4JFECXU.mjs → chunk-F4HMCXAX.mjs} +6 -3
- package/dist/{chunk-W7NTRSPD.mjs → chunk-HEAWMZEM.mjs} +105 -66
- package/dist/{chunk-IX6SEOSK.mjs → chunk-JENYDTXH.mjs} +52 -44
- package/dist/chunk-KFHZMFAX.js +23 -0
- package/dist/{chunk-6AN5X3YE.js → chunk-KXU6VH2Y.js} +10 -11
- package/dist/{chunk-WNVHPMBI.js → chunk-N33GSDNQ.js} +106 -65
- package/dist/chunk-OH46TGEA.mjs +20 -0
- package/dist/{chunk-QNLSCOR5.mjs → chunk-OLOSU2BD.mjs} +1 -1
- package/dist/chunk-PLKXCJIB.js +8 -0
- package/dist/{chunk-GSUC4HWP.mjs → chunk-QXKPIENP.mjs} +1 -1
- package/dist/chunk-UBHQJFUW.js +8 -0
- package/dist/{chunk-6NOCY764.js → chunk-VKXSL3ZL.js} +2 -2
- package/dist/chunk-XKNEQDAT.js +8 -0
- package/dist/{chunk-EN4PN7X3.mjs → chunk-Z23AMUSW.mjs} +1 -1
- package/dist/gestureLayer/index.d.mts +3 -3
- package/dist/gestureLayer/index.d.ts +3 -3
- package/dist/gestureLayer/index.js +12 -18
- package/dist/gestureLayer/index.mjs +5 -11
- package/dist/index.d.mts +87 -45
- package/dist/index.d.ts +87 -45
- package/dist/index.js +114 -91
- package/dist/index.mjs +66 -59
- package/dist/motion/FlatList.d.mts +1 -1
- package/dist/motion/FlatList.d.ts +1 -1
- package/dist/motion/FlatList.js +5 -5
- package/dist/motion/FlatList.mjs +4 -4
- 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 +2 -1
- package/dist/touch/index.d.ts +2 -1
- package/dist/touch/index.js +16 -31
- package/dist/touch/index.mjs +11 -29
- package/dist/{types-DyJpG64F.d.mts → types-08mG8fNk.d.mts} +10 -3
- package/dist/{types-DyJpG64F.d.ts → types-08mG8fNk.d.ts} +10 -3
- package/dist/{useGesture-DbH46EBp.d.ts → useGesture-D1lHeQQ6.d.ts} +1 -1
- package/dist/{useGesture-CnZQnYHH.d.mts → useGesture-DjszaHWz.d.mts} +1 -1
- package/package.json +4 -2
- package/src/config/namedTransitions.ts +7 -9
- package/src/gestureLayer/index.ts +3 -0
- package/src/gestureLayer/useGestureLayer.ts +6 -9
- package/src/gestures/focusVisibility.ts +19 -17
- package/src/gestures/index.ts +1 -1
- package/src/index.ts +9 -0
- package/src/layout/resolveLayout.ts +4 -1
- package/src/layout/useSharedLayout.ts +2 -1
- package/src/motion/createMotionComponent.tsx +92 -44
- package/src/presence/Presence.tsx +5 -7
- package/src/touch/applyBounds.ts +30 -0
- package/src/touch/index.ts +1 -0
- package/src/touch/useTouchDrag.ts +15 -45
- package/src/transitions/constants.ts +14 -0
- package/src/transitions/easing.ts +23 -11
- package/src/transitions/index.ts +5 -0
- package/src/transitions/keys.ts +0 -2
- package/src/transitions/resolve.ts +86 -11
- package/src/transitions/resolveSequence.ts +3 -1
- package/src/transitions/runtime.ts +4 -7
- package/src/transitions/spring.ts +7 -2
- package/src/types.ts +9 -2
- package/src/values/extrapolation.ts +21 -0
- package/src/values/index.ts +1 -0
- package/src/values/useGesture.ts +9 -2
- package/src/values/useInterpolatedStyle.ts +5 -12
- package/src/values/useShadow.ts +18 -7
- package/src/values/useSpring.ts +34 -25
- package/src/values/useTransform.ts +24 -20
- package/src/values/useTranslateStyle.ts +31 -0
- package/dist/chunk-24NUL23E.js +0 -8
- package/dist/chunk-4XBX7KOD.js +0 -8
- package/dist/chunk-Z5USXWTE.js +0 -8
package/dist/touch/index.mjs
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { applyBounds, useTranslateStyle } from '../chunk-OH46TGEA.mjs';
|
|
2
|
+
export { applyBounds } from '../chunk-OH46TGEA.mjs';
|
|
3
|
+
import { buildReleaseAnimation } from '../chunk-HEAWMZEM.mjs';
|
|
4
|
+
import { useRef, useMemo } from 'react';
|
|
3
5
|
import { PanResponder } from 'react-native';
|
|
4
|
-
import { useSharedValue
|
|
6
|
+
import { useSharedValue } from 'react-native-reanimated';
|
|
5
7
|
|
|
6
8
|
function useTouchDrag(options = {}) {
|
|
7
9
|
const { axis = "both", constraints, elastic = 0 } = options;
|
|
@@ -17,22 +19,12 @@ function useTouchDrag(options = {}) {
|
|
|
17
19
|
const top = constraints?.top;
|
|
18
20
|
const bottom = constraints?.bottom;
|
|
19
21
|
const elasticCoef = elastic;
|
|
20
|
-
const
|
|
22
|
+
const callbacksRef = useRef(options);
|
|
23
|
+
callbacksRef.current = options;
|
|
21
24
|
const responder = useMemo(
|
|
22
25
|
() => buildResponder(),
|
|
23
26
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
24
|
-
[
|
|
25
|
-
lockX,
|
|
26
|
-
lockY,
|
|
27
|
-
left,
|
|
28
|
-
right,
|
|
29
|
-
top,
|
|
30
|
-
bottom,
|
|
31
|
-
elasticCoef,
|
|
32
|
-
onDragStart,
|
|
33
|
-
onDragEnd,
|
|
34
|
-
onRelease
|
|
35
|
-
]
|
|
27
|
+
[lockX, lockY, left, right, top, bottom, elasticCoef]
|
|
36
28
|
);
|
|
37
29
|
function buildResponder() {
|
|
38
30
|
const handleEnd = (g) => {
|
|
@@ -41,6 +33,7 @@ function useTouchDrag(options = {}) {
|
|
|
41
33
|
const y = dragY.value;
|
|
42
34
|
const vx = g.vx * 1e3;
|
|
43
35
|
const vy = g.vy * 1e3;
|
|
36
|
+
const { onRelease, onDragEnd } = callbacksRef.current;
|
|
44
37
|
if (onRelease) {
|
|
45
38
|
const result = onRelease({ x, y, velocity: { x: vx, y: vy } });
|
|
46
39
|
if (result) {
|
|
@@ -72,7 +65,7 @@ function useTouchDrag(options = {}) {
|
|
|
72
65
|
startX.value = dragX.value;
|
|
73
66
|
startY.value = dragY.value;
|
|
74
67
|
isDragging.value = true;
|
|
75
|
-
|
|
68
|
+
callbacksRef.current.onDragStart?.();
|
|
76
69
|
},
|
|
77
70
|
onPanResponderMove: (_e, g) => {
|
|
78
71
|
if (lockX) {
|
|
@@ -96,9 +89,7 @@ function useTouchDrag(options = {}) {
|
|
|
96
89
|
onPanResponderTerminate: (_e, g) => handleEnd(g)
|
|
97
90
|
});
|
|
98
91
|
}
|
|
99
|
-
const animatedStyle =
|
|
100
|
-
transform: [{ translateX: dragX.value }, { translateY: dragY.value }]
|
|
101
|
-
}));
|
|
92
|
+
const animatedStyle = useTranslateStyle(dragX, dragY);
|
|
102
93
|
return {
|
|
103
94
|
panHandlers: responder.panHandlers,
|
|
104
95
|
animatedStyle,
|
|
@@ -107,14 +98,5 @@ function useTouchDrag(options = {}) {
|
|
|
107
98
|
isDragging
|
|
108
99
|
};
|
|
109
100
|
}
|
|
110
|
-
function applyBounds(value, min, max, elastic) {
|
|
111
|
-
if (min !== void 0 && value < min) {
|
|
112
|
-
return elastic > 0 ? min + (value - min) * elastic : min;
|
|
113
|
-
}
|
|
114
|
-
if (max !== void 0 && value > max) {
|
|
115
|
-
return elastic > 0 ? max + (value - max) * elastic : max;
|
|
116
|
-
}
|
|
117
|
-
return value;
|
|
118
|
-
}
|
|
119
101
|
|
|
120
102
|
export { useTouchDrag };
|
|
@@ -24,8 +24,6 @@ interface SpringTransition {
|
|
|
24
24
|
friction?: number;
|
|
25
25
|
mass?: number;
|
|
26
26
|
velocity?: number;
|
|
27
|
-
restSpeedThreshold?: number;
|
|
28
|
-
restDisplacementThreshold?: number;
|
|
29
27
|
delay?: number;
|
|
30
28
|
repeat?: RepeatConfig;
|
|
31
29
|
}
|
|
@@ -107,6 +105,15 @@ type NamedTransitions = Partial<Record<TransitionName, TransitionConfig>>;
|
|
|
107
105
|
type TransitionInput = TransitionConfig | TransitionName;
|
|
108
106
|
/**
|
|
109
107
|
* Repeat config — one shape, not three flags. Default `alternate: true`.
|
|
108
|
+
*
|
|
109
|
+
* `count` is the total number of iterations, including the first pass, so
|
|
110
|
+
* `repeat: 2` plays the animation twice. A count below `1` runs the animation
|
|
111
|
+
* once and warns in dev.
|
|
112
|
+
*
|
|
113
|
+
* `alternate` reverses direction on every other pass for a single-value
|
|
114
|
+
* animation. It has no effect on a sequence (an array target): Reanimated
|
|
115
|
+
* restarts a sequence at its first step on every pass. Append the reverse
|
|
116
|
+
* steps to the sequence to alternate.
|
|
110
117
|
*/
|
|
111
118
|
type RepeatConfig = number | 'infinite' | {
|
|
112
119
|
count: number | 'infinite';
|
|
@@ -456,4 +463,4 @@ interface MotionComponent<C extends ComponentType<any>> {
|
|
|
456
463
|
displayName?: string;
|
|
457
464
|
}
|
|
458
465
|
|
|
459
|
-
export type { AnimatableValue as A, BoxShadowInput as B, DecayTransition as D, EasingInput as E, GestureLayerTransitions as G, MotionComponent as M, NamedTransitions as N, PerPropertyTransition as P, RegisteredTransitions as R, SpringTransition as S, TransitionConfig as T, VariantsMap as V, MotionProps as a, TransitionInput as b, TransitionName as c, VariantController as d, AnimateStyle as e, AnimationCallbackInfo as f, EasingFunction as g, EasingFunctionFactory as h, GestureSubStates as i,
|
|
466
|
+
export type { AnimatableValue as A, BoxShadowInput as B, DecayTransition as D, EasingInput as E, GestureLayerTransitions as G, MotionComponent as M, NamedTransitions as N, PerPropertyTransition as P, RegisteredTransitions as R, SpringTransition as S, TransitionConfig as T, VariantsMap as V, MotionProps as a, TransitionInput as b, TransitionName as c, VariantController as d, AnimateStyle as e, AnimationCallbackInfo as f, EasingFunction as g, EasingFunctionFactory as h, GestureSubStates as i, MotionComponentProps as j, NoAnimationTransition as k, RepeatConfig as l, SequenceStep as m, TimingTransition as n, Transition as o };
|
|
@@ -24,8 +24,6 @@ interface SpringTransition {
|
|
|
24
24
|
friction?: number;
|
|
25
25
|
mass?: number;
|
|
26
26
|
velocity?: number;
|
|
27
|
-
restSpeedThreshold?: number;
|
|
28
|
-
restDisplacementThreshold?: number;
|
|
29
27
|
delay?: number;
|
|
30
28
|
repeat?: RepeatConfig;
|
|
31
29
|
}
|
|
@@ -107,6 +105,15 @@ type NamedTransitions = Partial<Record<TransitionName, TransitionConfig>>;
|
|
|
107
105
|
type TransitionInput = TransitionConfig | TransitionName;
|
|
108
106
|
/**
|
|
109
107
|
* Repeat config — one shape, not three flags. Default `alternate: true`.
|
|
108
|
+
*
|
|
109
|
+
* `count` is the total number of iterations, including the first pass, so
|
|
110
|
+
* `repeat: 2` plays the animation twice. A count below `1` runs the animation
|
|
111
|
+
* once and warns in dev.
|
|
112
|
+
*
|
|
113
|
+
* `alternate` reverses direction on every other pass for a single-value
|
|
114
|
+
* animation. It has no effect on a sequence (an array target): Reanimated
|
|
115
|
+
* restarts a sequence at its first step on every pass. Append the reverse
|
|
116
|
+
* steps to the sequence to alternate.
|
|
110
117
|
*/
|
|
111
118
|
type RepeatConfig = number | 'infinite' | {
|
|
112
119
|
count: number | 'infinite';
|
|
@@ -456,4 +463,4 @@ interface MotionComponent<C extends ComponentType<any>> {
|
|
|
456
463
|
displayName?: string;
|
|
457
464
|
}
|
|
458
465
|
|
|
459
|
-
export type { AnimatableValue as A, BoxShadowInput as B, DecayTransition as D, EasingInput as E, GestureLayerTransitions as G, MotionComponent as M, NamedTransitions as N, PerPropertyTransition as P, RegisteredTransitions as R, SpringTransition as S, TransitionConfig as T, VariantsMap as V, MotionProps as a, TransitionInput as b, TransitionName as c, VariantController as d, AnimateStyle as e, AnimationCallbackInfo as f, EasingFunction as g, EasingFunctionFactory as h, GestureSubStates as i,
|
|
466
|
+
export type { AnimatableValue as A, BoxShadowInput as B, DecayTransition as D, EasingInput as E, GestureLayerTransitions as G, MotionComponent as M, NamedTransitions as N, PerPropertyTransition as P, RegisteredTransitions as R, SpringTransition as S, TransitionConfig as T, VariantsMap as V, MotionProps as a, TransitionInput as b, TransitionName as c, VariantController as d, AnimateStyle as e, AnimationCallbackInfo as f, EasingFunction as g, EasingFunctionFactory as h, GestureSubStates as i, MotionComponentProps as j, NoAnimationTransition as k, RepeatConfig as l, SequenceStep as m, TimingTransition as n, Transition as o };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { SharedValue } from 'react-native-reanimated';
|
|
2
|
-
import { b as TransitionInput, G as GestureLayerTransitions } from './types-
|
|
2
|
+
import { b as TransitionInput, G as GestureLayerTransitions } from './types-08mG8fNk.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Handler bag returned by `useGesture`. Spread on a `Pressable` to drive the
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { SharedValue } from 'react-native-reanimated';
|
|
2
|
-
import { b as TransitionInput, G as GestureLayerTransitions } from './types-
|
|
2
|
+
import { b as TransitionInput, G as GestureLayerTransitions } from './types-08mG8fNk.mjs';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Handler bag returned by `useGesture`. Spread on a `Pressable` to drive the
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rootnative/inertia",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.10",
|
|
4
4
|
"description": "Declarative animation primitives for React Native, built on react-native-reanimated.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "RootNative",
|
|
@@ -125,13 +125,14 @@
|
|
|
125
125
|
"!**/*.test.*"
|
|
126
126
|
],
|
|
127
127
|
"peerDependencies": {
|
|
128
|
+
"@testing-library/react-native": ">=13.0.0",
|
|
128
129
|
"react": ">=19.0.0",
|
|
129
130
|
"react-native": ">=0.81.0",
|
|
130
131
|
"react-native-reanimated": ">=4.0.0",
|
|
131
132
|
"react-native-worklets": ">=0.5.0"
|
|
132
133
|
},
|
|
133
134
|
"peerDependenciesMeta": {
|
|
134
|
-
"react-native
|
|
135
|
+
"@testing-library/react-native": {
|
|
135
136
|
"optional": true
|
|
136
137
|
}
|
|
137
138
|
},
|
|
@@ -145,6 +146,7 @@
|
|
|
145
146
|
"react": "19.1.0",
|
|
146
147
|
"react-native": "0.81.5",
|
|
147
148
|
"react-native-reanimated": "~4.1.1",
|
|
149
|
+
"react-native-worklets": "~0.5.1",
|
|
148
150
|
"react-test-renderer": "19.1.0",
|
|
149
151
|
"size-limit": "^11.1.0",
|
|
150
152
|
"tsup": "^8.3.5",
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { warnOnce } from '../internal/warnOnce'
|
|
1
2
|
import { isTopLevelTransition } from '../transitions/keys'
|
|
2
3
|
import {
|
|
3
4
|
type NamedTransitions,
|
|
@@ -6,8 +7,6 @@ import {
|
|
|
6
7
|
type TransitionInput,
|
|
7
8
|
} from '../types'
|
|
8
9
|
|
|
9
|
-
declare const __DEV__: boolean
|
|
10
|
-
|
|
11
10
|
/**
|
|
12
11
|
* Fallback used when a name isn't found in the registry: the library default
|
|
13
12
|
* spring, matching what an omitted transition resolves to everywhere else.
|
|
@@ -26,13 +25,12 @@ export function lookupNamedTransition(
|
|
|
26
25
|
): TransitionConfig {
|
|
27
26
|
const cfg = registry[name]
|
|
28
27
|
if (cfg) return cfg
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
}
|
|
28
|
+
warnOnce(
|
|
29
|
+
`unknown-transition:${name}`,
|
|
30
|
+
`[inertia] Unknown transition name "${name}" — falling back to the ` +
|
|
31
|
+
`default spring. Register it on a provider: ` +
|
|
32
|
+
`<MotionConfig transitions={{ '${name}': { ... } }}>.`,
|
|
33
|
+
)
|
|
36
34
|
return UNKNOWN_NAME_FALLBACK
|
|
37
35
|
}
|
|
38
36
|
|
|
@@ -20,3 +20,6 @@ export type {
|
|
|
20
20
|
UseGestureLayerOptions,
|
|
21
21
|
UseGestureLayerResult,
|
|
22
22
|
} from './useGestureLayer'
|
|
23
|
+
// The per-layer form of `UseGestureLayerOptions.transition`. Re-exported here
|
|
24
|
+
// so a consumer of this subpath can name it without also importing the root.
|
|
25
|
+
export type { GestureLayerTransitions } from '../types'
|
|
@@ -210,7 +210,10 @@ export function useGestureLayer(
|
|
|
210
210
|
// JS-thread precompute: union of keys across all layers, per-key type
|
|
211
211
|
// (number vs color), and a rest-fallback table. The worklet body reads
|
|
212
212
|
// from `meta` instead of probing each layer per frame — the type check
|
|
213
|
-
// only runs when
|
|
213
|
+
// only runs when the layers change structurally. Keyed on a signature, not
|
|
214
|
+
// on object identity: `states` is usually an inline literal, and a fresh
|
|
215
|
+
// `meta` each render would rebuild the animated style's worklet.
|
|
216
|
+
const statesSig = stableSig(states)
|
|
214
217
|
const meta = useMemo(() => {
|
|
215
218
|
const layers = {
|
|
216
219
|
rest: states.rest,
|
|
@@ -251,14 +254,8 @@ export function useGestureLayer(
|
|
|
251
254
|
restRaw !== undefined ? restRaw : isColor ? 'transparent' : 0
|
|
252
255
|
}
|
|
253
256
|
return { layers, keys, types, restValues }
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
states.hovered,
|
|
257
|
-
states.focused,
|
|
258
|
-
states.focusVisible,
|
|
259
|
-
states.pressed,
|
|
260
|
-
states.disabled,
|
|
261
|
-
])
|
|
257
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
258
|
+
}, [statesSig])
|
|
262
259
|
|
|
263
260
|
const style = useAnimatedStyle(() => {
|
|
264
261
|
const { layers, keys, types, restValues } = meta
|
|
@@ -12,15 +12,16 @@ import { Platform } from 'react-native'
|
|
|
12
12
|
* arrives via D-pad, screen reader, or hardware keyboard, all of which are
|
|
13
13
|
* keyboard-equivalent — so `isFocusVisible()` is unconditionally `true`.
|
|
14
14
|
*
|
|
15
|
-
* The web listeners attach
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
15
|
+
* The web listeners attach when the first component that tracks
|
|
16
|
+
* `focusVisible` mounts (`installFocusVisibility`, called from a mount
|
|
17
|
+
* effect), in the capture phase so they run before the focus event reaches
|
|
18
|
+
* the focused element, and they stay installed for the lifetime of the
|
|
19
|
+
* document. Mount-time installation is early enough: the click that focuses
|
|
20
|
+
* a gesture-wired element can only land on an element that is already
|
|
21
|
+
* mounted, so its `mousedown` is observed. The listeners are not attached at
|
|
22
|
+
* import time — `@rootnative/inertia` declares `sideEffects: false`, and an
|
|
23
|
+
* import-time listener would make that declaration false. They are passive
|
|
24
|
+
* and idle-cheap; the cost is one boolean read per `onFocus` dispatch.
|
|
24
25
|
*/
|
|
25
26
|
|
|
26
27
|
type InputModality = 'keyboard' | 'pointer'
|
|
@@ -38,7 +39,14 @@ function setPointer() {
|
|
|
38
39
|
modality = 'pointer'
|
|
39
40
|
}
|
|
40
41
|
|
|
41
|
-
|
|
42
|
+
/**
|
|
43
|
+
* Attach the document listeners that track input modality on web. Idempotent
|
|
44
|
+
* and a no-op on native or without a `document`. Call it from a mount effect
|
|
45
|
+
* of any component that reads `isFocusVisible()`, so the pointer event that
|
|
46
|
+
* precedes the first focus is observed (see module doc above).
|
|
47
|
+
* `isFocusVisible` also calls it as a safety net.
|
|
48
|
+
*/
|
|
49
|
+
export function installFocusVisibility(): void {
|
|
42
50
|
if (installed) return
|
|
43
51
|
if (Platform.OS !== 'web') return
|
|
44
52
|
if (typeof document === 'undefined') return
|
|
@@ -49,12 +57,6 @@ function ensureInstalled(): void {
|
|
|
49
57
|
installed = true
|
|
50
58
|
}
|
|
51
59
|
|
|
52
|
-
// Install at import time so the pointer event that precedes the first focus
|
|
53
|
-
// is observed (see module doc above). `ensureInstalled` stays in
|
|
54
|
-
// `isFocusVisible` as a safety net for environments where `document` appears
|
|
55
|
-
// after import.
|
|
56
|
-
ensureInstalled()
|
|
57
|
-
|
|
58
60
|
/**
|
|
59
61
|
* `true` if the next `onFocus` should be treated as "focus-visible" (keyboard
|
|
60
62
|
* focus). On native, always `true`. On web, reflects the most recent user
|
|
@@ -62,7 +64,7 @@ ensureInstalled()
|
|
|
62
64
|
*/
|
|
63
65
|
export function isFocusVisible(): boolean {
|
|
64
66
|
if (Platform.OS !== 'web') return true
|
|
65
|
-
|
|
67
|
+
installFocusVisibility()
|
|
66
68
|
return modality === 'keyboard'
|
|
67
69
|
}
|
|
68
70
|
|
package/src/gestures/index.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { isFocusVisible } from './focusVisibility'
|
|
1
|
+
export { installFocusVisibility, isFocusVisible } from './focusVisibility'
|
package/src/index.ts
CHANGED
|
@@ -42,12 +42,18 @@ export {
|
|
|
42
42
|
resolveTransition,
|
|
43
43
|
resolveAnimatableValue,
|
|
44
44
|
ensureWorkletEasing,
|
|
45
|
+
isTopLevelTransition,
|
|
46
|
+
stableSig,
|
|
45
47
|
type AnimationCallback,
|
|
48
|
+
type CallbackFactory,
|
|
46
49
|
} from './transitions'
|
|
47
50
|
// Seed value for any color shared value a custom animated component drives
|
|
48
51
|
// through `resolveTransition`. Exported because the obvious choice —
|
|
49
52
|
// `'transparent'` — cannot be animated away from; see the symbol's own docs.
|
|
50
53
|
export { TRANSPARENT } from './internal/color'
|
|
54
|
+
// Worklet-safe clamp shared by `useTouchDrag` and the gesture adapters'
|
|
55
|
+
// `useDrag`; exported so a custom drag can apply the same rubber-band rule.
|
|
56
|
+
export { applyBounds } from './touch/applyBounds'
|
|
51
57
|
export {
|
|
52
58
|
useAnimation,
|
|
53
59
|
useAnimator,
|
|
@@ -61,6 +67,7 @@ export {
|
|
|
61
67
|
useShadow,
|
|
62
68
|
useSpring,
|
|
63
69
|
useTransform,
|
|
70
|
+
useTranslateStyle,
|
|
64
71
|
useVariants,
|
|
65
72
|
} from './values'
|
|
66
73
|
// The value-layer hooks above all return Reanimated `SharedValue`s — export
|
|
@@ -97,8 +104,10 @@ export type {
|
|
|
97
104
|
EasingFunction,
|
|
98
105
|
EasingFunctionFactory,
|
|
99
106
|
EasingInput,
|
|
107
|
+
GestureLayerTransitions,
|
|
100
108
|
GestureSubStates,
|
|
101
109
|
MotionComponent,
|
|
110
|
+
MotionComponentProps,
|
|
102
111
|
MotionProps,
|
|
103
112
|
NamedTransitions,
|
|
104
113
|
NoAnimationTransition,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { LinearTransition } from 'react-native-reanimated'
|
|
2
|
+
import { DEFAULT_LAYOUT_DURATION } from '../transitions/constants'
|
|
2
3
|
import { ensureWorkletEasing } from '../transitions/easing'
|
|
3
4
|
import { DEFAULT_SPRING, springToReanimated } from '../transitions/spring'
|
|
4
5
|
import { type TransitionConfig } from '../types'
|
|
@@ -34,7 +35,9 @@ export function resolveLayoutTransition(
|
|
|
34
35
|
if (cfg.type === 'no-animation') return undefined
|
|
35
36
|
|
|
36
37
|
if (cfg.type === 'timing') {
|
|
37
|
-
let builder = LinearTransition.duration(
|
|
38
|
+
let builder = LinearTransition.duration(
|
|
39
|
+
cfg.duration ?? DEFAULT_LAYOUT_DURATION,
|
|
40
|
+
)
|
|
38
41
|
const easing = ensureWorkletEasing(cfg.easing)
|
|
39
42
|
if (easing) builder = builder.easing(easing)
|
|
40
43
|
if (cfg.delay) builder = builder.delay(cfg.delay)
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
withSpring,
|
|
16
16
|
withTiming,
|
|
17
17
|
} from 'react-native-reanimated'
|
|
18
|
+
import { DEFAULT_LAYOUT_DURATION } from '../transitions/constants'
|
|
18
19
|
import { DEFAULT_SPRING, springToReanimated } from '../transitions/spring'
|
|
19
20
|
import { type SpringTransition, type TransitionConfig } from '../types'
|
|
20
21
|
import { measureWindowRect } from './measureWindow'
|
|
@@ -334,7 +335,7 @@ function legBuilder(
|
|
|
334
335
|
transition: TransitionConfig | undefined,
|
|
335
336
|
): (from: number, to: number) => number {
|
|
336
337
|
if (transition?.type === 'timing') {
|
|
337
|
-
const duration = transition.duration ??
|
|
338
|
+
const duration = transition.duration ?? DEFAULT_LAYOUT_DURATION
|
|
338
339
|
return (from, to) =>
|
|
339
340
|
withSequence(
|
|
340
341
|
withTiming(from, { duration: 0 }),
|