@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,216 @@
1
+ import { BoxProps, ResponsiveValue } from "@shopify/restyle";
2
+ import { StyleProp, TextInput as RNTextInput, TextInputProps as RNTextInputProps, ViewProps, ViewStyle } from "react-native";
3
+ import { RestyleTheme } from "../../../core/restyle";
4
+ import { RestyleColor } from "../../../types";
5
+ import { IconName, IconSize } from "../../content/Icon";
6
+
7
+ /**
8
+ * Size variant for the TextInput component.
9
+ * Derived from the restyle theme's `textInputSizes` keys.
10
+ *
11
+ * - `sm`: 40px height - Compact forms, dense UIs
12
+ * - `md`: 48px height - Default mobile size
13
+ * - `lg`: 56px height - Tablets, emphasized inputs
14
+ */
15
+ export type TextInputSize = Exclude<keyof RestyleTheme["textInputSizes"], "defaults">;
16
+
17
+ /**
18
+ * Visual variant for the TextInput component.
19
+ * Derived from the restyle theme's `textInputVariants` keys.
20
+ *
21
+ * - `outlined`: Border with transparent background
22
+ * - `filled`: Filled background with subtle border
23
+ * - `textarea`: Multi-line text input with configurable height, cursor starts at top
24
+ */
25
+ export type TextInputVariant = Exclude<keyof RestyleTheme["textInputVariants"], "defaults">;
26
+
27
+ /**
28
+ * Text variant type for labels and helper text.
29
+ */
30
+ export type TextInputTextVariant = Exclude<keyof RestyleTheme["textVariants"], "defaults">;
31
+
32
+ /** Ref type for the TextInput component — the underlying React Native TextInput instance. */
33
+ export type TextInputRef = RNTextInput;
34
+
35
+
36
+ /**
37
+ * Props for the base TextInput container with Restyle support.
38
+ * @internal
39
+ */
40
+ export type BaseTextInputContainerProps = BoxProps<RestyleTheme> & ViewProps;
41
+
42
+ /**
43
+ * Base props for the TextInput container component.
44
+ */
45
+ export interface BaseTextInputProps
46
+ extends BoxProps<RestyleTheme>,
47
+ Omit<RNTextInputProps, "style"> {}
48
+
49
+ /**
50
+ * Props for the TextInput component.
51
+ *
52
+ * @example
53
+ * // Basic usage
54
+ * <TextInput label="Email" value={email} onChangeText={setEmail} />
55
+ *
56
+ * @example
57
+ * // With icons and validation
58
+ * <TextInput
59
+ * label="Email"
60
+ * value={email}
61
+ * onChangeText={setEmail}
62
+ * leftIconName="email"
63
+ * rightIconName={isValid ? "check-circle" : undefined}
64
+ * size={{ phone: "md", tablet: "lg" }}
65
+ * variant="outlined"
66
+ * error={emailError}
67
+ * helperText="Enter your email address"
68
+ * required
69
+ * showCharCount
70
+ * maxLength={100}
71
+ * accessibilityLabel="Email address"
72
+ * accessibilityHint="Enter a valid email address"
73
+ * />
74
+ */
75
+ export interface TextInputProps extends BaseTextInputProps {
76
+ /** Label text displayed above the input */
77
+ label?: string;
78
+ /** Helper text displayed below the input */
79
+ helperText?: string;
80
+ /** Error message (displays in red, replaces helperText) */
81
+ error?: string;
82
+ /** Size of the input (supports responsive values) */
83
+ size?: ResponsiveValue<TextInputSize, RestyleTheme["breakpoints"]>;
84
+ /** Visual variant of the input (supports responsive values) */
85
+ variant?: ResponsiveValue<TextInputVariant, RestyleTheme["breakpoints"]>;
86
+ /** Height for textarea variant (default: 120). */
87
+ textareaHeight?: number;
88
+ /** Icon name for left icon */
89
+ leftIconName?: IconName;
90
+ /** Icon name for right icon */
91
+ rightIconName?: IconName;
92
+ /** Whether the input is disabled */
93
+ disabled?: boolean;
94
+ /** Whether the input is required */
95
+ required?: boolean;
96
+ /** Whether to show character count */
97
+ showCharCount?: boolean;
98
+ /** Primary color for focus state */
99
+ color?: RestyleColor;
100
+ /** Container style overrides */
101
+ containerStyle?: StyleProp<ViewStyle>;
102
+ /** Input container style overrides */
103
+ inputContainerStyle?: StyleProp<ViewStyle>;
104
+ /** Test ID for testing */
105
+ testID?: string;
106
+ /** Accessibility label */
107
+ accessibilityLabel?: string;
108
+ /** Accessibility hint */
109
+ accessibilityHint?: string;
110
+ }
111
+
112
+ /**
113
+ * Parameters for the useTextInputLogic hook.
114
+ */
115
+ export interface UseTextInputLogicParams {
116
+ variant: ResponsiveValue<TextInputVariant, RestyleTheme["breakpoints"]>;
117
+ size: ResponsiveValue<TextInputSize, RestyleTheme["breakpoints"]>;
118
+ color: RestyleColor;
119
+ disabled: boolean;
120
+ error?: string;
121
+ isFocused: boolean;
122
+ leftIconName?: IconName;
123
+ rightIconName?: IconName;
124
+ label?: string;
125
+ accessibilityLabel?: string;
126
+ accessibilityHint?: string;
127
+ required?: boolean;
128
+ }
129
+
130
+ /**
131
+ * Return value from the useTextInputLogic hook.
132
+ */
133
+ export interface UseTextInputLogicReturn {
134
+ /** Whether the input is disabled */
135
+ isDisabled: boolean;
136
+ /** Whether the input has an error */
137
+ hasError: boolean;
138
+ /** Container opacity */
139
+ opacity: number;
140
+ /** Background color key */
141
+ finalBackgroundColor: RestyleColor | "transparent";
142
+ /** Border color key */
143
+ finalBorderColor: RestyleColor;
144
+ /** Text color key */
145
+ finalTextColor: RestyleColor;
146
+ /** Placeholder color key */
147
+ finalPlaceholderColor: RestyleColor;
148
+ /** Label color key */
149
+ finalLabelColor: RestyleColor;
150
+ /** Border width */
151
+ borderWidth: number;
152
+ /** Left icon size */
153
+ leftIconSize: IconSize | undefined;
154
+ /** Right icon size */
155
+ rightIconSize: IconSize | undefined;
156
+ /** Icon color key */
157
+ iconColor: RestyleColor;
158
+ /** Accessibility props */
159
+ a11yProps: TextInputA11yProps;
160
+ }
161
+
162
+ /**
163
+ * Parameters for the getTextInputA11y function.
164
+ */
165
+ export interface TextInputA11yParams {
166
+ label?: string;
167
+ accessibilityLabel?: string;
168
+ accessibilityHint?: string;
169
+ disabled: boolean;
170
+ error?: string;
171
+ required?: boolean;
172
+ fallbackLabel: string;
173
+ requiredLabel: string;
174
+ errorPrefixLabel: string;
175
+ }
176
+
177
+ /**
178
+ * Accessibility props returned by getTextInputA11y.
179
+ */
180
+ export interface TextInputA11yProps {
181
+ accessibilityLabel: string;
182
+ accessibilityHint?: string;
183
+ accessibilityState: { disabled: boolean };
184
+ }
185
+
186
+ /**
187
+ * Parameters for resolveTextInputStyle function.
188
+ */
189
+ export interface ResolveTextInputStyleParams {
190
+ variant: TextInputVariant;
191
+ disabled: boolean;
192
+ error?: string;
193
+ isFocused: boolean;
194
+ color: RestyleColor;
195
+ theme: RestyleTheme;
196
+ }
197
+
198
+ /**
199
+ * Result from resolveTextInputStyle function.
200
+ */
201
+ export interface TextInputStyleResult {
202
+ backgroundColor: string;
203
+ borderColor: string;
204
+ borderWidth: number;
205
+ opacity: number;
206
+ }
207
+
208
+ /**
209
+ * Size configuration for TextInput.
210
+ */
211
+ export interface TextInputSizeConfig {
212
+ height: number;
213
+ paddingHorizontal: number;
214
+ fontSize: number;
215
+ iconSize: number;
216
+ }
@@ -0,0 +1,37 @@
1
+ /**
2
+ * TextInput Module
3
+ *
4
+ * Molecule component for text entry with labels, icons, and validation.
5
+ *
6
+ * Combines Icon, Text, and Box atoms into a complete form field.
7
+ *
8
+ * ## Variants
9
+ * - `outlined`: Border with transparent background (default)
10
+ * - `filled`: Filled background with subtle border
11
+ * - `textarea`: Multi-line with configurable height
12
+ *
13
+ * @example
14
+ * import { TextInput } from "@/design-system/primitives/inputs/TextInput";
15
+ *
16
+ * <TextInput
17
+ * label="Email"
18
+ * value={email}
19
+ * onChangeText={setEmail}
20
+ * leftIconName="email"
21
+ * error={emailError}
22
+ * required
23
+ * />
24
+ */
25
+
26
+ export { TextInput } from "./TextInput";
27
+
28
+ export type {
29
+ TextInputProps,
30
+ TextInputRef,
31
+ TextInputSize,
32
+ TextInputVariant,
33
+ TextInputA11yParams,
34
+ TextInputA11yProps,
35
+ } from "./TextInput.types";
36
+
37
+ export { getTextInputA11y } from "./TextInput.a11y";
@@ -0,0 +1,195 @@
1
+ import { useDesignSystem } from "../../../provider";
2
+ import { useResponsiveProp } from "@shopify/restyle";
3
+ import { useMemo } from "react";
4
+ import { RestyleColor } from "../../../types";
5
+ import { getTextInputA11y } from "./TextInput.a11y";
6
+ import {
7
+ getTextInputIconColor,
8
+ getTextInputIconSize,
9
+ } from "./TextInput.helpers";
10
+ import {
11
+ TextInputSize,
12
+ TextInputVariant,
13
+ UseTextInputLogicParams,
14
+ UseTextInputLogicReturn,
15
+ } from "./TextInput.types";
16
+
17
+ /**
18
+ * Orchestrates TextInput rendering logic and state management.
19
+ *
20
+ * Handles:
21
+ * - Responsive size and variant resolution
22
+ * - State-based color calculations (error, focus, disabled)
23
+ * - Background and border color computation
24
+ * - Icon sizing and color coordination
25
+ * - Label variant selection
26
+ * - Border width adjustment on focus (1px → 2px)
27
+ * - Accessibility props generation
28
+ *
29
+ * @param params - Configuration object for text input behavior
30
+ * @param params.variant - Visual variant ('outlined' | 'filled' | 'textarea')
31
+ * @param params.size - Size variant ('sm' | 'md' | 'lg')
32
+ * @param params.color - Theme color token for focus state
33
+ * @param params.disabled - Whether input is disabled
34
+ * @param params.error - Error message (presence triggers error state)
35
+ * @param params.isFocused - Whether input has focus
36
+ * @param params.leftIconName - Optional left icon
37
+ * @param params.rightIconName - Optional right icon
38
+ * @param params.label - Input label text
39
+ * @param params.accessibilityLabel - Custom a11y label
40
+ * @param params.accessibilityHint - Describes expected input
41
+ * @param params.required - Whether field is required
42
+ *
43
+ * @returns Computed values for rendering TextInput
44
+ * @returns {boolean} isDisabled - Disabled state flag
45
+ * @returns {boolean} hasError - Error state flag
46
+ * @returns {number} opacity - Container opacity (0.5 when disabled)
47
+ * @returns {string} finalBackgroundColor - Background color token
48
+ * @returns {string} finalBorderColor - Border color token
49
+ * @returns {string} finalTextColor - Text color token
50
+ * @returns {string} finalPlaceholderColor - Placeholder color token
51
+ * @returns {string} finalLabelColor - Label color token
52
+ * @returns {number} borderWidth - Border width (1 or 2)
53
+ * @returns {number} leftIconSize - Left icon size in pixels
54
+ * @returns {number} rightIconSize - Right icon size in pixels
55
+ * @returns {string} iconColor - Icon color token
56
+ * @returns {object} a11yProps - Accessibility props
57
+ *
58
+ * @performance This hook uses useMemo() for expensive calculations
59
+ *
60
+ * @example
61
+ * const {
62
+ * finalBackgroundColor,
63
+ * finalBorderColor,
64
+ * borderWidth,
65
+ * leftIconSize,
66
+ * a11yProps
67
+ * } = useTextInputLogic({
68
+ * variant: "outlined",
69
+ * size: "md",
70
+ * color: "accentPrimary",
71
+ * isFocused: true,
72
+ * leftIconName: "search",
73
+ * label: "Search products",
74
+ * });
75
+ */
76
+ export function useTextInputLogic(
77
+ params: UseTextInputLogicParams
78
+ ): UseTextInputLogicReturn {
79
+ const {
80
+ variant,
81
+ size,
82
+ color,
83
+ disabled,
84
+ error,
85
+ isFocused,
86
+ leftIconName,
87
+ rightIconName,
88
+ label,
89
+ accessibilityLabel,
90
+ accessibilityHint,
91
+ required,
92
+ } = params;
93
+
94
+ const { labels: t } = useDesignSystem();
95
+ const resolvedSize = (useResponsiveProp(size) ?? "md") as TextInputSize;
96
+ const resolvedVariant = (useResponsiveProp(variant) ?? "outlined") as TextInputVariant;
97
+
98
+ const isDisabled = disabled;
99
+ const hasError = !!error;
100
+ const opacity = isDisabled ? 0.5 : 1;
101
+
102
+ // Icon sizes (only if icons provided)
103
+ const leftIconSize = leftIconName
104
+ ? getTextInputIconSize(resolvedSize)
105
+ : undefined;
106
+ const rightIconSize = rightIconName
107
+ ? getTextInputIconSize(resolvedSize)
108
+ : undefined;
109
+
110
+ // Icon color
111
+ const iconColor = getTextInputIconColor(hasError, isFocused, color);
112
+
113
+ // Background color
114
+ // Use backgroundTertiary for filled variant to ensure distinction in dark mode
115
+ // Textarea uses same background as outlined
116
+ const finalBackgroundColor = useMemo(():
117
+ | RestyleColor
118
+ | "transparent" => {
119
+ if (isDisabled) {
120
+ return "interactiveDisabled";
121
+ }
122
+ if (resolvedVariant === "filled") {
123
+ return "backgroundTertiary";
124
+ }
125
+ // Both outlined and textarea use surfacePrimary
126
+ return "surfacePrimary";
127
+ }, [resolvedVariant, isDisabled]);
128
+
129
+ // Border color
130
+ const finalBorderColor = useMemo((): RestyleColor => {
131
+ if (isDisabled) {
132
+ return "borderSubtle";
133
+ }
134
+ if (hasError) {
135
+ return "feedbackError";
136
+ }
137
+ if (isFocused) {
138
+ return color;
139
+ }
140
+ return "borderDefault";
141
+ }, [isDisabled, hasError, isFocused, color]);
142
+
143
+ // Text color
144
+ const finalTextColor: RestyleColor = isDisabled ? "textDisabled" : "textPrimary";
145
+
146
+ // Placeholder color
147
+ const finalPlaceholderColor: RestyleColor = "textTertiary";
148
+
149
+ // Label color
150
+ const finalLabelColor = useMemo((): RestyleColor => {
151
+ if (hasError) {
152
+ return "feedbackError";
153
+ }
154
+ if (isFocused) {
155
+ return color;
156
+ }
157
+ return "textPrimary";
158
+ }, [hasError, isFocused, color]);
159
+
160
+ // Border width
161
+ const borderWidth = isFocused ? 2 : 1;
162
+
163
+ // Accessibility props
164
+ const a11yProps = useMemo(
165
+ () =>
166
+ getTextInputA11y({
167
+ label,
168
+ accessibilityLabel,
169
+ accessibilityHint,
170
+ disabled: isDisabled,
171
+ error,
172
+ required,
173
+ fallbackLabel: t.designSystem.textInput.fallbackLabel,
174
+ requiredLabel: t.designSystem.textInput.required,
175
+ errorPrefixLabel: t.designSystem.textInput.errorPrefix,
176
+ }),
177
+ [label, accessibilityLabel, accessibilityHint, isDisabled, error, required, t]
178
+ );
179
+
180
+ return {
181
+ isDisabled,
182
+ hasError,
183
+ opacity,
184
+ finalBackgroundColor,
185
+ finalBorderColor,
186
+ finalTextColor,
187
+ finalPlaceholderColor,
188
+ finalLabelColor,
189
+ borderWidth,
190
+ leftIconSize,
191
+ rightIconSize,
192
+ iconColor,
193
+ a11yProps,
194
+ };
195
+ }
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Inputs Components Module
3
+ *
4
+ * Components that capture user data and selections.
5
+ */
6
+
7
+ export {
8
+ TextInput,
9
+ type TextInputProps,
10
+ type TextInputRef,
11
+ type TextInputSize,
12
+ type TextInputVariant,
13
+
14
+ } from "./TextInput";
15
+
16
+ export {
17
+ Checkbox,
18
+ type CheckboxProps,
19
+ type CheckboxRef,
20
+ type CheckboxSize,
21
+ } from "./Checkbox";
22
+
23
+ export {
24
+ RadioButton,
25
+ type RadioButtonProps,
26
+ type RadioButtonRef,
27
+ type RadioButtonSize,
28
+ } from "./RadioButton";
29
+
30
+ export {
31
+ Switch,
32
+ type SwitchProps,
33
+ type SwitchRef,
34
+ type SwitchSize,
35
+ } from "./Switch";
36
+
37
+ export {
38
+ SegmentedControl,
39
+ type SegmentedControlProps,
40
+ type SegmentedControlSize,
41
+ type SegmentedControlVariant,
42
+ type SegmentOption,
43
+ } from "./SegmentedControl";
44
+
45
+ export {
46
+ SelectSheet,
47
+ type SelectSheetProps,
48
+ type SelectSheetOption,
49
+ type SelectSheetMode,
50
+ type SelectSheetPosition,
51
+ type SelectSheetIndicatorPosition,
52
+ } from "./SelectSheet";
@@ -0,0 +1,44 @@
1
+ /**
2
+ * AnimatedBox Component
3
+ *
4
+ * @description Animated version of Box for Animated API integration - Atom
5
+ *
6
+ * AnimatedBox wraps Box with React Native's Animated API, enabling
7
+ * smooth transitions and animations while maintaining Restyle props.
8
+ *
9
+ * ## Usage
10
+ * Use AnimatedBox when you need to animate layout properties using
11
+ * React Native's Animated API (Animated.Value, Animated.timing, etc.).
12
+ *
13
+ * ## Features
14
+ * - All Box/Restyle props available
15
+ * - Compatible with Animated.Value for transforms, opacity, etc.
16
+ * - Use with interpolate() for complex animations
17
+ *
18
+ * @see Box.tsx - Base component without animation
19
+ * @see https://reactnative.dev/docs/animated - Animated API docs
20
+ *
21
+ * @example
22
+ * // Fade animation
23
+ * const opacity = useRef(new Animated.Value(0)).current;
24
+ *
25
+ * <AnimatedBox style={{ opacity }} padding="lg">
26
+ * <Text>Fading content</Text>
27
+ * </AnimatedBox>
28
+ *
29
+ * @example
30
+ * // Transform animation
31
+ * const translateX = useRef(new Animated.Value(-100)).current;
32
+ *
33
+ * <AnimatedBox
34
+ * style={{ transform: [{ translateX }] }}
35
+ * backgroundColor="surfacePrimary"
36
+ * >
37
+ * <Text>Sliding content</Text>
38
+ * </AnimatedBox>
39
+ */
40
+
41
+ import { Animated } from "react-native";
42
+ import { Box } from "./Box";
43
+
44
+ export const AnimatedBox = Animated.createAnimatedComponent(Box);
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Box Component
3
+ *
4
+ * @description Fundamental layout primitive with Restyle integration - Atom
5
+ *
6
+ * Box is the most basic building block of the design system.
7
+ * It's a View with all Restyle layout, spacing, and color props.
8
+ *
9
+ * ## Usage
10
+ * Use Box for any layout needs: containers, wrappers, spacers, etc.
11
+ * It provides type-safe access to all theme tokens.
12
+ *
13
+ * ## Available Props (from Restyle)
14
+ * - **Layout**: width, height, flex, flexDirection, alignItems, justifyContent, etc.
15
+ * - **Spacing**: margin, padding, gap (with theme tokens: xs, sm, md, lg, xl, etc.)
16
+ * - **Colors**: backgroundColor, borderColor (with theme color tokens)
17
+ * - **Borders**: borderWidth, borderRadius (with theme radii tokens)
18
+ *
19
+ * @see https://github.com/Shopify/restyle - Restyle documentation
20
+ *
21
+ * @example
22
+ * // Basic container
23
+ * <Box padding="lg" backgroundColor="surfacePrimary">
24
+ * <Text>Content</Text>
25
+ * </Box>
26
+ *
27
+ * @example
28
+ * // Flex layout
29
+ * <Box flexDirection="row" alignItems="center" gap="sm">
30
+ * <Icon name="check" />
31
+ * <Text>Label</Text>
32
+ * </Box>
33
+ *
34
+ * @example
35
+ * // Responsive padding
36
+ * <Box padding={{ phone: "md", tablet: "xl" }}>
37
+ * <Text>Responsive content</Text>
38
+ * </Box>
39
+ */
40
+
41
+ import { createBox } from "@shopify/restyle";
42
+ import { ComponentProps } from "react";
43
+ import { RestyleTheme } from "../../core";
44
+
45
+ export const Box = createBox<RestyleTheme>();
46
+
47
+ /**
48
+ * BoxRestyleProps — Reusable type for Box Restyle props.
49
+ *
50
+ * Use this type when creating components with a root Box
51
+ * to allow consumers to pass layout/styling props.
52
+ *
53
+ * @example
54
+ * ```tsx
55
+ * interface MyCardProps extends BoxRestyleProps {
56
+ * title: string;
57
+ * }
58
+ *
59
+ * function MyCard({ title, ...boxProps }: MyCardProps) {
60
+ * return (
61
+ * <Box padding="lg" {...boxProps}>
62
+ * <Text>{title}</Text>
63
+ * </Box>
64
+ * );
65
+ * }
66
+ *
67
+ * // Usage
68
+ * <MyCard title="Hello" marginTop="md" backgroundColor="surfacePrimary" />
69
+ * ```
70
+ */
71
+ export type BoxRestyleProps = ComponentProps<typeof Box>;