@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.
Files changed (187) hide show
  1. package/dist/index.d.mts +52556 -0
  2. package/dist/index.d.ts +52556 -0
  3. package/dist/index.js +8753 -0
  4. package/dist/index.mjs +8777 -0
  5. package/package.json +70 -0
  6. package/src/__test-utils__/index.tsx +39 -0
  7. package/src/components/CalendarStrip/CalendarStrip.helpers.ts +106 -0
  8. package/src/components/CalendarStrip/CalendarStrip.tsx +83 -0
  9. package/src/components/CalendarStrip/CalendarStrip.types.ts +133 -0
  10. package/src/components/CalendarStrip/DayCard/DayCard.helpers.ts +44 -0
  11. package/src/components/CalendarStrip/DayCard/DayCard.tsx +71 -0
  12. package/src/components/CalendarStrip/DayCard/DayCard.types.ts +134 -0
  13. package/src/components/CalendarStrip/DayCard/index.ts +2 -0
  14. package/src/components/CalendarStrip/DayCard/useDayCardLogic.ts +45 -0
  15. package/src/components/CalendarStrip/index.ts +9 -0
  16. package/src/components/CalendarStrip/useCalendarStripLogic.ts +53 -0
  17. package/src/components/EmptyState/EmptyState.helpers.ts +104 -0
  18. package/src/components/EmptyState/EmptyState.tsx +205 -0
  19. package/src/components/EmptyState/EmptyState.types.ts +213 -0
  20. package/src/components/EmptyState/index.ts +44 -0
  21. package/src/components/EmptyState/useEmptyStateLogic.ts +131 -0
  22. package/src/components/Header/Header.helpers.ts +93 -0
  23. package/src/components/Header/Header.tsx +185 -0
  24. package/src/components/Header/Header.types.ts +153 -0
  25. package/src/components/Header/index.ts +44 -0
  26. package/src/components/Header/useHeaderLogic.ts +146 -0
  27. package/src/components/ScheduleItem/ScheduleItem/ScheduleItem.helpers.ts +50 -0
  28. package/src/components/ScheduleItem/ScheduleItem/ScheduleItem.tsx +78 -0
  29. package/src/components/ScheduleItem/ScheduleItem/ScheduleItem.types.ts +99 -0
  30. package/src/components/ScheduleItem/ScheduleItem/index.ts +16 -0
  31. package/src/components/ScheduleItem/ScheduleItem/useScheduleItemLogic.ts +31 -0
  32. package/src/components/ScheduleItem/index.ts +15 -0
  33. package/src/components/index.ts +40 -0
  34. package/src/core/index.ts +34 -0
  35. package/src/core/restyle/RestyleThemeProviderWrapper.tsx +31 -0
  36. package/src/core/restyle/index.ts +38 -0
  37. package/src/core/restyle/restylePresetRegistry.ts +195 -0
  38. package/src/core/restyle/restyleTheme.ts +1352 -0
  39. package/src/core/restyle/restyleTypes.ts +8 -0
  40. package/src/core/restyle/useRestyleTheme.ts +10 -0
  41. package/src/hooks/animations/index.ts +3 -0
  42. package/src/hooks/animations/useAnimatedValue.ts +10 -0
  43. package/src/hooks/animations/useEntranceAnimation.ts +106 -0
  44. package/src/hooks/animations/usePulseAnimation.ts +63 -0
  45. package/src/hooks/index.ts +30 -0
  46. package/src/hooks/useReducedMotion.ts +60 -0
  47. package/src/i18n/index.ts +2 -0
  48. package/src/i18n/labels/en.ts +120 -0
  49. package/src/i18n/labels/es.ts +120 -0
  50. package/src/i18n/labels/index.ts +6 -0
  51. package/src/i18n/labels/types.ts +165 -0
  52. package/src/index.tsx +215 -0
  53. package/src/primitives/actions/Button/Button.helpers.ts +243 -0
  54. package/src/primitives/actions/Button/Button.tsx +198 -0
  55. package/src/primitives/actions/Button/Button.types.ts +207 -0
  56. package/src/primitives/actions/Button/index.ts +41 -0
  57. package/src/primitives/actions/Button/useButtonLogic.ts +160 -0
  58. package/src/primitives/actions/IconButton/IconButton.helpers.ts +235 -0
  59. package/src/primitives/actions/IconButton/IconButton.tsx +177 -0
  60. package/src/primitives/actions/IconButton/IconButton.types.ts +273 -0
  61. package/src/primitives/actions/IconButton/index.ts +30 -0
  62. package/src/primitives/actions/IconButton/useIconButtonLogic.ts +172 -0
  63. package/src/primitives/actions/index.ts +20 -0
  64. package/src/primitives/content/Avatar/Avatar.helpers.ts +177 -0
  65. package/src/primitives/content/Avatar/Avatar.tsx +199 -0
  66. package/src/primitives/content/Avatar/Avatar.types.ts +222 -0
  67. package/src/primitives/content/Avatar/index.ts +46 -0
  68. package/src/primitives/content/Avatar/useAvatarLogic.ts +149 -0
  69. package/src/primitives/content/Badge/Badge.helpers.ts +175 -0
  70. package/src/primitives/content/Badge/Badge.tsx +174 -0
  71. package/src/primitives/content/Badge/Badge.types.ts +223 -0
  72. package/src/primitives/content/Badge/index.ts +40 -0
  73. package/src/primitives/content/Badge/useBadgeLogic.ts +128 -0
  74. package/src/primitives/content/Card/Card.helpers.ts +27 -0
  75. package/src/primitives/content/Card/Card.tsx +123 -0
  76. package/src/primitives/content/Card/Card.types.ts +95 -0
  77. package/src/primitives/content/Card/index.ts +20 -0
  78. package/src/primitives/content/Card/useCardLogic.ts +48 -0
  79. package/src/primitives/content/Chip/Chip.helpers.ts +304 -0
  80. package/src/primitives/content/Chip/Chip.tsx +205 -0
  81. package/src/primitives/content/Chip/Chip.types.ts +234 -0
  82. package/src/primitives/content/Chip/index.ts +47 -0
  83. package/src/primitives/content/Chip/useChipLogic.ts +167 -0
  84. package/src/primitives/content/Icon/Icon.helpers.ts +54 -0
  85. package/src/primitives/content/Icon/Icon.tsx +110 -0
  86. package/src/primitives/content/Icon/Icon.types.ts +95 -0
  87. package/src/primitives/content/Icon/index.ts +20 -0
  88. package/src/primitives/content/Icon/useIconLogic.ts +73 -0
  89. package/src/primitives/content/index.ts +45 -0
  90. package/src/primitives/feedback/ProgressBar/ProgressBar.helpers.ts +122 -0
  91. package/src/primitives/feedback/ProgressBar/ProgressBar.tsx +154 -0
  92. package/src/primitives/feedback/ProgressBar/ProgressBar.types.ts +178 -0
  93. package/src/primitives/feedback/ProgressBar/index.ts +17 -0
  94. package/src/primitives/feedback/ProgressBar/useProgressBarLogic.ts +120 -0
  95. package/src/primitives/feedback/Skeleton/Skeleton.helpers.ts +145 -0
  96. package/src/primitives/feedback/Skeleton/Skeleton.tsx +155 -0
  97. package/src/primitives/feedback/Skeleton/Skeleton.types.ts +223 -0
  98. package/src/primitives/feedback/Skeleton/index.ts +44 -0
  99. package/src/primitives/feedback/Skeleton/useSkeletonLogic.ts +125 -0
  100. package/src/primitives/feedback/Spinner/Spinner.helpers.ts +40 -0
  101. package/src/primitives/feedback/Spinner/Spinner.tsx +105 -0
  102. package/src/primitives/feedback/Spinner/Spinner.types.ts +114 -0
  103. package/src/primitives/feedback/Spinner/index.ts +18 -0
  104. package/src/primitives/feedback/Spinner/useSpinnerLogic.ts +84 -0
  105. package/src/primitives/feedback/Toast/Toast.helpers.ts +163 -0
  106. package/src/primitives/feedback/Toast/Toast.tsx +190 -0
  107. package/src/primitives/feedback/Toast/Toast.types.ts +270 -0
  108. package/src/primitives/feedback/Toast/ToastContext.tsx +96 -0
  109. package/src/primitives/feedback/Toast/ToastProvider.tsx +241 -0
  110. package/src/primitives/feedback/Toast/index.ts +59 -0
  111. package/src/primitives/feedback/Toast/useToastLogic.ts +112 -0
  112. package/src/primitives/feedback/index.ts +45 -0
  113. package/src/primitives/index.ts +158 -0
  114. package/src/primitives/inputs/Checkbox/Checkbox.helpers.ts +132 -0
  115. package/src/primitives/inputs/Checkbox/Checkbox.tsx +150 -0
  116. package/src/primitives/inputs/Checkbox/Checkbox.types.ts +106 -0
  117. package/src/primitives/inputs/Checkbox/index.ts +30 -0
  118. package/src/primitives/inputs/Checkbox/useCheckboxLogic.ts +121 -0
  119. package/src/primitives/inputs/RadioButton/RadioButton.helpers.ts +123 -0
  120. package/src/primitives/inputs/RadioButton/RadioButton.tsx +159 -0
  121. package/src/primitives/inputs/RadioButton/RadioButton.types.ts +106 -0
  122. package/src/primitives/inputs/RadioButton/index.ts +25 -0
  123. package/src/primitives/inputs/RadioButton/useRadioButtonLogic.ts +117 -0
  124. package/src/primitives/inputs/SegmentedControl/SegmentedControl.helpers.ts +174 -0
  125. package/src/primitives/inputs/SegmentedControl/SegmentedControl.tsx +224 -0
  126. package/src/primitives/inputs/SegmentedControl/SegmentedControl.types.ts +187 -0
  127. package/src/primitives/inputs/SegmentedControl/index.ts +39 -0
  128. package/src/primitives/inputs/SegmentedControl/useSegmentedControlLogic.ts +151 -0
  129. package/src/primitives/inputs/SelectSheet/SelectSheet.helpers.ts +147 -0
  130. package/src/primitives/inputs/SelectSheet/SelectSheet.tsx +247 -0
  131. package/src/primitives/inputs/SelectSheet/SelectSheet.types.ts +196 -0
  132. package/src/primitives/inputs/SelectSheet/SelectSheetOption.tsx +177 -0
  133. package/src/primitives/inputs/SelectSheet/index.ts +48 -0
  134. package/src/primitives/inputs/SelectSheet/useSelectSheetLogic.ts +309 -0
  135. package/src/primitives/inputs/Switch/Switch.helpers.ts +109 -0
  136. package/src/primitives/inputs/Switch/Switch.tsx +191 -0
  137. package/src/primitives/inputs/Switch/Switch.types.ts +154 -0
  138. package/src/primitives/inputs/Switch/index.ts +40 -0
  139. package/src/primitives/inputs/Switch/useSwitchLogic.ts +192 -0
  140. package/src/primitives/inputs/TextInput/TextInput.helpers.ts +206 -0
  141. package/src/primitives/inputs/TextInput/TextInput.tsx +392 -0
  142. package/src/primitives/inputs/TextInput/TextInput.types.ts +216 -0
  143. package/src/primitives/inputs/TextInput/index.ts +37 -0
  144. package/src/primitives/inputs/TextInput/useTextInputLogic.ts +195 -0
  145. package/src/primitives/inputs/index.ts +52 -0
  146. package/src/primitives/layout/AnimatedBox.tsx +44 -0
  147. package/src/primitives/layout/Box.tsx +71 -0
  148. package/src/primitives/layout/Divider/Divider.helpers.ts +115 -0
  149. package/src/primitives/layout/Divider/Divider.tsx +139 -0
  150. package/src/primitives/layout/Divider/Divider.types.ts +178 -0
  151. package/src/primitives/layout/Divider/index.ts +24 -0
  152. package/src/primitives/layout/Divider/useDividerLogic.ts +109 -0
  153. package/src/primitives/layout/FlatList.tsx +66 -0
  154. package/src/primitives/layout/Pressable.tsx +74 -0
  155. package/src/primitives/layout/ScrollView.tsx +63 -0
  156. package/src/primitives/layout/Stack.tsx +69 -0
  157. package/src/primitives/layout/index.ts +40 -0
  158. package/src/primitives/navigation/index.ts +6 -0
  159. package/src/primitives/overlays/Modal/Modal.helpers.ts +31 -0
  160. package/src/primitives/overlays/Modal/Modal.tsx +264 -0
  161. package/src/primitives/overlays/Modal/Modal.types.ts +193 -0
  162. package/src/primitives/overlays/Modal/index.ts +43 -0
  163. package/src/primitives/overlays/Modal/useModalLogic.ts +103 -0
  164. package/src/primitives/overlays/index.ts +12 -0
  165. package/src/primitives/typography/Text.tsx +51 -0
  166. package/src/primitives/typography/index.ts +1 -0
  167. package/src/provider/DesignSystemContext.ts +22 -0
  168. package/src/provider/DesignSystemProvider.tsx +121 -0
  169. package/src/provider/index.ts +7 -0
  170. package/src/providers/ThemeProvider/createTheme.ts +304 -0
  171. package/src/providers/ThemeProvider/defaultTheme.ts +70 -0
  172. package/src/providers/ThemeProvider/index.ts +34 -0
  173. package/src/providers/ThemeProvider/types.ts +249 -0
  174. package/src/providers/index.ts +29 -0
  175. package/src/tokens/colors.ts +371 -0
  176. package/src/tokens/index.ts +145 -0
  177. package/src/tokens/motion.ts +176 -0
  178. package/src/tokens/radii.ts +82 -0
  179. package/src/tokens/scales.ts +588 -0
  180. package/src/tokens/shadows.ts +190 -0
  181. package/src/tokens/spacing.ts +140 -0
  182. package/src/tokens/tokens.json +207 -0
  183. package/src/tokens/typography.ts +251 -0
  184. package/src/types.ts +50 -0
  185. package/src/utils/accessibility.ts +169 -0
  186. package/src/utils/index.ts +25 -0
  187. package/src/utils/platform.ts +72 -0
@@ -0,0 +1,190 @@
1
+ /**
2
+ * Toast Component
3
+ *
4
+ * @description Toast notification for feedback messages - Atom
5
+ *
6
+ * Toast provides temporary, non-blocking notifications to users.
7
+ * It supports success, error, warning, and info variants with
8
+ * configurable duration, dismiss behavior, and optional actions.
9
+ *
10
+ * ## Variants
11
+ * | Variant | Use Case |
12
+ * |---------|----------|
13
+ * | success | Operation completed successfully |
14
+ * | error | Operation failed, requires attention |
15
+ * | warning | Caution, potential issue |
16
+ * | info | Informational message |
17
+ *
18
+ * ## Features
19
+ * - Four semantic variants (success, error, warning, info)
20
+ * - Auto-dismiss with configurable duration
21
+ * - Manual dismiss with close button
22
+ * - Optional action button
23
+ * - Smooth enter/exit animations
24
+ * - Full accessibility support (WCAG 4.1.3)
25
+ *
26
+ * @performance
27
+ * - Wrapped with React.memo() to prevent unnecessary re-renders
28
+ * - Uses useMemo() for color token resolution and icon determination
29
+ * - Animated.timing with native driver for smooth 60fps slide animations
30
+ * - Auto-dismiss timer cleared on unmount to prevent memory leaks
31
+ *
32
+ * @see Toast.types.ts - Type definitions
33
+ * @see Toast.helpers.ts - Pure calculation functions
34
+ * @see Toast.a11y.ts - Accessibility prop generation
35
+ * @see ToastProvider.tsx - Provider for toast context
36
+ *
37
+ * @example
38
+ * // Basic usage
39
+ * <Toast
40
+ * id="toast-1"
41
+ * message="Changes saved successfully"
42
+ * variant="success"
43
+ * onDismiss={() => removeToast("toast-1")}
44
+ * />
45
+ *
46
+ * @example
47
+ * // With action button
48
+ * <Toast
49
+ * id="toast-2"
50
+ * message="Item deleted"
51
+ * variant="info"
52
+ * action={{ label: "Undo", onPress: handleUndo }}
53
+ * onDismiss={() => removeToast("toast-2")}
54
+ * />
55
+ */
56
+
57
+ import {
58
+ border,
59
+ createRestyleComponent,
60
+ createVariant,
61
+ layout,
62
+ spacing,
63
+ spacingShorthand,
64
+ } from "@shopify/restyle";
65
+ import React, { memo, useCallback } from "react";
66
+ import { RestyleTheme } from "../../../core/restyle";
67
+ import { BaseThemeColor } from "../../../types";
68
+ import { useEntranceAnimation } from "../../../hooks/animations";
69
+ import { Button } from "../../actions/Button";
70
+ import { IconButton } from "../../actions/IconButton";
71
+ import { Icon } from "../../content/Icon";
72
+ import { AnimatedBox, Box } from "../../layout";
73
+ import { Text } from "../../typography";
74
+ import { BaseToastProps, ToastProps } from "./Toast.types";
75
+ import { useToastLogic } from "./useToastLogic";
76
+
77
+ /**
78
+ * Base container with Restyle variant support.
79
+ * @internal
80
+ */
81
+ const BaseToastContainer = createRestyleComponent<BaseToastProps, RestyleTheme>(
82
+ [
83
+ createVariant({ themeKey: "toastVariants" }),
84
+ border,
85
+ layout,
86
+ spacing,
87
+ spacingShorthand,
88
+ ],
89
+ Box,
90
+ );
91
+
92
+ function ToastComponent({
93
+ id,
94
+ message,
95
+ variant = "info",
96
+ onDismiss,
97
+ action,
98
+ dismissible = true,
99
+ iconName,
100
+ testID,
101
+ accessibilityLabel,
102
+ ...rest
103
+ }: ToastProps) {
104
+ const {
105
+ backgroundColorToken,
106
+ borderColorToken,
107
+ iconColorToken,
108
+ textColorToken,
109
+ resolvedIconName,
110
+ a11yProps,
111
+ } = useToastLogic({
112
+ variant,
113
+ iconName,
114
+ accessibilityLabel,
115
+ message,
116
+ });
117
+
118
+ const { animatedStyle, dismiss } = useEntranceAnimation({
119
+ spring: { tension: 50, friction: 8 },
120
+ });
121
+
122
+ const handleDismiss = useCallback(() => {
123
+ dismiss(onDismiss);
124
+ }, [dismiss, onDismiss]);
125
+
126
+ const handleActionPress = useCallback(() => {
127
+ action?.onPress();
128
+ }, [action]);
129
+
130
+ return (
131
+ <AnimatedBox style={animatedStyle}>
132
+ <BaseToastContainer
133
+ variant={variant}
134
+ backgroundColor={backgroundColorToken as BaseThemeColor}
135
+ borderColor={borderColorToken as BaseThemeColor}
136
+ borderWidth={1}
137
+ borderRadius="md"
138
+ padding="sm"
139
+ flexDirection="row"
140
+ alignItems="center"
141
+ gap="sm"
142
+ testID={testID}
143
+ {...a11yProps}
144
+ {...rest}
145
+ >
146
+ {/* Status icon */}
147
+ <Icon
148
+ name={resolvedIconName}
149
+ size="md"
150
+ color={iconColorToken}
151
+ accessibilityLabel={resolvedIconName}
152
+ />
153
+
154
+ {/* Message */}
155
+ <Box flex={1}>
156
+ <Text variant="bodySmall" color={textColorToken as BaseThemeColor} numberOfLines={2}>
157
+ {message}
158
+ </Text>
159
+ </Box>
160
+
161
+ {/* Action button */}
162
+ {action && (
163
+ <Button
164
+ title={action.label}
165
+ onPress={handleActionPress}
166
+ variant="ghost"
167
+ size="sm"
168
+ color={iconColorToken as BaseThemeColor}
169
+ accessibilityLabel={action.label}
170
+ />
171
+ )}
172
+
173
+ {/* Close button */}
174
+ {dismissible && (
175
+ <IconButton
176
+ iconName="close"
177
+ onPress={handleDismiss}
178
+ variant="ghost"
179
+ size="sm"
180
+ color={iconColorToken as BaseThemeColor}
181
+ accessibilityLabel="Dismiss notification"
182
+ />
183
+ )}
184
+ </BaseToastContainer>
185
+ </AnimatedBox>
186
+ );
187
+ }
188
+
189
+ export const Toast = memo(ToastComponent);
190
+ Toast.displayName = "Toast";
@@ -0,0 +1,270 @@
1
+ /**
2
+ * Toast Component Types
3
+ *
4
+ * Type definitions for the Toast component and its related hooks/helpers.
5
+ *
6
+ * @see Toast.tsx - Component implementation
7
+ */
8
+
9
+ import { BoxProps, ResponsiveValue, VariantProps } from "@shopify/restyle";
10
+ import { ViewProps } from "react-native";
11
+ import { RestyleTheme } from "../../../core/restyle";
12
+ import { RestyleColor, MaterialIconName } from "../../../types";
13
+
14
+ // =============================================================================
15
+ // VARIANT TYPES
16
+ // =============================================================================
17
+
18
+ /**
19
+ * Visual variants for the Toast indicating status/feedback type.
20
+ *
21
+ * - `success`: Positive feedback, operation completed
22
+ * - `error`: Error state, operation failed
23
+ * - `warning`: Caution, potential issue
24
+ * - `info`: Informational message
25
+ */
26
+ export type ToastVariant = Exclude<
27
+ keyof RestyleTheme["toastVariants"],
28
+ "defaults"
29
+ >;
30
+
31
+ /**
32
+ * Position of the toast on screen.
33
+ *
34
+ * - `top`: Display at top of screen
35
+ * - `bottom`: Display at bottom of screen
36
+ */
37
+ export type ToastPosition = "top" | "bottom";
38
+
39
+ // =============================================================================
40
+ // RESTYLE PROP TYPES
41
+ // =============================================================================
42
+
43
+ /** Restyle props for Toast variant */
44
+ type ToastVariantProps = VariantProps<RestyleTheme, "toastVariants">;
45
+
46
+ /** Combined restyle props for base toast */
47
+ export type BaseToastProps = ToastVariantProps &
48
+ BoxProps<RestyleTheme> &
49
+ ViewProps;
50
+
51
+ // =============================================================================
52
+ // TOAST DATA TYPES
53
+ // =============================================================================
54
+
55
+ /**
56
+ * Action button configuration for toast.
57
+ */
58
+ export interface ToastAction {
59
+ /** Label text for the action button */
60
+ label: string;
61
+ /** Callback when action is pressed */
62
+ onPress: () => void;
63
+ }
64
+
65
+ /**
66
+ * Configuration for a single toast notification.
67
+ */
68
+ export interface ToastConfig {
69
+ /** Unique identifier for the toast */
70
+ id: string;
71
+ /** Message to display */
72
+ message: string;
73
+ /** Visual variant indicating status */
74
+ variant: ToastVariant;
75
+ /** Duration in ms before auto-dismiss (0 = no auto-dismiss) */
76
+ duration?: number;
77
+ /** Optional action button */
78
+ action?: ToastAction;
79
+ /** Whether to show close button */
80
+ dismissible?: boolean;
81
+ /** Optional custom icon name (defaults based on variant) */
82
+ iconName?: MaterialIconName;
83
+ /** Accessibility label override */
84
+ accessibilityLabel?: string;
85
+ }
86
+
87
+ // =============================================================================
88
+ // COMPONENT PROPS
89
+ // =============================================================================
90
+
91
+ /**
92
+ * Props for the Toast component.
93
+ *
94
+ * @example
95
+ * <Toast
96
+ * message="Changes saved successfully"
97
+ * variant="success"
98
+ * onDismiss={() => removeToast(id)}
99
+ * />
100
+ */
101
+ export interface ToastProps extends Omit<BaseToastProps, "variant"> {
102
+ /** Unique identifier for the toast */
103
+ id: string;
104
+
105
+ /** Message to display */
106
+ message: string;
107
+
108
+ /**
109
+ * Visual variant indicating status (supports responsive values).
110
+ * @default "info"
111
+ */
112
+ variant?: ResponsiveValue<ToastVariant, RestyleTheme["breakpoints"]>;
113
+
114
+ /**
115
+ * Callback when toast is dismissed (close button or auto-dismiss).
116
+ */
117
+ onDismiss: () => void;
118
+
119
+ /** Optional action button */
120
+ action?: ToastAction;
121
+
122
+ /**
123
+ * Whether to show close button.
124
+ * @default true
125
+ */
126
+ dismissible?: boolean;
127
+
128
+ /** Optional custom icon name (defaults based on variant) */
129
+ iconName?: MaterialIconName;
130
+
131
+ /** Test ID for testing frameworks */
132
+ testID?: string;
133
+
134
+ /** Accessibility label override */
135
+ accessibilityLabel?: string;
136
+ }
137
+
138
+ /**
139
+ * Props for the ToastContainer component that manages toast positioning and queue.
140
+ */
141
+ export interface ToastContainerProps {
142
+ /**
143
+ * Position of toasts on screen.
144
+ * @default "bottom"
145
+ */
146
+ position?: ToastPosition;
147
+
148
+ /**
149
+ * Maximum number of visible toasts.
150
+ * @default 3
151
+ */
152
+ maxVisible?: number;
153
+
154
+ /** Test ID for testing frameworks */
155
+ testID?: string;
156
+ }
157
+
158
+ // =============================================================================
159
+ // HOOK TYPES
160
+ // =============================================================================
161
+
162
+ /**
163
+ * Parameters for useToastLogic hook.
164
+ */
165
+ export interface UseToastLogicParams {
166
+ variant: ResponsiveValue<ToastVariant, RestyleTheme["breakpoints"]>;
167
+ iconName?: MaterialIconName;
168
+ accessibilityLabel?: string;
169
+ message: string;
170
+ }
171
+
172
+ /**
173
+ * Return value from useToastLogic hook.
174
+ */
175
+ export interface UseToastLogicReturn {
176
+ /** Theme variant key for restyle */
177
+ themeVariantKey: ToastVariant;
178
+ /** Background color token */
179
+ backgroundColorToken: RestyleColor;
180
+ /** Border color token */
181
+ borderColorToken: RestyleColor;
182
+ /** Icon color token */
183
+ iconColorToken: RestyleColor;
184
+ /** Text color token */
185
+ textColorToken: RestyleColor;
186
+ /** Resolved icon name based on variant */
187
+ resolvedIconName: MaterialIconName;
188
+ /** Accessibility props */
189
+ a11yProps: ToastA11yProps;
190
+ }
191
+
192
+ // =============================================================================
193
+ // CONTEXT TYPES
194
+ // =============================================================================
195
+
196
+ /**
197
+ * Options for showing a toast via useToast hook.
198
+ */
199
+ export interface ShowToastOptions {
200
+ /** Message to display */
201
+ message: string;
202
+ /**
203
+ * Visual variant indicating status.
204
+ * @default "info"
205
+ */
206
+ variant?: ToastVariant;
207
+ /**
208
+ * Duration in ms before auto-dismiss.
209
+ * @default 3000
210
+ */
211
+ duration?: number;
212
+ /** Optional action button */
213
+ action?: ToastAction;
214
+ /**
215
+ * Whether to show close button.
216
+ * @default true
217
+ */
218
+ dismissible?: boolean;
219
+ /** Optional custom icon name */
220
+ iconName?: MaterialIconName;
221
+ /** Accessibility label override */
222
+ accessibilityLabel?: string;
223
+ }
224
+
225
+ /**
226
+ * Toast context value returned by useToast hook.
227
+ */
228
+ export interface ToastContextValue {
229
+ /** Show a toast notification */
230
+ show: (options: ShowToastOptions) => string;
231
+ /** Show a success toast */
232
+ success: (message: string, options?: Omit<ShowToastOptions, "message" | "variant">) => string;
233
+ /** Show an error toast */
234
+ error: (message: string, options?: Omit<ShowToastOptions, "message" | "variant">) => string;
235
+ /** Show a warning toast */
236
+ warning: (message: string, options?: Omit<ShowToastOptions, "message" | "variant">) => string;
237
+ /** Show an info toast */
238
+ info: (message: string, options?: Omit<ShowToastOptions, "message" | "variant">) => string;
239
+ /** Dismiss a specific toast by ID */
240
+ dismiss: (id: string) => void;
241
+ /** Dismiss all toasts */
242
+ dismissAll: () => void;
243
+ }
244
+
245
+ // =============================================================================
246
+ // ACCESSIBILITY TYPES
247
+ // =============================================================================
248
+
249
+ /**
250
+ * Parameters for generating toast accessibility props.
251
+ */
252
+ export interface ToastA11yParams {
253
+ /** Toast variant for role announcement */
254
+ variant: ToastVariant;
255
+ /** Custom accessibility label */
256
+ accessibilityLabel?: string;
257
+ /** Toast message */
258
+ message: string;
259
+ /** Translated prefix per variant */
260
+ variantPrefixes: Record<ToastVariant, string>;
261
+ }
262
+
263
+ /**
264
+ * Accessibility props returned by getToastA11y.
265
+ */
266
+ export interface ToastA11yProps {
267
+ accessibilityLabel: string;
268
+ accessibilityRole: "alert";
269
+ accessibilityLiveRegion: "polite" | "assertive";
270
+ }
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Toast Context
3
+ *
4
+ * Context for managing toast notifications across the app.
5
+ * Provides methods to show, dismiss, and manage toast queue.
6
+ *
7
+ * @see ToastProvider.tsx - Provider implementation
8
+ * @see Toast.tsx - Toast component
9
+ *
10
+ * @example
11
+ * // In a component
12
+ * const toast = useToast();
13
+ * toast.success("Changes saved!");
14
+ */
15
+
16
+ import { createContext, useContext } from "react";
17
+ import { ToastContextValue } from "./Toast.types";
18
+
19
+ /**
20
+ * Default context value that throws if used outside provider.
21
+ * @internal
22
+ */
23
+ const defaultContextValue: ToastContextValue = {
24
+ show: () => {
25
+ throw new Error("useToast must be used within a ToastProvider");
26
+ },
27
+ success: () => {
28
+ throw new Error("useToast must be used within a ToastProvider");
29
+ },
30
+ error: () => {
31
+ throw new Error("useToast must be used within a ToastProvider");
32
+ },
33
+ warning: () => {
34
+ throw new Error("useToast must be used within a ToastProvider");
35
+ },
36
+ info: () => {
37
+ throw new Error("useToast must be used within a ToastProvider");
38
+ },
39
+ dismiss: () => {
40
+ throw new Error("useToast must be used within a ToastProvider");
41
+ },
42
+ dismissAll: () => {
43
+ throw new Error("useToast must be used within a ToastProvider");
44
+ },
45
+ };
46
+
47
+ /**
48
+ * Toast context for managing toast notifications.
49
+ * @internal
50
+ */
51
+ export const ToastContext = createContext<ToastContextValue>(defaultContextValue);
52
+
53
+ /**
54
+ * Hook to access toast methods from anywhere in the app.
55
+ *
56
+ * Must be used within a ToastProvider.
57
+ *
58
+ * @returns Toast context with show/dismiss methods
59
+ * @throws Error if used outside ToastProvider
60
+ *
61
+ * @example
62
+ * // Show different toast types
63
+ * const toast = useToast();
64
+ *
65
+ * toast.success("Profile updated!");
66
+ * toast.error("Failed to save changes");
67
+ * toast.warning("Your session will expire soon");
68
+ * toast.info("New features available");
69
+ *
70
+ * @example
71
+ * // With options
72
+ * const toast = useToast();
73
+ *
74
+ * toast.show({
75
+ * message: "Item deleted",
76
+ * variant: "info",
77
+ * duration: 5000,
78
+ * action: {
79
+ * label: "Undo",
80
+ * onPress: () => undoDelete(),
81
+ * },
82
+ * });
83
+ *
84
+ * @example
85
+ * // Dismiss toasts
86
+ * const toast = useToast();
87
+ * const id = toast.success("Saved!");
88
+ *
89
+ * // Later...
90
+ * toast.dismiss(id); // Dismiss specific toast
91
+ * toast.dismissAll(); // Dismiss all toasts
92
+ */
93
+ export function useToast(): ToastContextValue {
94
+ const context = useContext(ToastContext);
95
+ return context;
96
+ }