@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,241 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Toast Provider
|
|
3
|
+
*
|
|
4
|
+
* Provider component that manages the toast notification queue
|
|
5
|
+
* and renders toasts at a configured position on screen.
|
|
6
|
+
*
|
|
7
|
+
* ## Features
|
|
8
|
+
* - Queue management with max visible limit
|
|
9
|
+
* - Auto-dismiss with configurable duration
|
|
10
|
+
* - Position at top or bottom of screen
|
|
11
|
+
* - Safe area aware positioning
|
|
12
|
+
* - Smooth stacked animations
|
|
13
|
+
*
|
|
14
|
+
* @see ToastContext.tsx - Context and useToast hook
|
|
15
|
+
* @see Toast.tsx - Toast component
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* // In your app root
|
|
19
|
+
* <ToastProvider position="bottom" maxVisible={3}>
|
|
20
|
+
* <App />
|
|
21
|
+
* </ToastProvider>
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* // In any child component
|
|
25
|
+
* const toast = useToast();
|
|
26
|
+
* toast.success("Saved successfully!");
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
import React, { useCallback, useMemo, useRef, useState } from "react";
|
|
30
|
+
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|
31
|
+
import { Box } from "../../layout";
|
|
32
|
+
import { Toast } from "./Toast";
|
|
33
|
+
import { generateToastId } from "./Toast.helpers";
|
|
34
|
+
import {
|
|
35
|
+
ShowToastOptions,
|
|
36
|
+
ToastConfig,
|
|
37
|
+
ToastContainerProps,
|
|
38
|
+
ToastContextValue,
|
|
39
|
+
} from "./Toast.types";
|
|
40
|
+
import { ToastContext } from "./ToastContext";
|
|
41
|
+
|
|
42
|
+
/** Default duration for auto-dismiss in ms */
|
|
43
|
+
const DEFAULT_DURATION = 3000;
|
|
44
|
+
|
|
45
|
+
/** Default max visible toasts */
|
|
46
|
+
const DEFAULT_MAX_VISIBLE = 3;
|
|
47
|
+
|
|
48
|
+
interface ToastProviderProps extends ToastContainerProps {
|
|
49
|
+
/** Child components */
|
|
50
|
+
children: React.ReactNode;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Provider component for toast notifications.
|
|
55
|
+
*
|
|
56
|
+
* Wrap your app with this provider to enable toast notifications
|
|
57
|
+
* from anywhere using the useToast hook.
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* <ToastProvider position="bottom">
|
|
61
|
+
* <App />
|
|
62
|
+
* </ToastProvider>
|
|
63
|
+
*/
|
|
64
|
+
export function ToastProvider({
|
|
65
|
+
children,
|
|
66
|
+
position = "bottom",
|
|
67
|
+
maxVisible = DEFAULT_MAX_VISIBLE,
|
|
68
|
+
testID,
|
|
69
|
+
}: ToastProviderProps) {
|
|
70
|
+
const [toasts, setToasts] = useState<ToastConfig[]>([]);
|
|
71
|
+
const timersRef = useRef<Map<string, NodeJS.Timeout>>(new Map());
|
|
72
|
+
const insets = useSafeAreaInsets();
|
|
73
|
+
|
|
74
|
+
// Clean up timer for a toast
|
|
75
|
+
const clearTimer = useCallback((id: string) => {
|
|
76
|
+
const timer = timersRef.current.get(id);
|
|
77
|
+
if (timer) {
|
|
78
|
+
clearTimeout(timer);
|
|
79
|
+
timersRef.current.delete(id);
|
|
80
|
+
}
|
|
81
|
+
}, []);
|
|
82
|
+
|
|
83
|
+
// Dismiss a specific toast
|
|
84
|
+
const dismiss = useCallback(
|
|
85
|
+
(id: string) => {
|
|
86
|
+
clearTimer(id);
|
|
87
|
+
setToasts((prev) => prev.filter((toast) => toast.id !== id));
|
|
88
|
+
},
|
|
89
|
+
[clearTimer],
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
// Dismiss all toasts
|
|
93
|
+
const dismissAll = useCallback(() => {
|
|
94
|
+
timersRef.current.forEach((_, id) => clearTimer(id));
|
|
95
|
+
setToasts([]);
|
|
96
|
+
}, [clearTimer]);
|
|
97
|
+
|
|
98
|
+
// Show a new toast
|
|
99
|
+
const show = useCallback(
|
|
100
|
+
(options: ShowToastOptions): string => {
|
|
101
|
+
const id = generateToastId();
|
|
102
|
+
const duration = options.duration ?? DEFAULT_DURATION;
|
|
103
|
+
|
|
104
|
+
const config: ToastConfig = {
|
|
105
|
+
id,
|
|
106
|
+
message: options.message,
|
|
107
|
+
variant: options.variant ?? "info",
|
|
108
|
+
duration,
|
|
109
|
+
action: options.action,
|
|
110
|
+
dismissible: options.dismissible ?? true,
|
|
111
|
+
iconName: options.iconName,
|
|
112
|
+
accessibilityLabel: options.accessibilityLabel,
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
setToasts((prev) => {
|
|
116
|
+
// Remove oldest if at max capacity
|
|
117
|
+
const newToasts = [...prev, config];
|
|
118
|
+
if (newToasts.length > maxVisible) {
|
|
119
|
+
const removed = newToasts.shift();
|
|
120
|
+
if (removed) {
|
|
121
|
+
clearTimer(removed.id);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return newToasts;
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
// Set auto-dismiss timer if duration > 0
|
|
128
|
+
if (duration > 0) {
|
|
129
|
+
const timer = setTimeout(() => {
|
|
130
|
+
dismiss(id);
|
|
131
|
+
}, duration);
|
|
132
|
+
timersRef.current.set(id, timer as unknown as NodeJS.Timeout);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return id;
|
|
136
|
+
},
|
|
137
|
+
[maxVisible, clearTimer, dismiss],
|
|
138
|
+
);
|
|
139
|
+
|
|
140
|
+
// Convenience methods for each variant
|
|
141
|
+
const success = useCallback(
|
|
142
|
+
(
|
|
143
|
+
message: string,
|
|
144
|
+
options?: Omit<ShowToastOptions, "message" | "variant">,
|
|
145
|
+
) => show({ ...options, message, variant: "success" }),
|
|
146
|
+
[show],
|
|
147
|
+
);
|
|
148
|
+
|
|
149
|
+
const error = useCallback(
|
|
150
|
+
(
|
|
151
|
+
message: string,
|
|
152
|
+
options?: Omit<ShowToastOptions, "message" | "variant">,
|
|
153
|
+
) => show({ ...options, message, variant: "error" }),
|
|
154
|
+
[show],
|
|
155
|
+
);
|
|
156
|
+
|
|
157
|
+
const warning = useCallback(
|
|
158
|
+
(
|
|
159
|
+
message: string,
|
|
160
|
+
options?: Omit<ShowToastOptions, "message" | "variant">,
|
|
161
|
+
) => show({ ...options, message, variant: "warning" }),
|
|
162
|
+
[show],
|
|
163
|
+
);
|
|
164
|
+
|
|
165
|
+
const info = useCallback(
|
|
166
|
+
(
|
|
167
|
+
message: string,
|
|
168
|
+
options?: Omit<ShowToastOptions, "message" | "variant">,
|
|
169
|
+
) => show({ ...options, message, variant: "info" }),
|
|
170
|
+
[show],
|
|
171
|
+
);
|
|
172
|
+
|
|
173
|
+
// Memoize context value
|
|
174
|
+
const contextValue: ToastContextValue = useMemo(
|
|
175
|
+
() => ({
|
|
176
|
+
show,
|
|
177
|
+
success,
|
|
178
|
+
error,
|
|
179
|
+
warning,
|
|
180
|
+
info,
|
|
181
|
+
dismiss,
|
|
182
|
+
dismissAll,
|
|
183
|
+
}),
|
|
184
|
+
[show, success, error, warning, info, dismiss, dismissAll],
|
|
185
|
+
);
|
|
186
|
+
|
|
187
|
+
// Calculate container position styles
|
|
188
|
+
const containerStyle = useMemo(() => {
|
|
189
|
+
const baseStyle = {
|
|
190
|
+
position: "absolute" as const,
|
|
191
|
+
left: 16,
|
|
192
|
+
right: 16,
|
|
193
|
+
zIndex: 9999,
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
if (position === "top") {
|
|
197
|
+
return {
|
|
198
|
+
...baseStyle,
|
|
199
|
+
top: insets.top + 8,
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
return {
|
|
204
|
+
...baseStyle,
|
|
205
|
+
bottom: insets.bottom + 8,
|
|
206
|
+
};
|
|
207
|
+
}, [position, insets]);
|
|
208
|
+
|
|
209
|
+
return (
|
|
210
|
+
<ToastContext.Provider value={contextValue}>
|
|
211
|
+
{children}
|
|
212
|
+
|
|
213
|
+
{/* Toast container */}
|
|
214
|
+
{toasts.length > 0 && (
|
|
215
|
+
<Box
|
|
216
|
+
style={containerStyle}
|
|
217
|
+
gap="xs"
|
|
218
|
+
testID={testID}
|
|
219
|
+
pointerEvents="box-none"
|
|
220
|
+
>
|
|
221
|
+
{toasts.map((toast) => (
|
|
222
|
+
<Toast
|
|
223
|
+
key={toast.id}
|
|
224
|
+
id={toast.id}
|
|
225
|
+
message={toast.message}
|
|
226
|
+
variant={toast.variant}
|
|
227
|
+
action={toast.action}
|
|
228
|
+
dismissible={toast.dismissible}
|
|
229
|
+
iconName={toast.iconName}
|
|
230
|
+
accessibilityLabel={toast.accessibilityLabel}
|
|
231
|
+
onDismiss={() => dismiss(toast.id)}
|
|
232
|
+
testID={testID ? `${testID}-toast-${toast.id}` : undefined}
|
|
233
|
+
/>
|
|
234
|
+
))}
|
|
235
|
+
</Box>
|
|
236
|
+
)}
|
|
237
|
+
</ToastContext.Provider>
|
|
238
|
+
);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
ToastProvider.displayName = "ToastProvider";
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Toast Module
|
|
3
|
+
*
|
|
4
|
+
* Toast notifications for user feedback with variants for
|
|
5
|
+
* success, error, warning, and info states.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* // Using the provider and hook
|
|
9
|
+
* import { ToastProvider, useToast } from "@/design-system/primitives/feedback/Toast";
|
|
10
|
+
*
|
|
11
|
+
* // In app root
|
|
12
|
+
* <ToastProvider position="bottom">
|
|
13
|
+
* <App />
|
|
14
|
+
* </ToastProvider>
|
|
15
|
+
*
|
|
16
|
+
* // In any component
|
|
17
|
+
* const toast = useToast();
|
|
18
|
+
* toast.success("Saved!");
|
|
19
|
+
* toast.error("Failed to save");
|
|
20
|
+
* toast.warning("Low battery");
|
|
21
|
+
* toast.info("New update available");
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* // Direct Toast component usage (advanced)
|
|
25
|
+
* import { Toast } from "@/design-system/primitives/feedback/Toast";
|
|
26
|
+
*
|
|
27
|
+
* <Toast
|
|
28
|
+
* id="toast-1"
|
|
29
|
+
* message="Changes saved"
|
|
30
|
+
* variant="success"
|
|
31
|
+
* onDismiss={() => handleDismiss("toast-1")}
|
|
32
|
+
* />
|
|
33
|
+
*/
|
|
34
|
+
|
|
35
|
+
// Main component
|
|
36
|
+
export { Toast } from "./Toast";
|
|
37
|
+
|
|
38
|
+
// Provider and context
|
|
39
|
+
export { ToastProvider } from "./ToastProvider";
|
|
40
|
+
export { ToastContext, useToast } from "./ToastContext";
|
|
41
|
+
|
|
42
|
+
// Types
|
|
43
|
+
export type {
|
|
44
|
+
ToastProps,
|
|
45
|
+
ToastVariant,
|
|
46
|
+
ToastPosition,
|
|
47
|
+
ToastConfig,
|
|
48
|
+
ToastAction,
|
|
49
|
+
ToastContainerProps,
|
|
50
|
+
ShowToastOptions,
|
|
51
|
+
ToastContextValue,
|
|
52
|
+
BaseToastProps,
|
|
53
|
+
} from "./Toast.types";
|
|
54
|
+
|
|
55
|
+
// Helpers (for testing or advanced usage)
|
|
56
|
+
export { generateToastId } from "./Toast.helpers";
|
|
57
|
+
|
|
58
|
+
// Accessibility
|
|
59
|
+
export * from "./Toast.a11y";
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Toast Logic Hook
|
|
3
|
+
*
|
|
4
|
+
* Extracts all computational logic from the Toast component.
|
|
5
|
+
* Returns memoized values for optimal render performance.
|
|
6
|
+
*
|
|
7
|
+
* Responsibilities:
|
|
8
|
+
* - Map variant to color tokens
|
|
9
|
+
* - Resolve icon based on variant
|
|
10
|
+
* - Generate accessibility props
|
|
11
|
+
*
|
|
12
|
+
* @see Toast.tsx - Component consuming this hook
|
|
13
|
+
* @see Toast.helpers.ts - Pure calculation functions
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import { useDesignSystem } from "../../../provider";
|
|
17
|
+
import { useResponsiveProp } from "@shopify/restyle";
|
|
18
|
+
import { useMemo } from "react";
|
|
19
|
+
import { getToastA11y } from "./Toast.a11y";
|
|
20
|
+
import {
|
|
21
|
+
getToastBackgroundColor,
|
|
22
|
+
getToastBorderColor,
|
|
23
|
+
getToastIcon,
|
|
24
|
+
getToastIconColor,
|
|
25
|
+
getToastTextColor,
|
|
26
|
+
} from "./Toast.helpers";
|
|
27
|
+
import { ToastVariant, UseToastLogicParams, UseToastLogicReturn } from "./Toast.types";
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Orchestrates Toast rendering logic and state management.
|
|
31
|
+
*
|
|
32
|
+
* Handles:
|
|
33
|
+
* - Responsive variant resolution
|
|
34
|
+
* - Color token mapping (background, border, icon, text)
|
|
35
|
+
* - Icon resolution based on variant (auto or custom)
|
|
36
|
+
* - Accessibility props generation with semantic roles
|
|
37
|
+
*
|
|
38
|
+
* @param params - Configuration object for toast behavior
|
|
39
|
+
* @param params.variant - Semantic variant ('info' | 'success' | 'warning' | 'error')
|
|
40
|
+
* @param params.iconName - Optional custom icon (overrides variant default)
|
|
41
|
+
* @param params.accessibilityLabel - Custom a11y label
|
|
42
|
+
* @param params.message - Toast message text
|
|
43
|
+
*
|
|
44
|
+
* @returns Computed values for rendering Toast
|
|
45
|
+
* @returns {string} themeVariantKey - Resolved variant identifier
|
|
46
|
+
* @returns {string} backgroundColorToken - Background color token
|
|
47
|
+
* @returns {string} borderColorToken - Border color token
|
|
48
|
+
* @returns {string} iconColorToken - Icon color token
|
|
49
|
+
* @returns {string} textColorToken - Text color token
|
|
50
|
+
* @returns {string} resolvedIconName - Icon name (variant default or custom)
|
|
51
|
+
* @returns {object} a11yProps - Accessibility props with semantic role
|
|
52
|
+
*
|
|
53
|
+
* @performance This hook uses useMemo() for color and icon resolution
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* const {
|
|
57
|
+
* backgroundColorToken,
|
|
58
|
+
* iconColorToken,
|
|
59
|
+
* resolvedIconName,
|
|
60
|
+
* a11yProps,
|
|
61
|
+
* } = useToastLogic({
|
|
62
|
+
* variant: "success",
|
|
63
|
+
* message: "Changes saved successfully",
|
|
64
|
+
* });
|
|
65
|
+
*/
|
|
66
|
+
export function useToastLogic({
|
|
67
|
+
variant,
|
|
68
|
+
iconName,
|
|
69
|
+
accessibilityLabel,
|
|
70
|
+
message,
|
|
71
|
+
}: UseToastLogicParams): UseToastLogicReturn {
|
|
72
|
+
const { labels: t } = useDesignSystem();
|
|
73
|
+
|
|
74
|
+
const resolvedVariant = (useResponsiveProp(variant) ?? "info") as ToastVariant;
|
|
75
|
+
|
|
76
|
+
const variantPrefixes = useMemo(() => ({
|
|
77
|
+
success: t.designSystem.toast.prefixSuccess,
|
|
78
|
+
error: t.designSystem.toast.prefixError,
|
|
79
|
+
warning: t.designSystem.toast.prefixWarning,
|
|
80
|
+
info: t.designSystem.toast.prefixInfo,
|
|
81
|
+
}), [t]);
|
|
82
|
+
|
|
83
|
+
const colorTokens = useMemo(
|
|
84
|
+
() => ({
|
|
85
|
+
backgroundColorToken: getToastBackgroundColor(resolvedVariant),
|
|
86
|
+
borderColorToken: getToastBorderColor(resolvedVariant),
|
|
87
|
+
iconColorToken: getToastIconColor(resolvedVariant),
|
|
88
|
+
textColorToken: getToastTextColor(resolvedVariant),
|
|
89
|
+
}),
|
|
90
|
+
[resolvedVariant]
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
const resolvedIconName = getToastIcon(resolvedVariant, iconName);
|
|
94
|
+
|
|
95
|
+
const a11yProps = useMemo(
|
|
96
|
+
() =>
|
|
97
|
+
getToastA11y({
|
|
98
|
+
variant: resolvedVariant,
|
|
99
|
+
accessibilityLabel,
|
|
100
|
+
message,
|
|
101
|
+
variantPrefixes,
|
|
102
|
+
}),
|
|
103
|
+
[resolvedVariant, accessibilityLabel, message, variantPrefixes]
|
|
104
|
+
);
|
|
105
|
+
|
|
106
|
+
return {
|
|
107
|
+
themeVariantKey: resolvedVariant,
|
|
108
|
+
...colorTokens,
|
|
109
|
+
resolvedIconName,
|
|
110
|
+
a11yProps,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Feedback Components Module
|
|
3
|
+
*
|
|
4
|
+
* Components that provide visual feedback to users during
|
|
5
|
+
* loading states, errors, and other system events.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* import { Spinner, ProgressBar, Skeleton, EmptyState, Toast, useToast, ToastProvider } from "@/design-system/primitives/feedback";
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
export {
|
|
12
|
+
ProgressBar,
|
|
13
|
+
type ProgressBarProps,
|
|
14
|
+
type ProgressBarSize,
|
|
15
|
+
} from "./ProgressBar";
|
|
16
|
+
|
|
17
|
+
export {
|
|
18
|
+
Skeleton,
|
|
19
|
+
type SkeletonAnimation,
|
|
20
|
+
type SkeletonProps,
|
|
21
|
+
type SkeletonSize,
|
|
22
|
+
type SkeletonVariant,
|
|
23
|
+
} from "./Skeleton";
|
|
24
|
+
|
|
25
|
+
export {
|
|
26
|
+
Spinner,
|
|
27
|
+
type SpinnerProps,
|
|
28
|
+
type SpinnerSize,
|
|
29
|
+
} from "./Spinner";
|
|
30
|
+
|
|
31
|
+
export {
|
|
32
|
+
Toast,
|
|
33
|
+
ToastProvider,
|
|
34
|
+
ToastContext,
|
|
35
|
+
useToast,
|
|
36
|
+
generateToastId,
|
|
37
|
+
type ToastProps,
|
|
38
|
+
type ToastVariant,
|
|
39
|
+
type ToastPosition,
|
|
40
|
+
type ToastConfig,
|
|
41
|
+
type ToastAction,
|
|
42
|
+
type ToastContainerProps,
|
|
43
|
+
type ShowToastOptions,
|
|
44
|
+
type ToastContextValue,
|
|
45
|
+
} from "./Toast";
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Design System Components
|
|
3
|
+
*
|
|
4
|
+
* Barrel export for all design system components.
|
|
5
|
+
* Grouped by interaction model.
|
|
6
|
+
*
|
|
7
|
+
* ## Categories
|
|
8
|
+
*
|
|
9
|
+
* - **actions** — User triggers something (Button, IconButton)
|
|
10
|
+
* - **inputs** — User provides data/selection (TextInput, Checkbox, Switch, etc.)
|
|
11
|
+
* - **content** — Presents information (Avatar, Badge, Card, Icon, etc.)
|
|
12
|
+
* - **feedback** — System communicates state (Spinner, Toast, Skeleton, etc.)
|
|
13
|
+
* - **layout** — Structures space (Divider, Box)
|
|
14
|
+
* - **navigation** — Orients the user (Header)
|
|
15
|
+
* - **overlays** — Elevated surfaces (Modal)
|
|
16
|
+
*
|
|
17
|
+
* ## Touch Targets
|
|
18
|
+
* All interactive components meet 44px minimum (Apple HIG)
|
|
19
|
+
* via container size or hitSlop.
|
|
20
|
+
*
|
|
21
|
+
* @see tokens/scales.ts - Mathematical constants (ICON_RATIOS, touch targets)
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
// ─── Actions ────────────────────────────────────────────────────────────────
|
|
25
|
+
export {
|
|
26
|
+
Button,
|
|
27
|
+
IconButton,
|
|
28
|
+
type ButtonProps,
|
|
29
|
+
type ButtonRef,
|
|
30
|
+
type ButtonSize,
|
|
31
|
+
type ButtonVariant,
|
|
32
|
+
type IconButtonProps,
|
|
33
|
+
type IconButtonSize,
|
|
34
|
+
type IconButtonVariant,
|
|
35
|
+
} from "./actions";
|
|
36
|
+
|
|
37
|
+
// ─── Inputs ─────────────────────────────────────────────────────────────────
|
|
38
|
+
export {
|
|
39
|
+
Checkbox,
|
|
40
|
+
RadioButton,
|
|
41
|
+
SegmentedControl,
|
|
42
|
+
SelectSheet,
|
|
43
|
+
Switch,
|
|
44
|
+
TextInput,
|
|
45
|
+
type CheckboxProps,
|
|
46
|
+
type CheckboxRef,
|
|
47
|
+
type CheckboxSize,
|
|
48
|
+
type RadioButtonProps,
|
|
49
|
+
type RadioButtonRef,
|
|
50
|
+
type RadioButtonSize,
|
|
51
|
+
type SegmentedControlProps,
|
|
52
|
+
type SegmentedControlSize,
|
|
53
|
+
type SegmentedControlVariant,
|
|
54
|
+
type SegmentOption,
|
|
55
|
+
type SelectSheetIndicatorPosition,
|
|
56
|
+
type SelectSheetMode,
|
|
57
|
+
type SelectSheetOption,
|
|
58
|
+
type SelectSheetPosition,
|
|
59
|
+
type SelectSheetProps,
|
|
60
|
+
type SwitchProps,
|
|
61
|
+
type SwitchRef,
|
|
62
|
+
type SwitchSize,
|
|
63
|
+
type TextInputProps,
|
|
64
|
+
type TextInputRef,
|
|
65
|
+
type TextInputSize,
|
|
66
|
+
type TextInputVariant,
|
|
67
|
+
} from "./inputs";
|
|
68
|
+
|
|
69
|
+
// ─── Content ────────────────────────────────────────────────────────────────
|
|
70
|
+
export {
|
|
71
|
+
Avatar,
|
|
72
|
+
Badge,
|
|
73
|
+
Card,
|
|
74
|
+
Chip,
|
|
75
|
+
Icon,
|
|
76
|
+
type AvatarProps,
|
|
77
|
+
type AvatarSize,
|
|
78
|
+
type AvatarStatus,
|
|
79
|
+
type BadgeProps,
|
|
80
|
+
type BadgeSize,
|
|
81
|
+
type BadgeVariant,
|
|
82
|
+
type CardProps,
|
|
83
|
+
type CardVariant,
|
|
84
|
+
type ChipProps,
|
|
85
|
+
type ChipSize,
|
|
86
|
+
type ChipVariant,
|
|
87
|
+
type IconName,
|
|
88
|
+
type IconProps,
|
|
89
|
+
} from "./content";
|
|
90
|
+
|
|
91
|
+
// ─── Feedback ───────────────────────────────────────────────────────────────
|
|
92
|
+
export {
|
|
93
|
+
generateToastId,
|
|
94
|
+
ProgressBar,
|
|
95
|
+
Skeleton,
|
|
96
|
+
Spinner,
|
|
97
|
+
Toast,
|
|
98
|
+
ToastContext,
|
|
99
|
+
ToastProvider,
|
|
100
|
+
useToast,
|
|
101
|
+
type ProgressBarProps,
|
|
102
|
+
type ProgressBarSize,
|
|
103
|
+
type ShowToastOptions,
|
|
104
|
+
type SkeletonAnimation,
|
|
105
|
+
type SkeletonProps,
|
|
106
|
+
type SkeletonSize,
|
|
107
|
+
type SkeletonVariant,
|
|
108
|
+
type SpinnerProps,
|
|
109
|
+
type SpinnerSize,
|
|
110
|
+
type ToastAction,
|
|
111
|
+
type ToastConfig,
|
|
112
|
+
type ToastContainerProps,
|
|
113
|
+
type ToastContextValue,
|
|
114
|
+
type ToastPosition,
|
|
115
|
+
type ToastProps,
|
|
116
|
+
type ToastVariant,
|
|
117
|
+
} from "./feedback";
|
|
118
|
+
|
|
119
|
+
// ─── Layout ─────────────────────────────────────────────────────────────────
|
|
120
|
+
export {
|
|
121
|
+
AnimatedBox,
|
|
122
|
+
Box,
|
|
123
|
+
Divider,
|
|
124
|
+
FlatList,
|
|
125
|
+
HStack,
|
|
126
|
+
Pressable,
|
|
127
|
+
ScrollView,
|
|
128
|
+
VStack,
|
|
129
|
+
type BoxRestyleProps,
|
|
130
|
+
type DividerColor,
|
|
131
|
+
type DividerOrientation,
|
|
132
|
+
type DividerProps,
|
|
133
|
+
type DividerSpacing,
|
|
134
|
+
type DividerThickness,
|
|
135
|
+
type FlatListProps,
|
|
136
|
+
type FlatListRef,
|
|
137
|
+
type FlatListRestyleProps,
|
|
138
|
+
type HStackProps,
|
|
139
|
+
type PressableProps,
|
|
140
|
+
type PressableRestyleProps,
|
|
141
|
+
type ScrollViewProps,
|
|
142
|
+
type ScrollViewRef,
|
|
143
|
+
type ScrollViewRestyleProps,
|
|
144
|
+
type VStackProps,
|
|
145
|
+
} from "./layout";
|
|
146
|
+
|
|
147
|
+
// ─── Navigation ─────────────────────────────────────────────────────────────
|
|
148
|
+
// (Header moved to design-system/components)
|
|
149
|
+
|
|
150
|
+
// ─── Overlays ───────────────────────────────────────────────────────────────
|
|
151
|
+
export {
|
|
152
|
+
Modal,
|
|
153
|
+
type ModalAction,
|
|
154
|
+
type ModalPosition,
|
|
155
|
+
type ModalProps,
|
|
156
|
+
} from "./overlays";
|
|
157
|
+
|
|
158
|
+
export * from "./typography";
|