@idealyst/components 1.1.7 → 1.1.9

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 (129) hide show
  1. package/package.json +3 -3
  2. package/plugin/web.js +280 -532
  3. package/src/Accordion/Accordion.native.tsx +8 -6
  4. package/src/Accordion/Accordion.styles.old.tsx +298 -0
  5. package/src/Accordion/Accordion.styles.tsx +102 -236
  6. package/src/Accordion/Accordion.web.tsx +1 -3
  7. package/src/ActivityIndicator/ActivityIndicator.styles.old.tsx +94 -0
  8. package/src/ActivityIndicator/ActivityIndicator.styles.tsx +44 -74
  9. package/src/Alert/Alert.native.tsx +16 -6
  10. package/src/Alert/Alert.styles.old.tsx +209 -0
  11. package/src/Alert/Alert.styles.tsx +67 -149
  12. package/src/Alert/Alert.web.tsx +3 -4
  13. package/src/Avatar/Avatar.styles.old.tsx +99 -0
  14. package/src/Avatar/Avatar.styles.tsx +35 -80
  15. package/src/Badge/Badge.styles.old.tsx +157 -0
  16. package/src/Badge/Badge.styles.tsx +61 -121
  17. package/src/Badge/Badge.web.tsx +8 -15
  18. package/src/Breadcrumb/Breadcrumb.styles.old.tsx +231 -0
  19. package/src/Breadcrumb/Breadcrumb.styles.tsx +83 -200
  20. package/src/Breadcrumb/Breadcrumb.web.tsx +31 -30
  21. package/src/Button/Button.native.tsx +14 -21
  22. package/src/Button/Button.styles.tsx +103 -140
  23. package/src/Button/Button.web.tsx +9 -19
  24. package/src/Card/Card.native.tsx +7 -11
  25. package/src/Card/Card.styles.old.tsx +160 -0
  26. package/src/Card/Card.styles.tsx +105 -142
  27. package/src/Card/Card.web.tsx +5 -4
  28. package/src/Checkbox/Checkbox.native.tsx +9 -5
  29. package/src/Checkbox/Checkbox.styles.old.tsx +271 -0
  30. package/src/Checkbox/Checkbox.styles.tsx +104 -216
  31. package/src/Checkbox/Checkbox.web.tsx +7 -8
  32. package/src/Chip/Chip.styles.old.tsx +184 -0
  33. package/src/Chip/Chip.styles.tsx +34 -72
  34. package/src/Chip/Chip.web.tsx +3 -5
  35. package/src/Dialog/Dialog.native.tsx +7 -4
  36. package/src/Dialog/Dialog.styles.old.tsx +202 -0
  37. package/src/Dialog/Dialog.styles.tsx +69 -133
  38. package/src/Dialog/Dialog.web.tsx +3 -3
  39. package/src/Dialog/types.ts +1 -1
  40. package/src/Divider/Divider.styles.old.tsx +172 -0
  41. package/src/Divider/Divider.styles.tsx +62 -84
  42. package/src/Icon/Icon.native.tsx +8 -8
  43. package/src/Icon/Icon.styles.old.tsx +81 -0
  44. package/src/Icon/Icon.styles.tsx +52 -66
  45. package/src/Icon/Icon.web.tsx +62 -21
  46. package/src/Icon/IconRegistry.native.ts +41 -0
  47. package/src/Icon/IconRegistry.ts +107 -0
  48. package/src/Icon/IconSvg/IconSvg.web.tsx +28 -5
  49. package/src/Icon/icon-resolver.ts +12 -43
  50. package/src/Icon/index.native.ts +2 -1
  51. package/src/Icon/index.ts +1 -0
  52. package/src/Icon/index.web.ts +1 -0
  53. package/src/Image/Image.styles.old.tsx +69 -0
  54. package/src/Image/Image.styles.tsx +46 -60
  55. package/src/Input/Input.native.tsx +138 -53
  56. package/src/Input/Input.styles.old.tsx +289 -0
  57. package/src/Input/Input.styles.tsx +134 -232
  58. package/src/Input/Input.web.tsx +5 -8
  59. package/src/List/List.native.tsx +5 -2
  60. package/src/List/List.styles.old.tsx +242 -0
  61. package/src/List/List.styles.tsx +179 -215
  62. package/src/List/ListItem.native.tsx +16 -11
  63. package/src/List/ListItem.web.tsx +26 -16
  64. package/src/Menu/Menu.styles.old.tsx +197 -0
  65. package/src/Menu/Menu.styles.tsx +68 -150
  66. package/src/Menu/MenuItem.native.tsx +5 -3
  67. package/src/Menu/MenuItem.styles.old.tsx +114 -0
  68. package/src/Menu/MenuItem.styles.tsx +57 -89
  69. package/src/Menu/MenuItem.web.tsx +10 -7
  70. package/src/Popover/Popover.native.tsx +10 -4
  71. package/src/Popover/Popover.styles.old.tsx +135 -0
  72. package/src/Popover/Popover.styles.tsx +51 -112
  73. package/src/Pressable/Pressable.styles.old.tsx +27 -0
  74. package/src/Pressable/Pressable.styles.tsx +35 -27
  75. package/src/Progress/Progress.styles.old.tsx +200 -0
  76. package/src/Progress/Progress.styles.tsx +75 -164
  77. package/src/RadioButton/RadioButton.native.tsx +4 -3
  78. package/src/RadioButton/RadioButton.styles.old.tsx +175 -0
  79. package/src/RadioButton/RadioButton.styles.tsx +83 -154
  80. package/src/RadioButton/RadioButton.web.tsx +2 -2
  81. package/src/SVGImage/SVGImage.styles.old.tsx +86 -0
  82. package/src/SVGImage/SVGImage.styles.tsx +35 -78
  83. package/src/Screen/Screen.native.tsx +19 -26
  84. package/src/Screen/Screen.styles.old.tsx +87 -0
  85. package/src/Screen/Screen.styles.tsx +103 -68
  86. package/src/Screen/Screen.web.tsx +2 -2
  87. package/src/Select/Select.native.tsx +42 -33
  88. package/src/Select/Select.styles.old.tsx +353 -0
  89. package/src/Select/Select.styles.tsx +214 -300
  90. package/src/Select/Select.web.tsx +45 -33
  91. package/src/Skeleton/Skeleton.styles.old.tsx +67 -0
  92. package/src/Skeleton/Skeleton.styles.tsx +29 -53
  93. package/src/Slider/Slider.styles.old.tsx +259 -0
  94. package/src/Slider/Slider.styles.tsx +153 -234
  95. package/src/Slider/Slider.web.tsx +2 -4
  96. package/src/Switch/Switch.native.tsx +9 -7
  97. package/src/Switch/Switch.styles.old.tsx +203 -0
  98. package/src/Switch/Switch.styles.tsx +101 -174
  99. package/src/Switch/Switch.web.tsx +7 -8
  100. package/src/TabBar/TabBar.native.tsx +3 -2
  101. package/src/TabBar/TabBar.styles.old.tsx +343 -0
  102. package/src/TabBar/TabBar.styles.tsx +145 -279
  103. package/src/Table/Table.native.tsx +180 -68
  104. package/src/Table/Table.styles.old.tsx +311 -0
  105. package/src/Table/Table.styles.tsx +140 -281
  106. package/src/Table/Table.web.tsx +169 -70
  107. package/src/Text/Text.native.tsx +1 -3
  108. package/src/Text/Text.style.demo.tsx +16 -0
  109. package/src/Text/Text.styles.old.tsx +219 -0
  110. package/src/Text/Text.styles.tsx +94 -84
  111. package/src/Text/Text.web.tsx +3 -2
  112. package/src/Text/index.ts +1 -0
  113. package/src/TextArea/TextArea.native.tsx +21 -8
  114. package/src/TextArea/TextArea.styles.old.tsx +213 -0
  115. package/src/TextArea/TextArea.styles.tsx +87 -187
  116. package/src/TextArea/TextArea.web.tsx +17 -6
  117. package/src/Tooltip/Tooltip.styles.old.tsx +82 -0
  118. package/src/Tooltip/Tooltip.styles.tsx +32 -56
  119. package/src/Video/Video.styles.old.tsx +51 -0
  120. package/src/Video/Video.styles.tsx +32 -44
  121. package/src/View/View.native.tsx +41 -13
  122. package/src/View/View.styles.old.tsx +125 -0
  123. package/src/View/View.styles.tsx +76 -106
  124. package/src/View/View.web.tsx +5 -21
  125. package/src/View/types.ts +31 -3
  126. package/src/examples/ButtonExamples.tsx +20 -0
  127. package/src/examples/CardExamples.tsx +0 -6
  128. package/src/extensions/extendComponent.ts +61 -0
  129. package/src/index.ts +1 -1
@@ -1,154 +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
- 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
- }
5
+ import { defineStyle, ThemeStyleWrapper } from '@idealyst/theme';
6
+ import type { Theme as BaseTheme, Intent, Size } from '@idealyst/theme';
7
+ import { ViewStyleSize } from '../utils/viewStyleProps';
23
8
 
24
- export type ExpandedCheckboxStyles = StylesheetStyles<keyof CheckboxVariants>;
9
+ // Required: Unistyles must see StyleSheet usage in original source to process this file
10
+ void StyleSheet;
25
11
 
26
- export type CheckboxStylesheet = {
27
- wrapper: ExpandedCheckboxStyles;
28
- container: ExpandedCheckboxStyles;
29
- checkbox: ExpandedCheckboxStyles;
30
- label: ExpandedCheckboxStyles;
31
- checkmark: ExpandedCheckboxStyles;
32
- helperText: ExpandedCheckboxStyles;
33
- }
12
+ // Wrap theme for $iterator support
13
+ type Theme = ThemeStyleWrapper<BaseTheme>;
34
14
 
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
- }
15
+ type CheckboxType = 'default' | 'outlined';
42
16
 
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
- }
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
+ };
55
29
 
56
30
  /**
57
- * Create type variants for checkbox
31
+ * Checkbox styles with intent/type/checked handling.
58
32
  */
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}`,
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,
66
40
  },
67
- },
68
- outlined: {
69
- borderWidth: 2,
70
- borderColor: theme.colors.border.primary,
71
- _web: {
72
- border: `2px solid ${theme.colors.border.primary}`,
41
+ marginVertical: {
42
+ marginVertical: theme.sizes.$view.padding,
73
43
  },
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}`,
44
+ marginHorizontal: {
45
+ marginHorizontal: theme.sizes.$view.padding,
90
46
  },
91
47
  },
92
- false: {
93
- backgroundColor: 'transparent',
48
+ _web: {
49
+ display: 'flex',
50
+ flexDirection: 'column',
51
+ alignItems: 'flex-start',
52
+ width: 'auto',
94
53
  },
95
- } as const;
96
- }
54
+ }),
97
55
 
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
- }
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
+ }),
110
69
 
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
- }
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;
123
79
 
124
- function createCheckboxStyles(theme: Theme) {
125
- return ({ intent }: Partial<CheckboxVariants>) => {
126
80
  return {
127
- alignItems: 'center',
128
- justifyContent: 'center',
81
+ alignItems: 'center' as const,
82
+ justifyContent: 'center' as const,
129
83
  borderRadius: 4,
130
- position: 'relative',
131
- backgroundColor: 'transparent',
132
- 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,
133
90
  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
- },
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 },
152
97
  },
153
98
  },
154
99
  _web: {
@@ -160,76 +105,46 @@ function createCheckboxStyles(theme: Theme) {
160
105
  MozAppearance: 'none',
161
106
  appearance: 'none',
162
107
  transition: 'all 0.2s ease',
108
+ cursor: disabled ? 'not-allowed' : 'pointer',
109
+ border: `${borderWidth}px solid ${borderColor}`,
163
110
  _focus: {
164
111
  outline: `2px solid ${theme.intents.primary.primary}`,
165
112
  outlineOffset: '2px',
166
113
  },
114
+ _hover: disabled ? {} : { opacity: 0.8 },
115
+ _active: disabled ? {} : { opacity: 0.6 },
167
116
  },
168
117
  } as const;
169
- }
170
- }
118
+ },
171
119
 
172
- function createCheckmarkStyles(_theme: Theme) {
173
- return () => ({
120
+ checkmark: ({ checked = false }: CheckboxDynamicProps) => ({
174
121
  position: 'absolute' as const,
175
122
  display: 'flex' as const,
176
123
  alignItems: 'center' as const,
177
124
  justifyContent: 'center' as const,
178
125
  color: '#ffffff',
126
+ opacity: checked ? 1 : 0,
179
127
  variants: {
180
- size: createCheckmarkSizeVariants(),
181
- visible: {
182
- true: { opacity: 1 },
183
- 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 },
184
134
  },
185
135
  },
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
- }
136
+ }),
224
137
 
225
- function createLabelStyles(theme: Theme) {
226
- return () => ({
138
+ label: ({ disabled = false }: CheckboxDynamicProps) => ({
227
139
  color: theme.colors.text.primary,
140
+ opacity: disabled ? 0.5 : 1,
228
141
  variants: {
229
- size: createLabelSizeVariants(),
230
- disabled: {
231
- true: { opacity: 0.5 },
232
- 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 },
233
148
  },
234
149
  },
235
150
  _web: {
@@ -238,38 +153,11 @@ function createLabelStyles(theme: Theme) {
238
153
  margin: 0,
239
154
  padding: 0,
240
155
  },
241
- });
242
- }
156
+ }),
243
157
 
244
- function createHelperTextStyles(theme: Theme) {
245
- return () => ({
158
+ helperText: ({ error = false }: CheckboxDynamicProps) => ({
246
159
  fontSize: 14,
247
- color: theme.colors.text.secondary,
160
+ color: error ? theme.intents.error.primary : theme.colors.text.secondary,
248
161
  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
- const extended = applyExtensions('Checkbox', theme, {
263
- container: createContainerStyles(),
264
- checkbox: createCheckboxStyles(theme),
265
- checkmark: createCheckmarkStyles(theme),
266
- });
267
-
268
- return {
269
- ...extended,
270
- // Minor utility styles (not extended)
271
- wrapper: createWrapperStyles(theme)(),
272
- label: createLabelStyles(theme)(),
273
- helperText: createHelperTextStyles(theme)(),
274
- };
275
- });
162
+ }),
163
+ }));
@@ -3,7 +3,6 @@ import { getWebProps } from 'react-native-unistyles/web';
3
3
  import { CheckboxProps } from './types';
4
4
  import { checkboxStyles } from './Checkbox.styles';
5
5
  import { IconSvg } from '../Icon/IconSvg/IconSvg.web';
6
- import { resolveIconPath } from '../Icon/icon-resolver';
7
6
  import useMergeRefs from '../hooks/useMergeRefs';
8
7
  import { getWebSelectionAriaProps, generateAccessibilityId, combineIds } from '../utils/accessibility';
9
8
 
@@ -124,13 +123,13 @@ const Checkbox = forwardRef<HTMLDivElement, CheckboxProps>(({
124
123
  marginHorizontal,
125
124
  });
126
125
 
127
- // Create style arrays
128
- const wrapperStyleArray = [checkboxStyles.wrapper, style as any];
126
+ // Create style arrays - call as functions with required props for theme reactivity
127
+ const wrapperStyleArray = [(checkboxStyles.wrapper as any)({}), style as any];
129
128
  const containerStyleArray = [(checkboxStyles.container as any)({})];
130
- const checkboxStyleArray = [(checkboxStyles.checkbox as any)({ intent })];
131
- const labelStyleArray = [checkboxStyles.label];
132
- const helperTextStyleArray = [checkboxStyles.helperText];
133
- const checkmarkStyleArray = [(checkboxStyles.checkmark as any)({})];
129
+ const checkboxStyleArray = [(checkboxStyles.checkbox as any)({ intent, checked: internalChecked, disabled, type: variant })];
130
+ const labelStyleArray = [(checkboxStyles.label as any)({ disabled })];
131
+ const helperTextStyleArray = [(checkboxStyles.helperText as any)({ error: !!error })];
132
+ const checkmarkStyleArray = [(checkboxStyles.checkmark as any)({ checked: internalChecked })];
134
133
 
135
134
  // Generate web props
136
135
  const wrapperProps = getWebProps(wrapperStyleArray);
@@ -177,7 +176,7 @@ const Checkbox = forwardRef<HTMLDivElement, CheckboxProps>(({
177
176
  <div {...checkboxProps}>
178
177
  {(internalChecked || indeterminate) && (
179
178
  <IconSvg
180
- path={resolveIconPath(indeterminate ? 'minus' : 'check')}
179
+ name={indeterminate ? 'minus' : 'check'}
181
180
  {...checkmarkProps}
182
181
  aria-label={indeterminate ? 'minus' : 'check'}
183
182
  />
@@ -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
+ });