@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,153 +1,99 @@
1
+ /**
2
+ * Checkbox styles using defineStyle with $iterator expansion.
3
+ */
1
4
  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
-
9
- type CheckboxSize = Size;
10
- type CheckboxIntent = Intent | 'info';
11
- type CheckboxType = 'default' | 'outlined';
12
-
13
- type CheckboxVariants = {
14
- size: CheckboxSize;
15
- intent: CheckboxIntent;
16
- type: CheckboxType;
17
- checked: boolean;
18
- disabled: boolean;
19
- visible: boolean;
20
- error: boolean;
21
- }
5
+ import { defineStyle, ThemeStyleWrapper } from '@idealyst/theme';
6
+ import type { Theme as BaseTheme, Intent, Size } from '@idealyst/theme';
7
+ import { ViewStyleSize } from '../utils/viewStyleProps';
22
8
 
23
- export type ExpandedCheckboxStyles = StylesheetStyles<keyof CheckboxVariants>;
9
+ // Required: Unistyles must see StyleSheet usage in original source to process this file
10
+ void StyleSheet;
24
11
 
25
- export type CheckboxStylesheet = {
26
- wrapper: ExpandedCheckboxStyles;
27
- container: ExpandedCheckboxStyles;
28
- checkbox: ExpandedCheckboxStyles;
29
- label: ExpandedCheckboxStyles;
30
- checkmark: ExpandedCheckboxStyles;
31
- helperText: ExpandedCheckboxStyles;
32
- }
12
+ // Wrap theme for $iterator support
13
+ type Theme = ThemeStyleWrapper<BaseTheme>;
33
14
 
34
- /**
35
- * Helper to get intent colors, mapping 'info' to 'primary'
36
- */
37
- function getIntentColors(theme: Theme, intent: CheckboxIntent) {
38
- const actualIntent = intent === 'info' ? 'primary' : intent;
39
- return theme.intents[actualIntent as Intent];
40
- }
15
+ type CheckboxType = 'default' | 'outlined';
41
16
 
42
- /**
43
- * Create size variants for checkbox
44
- */
45
- function createCheckboxSizeVariants() {
46
- return {
47
- xs: { width: 14, height: 14 },
48
- sm: { width: 16, height: 16 },
49
- md: { width: 20, height: 20 },
50
- lg: { width: 24, height: 24 },
51
- xl: { width: 28, height: 28 },
52
- } as const;
53
- }
17
+ export type CheckboxDynamicProps = {
18
+ size?: Size;
19
+ intent?: Intent;
20
+ type?: CheckboxType;
21
+ checked?: boolean;
22
+ disabled?: boolean;
23
+ visible?: boolean;
24
+ error?: boolean;
25
+ margin?: ViewStyleSize;
26
+ marginVertical?: ViewStyleSize;
27
+ marginHorizontal?: ViewStyleSize;
28
+ };
54
29
 
55
30
  /**
56
- * Create type variants for checkbox
31
+ * Checkbox styles with intent/type/checked handling.
57
32
  */
58
- function createCheckboxTypeVariants(theme: Theme) {
59
- return {
60
- default: {
61
- borderWidth: 1,
62
- borderColor: theme.colors.border.primary,
63
- _web: {
64
- border: `1px solid ${theme.colors.border.primary}`,
33
+ export const checkboxStyles = defineStyle('Checkbox', (theme: Theme) => ({
34
+ wrapper: (_props: CheckboxDynamicProps) => ({
35
+ flexDirection: 'column' as const,
36
+ gap: 4,
37
+ variants: {
38
+ margin: {
39
+ margin: theme.sizes.$view.padding,
65
40
  },
66
- },
67
- outlined: {
68
- borderWidth: 2,
69
- borderColor: theme.colors.border.primary,
70
- _web: {
71
- border: `2px solid ${theme.colors.border.primary}`,
41
+ marginVertical: {
42
+ marginVertical: theme.sizes.$view.padding,
72
43
  },
73
- },
74
- } as const;
75
- }
76
-
77
- /**
78
- * Create checked state variants dynamically based on intent
79
- */
80
- function createCheckedVariants(theme: Theme, intent: CheckboxIntent) {
81
- const colors = getIntentColors(theme, intent);
82
-
83
- return {
84
- true: {
85
- backgroundColor: colors.primary,
86
- borderColor: colors.primary,
87
- _web: {
88
- border: `1px solid ${colors.primary}`,
44
+ marginHorizontal: {
45
+ marginHorizontal: theme.sizes.$view.padding,
89
46
  },
90
47
  },
91
- false: {
92
- backgroundColor: 'transparent',
48
+ _web: {
49
+ display: 'flex',
50
+ flexDirection: 'column',
51
+ alignItems: 'flex-start',
52
+ width: 'auto',
93
53
  },
94
- } as const;
95
- }
54
+ }),
96
55
 
97
- /**
98
- * Create size variants for label
99
- */
100
- function createLabelSizeVariants() {
101
- return {
102
- xs: { fontSize: 12 },
103
- sm: { fontSize: 14 },
104
- md: { fontSize: 16 },
105
- lg: { fontSize: 18 },
106
- xl: { fontSize: 20 },
107
- } as const;
108
- }
56
+ container: (_props: CheckboxDynamicProps) => ({
57
+ flexDirection: 'row' as const,
58
+ alignItems: 'center' as const,
59
+ gap: 8,
60
+ _web: {
61
+ display: 'flex',
62
+ flexDirection: 'row',
63
+ alignItems: 'center',
64
+ gap: 8,
65
+ width: 'fit-content',
66
+ cursor: 'pointer',
67
+ },
68
+ }),
109
69
 
110
- /**
111
- * Create size variants for checkmark
112
- */
113
- function createCheckmarkSizeVariants() {
114
- return {
115
- xs: { width: 10, height: 10 },
116
- sm: { width: 12, height: 12 },
117
- md: { width: 14, height: 14 },
118
- lg: { width: 16, height: 16 },
119
- xl: { width: 20, height: 20 },
120
- } as const;
121
- }
70
+ checkbox: ({ intent = 'primary', type = 'default', checked = false, disabled = false }: CheckboxDynamicProps) => {
71
+ const intentColors = theme.intents[intent];
72
+
73
+ // Base border styles based on type
74
+ const borderWidth = type === 'outlined' ? 2 : 1;
75
+
76
+ // Checked state colors
77
+ const backgroundColor = checked ? intentColors.primary : 'transparent';
78
+ const borderColor = checked ? intentColors.primary : theme.colors.border.primary;
122
79
 
123
- function createCheckboxStyles(theme: Theme) {
124
- return ({ intent }: Partial<CheckboxVariants>) => {
125
80
  return {
126
- alignItems: 'center',
127
- justifyContent: 'center',
81
+ alignItems: 'center' as const,
82
+ justifyContent: 'center' as const,
128
83
  borderRadius: 4,
129
- position: 'relative',
130
- backgroundColor: 'transparent',
131
- borderColor: theme.colors.border.primary,
84
+ position: 'relative' as const,
85
+ backgroundColor,
86
+ borderColor,
87
+ borderWidth,
88
+ borderStyle: 'solid' as const,
89
+ opacity: disabled ? 0.5 : 1,
132
90
  variants: {
133
- size: createCheckboxSizeVariants(),
134
- type: createCheckboxTypeVariants(theme),
135
- checked: createCheckedVariants(theme, intent),
136
- disabled: {
137
- true: {
138
- opacity: 0.5,
139
- _web: {
140
- cursor: 'not-allowed',
141
- },
142
- },
143
- false: {
144
- opacity: 1,
145
- _web: {
146
- cursor: 'pointer',
147
- _hover: { opacity: 0.8 },
148
- _active: { opacity: 0.6 },
149
- },
150
- },
91
+ size: {
92
+ xs: { width: 14, height: 14 },
93
+ sm: { width: 16, height: 16 },
94
+ md: { width: 20, height: 20 },
95
+ lg: { width: 24, height: 24 },
96
+ xl: { width: 28, height: 28 },
151
97
  },
152
98
  },
153
99
  _web: {
@@ -159,73 +105,46 @@ function createCheckboxStyles(theme: Theme) {
159
105
  MozAppearance: 'none',
160
106
  appearance: 'none',
161
107
  transition: 'all 0.2s ease',
108
+ cursor: disabled ? 'not-allowed' : 'pointer',
109
+ border: `${borderWidth}px solid ${borderColor}`,
162
110
  _focus: {
163
111
  outline: `2px solid ${theme.intents.primary.primary}`,
164
112
  outlineOffset: '2px',
165
113
  },
114
+ _hover: disabled ? {} : { opacity: 0.8 },
115
+ _active: disabled ? {} : { opacity: 0.6 },
166
116
  },
167
117
  } as const;
168
- }
169
- }
118
+ },
170
119
 
171
- function createCheckmarkStyles(_theme: Theme) {
172
- return {
173
- position: 'absolute',
174
- display: 'flex',
175
- alignItems: 'center',
176
- justifyContent: 'center',
120
+ checkmark: ({ checked = false }: CheckboxDynamicProps) => ({
121
+ position: 'absolute' as const,
122
+ display: 'flex' as const,
123
+ alignItems: 'center' as const,
124
+ justifyContent: 'center' as const,
177
125
  color: '#ffffff',
126
+ opacity: checked ? 1 : 0,
178
127
  variants: {
179
- size: createCheckmarkSizeVariants(),
180
- visible: {
181
- true: { opacity: 1 },
182
- false: { opacity: 0 },
128
+ size: {
129
+ xs: { width: 10, height: 10 },
130
+ sm: { width: 12, height: 12 },
131
+ md: { width: 14, height: 14 },
132
+ lg: { width: 16, height: 16 },
133
+ xl: { width: 20, height: 20 },
183
134
  },
184
135
  },
185
- } as const;
186
- }
136
+ }),
187
137
 
188
- // Styles are inlined here instead of in @idealyst/theme because Unistyles' Babel
189
- // transform on native cannot resolve function calls to extract variant structures.
190
- export const checkboxStyles = StyleSheet.create((theme: Theme) => {
191
- return {
192
- wrapper: {
193
- flexDirection: 'column',
194
- gap: 4,
195
- variants: {
196
- // Spacing variants from FormInputStyleProps
197
- margin: buildMarginVariants(theme),
198
- marginVertical: buildMarginVerticalVariants(theme),
199
- marginHorizontal: buildMarginHorizontalVariants(theme),
200
- },
201
- _web: {
202
- display: 'flex',
203
- flexDirection: 'column',
204
- alignItems: 'flex-start',
205
- width: 'auto',
206
- },
207
- },
208
- container: {
209
- flexDirection: 'row',
210
- alignItems: 'center',
211
- gap: 8,
212
- _web: {
213
- display: 'flex',
214
- flexDirection: 'row',
215
- alignItems: 'center',
216
- gap: 8,
217
- width: 'fit-content',
218
- cursor: 'pointer',
219
- },
220
- },
221
- checkbox: createCheckboxStyles(theme),
222
- label: {
138
+ label: ({ disabled = false }: CheckboxDynamicProps) => ({
223
139
  color: theme.colors.text.primary,
140
+ opacity: disabled ? 0.5 : 1,
224
141
  variants: {
225
- size: createLabelSizeVariants(),
226
- disabled: {
227
- true: { opacity: 0.5 },
228
- false: { opacity: 1 },
142
+ size: {
143
+ xs: { fontSize: 12 },
144
+ sm: { fontSize: 14 },
145
+ md: { fontSize: 16 },
146
+ lg: { fontSize: 18 },
147
+ xl: { fontSize: 20 },
229
148
  },
230
149
  },
231
150
  _web: {
@@ -234,18 +153,11 @@ export const checkboxStyles = StyleSheet.create((theme: Theme) => {
234
153
  margin: 0,
235
154
  padding: 0,
236
155
  },
237
- },
238
- checkmark: createCheckmarkStyles(theme),
239
- helperText: {
156
+ }),
157
+
158
+ helperText: ({ error = false }: CheckboxDynamicProps) => ({
240
159
  fontSize: 14,
241
- color: theme.colors.text.secondary,
160
+ color: error ? theme.intents.error.primary : theme.colors.text.secondary,
242
161
  marginTop: 2,
243
- variants: {
244
- error: {
245
- true: { color: theme.intents.error.primary },
246
- false: { color: theme.colors.text.secondary },
247
- },
248
- },
249
- },
250
- };
251
- });
162
+ }),
163
+ }));
@@ -124,13 +124,13 @@ const Checkbox = forwardRef<HTMLDivElement, CheckboxProps>(({
124
124
  marginHorizontal,
125
125
  });
126
126
 
127
- // Create style arrays
128
- const wrapperStyleArray = [checkboxStyles.wrapper, style as any];
129
- const containerStyleArray = [checkboxStyles.container];
130
- const checkboxStyleArray = [checkboxStyles.checkbox({ intent })];
131
- const labelStyleArray = [checkboxStyles.label];
132
- const helperTextStyleArray = [checkboxStyles.helperText];
133
- const checkmarkStyleArray = [checkboxStyles.checkmark];
127
+ // Create style arrays - call as functions with required props for theme reactivity
128
+ const wrapperStyleArray = [(checkboxStyles.wrapper as any)({}), style as any];
129
+ const containerStyleArray = [(checkboxStyles.container as any)({})];
130
+ const checkboxStyleArray = [(checkboxStyles.checkbox as any)({ intent, checked: internalChecked, disabled, type: variant })];
131
+ const labelStyleArray = [(checkboxStyles.label as any)({ disabled })];
132
+ const helperTextStyleArray = [(checkboxStyles.helperText as any)({ error: !!error })];
133
+ const checkmarkStyleArray = [(checkboxStyles.checkmark as any)({ checked: internalChecked })];
134
134
 
135
135
  // Generate web props
136
136
  const wrapperProps = getWebProps(wrapperStyleArray);
@@ -42,11 +42,11 @@ const Chip = forwardRef<ComponentRef<typeof Pressable>, ChipProps>(({
42
42
  const isSelected = selectable ? selected : false;
43
43
 
44
44
  // Compute dynamic styles
45
- const containerStyle = chipStyles.container(size, intent, type, isSelected, disabled);
46
- const labelStyle = chipStyles.label(size, intent, type, isSelected);
47
- const iconStyle = chipStyles.icon(size, intent, type, isSelected);
48
- const deleteButtonStyle = chipStyles.deleteButton(size);
49
- const deleteIconStyle = chipStyles.deleteIcon(size, intent, type, isSelected);
45
+ const containerStyle = (chipStyles.container as any)({ size, intent, type, selected: isSelected, disabled });
46
+ const labelStyle = (chipStyles.label as any)({ size, intent, type, selected: isSelected });
47
+ const iconStyle = (chipStyles.icon as any)({ size, intent, type, selected: isSelected });
48
+ const deleteButtonStyle = (chipStyles.deleteButton as any)({ size });
49
+ const deleteIconStyle = (chipStyles.deleteIcon as any)({ size, intent, type, selected: isSelected });
50
50
 
51
51
  // Map chip size to icon size
52
52
  const iconSize = size === 'sm' ? 12 : size === 'md' ? 14 : 16;
@@ -0,0 +1,184 @@
1
+ import { StyleSheet } from 'react-native-unistyles';
2
+ import { Theme, Intent } from '@idealyst/theme';
3
+ import { applyExtensions } from '../extensions/applyExtension';
4
+
5
+ type ChipSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';
6
+ type ChipType = 'filled' | 'outlined' | 'soft';
7
+ type ChipIntent = Intent;
8
+
9
+ type ChipDynamicProps = {
10
+ size: ChipSize;
11
+ intent: ChipIntent;
12
+ type: ChipType;
13
+ selected: boolean;
14
+ disabled?: boolean;
15
+ };
16
+
17
+ type ChipDeleteButtonProps = {
18
+ size: ChipSize;
19
+ };
20
+
21
+ /**
22
+ * Create container styles
23
+ */
24
+ function createContainerStyles(theme: Theme) {
25
+ return ({ size, intent, type, selected, disabled = false }: ChipDynamicProps) => {
26
+ const intentValue = theme.intents[intent];
27
+ const sizeValue = theme.sizes.chip[size];
28
+
29
+ // Compute colors based on type and selected state
30
+ let backgroundColor: string;
31
+ let borderColor: string;
32
+ let borderWidth: number;
33
+
34
+ if (type === 'filled') {
35
+ borderWidth = 1;
36
+ backgroundColor = selected ? intentValue.contrast : intentValue.primary;
37
+ borderColor = selected ? intentValue.primary : 'transparent';
38
+ } else if (type === 'outlined') {
39
+ borderWidth = 1;
40
+ backgroundColor = selected ? intentValue.primary : 'transparent';
41
+ borderColor = intentValue.primary;
42
+ } else { // soft
43
+ borderWidth = 0;
44
+ backgroundColor = selected ? intentValue.primary : intentValue.light;
45
+ borderColor = 'transparent';
46
+ }
47
+
48
+ return {
49
+ display: 'flex' as const,
50
+ flexDirection: 'row' as const,
51
+ alignItems: 'center' as const,
52
+ justifyContent: 'center' as const,
53
+ gap: 4,
54
+ paddingHorizontal: sizeValue.paddingHorizontal as number,
55
+ paddingVertical: sizeValue.paddingVertical as number,
56
+ minHeight: sizeValue.minHeight as number,
57
+ borderRadius: sizeValue.borderRadius as number,
58
+ backgroundColor,
59
+ borderColor,
60
+ borderWidth,
61
+ borderStyle: borderWidth > 0 ? ('solid' as const) : undefined,
62
+ opacity: disabled ? 0.5 : 1,
63
+ } as const;
64
+ };
65
+ }
66
+
67
+ /**
68
+ * Create label styles
69
+ */
70
+ function createLabelStyles(theme: Theme) {
71
+ return ({ size, intent, type, selected }: ChipDynamicProps) => {
72
+ const intentValue = theme.intents[intent];
73
+ const sizeValue = theme.sizes.chip[size];
74
+
75
+ // Compute color based on type and selected state
76
+ let color: string;
77
+
78
+ if (type === 'filled') {
79
+ color = selected ? intentValue.primary : intentValue.contrast;
80
+ } else if (type === 'outlined') {
81
+ color = selected ? theme.colors.text.inverse : intentValue.primary;
82
+ } else { // soft
83
+ color = selected ? theme.colors.text.inverse : intentValue.dark;
84
+ }
85
+
86
+ return {
87
+ fontFamily: 'inherit',
88
+ fontWeight: '500' as const,
89
+ fontSize: sizeValue.fontSize as number,
90
+ lineHeight: sizeValue.lineHeight as number,
91
+ color,
92
+ } as const;
93
+ };
94
+ }
95
+
96
+ /**
97
+ * Create icon styles
98
+ */
99
+ function createIconStyles(theme: Theme) {
100
+ return ({ size, intent, type, selected }: ChipDynamicProps) => {
101
+ const intentValue = theme.intents[intent];
102
+ const sizeValue = theme.sizes.chip[size];
103
+
104
+ // Compute color based on type and selected state (same logic as label)
105
+ let color: string;
106
+
107
+ if (type === 'filled') {
108
+ color = selected ? intentValue.primary : intentValue.contrast;
109
+ } else if (type === 'outlined') {
110
+ color = selected ? theme.colors.text.inverse : intentValue.primary;
111
+ } else { // soft
112
+ color = selected ? theme.colors.text.inverse : intentValue.dark;
113
+ }
114
+
115
+ return {
116
+ display: 'flex' as const,
117
+ alignItems: 'center' as const,
118
+ justifyContent: 'center' as const,
119
+ width: sizeValue.iconSize as number,
120
+ height: sizeValue.iconSize as number,
121
+ color,
122
+ } as const;
123
+ };
124
+ }
125
+
126
+ /**
127
+ * Create delete button styles
128
+ */
129
+ function createDeleteButtonStyles(theme: Theme) {
130
+ return ({ size }: ChipDeleteButtonProps) => {
131
+ const sizeValue = theme.sizes.chip[size];
132
+
133
+ return {
134
+ display: 'flex' as const,
135
+ alignItems: 'center' as const,
136
+ justifyContent: 'center' as const,
137
+ padding: 0,
138
+ marginLeft: 4,
139
+ borderRadius: 12,
140
+ width: sizeValue.iconSize as number,
141
+ height: sizeValue.iconSize as number,
142
+ } as const;
143
+ };
144
+ }
145
+
146
+ /**
147
+ * Create delete icon styles
148
+ */
149
+ function createDeleteIconStyles(theme: Theme) {
150
+ return ({ size, intent, type, selected }: ChipDynamicProps) => {
151
+ const intentValue = theme.intents[intent];
152
+ const sizeValue = theme.sizes.chip[size];
153
+
154
+ // Compute color based on type and selected state (same logic as label/icon)
155
+ let color: string;
156
+
157
+ if (type === 'filled') {
158
+ color = selected ? intentValue.primary : intentValue.contrast;
159
+ } else if (type === 'outlined') {
160
+ color = selected ? theme.colors.text.inverse : intentValue.primary;
161
+ } else { // soft
162
+ color = selected ? theme.colors.text.inverse : intentValue.dark;
163
+ }
164
+
165
+ return {
166
+ fontSize: sizeValue.iconSize as number,
167
+ color,
168
+ } as const;
169
+ };
170
+ }
171
+
172
+ // Styles are inlined here instead of in @idealyst/theme because Unistyles' Babel
173
+ // transform on native cannot resolve function calls to extract variant structures.
174
+ export const chipStyles = StyleSheet.create((theme: Theme) => {
175
+ // Apply extensions to main visual elements
176
+
177
+ return applyExtensions('Chip', theme, {container: createContainerStyles(theme),
178
+ label: createLabelStyles(theme),
179
+ icon: createIconStyles(theme),
180
+ // Additional styles (merged from return)
181
+ // Minor utility styles (not extended)
182
+ deleteButton: createDeleteButtonStyles(theme),
183
+ deleteIcon: createDeleteIconStyles(theme)});
184
+ });