@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,304 +1,131 @@
1
- import { StyleSheet } from 'react-native-unistyles';
2
- import { Theme, Intent, CompoundVariants} from '@idealyst/theme';
3
-
4
- type AlertType = 'filled' | 'outlined' | 'soft';
5
- type AlertIntent = Intent | 'info'; // Alert includes 'info' which maps to primary
6
-
7
- export type AlertVariants = {
8
- type: AlertType;
9
- intent: AlertIntent;
10
- }
11
-
12
-
13
- /**
14
- * Create type variants (structure only, colors handled by compound variants)
15
- */
16
- const TypeVariants = {
17
- filled: {
18
- borderWidth: 1,
19
- borderStyle: 'solid' as const,
20
- },
21
- outlined: {
22
- backgroundColor: 'transparent',
23
- borderWidth: 1,
24
- borderStyle: 'solid' as const,
25
- },
26
- soft: {
27
- borderWidth: 1,
28
- borderStyle: 'solid' as const,
29
- }
30
- } as const;
31
-
32
- /**
33
- * Create compound variants for container (type + intent combinations)
34
- */
35
- function createContainerCompoundVariants(theme: Theme) {
36
- const compoundVariants: CompoundVariants<keyof AlertVariants> = [];
37
-
38
- // Process standard intents from theme
39
- for (const intent in theme.intents) {
40
- const intentValue = theme.intents[intent as Intent];
41
-
42
- // Filled + intent
43
- compoundVariants.push({
44
- intent,
45
- type: 'filled',
46
- styles: {
47
- backgroundColor: intentValue.primary,
48
- borderColor: intentValue.primary,
49
- },
50
- });
51
-
52
- // Outlined + intent
53
- compoundVariants.push({
54
- intent,
55
- type: 'outlined',
56
- styles: {
57
- borderColor: intentValue.primary,
58
- },
59
- });
60
-
61
- // Soft + intent
62
- compoundVariants.push({
63
- intent,
64
- type: 'soft',
65
- styles: {
66
- backgroundColor: intentValue.light,
67
- borderColor: intentValue.light,
68
- },
69
- });
70
- }
71
-
72
- // Add 'info' intent (maps to primary)
73
- const primaryIntent = theme.intents.primary;
74
- compoundVariants.push({
75
- intent: 'info',
76
- type: 'filled',
77
- styles: {
78
- backgroundColor: primaryIntent.primary,
79
- borderColor: primaryIntent.primary,
80
- },
81
- });
82
- compoundVariants.push({
83
- intent: 'info',
84
- type: 'outlined',
85
- styles: {
86
- borderColor: primaryIntent.primary,
87
- },
88
- });
89
- compoundVariants.push({
90
- intent: 'info',
91
- type: 'soft',
92
- styles: {
93
- backgroundColor: primaryIntent.light,
94
- borderColor: primaryIntent.light,
95
- },
96
- });
97
-
98
- return compoundVariants;
99
- }
100
-
101
1
  /**
102
- * Create compound variants for icon/title colors (type + intent combinations)
2
+ * Alert styles using defineStyle with dynamic intent/type handling.
103
3
  */
104
- function createIconTitleCompoundVariants(theme: Theme) {
105
- const compoundVariants: CompoundVariants<keyof AlertVariants> = [];
106
-
107
- // Process standard intents from theme
108
- for (const intent in theme.intents) {
109
- const intentValue = theme.intents[intent as Intent];
110
-
111
- // Filled type: use contrast color
112
- compoundVariants.push({
113
- intent,
114
- type: 'filled',
115
- styles: {
116
- color: intentValue.contrast,
117
- },
118
- });
4
+ import { StyleSheet } from 'react-native-unistyles';
5
+ import { defineStyle, ThemeStyleWrapper } from '@idealyst/theme';
6
+ import type { Theme as BaseTheme, Intent } from '@idealyst/theme';
119
7
 
120
- // Outlined type: use primary color
121
- compoundVariants.push({
122
- intent,
123
- type: 'outlined',
124
- styles: {
125
- color: intentValue.primary,
126
- },
127
- });
8
+ // Required: Unistyles must see StyleSheet usage in original source to process this file
9
+ void StyleSheet;
128
10
 
129
- // Soft type: use primary color
130
- compoundVariants.push({
131
- intent,
132
- type: 'soft',
133
- styles: {
134
- color: intentValue.primary,
135
- },
136
- });
137
- }
11
+ // Wrap theme for $iterator support
12
+ type Theme = ThemeStyleWrapper<BaseTheme>;
138
13
 
139
- // Add 'info' intent (maps to primary)
140
- const primaryIntent = theme.intents.primary;
141
- compoundVariants.push({
142
- intent: 'info',
143
- type: 'filled',
144
- styles: {
145
- color: primaryIntent.contrast,
146
- },
147
- });
148
- compoundVariants.push({
149
- intent: 'info',
150
- type: 'outlined',
151
- styles: {
152
- color: primaryIntent.primary,
153
- },
154
- });
155
- compoundVariants.push({
156
- intent: 'info',
157
- type: 'soft',
158
- styles: {
159
- color: primaryIntent.primary,
160
- },
161
- });
14
+ type AlertType = 'filled' | 'outlined' | 'soft';
162
15
 
163
- return compoundVariants;
164
- }
16
+ export type AlertDynamicProps = {
17
+ intent?: Intent;
18
+ type?: AlertType;
19
+ };
165
20
 
166
21
  /**
167
- * Create compound variants for message colors (type + intent combinations)
22
+ * Alert styles with intent/type combination handling.
168
23
  */
169
- function createMessageCompoundVariants(theme: Theme): CompoundVariants<keyof AlertVariants> {
170
- const compoundVariants: CompoundVariants<keyof AlertVariants> = [];
171
-
172
- // Process standard intents from theme
173
- for (const intent in theme.intents) {
174
- const intentValue = theme.intents[intent as Intent];
175
-
176
- // Filled type: use contrast color
177
- compoundVariants.push({
178
- intent,
179
- type: 'filled',
180
- styles: {
181
- color: intentValue.contrast,
182
- },
183
- });
184
-
185
- // Outlined type: use primary text color
186
- compoundVariants.push({
187
- intent,
188
- type: 'outlined',
189
- styles: {
190
- color: theme.colors.text.primary,
191
- },
192
- });
193
-
194
- // Soft type: use primary text color
195
- compoundVariants.push({
196
- intent,
197
- type: 'soft',
198
- styles: {
199
- color: theme.colors.text.primary,
200
- },
201
- });
202
- }
203
-
204
- // Add 'info' intent (maps to primary)
205
- const primaryIntent = theme.intents.primary;
206
- compoundVariants.push({
207
- intent: 'info',
208
- type: 'filled',
209
- styles: {
210
- color: primaryIntent.contrast,
211
- },
212
- });
213
- compoundVariants.push({
214
- intent: 'info',
215
- type: 'outlined',
216
- styles: {
217
- color: theme.colors.text.primary,
218
- },
219
- });
220
- compoundVariants.push({
221
- intent: 'info',
222
- type: 'soft',
223
- styles: {
224
- color: theme.colors.text.primary,
225
- },
226
- });
227
-
228
- return compoundVariants;
229
- }
230
-
231
- export const alertStyles = StyleSheet.create((theme: Theme) => {
232
- return {
233
- container: {
234
- display: 'flex',
235
- flexDirection: 'row',
236
- alignItems: 'flex-start',
24
+ export const alertStyles = defineStyle('Alert', (theme: Theme) => ({
25
+ container: ({ intent = 'neutral', type = 'soft' }: AlertDynamicProps) => {
26
+ const intentValue = theme.intents[intent];
27
+
28
+ // Background color based on type
29
+ const backgroundColor = type === 'filled'
30
+ ? intentValue.primary
31
+ : type === 'soft'
32
+ ? intentValue.light
33
+ : 'transparent';
34
+
35
+ // Border color based on type
36
+ const borderColor = (type === 'filled' || type === 'outlined')
37
+ ? intentValue.primary
38
+ : intentValue.light;
39
+
40
+ return {
41
+ display: 'flex' as const,
42
+ flexDirection: 'row' as const,
43
+ alignItems: 'flex-start' as const,
237
44
  gap: 8,
238
45
  padding: 16,
239
46
  borderRadius: 8,
240
47
  borderWidth: 1,
241
48
  borderStyle: 'solid' as const,
242
- variants: {
243
- type: TypeVariants,
244
- } as const,
245
- compoundVariants: createContainerCompoundVariants(theme),
246
- } as const,
247
- iconContainer: {
248
- display: 'flex',
249
- alignItems: 'center',
250
- justifyContent: 'center',
49
+ backgroundColor,
50
+ borderColor,
51
+ } as const;
52
+ },
53
+
54
+ iconContainer: ({ intent = 'neutral', type = 'soft' }: AlertDynamicProps) => {
55
+ const intentValue = theme.intents[intent];
56
+ const color = type === 'filled' ? intentValue.contrast : intentValue.primary;
57
+
58
+ return {
59
+ display: 'flex' as const,
60
+ alignItems: 'center' as const,
61
+ justifyContent: 'center' as const,
251
62
  flexShrink: 0,
252
63
  width: 24,
253
64
  height: 24,
254
- compoundVariants: createIconTitleCompoundVariants(theme),
255
- } as const,
256
- content: {
257
- flex: 1,
258
- display: 'flex',
259
- flexDirection: 'column',
260
- gap: 4,
261
- },
262
- title: {
65
+ color,
66
+ } as const;
67
+ },
68
+
69
+ title: ({ intent = 'neutral', type = 'soft' }: AlertDynamicProps) => {
70
+ const intentValue = theme.intents[intent];
71
+ const color = type === 'filled' ? intentValue.contrast : intentValue.primary;
72
+
73
+ return {
263
74
  fontSize: 16,
264
75
  lineHeight: 24,
265
- fontWeight: '600',
266
- compoundVariants: createIconTitleCompoundVariants(theme),
267
- },
268
- message: {
76
+ fontWeight: '600' as const,
77
+ color,
78
+ } as const;
79
+ },
80
+
81
+ message: ({ intent = 'neutral', type = 'soft' }: AlertDynamicProps) => {
82
+ const intentValue = theme.intents[intent];
83
+ const color = type === 'filled' ? intentValue.contrast : theme.colors.text.primary;
84
+
85
+ return {
269
86
  fontSize: 14,
270
87
  lineHeight: 20,
271
- compoundVariants: createMessageCompoundVariants(theme),
272
- },
273
- actions: {
274
- marginTop: 4,
275
- display: 'flex',
276
- flexDirection: 'row',
277
- gap: 8,
278
- },
279
- closeButton: {
280
- padding: 4,
281
- backgroundColor: 'transparent',
282
- borderRadius: 4,
283
- display: 'flex',
284
- alignItems: 'center',
285
- justifyContent: 'center',
286
- flexShrink: 0,
287
- _web: {
288
- border: 'none',
289
- cursor: 'pointer',
290
- outline: 'none',
291
- _hover: {
292
- backgroundColor: 'rgba(0, 0, 0, 0.1)',
293
- },
88
+ color,
89
+ } as const;
90
+ },
91
+
92
+ content: (_props: AlertDynamicProps) => ({
93
+ flex: 1,
94
+ display: 'flex' as const,
95
+ flexDirection: 'column' as const,
96
+ gap: 4,
97
+ }),
98
+
99
+ actions: (_props: AlertDynamicProps) => ({
100
+ marginTop: 4,
101
+ display: 'flex' as const,
102
+ flexDirection: 'row' as const,
103
+ gap: 8,
104
+ }),
105
+
106
+ closeButton: (_props: AlertDynamicProps) => ({
107
+ padding: 4,
108
+ backgroundColor: 'transparent' as const,
109
+ borderRadius: 4,
110
+ display: 'flex' as const,
111
+ alignItems: 'center' as const,
112
+ justifyContent: 'center' as const,
113
+ flexShrink: 0,
114
+ _web: {
115
+ border: 'none',
116
+ cursor: 'pointer',
117
+ outline: 'none',
118
+ _hover: {
119
+ backgroundColor: 'rgba(0, 0, 0, 0.1)',
294
120
  },
295
121
  },
296
- closeIcon: {
297
- display: 'flex',
298
- alignItems: 'center',
299
- justifyContent: 'center',
300
- width: 16,
301
- height: 16,
302
- },
303
- } as const;
304
- });
122
+ }),
123
+
124
+ closeIcon: (_props: AlertDynamicProps) => ({
125
+ display: 'flex' as const,
126
+ alignItems: 'center' as const,
127
+ justifyContent: 'center' as const,
128
+ width: 16,
129
+ height: 16,
130
+ }),
131
+ }));
@@ -31,17 +31,13 @@ const Alert = forwardRef<HTMLDivElement, AlertProps>(({
31
31
  testID,
32
32
  id,
33
33
  }, ref) => {
34
- // Apply variants to stylesheet
35
- alertStyles.useVariants({
36
- type,
37
- intent,
38
- });
39
-
40
- const containerProps = getWebProps([alertStyles.container, style as any]);
41
- const iconContainerProps = getWebProps([alertStyles.iconContainer]);
34
+ // Compute dynamic styles with intent and type
35
+ const dynamicProps = { intent, type };
36
+ const containerProps = getWebProps([(alertStyles.container as any)(dynamicProps), style as any]);
37
+ const iconContainerProps = getWebProps([(alertStyles.iconContainer as any)(dynamicProps)]);
42
38
  const contentProps = getWebProps([alertStyles.content]);
43
- const titleProps = getWebProps([alertStyles.title]);
44
- const messageProps = getWebProps([alertStyles.message]);
39
+ const titleProps = getWebProps([(alertStyles.title as any)(dynamicProps)]);
40
+ const messageProps = getWebProps([(alertStyles.message as any)(dynamicProps)]);
45
41
  const actionsProps = getWebProps([alertStyles.actions]);
46
42
  const closeButtonProps = getWebProps([alertStyles.closeButton]);
47
43
  const closeIconProps = getWebProps([alertStyles.closeIcon]);
@@ -41,8 +41,11 @@ const Avatar = forwardRef<View, AvatarProps>(({
41
41
  setHasError(true);
42
42
  };
43
43
 
44
+ const avatarStyle = (avatarStyles.avatar as any)({});
45
+ const fallbackStyle = (avatarStyles.fallback as any)({});
46
+
44
47
  return (
45
- <View ref={ref} nativeID={id} style={[avatarStyles.avatar, style]} testID={testID} {...nativeA11yProps}>
48
+ <View ref={ref} nativeID={id} style={[avatarStyle, style]} testID={testID} {...nativeA11yProps}>
46
49
  {src && !hasError ? (
47
50
  <Image
48
51
  source={typeof src === 'string' ? { uri: src } : src}
@@ -51,7 +54,7 @@ const Avatar = forwardRef<View, AvatarProps>(({
51
54
  accessibilityLabel={alt}
52
55
  />
53
56
  ) : (
54
- <Text style={avatarStyles.fallback}>
57
+ <Text style={fallbackStyle}>
55
58
  {fallback}
56
59
  </Text>
57
60
  )}
@@ -0,0 +1,99 @@
1
+ import { StyleSheet } from 'react-native-unistyles';
2
+ import { Theme, StylesheetStyles, Size } from '@idealyst/theme';
3
+ import { buildSizeVariants } from '../utils/buildSizeVariants';
4
+ import { applyExtensions } from '../extensions/applyExtension';
5
+
6
+ type AvatarSize = Size;
7
+ type AvatarShape = 'circle' | 'square';
8
+
9
+ type AvatarVariants = {
10
+ size: AvatarSize;
11
+ shape: AvatarShape;
12
+ }
13
+
14
+ export type ExpandedAvatarStyles = StylesheetStyles<keyof AvatarVariants>;
15
+
16
+ export type AvatarStylesheet = {
17
+ avatar: ExpandedAvatarStyles;
18
+ image: ExpandedAvatarStyles;
19
+ fallback: ExpandedAvatarStyles;
20
+ }
21
+
22
+ function createAvatarSizeVariants(theme: Theme) {
23
+ return buildSizeVariants(theme, 'avatar', (size) => ({
24
+ width: size.width,
25
+ height: size.height,
26
+ }));
27
+ }
28
+
29
+ function createAvatarShapeVariants(theme: Theme) {
30
+ return {
31
+ circle: {
32
+ borderRadius: 9999,
33
+ },
34
+ square: {
35
+ borderRadius: 8,
36
+ },
37
+ } as const;
38
+ }
39
+
40
+ function createFallbackSizeVariants(theme: Theme) {
41
+ return buildSizeVariants(theme, 'avatar', (size) => ({
42
+ fontSize: size.fontSize,
43
+ }));
44
+ }
45
+
46
+ /**
47
+ * Create container styles
48
+ */
49
+ function createContainerStyles(theme: Theme) {
50
+ return () => ({
51
+ display: 'flex' as const,
52
+ alignItems: 'center' as const,
53
+ justifyContent: 'center' as const,
54
+ backgroundColor: theme.colors.surface.secondary,
55
+ overflow: 'hidden' as const,
56
+ variants: {
57
+ size: createAvatarSizeVariants(theme),
58
+ shape: createAvatarShapeVariants(theme),
59
+ },
60
+ });
61
+ }
62
+
63
+ /**
64
+ * Create image styles
65
+ */
66
+ function createImageStyles() {
67
+ return () => ({
68
+ width: '100%' as const,
69
+ height: '100%' as const,
70
+ });
71
+ }
72
+
73
+ /**
74
+ * Create fallback styles
75
+ */
76
+ function createFallbackStyles(theme: Theme) {
77
+ return () => ({
78
+ color: theme.colors.text.primary,
79
+ fontWeight: '600' as const,
80
+ variants: {
81
+ size: createFallbackSizeVariants(theme),
82
+ },
83
+ });
84
+ }
85
+
86
+ // Styles are inlined here instead of in @idealyst/theme because Unistyles' Babel
87
+ // transform on native cannot resolve function calls to extract variant structures.
88
+ export const avatarStyles = StyleSheet.create((theme: Theme) => {
89
+ // Apply extensions to main visual elements
90
+
91
+ return applyExtensions('Avatar', theme, {avatar: createContainerStyles(theme),
92
+ fallback: createFallbackStyles(theme),
93
+ // Additional styles (merged from return)
94
+ // Minor utility styles (not extended)
95
+ image: {
96
+ width: '100%',
97
+ height: '100%',
98
+ }});
99
+ });
@@ -1,73 +1,58 @@
1
+ /**
2
+ * Avatar styles using defineStyle with $iterator expansion.
3
+ */
1
4
  import { StyleSheet } from 'react-native-unistyles';
2
- import { Theme, StylesheetStyles, Size} from '@idealyst/theme';
3
- import { buildSizeVariants } from '../utils/buildSizeVariants';
5
+ import { defineStyle, ThemeStyleWrapper } from '@idealyst/theme';
6
+ import type { Theme as BaseTheme, Size } from '@idealyst/theme';
4
7
 
5
- type AvatarSize = Size;
6
- type AvatarShape = 'circle' | 'square';
7
-
8
- type AvatarVariants = {
9
- size: AvatarSize;
10
- shape: AvatarShape;
11
- }
12
-
13
- export type ExpandedAvatarStyles = StylesheetStyles<keyof AvatarVariants>;
14
-
15
- export type AvatarStylesheet = {
16
- avatar: ExpandedAvatarStyles;
17
- image: ExpandedAvatarStyles;
18
- fallback: ExpandedAvatarStyles;
19
- }
20
-
21
- function createAvatarSizeVariants(theme: Theme) {
22
- return buildSizeVariants(theme, 'avatar', (size) => ({
23
- width: size.width,
24
- height: size.height,
25
- }));
26
- }
8
+ // Required: Unistyles must see StyleSheet usage in original source to process this file
9
+ void StyleSheet;
27
10
 
28
- function createAvatarShapeVariants(theme: Theme) {
29
- return {
30
- circle: {
31
- borderRadius: 9999,
32
- },
33
- square: {
34
- borderRadius: 8,
35
- },
36
- } as const;
37
- }
11
+ // Wrap theme for $iterator support
12
+ type Theme = ThemeStyleWrapper<BaseTheme>;
38
13
 
39
- function createFallbackSizeVariants(theme: Theme) {
40
- return buildSizeVariants(theme, 'avatar', (size) => ({
41
- fontSize: size.fontSize,
42
- }));
43
- }
14
+ type AvatarShape = 'circle' | 'square';
44
15
 
45
- // Styles are inlined here instead of in @idealyst/theme because Unistyles' Babel
46
- // transform on native cannot resolve function calls to extract variant structures.
47
- // @ts-ignore - TS language server needs restart to pick up theme structure changes
48
- export const avatarStyles = StyleSheet.create((theme: Theme) => {
49
- return {
50
- avatar: {
51
- display: 'flex',
52
- alignItems: 'center',
53
- justifyContent: 'center',
16
+ export type AvatarDynamicProps = {
17
+ size?: Size;
18
+ shape?: AvatarShape;
19
+ };
20
+
21
+ /**
22
+ * Avatar styles with size and shape variants.
23
+ */
24
+ export const avatarStyles = defineStyle('Avatar', (theme: Theme) => ({
25
+ avatar: (_props: AvatarDynamicProps) => ({
26
+ display: 'flex' as const,
27
+ alignItems: 'center' as const,
28
+ justifyContent: 'center' as const,
54
29
  backgroundColor: theme.colors.surface.secondary,
55
- overflow: 'hidden',
30
+ overflow: 'hidden' as const,
56
31
  variants: {
57
- size: createAvatarSizeVariants(theme),
58
- shape: createAvatarShapeVariants(theme),
32
+ // $iterator expands for each avatar size
33
+ size: {
34
+ width: theme.sizes.$avatar.width,
35
+ height: theme.sizes.$avatar.height,
36
+ },
37
+ shape: {
38
+ circle: { borderRadius: 9999 },
39
+ square: { borderRadius: 8 },
40
+ },
59
41
  },
60
- },
61
- image: {
62
- width: '100%',
63
- height: '100%',
64
- },
65
- fallback: {
42
+ }),
43
+
44
+ image: (_props: AvatarDynamicProps) => ({
45
+ width: '100%' as const,
46
+ height: '100%' as const,
47
+ }),
48
+
49
+ fallback: (_props: AvatarDynamicProps) => ({
66
50
  color: theme.colors.text.primary,
67
- fontWeight: '600',
51
+ fontWeight: '600' as const,
68
52
  variants: {
69
- size: createFallbackSizeVariants(theme),
53
+ size: {
54
+ fontSize: theme.sizes.$avatar.fontSize,
55
+ },
70
56
  },
71
- },
72
- };
73
- });
57
+ }),
58
+ }));