@idealyst/components 1.1.6 → 1.1.8

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 (144) hide show
  1. package/package.json +8 -3
  2. package/src/Accordion/Accordion.native.tsx +22 -14
  3. package/src/Accordion/Accordion.styles.old.tsx +298 -0
  4. package/src/Accordion/Accordion.styles.tsx +139 -248
  5. package/src/Accordion/Accordion.web.tsx +12 -7
  6. package/src/ActivityIndicator/ActivityIndicator.native.tsx +3 -2
  7. package/src/ActivityIndicator/ActivityIndicator.styles.old.tsx +94 -0
  8. package/src/ActivityIndicator/ActivityIndicator.styles.tsx +43 -62
  9. package/src/ActivityIndicator/ActivityIndicator.web.tsx +2 -2
  10. package/src/Alert/Alert.native.tsx +26 -15
  11. package/src/Alert/Alert.styles.old.tsx +209 -0
  12. package/src/Alert/Alert.styles.tsx +108 -281
  13. package/src/Alert/Alert.web.tsx +6 -10
  14. package/src/Avatar/Avatar.native.tsx +5 -2
  15. package/src/Avatar/Avatar.styles.old.tsx +99 -0
  16. package/src/Avatar/Avatar.styles.tsx +47 -62
  17. package/src/Avatar/Avatar.web.tsx +2 -2
  18. package/src/Badge/Badge.native.tsx +2 -2
  19. package/src/Badge/Badge.styles.old.tsx +157 -0
  20. package/src/Badge/Badge.styles.tsx +69 -108
  21. package/src/Badge/Badge.web.tsx +6 -6
  22. package/src/Breadcrumb/Breadcrumb.native.tsx +12 -5
  23. package/src/Breadcrumb/Breadcrumb.styles.old.tsx +231 -0
  24. package/src/Breadcrumb/Breadcrumb.styles.tsx +93 -209
  25. package/src/Breadcrumb/Breadcrumb.web.tsx +39 -27
  26. package/src/Button/Button.native.tsx +39 -14
  27. package/src/Button/Button.styles.tsx +99 -253
  28. package/src/Button/Button.web.tsx +10 -8
  29. package/src/Card/Card.native.tsx +8 -4
  30. package/src/Card/Card.styles.old.tsx +160 -0
  31. package/src/Card/Card.styles.tsx +107 -142
  32. package/src/Card/Card.web.tsx +6 -4
  33. package/src/Checkbox/Checkbox.native.tsx +14 -6
  34. package/src/Checkbox/Checkbox.styles.old.tsx +271 -0
  35. package/src/Checkbox/Checkbox.styles.tsx +109 -197
  36. package/src/Checkbox/Checkbox.web.tsx +7 -7
  37. package/src/Chip/Chip.native.tsx +5 -5
  38. package/src/Chip/Chip.styles.old.tsx +184 -0
  39. package/src/Chip/Chip.styles.tsx +34 -22
  40. package/src/Chip/Chip.web.tsx +5 -5
  41. package/src/Dialog/Dialog.native.tsx +16 -7
  42. package/src/Dialog/Dialog.styles.old.tsx +202 -0
  43. package/src/Dialog/Dialog.styles.tsx +108 -132
  44. package/src/Dialog/Dialog.web.tsx +4 -4
  45. package/src/Divider/Divider.native.tsx +29 -42
  46. package/src/Divider/Divider.styles.old.tsx +172 -0
  47. package/src/Divider/Divider.styles.tsx +116 -242
  48. package/src/Divider/Divider.web.tsx +17 -14
  49. package/src/Icon/Icon.native.tsx +12 -4
  50. package/src/Icon/Icon.styles.old.tsx +81 -0
  51. package/src/Icon/Icon.styles.tsx +52 -60
  52. package/src/Icon/Icon.web.tsx +43 -7
  53. package/src/Icon/IconSvg/IconSvg.web.tsx +2 -0
  54. package/src/Image/Image.styles.old.tsx +69 -0
  55. package/src/Image/Image.styles.tsx +45 -43
  56. package/src/Input/Input.native.tsx +140 -56
  57. package/src/Input/Input.styles.old.tsx +289 -0
  58. package/src/Input/Input.styles.tsx +177 -228
  59. package/src/Input/Input.web.tsx +5 -8
  60. package/src/Link/Link.native.tsx +4 -1
  61. package/src/List/List.native.tsx +5 -2
  62. package/src/List/List.styles.old.tsx +242 -0
  63. package/src/List/List.styles.tsx +178 -240
  64. package/src/List/ListItem.native.tsx +16 -8
  65. package/src/List/ListItem.web.tsx +26 -15
  66. package/src/Menu/Menu.native.tsx +1 -1
  67. package/src/Menu/Menu.styles.old.tsx +197 -0
  68. package/src/Menu/Menu.styles.tsx +90 -156
  69. package/src/Menu/Menu.web.tsx +2 -2
  70. package/src/Menu/MenuItem.native.tsx +9 -5
  71. package/src/Menu/MenuItem.styles.old.tsx +114 -0
  72. package/src/Menu/MenuItem.styles.tsx +71 -104
  73. package/src/Menu/MenuItem.web.tsx +23 -5
  74. package/src/Popover/Popover.native.tsx +10 -4
  75. package/src/Popover/Popover.styles.old.tsx +135 -0
  76. package/src/Popover/Popover.styles.tsx +46 -96
  77. package/src/Popover/Popover.web.tsx +1 -1
  78. package/src/Pressable/Pressable.native.tsx +3 -1
  79. package/src/Pressable/Pressable.styles.old.tsx +27 -0
  80. package/src/Pressable/Pressable.styles.tsx +35 -20
  81. package/src/Pressable/Pressable.web.tsx +1 -1
  82. package/src/Progress/Progress.native.tsx +15 -6
  83. package/src/Progress/Progress.styles.old.tsx +200 -0
  84. package/src/Progress/Progress.styles.tsx +69 -118
  85. package/src/Progress/Progress.web.tsx +10 -9
  86. package/src/RadioButton/RadioButton.native.tsx +10 -4
  87. package/src/RadioButton/RadioButton.styles.old.tsx +175 -0
  88. package/src/RadioButton/RadioButton.styles.tsx +81 -145
  89. package/src/RadioButton/RadioButton.web.tsx +4 -4
  90. package/src/SVGImage/SVGImage.styles.old.tsx +86 -0
  91. package/src/SVGImage/SVGImage.styles.tsx +35 -66
  92. package/src/Screen/Screen.native.tsx +30 -27
  93. package/src/Screen/Screen.styles.old.tsx +87 -0
  94. package/src/Screen/Screen.styles.tsx +120 -71
  95. package/src/Screen/Screen.web.tsx +2 -2
  96. package/src/Select/Select.native.tsx +44 -29
  97. package/src/Select/Select.styles.old.tsx +353 -0
  98. package/src/Select/Select.styles.tsx +244 -293
  99. package/src/Select/Select.web.tsx +5 -5
  100. package/src/Skeleton/Skeleton.styles.old.tsx +67 -0
  101. package/src/Skeleton/Skeleton.styles.tsx +31 -43
  102. package/src/Slider/Slider.native.tsx +9 -5
  103. package/src/Slider/Slider.styles.old.tsx +259 -0
  104. package/src/Slider/Slider.styles.tsx +157 -227
  105. package/src/Slider/Slider.web.tsx +5 -5
  106. package/src/Switch/Switch.native.tsx +11 -5
  107. package/src/Switch/Switch.styles.old.tsx +203 -0
  108. package/src/Switch/Switch.styles.tsx +103 -149
  109. package/src/Switch/Switch.web.tsx +8 -8
  110. package/src/TabBar/TabBar.native.tsx +24 -31
  111. package/src/TabBar/TabBar.styles.old.tsx +343 -0
  112. package/src/TabBar/TabBar.styles.tsx +204 -494
  113. package/src/TabBar/TabBar.web.tsx +21 -33
  114. package/src/Table/Table.native.tsx +18 -9
  115. package/src/Table/Table.styles.old.tsx +311 -0
  116. package/src/Table/Table.styles.tsx +151 -278
  117. package/src/Table/Table.web.tsx +1 -1
  118. package/src/Text/Text.native.tsx +1 -4
  119. package/src/Text/Text.style.demo.tsx +16 -0
  120. package/src/Text/Text.styles.old.tsx +219 -0
  121. package/src/Text/Text.styles.tsx +94 -78
  122. package/src/Text/Text.web.tsx +2 -2
  123. package/src/Text/index.ts +1 -0
  124. package/src/TextArea/TextArea.styles.old.tsx +213 -0
  125. package/src/TextArea/TextArea.styles.tsx +101 -157
  126. package/src/Tooltip/Tooltip.native.tsx +2 -2
  127. package/src/Tooltip/Tooltip.styles.old.tsx +82 -0
  128. package/src/Tooltip/Tooltip.styles.tsx +38 -53
  129. package/src/Tooltip/Tooltip.web.tsx +2 -2
  130. package/src/Video/Video.styles.old.tsx +51 -0
  131. package/src/Video/Video.styles.tsx +32 -28
  132. package/src/View/View.native.tsx +12 -12
  133. package/src/View/View.styles.old.tsx +125 -0
  134. package/src/View/View.styles.tsx +84 -103
  135. package/src/View/View.web.tsx +14 -2
  136. package/src/examples/CardExamples.tsx +0 -6
  137. package/src/extensions/applyExtension.ts +210 -0
  138. package/src/extensions/extendComponent.ts +438 -0
  139. package/src/extensions/index.ts +102 -0
  140. package/src/extensions/types.ts +497 -0
  141. package/src/globals.ts +16 -0
  142. package/src/index.native.ts +4 -0
  143. package/src/index.ts +28 -0
  144. package/src/utils/deepMerge.ts +54 -2
@@ -1,158 +1,123 @@
1
+ /**
2
+ * Card styles using defineStyle with $iterator expansion.
3
+ */
1
4
  import { StyleSheet } from 'react-native-unistyles';
2
- import { Theme, Intent, CompoundVariants } from '@idealyst/theme';
3
- import {
4
- buildGapVariants,
5
- buildPaddingVariants,
6
- buildPaddingVerticalVariants,
7
- buildPaddingHorizontalVariants,
8
- buildMarginVariants,
9
- buildMarginVerticalVariants,
10
- buildMarginHorizontalVariants,
11
- } from '../utils/buildViewStyleVariants';
5
+ import { defineStyle, ThemeStyleWrapper } from '@idealyst/theme';
6
+ import type { Theme as BaseTheme, Intent, Radius } from '@idealyst/theme';
12
7
  import { ViewStyleSize } from '../utils/viewStyleProps';
13
8
 
9
+ // Required: Unistyles must see StyleSheet usage in original source to process this file
10
+ void StyleSheet;
11
+
12
+ // Wrap theme for $iterator support
13
+ type Theme = ThemeStyleWrapper<BaseTheme>;
14
+
14
15
  type CardType = 'outlined' | 'elevated' | 'filled';
15
- type CardRadius = 'none' | 'sm' | 'md' | 'lg' | 'xs' | 'xl';
16
16
  type CardIntent = Intent | 'info' | 'neutral';
17
17
 
18
18
  export type CardVariants = {
19
- type: CardType;
20
- radius: CardRadius;
21
- intent: CardIntent;
22
- clickable: boolean;
23
- disabled: boolean;
24
- // Spacing variants from ContainerStyleProps
25
- gap: ViewStyleSize;
26
- padding: ViewStyleSize;
27
- paddingVertical: ViewStyleSize;
28
- paddingHorizontal: ViewStyleSize;
29
- margin: ViewStyleSize;
30
- marginVertical: ViewStyleSize;
31
- marginHorizontal: ViewStyleSize;
19
+ type: CardType;
20
+ radius: Radius;
21
+ intent: CardIntent;
22
+ clickable: boolean;
23
+ disabled: boolean;
24
+ gap: ViewStyleSize;
25
+ padding: ViewStyleSize;
26
+ paddingVertical: ViewStyleSize;
27
+ paddingHorizontal: ViewStyleSize;
28
+ margin: ViewStyleSize;
29
+ marginVertical: ViewStyleSize;
30
+ marginHorizontal: ViewStyleSize;
32
31
  };
33
32
 
34
- /**
35
- * Create type variants (structure only, colors handled by compound variants)
36
- */
37
- function createTypeVariants(theme: Theme) {
38
- return {
39
- outlined: {
40
- backgroundColor: 'transparent',
41
- borderWidth: 1,
42
- borderStyle: 'solid' as const,
43
- },
44
- elevated: {
45
- backgroundColor: theme.colors.surface.primary,
46
- borderWidth: 0,
47
- ...theme.shadows.md,
48
- },
49
- filled: {
50
- backgroundColor: theme.colors.surface.secondary,
51
- borderWidth: 0,
52
- },
53
- } as const;
54
- }
33
+ export type CardDynamicProps = {
34
+ intent?: CardIntent;
35
+ type?: CardType;
36
+ };
55
37
 
56
38
  /**
57
- * Create compound variants for type + intent combinations
39
+ * Card styles with dynamic type/intent handling.
40
+ *
41
+ * NOTE: Top-level theme access required for Unistyles reactivity.
58
42
  */
59
- function createCardCompoundVariants(theme: Theme) {
60
- const compoundVariants: CompoundVariants<keyof CardVariants> = [];
61
-
62
- // Add intent-based border colors for outlined type
63
- for (const intent in theme.intents) {
64
- const intentValue = theme.intents[intent as Intent];
65
-
66
- compoundVariants.push({
67
- intent,
68
- type: 'outlined',
69
- styles: {
70
- borderColor: intentValue.primary,
71
- },
72
- });
73
- }
74
-
75
- // Add special intents (info, neutral) for outlined type
76
- compoundVariants.push({
77
- intent: 'info',
78
- type: 'outlined',
79
- styles: {
80
- borderColor: theme.colors.border.secondary,
81
- },
82
- });
83
- compoundVariants.push({
84
- intent: 'neutral',
85
- type: 'outlined',
86
- styles: {
87
- borderColor: theme.colors.border.secondary,
88
- },
89
- });
90
-
91
- return compoundVariants;
92
- }
93
-
94
- // Styles are inlined here instead of in @idealyst/theme because Unistyles' Babel
95
- // transform on native cannot resolve function calls to extract variant structures.
96
- export const cardStyles = StyleSheet.create((theme: Theme) => {
97
- return {
98
- card: {
99
- backgroundColor: theme.colors.surface.primary,
100
- position: 'relative',
101
- overflow: 'hidden',
102
- variants: {
103
- type: createTypeVariants(theme),
104
- radius: {
105
- none: { borderRadius: 0 },
106
- xs: { borderRadius: 2 },
107
- sm: { borderRadius: 4 },
108
- md: { borderRadius: 8 },
109
- lg: { borderRadius: 12 },
110
- xl: { borderRadius: 16 },
111
- },
112
- clickable: {
113
- true: {
114
- _web: {
115
- cursor: 'pointer',
116
- transition: 'all 0.2s ease',
117
- _hover: {
118
- transform: 'translateY(-2px)',
119
- boxShadow:
120
- '0 4px 12px rgba(0, 0, 0, 0.08), 0 2px 4px rgba(0, 0, 0, 0.06)',
121
- },
43
+ export const cardStyles = defineStyle('Card', (theme: Theme) => ({
44
+ card: (_props: CardDynamicProps) => ({
45
+ position: 'relative' as const,
46
+ overflow: 'hidden' as const,
47
+ // Theme marker for Unistyles reactivity
48
+ backgroundColor: theme.colors.surface.primary,
49
+ borderColor: theme.colors.border.secondary,
50
+ variants: {
51
+ type: {
52
+ outlined: {
53
+ backgroundColor: 'transparent',
54
+ borderWidth: 1,
55
+ borderStyle: 'solid' as const,
56
+ },
57
+ elevated: {
58
+ backgroundColor: theme.colors.surface.primary,
59
+ borderWidth: 0,
60
+ ...theme.shadows.md,
61
+ },
62
+ filled: {
63
+ backgroundColor: theme.colors.surface.secondary,
64
+ borderWidth: 0,
65
+ },
122
66
  },
123
- },
124
- false: {
125
- _web: {
126
- cursor: 'default',
67
+ radius: {
68
+ none: { borderRadius: 0 },
69
+ xs: { borderRadius: 2 },
70
+ sm: { borderRadius: 4 },
71
+ md: { borderRadius: 8 },
72
+ lg: { borderRadius: 12 },
73
+ xl: { borderRadius: 16 },
74
+ },
75
+ clickable: {
76
+ true: {
77
+ _web: {
78
+ cursor: 'pointer',
79
+ transition: 'all 0.2s ease',
80
+ _hover: {
81
+ transform: 'translateY(-2px)',
82
+ boxShadow: '0 4px 12px rgba(0, 0, 0, 0.08), 0 2px 4px rgba(0, 0, 0, 0.06)',
83
+ },
84
+ },
85
+ },
86
+ false: {
87
+ _web: { cursor: 'default' },
88
+ },
89
+ },
90
+ disabled: {
91
+ true: { opacity: 0.6, _web: { cursor: 'not-allowed' } },
92
+ false: { opacity: 1 },
93
+ },
94
+ // $iterator expands for each view size
95
+ gap: {
96
+ gap: theme.sizes.$view.spacing,
97
+ },
98
+ padding: {
99
+ padding: theme.sizes.$view.padding,
100
+ },
101
+ paddingVertical: {
102
+ paddingVertical: theme.sizes.$view.padding,
103
+ },
104
+ paddingHorizontal: {
105
+ paddingHorizontal: theme.sizes.$view.padding,
106
+ },
107
+ margin: {
108
+ margin: theme.sizes.$view.padding,
109
+ },
110
+ marginVertical: {
111
+ marginVertical: theme.sizes.$view.padding,
112
+ },
113
+ marginHorizontal: {
114
+ marginHorizontal: theme.sizes.$view.padding,
115
+ },
127
116
  },
128
- },
129
- },
130
- disabled: {
131
- true: {
132
- opacity: 0.6,
133
117
  _web: {
134
- cursor: 'not-allowed',
118
+ display: 'flex',
119
+ flexDirection: 'column',
120
+ boxSizing: 'border-box',
135
121
  },
136
- },
137
- false: {
138
- opacity: 1,
139
- },
140
- },
141
- // Spacing variants from ContainerStyleProps
142
- gap: buildGapVariants(theme),
143
- padding: buildPaddingVariants(theme),
144
- paddingVertical: buildPaddingVerticalVariants(theme),
145
- paddingHorizontal: buildPaddingHorizontalVariants(theme),
146
- margin: buildMarginVariants(theme),
147
- marginVertical: buildMarginVerticalVariants(theme),
148
- marginHorizontal: buildMarginHorizontalVariants(theme),
149
- },
150
- compoundVariants: createCardCompoundVariants(theme),
151
- _web: {
152
- display: 'flex',
153
- flexDirection: 'column',
154
- boxSizing: 'border-box',
155
- },
156
- } as const,
157
- };
158
- });
122
+ }),
123
+ }));
@@ -51,10 +51,9 @@ const Card = forwardRef<HTMLDivElement | HTMLButtonElement, CardProps>(({
51
51
 
52
52
  // Apply variants
53
53
  cardStyles.useVariants({
54
- clickable,
55
- radius,
56
54
  type,
57
- intent,
55
+ radius,
56
+ clickable,
58
57
  disabled,
59
58
  gap,
60
59
  padding,
@@ -65,8 +64,11 @@ const Card = forwardRef<HTMLDivElement | HTMLButtonElement, CardProps>(({
65
64
  marginHorizontal,
66
65
  });
67
66
 
67
+ // Get card style
68
+ const cardStyle = (cardStyles.card as any)({});
69
+
68
70
  // Generate web props
69
- const webProps = getWebProps([cardStyles.card, style as any]);
71
+ const webProps = getWebProps([cardStyle, style as any]);
70
72
 
71
73
  const mergedRef = useMergeRefs(ref, webProps.ref);
72
74
 
@@ -99,33 +99,41 @@ const Checkbox = forwardRef<View, CheckboxProps>(({
99
99
  const labelContent = children || label;
100
100
  const displayHelperText = error || helperText;
101
101
 
102
+ // Get dynamic styles - call as functions for theme reactivity
103
+ const wrapperStyle = (checkboxStyles.wrapper as any)({});
104
+ const containerStyle = (checkboxStyles.container as any)({});
105
+ const checkboxStyle = (checkboxStyles.checkbox as any)({ intent, checked: internalChecked, disabled, type: variant });
106
+ const checkmarkStyle = (checkboxStyles.checkmark as any)({ checked: internalChecked });
107
+ const labelStyle = (checkboxStyles.label as any)({ disabled });
108
+ const helperTextStyle = (checkboxStyles.helperText as any)({ error: !!error });
109
+
102
110
  return (
103
- <View ref={ref} nativeID={id} style={[checkboxStyles.wrapper, style]}>
111
+ <View ref={ref} nativeID={id} style={[wrapperStyle, style]}>
104
112
  <Pressable
105
113
  onPress={handlePress}
106
114
  disabled={disabled}
107
115
  testID={testID}
108
116
  {...nativeA11yProps}
109
- style={checkboxStyles.container}
117
+ style={containerStyle}
110
118
  >
111
- <View style={checkboxStyles.checkbox({ intent })}>
119
+ <View style={checkboxStyle}>
112
120
  {(internalChecked || indeterminate) && (
113
121
  <MaterialCommunityIcons
114
122
  name={indeterminate ? 'minus' : 'check'}
115
123
  size={14}
116
124
  color="#ffffff"
117
- style={checkboxStyles.checkmark}
125
+ style={checkmarkStyle}
118
126
  />
119
127
  )}
120
128
  </View>
121
129
  {labelContent && (
122
- <Text style={checkboxStyles.label}>
130
+ <Text style={labelStyle}>
123
131
  {labelContent}
124
132
  </Text>
125
133
  )}
126
134
  </Pressable>
127
135
  {displayHelperText && (
128
- <Text style={checkboxStyles.helperText}>
136
+ <Text style={helperTextStyle}>
129
137
  {error || helperText}
130
138
  </Text>
131
139
  )}
@@ -0,0 +1,271 @@
1
+ import { StyleSheet } from 'react-native-unistyles';
2
+ import { Theme, StylesheetStyles, Intent, Size } from '@idealyst/theme';
3
+ import {
4
+ buildMarginVariants,
5
+ buildMarginVerticalVariants,
6
+ buildMarginHorizontalVariants,
7
+ } from '../utils/buildViewStyleVariants';
8
+ import { applyExtensions } from '../extensions/applyExtension';
9
+
10
+ type CheckboxSize = Size;
11
+ type CheckboxIntent = Intent | 'info';
12
+ type CheckboxType = 'default' | 'outlined';
13
+
14
+ type CheckboxVariants = {
15
+ size: CheckboxSize;
16
+ intent: CheckboxIntent;
17
+ type: CheckboxType;
18
+ checked: boolean;
19
+ disabled: boolean;
20
+ visible: boolean;
21
+ error: boolean;
22
+ }
23
+
24
+ export type ExpandedCheckboxStyles = StylesheetStyles<keyof CheckboxVariants>;
25
+
26
+ export type CheckboxStylesheet = {
27
+ wrapper: ExpandedCheckboxStyles;
28
+ container: ExpandedCheckboxStyles;
29
+ checkbox: ExpandedCheckboxStyles;
30
+ label: ExpandedCheckboxStyles;
31
+ checkmark: ExpandedCheckboxStyles;
32
+ helperText: ExpandedCheckboxStyles;
33
+ }
34
+
35
+ /**
36
+ * Helper to get intent colors, mapping 'info' to 'primary'
37
+ */
38
+ function getIntentColors(theme: Theme, intent: CheckboxIntent) {
39
+ const actualIntent = intent === 'info' ? 'primary' : intent;
40
+ return theme.intents[actualIntent as Intent];
41
+ }
42
+
43
+ /**
44
+ * Create size variants for checkbox
45
+ */
46
+ function createCheckboxSizeVariants() {
47
+ return {
48
+ xs: { width: 14, height: 14 },
49
+ sm: { width: 16, height: 16 },
50
+ md: { width: 20, height: 20 },
51
+ lg: { width: 24, height: 24 },
52
+ xl: { width: 28, height: 28 },
53
+ } as const;
54
+ }
55
+
56
+ /**
57
+ * Create type variants for checkbox
58
+ */
59
+ function createCheckboxTypeVariants(theme: Theme) {
60
+ return {
61
+ default: {
62
+ borderWidth: 1,
63
+ borderColor: theme.colors.border.primary,
64
+ _web: {
65
+ border: `1px solid ${theme.colors.border.primary}`,
66
+ },
67
+ },
68
+ outlined: {
69
+ borderWidth: 2,
70
+ borderColor: theme.colors.border.primary,
71
+ _web: {
72
+ border: `2px solid ${theme.colors.border.primary}`,
73
+ },
74
+ },
75
+ } as const;
76
+ }
77
+
78
+ /**
79
+ * Create checked state variants dynamically based on intent
80
+ */
81
+ function createCheckedVariants(theme: Theme, intent: CheckboxIntent) {
82
+ const colors = getIntentColors(theme, intent);
83
+
84
+ return {
85
+ true: {
86
+ backgroundColor: colors.primary,
87
+ borderColor: colors.primary,
88
+ _web: {
89
+ border: `1px solid ${colors.primary}`,
90
+ },
91
+ },
92
+ false: {
93
+ backgroundColor: 'transparent',
94
+ },
95
+ } as const;
96
+ }
97
+
98
+ /**
99
+ * Create size variants for label
100
+ */
101
+ function createLabelSizeVariants() {
102
+ return {
103
+ xs: { fontSize: 12 },
104
+ sm: { fontSize: 14 },
105
+ md: { fontSize: 16 },
106
+ lg: { fontSize: 18 },
107
+ xl: { fontSize: 20 },
108
+ } as const;
109
+ }
110
+
111
+ /**
112
+ * Create size variants for checkmark
113
+ */
114
+ function createCheckmarkSizeVariants() {
115
+ return {
116
+ xs: { width: 10, height: 10 },
117
+ sm: { width: 12, height: 12 },
118
+ md: { width: 14, height: 14 },
119
+ lg: { width: 16, height: 16 },
120
+ xl: { width: 20, height: 20 },
121
+ } as const;
122
+ }
123
+
124
+ function createCheckboxStyles(theme: Theme) {
125
+ return ({ intent }: Partial<CheckboxVariants>) => {
126
+ return {
127
+ alignItems: 'center',
128
+ justifyContent: 'center',
129
+ borderRadius: 4,
130
+ position: 'relative',
131
+ backgroundColor: 'transparent',
132
+ borderColor: theme.colors.border.primary,
133
+ variants: {
134
+ size: createCheckboxSizeVariants(),
135
+ type: createCheckboxTypeVariants(theme),
136
+ checked: createCheckedVariants(theme, intent),
137
+ disabled: {
138
+ true: {
139
+ opacity: 0.5,
140
+ _web: {
141
+ cursor: 'not-allowed',
142
+ },
143
+ },
144
+ false: {
145
+ opacity: 1,
146
+ _web: {
147
+ cursor: 'pointer',
148
+ _hover: { opacity: 0.8 },
149
+ _active: { opacity: 0.6 },
150
+ },
151
+ },
152
+ },
153
+ },
154
+ _web: {
155
+ outline: 'none',
156
+ display: 'flex',
157
+ boxSizing: 'border-box',
158
+ userSelect: 'none',
159
+ WebkitAppearance: 'none',
160
+ MozAppearance: 'none',
161
+ appearance: 'none',
162
+ transition: 'all 0.2s ease',
163
+ _focus: {
164
+ outline: `2px solid ${theme.intents.primary.primary}`,
165
+ outlineOffset: '2px',
166
+ },
167
+ },
168
+ } as const;
169
+ }
170
+ }
171
+
172
+ function createCheckmarkStyles(_theme: Theme) {
173
+ return () => ({
174
+ position: 'absolute' as const,
175
+ display: 'flex' as const,
176
+ alignItems: 'center' as const,
177
+ justifyContent: 'center' as const,
178
+ color: '#ffffff',
179
+ variants: {
180
+ size: createCheckmarkSizeVariants(),
181
+ visible: {
182
+ true: { opacity: 1 },
183
+ false: { opacity: 0 },
184
+ },
185
+ },
186
+ });
187
+ }
188
+
189
+ // Helper functions to create static styles wrapped in dynamic functions
190
+ function createWrapperStyles(theme: Theme) {
191
+ return () => ({
192
+ flexDirection: 'column' as const,
193
+ gap: 4,
194
+ variants: {
195
+ // Spacing variants from FormInputStyleProps
196
+ margin: buildMarginVariants(theme),
197
+ marginVertical: buildMarginVerticalVariants(theme),
198
+ marginHorizontal: buildMarginHorizontalVariants(theme),
199
+ },
200
+ _web: {
201
+ display: 'flex',
202
+ flexDirection: 'column',
203
+ alignItems: 'flex-start',
204
+ width: 'auto',
205
+ },
206
+ });
207
+ }
208
+
209
+ function createContainerStyles() {
210
+ return () => ({
211
+ flexDirection: 'row' as const,
212
+ alignItems: 'center' as const,
213
+ gap: 8,
214
+ _web: {
215
+ display: 'flex',
216
+ flexDirection: 'row',
217
+ alignItems: 'center',
218
+ gap: 8,
219
+ width: 'fit-content',
220
+ cursor: 'pointer',
221
+ },
222
+ });
223
+ }
224
+
225
+ function createLabelStyles(theme: Theme) {
226
+ return () => ({
227
+ color: theme.colors.text.primary,
228
+ variants: {
229
+ size: createLabelSizeVariants(),
230
+ disabled: {
231
+ true: { opacity: 0.5 },
232
+ false: { opacity: 1 },
233
+ },
234
+ },
235
+ _web: {
236
+ display: 'block',
237
+ textAlign: 'left',
238
+ margin: 0,
239
+ padding: 0,
240
+ },
241
+ });
242
+ }
243
+
244
+ function createHelperTextStyles(theme: Theme) {
245
+ return () => ({
246
+ fontSize: 14,
247
+ color: theme.colors.text.secondary,
248
+ marginTop: 2,
249
+ variants: {
250
+ error: {
251
+ true: { color: theme.intents.error.primary },
252
+ false: { color: theme.colors.text.secondary },
253
+ },
254
+ },
255
+ });
256
+ }
257
+
258
+ // Styles are inlined here instead of in @idealyst/theme because Unistyles' Babel
259
+ // transform on native cannot resolve function calls to extract variant structures.
260
+ export const checkboxStyles = StyleSheet.create((theme: Theme) => {
261
+ // Apply extensions to main visual elements
262
+
263
+ return applyExtensions('Checkbox', theme, {container: createContainerStyles(),
264
+ checkbox: createCheckboxStyles(theme),
265
+ checkmark: createCheckmarkStyles(theme),
266
+ // Additional styles (merged from return)
267
+ // Minor utility styles (not extended)
268
+ wrapper: createWrapperStyles(theme)(),
269
+ label: createLabelStyles(theme)(),
270
+ helperText: createHelperTextStyles(theme)()});
271
+ });