@praxiis/ui 0.0.1
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/dist/index.d.mts +52556 -0
- package/dist/index.d.ts +52556 -0
- package/dist/index.js +8753 -0
- package/dist/index.mjs +8777 -0
- package/package.json +70 -0
- package/src/__test-utils__/index.tsx +39 -0
- package/src/components/CalendarStrip/CalendarStrip.helpers.ts +106 -0
- package/src/components/CalendarStrip/CalendarStrip.tsx +83 -0
- package/src/components/CalendarStrip/CalendarStrip.types.ts +133 -0
- package/src/components/CalendarStrip/DayCard/DayCard.helpers.ts +44 -0
- package/src/components/CalendarStrip/DayCard/DayCard.tsx +71 -0
- package/src/components/CalendarStrip/DayCard/DayCard.types.ts +134 -0
- package/src/components/CalendarStrip/DayCard/index.ts +2 -0
- package/src/components/CalendarStrip/DayCard/useDayCardLogic.ts +45 -0
- package/src/components/CalendarStrip/index.ts +9 -0
- package/src/components/CalendarStrip/useCalendarStripLogic.ts +53 -0
- package/src/components/EmptyState/EmptyState.helpers.ts +104 -0
- package/src/components/EmptyState/EmptyState.tsx +205 -0
- package/src/components/EmptyState/EmptyState.types.ts +213 -0
- package/src/components/EmptyState/index.ts +44 -0
- package/src/components/EmptyState/useEmptyStateLogic.ts +131 -0
- package/src/components/Header/Header.helpers.ts +93 -0
- package/src/components/Header/Header.tsx +185 -0
- package/src/components/Header/Header.types.ts +153 -0
- package/src/components/Header/index.ts +44 -0
- package/src/components/Header/useHeaderLogic.ts +146 -0
- package/src/components/ScheduleItem/ScheduleItem/ScheduleItem.helpers.ts +50 -0
- package/src/components/ScheduleItem/ScheduleItem/ScheduleItem.tsx +78 -0
- package/src/components/ScheduleItem/ScheduleItem/ScheduleItem.types.ts +99 -0
- package/src/components/ScheduleItem/ScheduleItem/index.ts +16 -0
- package/src/components/ScheduleItem/ScheduleItem/useScheduleItemLogic.ts +31 -0
- package/src/components/ScheduleItem/index.ts +15 -0
- package/src/components/index.ts +40 -0
- package/src/core/index.ts +34 -0
- package/src/core/restyle/RestyleThemeProviderWrapper.tsx +31 -0
- package/src/core/restyle/index.ts +38 -0
- package/src/core/restyle/restylePresetRegistry.ts +195 -0
- package/src/core/restyle/restyleTheme.ts +1352 -0
- package/src/core/restyle/restyleTypes.ts +8 -0
- package/src/core/restyle/useRestyleTheme.ts +10 -0
- package/src/hooks/animations/index.ts +3 -0
- package/src/hooks/animations/useAnimatedValue.ts +10 -0
- package/src/hooks/animations/useEntranceAnimation.ts +106 -0
- package/src/hooks/animations/usePulseAnimation.ts +63 -0
- package/src/hooks/index.ts +30 -0
- package/src/hooks/useReducedMotion.ts +60 -0
- package/src/i18n/index.ts +2 -0
- package/src/i18n/labels/en.ts +120 -0
- package/src/i18n/labels/es.ts +120 -0
- package/src/i18n/labels/index.ts +6 -0
- package/src/i18n/labels/types.ts +165 -0
- package/src/index.tsx +215 -0
- package/src/primitives/actions/Button/Button.helpers.ts +243 -0
- package/src/primitives/actions/Button/Button.tsx +198 -0
- package/src/primitives/actions/Button/Button.types.ts +207 -0
- package/src/primitives/actions/Button/index.ts +41 -0
- package/src/primitives/actions/Button/useButtonLogic.ts +160 -0
- package/src/primitives/actions/IconButton/IconButton.helpers.ts +235 -0
- package/src/primitives/actions/IconButton/IconButton.tsx +177 -0
- package/src/primitives/actions/IconButton/IconButton.types.ts +273 -0
- package/src/primitives/actions/IconButton/index.ts +30 -0
- package/src/primitives/actions/IconButton/useIconButtonLogic.ts +172 -0
- package/src/primitives/actions/index.ts +20 -0
- package/src/primitives/content/Avatar/Avatar.helpers.ts +177 -0
- package/src/primitives/content/Avatar/Avatar.tsx +199 -0
- package/src/primitives/content/Avatar/Avatar.types.ts +222 -0
- package/src/primitives/content/Avatar/index.ts +46 -0
- package/src/primitives/content/Avatar/useAvatarLogic.ts +149 -0
- package/src/primitives/content/Badge/Badge.helpers.ts +175 -0
- package/src/primitives/content/Badge/Badge.tsx +174 -0
- package/src/primitives/content/Badge/Badge.types.ts +223 -0
- package/src/primitives/content/Badge/index.ts +40 -0
- package/src/primitives/content/Badge/useBadgeLogic.ts +128 -0
- package/src/primitives/content/Card/Card.helpers.ts +27 -0
- package/src/primitives/content/Card/Card.tsx +123 -0
- package/src/primitives/content/Card/Card.types.ts +95 -0
- package/src/primitives/content/Card/index.ts +20 -0
- package/src/primitives/content/Card/useCardLogic.ts +48 -0
- package/src/primitives/content/Chip/Chip.helpers.ts +304 -0
- package/src/primitives/content/Chip/Chip.tsx +205 -0
- package/src/primitives/content/Chip/Chip.types.ts +234 -0
- package/src/primitives/content/Chip/index.ts +47 -0
- package/src/primitives/content/Chip/useChipLogic.ts +167 -0
- package/src/primitives/content/Icon/Icon.helpers.ts +54 -0
- package/src/primitives/content/Icon/Icon.tsx +110 -0
- package/src/primitives/content/Icon/Icon.types.ts +95 -0
- package/src/primitives/content/Icon/index.ts +20 -0
- package/src/primitives/content/Icon/useIconLogic.ts +73 -0
- package/src/primitives/content/index.ts +45 -0
- package/src/primitives/feedback/ProgressBar/ProgressBar.helpers.ts +122 -0
- package/src/primitives/feedback/ProgressBar/ProgressBar.tsx +154 -0
- package/src/primitives/feedback/ProgressBar/ProgressBar.types.ts +178 -0
- package/src/primitives/feedback/ProgressBar/index.ts +17 -0
- package/src/primitives/feedback/ProgressBar/useProgressBarLogic.ts +120 -0
- package/src/primitives/feedback/Skeleton/Skeleton.helpers.ts +145 -0
- package/src/primitives/feedback/Skeleton/Skeleton.tsx +155 -0
- package/src/primitives/feedback/Skeleton/Skeleton.types.ts +223 -0
- package/src/primitives/feedback/Skeleton/index.ts +44 -0
- package/src/primitives/feedback/Skeleton/useSkeletonLogic.ts +125 -0
- package/src/primitives/feedback/Spinner/Spinner.helpers.ts +40 -0
- package/src/primitives/feedback/Spinner/Spinner.tsx +105 -0
- package/src/primitives/feedback/Spinner/Spinner.types.ts +114 -0
- package/src/primitives/feedback/Spinner/index.ts +18 -0
- package/src/primitives/feedback/Spinner/useSpinnerLogic.ts +84 -0
- package/src/primitives/feedback/Toast/Toast.helpers.ts +163 -0
- package/src/primitives/feedback/Toast/Toast.tsx +190 -0
- package/src/primitives/feedback/Toast/Toast.types.ts +270 -0
- package/src/primitives/feedback/Toast/ToastContext.tsx +96 -0
- package/src/primitives/feedback/Toast/ToastProvider.tsx +241 -0
- package/src/primitives/feedback/Toast/index.ts +59 -0
- package/src/primitives/feedback/Toast/useToastLogic.ts +112 -0
- package/src/primitives/feedback/index.ts +45 -0
- package/src/primitives/index.ts +158 -0
- package/src/primitives/inputs/Checkbox/Checkbox.helpers.ts +132 -0
- package/src/primitives/inputs/Checkbox/Checkbox.tsx +150 -0
- package/src/primitives/inputs/Checkbox/Checkbox.types.ts +106 -0
- package/src/primitives/inputs/Checkbox/index.ts +30 -0
- package/src/primitives/inputs/Checkbox/useCheckboxLogic.ts +121 -0
- package/src/primitives/inputs/RadioButton/RadioButton.helpers.ts +123 -0
- package/src/primitives/inputs/RadioButton/RadioButton.tsx +159 -0
- package/src/primitives/inputs/RadioButton/RadioButton.types.ts +106 -0
- package/src/primitives/inputs/RadioButton/index.ts +25 -0
- package/src/primitives/inputs/RadioButton/useRadioButtonLogic.ts +117 -0
- package/src/primitives/inputs/SegmentedControl/SegmentedControl.helpers.ts +174 -0
- package/src/primitives/inputs/SegmentedControl/SegmentedControl.tsx +224 -0
- package/src/primitives/inputs/SegmentedControl/SegmentedControl.types.ts +187 -0
- package/src/primitives/inputs/SegmentedControl/index.ts +39 -0
- package/src/primitives/inputs/SegmentedControl/useSegmentedControlLogic.ts +151 -0
- package/src/primitives/inputs/SelectSheet/SelectSheet.helpers.ts +147 -0
- package/src/primitives/inputs/SelectSheet/SelectSheet.tsx +247 -0
- package/src/primitives/inputs/SelectSheet/SelectSheet.types.ts +196 -0
- package/src/primitives/inputs/SelectSheet/SelectSheetOption.tsx +177 -0
- package/src/primitives/inputs/SelectSheet/index.ts +48 -0
- package/src/primitives/inputs/SelectSheet/useSelectSheetLogic.ts +309 -0
- package/src/primitives/inputs/Switch/Switch.helpers.ts +109 -0
- package/src/primitives/inputs/Switch/Switch.tsx +191 -0
- package/src/primitives/inputs/Switch/Switch.types.ts +154 -0
- package/src/primitives/inputs/Switch/index.ts +40 -0
- package/src/primitives/inputs/Switch/useSwitchLogic.ts +192 -0
- package/src/primitives/inputs/TextInput/TextInput.helpers.ts +206 -0
- package/src/primitives/inputs/TextInput/TextInput.tsx +392 -0
- package/src/primitives/inputs/TextInput/TextInput.types.ts +216 -0
- package/src/primitives/inputs/TextInput/index.ts +37 -0
- package/src/primitives/inputs/TextInput/useTextInputLogic.ts +195 -0
- package/src/primitives/inputs/index.ts +52 -0
- package/src/primitives/layout/AnimatedBox.tsx +44 -0
- package/src/primitives/layout/Box.tsx +71 -0
- package/src/primitives/layout/Divider/Divider.helpers.ts +115 -0
- package/src/primitives/layout/Divider/Divider.tsx +139 -0
- package/src/primitives/layout/Divider/Divider.types.ts +178 -0
- package/src/primitives/layout/Divider/index.ts +24 -0
- package/src/primitives/layout/Divider/useDividerLogic.ts +109 -0
- package/src/primitives/layout/FlatList.tsx +66 -0
- package/src/primitives/layout/Pressable.tsx +74 -0
- package/src/primitives/layout/ScrollView.tsx +63 -0
- package/src/primitives/layout/Stack.tsx +69 -0
- package/src/primitives/layout/index.ts +40 -0
- package/src/primitives/navigation/index.ts +6 -0
- package/src/primitives/overlays/Modal/Modal.helpers.ts +31 -0
- package/src/primitives/overlays/Modal/Modal.tsx +264 -0
- package/src/primitives/overlays/Modal/Modal.types.ts +193 -0
- package/src/primitives/overlays/Modal/index.ts +43 -0
- package/src/primitives/overlays/Modal/useModalLogic.ts +103 -0
- package/src/primitives/overlays/index.ts +12 -0
- package/src/primitives/typography/Text.tsx +51 -0
- package/src/primitives/typography/index.ts +1 -0
- package/src/provider/DesignSystemContext.ts +22 -0
- package/src/provider/DesignSystemProvider.tsx +121 -0
- package/src/provider/index.ts +7 -0
- package/src/providers/ThemeProvider/createTheme.ts +304 -0
- package/src/providers/ThemeProvider/defaultTheme.ts +70 -0
- package/src/providers/ThemeProvider/index.ts +34 -0
- package/src/providers/ThemeProvider/types.ts +249 -0
- package/src/providers/index.ts +29 -0
- package/src/tokens/colors.ts +371 -0
- package/src/tokens/index.ts +145 -0
- package/src/tokens/motion.ts +176 -0
- package/src/tokens/radii.ts +82 -0
- package/src/tokens/scales.ts +588 -0
- package/src/tokens/shadows.ts +190 -0
- package/src/tokens/spacing.ts +140 -0
- package/src/tokens/tokens.json +207 -0
- package/src/tokens/typography.ts +251 -0
- package/src/types.ts +50 -0
- package/src/utils/accessibility.ts +169 -0
- package/src/utils/index.ts +25 -0
- package/src/utils/platform.ts +72 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* El Sendero Design System - Restyle Theme Hook
|
|
3
|
+
*
|
|
4
|
+
* Thin wrapper around Restyle's useTheme to access the active Restyle theme.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { useTheme } from "@shopify/restyle";
|
|
8
|
+
import { RestyleTheme } from "./restyleTheme";
|
|
9
|
+
|
|
10
|
+
export const useRestyleTheme = () => useTheme<RestyleTheme>();
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { useRef } from "react";
|
|
2
|
+
import { Animated } from "react-native";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Creates a stable Animated.Value that persists across re-renders.
|
|
6
|
+
* Replaces the `useRef(new Animated.Value(x)).current` boilerplate.
|
|
7
|
+
*/
|
|
8
|
+
export function useAnimatedValue(initialValue: number): Animated.Value {
|
|
9
|
+
return useRef(new Animated.Value(initialValue)).current;
|
|
10
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { useCallback, useEffect, useMemo } from "react";
|
|
2
|
+
import { Animated } from "react-native";
|
|
3
|
+
import { useReducedMotion } from "../useReducedMotion";
|
|
4
|
+
import { springConfig, duration as durationTokens } from "../../tokens/motion";
|
|
5
|
+
import { useAnimatedValue } from "./useAnimatedValue";
|
|
6
|
+
|
|
7
|
+
export interface EntranceAnimationConfig {
|
|
8
|
+
/** Spring config for entrance. Default: springConfig.gentle */
|
|
9
|
+
spring?: { tension: number; friction: number };
|
|
10
|
+
/** Exit timing duration in ms. Default: duration.normal (200) */
|
|
11
|
+
exitDuration?: number;
|
|
12
|
+
/** TranslateY offset (px). Default: -20 */
|
|
13
|
+
translateY?: number;
|
|
14
|
+
/** Initial scale. Default: 0.95 */
|
|
15
|
+
initialScale?: number;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface EntranceAnimationResult {
|
|
19
|
+
/** The underlying animated value (0 = hidden, 1 = visible) */
|
|
20
|
+
animatedValue: Animated.Value;
|
|
21
|
+
/** Pre-built animated style with opacity, translateY, and scale */
|
|
22
|
+
animatedStyle: {
|
|
23
|
+
opacity: Animated.Value;
|
|
24
|
+
transform: (
|
|
25
|
+
| { translateY: Animated.AnimatedInterpolation<number> }
|
|
26
|
+
| { scale: Animated.AnimatedInterpolation<number> }
|
|
27
|
+
)[];
|
|
28
|
+
};
|
|
29
|
+
/** Call to animate out, invokes callback when complete */
|
|
30
|
+
dismiss: (onComplete: () => void) => void;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Entrance/exit animation with opacity, translateY, and scale.
|
|
35
|
+
* Entrance uses spring physics, exit uses timing.
|
|
36
|
+
* Respects reduced motion — skips all animations when enabled.
|
|
37
|
+
* Wired to springConfig.gentle and duration.normal by default.
|
|
38
|
+
*/
|
|
39
|
+
export function useEntranceAnimation(
|
|
40
|
+
config?: EntranceAnimationConfig,
|
|
41
|
+
): EntranceAnimationResult {
|
|
42
|
+
const {
|
|
43
|
+
spring = springConfig.gentle,
|
|
44
|
+
exitDuration = durationTokens.normal,
|
|
45
|
+
translateY = -20,
|
|
46
|
+
initialScale = 0.95,
|
|
47
|
+
} = config ?? {};
|
|
48
|
+
|
|
49
|
+
const prefersReducedMotion = useReducedMotion();
|
|
50
|
+
const animatedValue = useAnimatedValue(prefersReducedMotion ? 1 : 0);
|
|
51
|
+
|
|
52
|
+
// Entrance spring
|
|
53
|
+
useEffect(() => {
|
|
54
|
+
if (prefersReducedMotion) {
|
|
55
|
+
animatedValue.setValue(1);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
Animated.spring(animatedValue, {
|
|
60
|
+
toValue: 1,
|
|
61
|
+
useNativeDriver: true,
|
|
62
|
+
...spring,
|
|
63
|
+
}).start();
|
|
64
|
+
}, [animatedValue, prefersReducedMotion, spring]);
|
|
65
|
+
|
|
66
|
+
// Dismiss handler
|
|
67
|
+
const dismiss = useCallback(
|
|
68
|
+
(onComplete: () => void) => {
|
|
69
|
+
if (prefersReducedMotion) {
|
|
70
|
+
onComplete();
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
Animated.timing(animatedValue, {
|
|
75
|
+
toValue: 0,
|
|
76
|
+
duration: exitDuration,
|
|
77
|
+
useNativeDriver: true,
|
|
78
|
+
}).start(() => onComplete());
|
|
79
|
+
},
|
|
80
|
+
[animatedValue, prefersReducedMotion, exitDuration],
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
// Pre-built style
|
|
84
|
+
const animatedStyle = useMemo(
|
|
85
|
+
() => ({
|
|
86
|
+
opacity: animatedValue,
|
|
87
|
+
transform: [
|
|
88
|
+
{
|
|
89
|
+
translateY: animatedValue.interpolate({
|
|
90
|
+
inputRange: [0, 1],
|
|
91
|
+
outputRange: [translateY, 0],
|
|
92
|
+
}),
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
scale: animatedValue.interpolate({
|
|
96
|
+
inputRange: [0, 1],
|
|
97
|
+
outputRange: [initialScale, 1],
|
|
98
|
+
}),
|
|
99
|
+
},
|
|
100
|
+
],
|
|
101
|
+
}),
|
|
102
|
+
[animatedValue, translateY, initialScale],
|
|
103
|
+
);
|
|
104
|
+
|
|
105
|
+
return { animatedValue, animatedStyle, dismiss };
|
|
106
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { useEffect } from "react";
|
|
2
|
+
import { Animated, Easing } from "react-native";
|
|
3
|
+
import { useReducedMotion } from "../useReducedMotion";
|
|
4
|
+
import { semanticMotion } from "../../tokens/motion";
|
|
5
|
+
import { useAnimatedValue } from "./useAnimatedValue";
|
|
6
|
+
|
|
7
|
+
export interface PulseAnimationConfig {
|
|
8
|
+
/** Total pulse cycle duration in ms. Default: semanticMotion.skeleton.duration (1500) */
|
|
9
|
+
duration?: number;
|
|
10
|
+
/** Minimum opacity. Default: 0.4 */
|
|
11
|
+
minOpacity?: number;
|
|
12
|
+
/** Maximum opacity. Default: 1 */
|
|
13
|
+
maxOpacity?: number;
|
|
14
|
+
/** Whether the animation is active. Default: true */
|
|
15
|
+
enabled?: boolean;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Looping opacity pulse animation.
|
|
20
|
+
* Respects reduced motion — returns static max opacity when disabled.
|
|
21
|
+
* Wired to semanticMotion.skeleton duration by default.
|
|
22
|
+
*/
|
|
23
|
+
export function usePulseAnimation(config?: PulseAnimationConfig): Animated.Value {
|
|
24
|
+
const {
|
|
25
|
+
duration = semanticMotion.skeleton.duration,
|
|
26
|
+
minOpacity = 0.4,
|
|
27
|
+
maxOpacity = 1,
|
|
28
|
+
enabled = true,
|
|
29
|
+
} = config ?? {};
|
|
30
|
+
|
|
31
|
+
const prefersReducedMotion = useReducedMotion();
|
|
32
|
+
const opacity = useAnimatedValue(maxOpacity);
|
|
33
|
+
const isActive = enabled && !prefersReducedMotion;
|
|
34
|
+
|
|
35
|
+
useEffect(() => {
|
|
36
|
+
if (!isActive) {
|
|
37
|
+
opacity.setValue(maxOpacity);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const animation = Animated.loop(
|
|
42
|
+
Animated.sequence([
|
|
43
|
+
Animated.timing(opacity, {
|
|
44
|
+
toValue: minOpacity,
|
|
45
|
+
duration: duration / 2,
|
|
46
|
+
easing: Easing.inOut(Easing.ease),
|
|
47
|
+
useNativeDriver: true,
|
|
48
|
+
}),
|
|
49
|
+
Animated.timing(opacity, {
|
|
50
|
+
toValue: maxOpacity,
|
|
51
|
+
duration: duration / 2,
|
|
52
|
+
easing: Easing.inOut(Easing.ease),
|
|
53
|
+
useNativeDriver: true,
|
|
54
|
+
}),
|
|
55
|
+
]),
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
animation.start();
|
|
59
|
+
return () => animation.stop();
|
|
60
|
+
}, [isActive, duration, minOpacity, maxOpacity, opacity]);
|
|
61
|
+
|
|
62
|
+
return opacity;
|
|
63
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Design System Hooks
|
|
3
|
+
*
|
|
4
|
+
* Custom hooks for motion, animation, and accessibility.
|
|
5
|
+
*
|
|
6
|
+
* ## Motion Hooks
|
|
7
|
+
* - **useReducedMotion**: Respect user's reduced motion preference
|
|
8
|
+
* - **useMotionSafeDuration**: Get 0 duration when reduced motion enabled
|
|
9
|
+
*
|
|
10
|
+
* ## Animation Hooks
|
|
11
|
+
* - **useAnimatedValue**: Stable Animated.Value across re-renders
|
|
12
|
+
* - **usePulseAnimation**: Looping opacity pulse (skeleton shimmer)
|
|
13
|
+
* - **useEntranceAnimation**: Spring entrance + timing exit
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* import { useReducedMotion, usePulseAnimation } from "@/design-system/hooks";
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
// Re-export motion hooks
|
|
20
|
+
export { useReducedMotion, useMotionSafeDuration } from './useReducedMotion';
|
|
21
|
+
|
|
22
|
+
// Re-export animation hooks
|
|
23
|
+
export {
|
|
24
|
+
useAnimatedValue,
|
|
25
|
+
usePulseAnimation,
|
|
26
|
+
useEntranceAnimation,
|
|
27
|
+
type PulseAnimationConfig,
|
|
28
|
+
type EntranceAnimationConfig,
|
|
29
|
+
type EntranceAnimationResult,
|
|
30
|
+
} from './animations';
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* StayEasy Design System - Reduced Motion Hook
|
|
3
|
+
*
|
|
4
|
+
* Respects user's accessibility preference for reduced motion.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* const prefersReducedMotion = useReducedMotion();
|
|
8
|
+
* const animationDuration = prefersReducedMotion ? 0 : 200;
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { useEffect, useState } from 'react';
|
|
12
|
+
import { AccessibilityInfo } from 'react-native';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Hook to detect if the user prefers reduced motion.
|
|
16
|
+
*
|
|
17
|
+
* On iOS: Checks "Reduce Motion" setting
|
|
18
|
+
* On Android: Checks "Remove animations" setting
|
|
19
|
+
*
|
|
20
|
+
* @returns true if user prefers reduced motion
|
|
21
|
+
*/
|
|
22
|
+
export function useReducedMotion(): boolean {
|
|
23
|
+
const [prefersReducedMotion, setPrefersReducedMotion] = useState(false);
|
|
24
|
+
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
// Check initial value
|
|
27
|
+
AccessibilityInfo.isReduceMotionEnabled().then((enabled) => {
|
|
28
|
+
setPrefersReducedMotion(enabled);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
// Subscribe to changes
|
|
32
|
+
const subscription = AccessibilityInfo.addEventListener(
|
|
33
|
+
'reduceMotionChanged',
|
|
34
|
+
(enabled) => {
|
|
35
|
+
setPrefersReducedMotion(enabled);
|
|
36
|
+
}
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
return () => {
|
|
40
|
+
subscription.remove();
|
|
41
|
+
};
|
|
42
|
+
}, []);
|
|
43
|
+
|
|
44
|
+
return prefersReducedMotion;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Get motion-safe duration.
|
|
49
|
+
* Returns 0 if reduced motion is preferred, otherwise the provided duration.
|
|
50
|
+
*
|
|
51
|
+
* @param duration - The desired animation duration in ms
|
|
52
|
+
* @returns Safe duration respecting user preference
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* const duration = useMotionSafeDuration(200);
|
|
56
|
+
*/
|
|
57
|
+
export function useMotionSafeDuration(duration: number): number {
|
|
58
|
+
const prefersReducedMotion = useReducedMotion();
|
|
59
|
+
return prefersReducedMotion ? 0 : duration;
|
|
60
|
+
}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import type { DesignSystemLabels } from "./types";
|
|
2
|
+
|
|
3
|
+
export const en: DesignSystemLabels = {
|
|
4
|
+
designSystem: {
|
|
5
|
+
button: {
|
|
6
|
+
loadingLabel: "Loading",
|
|
7
|
+
},
|
|
8
|
+
iconButton: {
|
|
9
|
+
loadingLabel: "Loading",
|
|
10
|
+
},
|
|
11
|
+
radioButton: {
|
|
12
|
+
fallbackLabel: "Radio button",
|
|
13
|
+
},
|
|
14
|
+
avatar: {
|
|
15
|
+
fallbackLabel: "User avatar",
|
|
16
|
+
statusOnline: "online",
|
|
17
|
+
statusOffline: "offline",
|
|
18
|
+
statusBusy: "busy",
|
|
19
|
+
statusAway: "away",
|
|
20
|
+
},
|
|
21
|
+
badge: {
|
|
22
|
+
fallbackLabel: "badge",
|
|
23
|
+
statusIndicator: "status indicator",
|
|
24
|
+
colorPrimary: "indicator",
|
|
25
|
+
colorSuccess: "success",
|
|
26
|
+
colorWarning: "warning",
|
|
27
|
+
colorError: "error",
|
|
28
|
+
colorInfo: "information",
|
|
29
|
+
},
|
|
30
|
+
chip: {
|
|
31
|
+
toggleHint: "Double tap to toggle selection",
|
|
32
|
+
removeHint: "Double tap to remove",
|
|
33
|
+
},
|
|
34
|
+
spinner: {
|
|
35
|
+
fallbackLabel: "Loading",
|
|
36
|
+
},
|
|
37
|
+
progressBar: {
|
|
38
|
+
fallbackLabel: "Progress",
|
|
39
|
+
},
|
|
40
|
+
toast: {
|
|
41
|
+
prefixSuccess: "Success",
|
|
42
|
+
prefixError: "Error",
|
|
43
|
+
prefixWarning: "Warning",
|
|
44
|
+
prefixInfo: "Info",
|
|
45
|
+
},
|
|
46
|
+
textInput: {
|
|
47
|
+
fallbackLabel: "Text input",
|
|
48
|
+
required: "required",
|
|
49
|
+
errorPrefix: "Error",
|
|
50
|
+
},
|
|
51
|
+
modal: {
|
|
52
|
+
fallbackTitle: "Modal",
|
|
53
|
+
positionBottom: "bottom sheet",
|
|
54
|
+
positionTop: "top dialog",
|
|
55
|
+
positionCenter: "dialog",
|
|
56
|
+
closeLabel: "Close",
|
|
57
|
+
closeHint: "Closes the modal dialog",
|
|
58
|
+
},
|
|
59
|
+
segmentedControl: {
|
|
60
|
+
containerLabel: "Segmented control",
|
|
61
|
+
options: "options",
|
|
62
|
+
selected: "selected",
|
|
63
|
+
currentlySelected: "Currently selected",
|
|
64
|
+
doubleTapToSelect: "Double tap to select",
|
|
65
|
+
of: "of",
|
|
66
|
+
},
|
|
67
|
+
selectSheet: {
|
|
68
|
+
positionBottom: "bottom sheet",
|
|
69
|
+
positionTop: "top sheet",
|
|
70
|
+
positionCenter: "dialog",
|
|
71
|
+
fallbackTitle: "Selection",
|
|
72
|
+
selected: "selected",
|
|
73
|
+
disabled: "disabled",
|
|
74
|
+
of: "of",
|
|
75
|
+
doneLabel: "Done",
|
|
76
|
+
itemsSelected: "items selected",
|
|
77
|
+
doneHint: "Confirms selection and closes the sheet",
|
|
78
|
+
closeLabel: "Close",
|
|
79
|
+
closeHint: "Closes the selection sheet without saving",
|
|
80
|
+
deselected: "deselected",
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
calendar: {
|
|
84
|
+
datePicker: {
|
|
85
|
+
label: "Date picker",
|
|
86
|
+
selected: "selected",
|
|
87
|
+
today: "today",
|
|
88
|
+
daysShown: "days shown",
|
|
89
|
+
},
|
|
90
|
+
days: {
|
|
91
|
+
sun: "Sun",
|
|
92
|
+
mon: "Mon",
|
|
93
|
+
tue: "Tue",
|
|
94
|
+
wed: "Wed",
|
|
95
|
+
thu: "Thu",
|
|
96
|
+
fri: "Fri",
|
|
97
|
+
sat: "Sat",
|
|
98
|
+
},
|
|
99
|
+
months: {
|
|
100
|
+
jan: "Jan",
|
|
101
|
+
feb: "Feb",
|
|
102
|
+
mar: "Mar",
|
|
103
|
+
apr: "Apr",
|
|
104
|
+
may: "May",
|
|
105
|
+
jun: "Jun",
|
|
106
|
+
jul: "Jul",
|
|
107
|
+
aug: "Aug",
|
|
108
|
+
sep: "Sep",
|
|
109
|
+
oct: "Oct",
|
|
110
|
+
nov: "Nov",
|
|
111
|
+
dec: "Dec",
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
header: {
|
|
115
|
+
backButton: {
|
|
116
|
+
label: "Go back",
|
|
117
|
+
hint: "Navigates to the previous screen",
|
|
118
|
+
},
|
|
119
|
+
},
|
|
120
|
+
};
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import type { DesignSystemLabels } from "./types";
|
|
2
|
+
|
|
3
|
+
export const es: DesignSystemLabels = {
|
|
4
|
+
designSystem: {
|
|
5
|
+
button: {
|
|
6
|
+
loadingLabel: "Cargando",
|
|
7
|
+
},
|
|
8
|
+
iconButton: {
|
|
9
|
+
loadingLabel: "Cargando",
|
|
10
|
+
},
|
|
11
|
+
radioButton: {
|
|
12
|
+
fallbackLabel: "Botón de radio",
|
|
13
|
+
},
|
|
14
|
+
avatar: {
|
|
15
|
+
fallbackLabel: "Avatar de usuario",
|
|
16
|
+
statusOnline: "en línea",
|
|
17
|
+
statusOffline: "desconectado",
|
|
18
|
+
statusBusy: "ocupado",
|
|
19
|
+
statusAway: "ausente",
|
|
20
|
+
},
|
|
21
|
+
badge: {
|
|
22
|
+
fallbackLabel: "insignia",
|
|
23
|
+
statusIndicator: "indicador de estado",
|
|
24
|
+
colorPrimary: "indicador",
|
|
25
|
+
colorSuccess: "éxito",
|
|
26
|
+
colorWarning: "advertencia",
|
|
27
|
+
colorError: "error",
|
|
28
|
+
colorInfo: "información",
|
|
29
|
+
},
|
|
30
|
+
chip: {
|
|
31
|
+
toggleHint: "Toca dos veces para alternar selección",
|
|
32
|
+
removeHint: "Toca dos veces para eliminar",
|
|
33
|
+
},
|
|
34
|
+
spinner: {
|
|
35
|
+
fallbackLabel: "Cargando",
|
|
36
|
+
},
|
|
37
|
+
progressBar: {
|
|
38
|
+
fallbackLabel: "Progreso",
|
|
39
|
+
},
|
|
40
|
+
toast: {
|
|
41
|
+
prefixSuccess: "Éxito",
|
|
42
|
+
prefixError: "Error",
|
|
43
|
+
prefixWarning: "Advertencia",
|
|
44
|
+
prefixInfo: "Info",
|
|
45
|
+
},
|
|
46
|
+
textInput: {
|
|
47
|
+
fallbackLabel: "Campo de texto",
|
|
48
|
+
required: "requerido",
|
|
49
|
+
errorPrefix: "Error",
|
|
50
|
+
},
|
|
51
|
+
modal: {
|
|
52
|
+
fallbackTitle: "Modal",
|
|
53
|
+
positionBottom: "hoja inferior",
|
|
54
|
+
positionTop: "diálogo superior",
|
|
55
|
+
positionCenter: "diálogo",
|
|
56
|
+
closeLabel: "Cerrar",
|
|
57
|
+
closeHint: "Cierra el diálogo modal",
|
|
58
|
+
},
|
|
59
|
+
segmentedControl: {
|
|
60
|
+
containerLabel: "Control segmentado",
|
|
61
|
+
options: "opciones",
|
|
62
|
+
selected: "seleccionado",
|
|
63
|
+
currentlySelected: "Actualmente seleccionado",
|
|
64
|
+
doubleTapToSelect: "Toca dos veces para seleccionar",
|
|
65
|
+
of: "de",
|
|
66
|
+
},
|
|
67
|
+
selectSheet: {
|
|
68
|
+
positionBottom: "hoja inferior",
|
|
69
|
+
positionTop: "hoja superior",
|
|
70
|
+
positionCenter: "diálogo",
|
|
71
|
+
fallbackTitle: "Selección",
|
|
72
|
+
selected: "seleccionado",
|
|
73
|
+
disabled: "deshabilitado",
|
|
74
|
+
of: "de",
|
|
75
|
+
doneLabel: "Listo",
|
|
76
|
+
itemsSelected: "elementos seleccionados",
|
|
77
|
+
doneHint: "Confirma la selección y cierra la hoja",
|
|
78
|
+
closeLabel: "Cerrar",
|
|
79
|
+
closeHint: "Cierra la hoja de selección sin guardar",
|
|
80
|
+
deselected: "deseleccionado",
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
calendar: {
|
|
84
|
+
datePicker: {
|
|
85
|
+
label: "Selector de fecha",
|
|
86
|
+
selected: "seleccionado",
|
|
87
|
+
today: "hoy",
|
|
88
|
+
daysShown: "días mostrados",
|
|
89
|
+
},
|
|
90
|
+
days: {
|
|
91
|
+
sun: "Dom",
|
|
92
|
+
mon: "Lun",
|
|
93
|
+
tue: "Mar",
|
|
94
|
+
wed: "Mié",
|
|
95
|
+
thu: "Jue",
|
|
96
|
+
fri: "Vie",
|
|
97
|
+
sat: "Sáb",
|
|
98
|
+
},
|
|
99
|
+
months: {
|
|
100
|
+
jan: "Ene",
|
|
101
|
+
feb: "Feb",
|
|
102
|
+
mar: "Mar",
|
|
103
|
+
apr: "Abr",
|
|
104
|
+
may: "May",
|
|
105
|
+
jun: "Jun",
|
|
106
|
+
jul: "Jul",
|
|
107
|
+
aug: "Ago",
|
|
108
|
+
sep: "Sep",
|
|
109
|
+
oct: "Oct",
|
|
110
|
+
nov: "Nov",
|
|
111
|
+
dec: "Dic",
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
header: {
|
|
115
|
+
backButton: {
|
|
116
|
+
label: "Volver",
|
|
117
|
+
hint: "Navega a la pantalla anterior",
|
|
118
|
+
},
|
|
119
|
+
},
|
|
120
|
+
};
|