reactnatively-animations 0.1.0
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/LICENSE +20 -0
- package/dist/index.d.mts +47 -0
- package/dist/index.d.ts +47 -0
- package/dist/index.js +165 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +144 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +59 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Hakizimana Fred
|
|
4
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
5
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
6
|
+
in the Software without restriction, including without limitation the rights
|
|
7
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
8
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
9
|
+
furnished to do so, subject to the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be included in all
|
|
12
|
+
copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
15
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
16
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
17
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
18
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
19
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
20
|
+
SOFTWARE.
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { WithSpringConfig, WithTimingConfig, AnimatedStyle } from 'react-native-reanimated';
|
|
2
|
+
import { duration, springs, SpringConfig } from 'reactnatively-theme';
|
|
3
|
+
export { springs } from 'reactnatively-theme';
|
|
4
|
+
import { ViewStyle } from 'react-native';
|
|
5
|
+
|
|
6
|
+
declare const SPRING_SNAPPY: WithSpringConfig;
|
|
7
|
+
declare const SPRING_LIQUID: WithSpringConfig;
|
|
8
|
+
declare const SPRING_REVEAL: WithSpringConfig;
|
|
9
|
+
declare const SPRING_BOUNCE: WithSpringConfig;
|
|
10
|
+
declare const SPRING_PRECISE: WithSpringConfig;
|
|
11
|
+
|
|
12
|
+
declare const TIMING_FAST: WithTimingConfig;
|
|
13
|
+
declare const TIMING_NORMAL: WithTimingConfig;
|
|
14
|
+
declare const TIMING_SLOW: WithTimingConfig;
|
|
15
|
+
declare const TIMING_ENTER: WithTimingConfig;
|
|
16
|
+
declare const TIMING_EXIT: WithTimingConfig;
|
|
17
|
+
declare const TIMING_BLUR_IN: WithTimingConfig;
|
|
18
|
+
declare const TIMING_BLUR_OUT: WithTimingConfig;
|
|
19
|
+
|
|
20
|
+
declare function useReducedMotion(): boolean;
|
|
21
|
+
declare function useSpring(key: keyof typeof springs): SpringConfig;
|
|
22
|
+
declare function useDuration(key: keyof typeof duration): number;
|
|
23
|
+
|
|
24
|
+
interface PressAnimationConfig {
|
|
25
|
+
pressedScale?: number;
|
|
26
|
+
pressedOpacity?: number;
|
|
27
|
+
disabled?: boolean;
|
|
28
|
+
}
|
|
29
|
+
interface PressAnimationResult {
|
|
30
|
+
animatedStyle: AnimatedStyle<ViewStyle>;
|
|
31
|
+
handlers: {
|
|
32
|
+
onPressIn: () => void;
|
|
33
|
+
onPressOut: () => void;
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
declare function usePressAnimation({ pressedScale, pressedOpacity, disabled, }?: PressAnimationConfig): PressAnimationResult;
|
|
37
|
+
|
|
38
|
+
type EntranceVariant = 'fade' | 'slideUp' | 'slideDown' | 'scale' | 'none';
|
|
39
|
+
interface EntranceAnimationConfig {
|
|
40
|
+
variant?: EntranceVariant;
|
|
41
|
+
delay?: number;
|
|
42
|
+
slideOffset?: number;
|
|
43
|
+
visible?: boolean;
|
|
44
|
+
}
|
|
45
|
+
declare function useEntranceAnimation({ variant, delay, slideOffset, visible, }?: EntranceAnimationConfig): AnimatedStyle<ViewStyle>;
|
|
46
|
+
|
|
47
|
+
export { type EntranceAnimationConfig, type EntranceVariant, type PressAnimationConfig, type PressAnimationResult, SPRING_BOUNCE, SPRING_LIQUID, SPRING_PRECISE, SPRING_REVEAL, SPRING_SNAPPY, TIMING_BLUR_IN, TIMING_BLUR_OUT, TIMING_ENTER, TIMING_EXIT, TIMING_FAST, TIMING_NORMAL, TIMING_SLOW, useDuration, useEntranceAnimation, usePressAnimation, useReducedMotion, useSpring };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { WithSpringConfig, WithTimingConfig, AnimatedStyle } from 'react-native-reanimated';
|
|
2
|
+
import { duration, springs, SpringConfig } from 'reactnatively-theme';
|
|
3
|
+
export { springs } from 'reactnatively-theme';
|
|
4
|
+
import { ViewStyle } from 'react-native';
|
|
5
|
+
|
|
6
|
+
declare const SPRING_SNAPPY: WithSpringConfig;
|
|
7
|
+
declare const SPRING_LIQUID: WithSpringConfig;
|
|
8
|
+
declare const SPRING_REVEAL: WithSpringConfig;
|
|
9
|
+
declare const SPRING_BOUNCE: WithSpringConfig;
|
|
10
|
+
declare const SPRING_PRECISE: WithSpringConfig;
|
|
11
|
+
|
|
12
|
+
declare const TIMING_FAST: WithTimingConfig;
|
|
13
|
+
declare const TIMING_NORMAL: WithTimingConfig;
|
|
14
|
+
declare const TIMING_SLOW: WithTimingConfig;
|
|
15
|
+
declare const TIMING_ENTER: WithTimingConfig;
|
|
16
|
+
declare const TIMING_EXIT: WithTimingConfig;
|
|
17
|
+
declare const TIMING_BLUR_IN: WithTimingConfig;
|
|
18
|
+
declare const TIMING_BLUR_OUT: WithTimingConfig;
|
|
19
|
+
|
|
20
|
+
declare function useReducedMotion(): boolean;
|
|
21
|
+
declare function useSpring(key: keyof typeof springs): SpringConfig;
|
|
22
|
+
declare function useDuration(key: keyof typeof duration): number;
|
|
23
|
+
|
|
24
|
+
interface PressAnimationConfig {
|
|
25
|
+
pressedScale?: number;
|
|
26
|
+
pressedOpacity?: number;
|
|
27
|
+
disabled?: boolean;
|
|
28
|
+
}
|
|
29
|
+
interface PressAnimationResult {
|
|
30
|
+
animatedStyle: AnimatedStyle<ViewStyle>;
|
|
31
|
+
handlers: {
|
|
32
|
+
onPressIn: () => void;
|
|
33
|
+
onPressOut: () => void;
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
declare function usePressAnimation({ pressedScale, pressedOpacity, disabled, }?: PressAnimationConfig): PressAnimationResult;
|
|
37
|
+
|
|
38
|
+
type EntranceVariant = 'fade' | 'slideUp' | 'slideDown' | 'scale' | 'none';
|
|
39
|
+
interface EntranceAnimationConfig {
|
|
40
|
+
variant?: EntranceVariant;
|
|
41
|
+
delay?: number;
|
|
42
|
+
slideOffset?: number;
|
|
43
|
+
visible?: boolean;
|
|
44
|
+
}
|
|
45
|
+
declare function useEntranceAnimation({ variant, delay, slideOffset, visible, }?: EntranceAnimationConfig): AnimatedStyle<ViewStyle>;
|
|
46
|
+
|
|
47
|
+
export { type EntranceAnimationConfig, type EntranceVariant, type PressAnimationConfig, type PressAnimationResult, SPRING_BOUNCE, SPRING_LIQUID, SPRING_PRECISE, SPRING_REVEAL, SPRING_SNAPPY, TIMING_BLUR_IN, TIMING_BLUR_OUT, TIMING_ENTER, TIMING_EXIT, TIMING_FAST, TIMING_NORMAL, TIMING_SLOW, useDuration, useEntranceAnimation, usePressAnimation, useReducedMotion, useSpring };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var reactnativelyTheme = require('reactnatively-theme');
|
|
4
|
+
var reactNativeReanimated = require('react-native-reanimated');
|
|
5
|
+
var react = require('react');
|
|
6
|
+
|
|
7
|
+
// src/presets/spring.ts
|
|
8
|
+
var SPRING_SNAPPY = reactnativelyTheme.springs.snappy;
|
|
9
|
+
var SPRING_LIQUID = reactnativelyTheme.springs.liquid;
|
|
10
|
+
var SPRING_REVEAL = reactnativelyTheme.springs.reveal;
|
|
11
|
+
var SPRING_BOUNCE = reactnativelyTheme.springs.bounce;
|
|
12
|
+
var SPRING_PRECISE = reactnativelyTheme.springs.precise;
|
|
13
|
+
function bezier(arr) {
|
|
14
|
+
const [x1 = 0, y1 = 0, x2 = 1, y2 = 1] = arr;
|
|
15
|
+
return reactNativeReanimated.Easing.bezier(x1, y1, x2, y2);
|
|
16
|
+
}
|
|
17
|
+
var TIMING_FAST = {
|
|
18
|
+
duration: reactnativelyTheme.duration.fast,
|
|
19
|
+
easing: bezier(reactnativelyTheme.easing.standard)
|
|
20
|
+
};
|
|
21
|
+
var TIMING_NORMAL = {
|
|
22
|
+
duration: reactnativelyTheme.duration.normal,
|
|
23
|
+
easing: bezier(reactnativelyTheme.easing.standard)
|
|
24
|
+
};
|
|
25
|
+
var TIMING_SLOW = {
|
|
26
|
+
duration: reactnativelyTheme.duration.slow,
|
|
27
|
+
easing: bezier(reactnativelyTheme.easing.standard)
|
|
28
|
+
};
|
|
29
|
+
var TIMING_ENTER = {
|
|
30
|
+
duration: reactnativelyTheme.duration.enter,
|
|
31
|
+
easing: bezier(reactnativelyTheme.easing.decelerate)
|
|
32
|
+
};
|
|
33
|
+
var TIMING_EXIT = {
|
|
34
|
+
duration: reactnativelyTheme.duration.exit,
|
|
35
|
+
easing: bezier(reactnativelyTheme.easing.accelerate)
|
|
36
|
+
};
|
|
37
|
+
var TIMING_BLUR_IN = {
|
|
38
|
+
duration: reactnativelyTheme.duration.blurIn,
|
|
39
|
+
easing: bezier(reactnativelyTheme.easing.decelerate)
|
|
40
|
+
};
|
|
41
|
+
var TIMING_BLUR_OUT = {
|
|
42
|
+
duration: reactnativelyTheme.duration.blurOut,
|
|
43
|
+
easing: bezier(reactnativelyTheme.easing.accelerate)
|
|
44
|
+
};
|
|
45
|
+
function useReducedMotion() {
|
|
46
|
+
return reactNativeReanimated.useReducedMotion();
|
|
47
|
+
}
|
|
48
|
+
function useSpring(key) {
|
|
49
|
+
const isReduced = reactNativeReanimated.useReducedMotion();
|
|
50
|
+
return isReduced ? reactnativelyTheme.reducedMotion.springs[key] : reactnativelyTheme.springs[key];
|
|
51
|
+
}
|
|
52
|
+
function useDuration(key) {
|
|
53
|
+
const isReduced = reactNativeReanimated.useReducedMotion();
|
|
54
|
+
if (isReduced && key in reactnativelyTheme.reducedMotion.duration) {
|
|
55
|
+
return reactnativelyTheme.reducedMotion.duration[key];
|
|
56
|
+
}
|
|
57
|
+
return reactnativelyTheme.duration[key];
|
|
58
|
+
}
|
|
59
|
+
function usePressAnimation({
|
|
60
|
+
pressedScale = 0.96,
|
|
61
|
+
pressedOpacity = 0.88,
|
|
62
|
+
disabled = false
|
|
63
|
+
} = {}) {
|
|
64
|
+
const isReduced = useReducedMotion();
|
|
65
|
+
const pressed = reactNativeReanimated.useSharedValue(0);
|
|
66
|
+
const animatedStyle = reactNativeReanimated.useAnimatedStyle(() => {
|
|
67
|
+
"worklet";
|
|
68
|
+
if (disabled || isReduced) return {};
|
|
69
|
+
return {
|
|
70
|
+
transform: [
|
|
71
|
+
{ scale: reactNativeReanimated.interpolate(pressed.value, [0, 1], [1, pressedScale]) }
|
|
72
|
+
],
|
|
73
|
+
opacity: reactNativeReanimated.interpolate(pressed.value, [0, 1], [1, pressedOpacity])
|
|
74
|
+
};
|
|
75
|
+
});
|
|
76
|
+
const handlers = {
|
|
77
|
+
onPressIn: () => {
|
|
78
|
+
"worklet";
|
|
79
|
+
pressed.value = reactNativeReanimated.withSpring(1, SPRING_SNAPPY);
|
|
80
|
+
},
|
|
81
|
+
onPressOut: () => {
|
|
82
|
+
"worklet";
|
|
83
|
+
pressed.value = reactNativeReanimated.withSpring(0, SPRING_SNAPPY);
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
return { animatedStyle, handlers };
|
|
87
|
+
}
|
|
88
|
+
function useEntranceAnimation({
|
|
89
|
+
variant = "fade",
|
|
90
|
+
delay = 0,
|
|
91
|
+
slideOffset = 20,
|
|
92
|
+
visible = true
|
|
93
|
+
} = {}) {
|
|
94
|
+
const isReduced = useReducedMotion();
|
|
95
|
+
const progress = reactNativeReanimated.useSharedValue(visible ? 1 : 0);
|
|
96
|
+
react.useEffect(() => {
|
|
97
|
+
const timer = delay > 0 ? setTimeout(animate, delay) : null;
|
|
98
|
+
if (!timer) animate();
|
|
99
|
+
return () => {
|
|
100
|
+
if (timer) clearTimeout(timer);
|
|
101
|
+
};
|
|
102
|
+
function animate() {
|
|
103
|
+
if (isReduced) {
|
|
104
|
+
progress.value = visible ? 1 : 0;
|
|
105
|
+
} else {
|
|
106
|
+
progress.value = visible ? reactNativeReanimated.withSpring(1, SPRING_REVEAL) : reactNativeReanimated.withTiming(0, TIMING_ENTER);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}, [visible, isReduced, delay]);
|
|
110
|
+
return reactNativeReanimated.useAnimatedStyle(() => {
|
|
111
|
+
"worklet";
|
|
112
|
+
if (variant === "none") return {};
|
|
113
|
+
const opacity = reactNativeReanimated.interpolate(progress.value, [0, 1], [0, 1]);
|
|
114
|
+
if (variant === "fade") {
|
|
115
|
+
return { opacity };
|
|
116
|
+
}
|
|
117
|
+
if (variant === "scale") {
|
|
118
|
+
return {
|
|
119
|
+
opacity,
|
|
120
|
+
transform: [{ scale: reactNativeReanimated.interpolate(progress.value, [0, 1], [0.92, 1]) }]
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
if (variant === "slideUp") {
|
|
124
|
+
return {
|
|
125
|
+
opacity,
|
|
126
|
+
transform: [
|
|
127
|
+
{ translateY: reactNativeReanimated.interpolate(progress.value, [0, 1], [slideOffset, 0]) }
|
|
128
|
+
]
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
if (variant === "slideDown") {
|
|
132
|
+
return {
|
|
133
|
+
opacity,
|
|
134
|
+
transform: [
|
|
135
|
+
{ translateY: reactNativeReanimated.interpolate(progress.value, [0, 1], [-slideOffset, 0]) }
|
|
136
|
+
]
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
return { opacity };
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
Object.defineProperty(exports, "springs", {
|
|
144
|
+
enumerable: true,
|
|
145
|
+
get: function () { return reactnativelyTheme.springs; }
|
|
146
|
+
});
|
|
147
|
+
exports.SPRING_BOUNCE = SPRING_BOUNCE;
|
|
148
|
+
exports.SPRING_LIQUID = SPRING_LIQUID;
|
|
149
|
+
exports.SPRING_PRECISE = SPRING_PRECISE;
|
|
150
|
+
exports.SPRING_REVEAL = SPRING_REVEAL;
|
|
151
|
+
exports.SPRING_SNAPPY = SPRING_SNAPPY;
|
|
152
|
+
exports.TIMING_BLUR_IN = TIMING_BLUR_IN;
|
|
153
|
+
exports.TIMING_BLUR_OUT = TIMING_BLUR_OUT;
|
|
154
|
+
exports.TIMING_ENTER = TIMING_ENTER;
|
|
155
|
+
exports.TIMING_EXIT = TIMING_EXIT;
|
|
156
|
+
exports.TIMING_FAST = TIMING_FAST;
|
|
157
|
+
exports.TIMING_NORMAL = TIMING_NORMAL;
|
|
158
|
+
exports.TIMING_SLOW = TIMING_SLOW;
|
|
159
|
+
exports.useDuration = useDuration;
|
|
160
|
+
exports.useEntranceAnimation = useEntranceAnimation;
|
|
161
|
+
exports.usePressAnimation = usePressAnimation;
|
|
162
|
+
exports.useReducedMotion = useReducedMotion;
|
|
163
|
+
exports.useSpring = useSpring;
|
|
164
|
+
//# sourceMappingURL=index.js.map
|
|
165
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/presets/spring.ts","../src/presets/timing.ts","../src/hooks/useReducedMotion.ts","../src/hooks/usePressAnimation.ts","../src/hooks/useEntranceAnimation.ts"],"names":["springTokens","Easing","durationTokens","easingTokens","useReanimatedReducedMotion","reducedMotion","springs","duration","useSharedValue","useAnimatedStyle","interpolate","withSpring","useEffect","withTiming"],"mappings":"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","file":"index.js","sourcesContent":["import type { WithSpringConfig } from 'react-native-reanimated';\nimport { springs as springTokens } from 'reactnatively-theme';\n\n// Re-export typed spring configs for Reanimated's withSpring\nexport const SPRING_SNAPPY: WithSpringConfig = springTokens.snappy;\nexport const SPRING_LIQUID: WithSpringConfig = springTokens.liquid;\nexport const SPRING_REVEAL: WithSpringConfig = springTokens.reveal;\nexport const SPRING_BOUNCE: WithSpringConfig = springTokens.bounce;\nexport const SPRING_PRECISE: WithSpringConfig = springTokens.precise;\n\nexport { springTokens as springs };\n","import { Easing, type WithTimingConfig } from 'react-native-reanimated';\nimport { duration as durationTokens, easing as easingTokens } from 'reactnatively-theme';\n\nfunction bezier(arr: readonly number[]): ReturnType<typeof Easing.bezier> {\n const [x1 = 0, y1 = 0, x2 = 1, y2 = 1] = arr;\n return Easing.bezier(x1, y1, x2, y2);\n}\n\nexport const TIMING_FAST: WithTimingConfig = {\n duration: durationTokens.fast,\n easing: bezier(easingTokens.standard),\n};\n\nexport const TIMING_NORMAL: WithTimingConfig = {\n duration: durationTokens.normal,\n easing: bezier(easingTokens.standard),\n};\n\nexport const TIMING_SLOW: WithTimingConfig = {\n duration: durationTokens.slow,\n easing: bezier(easingTokens.standard),\n};\n\nexport const TIMING_ENTER: WithTimingConfig = {\n duration: durationTokens.enter,\n easing: bezier(easingTokens.decelerate),\n};\n\nexport const TIMING_EXIT: WithTimingConfig = {\n duration: durationTokens.exit,\n easing: bezier(easingTokens.accelerate),\n};\n\nexport const TIMING_BLUR_IN: WithTimingConfig = {\n duration: durationTokens.blurIn,\n easing: bezier(easingTokens.decelerate),\n};\n\nexport const TIMING_BLUR_OUT: WithTimingConfig = {\n duration: durationTokens.blurOut,\n easing: bezier(easingTokens.accelerate),\n};\n","import { useReducedMotion as useReanimatedReducedMotion } from 'react-native-reanimated';\nimport { reducedMotion, springs, duration } from 'reactnatively-theme';\nimport type { SpringConfig } from 'reactnatively-theme';\n\nexport function useReducedMotion(): boolean {\n return useReanimatedReducedMotion();\n}\n\n// Returns the correct spring config — reduced if the user has the system setting on\nexport function useSpring(key: keyof typeof springs): SpringConfig {\n const isReduced = useReanimatedReducedMotion();\n return isReduced\n ? (reducedMotion.springs[key] as unknown as SpringConfig)\n : springs[key];\n}\n\n// Returns the correct duration — collapsed if reduced motion is on\nexport function useDuration(key: keyof typeof duration): number {\n const isReduced = useReanimatedReducedMotion();\n if (isReduced && key in reducedMotion.duration) {\n return reducedMotion.duration[key as keyof typeof reducedMotion.duration];\n }\n return duration[key];\n}\n","import {\n useSharedValue,\n useAnimatedStyle,\n withSpring,\n interpolate,\n type AnimatedStyle,\n} from 'react-native-reanimated';\nimport type { ViewStyle } from 'react-native';\nimport { SPRING_SNAPPY } from '../presets/spring';\nimport { useReducedMotion } from './useReducedMotion';\n\nexport interface PressAnimationConfig {\n // How much the element scales down on press (0.94 = 6% smaller)\n pressedScale?: number;\n // Opacity at peak press\n pressedOpacity?: number;\n // Whether to animate\n disabled?: boolean;\n}\n\nexport interface PressAnimationResult {\n animatedStyle: AnimatedStyle<ViewStyle>;\n handlers: {\n onPressIn: () => void;\n onPressOut: () => void;\n };\n}\n\nexport function usePressAnimation({\n pressedScale = 0.96,\n pressedOpacity = 0.88,\n disabled = false,\n}: PressAnimationConfig = {}): PressAnimationResult {\n const isReduced = useReducedMotion();\n const pressed = useSharedValue(0);\n\n const animatedStyle = useAnimatedStyle((): ViewStyle => {\n 'worklet';\n if (disabled || isReduced) return {};\n return {\n transform: [\n { scale: interpolate(pressed.value, [0, 1], [1, pressedScale]) },\n ],\n opacity: interpolate(pressed.value, [0, 1], [1, pressedOpacity]),\n };\n });\n\n const handlers = {\n onPressIn: () => {\n 'worklet';\n pressed.value = withSpring(1, SPRING_SNAPPY);\n },\n onPressOut: () => {\n 'worklet';\n pressed.value = withSpring(0, SPRING_SNAPPY);\n },\n };\n\n return { animatedStyle, handlers };\n}\n","import { useEffect } from 'react';\nimport {\n useSharedValue,\n useAnimatedStyle,\n withSpring,\n withTiming,\n interpolate,\n type AnimatedStyle,\n} from 'react-native-reanimated';\nimport type { ViewStyle } from 'react-native';\nimport { SPRING_REVEAL } from '../presets/spring';\nimport { TIMING_ENTER } from '../presets/timing';\nimport { useReducedMotion } from './useReducedMotion';\n\nexport type EntranceVariant = 'fade' | 'slideUp' | 'slideDown' | 'scale' | 'none';\n\nexport interface EntranceAnimationConfig {\n variant?: EntranceVariant;\n delay?: number;\n slideOffset?: number;\n visible?: boolean;\n}\n\nexport function useEntranceAnimation({\n variant = 'fade',\n delay = 0,\n slideOffset = 20,\n visible = true,\n}: EntranceAnimationConfig = {}): AnimatedStyle<ViewStyle> {\n const isReduced = useReducedMotion();\n const progress = useSharedValue(visible ? 1 : 0);\n\n useEffect(() => {\n const timer = delay > 0 ? setTimeout(animate, delay) : null;\n if (!timer) animate();\n return () => { if (timer) clearTimeout(timer); };\n\n function animate() {\n if (isReduced) {\n progress.value = visible ? 1 : 0;\n } else {\n progress.value = visible\n ? withSpring(1, SPRING_REVEAL)\n : withTiming(0, TIMING_ENTER);\n }\n }\n }, [visible, isReduced, delay]);\n\n return useAnimatedStyle((): ViewStyle => {\n 'worklet';\n if (variant === 'none') return {};\n\n const opacity = interpolate(progress.value, [0, 1], [0, 1]);\n\n if (variant === 'fade') {\n return { opacity };\n }\n\n if (variant === 'scale') {\n return {\n opacity,\n transform: [{ scale: interpolate(progress.value, [0, 1], [0.92, 1]) }],\n };\n }\n\n if (variant === 'slideUp') {\n return {\n opacity,\n transform: [\n { translateY: interpolate(progress.value, [0, 1], [slideOffset, 0]) },\n ],\n };\n }\n\n if (variant === 'slideDown') {\n return {\n opacity,\n transform: [\n { translateY: interpolate(progress.value, [0, 1], [-slideOffset, 0]) },\n ],\n };\n }\n\n return { opacity };\n });\n}\n"]}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { springs, easing, duration, reducedMotion } from 'reactnatively-theme';
|
|
2
|
+
export { springs } from 'reactnatively-theme';
|
|
3
|
+
import { Easing, useReducedMotion as useReducedMotion$1, useSharedValue, useAnimatedStyle, interpolate, withSpring, withTiming } from 'react-native-reanimated';
|
|
4
|
+
import { useEffect } from 'react';
|
|
5
|
+
|
|
6
|
+
// src/presets/spring.ts
|
|
7
|
+
var SPRING_SNAPPY = springs.snappy;
|
|
8
|
+
var SPRING_LIQUID = springs.liquid;
|
|
9
|
+
var SPRING_REVEAL = springs.reveal;
|
|
10
|
+
var SPRING_BOUNCE = springs.bounce;
|
|
11
|
+
var SPRING_PRECISE = springs.precise;
|
|
12
|
+
function bezier(arr) {
|
|
13
|
+
const [x1 = 0, y1 = 0, x2 = 1, y2 = 1] = arr;
|
|
14
|
+
return Easing.bezier(x1, y1, x2, y2);
|
|
15
|
+
}
|
|
16
|
+
var TIMING_FAST = {
|
|
17
|
+
duration: duration.fast,
|
|
18
|
+
easing: bezier(easing.standard)
|
|
19
|
+
};
|
|
20
|
+
var TIMING_NORMAL = {
|
|
21
|
+
duration: duration.normal,
|
|
22
|
+
easing: bezier(easing.standard)
|
|
23
|
+
};
|
|
24
|
+
var TIMING_SLOW = {
|
|
25
|
+
duration: duration.slow,
|
|
26
|
+
easing: bezier(easing.standard)
|
|
27
|
+
};
|
|
28
|
+
var TIMING_ENTER = {
|
|
29
|
+
duration: duration.enter,
|
|
30
|
+
easing: bezier(easing.decelerate)
|
|
31
|
+
};
|
|
32
|
+
var TIMING_EXIT = {
|
|
33
|
+
duration: duration.exit,
|
|
34
|
+
easing: bezier(easing.accelerate)
|
|
35
|
+
};
|
|
36
|
+
var TIMING_BLUR_IN = {
|
|
37
|
+
duration: duration.blurIn,
|
|
38
|
+
easing: bezier(easing.decelerate)
|
|
39
|
+
};
|
|
40
|
+
var TIMING_BLUR_OUT = {
|
|
41
|
+
duration: duration.blurOut,
|
|
42
|
+
easing: bezier(easing.accelerate)
|
|
43
|
+
};
|
|
44
|
+
function useReducedMotion() {
|
|
45
|
+
return useReducedMotion$1();
|
|
46
|
+
}
|
|
47
|
+
function useSpring(key) {
|
|
48
|
+
const isReduced = useReducedMotion$1();
|
|
49
|
+
return isReduced ? reducedMotion.springs[key] : springs[key];
|
|
50
|
+
}
|
|
51
|
+
function useDuration(key) {
|
|
52
|
+
const isReduced = useReducedMotion$1();
|
|
53
|
+
if (isReduced && key in reducedMotion.duration) {
|
|
54
|
+
return reducedMotion.duration[key];
|
|
55
|
+
}
|
|
56
|
+
return duration[key];
|
|
57
|
+
}
|
|
58
|
+
function usePressAnimation({
|
|
59
|
+
pressedScale = 0.96,
|
|
60
|
+
pressedOpacity = 0.88,
|
|
61
|
+
disabled = false
|
|
62
|
+
} = {}) {
|
|
63
|
+
const isReduced = useReducedMotion();
|
|
64
|
+
const pressed = useSharedValue(0);
|
|
65
|
+
const animatedStyle = useAnimatedStyle(() => {
|
|
66
|
+
"worklet";
|
|
67
|
+
if (disabled || isReduced) return {};
|
|
68
|
+
return {
|
|
69
|
+
transform: [
|
|
70
|
+
{ scale: interpolate(pressed.value, [0, 1], [1, pressedScale]) }
|
|
71
|
+
],
|
|
72
|
+
opacity: interpolate(pressed.value, [0, 1], [1, pressedOpacity])
|
|
73
|
+
};
|
|
74
|
+
});
|
|
75
|
+
const handlers = {
|
|
76
|
+
onPressIn: () => {
|
|
77
|
+
"worklet";
|
|
78
|
+
pressed.value = withSpring(1, SPRING_SNAPPY);
|
|
79
|
+
},
|
|
80
|
+
onPressOut: () => {
|
|
81
|
+
"worklet";
|
|
82
|
+
pressed.value = withSpring(0, SPRING_SNAPPY);
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
return { animatedStyle, handlers };
|
|
86
|
+
}
|
|
87
|
+
function useEntranceAnimation({
|
|
88
|
+
variant = "fade",
|
|
89
|
+
delay = 0,
|
|
90
|
+
slideOffset = 20,
|
|
91
|
+
visible = true
|
|
92
|
+
} = {}) {
|
|
93
|
+
const isReduced = useReducedMotion();
|
|
94
|
+
const progress = useSharedValue(visible ? 1 : 0);
|
|
95
|
+
useEffect(() => {
|
|
96
|
+
const timer = delay > 0 ? setTimeout(animate, delay) : null;
|
|
97
|
+
if (!timer) animate();
|
|
98
|
+
return () => {
|
|
99
|
+
if (timer) clearTimeout(timer);
|
|
100
|
+
};
|
|
101
|
+
function animate() {
|
|
102
|
+
if (isReduced) {
|
|
103
|
+
progress.value = visible ? 1 : 0;
|
|
104
|
+
} else {
|
|
105
|
+
progress.value = visible ? withSpring(1, SPRING_REVEAL) : withTiming(0, TIMING_ENTER);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}, [visible, isReduced, delay]);
|
|
109
|
+
return useAnimatedStyle(() => {
|
|
110
|
+
"worklet";
|
|
111
|
+
if (variant === "none") return {};
|
|
112
|
+
const opacity = interpolate(progress.value, [0, 1], [0, 1]);
|
|
113
|
+
if (variant === "fade") {
|
|
114
|
+
return { opacity };
|
|
115
|
+
}
|
|
116
|
+
if (variant === "scale") {
|
|
117
|
+
return {
|
|
118
|
+
opacity,
|
|
119
|
+
transform: [{ scale: interpolate(progress.value, [0, 1], [0.92, 1]) }]
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
if (variant === "slideUp") {
|
|
123
|
+
return {
|
|
124
|
+
opacity,
|
|
125
|
+
transform: [
|
|
126
|
+
{ translateY: interpolate(progress.value, [0, 1], [slideOffset, 0]) }
|
|
127
|
+
]
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
if (variant === "slideDown") {
|
|
131
|
+
return {
|
|
132
|
+
opacity,
|
|
133
|
+
transform: [
|
|
134
|
+
{ translateY: interpolate(progress.value, [0, 1], [-slideOffset, 0]) }
|
|
135
|
+
]
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
return { opacity };
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export { SPRING_BOUNCE, SPRING_LIQUID, SPRING_PRECISE, SPRING_REVEAL, SPRING_SNAPPY, TIMING_BLUR_IN, TIMING_BLUR_OUT, TIMING_ENTER, TIMING_EXIT, TIMING_FAST, TIMING_NORMAL, TIMING_SLOW, useDuration, useEntranceAnimation, usePressAnimation, useReducedMotion, useSpring };
|
|
143
|
+
//# sourceMappingURL=index.mjs.map
|
|
144
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/presets/spring.ts","../src/presets/timing.ts","../src/hooks/useReducedMotion.ts","../src/hooks/usePressAnimation.ts","../src/hooks/useEntranceAnimation.ts"],"names":["springTokens","durationTokens","easingTokens","useReanimatedReducedMotion","useSharedValue","withSpring","useAnimatedStyle","interpolate"],"mappings":"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","file":"index.mjs","sourcesContent":["import type { WithSpringConfig } from 'react-native-reanimated';\nimport { springs as springTokens } from 'reactnatively-theme';\n\n// Re-export typed spring configs for Reanimated's withSpring\nexport const SPRING_SNAPPY: WithSpringConfig = springTokens.snappy;\nexport const SPRING_LIQUID: WithSpringConfig = springTokens.liquid;\nexport const SPRING_REVEAL: WithSpringConfig = springTokens.reveal;\nexport const SPRING_BOUNCE: WithSpringConfig = springTokens.bounce;\nexport const SPRING_PRECISE: WithSpringConfig = springTokens.precise;\n\nexport { springTokens as springs };\n","import { Easing, type WithTimingConfig } from 'react-native-reanimated';\nimport { duration as durationTokens, easing as easingTokens } from 'reactnatively-theme';\n\nfunction bezier(arr: readonly number[]): ReturnType<typeof Easing.bezier> {\n const [x1 = 0, y1 = 0, x2 = 1, y2 = 1] = arr;\n return Easing.bezier(x1, y1, x2, y2);\n}\n\nexport const TIMING_FAST: WithTimingConfig = {\n duration: durationTokens.fast,\n easing: bezier(easingTokens.standard),\n};\n\nexport const TIMING_NORMAL: WithTimingConfig = {\n duration: durationTokens.normal,\n easing: bezier(easingTokens.standard),\n};\n\nexport const TIMING_SLOW: WithTimingConfig = {\n duration: durationTokens.slow,\n easing: bezier(easingTokens.standard),\n};\n\nexport const TIMING_ENTER: WithTimingConfig = {\n duration: durationTokens.enter,\n easing: bezier(easingTokens.decelerate),\n};\n\nexport const TIMING_EXIT: WithTimingConfig = {\n duration: durationTokens.exit,\n easing: bezier(easingTokens.accelerate),\n};\n\nexport const TIMING_BLUR_IN: WithTimingConfig = {\n duration: durationTokens.blurIn,\n easing: bezier(easingTokens.decelerate),\n};\n\nexport const TIMING_BLUR_OUT: WithTimingConfig = {\n duration: durationTokens.blurOut,\n easing: bezier(easingTokens.accelerate),\n};\n","import { useReducedMotion as useReanimatedReducedMotion } from 'react-native-reanimated';\nimport { reducedMotion, springs, duration } from 'reactnatively-theme';\nimport type { SpringConfig } from 'reactnatively-theme';\n\nexport function useReducedMotion(): boolean {\n return useReanimatedReducedMotion();\n}\n\n// Returns the correct spring config — reduced if the user has the system setting on\nexport function useSpring(key: keyof typeof springs): SpringConfig {\n const isReduced = useReanimatedReducedMotion();\n return isReduced\n ? (reducedMotion.springs[key] as unknown as SpringConfig)\n : springs[key];\n}\n\n// Returns the correct duration — collapsed if reduced motion is on\nexport function useDuration(key: keyof typeof duration): number {\n const isReduced = useReanimatedReducedMotion();\n if (isReduced && key in reducedMotion.duration) {\n return reducedMotion.duration[key as keyof typeof reducedMotion.duration];\n }\n return duration[key];\n}\n","import {\n useSharedValue,\n useAnimatedStyle,\n withSpring,\n interpolate,\n type AnimatedStyle,\n} from 'react-native-reanimated';\nimport type { ViewStyle } from 'react-native';\nimport { SPRING_SNAPPY } from '../presets/spring';\nimport { useReducedMotion } from './useReducedMotion';\n\nexport interface PressAnimationConfig {\n // How much the element scales down on press (0.94 = 6% smaller)\n pressedScale?: number;\n // Opacity at peak press\n pressedOpacity?: number;\n // Whether to animate\n disabled?: boolean;\n}\n\nexport interface PressAnimationResult {\n animatedStyle: AnimatedStyle<ViewStyle>;\n handlers: {\n onPressIn: () => void;\n onPressOut: () => void;\n };\n}\n\nexport function usePressAnimation({\n pressedScale = 0.96,\n pressedOpacity = 0.88,\n disabled = false,\n}: PressAnimationConfig = {}): PressAnimationResult {\n const isReduced = useReducedMotion();\n const pressed = useSharedValue(0);\n\n const animatedStyle = useAnimatedStyle((): ViewStyle => {\n 'worklet';\n if (disabled || isReduced) return {};\n return {\n transform: [\n { scale: interpolate(pressed.value, [0, 1], [1, pressedScale]) },\n ],\n opacity: interpolate(pressed.value, [0, 1], [1, pressedOpacity]),\n };\n });\n\n const handlers = {\n onPressIn: () => {\n 'worklet';\n pressed.value = withSpring(1, SPRING_SNAPPY);\n },\n onPressOut: () => {\n 'worklet';\n pressed.value = withSpring(0, SPRING_SNAPPY);\n },\n };\n\n return { animatedStyle, handlers };\n}\n","import { useEffect } from 'react';\nimport {\n useSharedValue,\n useAnimatedStyle,\n withSpring,\n withTiming,\n interpolate,\n type AnimatedStyle,\n} from 'react-native-reanimated';\nimport type { ViewStyle } from 'react-native';\nimport { SPRING_REVEAL } from '../presets/spring';\nimport { TIMING_ENTER } from '../presets/timing';\nimport { useReducedMotion } from './useReducedMotion';\n\nexport type EntranceVariant = 'fade' | 'slideUp' | 'slideDown' | 'scale' | 'none';\n\nexport interface EntranceAnimationConfig {\n variant?: EntranceVariant;\n delay?: number;\n slideOffset?: number;\n visible?: boolean;\n}\n\nexport function useEntranceAnimation({\n variant = 'fade',\n delay = 0,\n slideOffset = 20,\n visible = true,\n}: EntranceAnimationConfig = {}): AnimatedStyle<ViewStyle> {\n const isReduced = useReducedMotion();\n const progress = useSharedValue(visible ? 1 : 0);\n\n useEffect(() => {\n const timer = delay > 0 ? setTimeout(animate, delay) : null;\n if (!timer) animate();\n return () => { if (timer) clearTimeout(timer); };\n\n function animate() {\n if (isReduced) {\n progress.value = visible ? 1 : 0;\n } else {\n progress.value = visible\n ? withSpring(1, SPRING_REVEAL)\n : withTiming(0, TIMING_ENTER);\n }\n }\n }, [visible, isReduced, delay]);\n\n return useAnimatedStyle((): ViewStyle => {\n 'worklet';\n if (variant === 'none') return {};\n\n const opacity = interpolate(progress.value, [0, 1], [0, 1]);\n\n if (variant === 'fade') {\n return { opacity };\n }\n\n if (variant === 'scale') {\n return {\n opacity,\n transform: [{ scale: interpolate(progress.value, [0, 1], [0.92, 1]) }],\n };\n }\n\n if (variant === 'slideUp') {\n return {\n opacity,\n transform: [\n { translateY: interpolate(progress.value, [0, 1], [slideOffset, 0]) },\n ],\n };\n }\n\n if (variant === 'slideDown') {\n return {\n opacity,\n transform: [\n { translateY: interpolate(progress.value, [0, 1], [-slideOffset, 0]) },\n ],\n };\n }\n\n return { opacity };\n });\n}\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "reactnatively-animations",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Animation presets and hooks for the Reactnatively Liquid Glass framework",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"module": "./dist/index.mjs",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.mjs",
|
|
12
|
+
"require": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"sideEffects": false,
|
|
16
|
+
"files": [
|
|
17
|
+
"dist"
|
|
18
|
+
],
|
|
19
|
+
"dependencies": {
|
|
20
|
+
"reactnatively-theme": "0.1.0",
|
|
21
|
+
"reactnatively-utils": "0.1.0"
|
|
22
|
+
},
|
|
23
|
+
"peerDependencies": {
|
|
24
|
+
"react": ">=18.0.0",
|
|
25
|
+
"react-native": ">=0.73.0",
|
|
26
|
+
"react-native-reanimated": ">=3.6.0"
|
|
27
|
+
},
|
|
28
|
+
"devDependencies": {
|
|
29
|
+
"tsup": "^8.2.4",
|
|
30
|
+
"typescript": "^5.5.3",
|
|
31
|
+
"@reactnatively/tsconfig": "0.0.0"
|
|
32
|
+
},
|
|
33
|
+
"keywords": [
|
|
34
|
+
"react-native",
|
|
35
|
+
"expo",
|
|
36
|
+
"animations",
|
|
37
|
+
"reanimated",
|
|
38
|
+
"ui",
|
|
39
|
+
"design-system",
|
|
40
|
+
"glass",
|
|
41
|
+
"liquid-glass",
|
|
42
|
+
"typescript"
|
|
43
|
+
],
|
|
44
|
+
"repository": {
|
|
45
|
+
"type": "git",
|
|
46
|
+
"url": "https://github.com/hakizimana-fred/reactnatively.git",
|
|
47
|
+
"directory": "packages/animations"
|
|
48
|
+
},
|
|
49
|
+
"license": "MIT",
|
|
50
|
+
"publishConfig": {
|
|
51
|
+
"access": "public"
|
|
52
|
+
},
|
|
53
|
+
"scripts": {
|
|
54
|
+
"build": "tsup",
|
|
55
|
+
"dev": "tsup --watch",
|
|
56
|
+
"typecheck": "tsc --noEmit",
|
|
57
|
+
"clean": "rm -rf dist"
|
|
58
|
+
}
|
|
59
|
+
}
|