@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
@@ -0,0 +1,219 @@
1
+ import { StyleSheet } from "react-native-unistyles";
2
+ import { Theme, Typography } from '@idealyst/theme';
3
+ import { TextAlignVariant, TextColorVariant, TextWeightVariant, TextTypographyVariant } from "./types";
4
+ import { applyExtensions } from '../extensions/applyExtension';
5
+
6
+ export type TextVariants = {
7
+ typography: TextTypographyVariant;
8
+ weight: TextWeightVariant;
9
+ align: TextAlignVariant;
10
+ }
11
+
12
+ type TextStyleParams = {
13
+ color?: TextColorVariant;
14
+ }
15
+
16
+ /**
17
+ * Create typography variants from theme
18
+ */
19
+ function createTypographyVariants(theme: Theme) {
20
+ const variants: Record<string, object> = {};
21
+ for (const key in theme.sizes.typography) {
22
+ const typo = theme.sizes.typography[key as Typography];
23
+ variants[key] = {
24
+ fontSize: typo.fontSize,
25
+ lineHeight: typo.lineHeight,
26
+ fontWeight: typo.fontWeight,
27
+ };
28
+ }
29
+ return variants;
30
+ }
31
+
32
+ /**
33
+ * Create spacing variants from theme
34
+ */
35
+ function createSpacingVariants(theme: Theme) {
36
+ return {
37
+ gap: {
38
+ xs: { gap: theme.sizes.view.xs.spacing },
39
+ sm: { gap: theme.sizes.view.sm.spacing },
40
+ md: { gap: theme.sizes.view.md.spacing },
41
+ lg: { gap: theme.sizes.view.lg.spacing },
42
+ xl: { gap: theme.sizes.view.xl.spacing },
43
+ },
44
+ padding: {
45
+ xs: { padding: theme.sizes.view.xs.padding },
46
+ sm: { padding: theme.sizes.view.sm.padding },
47
+ md: { padding: theme.sizes.view.md.padding },
48
+ lg: { padding: theme.sizes.view.lg.padding },
49
+ xl: { padding: theme.sizes.view.xl.padding },
50
+ },
51
+ paddingVertical: {
52
+ xs: { paddingVertical: theme.sizes.view.xs.padding },
53
+ sm: { paddingVertical: theme.sizes.view.sm.padding },
54
+ md: { paddingVertical: theme.sizes.view.md.padding },
55
+ lg: { paddingVertical: theme.sizes.view.lg.padding },
56
+ xl: { paddingVertical: theme.sizes.view.xl.padding },
57
+ },
58
+ paddingHorizontal: {
59
+ xs: { paddingHorizontal: theme.sizes.view.xs.padding },
60
+ sm: { paddingHorizontal: theme.sizes.view.sm.padding },
61
+ md: { paddingHorizontal: theme.sizes.view.md.padding },
62
+ lg: { paddingHorizontal: theme.sizes.view.lg.padding },
63
+ xl: { paddingHorizontal: theme.sizes.view.xl.padding },
64
+ },
65
+ };
66
+ }
67
+
68
+ /**
69
+ * Create text styles
70
+ */
71
+ function createTextStyles(theme: Theme) {
72
+ const spacingVariants = createSpacingVariants(theme);
73
+
74
+ return ({ color }: TextStyleParams) => ({
75
+ margin: 0,
76
+ padding: 0,
77
+ color: theme.colors.text[color ?? 'primary'] || theme.colors.text.primary,
78
+ variants: {
79
+ typography: createTypographyVariants(theme),
80
+ weight: {
81
+ light: { fontWeight: '300' },
82
+ normal: { fontWeight: '400' },
83
+ medium: { fontWeight: '500' },
84
+ semibold: { fontWeight: '600' },
85
+ bold: { fontWeight: '700' },
86
+ } as const,
87
+ align: {
88
+ left: { textAlign: 'left' },
89
+ center: { textAlign: 'center' },
90
+ right: { textAlign: 'right' },
91
+ } as const,
92
+ ...spacingVariants,
93
+ } as const,
94
+ _web: {
95
+ fontFamily: 'inherit',
96
+ },
97
+ });
98
+ }
99
+
100
+ // Babel plugin transforms applyExtensions to inline theme.__extensions access
101
+ export const textStyles = StyleSheet.create((theme: Theme) => {
102
+ return applyExtensions('Text', theme, {
103
+ text: createTextStyles(theme),
104
+ });
105
+ });
106
+
107
+ // =============================================================================
108
+ // TEST: buildStyles approach
109
+ // =============================================================================
110
+
111
+ // This is what DEVELOPERS would write (nice API with helpers):
112
+ // export const textStylesDef = buildStyles('Text', (theme) => ({
113
+ // text: createTextStyles(theme),
114
+ // }));
115
+
116
+ // This is what BABEL would generate (flat ObjectExpression, direct theme access):
117
+ // The key is ALL theme accesses are directly visible - no function calls hiding them
118
+ export const testTextStyles = StyleSheet.create((theme: Theme) => ({
119
+ text: ({ color }: TextStyleParams) => ({
120
+ margin: 0,
121
+ padding: 0,
122
+ // Direct theme access - Unistyles can trace this
123
+ color: theme.colors.text[color ?? 'primary'] || theme.colors.text.primary,
124
+ variants: {
125
+ // Typography variants - all expanded inline
126
+ typography: {
127
+ h1: {
128
+ fontSize: theme.sizes.typography.h1.fontSize,
129
+ lineHeight: theme.sizes.typography.h1.lineHeight,
130
+ fontWeight: theme.sizes.typography.h1.fontWeight,
131
+ },
132
+ h2: {
133
+ fontSize: theme.sizes.typography.h2.fontSize,
134
+ lineHeight: theme.sizes.typography.h2.lineHeight,
135
+ fontWeight: theme.sizes.typography.h2.fontWeight,
136
+ },
137
+ h3: {
138
+ fontSize: theme.sizes.typography.h3.fontSize,
139
+ lineHeight: theme.sizes.typography.h3.lineHeight,
140
+ fontWeight: theme.sizes.typography.h3.fontWeight,
141
+ },
142
+ h4: {
143
+ fontSize: theme.sizes.typography.h4.fontSize,
144
+ lineHeight: theme.sizes.typography.h4.lineHeight,
145
+ fontWeight: theme.sizes.typography.h4.fontWeight,
146
+ },
147
+ h5: {
148
+ fontSize: theme.sizes.typography.h5.fontSize,
149
+ lineHeight: theme.sizes.typography.h5.lineHeight,
150
+ fontWeight: theme.sizes.typography.h5.fontWeight,
151
+ },
152
+ h6: {
153
+ fontSize: theme.sizes.typography.h6.fontSize,
154
+ lineHeight: theme.sizes.typography.h6.lineHeight,
155
+ fontWeight: theme.sizes.typography.h6.fontWeight,
156
+ },
157
+ body1: {
158
+ fontSize: theme.sizes.typography.body1.fontSize,
159
+ lineHeight: theme.sizes.typography.body1.lineHeight,
160
+ fontWeight: theme.sizes.typography.body1.fontWeight,
161
+ },
162
+ body2: {
163
+ fontSize: theme.sizes.typography.body2.fontSize,
164
+ lineHeight: theme.sizes.typography.body2.lineHeight,
165
+ fontWeight: theme.sizes.typography.body2.fontWeight,
166
+ },
167
+ caption: {
168
+ fontSize: theme.sizes.typography.caption.fontSize,
169
+ lineHeight: theme.sizes.typography.caption.lineHeight,
170
+ fontWeight: theme.sizes.typography.caption.fontWeight,
171
+ },
172
+ },
173
+ weight: {
174
+ light: { fontWeight: '300' },
175
+ normal: { fontWeight: '400' },
176
+ medium: { fontWeight: '500' },
177
+ semibold: { fontWeight: '600' },
178
+ bold: { fontWeight: '700' },
179
+ } as const,
180
+ align: {
181
+ left: { textAlign: 'left' },
182
+ center: { textAlign: 'center' },
183
+ right: { textAlign: 'right' },
184
+ } as const,
185
+ // Spacing variants - all expanded inline
186
+ gap: {
187
+ xs: { gap: theme.sizes.view.xs.spacing },
188
+ sm: { gap: theme.sizes.view.sm.spacing },
189
+ md: { gap: theme.sizes.view.md.spacing },
190
+ lg: { gap: theme.sizes.view.lg.spacing },
191
+ xl: { gap: theme.sizes.view.xl.spacing },
192
+ },
193
+ padding: {
194
+ xs: { padding: theme.sizes.view.xs.padding },
195
+ sm: { padding: theme.sizes.view.sm.padding },
196
+ md: { padding: theme.sizes.view.md.padding },
197
+ lg: { padding: theme.sizes.view.lg.padding },
198
+ xl: { padding: theme.sizes.view.xl.padding },
199
+ },
200
+ paddingVertical: {
201
+ xs: { paddingVertical: theme.sizes.view.xs.padding },
202
+ sm: { paddingVertical: theme.sizes.view.sm.padding },
203
+ md: { paddingVertical: theme.sizes.view.md.padding },
204
+ lg: { paddingVertical: theme.sizes.view.lg.padding },
205
+ xl: { paddingVertical: theme.sizes.view.xl.padding },
206
+ },
207
+ paddingHorizontal: {
208
+ xs: { paddingHorizontal: theme.sizes.view.xs.padding },
209
+ sm: { paddingHorizontal: theme.sizes.view.sm.padding },
210
+ md: { paddingHorizontal: theme.sizes.view.md.padding },
211
+ lg: { paddingHorizontal: theme.sizes.view.lg.padding },
212
+ xl: { paddingHorizontal: theme.sizes.view.xl.padding },
213
+ },
214
+ } as const,
215
+ _web: {
216
+ fontFamily: 'inherit',
217
+ },
218
+ }),
219
+ }));
@@ -1,13 +1,18 @@
1
- import { StyleSheet } from "react-native-unistyles";
2
- import { Theme, Typography } from '@idealyst/theme';
3
- import {
4
- buildGapVariants,
5
- buildPaddingVariants,
6
- buildPaddingVerticalVariants,
7
- buildPaddingHorizontalVariants,
8
- } from '../utils/buildViewStyleVariants';
1
+ /**
2
+ * Text styles using defineStyle with $iterator expansion.
3
+ */
4
+ import { StyleSheet } from 'react-native-unistyles';
5
+ import { defineStyle, ThemeStyleWrapper } from '@idealyst/theme';
6
+
7
+ // Required: Unistyles must see StyleSheet usage in original source to process this file
8
+ void StyleSheet;
9
+ import type { Theme as BaseTheme } from '@idealyst/theme';
10
+ import type { TextStyle, ViewStyle } from 'react-native';
9
11
  import { TextAlignVariant, TextColorVariant, TextWeightVariant, TextTypographyVariant } from "./types";
10
12
 
13
+ // Wrap theme for $iterator support
14
+ type Theme = ThemeStyleWrapper<BaseTheme>;
15
+
11
16
  export type TextVariants = {
12
17
  typography: TextTypographyVariant;
13
18
  weight: TextWeightVariant;
@@ -15,82 +20,93 @@ export type TextVariants = {
15
20
  }
16
21
 
17
22
  /**
18
- * Create typography variants from theme
23
+ * All props available to dynamic Text style functions.
24
+ * Extensions and overrides receive these to make conditional styling decisions.
19
25
  */
20
- function createTypographyVariants(theme: Theme) {
21
- const variants: Record<string, object> = {};
26
+ export type TextStyleParams = {
27
+ /** Text color variant */
28
+ color?: TextColorVariant;
29
+ /** Typography variant (h1, h2, body1, etc.) */
30
+ typography?: TextTypographyVariant;
31
+ /** Font weight override */
32
+ weight?: TextWeightVariant;
33
+ /** Text alignment */
34
+ align?: TextAlignVariant;
35
+ }
22
36
 
23
- for (const key in theme.sizes.typography) {
24
- const typo = theme.sizes.typography[key as Typography];
25
- variants[key] = {
26
- fontSize: typo.fontSize,
27
- lineHeight: typo.lineHeight,
28
- fontWeight: typo.fontWeight,
37
+ /**
38
+ * Text style definition type for use with extendStyle/overrideStyle.
39
+ */
40
+ export interface TextStyleDef {
41
+ text: (params: TextStyleParams) => TextStyle & {
42
+ variants?: {
43
+ typography?: Record<string, TextStyle>;
44
+ weight?: Record<string, TextStyle>;
45
+ align?: Record<string, TextStyle>;
46
+ gap?: Record<string, ViewStyle>;
47
+ padding?: Record<string, ViewStyle>;
48
+ paddingVertical?: Record<string, ViewStyle>;
49
+ paddingHorizontal?: Record<string, ViewStyle>;
29
50
  };
30
- }
31
-
32
- return variants;
51
+ };
33
52
  }
34
53
 
35
- type TextStyleParams = {
36
- color?: TextColorVariant;
54
+ // Register Text style types for type-safe extendStyle/overrideStyle
55
+ declare module '@idealyst/theme' {
56
+ interface ComponentStyleRegistry {
57
+ Text: TextStyleDef;
58
+ }
37
59
  }
38
60
 
39
- function createTextStyles(theme: Theme) {
40
- return ({ color }: TextStyleParams) => {
41
- const colorValue = theme.colors.text[color ?? 'primary'] || theme.colors.text.primary;
42
-
43
- return {
44
- margin: 0,
45
- padding: 0,
46
- color: colorValue,
47
- variants: {
48
- typography: createTypographyVariants(theme),
49
- weight: {
50
- light: {
51
- fontWeight: '300',
52
- },
53
- normal: {
54
- fontWeight: '400',
55
- },
56
- medium: {
57
- fontWeight: '500',
58
- },
59
- semibold: {
60
- fontWeight: '600',
61
- },
62
- bold: {
63
- fontWeight: '700',
64
- },
65
- } as const,
66
- align: {
67
- left: {
68
- textAlign: 'left',
69
- },
70
- center: {
71
- textAlign: 'center',
72
- },
73
- right: {
74
- textAlign: 'right',
75
- },
76
- } as const,
77
- // Spacing variants from TextSpacingStyleProps
78
- gap: buildGapVariants(theme),
79
- padding: buildPaddingVariants(theme),
80
- paddingVertical: buildPaddingVerticalVariants(theme),
81
- paddingHorizontal: buildPaddingHorizontalVariants(theme),
61
+ /**
62
+ * Text styles with $iterator expansion.
63
+ *
64
+ * Babel expands:
65
+ * - theme.sizes.$typography.X → all typography keys (h1, h2, body1, etc.)
66
+ * - theme.sizes.$view.X → all view size keys (xs, sm, md, lg, xl)
67
+ */
68
+ // @ts-ignore - $iterator patterns are expanded by Babel
69
+ export const textStyles = defineStyle('Text', (theme: Theme) => ({
70
+ text: ({ color, typography, weight, align }: TextStyleParams) => ({
71
+ margin: 0,
72
+ padding: 0,
73
+ // Base color - can be overridden by extensions using any of the params
74
+ color: theme.colors.text[color ?? 'primary'] || theme.colors.text.primary,
75
+ variants: {
76
+ // Typography variants - $iterator expands for each typography key
77
+ typography: {
78
+ fontSize: theme.sizes.$typography.fontSize,
79
+ lineHeight: theme.sizes.$typography.lineHeight,
80
+ fontWeight: theme.sizes.$typography.fontWeight,
81
+ },
82
+ weight: {
83
+ light: { fontWeight: '300' },
84
+ normal: { fontWeight: '400' },
85
+ medium: { fontWeight: '500' },
86
+ semibold: { fontWeight: '600' },
87
+ bold: { fontWeight: '700' },
82
88
  } as const,
83
- _web: {
84
- fontFamily: 'inherit',
89
+ align: {
90
+ left: { textAlign: 'left' },
91
+ center: { textAlign: 'center' },
92
+ right: { textAlign: 'right' },
93
+ } as const,
94
+ // Spacing variants - $iterator expands for each view size key
95
+ gap: {
96
+ gap: theme.sizes.$view.spacing,
85
97
  },
86
- };
87
- }
88
- }
89
-
90
- // Styles are inlined here instead of in @idealyst/theme because Unistyles' Babel
91
- // transform on native cannot resolve function calls to extract variant structures.
92
- export const textStyles = StyleSheet.create((theme: Theme) => {
93
- return {
94
- text: createTextStyles(theme),
95
- };
96
- });
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
+ } as const,
108
+ _web: {
109
+ fontFamily: 'inherit',
110
+ },
111
+ }),
112
+ }));
@@ -29,9 +29,9 @@ const Text = forwardRef<HTMLSpanElement, TextProps>(({
29
29
  paddingHorizontal,
30
30
  });
31
31
 
32
- // Create the style array
32
+ // Create the style array - pass all style-affecting props to dynamic style function
33
33
  const textStyleArray = [
34
- textStyles.text({ color }),
34
+ (textStyles.text as any)({ color, typography, weight, align }),
35
35
  style,
36
36
  ];
37
37
 
package/src/Text/index.ts CHANGED
@@ -3,3 +3,4 @@ import TextComponent from './Text.web';
3
3
  export default TextComponent;
4
4
  export { TextComponent as Text };
5
5
  export * from './types';
6
+ export type { TextStyleDef, TextStyleParams, TextVariants } from './Text.styles';
@@ -0,0 +1,213 @@
1
+ import { StyleSheet } from 'react-native-unistyles';
2
+ import { Theme, StylesheetStyles, Intent, Size } from '@idealyst/theme';
3
+ import { buildSizeVariants } from '../utils/buildSizeVariants';
4
+ import {
5
+ buildMarginVariants,
6
+ buildMarginVerticalVariants,
7
+ buildMarginHorizontalVariants,
8
+ } from '../utils/buildViewStyleVariants';
9
+ import { TextAreaIntentVariant } from './types';
10
+ import { applyExtensions } from '../extensions/applyExtension';
11
+
12
+ /**
13
+ * Create size variants for textarea
14
+ */
15
+ function createTextareaSizeVariants(theme: Theme) {
16
+ return buildSizeVariants(theme, 'textarea', (size) => ({
17
+ fontSize: size.fontSize,
18
+ padding: size.padding,
19
+ lineHeight: size.lineHeight,
20
+ minHeight: size.minHeight,
21
+ }));
22
+ }
23
+
24
+ /**
25
+ * Get textarea styles based on intent, disabled, and hasError state
26
+ */
27
+ function getTextareaIntentStyles(theme: Theme, intent: TextAreaIntentVariant, disabled: boolean, hasError: boolean) {
28
+ if (disabled || hasError) {
29
+ return {} as const;
30
+ }
31
+
32
+ const intentValue = theme.intents[intent];
33
+ const baseStyles: any = {};
34
+
35
+ // For success and warning, set border color
36
+ if (intent === 'success' || intent === 'warning') {
37
+ baseStyles.borderColor = intentValue.primary;
38
+ }
39
+
40
+ // Focus styles for all intents when not disabled and not in error
41
+ baseStyles._web = {
42
+ _focus: {
43
+ borderColor: intentValue.primary,
44
+ boxShadow: `0 0 0 2px ${intentValue.primary}33`,
45
+ },
46
+ };
47
+
48
+ return baseStyles;
49
+ }
50
+
51
+ const createTextareaStyles = (theme: Theme) => {
52
+ return ({ intent, disabled, hasError }: { intent: TextAreaIntentVariant, disabled: boolean, hasError: boolean }) => {
53
+ const intentStyles = getTextareaIntentStyles(theme, intent, disabled, hasError);
54
+
55
+ return {
56
+ width: '100%',
57
+ color: theme.colors.text.primary,
58
+ backgroundColor: theme.colors.surface.primary,
59
+ borderWidth: 1,
60
+ borderStyle: 'solid',
61
+ borderColor: theme.colors.border.primary,
62
+ borderRadius: 8,
63
+ lineHeight: 'normal',
64
+ ...intentStyles,
65
+ variants: {
66
+ size: createTextareaSizeVariants(theme),
67
+ disabled: {
68
+ true: {
69
+ opacity: 0.5,
70
+ backgroundColor: theme.colors.surface.secondary,
71
+ _web: {
72
+ cursor: 'not-allowed',
73
+ },
74
+ },
75
+ false: {},
76
+ },
77
+ hasError: {
78
+ true: {
79
+ borderColor: theme.intents.error.primary,
80
+ },
81
+ false: {},
82
+ },
83
+ resize: {
84
+ none: {
85
+ _web: {
86
+ resize: 'none',
87
+ },
88
+ },
89
+ vertical: {
90
+ _web: {
91
+ resize: 'vertical',
92
+ },
93
+ },
94
+ horizontal: {
95
+ _web: {
96
+ resize: 'horizontal',
97
+ },
98
+ },
99
+ both: {
100
+ _web: {
101
+ resize: 'both',
102
+ },
103
+ },
104
+ },
105
+ },
106
+ _web: {
107
+ fontFamily: 'inherit',
108
+ outline: 'none',
109
+ transition: 'border-color 0.2s ease, box-shadow 0.2s ease',
110
+ boxSizing: 'border-box',
111
+ overflowY: 'hidden',
112
+ },
113
+ } as const;
114
+ }
115
+ }
116
+
117
+ // Helper functions to create static styles wrapped in dynamic functions
118
+ function createContainerStyles(theme: Theme) {
119
+ return () => ({
120
+ display: 'flex' as const,
121
+ flexDirection: 'column' as const,
122
+ gap: 4,
123
+ variants: {
124
+ // Spacing variants from FormInputStyleProps
125
+ margin: buildMarginVariants(theme),
126
+ marginVertical: buildMarginVerticalVariants(theme),
127
+ marginHorizontal: buildMarginHorizontalVariants(theme),
128
+ },
129
+ });
130
+ }
131
+
132
+ function createLabelStyles(theme: Theme) {
133
+ return () => ({
134
+ fontSize: 14,
135
+ fontWeight: '500' as const,
136
+ color: theme.colors.text.primary,
137
+ variants: {
138
+ disabled: {
139
+ true: {
140
+ opacity: 0.5,
141
+ },
142
+ false: {},
143
+ },
144
+ },
145
+ });
146
+ }
147
+
148
+ function createTextareaContainerStyles() {
149
+ return () => ({
150
+ position: 'relative' as const,
151
+ });
152
+ }
153
+
154
+ function createHelperTextStyles(theme: Theme) {
155
+ return () => ({
156
+ fontSize: 12,
157
+ color: theme.colors.text.secondary,
158
+ variants: {
159
+ hasError: {
160
+ true: {
161
+ color: theme.intents.error.primary,
162
+ },
163
+ false: {},
164
+ },
165
+ },
166
+ });
167
+ }
168
+
169
+ function createFooterStyles() {
170
+ return () => ({
171
+ display: 'flex' as const,
172
+ flexDirection: 'row' as const,
173
+ justifyContent: 'space-between' as const,
174
+ alignItems: 'center' as const,
175
+ gap: 4,
176
+ });
177
+ }
178
+
179
+ function createCharacterCountStyles(theme: Theme) {
180
+ return () => ({
181
+ fontSize: 12,
182
+ color: theme.colors.text.secondary,
183
+ variants: {
184
+ isNearLimit: {
185
+ true: {
186
+ color: theme.intents.warning.primary,
187
+ },
188
+ false: {},
189
+ },
190
+ isAtLimit: {
191
+ true: {
192
+ color: theme.intents.error.primary,
193
+ },
194
+ false: {},
195
+ },
196
+ },
197
+ });
198
+ }
199
+
200
+ // Styles are inlined here instead of in @idealyst/theme because Unistyles' Babel transform on native cannot resolve function calls to extract variant structures.
201
+ export const textAreaStyles = StyleSheet.create((theme: Theme) => {
202
+ // Apply extensions to main visual elements
203
+
204
+ return applyExtensions('TextArea', theme, {container: createContainerStyles(theme),
205
+ textarea: createTextareaStyles(theme),
206
+ // Additional styles (merged from return)
207
+ // Minor utility styles (not extended)
208
+ label: createLabelStyles(theme)(),
209
+ textareaContainer: createTextareaContainerStyles()(),
210
+ helperText: createHelperTextStyles(theme)(),
211
+ footer: createFooterStyles()(),
212
+ characterCount: createCharacterCountStyles(theme)()});
213
+ });