@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,1352 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* El Sendero Design System - Restyle Theme Configuration
|
|
3
|
+
*
|
|
4
|
+
* Maps all design system tokens to Restyle theme format.
|
|
5
|
+
* Restyle enables type-safe, prop-based styling for React Native components.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { createTheme } from "@shopify/restyle";
|
|
9
|
+
import {
|
|
10
|
+
baseColors,
|
|
11
|
+
darkSemanticColors,
|
|
12
|
+
fontFamily,
|
|
13
|
+
lightSemanticColors,
|
|
14
|
+
radii,
|
|
15
|
+
spacing,
|
|
16
|
+
typographyPresets,
|
|
17
|
+
zIndex,
|
|
18
|
+
} from "../../tokens";
|
|
19
|
+
|
|
20
|
+
// =============================================================================
|
|
21
|
+
// PRESET RESTYLE THEME BUILDER
|
|
22
|
+
// =============================================================================
|
|
23
|
+
|
|
24
|
+
import type { ThemeColors, DeepPartial } from "../../providers/ThemeProvider/types";
|
|
25
|
+
|
|
26
|
+
export type SemanticColorsInput = {
|
|
27
|
+
[K in keyof typeof lightSemanticColors]: {
|
|
28
|
+
[P in keyof (typeof lightSemanticColors)[K]]: string;
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export const flattenColors = (semanticColors: SemanticColorsInput) =>
|
|
33
|
+
({
|
|
34
|
+
// Backgrounds
|
|
35
|
+
backgroundPrimary: semanticColors.background.primary,
|
|
36
|
+
backgroundSecondary: semanticColors.background.secondary,
|
|
37
|
+
backgroundTertiary: semanticColors.background.tertiary,
|
|
38
|
+
backgroundInverse: semanticColors.background.inverse,
|
|
39
|
+
|
|
40
|
+
// Surfaces
|
|
41
|
+
surfacePrimary: semanticColors.surface.primary,
|
|
42
|
+
surfaceSecondary: semanticColors.surface.secondary,
|
|
43
|
+
surfaceElevated: semanticColors.surface.elevated,
|
|
44
|
+
surfaceOverlay: semanticColors.surface.overlay,
|
|
45
|
+
|
|
46
|
+
// Text
|
|
47
|
+
textPrimary: semanticColors.text.primary,
|
|
48
|
+
textSecondary: semanticColors.text.secondary,
|
|
49
|
+
textTertiary: semanticColors.text.tertiary,
|
|
50
|
+
textDisabled: semanticColors.text.disabled,
|
|
51
|
+
textInverse: semanticColors.text.inverse,
|
|
52
|
+
textLink: semanticColors.text.link,
|
|
53
|
+
|
|
54
|
+
// Borders
|
|
55
|
+
borderDefault: semanticColors.border.default,
|
|
56
|
+
borderSubtle: semanticColors.border.subtle,
|
|
57
|
+
borderStrong: semanticColors.border.strong,
|
|
58
|
+
borderFocus: semanticColors.border.focus,
|
|
59
|
+
|
|
60
|
+
// Accents
|
|
61
|
+
accentPrimary: semanticColors.accent.primary,
|
|
62
|
+
accentPrimaryHover: semanticColors.accent.primaryHover,
|
|
63
|
+
accentPrimaryPressed: semanticColors.accent.primaryPressed,
|
|
64
|
+
accentSecondary: semanticColors.accent.secondary,
|
|
65
|
+
accentSecondaryHover: semanticColors.accent.secondaryHover,
|
|
66
|
+
accentSecondaryPressed: semanticColors.accent.secondaryPressed,
|
|
67
|
+
|
|
68
|
+
// Interactive
|
|
69
|
+
interactiveDefault: semanticColors.interactive.default,
|
|
70
|
+
interactiveHover: semanticColors.interactive.hover,
|
|
71
|
+
interactivePressed: semanticColors.interactive.pressed,
|
|
72
|
+
interactiveDisabled: semanticColors.interactive.disabled,
|
|
73
|
+
|
|
74
|
+
// Feedback
|
|
75
|
+
feedbackSuccess: semanticColors.feedback.success,
|
|
76
|
+
feedbackSuccessLight: semanticColors.feedback.successLight,
|
|
77
|
+
feedbackSuccessDark: semanticColors.feedback.successDark,
|
|
78
|
+
feedbackWarning: semanticColors.feedback.warning,
|
|
79
|
+
feedbackWarningLight: semanticColors.feedback.warningLight,
|
|
80
|
+
feedbackWarningDark: semanticColors.feedback.warningDark,
|
|
81
|
+
feedbackError: semanticColors.feedback.error,
|
|
82
|
+
feedbackErrorLight: semanticColors.feedback.errorLight,
|
|
83
|
+
feedbackErrorDark: semanticColors.feedback.errorDark,
|
|
84
|
+
feedbackInfo: semanticColors.feedback.info,
|
|
85
|
+
feedbackInfoLight: semanticColors.feedback.infoLight,
|
|
86
|
+
feedbackInfoDark: semanticColors.feedback.infoDark,
|
|
87
|
+
|
|
88
|
+
// Danger (for buttons)
|
|
89
|
+
dangerPrimary: semanticColors.feedback.error,
|
|
90
|
+
dangerPrimaryHover: semanticColors.feedback.errorDark,
|
|
91
|
+
dangerPrimaryPressed: semanticColors.feedback.errorDark,
|
|
92
|
+
|
|
93
|
+
// Special
|
|
94
|
+
specialSkeleton: semanticColors.special.skeleton,
|
|
95
|
+
specialDivider: semanticColors.special.divider,
|
|
96
|
+
specialScrim: semanticColors.special.scrim,
|
|
97
|
+
|
|
98
|
+
// Emotion colors
|
|
99
|
+
emotionHappy: semanticColors.emotion.happy,
|
|
100
|
+
emotionCalm: semanticColors.emotion.calm,
|
|
101
|
+
emotionNeutral: semanticColors.emotion.neutral,
|
|
102
|
+
emotionSad: semanticColors.emotion.sad,
|
|
103
|
+
emotionAnxious: semanticColors.emotion.anxious,
|
|
104
|
+
emotionAngry: semanticColors.emotion.angry,
|
|
105
|
+
emotionOverwhelmed: semanticColors.emotion.overwhelmed,
|
|
106
|
+
|
|
107
|
+
// Transparent
|
|
108
|
+
transparent: "transparent",
|
|
109
|
+
|
|
110
|
+
// Base Colors - Blue (Primary)
|
|
111
|
+
blue50: baseColors.blue[50],
|
|
112
|
+
blue100: baseColors.blue[100],
|
|
113
|
+
blue200: baseColors.blue[200],
|
|
114
|
+
blue300: baseColors.blue[300],
|
|
115
|
+
blue400: baseColors.blue[400],
|
|
116
|
+
blue500: baseColors.blue[500],
|
|
117
|
+
blue600: baseColors.blue[600],
|
|
118
|
+
blue700: baseColors.blue[700],
|
|
119
|
+
blue800: baseColors.blue[800],
|
|
120
|
+
blue900: baseColors.blue[900],
|
|
121
|
+
|
|
122
|
+
// Base Colors - Pink (Accent)
|
|
123
|
+
pink50: baseColors.pink[50],
|
|
124
|
+
pink100: baseColors.pink[100],
|
|
125
|
+
pink200: baseColors.pink[200],
|
|
126
|
+
pink300: baseColors.pink[300],
|
|
127
|
+
pink400: baseColors.pink[400],
|
|
128
|
+
pink500: baseColors.pink[500],
|
|
129
|
+
pink600: baseColors.pink[600],
|
|
130
|
+
pink700: baseColors.pink[700],
|
|
131
|
+
pink800: baseColors.pink[800],
|
|
132
|
+
pink900: baseColors.pink[900],
|
|
133
|
+
|
|
134
|
+
// Base Colors - Yellow (Warning/Accent)
|
|
135
|
+
yellow50: baseColors.yellow[50],
|
|
136
|
+
yellow100: baseColors.yellow[100],
|
|
137
|
+
yellow200: baseColors.yellow[200],
|
|
138
|
+
yellow300: baseColors.yellow[300],
|
|
139
|
+
yellow400: baseColors.yellow[400],
|
|
140
|
+
yellow500: baseColors.yellow[500],
|
|
141
|
+
yellow600: baseColors.yellow[600],
|
|
142
|
+
yellow700: baseColors.yellow[700],
|
|
143
|
+
yellow800: baseColors.yellow[800],
|
|
144
|
+
yellow900: baseColors.yellow[900],
|
|
145
|
+
|
|
146
|
+
// Base Colors - Green (Success)
|
|
147
|
+
green50: baseColors.green[50],
|
|
148
|
+
green100: baseColors.green[100],
|
|
149
|
+
green200: baseColors.green[200],
|
|
150
|
+
green300: baseColors.green[300],
|
|
151
|
+
green400: baseColors.green[400],
|
|
152
|
+
green500: baseColors.green[500],
|
|
153
|
+
green600: baseColors.green[600],
|
|
154
|
+
green700: baseColors.green[700],
|
|
155
|
+
green800: baseColors.green[800],
|
|
156
|
+
green900: baseColors.green[900],
|
|
157
|
+
|
|
158
|
+
// Base Colors - Orange (Secondary accent)
|
|
159
|
+
orange50: baseColors.orange[50],
|
|
160
|
+
orange100: baseColors.orange[100],
|
|
161
|
+
orange200: baseColors.orange[200],
|
|
162
|
+
orange300: baseColors.orange[300],
|
|
163
|
+
orange400: baseColors.orange[400],
|
|
164
|
+
orange500: baseColors.orange[500],
|
|
165
|
+
orange600: baseColors.orange[600],
|
|
166
|
+
orange700: baseColors.orange[700],
|
|
167
|
+
orange800: baseColors.orange[800],
|
|
168
|
+
orange900: baseColors.orange[900],
|
|
169
|
+
|
|
170
|
+
// Base Colors - Amber (Alternative warning)
|
|
171
|
+
amber50: baseColors.amber[50],
|
|
172
|
+
amber100: baseColors.amber[100],
|
|
173
|
+
amber200: baseColors.amber[200],
|
|
174
|
+
amber300: baseColors.amber[300],
|
|
175
|
+
amber400: baseColors.amber[400],
|
|
176
|
+
amber500: baseColors.amber[500],
|
|
177
|
+
amber600: baseColors.amber[600],
|
|
178
|
+
amber700: baseColors.amber[700],
|
|
179
|
+
amber800: baseColors.amber[800],
|
|
180
|
+
amber900: baseColors.amber[900],
|
|
181
|
+
|
|
182
|
+
// Base Colors - Red (Error)
|
|
183
|
+
red50: baseColors.red[50],
|
|
184
|
+
red100: baseColors.red[100],
|
|
185
|
+
red200: baseColors.red[200],
|
|
186
|
+
red300: baseColors.red[300],
|
|
187
|
+
red400: baseColors.red[400],
|
|
188
|
+
red500: baseColors.red[500],
|
|
189
|
+
red600: baseColors.red[600],
|
|
190
|
+
red700: baseColors.red[700],
|
|
191
|
+
red800: baseColors.red[800],
|
|
192
|
+
red900: baseColors.red[900],
|
|
193
|
+
|
|
194
|
+
// Base Colors - Purple (Decorative)
|
|
195
|
+
purple50: baseColors.purple[50],
|
|
196
|
+
purple100: baseColors.purple[100],
|
|
197
|
+
purple200: baseColors.purple[200],
|
|
198
|
+
purple300: baseColors.purple[300],
|
|
199
|
+
purple400: baseColors.purple[400],
|
|
200
|
+
purple500: baseColors.purple[500],
|
|
201
|
+
purple600: baseColors.purple[600],
|
|
202
|
+
purple700: baseColors.purple[700],
|
|
203
|
+
purple800: baseColors.purple[800],
|
|
204
|
+
purple900: baseColors.purple[900],
|
|
205
|
+
|
|
206
|
+
// Base Colors - Cyan (Info/Accent)
|
|
207
|
+
cyan50: baseColors.cyan[50],
|
|
208
|
+
cyan100: baseColors.cyan[100],
|
|
209
|
+
cyan200: baseColors.cyan[200],
|
|
210
|
+
cyan300: baseColors.cyan[300],
|
|
211
|
+
cyan400: baseColors.cyan[400],
|
|
212
|
+
cyan500: baseColors.cyan[500],
|
|
213
|
+
cyan600: baseColors.cyan[600],
|
|
214
|
+
cyan700: baseColors.cyan[700],
|
|
215
|
+
cyan800: baseColors.cyan[800],
|
|
216
|
+
cyan900: baseColors.cyan[900],
|
|
217
|
+
|
|
218
|
+
// Base Colors - Deep Purple (Special)
|
|
219
|
+
deepPurple50: baseColors.deepPurple[50],
|
|
220
|
+
deepPurple100: baseColors.deepPurple[100],
|
|
221
|
+
deepPurple200: baseColors.deepPurple[200],
|
|
222
|
+
deepPurple300: baseColors.deepPurple[300],
|
|
223
|
+
deepPurple400: baseColors.deepPurple[400],
|
|
224
|
+
deepPurple500: baseColors.deepPurple[500],
|
|
225
|
+
deepPurple600: baseColors.deepPurple[600],
|
|
226
|
+
deepPurple700: baseColors.deepPurple[700],
|
|
227
|
+
deepPurple800: baseColors.deepPurple[800],
|
|
228
|
+
deepPurple900: baseColors.deepPurple[900],
|
|
229
|
+
|
|
230
|
+
// Base Colors - Gray
|
|
231
|
+
gray50: baseColors.gray[50],
|
|
232
|
+
gray100: baseColors.gray[100],
|
|
233
|
+
gray200: baseColors.gray[200],
|
|
234
|
+
gray300: baseColors.gray[300],
|
|
235
|
+
gray400: baseColors.gray[400],
|
|
236
|
+
gray500: baseColors.gray[500],
|
|
237
|
+
gray600: baseColors.gray[600],
|
|
238
|
+
gray700: baseColors.gray[700],
|
|
239
|
+
gray800: baseColors.gray[800],
|
|
240
|
+
gray900: baseColors.gray[900],
|
|
241
|
+
|
|
242
|
+
// Base Colors - Pure
|
|
243
|
+
white: baseColors.white,
|
|
244
|
+
black: baseColors.black,
|
|
245
|
+
|
|
246
|
+
// Text Color Aliases (for semantic usage like color="primary")
|
|
247
|
+
// These map to the flattened text colors for convenience
|
|
248
|
+
primary: semanticColors.text.primary,
|
|
249
|
+
secondary: semanticColors.text.secondary,
|
|
250
|
+
tertiary: semanticColors.text.tertiary,
|
|
251
|
+
disabled: semanticColors.text.disabled,
|
|
252
|
+
inverse: semanticColors.text.inverse,
|
|
253
|
+
link: semanticColors.text.link,
|
|
254
|
+
success: semanticColors.feedback.success,
|
|
255
|
+
warning: semanticColors.feedback.warning,
|
|
256
|
+
error: semanticColors.feedback.error,
|
|
257
|
+
info: semanticColors.feedback.info,
|
|
258
|
+
}) as const;
|
|
259
|
+
|
|
260
|
+
// =============================================================================
|
|
261
|
+
// COLOR PALETTES
|
|
262
|
+
// =============================================================================
|
|
263
|
+
|
|
264
|
+
const lightColors = flattenColors(lightSemanticColors);
|
|
265
|
+
const darkColors = flattenColors(darkSemanticColors);
|
|
266
|
+
|
|
267
|
+
// =============================================================================
|
|
268
|
+
// RESTYLE THEME DEFINITION
|
|
269
|
+
// =============================================================================
|
|
270
|
+
|
|
271
|
+
// =============================================================================
|
|
272
|
+
// HELPER: CREATE BASE THEME CONFIG
|
|
273
|
+
// Shared configuration for both light and dark themes
|
|
274
|
+
// =============================================================================
|
|
275
|
+
|
|
276
|
+
export const createBaseThemeConfig = (
|
|
277
|
+
colors: ReturnType<typeof flattenColors>,
|
|
278
|
+
) => ({
|
|
279
|
+
colors,
|
|
280
|
+
spacing,
|
|
281
|
+
borderRadii: radii,
|
|
282
|
+
textVariants: {
|
|
283
|
+
defaults: {
|
|
284
|
+
color: "textPrimary",
|
|
285
|
+
},
|
|
286
|
+
// Display variants
|
|
287
|
+
displayLarge: {
|
|
288
|
+
fontSize: typographyPresets.displayLarge.fontSize,
|
|
289
|
+
lineHeight: typographyPresets.displayLarge.lineHeight,
|
|
290
|
+
fontWeight: typographyPresets.displayLarge.fontWeight,
|
|
291
|
+
letterSpacing: typographyPresets.displayLarge.letterSpacing,
|
|
292
|
+
fontFamily: fontFamily.bold,
|
|
293
|
+
},
|
|
294
|
+
displayMedium: {
|
|
295
|
+
fontSize: typographyPresets.displayMedium.fontSize,
|
|
296
|
+
lineHeight: typographyPresets.displayMedium.lineHeight,
|
|
297
|
+
fontWeight: typographyPresets.displayMedium.fontWeight,
|
|
298
|
+
letterSpacing: typographyPresets.displayMedium.letterSpacing,
|
|
299
|
+
fontFamily: fontFamily.bold,
|
|
300
|
+
},
|
|
301
|
+
displaySmall: {
|
|
302
|
+
fontSize: typographyPresets.displaySmall.fontSize,
|
|
303
|
+
lineHeight: typographyPresets.displaySmall.lineHeight,
|
|
304
|
+
fontWeight: typographyPresets.displaySmall.fontWeight,
|
|
305
|
+
letterSpacing: typographyPresets.displaySmall.letterSpacing,
|
|
306
|
+
fontFamily: fontFamily.bold,
|
|
307
|
+
},
|
|
308
|
+
// Heading variants
|
|
309
|
+
headingLarge: {
|
|
310
|
+
fontSize: typographyPresets.headingLarge.fontSize,
|
|
311
|
+
lineHeight: typographyPresets.headingLarge.lineHeight,
|
|
312
|
+
fontWeight: typographyPresets.headingLarge.fontWeight,
|
|
313
|
+
letterSpacing: typographyPresets.headingLarge.letterSpacing,
|
|
314
|
+
fontFamily: fontFamily.semibold,
|
|
315
|
+
},
|
|
316
|
+
headingMedium: {
|
|
317
|
+
fontSize: typographyPresets.headingMedium.fontSize,
|
|
318
|
+
lineHeight: typographyPresets.headingMedium.lineHeight,
|
|
319
|
+
fontWeight: typographyPresets.headingMedium.fontWeight,
|
|
320
|
+
letterSpacing: typographyPresets.headingMedium.letterSpacing,
|
|
321
|
+
fontFamily: fontFamily.semibold,
|
|
322
|
+
},
|
|
323
|
+
headingSmall: {
|
|
324
|
+
fontSize: typographyPresets.headingSmall.fontSize,
|
|
325
|
+
lineHeight: typographyPresets.headingSmall.lineHeight,
|
|
326
|
+
fontWeight: typographyPresets.headingSmall.fontWeight,
|
|
327
|
+
letterSpacing: typographyPresets.headingSmall.letterSpacing,
|
|
328
|
+
fontFamily: fontFamily.semibold,
|
|
329
|
+
},
|
|
330
|
+
// Body variants
|
|
331
|
+
bodyLarge: {
|
|
332
|
+
fontSize: typographyPresets.bodyLarge.fontSize,
|
|
333
|
+
lineHeight: typographyPresets.bodyLarge.lineHeight,
|
|
334
|
+
fontWeight: typographyPresets.bodyLarge.fontWeight,
|
|
335
|
+
letterSpacing: typographyPresets.bodyLarge.letterSpacing,
|
|
336
|
+
fontFamily: fontFamily.regular,
|
|
337
|
+
},
|
|
338
|
+
bodyMedium: {
|
|
339
|
+
fontSize: typographyPresets.bodyMedium.fontSize,
|
|
340
|
+
lineHeight: typographyPresets.bodyMedium.lineHeight,
|
|
341
|
+
fontWeight: typographyPresets.bodyMedium.fontWeight,
|
|
342
|
+
letterSpacing: typographyPresets.bodyMedium.letterSpacing,
|
|
343
|
+
fontFamily: fontFamily.regular,
|
|
344
|
+
},
|
|
345
|
+
bodySmall: {
|
|
346
|
+
fontSize: typographyPresets.bodySmall.fontSize,
|
|
347
|
+
lineHeight: typographyPresets.bodySmall.lineHeight,
|
|
348
|
+
fontWeight: typographyPresets.bodySmall.fontWeight,
|
|
349
|
+
letterSpacing: typographyPresets.bodySmall.letterSpacing,
|
|
350
|
+
fontFamily: fontFamily.regular,
|
|
351
|
+
},
|
|
352
|
+
// Label variants
|
|
353
|
+
labelLarge: {
|
|
354
|
+
fontSize: typographyPresets.labelLarge.fontSize,
|
|
355
|
+
lineHeight: typographyPresets.labelLarge.lineHeight,
|
|
356
|
+
fontWeight: typographyPresets.labelLarge.fontWeight,
|
|
357
|
+
letterSpacing: typographyPresets.labelLarge.letterSpacing,
|
|
358
|
+
fontFamily: fontFamily.medium,
|
|
359
|
+
},
|
|
360
|
+
labelMedium: {
|
|
361
|
+
fontSize: typographyPresets.labelMedium.fontSize,
|
|
362
|
+
lineHeight: typographyPresets.labelMedium.lineHeight,
|
|
363
|
+
fontWeight: typographyPresets.labelMedium.fontWeight,
|
|
364
|
+
letterSpacing: typographyPresets.labelMedium.letterSpacing,
|
|
365
|
+
fontFamily: fontFamily.medium,
|
|
366
|
+
},
|
|
367
|
+
labelSmall: {
|
|
368
|
+
fontSize: typographyPresets.labelSmall.fontSize,
|
|
369
|
+
lineHeight: typographyPresets.labelSmall.lineHeight,
|
|
370
|
+
fontWeight: typographyPresets.labelSmall.fontWeight,
|
|
371
|
+
letterSpacing: typographyPresets.labelSmall.letterSpacing,
|
|
372
|
+
fontFamily: fontFamily.medium,
|
|
373
|
+
},
|
|
374
|
+
// Caption variants
|
|
375
|
+
caption: {
|
|
376
|
+
fontSize: typographyPresets.caption.fontSize,
|
|
377
|
+
lineHeight: typographyPresets.caption.lineHeight,
|
|
378
|
+
fontWeight: typographyPresets.caption.fontWeight,
|
|
379
|
+
letterSpacing: typographyPresets.caption.letterSpacing,
|
|
380
|
+
fontFamily: fontFamily.regular,
|
|
381
|
+
},
|
|
382
|
+
captionSmall: {
|
|
383
|
+
fontSize: typographyPresets.captionSmall.fontSize,
|
|
384
|
+
lineHeight: typographyPresets.captionSmall.lineHeight,
|
|
385
|
+
fontWeight: typographyPresets.captionSmall.fontWeight,
|
|
386
|
+
letterSpacing: typographyPresets.captionSmall.letterSpacing,
|
|
387
|
+
fontFamily: fontFamily.regular,
|
|
388
|
+
},
|
|
389
|
+
// Overline variant
|
|
390
|
+
overline: {
|
|
391
|
+
fontSize: typographyPresets.overline.fontSize,
|
|
392
|
+
lineHeight: typographyPresets.overline.lineHeight,
|
|
393
|
+
fontWeight: typographyPresets.overline.fontWeight,
|
|
394
|
+
letterSpacing: typographyPresets.overline.letterSpacing,
|
|
395
|
+
textTransform: typographyPresets.overline.textTransform,
|
|
396
|
+
fontFamily: fontFamily.semibold,
|
|
397
|
+
},
|
|
398
|
+
// Code variant
|
|
399
|
+
code: {
|
|
400
|
+
fontSize: typographyPresets.code.fontSize,
|
|
401
|
+
lineHeight: typographyPresets.code.lineHeight,
|
|
402
|
+
fontWeight: typographyPresets.code.fontWeight,
|
|
403
|
+
letterSpacing: typographyPresets.code.letterSpacing,
|
|
404
|
+
fontFamily: fontFamily.mono,
|
|
405
|
+
},
|
|
406
|
+
},
|
|
407
|
+
breakpoints: {
|
|
408
|
+
phone: 0,
|
|
409
|
+
tablet: 768,
|
|
410
|
+
},
|
|
411
|
+
zIndices: {
|
|
412
|
+
behind: zIndex.behind,
|
|
413
|
+
base: zIndex.base,
|
|
414
|
+
raised: zIndex.raised,
|
|
415
|
+
dropdown: zIndex.dropdown,
|
|
416
|
+
sticky: zIndex.sticky,
|
|
417
|
+
overlay: zIndex.overlay,
|
|
418
|
+
modal: zIndex.modal,
|
|
419
|
+
popover: zIndex.popover,
|
|
420
|
+
toast: zIndex.toast,
|
|
421
|
+
max: zIndex.max,
|
|
422
|
+
},
|
|
423
|
+
// ==========================================================================
|
|
424
|
+
// BUTTON SIZES
|
|
425
|
+
// ==========================================================================
|
|
426
|
+
// Mathematical relationship: Icon matches text visual weight (1:1)
|
|
427
|
+
//
|
|
428
|
+
// | Size | Height | Icon | Text Variant | Touch Target |
|
|
429
|
+
// |------|--------|------|--------------|--------------|
|
|
430
|
+
// | sm | 36px | 16px | labelSmall | 36px (native)|
|
|
431
|
+
// | md | 44px | 20px | labelMedium | 44px (native)|
|
|
432
|
+
// | lg | 52px | 24px | labelLarge | 52px (native)|
|
|
433
|
+
//
|
|
434
|
+
// See: tokens/scales.ts BUTTON_ICON_SIZE, BUTTON_TEXT_VARIANT
|
|
435
|
+
buttonSizes: {
|
|
436
|
+
defaults: {
|
|
437
|
+
height: 44,
|
|
438
|
+
paddingHorizontal: "md",
|
|
439
|
+
borderRadius: "md",
|
|
440
|
+
},
|
|
441
|
+
sm: {
|
|
442
|
+
height: 36,
|
|
443
|
+
paddingHorizontal: "sm",
|
|
444
|
+
},
|
|
445
|
+
md: {
|
|
446
|
+
height: 44,
|
|
447
|
+
paddingHorizontal: "md",
|
|
448
|
+
},
|
|
449
|
+
lg: {
|
|
450
|
+
height: 52,
|
|
451
|
+
paddingHorizontal: "lg",
|
|
452
|
+
},
|
|
453
|
+
},
|
|
454
|
+
// Button variants - visual styles only
|
|
455
|
+
buttonVariants: {
|
|
456
|
+
defaults: {
|
|
457
|
+
borderWidth: 0,
|
|
458
|
+
},
|
|
459
|
+
solid: {
|
|
460
|
+
borderWidth: 0,
|
|
461
|
+
},
|
|
462
|
+
outline: {
|
|
463
|
+
backgroundColor: "transparent",
|
|
464
|
+
borderWidth: 1.5,
|
|
465
|
+
},
|
|
466
|
+
ghost: {
|
|
467
|
+
backgroundColor: "transparent",
|
|
468
|
+
borderWidth: 0,
|
|
469
|
+
},
|
|
470
|
+
disabled: {
|
|
471
|
+
borderWidth: 0,
|
|
472
|
+
},
|
|
473
|
+
},
|
|
474
|
+
// ==========================================================================
|
|
475
|
+
// CHECKBOX SIZES
|
|
476
|
+
// ==========================================================================
|
|
477
|
+
// Mathematical relationship: Icon = Container × ~75% (toggleControl ratio)
|
|
478
|
+
//
|
|
479
|
+
// | Size | Container | Icon | Ratio | hitSlop | Touch Target |
|
|
480
|
+
// |------|-----------|------|-------|---------|--------------|
|
|
481
|
+
// | sm | 20px | 16px | 80% | 12px | 44px |
|
|
482
|
+
// | md | 24px | 20px | 83% | 10px | 44px |
|
|
483
|
+
// | lg | 32px | 24px | 75% | 6px | 44px |
|
|
484
|
+
//
|
|
485
|
+
// See: tokens/scales.ts CHECKBOX_ICON_SIZE, CHECKBOX_HIT_SLOP
|
|
486
|
+
checkboxSizes: {
|
|
487
|
+
defaults: {
|
|
488
|
+
width: 24,
|
|
489
|
+
height: 24,
|
|
490
|
+
borderRadius: "xs",
|
|
491
|
+
borderWidth: 2,
|
|
492
|
+
},
|
|
493
|
+
sm: {
|
|
494
|
+
width: 20,
|
|
495
|
+
height: 20,
|
|
496
|
+
},
|
|
497
|
+
md: {
|
|
498
|
+
width: 24,
|
|
499
|
+
height: 24,
|
|
500
|
+
},
|
|
501
|
+
lg: {
|
|
502
|
+
width: 32,
|
|
503
|
+
height: 32,
|
|
504
|
+
borderRadius: "sm",
|
|
505
|
+
},
|
|
506
|
+
},
|
|
507
|
+
// ==========================================================================
|
|
508
|
+
// RADIO BUTTON SIZES
|
|
509
|
+
// ==========================================================================
|
|
510
|
+
// Uses same container sizes as Checkbox but with circular shape (full radius).
|
|
511
|
+
// Inner dot size: ~40% of container for visual balance.
|
|
512
|
+
//
|
|
513
|
+
// | Size | Container | Inner Dot | hitSlop | Touch |
|
|
514
|
+
// |------|-----------|-----------|---------|-------|
|
|
515
|
+
// | sm | 20px | 8px | 12px | 44px |
|
|
516
|
+
// | md | 24px | 10px | 10px | 44px |
|
|
517
|
+
// | lg | 32px | 14px | 6px | 44px |
|
|
518
|
+
//
|
|
519
|
+
// See: tokens/scales.ts TOGGLE_CONTAINER_SIZES, RADIO_BUTTON_INNER_SIZE
|
|
520
|
+
radioButtonSizes: {
|
|
521
|
+
defaults: {
|
|
522
|
+
width: 24,
|
|
523
|
+
height: 24,
|
|
524
|
+
borderRadius: "full",
|
|
525
|
+
borderWidth: 2,
|
|
526
|
+
},
|
|
527
|
+
sm: {
|
|
528
|
+
width: 20,
|
|
529
|
+
height: 20,
|
|
530
|
+
},
|
|
531
|
+
md: {
|
|
532
|
+
width: 24,
|
|
533
|
+
height: 24,
|
|
534
|
+
},
|
|
535
|
+
lg: {
|
|
536
|
+
width: 32,
|
|
537
|
+
height: 32,
|
|
538
|
+
},
|
|
539
|
+
},
|
|
540
|
+
// ==========================================================================
|
|
541
|
+
// SWITCH SIZES
|
|
542
|
+
// ==========================================================================
|
|
543
|
+
// Mathematical relationship: Thumb = TrackHeight - (THUMB_INSET × 2)
|
|
544
|
+
// THUMB_INSET = 2px (from tokens/scales.ts)
|
|
545
|
+
//
|
|
546
|
+
// | Size | Track W | Track H | Thumb | W:H Ratio | hitSlop | Touch |
|
|
547
|
+
// |------|---------|---------|-------|-----------|---------|-------|
|
|
548
|
+
// | sm | 40px | 24px | 20px | 1.67:1 | 10px | 44px |
|
|
549
|
+
// | md | 48px | 28px | 24px | 1.71:1 | 8px | 44px |
|
|
550
|
+
// | lg | 56px | 32px | 28px | 1.75:1 | 6px | 44px |
|
|
551
|
+
//
|
|
552
|
+
// See: tokens/scales.ts SWITCH_DIMENSIONS, SWITCH_THUMB_INSET
|
|
553
|
+
switchSizes: {
|
|
554
|
+
defaults: {
|
|
555
|
+
// Track dimensions
|
|
556
|
+
width: 48,
|
|
557
|
+
height: 28,
|
|
558
|
+
borderRadius: "full",
|
|
559
|
+
},
|
|
560
|
+
sm: {
|
|
561
|
+
width: 40,
|
|
562
|
+
height: 24,
|
|
563
|
+
},
|
|
564
|
+
md: {
|
|
565
|
+
width: 48,
|
|
566
|
+
height: 28,
|
|
567
|
+
},
|
|
568
|
+
lg: {
|
|
569
|
+
width: 56,
|
|
570
|
+
height: 32,
|
|
571
|
+
},
|
|
572
|
+
},
|
|
573
|
+
// ==========================================================================
|
|
574
|
+
// TEXT INPUT VARIANTS
|
|
575
|
+
// ==========================================================================
|
|
576
|
+
// Visual style variants for TextInput. Actual border/background styling
|
|
577
|
+
// is resolved in TextInput.helpers.ts; keys here establish the type
|
|
578
|
+
// contract so TextInputVariant derives from the theme.
|
|
579
|
+
//
|
|
580
|
+
// | Variant | Background | Border | Use Case |
|
|
581
|
+
// |----------|----------------|-------------|----------|
|
|
582
|
+
// | outlined | transparent | 1.5px solid | Default, most forms |
|
|
583
|
+
// | filled | backgroundSecondary | subtle | Dense/compact UIs |
|
|
584
|
+
// | textarea | transparent | 1.5px solid | Multi-line text input |
|
|
585
|
+
textInputVariants: {
|
|
586
|
+
defaults: {},
|
|
587
|
+
outlined: {},
|
|
588
|
+
filled: {},
|
|
589
|
+
textarea: {},
|
|
590
|
+
},
|
|
591
|
+
// ==========================================================================
|
|
592
|
+
// TEXT INPUT SIZES
|
|
593
|
+
// ==========================================================================
|
|
594
|
+
// Height/padding presets for TextInput. Actual dimensions are
|
|
595
|
+
// resolved in TextInput.helpers.ts; keys establish the type contract.
|
|
596
|
+
//
|
|
597
|
+
// | Size | Height | Padding H | Font Size | Use Case |
|
|
598
|
+
// |------|--------|-----------|-----------|----------|
|
|
599
|
+
// | sm | 40px | 12px | 14px | Compact forms |
|
|
600
|
+
// | md | 48px | 16px | 16px | Default mobile |
|
|
601
|
+
// | lg | 56px | 20px | 18px | Tablets, emphasis |
|
|
602
|
+
textInputSizes: {
|
|
603
|
+
defaults: {},
|
|
604
|
+
sm: {},
|
|
605
|
+
md: {},
|
|
606
|
+
lg: {},
|
|
607
|
+
},
|
|
608
|
+
// ==========================================================================
|
|
609
|
+
// SELECT SHEET VARIANTS
|
|
610
|
+
// ==========================================================================
|
|
611
|
+
// Industry-standard dimensions based on Material Design 3 and iOS HIG.
|
|
612
|
+
//
|
|
613
|
+
// Variant Positioning:
|
|
614
|
+
// - center: Centered modal dialog with max-width constraint
|
|
615
|
+
// - bottom: Bottom sheet anchored to screen bottom
|
|
616
|
+
//
|
|
617
|
+
// Size Scale:
|
|
618
|
+
// | Size | Max Width | List Height | Header | Use Case |
|
|
619
|
+
// |------|-----------|-------------|--------|----------|
|
|
620
|
+
// | sm | 320px | 200px | 48px | Few options |
|
|
621
|
+
// | md | 400px | 300px | 56px | Default |
|
|
622
|
+
// SelectSheet - Simplified consistent width like Modal
|
|
623
|
+
// Phone: Full width - 16px margins
|
|
624
|
+
// Tablet (≥768px): Capped at 480px max-width for phone-like experience
|
|
625
|
+
//
|
|
626
|
+
// See: tokens/scales.ts SELECT_SHEET_LAYOUT
|
|
627
|
+
selectSheetVariants: {
|
|
628
|
+
defaults: {
|
|
629
|
+
backgroundColor: "surfaceElevated",
|
|
630
|
+
borderRadius: "xl",
|
|
631
|
+
overflow: "hidden",
|
|
632
|
+
},
|
|
633
|
+
},
|
|
634
|
+
// SelectSheet header - Consistent height
|
|
635
|
+
selectSheetHeader: {
|
|
636
|
+
height: 56,
|
|
637
|
+
paddingHorizontal: "lg",
|
|
638
|
+
borderBottomWidth: 1,
|
|
639
|
+
borderBottomColor: "borderSubtle",
|
|
640
|
+
flexDirection: "row",
|
|
641
|
+
alignItems: "center",
|
|
642
|
+
justifyContent: "space-between",
|
|
643
|
+
},
|
|
644
|
+
// SelectSheet option row - Consistent height with touch targets
|
|
645
|
+
selectSheetOptionRow: {
|
|
646
|
+
height: 52,
|
|
647
|
+
paddingHorizontal: "lg",
|
|
648
|
+
paddingVertical: "md",
|
|
649
|
+
flexDirection: "row",
|
|
650
|
+
alignItems: "center",
|
|
651
|
+
gap: "md",
|
|
652
|
+
},
|
|
653
|
+
// Card variants - visual styles
|
|
654
|
+
cardVariants: {
|
|
655
|
+
defaults: {
|
|
656
|
+
borderWidth: 0,
|
|
657
|
+
borderRadius: "lg",
|
|
658
|
+
},
|
|
659
|
+
flat: {
|
|
660
|
+
backgroundColor: "backgroundSecondary",
|
|
661
|
+
borderWidth: 0,
|
|
662
|
+
borderRadius: "lg",
|
|
663
|
+
},
|
|
664
|
+
outlined: {
|
|
665
|
+
backgroundColor: "backgroundSecondary",
|
|
666
|
+
borderWidth: 1,
|
|
667
|
+
borderColor: "borderDefault",
|
|
668
|
+
borderRadius: "lg",
|
|
669
|
+
},
|
|
670
|
+
},
|
|
671
|
+
// Header variants
|
|
672
|
+
headerVariants: {
|
|
673
|
+
defaults: {
|
|
674
|
+
backgroundColor: "surfacePrimary",
|
|
675
|
+
borderBottomWidth: 1,
|
|
676
|
+
borderBottomColor: "borderSubtle",
|
|
677
|
+
flexDirection: "row",
|
|
678
|
+
alignItems: "center",
|
|
679
|
+
gap: "xs",
|
|
680
|
+
paddingHorizontal: "lg", // 16px from spacing tokens
|
|
681
|
+
},
|
|
682
|
+
primary: {
|
|
683
|
+
backgroundColor: "surfacePrimary",
|
|
684
|
+
borderBottomWidth: 1,
|
|
685
|
+
borderBottomColor: "borderSubtle",
|
|
686
|
+
},
|
|
687
|
+
transparent: {
|
|
688
|
+
backgroundColor: "transparent",
|
|
689
|
+
borderBottomWidth: 0,
|
|
690
|
+
},
|
|
691
|
+
elevated: {
|
|
692
|
+
backgroundColor: "surfaceElevated",
|
|
693
|
+
borderBottomWidth: 0,
|
|
694
|
+
},
|
|
695
|
+
},
|
|
696
|
+
// Header sizes
|
|
697
|
+
// Content height only - safe area inset is added at runtime
|
|
698
|
+
// - sm (44px): Compact headers, modals - matches iOS minimum touch target
|
|
699
|
+
// - md (56px): Standard navigation, phone default
|
|
700
|
+
// - lg (64px): Prominent headers, tablet default
|
|
701
|
+
headerSizes: {
|
|
702
|
+
defaults: {
|
|
703
|
+
height: 56,
|
|
704
|
+
},
|
|
705
|
+
sm: {
|
|
706
|
+
height: 44,
|
|
707
|
+
},
|
|
708
|
+
md: {
|
|
709
|
+
height: 56,
|
|
710
|
+
},
|
|
711
|
+
lg: {
|
|
712
|
+
height: 64,
|
|
713
|
+
},
|
|
714
|
+
},
|
|
715
|
+
// Icon sizes
|
|
716
|
+
// Scale: 12 → 16 → 20 → 24 (+4px) → 32 → 40 → 48 (+8px)
|
|
717
|
+
// Smaller icons need finer control; larger icons can have bigger jumps
|
|
718
|
+
// - xs (12px): Badges, inline text indicators, status dots
|
|
719
|
+
// - sm (16px): Compact buttons, dense lists, checkbox icons (sm)
|
|
720
|
+
// - md (20px): Phone default, standard buttons, checkbox icons (md)
|
|
721
|
+
// - lg (24px): Primary actions, phone headers, checkbox icons (lg)
|
|
722
|
+
// - xl (32px): Tablet headers, emphasized actions
|
|
723
|
+
// - 2xl (40px): Empty states, onboarding illustrations
|
|
724
|
+
// - 3xl (48px): Hero sections, large feature illustrations
|
|
725
|
+
iconSizes: {
|
|
726
|
+
defaults: {
|
|
727
|
+
width: 20,
|
|
728
|
+
height: 20,
|
|
729
|
+
},
|
|
730
|
+
xs: {
|
|
731
|
+
width: 12,
|
|
732
|
+
height: 12,
|
|
733
|
+
},
|
|
734
|
+
sm: {
|
|
735
|
+
width: 16,
|
|
736
|
+
height: 16,
|
|
737
|
+
},
|
|
738
|
+
md: {
|
|
739
|
+
width: 20,
|
|
740
|
+
height: 20,
|
|
741
|
+
},
|
|
742
|
+
lg: {
|
|
743
|
+
width: 24,
|
|
744
|
+
height: 24,
|
|
745
|
+
},
|
|
746
|
+
xl: {
|
|
747
|
+
width: 32,
|
|
748
|
+
height: 32,
|
|
749
|
+
},
|
|
750
|
+
"2xl": {
|
|
751
|
+
width: 40,
|
|
752
|
+
height: 40,
|
|
753
|
+
},
|
|
754
|
+
"3xl": {
|
|
755
|
+
width: 48,
|
|
756
|
+
height: 48,
|
|
757
|
+
},
|
|
758
|
+
},
|
|
759
|
+
// IconButton variants (visual styles)
|
|
760
|
+
iconButtonVariants: {
|
|
761
|
+
defaults: {
|
|
762
|
+
borderRadius: "full",
|
|
763
|
+
borderWidth: 0,
|
|
764
|
+
backgroundColor: "accentPrimary", // Default to contained style
|
|
765
|
+
borderColor: "transparent",
|
|
766
|
+
},
|
|
767
|
+
contained: {
|
|
768
|
+
borderRadius: "full",
|
|
769
|
+
borderWidth: 0,
|
|
770
|
+
backgroundColor: "accentPrimary", // Default background, can be overridden via style prop
|
|
771
|
+
borderColor: "transparent",
|
|
772
|
+
},
|
|
773
|
+
outlined: {
|
|
774
|
+
borderRadius: "full",
|
|
775
|
+
borderWidth: 2,
|
|
776
|
+
backgroundColor: "transparent",
|
|
777
|
+
borderColor: "accentPrimary", // Default border color, can be overridden via style prop
|
|
778
|
+
},
|
|
779
|
+
ghost: {
|
|
780
|
+
borderRadius: "full",
|
|
781
|
+
borderWidth: 0,
|
|
782
|
+
backgroundColor: "transparent",
|
|
783
|
+
borderColor: "transparent",
|
|
784
|
+
},
|
|
785
|
+
},
|
|
786
|
+
// ==========================================================================
|
|
787
|
+
// ICON BUTTON SIZES
|
|
788
|
+
// ==========================================================================
|
|
789
|
+
// Mathematical relationship: Icon = Container × ~45% (circularButton ratio)
|
|
790
|
+
//
|
|
791
|
+
// | Size | Container | Icon | Ratio | hitSlop | Touch Target |
|
|
792
|
+
// |------|-----------|------|-------|---------|--------------|
|
|
793
|
+
// | sm | 36px | 16px | 44% | 4px | 44px |
|
|
794
|
+
// | md | 44px | 20px | 45% | 0px | 44px |
|
|
795
|
+
// | lg | 56px | 24px | 43% | 0px | 56px |
|
|
796
|
+
//
|
|
797
|
+
// Ghost variant uses icon size for hitSlop calculation:
|
|
798
|
+
// | Size | Icon | hitSlop | Touch Target |
|
|
799
|
+
// |------|------|---------|--------------|
|
|
800
|
+
// | sm | 16px | 14px | 44px |
|
|
801
|
+
// | md | 20px | 12px | 44px |
|
|
802
|
+
// | lg | 24px | 10px | 44px |
|
|
803
|
+
//
|
|
804
|
+
// See: tokens/scales.ts ICON_BUTTON_ICON_SIZE, ICON_BUTTON_HIT_SLOP
|
|
805
|
+
iconButtonSizes: {
|
|
806
|
+
defaults: {
|
|
807
|
+
width: 44,
|
|
808
|
+
height: 44,
|
|
809
|
+
alignItems: "center",
|
|
810
|
+
justifyContent: "center",
|
|
811
|
+
},
|
|
812
|
+
sm: {
|
|
813
|
+
width: 36,
|
|
814
|
+
height: 36,
|
|
815
|
+
},
|
|
816
|
+
md: {
|
|
817
|
+
width: 44,
|
|
818
|
+
height: 44,
|
|
819
|
+
},
|
|
820
|
+
lg: {
|
|
821
|
+
width: 56,
|
|
822
|
+
height: 56,
|
|
823
|
+
},
|
|
824
|
+
},
|
|
825
|
+
// ==========================================================================
|
|
826
|
+
// PROGRESS BAR SIZES
|
|
827
|
+
// ==========================================================================
|
|
828
|
+
// Height scales for progress bar track
|
|
829
|
+
//
|
|
830
|
+
// | Size | Height | Border Radius | Use Case |
|
|
831
|
+
// |------|--------|---------------|----------|
|
|
832
|
+
// | sm | 4px | 2px | Inline, compact indicators |
|
|
833
|
+
// | md | 8px | 4px | Standard progress bars |
|
|
834
|
+
// | lg | 12px | 6px | Prominent indicators |
|
|
835
|
+
//
|
|
836
|
+
// See: ProgressBar.helpers.ts PROGRESS_BAR_HEIGHTS
|
|
837
|
+
progressBarSizes: {
|
|
838
|
+
defaults: {
|
|
839
|
+
height: 8,
|
|
840
|
+
width: "100%",
|
|
841
|
+
},
|
|
842
|
+
sm: {
|
|
843
|
+
height: 4,
|
|
844
|
+
},
|
|
845
|
+
md: {
|
|
846
|
+
height: 8,
|
|
847
|
+
},
|
|
848
|
+
lg: {
|
|
849
|
+
height: 12,
|
|
850
|
+
},
|
|
851
|
+
},
|
|
852
|
+
// NOTE: progressBarVariants removed — ProgressBar now accepts a `color` prop
|
|
853
|
+
// (RestyleColor) instead of a variant key. Track background is always "borderSubtle".
|
|
854
|
+
// ==========================================================================
|
|
855
|
+
// SPINNER SIZES
|
|
856
|
+
// ==========================================================================
|
|
857
|
+
// Maps to React Native ActivityIndicator sizes
|
|
858
|
+
//
|
|
859
|
+
// | Size | ActivityIndicator | Use Case |
|
|
860
|
+
// |------|-------------------|----------|
|
|
861
|
+
// | sm | "small" | Inline loading, buttons |
|
|
862
|
+
// | lg | "large" | Full-screen loading, cards |
|
|
863
|
+
spinnerSizes: {
|
|
864
|
+
defaults: {},
|
|
865
|
+
sm: {},
|
|
866
|
+
lg: {},
|
|
867
|
+
},
|
|
868
|
+
// ==========================================================================
|
|
869
|
+
// AVATAR SIZES
|
|
870
|
+
// ==========================================================================
|
|
871
|
+
// Profile images with fallback initials following 8px grid
|
|
872
|
+
//
|
|
873
|
+
// | Size | Dimensions | Font | Use Case |
|
|
874
|
+
// |------|------------|------|----------|
|
|
875
|
+
// | sm | 32×32 | 12px | Compact lists, comments |
|
|
876
|
+
// | md | 40×40 | 14px | Standard avatar (default) |
|
|
877
|
+
// | lg | 56×56 | 20px | Profile headers, featured |
|
|
878
|
+
avatarSizes: {
|
|
879
|
+
defaults: {
|
|
880
|
+
borderRadius: "full",
|
|
881
|
+
alignItems: "center",
|
|
882
|
+
justifyContent: "center",
|
|
883
|
+
},
|
|
884
|
+
sm: {
|
|
885
|
+
width: 32,
|
|
886
|
+
height: 32,
|
|
887
|
+
},
|
|
888
|
+
md: {
|
|
889
|
+
width: 40,
|
|
890
|
+
height: 40,
|
|
891
|
+
},
|
|
892
|
+
lg: {
|
|
893
|
+
width: 56,
|
|
894
|
+
height: 56,
|
|
895
|
+
},
|
|
896
|
+
},
|
|
897
|
+
// ==========================================================================
|
|
898
|
+
// SKELETON VARIANTS
|
|
899
|
+
// ==========================================================================
|
|
900
|
+
// Shape variants for Skeleton. Actual border-radius/dimension logic
|
|
901
|
+
// is resolved in Skeleton.helpers.ts; keys establish the type contract.
|
|
902
|
+
//
|
|
903
|
+
// | Variant | Shape | Use Case |
|
|
904
|
+
// |--------------|-------------------|----------|
|
|
905
|
+
// | text | Rounded rectangle | Text placeholders |
|
|
906
|
+
// | circular | Circle | Avatar/icon placeholders |
|
|
907
|
+
// | rectangular | Sharp corners | Image/card placeholders |
|
|
908
|
+
skeletonVariants: {
|
|
909
|
+
defaults: {},
|
|
910
|
+
text: {},
|
|
911
|
+
circular: {},
|
|
912
|
+
rectangular: {},
|
|
913
|
+
},
|
|
914
|
+
// ==========================================================================
|
|
915
|
+
// SKELETON SIZES
|
|
916
|
+
// ==========================================================================
|
|
917
|
+
// Size presets for Skeleton. Actual dimensions vary by variant
|
|
918
|
+
// and are resolved in Skeleton.helpers.ts.
|
|
919
|
+
//
|
|
920
|
+
// | Size | Text Height | Circular | Rectangular | Use Case |
|
|
921
|
+
// |------|-------------|----------|-------------|----------|
|
|
922
|
+
// | sm | 16px | 32px | 80px | Compact elements |
|
|
923
|
+
// | md | 20px | 48px | 120px | Standard content |
|
|
924
|
+
// | lg | 28px | 64px | 160px | Headings/prominent |
|
|
925
|
+
skeletonSizes: {
|
|
926
|
+
defaults: {},
|
|
927
|
+
sm: {},
|
|
928
|
+
md: {},
|
|
929
|
+
lg: {},
|
|
930
|
+
},
|
|
931
|
+
// ==========================================================================
|
|
932
|
+
// CHIP SIZES
|
|
933
|
+
// ==========================================================================
|
|
934
|
+
// Compact elements for tags, filters, and selections
|
|
935
|
+
// Professional sizing: 28/32/40px with optimal density-to-usability ratio
|
|
936
|
+
//
|
|
937
|
+
// | Size | Height | Padding H | Icon | Text Variant | Use Case |
|
|
938
|
+
// |------|--------|-----------|------|--------------|----------|
|
|
939
|
+
// | sm | 28px | sm (8px) | xs | captionSmall | Dense UIs, compact tags |
|
|
940
|
+
// | md | 32px | md (12px) | sm | labelSmall | Standard (default) |
|
|
941
|
+
// | lg | 40px | lg (16px) | md | labelMedium | Prominent filters |
|
|
942
|
+
chipSizes: {
|
|
943
|
+
defaults: {
|
|
944
|
+
borderRadius: "full",
|
|
945
|
+
alignItems: "center",
|
|
946
|
+
justifyContent: "center",
|
|
947
|
+
flexDirection: "row",
|
|
948
|
+
gap: "xs",
|
|
949
|
+
},
|
|
950
|
+
sm: {
|
|
951
|
+
height: 28,
|
|
952
|
+
paddingHorizontal: "sm",
|
|
953
|
+
},
|
|
954
|
+
md: {
|
|
955
|
+
height: 32,
|
|
956
|
+
paddingHorizontal: "md",
|
|
957
|
+
},
|
|
958
|
+
lg: {
|
|
959
|
+
height: 40,
|
|
960
|
+
paddingHorizontal: "lg",
|
|
961
|
+
},
|
|
962
|
+
},
|
|
963
|
+
// Chip variants - visual styles (colors handled dynamically via logic hook)
|
|
964
|
+
chipVariants: {
|
|
965
|
+
defaults: {
|
|
966
|
+
borderRadius: "full",
|
|
967
|
+
borderWidth: 0,
|
|
968
|
+
},
|
|
969
|
+
filled: {
|
|
970
|
+
borderWidth: 0,
|
|
971
|
+
},
|
|
972
|
+
outlined: {
|
|
973
|
+
borderWidth: 1.5,
|
|
974
|
+
backgroundColor: "transparent",
|
|
975
|
+
},
|
|
976
|
+
},
|
|
977
|
+
// ==========================================================================
|
|
978
|
+
// BADGE SIZES
|
|
979
|
+
// ==========================================================================
|
|
980
|
+
// Compact status indicators, counts, and labels
|
|
981
|
+
// Heights follow 4px grid: 16/20/24px for visual consistency
|
|
982
|
+
//
|
|
983
|
+
// | Size | Height | Min Width | Dot Size | Padding H | Use Case |
|
|
984
|
+
// |------|--------|-----------|----------|-----------|----------|
|
|
985
|
+
// | sm | 16px | 16px | 6px | 2xs (2px) | Inline indicators |
|
|
986
|
+
// | md | 20px | 20px | 8px | xs (4px) | Standard (default) |
|
|
987
|
+
// | lg | 24px | 24px | 10px | sm (8px) | Prominent badges |
|
|
988
|
+
badgeSizes: {
|
|
989
|
+
defaults: {
|
|
990
|
+
borderRadius: "full",
|
|
991
|
+
alignItems: "center",
|
|
992
|
+
justifyContent: "center",
|
|
993
|
+
},
|
|
994
|
+
sm: {
|
|
995
|
+
height: 16,
|
|
996
|
+
minWidth: 16,
|
|
997
|
+
paddingHorizontal: "2xs",
|
|
998
|
+
},
|
|
999
|
+
md: {
|
|
1000
|
+
height: 20,
|
|
1001
|
+
minWidth: 20,
|
|
1002
|
+
paddingHorizontal: "xs",
|
|
1003
|
+
},
|
|
1004
|
+
lg: {
|
|
1005
|
+
height: 24,
|
|
1006
|
+
minWidth: 24,
|
|
1007
|
+
paddingHorizontal: "sm",
|
|
1008
|
+
},
|
|
1009
|
+
},
|
|
1010
|
+
// Badge variants - visual styles (colors handled dynamically via logic hook)
|
|
1011
|
+
badgeVariants: {
|
|
1012
|
+
defaults: {
|
|
1013
|
+
borderRadius: "full",
|
|
1014
|
+
borderWidth: 0,
|
|
1015
|
+
},
|
|
1016
|
+
filled: {
|
|
1017
|
+
borderWidth: 0,
|
|
1018
|
+
},
|
|
1019
|
+
outlined: {
|
|
1020
|
+
borderWidth: 1.5,
|
|
1021
|
+
backgroundColor: "transparent",
|
|
1022
|
+
},
|
|
1023
|
+
},
|
|
1024
|
+
// ==========================================================================
|
|
1025
|
+
// LIST ITEM SIZES
|
|
1026
|
+
// ==========================================================================
|
|
1027
|
+
// Flexible list item with leading/trailing content slots
|
|
1028
|
+
//
|
|
1029
|
+
// | Size | Min Height | Padding V | Padding H | Use Case |
|
|
1030
|
+
// |------|------------|-----------|-----------|----------|
|
|
1031
|
+
// | sm | 44px | xs (4px) | md (12px) | Compact lists, dense UIs |
|
|
1032
|
+
// | md | 56px | sm (8px) | md (12px) | Standard (default) |
|
|
1033
|
+
// | lg | 72px | md (12px) | lg (16px) | Prominent items, settings |
|
|
1034
|
+
listItemSizes: {
|
|
1035
|
+
defaults: {
|
|
1036
|
+
minHeight: 56,
|
|
1037
|
+
paddingHorizontal: "md",
|
|
1038
|
+
paddingVertical: "sm",
|
|
1039
|
+
},
|
|
1040
|
+
sm: {
|
|
1041
|
+
minHeight: 44,
|
|
1042
|
+
paddingHorizontal: "md",
|
|
1043
|
+
paddingVertical: "xs",
|
|
1044
|
+
},
|
|
1045
|
+
md: {
|
|
1046
|
+
minHeight: 56,
|
|
1047
|
+
paddingHorizontal: "md",
|
|
1048
|
+
paddingVertical: "sm",
|
|
1049
|
+
},
|
|
1050
|
+
lg: {
|
|
1051
|
+
minHeight: 72,
|
|
1052
|
+
paddingHorizontal: "lg",
|
|
1053
|
+
paddingVertical: "md",
|
|
1054
|
+
},
|
|
1055
|
+
},
|
|
1056
|
+
// ==========================================================================
|
|
1057
|
+
// TOAST VARIANTS
|
|
1058
|
+
// ==========================================================================
|
|
1059
|
+
// Toast notifications for user feedback
|
|
1060
|
+
// Consistent 48px min-height for comfortable reading and touch dismissal
|
|
1061
|
+
//
|
|
1062
|
+
// | Variant | Use Case |
|
|
1063
|
+
// |---------|----------|
|
|
1064
|
+
// | success | Positive feedback, operation completed |
|
|
1065
|
+
// | error | Error state, operation failed |
|
|
1066
|
+
// | warning | Caution, potential issue |
|
|
1067
|
+
// | info | Informational message |
|
|
1068
|
+
//
|
|
1069
|
+
// Colors are applied dynamically via component logic for theme awareness
|
|
1070
|
+
toastVariants: {
|
|
1071
|
+
defaults: {
|
|
1072
|
+
borderRadius: "md",
|
|
1073
|
+
borderWidth: 1,
|
|
1074
|
+
padding: "sm",
|
|
1075
|
+
flexDirection: "row",
|
|
1076
|
+
alignItems: "center",
|
|
1077
|
+
gap: "sm",
|
|
1078
|
+
minHeight: 48,
|
|
1079
|
+
},
|
|
1080
|
+
success: {},
|
|
1081
|
+
error: {},
|
|
1082
|
+
warning: {},
|
|
1083
|
+
info: {},
|
|
1084
|
+
},
|
|
1085
|
+
// ==========================================================================
|
|
1086
|
+
// DIVIDER VARIANTS
|
|
1087
|
+
// ==========================================================================
|
|
1088
|
+
// Visual separators for content sections
|
|
1089
|
+
//
|
|
1090
|
+
// | Variant | Color | Use Case |
|
|
1091
|
+
// |---------|-------|----------|
|
|
1092
|
+
// | subtle | borderSubtle | Light separation (default) |
|
|
1093
|
+
// | default | borderDefault | Standard separation |
|
|
1094
|
+
// | strong | borderStrong | Prominent separation |
|
|
1095
|
+
dividerVariants: {
|
|
1096
|
+
defaults: {},
|
|
1097
|
+
subtle: {
|
|
1098
|
+
backgroundColor: "borderSubtle",
|
|
1099
|
+
},
|
|
1100
|
+
default: {
|
|
1101
|
+
backgroundColor: "borderDefault",
|
|
1102
|
+
},
|
|
1103
|
+
strong: {
|
|
1104
|
+
backgroundColor: "borderStrong",
|
|
1105
|
+
},
|
|
1106
|
+
},
|
|
1107
|
+
// Divider thickness sizes
|
|
1108
|
+
dividerSizes: {
|
|
1109
|
+
defaults: {},
|
|
1110
|
+
thin: {
|
|
1111
|
+
height: 1,
|
|
1112
|
+
},
|
|
1113
|
+
medium: {
|
|
1114
|
+
height: 2,
|
|
1115
|
+
},
|
|
1116
|
+
thick: {
|
|
1117
|
+
height: 4,
|
|
1118
|
+
},
|
|
1119
|
+
},
|
|
1120
|
+
// ==========================================================================
|
|
1121
|
+
// CALENDAR STRIP SIZES
|
|
1122
|
+
// ==========================================================================
|
|
1123
|
+
// Horizontal row of tappable day cards
|
|
1124
|
+
//
|
|
1125
|
+
// | Size | Container Gap | Day Padding V | Day Number | Label |
|
|
1126
|
+
// |------|---------------|---------------|-------------|-------------|
|
|
1127
|
+
// | sm | xs (4px) | xs (4px) | labelSmall | captionSmall|
|
|
1128
|
+
// | md | md (12px) | md (12px) | labelMedium | captionSmall|
|
|
1129
|
+
// | lg | lg (16px) | lg (16px) | labelLarge | caption |
|
|
1130
|
+
// ScheduleItem sizes
|
|
1131
|
+
// | Size | Padding | Indicator H | Content Gap | Title | Time |
|
|
1132
|
+
// | sm | xs | 32px | 2xs | labelSmall | captionSmall |
|
|
1133
|
+
// | md | sm | 48px | 2xs | labelSmall | captionSmall |
|
|
1134
|
+
// | lg | md | 64px | xs | labelMedium | bodySmall |
|
|
1135
|
+
scheduleItemSizes: {
|
|
1136
|
+
defaults: {
|
|
1137
|
+
flexDirection: "row",
|
|
1138
|
+
alignItems: "center",
|
|
1139
|
+
borderRadius: "sm",
|
|
1140
|
+
backgroundColor: "backgroundSecondary",
|
|
1141
|
+
gap: "sm",
|
|
1142
|
+
},
|
|
1143
|
+
sm: { padding: "xs" },
|
|
1144
|
+
md: { padding: "sm" },
|
|
1145
|
+
lg: { padding: "md" },
|
|
1146
|
+
},
|
|
1147
|
+
|
|
1148
|
+
calendarStripSizes: {
|
|
1149
|
+
defaults: {
|
|
1150
|
+
flexDirection: "row",
|
|
1151
|
+
},
|
|
1152
|
+
sm: {
|
|
1153
|
+
gap: "xs",
|
|
1154
|
+
},
|
|
1155
|
+
md: {
|
|
1156
|
+
gap: "md",
|
|
1157
|
+
},
|
|
1158
|
+
lg: {
|
|
1159
|
+
gap: "lg",
|
|
1160
|
+
},
|
|
1161
|
+
},
|
|
1162
|
+
// ==========================================================================
|
|
1163
|
+
// EMPTY STATE SIZES
|
|
1164
|
+
// ==========================================================================
|
|
1165
|
+
// Centered empty state layouts
|
|
1166
|
+
//
|
|
1167
|
+
// | Variant | Icon Size | Title | Description | Padding | Use Case |
|
|
1168
|
+
// |---------|-----------|-------|-------------|---------|----------|
|
|
1169
|
+
// | default | xl (32px) | headingSmall | bodyMedium | xl | Full-page states |
|
|
1170
|
+
// | compact | lg (24px) | labelLarge | bodySmall | lg | Card/section states |
|
|
1171
|
+
emptyStateSizes: {
|
|
1172
|
+
defaults: {
|
|
1173
|
+
alignItems: "center",
|
|
1174
|
+
justifyContent: "center",
|
|
1175
|
+
flex: 1,
|
|
1176
|
+
},
|
|
1177
|
+
default: {
|
|
1178
|
+
padding: "xl",
|
|
1179
|
+
gap: "lg",
|
|
1180
|
+
},
|
|
1181
|
+
compact: {
|
|
1182
|
+
padding: "lg",
|
|
1183
|
+
gap: "md",
|
|
1184
|
+
},
|
|
1185
|
+
},
|
|
1186
|
+
// ==========================================================================
|
|
1187
|
+
// EMPTY STATE VARIANTS
|
|
1188
|
+
// ==========================================================================
|
|
1189
|
+
// Visual style variants for EmptyState. Layout dimensions live in
|
|
1190
|
+
// emptyStateSizes above; keys here provide the variant type contract
|
|
1191
|
+
// so EmptyStateVariant derives from the theme.
|
|
1192
|
+
//
|
|
1193
|
+
// | Variant | Padding | Gap | Title | Description | Use Case |
|
|
1194
|
+
// |---------|---------|-----|--------------|--------------|----------|
|
|
1195
|
+
// | default | xl | lg | headingSmall | bodyMedium | Full-page states |
|
|
1196
|
+
// | compact | lg | md | labelLarge | bodySmall | Card/section states |
|
|
1197
|
+
emptyStateVariants: {
|
|
1198
|
+
defaults: {},
|
|
1199
|
+
default: {},
|
|
1200
|
+
compact: {},
|
|
1201
|
+
},
|
|
1202
|
+
// ==========================================================================
|
|
1203
|
+
// SEGMENTED CONTROL SIZES
|
|
1204
|
+
// ==========================================================================
|
|
1205
|
+
// Toggle between multiple options - professional sizing with 44px touch target
|
|
1206
|
+
// Container heights: 36/44/52px matching button scale for visual harmony
|
|
1207
|
+
//
|
|
1208
|
+
// | Size | Height | Segment H | Padding | Gap | Text Variant | Use Case |
|
|
1209
|
+
// |------|--------|-----------|---------|-----|--------------|----------|
|
|
1210
|
+
// | sm | 36px | 28px | xs | 2xs | labelSmall | Compact filters |
|
|
1211
|
+
// | md | 44px | 36px | xs | 2xs | labelMedium | Standard (default) |
|
|
1212
|
+
// | lg | 52px | 44px | sm | xs | labelLarge | Prominent controls |
|
|
1213
|
+
segmentedControlSizes: {
|
|
1214
|
+
defaults: {
|
|
1215
|
+
borderRadius: "lg",
|
|
1216
|
+
flexDirection: "row",
|
|
1217
|
+
alignItems: "center",
|
|
1218
|
+
},
|
|
1219
|
+
sm: {
|
|
1220
|
+
height: 36,
|
|
1221
|
+
padding: "xs",
|
|
1222
|
+
gap: "2xs",
|
|
1223
|
+
},
|
|
1224
|
+
md: {
|
|
1225
|
+
height: 44,
|
|
1226
|
+
padding: "xs",
|
|
1227
|
+
gap: "2xs",
|
|
1228
|
+
},
|
|
1229
|
+
lg: {
|
|
1230
|
+
height: 52,
|
|
1231
|
+
padding: "sm",
|
|
1232
|
+
gap: "xs",
|
|
1233
|
+
},
|
|
1234
|
+
},
|
|
1235
|
+
// Segmented control segment sizes (inner segment dimensions)
|
|
1236
|
+
segmentedControlSegmentSizes: {
|
|
1237
|
+
defaults: {
|
|
1238
|
+
borderRadius: "md",
|
|
1239
|
+
alignItems: "center",
|
|
1240
|
+
justifyContent: "center",
|
|
1241
|
+
flex: 1,
|
|
1242
|
+
},
|
|
1243
|
+
sm: {
|
|
1244
|
+
height: 28,
|
|
1245
|
+
paddingHorizontal: "sm",
|
|
1246
|
+
},
|
|
1247
|
+
md: {
|
|
1248
|
+
height: 36,
|
|
1249
|
+
paddingHorizontal: "md",
|
|
1250
|
+
},
|
|
1251
|
+
lg: {
|
|
1252
|
+
height: 44,
|
|
1253
|
+
paddingHorizontal: "lg",
|
|
1254
|
+
},
|
|
1255
|
+
},
|
|
1256
|
+
// Segmented control variants - visual styles for container
|
|
1257
|
+
segmentedControlVariants: {
|
|
1258
|
+
defaults: {
|
|
1259
|
+
borderRadius: "lg",
|
|
1260
|
+
borderWidth: 0,
|
|
1261
|
+
},
|
|
1262
|
+
default: {
|
|
1263
|
+
backgroundColor: "backgroundTertiary",
|
|
1264
|
+
borderWidth: 0,
|
|
1265
|
+
},
|
|
1266
|
+
outline: {
|
|
1267
|
+
backgroundColor: "transparent",
|
|
1268
|
+
borderWidth: 1.5,
|
|
1269
|
+
borderColor: "borderDefault",
|
|
1270
|
+
},
|
|
1271
|
+
},
|
|
1272
|
+
});
|
|
1273
|
+
|
|
1274
|
+
// =============================================================================
|
|
1275
|
+
// RESTYLE THEMES
|
|
1276
|
+
// =============================================================================
|
|
1277
|
+
|
|
1278
|
+
export const restyleLightTheme = createTheme(
|
|
1279
|
+
createBaseThemeConfig(lightColors),
|
|
1280
|
+
);
|
|
1281
|
+
export const restyleDarkTheme = createTheme(createBaseThemeConfig(darkColors));
|
|
1282
|
+
|
|
1283
|
+
// Default export for backwards compatibility
|
|
1284
|
+
export const restyleTheme = restyleLightTheme;
|
|
1285
|
+
|
|
1286
|
+
export type RestyleTheme = typeof restyleLightTheme;
|
|
1287
|
+
|
|
1288
|
+
/**
|
|
1289
|
+
* Augmentable interface for app-specific color tokens.
|
|
1290
|
+
*
|
|
1291
|
+
* Apps extend the design system palette by augmenting this interface
|
|
1292
|
+
* via TypeScript declaration merging. Once augmented, the new color
|
|
1293
|
+
* token names are accepted by components whose color prop uses
|
|
1294
|
+
* `AppThemeColors` (e.g. Chip).
|
|
1295
|
+
*
|
|
1296
|
+
* @example
|
|
1297
|
+
* ```ts
|
|
1298
|
+
* // app-theme.d.ts (in your app, NOT in the package)
|
|
1299
|
+
* declare module "@praxiis/ui" {
|
|
1300
|
+
* interface AppThemeColors {
|
|
1301
|
+
* brandOrange: string;
|
|
1302
|
+
* brandTeal: string;
|
|
1303
|
+
* }
|
|
1304
|
+
* }
|
|
1305
|
+
* ```
|
|
1306
|
+
*
|
|
1307
|
+
* At runtime, provide a theme with matching color keys via
|
|
1308
|
+
* `<DesignSystemProvider lightTheme={...} darkTheme={...}>`.
|
|
1309
|
+
*/
|
|
1310
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
|
1311
|
+
export interface AppThemeColors {}
|
|
1312
|
+
|
|
1313
|
+
/**
|
|
1314
|
+
* Build a Restyle theme entirely from scratch.
|
|
1315
|
+
*
|
|
1316
|
+
* Use this when you want to define every color yourself with no defaults merged in.
|
|
1317
|
+
* Provide a complete SemanticColors object (same shape as lightSemanticColors /
|
|
1318
|
+
* darkSemanticColors) and get back a fully configured RestyleTheme.
|
|
1319
|
+
*
|
|
1320
|
+
* @example
|
|
1321
|
+
* const myLight = buildRestyleTheme({ background: { primary: '#fff', ... }, ... });
|
|
1322
|
+
*/
|
|
1323
|
+
export function buildRestyleTheme(
|
|
1324
|
+
colors: SemanticColorsInput,
|
|
1325
|
+
): typeof restyleLightTheme {
|
|
1326
|
+
return createTheme(createBaseThemeConfig(flattenColors(colors)));
|
|
1327
|
+
}
|
|
1328
|
+
|
|
1329
|
+
/**
|
|
1330
|
+
* Build a Restyle theme from ThemeColors overrides.
|
|
1331
|
+
* Merges overrides into the base semantic colors, keeping base primitives intact.
|
|
1332
|
+
*/
|
|
1333
|
+
export function buildRestyleThemeFromThemeColors(
|
|
1334
|
+
baseSemanticColors: SemanticColorsInput,
|
|
1335
|
+
overrides: DeepPartial<ThemeColors>,
|
|
1336
|
+
): typeof restyleLightTheme {
|
|
1337
|
+
const merged = {
|
|
1338
|
+
...baseSemanticColors,
|
|
1339
|
+
background: { ...baseSemanticColors.background, ...overrides.background },
|
|
1340
|
+
surface: { ...baseSemanticColors.surface, ...overrides.surface },
|
|
1341
|
+
text: { ...baseSemanticColors.text, ...overrides.text },
|
|
1342
|
+
border: { ...baseSemanticColors.border, ...overrides.border },
|
|
1343
|
+
accent: { ...baseSemanticColors.accent, ...overrides.accent },
|
|
1344
|
+
interactive: {
|
|
1345
|
+
...baseSemanticColors.interactive,
|
|
1346
|
+
...overrides.interactive,
|
|
1347
|
+
},
|
|
1348
|
+
feedback: { ...baseSemanticColors.feedback, ...overrides.feedback },
|
|
1349
|
+
special: { ...baseSemanticColors.special, ...overrides.special },
|
|
1350
|
+
};
|
|
1351
|
+
return createTheme(createBaseThemeConfig(flattenColors(merged)));
|
|
1352
|
+
}
|