@mrmeg/expo-ui 0.6.0 → 0.7.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/LLM_USAGE.md +4 -5
- package/README.md +6 -6
- package/dist/components/Accordion.js +21 -16
- package/dist/components/AnimatedView.d.ts +1 -1
- package/dist/components/AnimatedView.js +2 -2
- package/dist/components/Badge.d.ts +3 -2
- package/dist/components/Badge.js +4 -3
- package/dist/components/BottomSheet.js +31 -29
- package/dist/components/BottomSheetKeyboard.d.ts +7 -0
- package/dist/components/BottomSheetKeyboard.js +35 -0
- package/dist/components/Button.d.ts +55 -13
- package/dist/components/Button.js +72 -28
- package/dist/components/Card.js +8 -10
- package/dist/components/Checkbox.js +22 -25
- package/dist/components/Collapsible.js +3 -7
- package/dist/components/Dialog.js +1 -1
- package/dist/components/DismissKeyboard.js +3 -3
- package/dist/components/Drawer.js +21 -10
- package/dist/components/DropdownMenu.d.ts +16 -12
- package/dist/components/DropdownMenu.js +32 -30
- package/dist/components/EmptyState.js +1 -1
- package/dist/components/InputOTP.js +16 -40
- package/dist/components/Notification.js +50 -25
- package/dist/components/Popover.js +1 -1
- package/dist/components/Progress.d.ts +2 -2
- package/dist/components/Progress.js +36 -34
- package/dist/components/RadioGroup.js +22 -20
- package/dist/components/Select.js +30 -20
- package/dist/components/Skeleton.js +6 -6
- package/dist/components/Slider.js +90 -97
- package/dist/components/StyledText.context.d.ts +6 -0
- package/dist/components/StyledText.context.js +5 -0
- package/dist/components/StyledText.d.ts +7 -58
- package/dist/components/StyledText.js +8 -28
- package/dist/components/Switch.js +30 -26
- package/dist/components/Tabs.d.ts +23 -3
- package/dist/components/Tabs.js +39 -17
- package/dist/components/TextInput.d.ts +6 -2
- package/dist/components/TextInput.js +6 -7
- package/dist/components/Toggle.js +12 -7
- package/dist/components/ToggleGroup.js +17 -11
- package/dist/components/Tooltip.js +1 -1
- package/dist/hooks/useDimensions.js +25 -26
- package/dist/hooks/useReduceMotion.d.ts +5 -1
- package/dist/hooks/useReduceMotion.js +46 -41
- package/dist/hooks/useResources.js +6 -1
- package/dist/hooks/useScalePress.d.ts +6 -5
- package/dist/hooks/useScalePress.js +25 -21
- package/dist/hooks/useStaggeredEntrance.d.ts +9 -8
- package/dist/hooks/useStaggeredEntrance.js +48 -21
- package/dist/state/themeColorScope.js +3 -3
- package/llms-full.md +4 -5
- package/llms.txt +2 -2
- package/package.json +1 -4
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { useEffect } from "react";
|
|
2
|
-
import {
|
|
1
|
+
import { useEffect, useMemo, useRef } from "react";
|
|
2
|
+
import { Animated, Easing } from "react-native";
|
|
3
|
+
import { useReducedMotion } from "./useReduceMotion.js";
|
|
3
4
|
/**
|
|
4
|
-
* Hook for entrance animations with stagger support using
|
|
5
|
+
* Hook for entrance animations with stagger support using React Native Animated.
|
|
5
6
|
*
|
|
6
7
|
* Returns an animated style to apply to an Animated.View.
|
|
7
8
|
* Respects reduced motion preferences.
|
|
@@ -22,50 +23,76 @@ import { useSharedValue, useAnimatedStyle, withTiming, withSpring, withDelay, us
|
|
|
22
23
|
export function useStaggeredEntrance(options = {}) {
|
|
23
24
|
const { type = "fadeSlideUp", delay = 0, duration = 200, slideDistance = 8, initialScale = 0.95, } = options;
|
|
24
25
|
const reduceMotion = useReducedMotion();
|
|
25
|
-
const opacity =
|
|
26
|
-
const translateY =
|
|
26
|
+
const opacity = useRef(new Animated.Value(reduceMotion ? 1 : 0)).current;
|
|
27
|
+
const translateY = useRef(new Animated.Value(reduceMotion
|
|
27
28
|
? 0
|
|
28
29
|
: type === "fadeSlideUp"
|
|
29
30
|
? slideDistance
|
|
30
31
|
: type === "fadeSlideDown"
|
|
31
32
|
? -slideDistance
|
|
32
|
-
: 0);
|
|
33
|
-
const scale =
|
|
33
|
+
: 0)).current;
|
|
34
|
+
const scale = useRef(new Animated.Value(reduceMotion ? 1 : type === "scale" ? initialScale : 1)).current;
|
|
34
35
|
useEffect(() => {
|
|
35
36
|
if (reduceMotion) {
|
|
36
|
-
opacity.
|
|
37
|
-
translateY.
|
|
38
|
-
scale.
|
|
37
|
+
opacity.setValue(1);
|
|
38
|
+
translateY.setValue(0);
|
|
39
|
+
scale.setValue(1);
|
|
39
40
|
return;
|
|
40
41
|
}
|
|
42
|
+
opacity.setValue(0);
|
|
43
|
+
translateY.setValue(type === "fadeSlideUp"
|
|
44
|
+
? slideDistance
|
|
45
|
+
: type === "fadeSlideDown"
|
|
46
|
+
? -slideDistance
|
|
47
|
+
: 0);
|
|
48
|
+
scale.setValue(type === "scale" ? initialScale : 1);
|
|
41
49
|
const timingConfig = {
|
|
42
50
|
duration,
|
|
43
51
|
easing: Easing.out(Easing.cubic),
|
|
52
|
+
useNativeDriver: true,
|
|
44
53
|
};
|
|
45
|
-
|
|
54
|
+
const animations = [
|
|
55
|
+
Animated.timing(opacity, {
|
|
56
|
+
toValue: 1,
|
|
57
|
+
...timingConfig,
|
|
58
|
+
}),
|
|
59
|
+
];
|
|
46
60
|
if (type === "fadeSlideUp" || type === "fadeSlideDown") {
|
|
47
|
-
|
|
61
|
+
animations.push(Animated.timing(translateY, {
|
|
62
|
+
toValue: 0,
|
|
63
|
+
...timingConfig,
|
|
64
|
+
}));
|
|
48
65
|
}
|
|
49
66
|
if (type === "scale") {
|
|
50
|
-
|
|
67
|
+
animations.push(Animated.spring(scale, {
|
|
68
|
+
toValue: 1,
|
|
69
|
+
damping: 14,
|
|
70
|
+
stiffness: 250,
|
|
71
|
+
useNativeDriver: true,
|
|
72
|
+
}));
|
|
51
73
|
}
|
|
52
|
-
|
|
53
|
-
|
|
74
|
+
const animation = delay > 0
|
|
75
|
+
? Animated.sequence([Animated.delay(delay), Animated.parallel(animations)])
|
|
76
|
+
: Animated.parallel(animations);
|
|
77
|
+
animation.start();
|
|
78
|
+
return () => animation.stop();
|
|
79
|
+
}, [delay, duration, initialScale, opacity, reduceMotion, scale, slideDistance, translateY, type]);
|
|
80
|
+
const animatedStyle = useMemo(() => {
|
|
54
81
|
if (type === "fade") {
|
|
55
|
-
return { opacity
|
|
82
|
+
return { opacity };
|
|
56
83
|
}
|
|
57
84
|
if (type === "fadeSlideUp" || type === "fadeSlideDown") {
|
|
58
85
|
return {
|
|
59
|
-
opacity
|
|
60
|
-
transform: [{ translateY
|
|
86
|
+
opacity,
|
|
87
|
+
transform: [{ translateY }],
|
|
61
88
|
};
|
|
62
89
|
}
|
|
63
90
|
// scale
|
|
64
91
|
return {
|
|
65
|
-
opacity
|
|
66
|
-
transform: [{ scale
|
|
92
|
+
opacity,
|
|
93
|
+
transform: [{ scale }],
|
|
67
94
|
};
|
|
68
|
-
});
|
|
95
|
+
}, [opacity, scale, translateY, type]);
|
|
69
96
|
return animatedStyle;
|
|
70
97
|
}
|
|
71
98
|
/**
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { createContext,
|
|
2
|
+
import { createContext, use, useMemo } from "react";
|
|
3
3
|
/**
|
|
4
4
|
* Per-subtree color overrides, layered on top of the global theme by `useTheme`.
|
|
5
5
|
*
|
|
@@ -13,7 +13,7 @@ import { createContext, useContext, useMemo } from "react";
|
|
|
13
13
|
const ThemeColorScopeContext = createContext(null);
|
|
14
14
|
/** Read the active scoped override (null when not inside a scope). */
|
|
15
15
|
export function useThemeColorScope() {
|
|
16
|
-
return
|
|
16
|
+
return use(ThemeColorScopeContext);
|
|
17
17
|
}
|
|
18
18
|
// Nested scopes layer: the inner scope's keys win, the outer scope's fill in.
|
|
19
19
|
function mergeScopes(parent, next) {
|
|
@@ -25,7 +25,7 @@ function mergeScopes(parent, next) {
|
|
|
25
25
|
};
|
|
26
26
|
}
|
|
27
27
|
export function ThemeColorScope({ colors, children, }) {
|
|
28
|
-
const parent =
|
|
28
|
+
const parent = use(ThemeColorScopeContext);
|
|
29
29
|
const value = useMemo(() => mergeScopes(parent, colors), [parent, colors]);
|
|
30
30
|
return (_jsx(ThemeColorScopeContext.Provider, { value: value, children: children }));
|
|
31
31
|
}
|
package/llms-full.md
CHANGED
|
@@ -36,10 +36,9 @@ the root when the app uses package feedback or overlay components.
|
|
|
36
36
|
`BottomSheet`, `Drawer`, `DropdownMenu`, `Popover`, `SelectContent`,
|
|
37
37
|
`Tooltip`, or `globalUIStore` notifications.
|
|
38
38
|
|
|
39
|
-
On native, `BottomSheet.Content` composes its sheet transform with
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
text inputs, or pass `avoidKeyboard={false}` for sheets that should not move.
|
|
39
|
+
On native, `BottomSheet.Content` composes its sheet transform with React Native
|
|
40
|
+
keyboard event values. Pass `avoidKeyboard={false}` for sheets that should not
|
|
41
|
+
move.
|
|
43
42
|
|
|
44
43
|
i18n is optional. Plain children and `text` props work without `i18next` or
|
|
45
44
|
`react-i18next`. Use `configureExpoUiI18n()` only when a consuming app wants
|
|
@@ -87,7 +86,7 @@ Use this catalog before creating a new app-local primitive.
|
|
|
87
86
|
| `Alert` | `@mrmeg/expo-ui/components` | Cross-platform imperative alerts | Avoid direct `window.alert` and duplicated native/web branching. |
|
|
88
87
|
| `AnimatedView` | `@mrmeg/expo-ui/components` | Entrance and visibility animation | Keep simple reveal effects in the package wrapper. |
|
|
89
88
|
| `Badge` | `@mrmeg/expo-ui/components` | Short status labels | Prefer over custom pill views. |
|
|
90
|
-
| `BottomSheet` | `@mrmeg/expo-ui/components` | Mobile-first modal sheets | Requires root `UIProvider`;
|
|
89
|
+
| `BottomSheet` | `@mrmeg/expo-ui/components` | Mobile-first modal sheets | Requires root `UIProvider`; text-input sheets can disable `avoidKeyboard`. |
|
|
91
90
|
| `Button` | `@mrmeg/expo-ui/components` | Commands and CTAs | Use `preset`, not `variant`; visible heights are compact. |
|
|
92
91
|
| `Card` | `@mrmeg/expo-ui/components` | Individual framed content groups | Do not wrap whole page sections in cards. |
|
|
93
92
|
| `Checkbox` | `@mrmeg/expo-ui/components` | Boolean selection in forms or lists | Prefer over custom checkmark controls. |
|
package/llms.txt
CHANGED
|
@@ -25,8 +25,8 @@ Call useResources() once near the Expo app root. Mount UIProvider once near the
|
|
|
25
25
|
root before using package notifications or overlay primitives: Dialog,
|
|
26
26
|
AlertDialog, BottomSheet, Drawer, DropdownMenu, Popover, SelectContent, or
|
|
27
27
|
Tooltip.
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
BottomSheet.Content uses React Native keyboard events for text inputs;
|
|
29
|
+
avoidKeyboard defaults to true.
|
|
30
30
|
|
|
31
31
|
Use useTheme(), useStyles(), semantic tokens, StyledText, and package controls.
|
|
32
32
|
Do not add app-local Appearance or matchMedia listeners for package theme sync.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mrmeg/expo-ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Reusable Expo and React Native UI primitives for MrMeg projects.",
|
|
6
6
|
"keywords": [
|
|
@@ -109,12 +109,9 @@
|
|
|
109
109
|
"react": ">=19.2.0 <20.0.0",
|
|
110
110
|
"react-native": ">=0.83.0 <0.86.0",
|
|
111
111
|
"react-native-gesture-handler": ">=2.30.0 <2.32.0",
|
|
112
|
-
"react-native-keyboard-controller": ">=1.20.0 <2.0.0",
|
|
113
|
-
"react-native-reanimated": ">=4.2.0 <5.0.0",
|
|
114
112
|
"react-native-safe-area-context": ">=5.6.0 <6.0.0",
|
|
115
113
|
"react-native-screens": ">=4.23.0 <5.0.0",
|
|
116
114
|
"react-native-web": ">=0.21.0 <0.22.0",
|
|
117
|
-
"react-native-worklets": ">=0.7.0 <0.9.0",
|
|
118
115
|
"zustand": ">=5.0.0 <6.0.0"
|
|
119
116
|
},
|
|
120
117
|
"devDependencies": {
|