@idealyst/components 1.1.7 → 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 (105) hide show
  1. package/package.json +3 -3
  2. package/src/Accordion/Accordion.native.tsx +8 -6
  3. package/src/Accordion/Accordion.styles.old.tsx +298 -0
  4. package/src/Accordion/Accordion.styles.tsx +102 -236
  5. package/src/ActivityIndicator/ActivityIndicator.styles.old.tsx +94 -0
  6. package/src/ActivityIndicator/ActivityIndicator.styles.tsx +44 -74
  7. package/src/Alert/Alert.native.tsx +16 -6
  8. package/src/Alert/Alert.styles.old.tsx +209 -0
  9. package/src/Alert/Alert.styles.tsx +67 -149
  10. package/src/Avatar/Avatar.styles.old.tsx +99 -0
  11. package/src/Avatar/Avatar.styles.tsx +35 -80
  12. package/src/Badge/Badge.styles.old.tsx +157 -0
  13. package/src/Badge/Badge.styles.tsx +61 -121
  14. package/src/Breadcrumb/Breadcrumb.styles.old.tsx +231 -0
  15. package/src/Breadcrumb/Breadcrumb.styles.tsx +83 -200
  16. package/src/Breadcrumb/Breadcrumb.web.tsx +28 -23
  17. package/src/Button/Button.styles.tsx +89 -141
  18. package/src/Card/Card.native.tsx +7 -11
  19. package/src/Card/Card.styles.old.tsx +160 -0
  20. package/src/Card/Card.styles.tsx +105 -142
  21. package/src/Card/Card.web.tsx +5 -4
  22. package/src/Checkbox/Checkbox.native.tsx +9 -5
  23. package/src/Checkbox/Checkbox.styles.old.tsx +271 -0
  24. package/src/Checkbox/Checkbox.styles.tsx +104 -216
  25. package/src/Checkbox/Checkbox.web.tsx +6 -6
  26. package/src/Chip/Chip.styles.old.tsx +184 -0
  27. package/src/Chip/Chip.styles.tsx +34 -72
  28. package/src/Dialog/Dialog.native.tsx +7 -4
  29. package/src/Dialog/Dialog.styles.old.tsx +202 -0
  30. package/src/Dialog/Dialog.styles.tsx +69 -133
  31. package/src/Divider/Divider.styles.old.tsx +172 -0
  32. package/src/Divider/Divider.styles.tsx +62 -84
  33. package/src/Icon/Icon.native.tsx +8 -8
  34. package/src/Icon/Icon.styles.old.tsx +81 -0
  35. package/src/Icon/Icon.styles.tsx +52 -66
  36. package/src/Icon/Icon.web.tsx +43 -7
  37. package/src/Icon/IconSvg/IconSvg.web.tsx +2 -0
  38. package/src/Image/Image.styles.old.tsx +69 -0
  39. package/src/Image/Image.styles.tsx +46 -60
  40. package/src/Input/Input.native.tsx +138 -53
  41. package/src/Input/Input.styles.old.tsx +289 -0
  42. package/src/Input/Input.styles.tsx +127 -198
  43. package/src/List/List.native.tsx +5 -2
  44. package/src/List/List.styles.old.tsx +242 -0
  45. package/src/List/List.styles.tsx +179 -215
  46. package/src/List/ListItem.native.tsx +12 -6
  47. package/src/List/ListItem.web.tsx +23 -13
  48. package/src/Menu/Menu.styles.old.tsx +197 -0
  49. package/src/Menu/Menu.styles.tsx +68 -150
  50. package/src/Menu/MenuItem.native.tsx +5 -3
  51. package/src/Menu/MenuItem.styles.old.tsx +114 -0
  52. package/src/Menu/MenuItem.styles.tsx +57 -89
  53. package/src/Menu/MenuItem.web.tsx +8 -3
  54. package/src/Popover/Popover.native.tsx +10 -4
  55. package/src/Popover/Popover.styles.old.tsx +135 -0
  56. package/src/Popover/Popover.styles.tsx +51 -112
  57. package/src/Pressable/Pressable.styles.old.tsx +27 -0
  58. package/src/Pressable/Pressable.styles.tsx +35 -27
  59. package/src/Progress/Progress.styles.old.tsx +200 -0
  60. package/src/Progress/Progress.styles.tsx +75 -164
  61. package/src/RadioButton/RadioButton.native.tsx +4 -3
  62. package/src/RadioButton/RadioButton.styles.old.tsx +175 -0
  63. package/src/RadioButton/RadioButton.styles.tsx +83 -154
  64. package/src/RadioButton/RadioButton.web.tsx +2 -2
  65. package/src/SVGImage/SVGImage.styles.old.tsx +86 -0
  66. package/src/SVGImage/SVGImage.styles.tsx +35 -78
  67. package/src/Screen/Screen.native.tsx +18 -25
  68. package/src/Screen/Screen.styles.old.tsx +87 -0
  69. package/src/Screen/Screen.styles.tsx +105 -67
  70. package/src/Screen/Screen.web.tsx +1 -1
  71. package/src/Select/Select.native.tsx +42 -33
  72. package/src/Select/Select.styles.old.tsx +353 -0
  73. package/src/Select/Select.styles.tsx +223 -292
  74. package/src/Skeleton/Skeleton.styles.old.tsx +67 -0
  75. package/src/Skeleton/Skeleton.styles.tsx +29 -53
  76. package/src/Slider/Slider.styles.old.tsx +259 -0
  77. package/src/Slider/Slider.styles.tsx +153 -234
  78. package/src/Switch/Switch.native.tsx +7 -5
  79. package/src/Switch/Switch.styles.old.tsx +203 -0
  80. package/src/Switch/Switch.styles.tsx +101 -174
  81. package/src/Switch/Switch.web.tsx +5 -5
  82. package/src/TabBar/TabBar.native.tsx +3 -2
  83. package/src/TabBar/TabBar.styles.old.tsx +343 -0
  84. package/src/TabBar/TabBar.styles.tsx +145 -279
  85. package/src/Table/Table.native.tsx +18 -9
  86. package/src/Table/Table.styles.old.tsx +311 -0
  87. package/src/Table/Table.styles.tsx +152 -286
  88. package/src/Text/Text.native.tsx +1 -3
  89. package/src/Text/Text.style.demo.tsx +16 -0
  90. package/src/Text/Text.styles.old.tsx +219 -0
  91. package/src/Text/Text.styles.tsx +94 -84
  92. package/src/Text/Text.web.tsx +2 -2
  93. package/src/Text/index.ts +1 -0
  94. package/src/TextArea/TextArea.styles.old.tsx +213 -0
  95. package/src/TextArea/TextArea.styles.tsx +93 -181
  96. package/src/Tooltip/Tooltip.styles.old.tsx +82 -0
  97. package/src/Tooltip/Tooltip.styles.tsx +32 -56
  98. package/src/Video/Video.styles.old.tsx +51 -0
  99. package/src/Video/Video.styles.tsx +32 -44
  100. package/src/View/View.native.tsx +12 -14
  101. package/src/View/View.styles.old.tsx +125 -0
  102. package/src/View/View.styles.tsx +76 -106
  103. package/src/View/View.web.tsx +1 -0
  104. package/src/examples/CardExamples.tsx +0 -6
  105. package/src/extensions/extendComponent.ts +61 -0
@@ -0,0 +1,200 @@
1
+ import { StyleSheet } from 'react-native-unistyles';
2
+ import { Theme, Intent, Size } from '@idealyst/theme';
3
+ import { buildSizeVariants } from '../utils/buildSizeVariants';
4
+ import { applyExtensions } from '../extensions/applyExtension';
5
+
6
+ type ProgressSize = Size;
7
+ type ProgressIntent = Intent;
8
+
9
+ export type ProgressVariants = {
10
+ size: ProgressSize;
11
+ intent: ProgressIntent;
12
+ rounded: boolean;
13
+ }
14
+
15
+ type ProgressDynamicProps = {
16
+ intent?: ProgressIntent;
17
+ };
18
+
19
+ function createLinearTrackSizeVariants(theme: Theme) {
20
+ return buildSizeVariants(theme, 'progress', (size) => ({
21
+ height: size.linearHeight,
22
+ }));
23
+ }
24
+
25
+ function createCircularContainerSizeVariants(theme: Theme) {
26
+ return buildSizeVariants(theme, 'progress', (size) => ({
27
+ width: size.circularSize,
28
+ height: size.circularSize,
29
+ }));
30
+ }
31
+
32
+ function createLabelSizeVariants(theme: Theme) {
33
+ return buildSizeVariants(theme, 'progress', (size) => ({
34
+ fontSize: size.labelFontSize,
35
+ }));
36
+ }
37
+
38
+ function createCircularLabelSizeVariants(theme: Theme) {
39
+ return buildSizeVariants(theme, 'progress', (size) => ({
40
+ fontSize: size.circularLabelFontSize,
41
+ }));
42
+ }
43
+
44
+ /**
45
+ * Get bar background color based on intent
46
+ */
47
+ function getBarBackgroundColor(theme: Theme, intent: ProgressIntent): string {
48
+ return theme.intents[intent].primary;
49
+ }
50
+
51
+ /**
52
+ * Create dynamic linear bar styles
53
+ */
54
+ function createLinearBarStyles(theme: Theme) {
55
+ return ({ intent = 'primary' }: ProgressDynamicProps) => {
56
+ return {
57
+ height: '100%' as const,
58
+ backgroundColor: getBarBackgroundColor(theme, intent),
59
+ variants: {
60
+ rounded: {
61
+ true: { borderRadius: 9999 },
62
+ false: { borderRadius: 0 },
63
+ },
64
+ },
65
+ _web: {
66
+ transition: 'width 0.3s ease' as const,
67
+ },
68
+ } as const;
69
+ };
70
+ }
71
+
72
+ /**
73
+ * Create dynamic indeterminate bar styles
74
+ */
75
+ function createIndeterminateBarStyles(theme: Theme) {
76
+ return ({ intent = 'primary' }: ProgressDynamicProps) => {
77
+ return {
78
+ position: 'absolute' as const,
79
+ height: '100%' as const,
80
+ width: '40%' as const,
81
+ backgroundColor: getBarBackgroundColor(theme, intent),
82
+ variants: {
83
+ rounded: {
84
+ true: { borderRadius: 9999 },
85
+ false: { borderRadius: 0 },
86
+ },
87
+ },
88
+ } as const;
89
+ };
90
+ }
91
+
92
+ /**
93
+ * Create dynamic circular bar styles
94
+ */
95
+ function createCircularBarStyles(theme: Theme) {
96
+ return ({ intent = 'primary' }: ProgressDynamicProps) => {
97
+ return {
98
+ _web: {
99
+ stroke: getBarBackgroundColor(theme, intent),
100
+ },
101
+ } as const;
102
+ };
103
+ }
104
+
105
+ /**
106
+ * Create container styles
107
+ */
108
+ function createContainerStyles() {
109
+ return () => ({
110
+ gap: 4 as const,
111
+ });
112
+ }
113
+
114
+ /**
115
+ * Create linear track styles
116
+ */
117
+ function createLinearTrackStyles(theme: Theme) {
118
+ return () => ({
119
+ backgroundColor: theme.colors.border.secondary,
120
+ overflow: 'hidden' as const,
121
+ position: 'relative' as const,
122
+ variants: {
123
+ size: createLinearTrackSizeVariants(theme),
124
+ rounded: {
125
+ true: { borderRadius: 9999 },
126
+ false: { borderRadius: 0 },
127
+ },
128
+ },
129
+ });
130
+ }
131
+
132
+ /**
133
+ * Create circular container styles
134
+ */
135
+ function createCircularContainerStyles(theme: Theme) {
136
+ return () => ({
137
+ alignItems: 'center' as const,
138
+ justifyContent: 'center' as const,
139
+ position: 'relative' as const,
140
+ variants: {
141
+ size: createCircularContainerSizeVariants(theme),
142
+ } as const,
143
+ });
144
+ }
145
+
146
+ /**
147
+ * Create circular track styles
148
+ */
149
+ function createCircularTrackStyles(theme: Theme) {
150
+ return () => ({
151
+ _web: {
152
+ stroke: theme.colors.border.secondary,
153
+ },
154
+ });
155
+ }
156
+
157
+ /**
158
+ * Create label styles
159
+ */
160
+ function createLabelStyles(theme: Theme) {
161
+ return () => ({
162
+ color: theme.colors.text.primary,
163
+ textAlign: 'center' as const,
164
+ variants: {
165
+ size: createLabelSizeVariants(theme),
166
+ },
167
+ });
168
+ }
169
+
170
+ /**
171
+ * Create circular label styles
172
+ */
173
+ function createCircularLabelStyles(theme: Theme) {
174
+ return () => ({
175
+ position: 'absolute' as const,
176
+ fontWeight: '600' as const,
177
+ color: theme.colors.text.primary,
178
+ variants: {
179
+ size: createCircularLabelSizeVariants(theme),
180
+ },
181
+ });
182
+ }
183
+
184
+ // Styles are inlined here instead of in @idealyst/theme because Unistyles' Babel
185
+ // transform on native cannot resolve function calls to extract variant structures.
186
+ export const progressStyles = StyleSheet.create((theme: Theme) => {
187
+ // Apply extensions to main visual elements
188
+
189
+ return applyExtensions('Progress', theme, {container: createContainerStyles(),
190
+ linearTrack: createLinearTrackStyles(theme),
191
+ linearBar: createLinearBarStyles(theme),
192
+ // Additional styles (merged from return)
193
+ // Minor utility styles (not extended)
194
+ indeterminateBar: createIndeterminateBarStyles(theme),
195
+ circularContainer: createCircularContainerStyles(theme)(),
196
+ circularTrack: createCircularTrackStyles(theme)(),
197
+ circularBar: createCircularBarStyles(theme),
198
+ label: createLabelStyles(theme)(),
199
+ circularLabel: createCircularLabelStyles(theme)()});
200
+ });
@@ -1,204 +1,115 @@
1
+ /**
2
+ * Progress styles using defineStyle with $iterator expansion.
3
+ */
1
4
  import { StyleSheet } from 'react-native-unistyles';
2
- import { Theme, Intent, Size } from '@idealyst/theme';
3
- import { buildSizeVariants } from '../utils/buildSizeVariants';
4
- import { applyExtensions } from '../extensions/applyExtension';
5
+ import { defineStyle, ThemeStyleWrapper } from '@idealyst/theme';
6
+ import type { Theme as BaseTheme, Intent, Size } from '@idealyst/theme';
5
7
 
6
- type ProgressSize = Size;
7
- type ProgressIntent = Intent;
8
+ // Required: Unistyles must see StyleSheet usage in original source to process this file
9
+ void StyleSheet;
8
10
 
9
- export type ProgressVariants = {
10
- size: ProgressSize;
11
- intent: ProgressIntent;
12
- rounded: boolean;
13
- }
11
+ // Wrap theme for $iterator support
12
+ type Theme = ThemeStyleWrapper<BaseTheme>;
14
13
 
15
- type ProgressDynamicProps = {
16
- intent?: ProgressIntent;
14
+ export type ProgressDynamicProps = {
15
+ size?: Size;
16
+ intent?: Intent;
17
+ rounded?: boolean;
17
18
  };
18
19
 
19
- function createLinearTrackSizeVariants(theme: Theme) {
20
- return buildSizeVariants(theme, 'progress', (size) => ({
21
- height: size.linearHeight,
22
- }));
23
- }
24
-
25
- function createCircularContainerSizeVariants(theme: Theme) {
26
- return buildSizeVariants(theme, 'progress', (size) => ({
27
- width: size.circularSize,
28
- height: size.circularSize,
29
- }));
30
- }
31
-
32
- function createLabelSizeVariants(theme: Theme) {
33
- return buildSizeVariants(theme, 'progress', (size) => ({
34
- fontSize: size.labelFontSize,
35
- }));
36
- }
37
-
38
- function createCircularLabelSizeVariants(theme: Theme) {
39
- return buildSizeVariants(theme, 'progress', (size) => ({
40
- fontSize: size.circularLabelFontSize,
41
- }));
42
- }
43
-
44
20
  /**
45
- * Get bar background color based on intent
21
+ * Progress styles with intent-based coloring.
46
22
  */
47
- function getBarBackgroundColor(theme: Theme, intent: ProgressIntent): string {
48
- return theme.intents[intent].primary;
49
- }
23
+ export const progressStyles = defineStyle('Progress', (theme: Theme) => ({
24
+ container: (_props: ProgressDynamicProps) => ({
25
+ gap: 4 as const,
26
+ }),
50
27
 
51
- /**
52
- * Create dynamic linear bar styles
53
- */
54
- function createLinearBarStyles(theme: Theme) {
55
- return ({ intent = 'primary' }: ProgressDynamicProps) => {
56
- return {
57
- height: '100%' as const,
58
- backgroundColor: getBarBackgroundColor(theme, intent),
59
- variants: {
60
- rounded: {
61
- true: { borderRadius: 9999 },
62
- false: { borderRadius: 0 },
63
- },
64
- },
65
- _web: {
66
- transition: 'width 0.3s ease' as const,
28
+ linearTrack: (_props: ProgressDynamicProps) => ({
29
+ backgroundColor: theme.colors.border.secondary,
30
+ overflow: 'hidden' as const,
31
+ position: 'relative' as const,
32
+ variants: {
33
+ // $iterator expands for each progress size
34
+ size: {
35
+ height: theme.sizes.$progress.linearHeight,
67
36
  },
68
- } as const;
69
- };
70
- }
71
-
72
- /**
73
- * Create dynamic indeterminate bar styles
74
- */
75
- function createIndeterminateBarStyles(theme: Theme) {
76
- return ({ intent = 'primary' }: ProgressDynamicProps) => {
77
- return {
78
- position: 'absolute' as const,
79
- height: '100%' as const,
80
- width: '40%' as const,
81
- backgroundColor: getBarBackgroundColor(theme, intent),
82
- variants: {
83
- rounded: {
84
- true: { borderRadius: 9999 },
85
- false: { borderRadius: 0 },
86
- },
37
+ rounded: {
38
+ true: { borderRadius: 9999 },
39
+ false: { borderRadius: 0 },
87
40
  },
88
- } as const;
89
- };
90
- }
41
+ },
42
+ }),
91
43
 
92
- /**
93
- * Create dynamic circular bar styles
94
- */
95
- function createCircularBarStyles(theme: Theme) {
96
- return ({ intent = 'primary' }: ProgressDynamicProps) => {
97
- return {
98
- _web: {
99
- stroke: getBarBackgroundColor(theme, intent),
44
+ linearBar: ({ intent = 'primary' }: ProgressDynamicProps) => ({
45
+ height: '100%' as const,
46
+ backgroundColor: theme.intents[intent].primary,
47
+ variants: {
48
+ rounded: {
49
+ true: { borderRadius: 9999 },
50
+ false: { borderRadius: 0 },
100
51
  },
101
- } as const;
102
- };
103
- }
104
-
105
- /**
106
- * Create container styles
107
- */
108
- function createContainerStyles() {
109
- return () => ({
110
- gap: 4 as const,
111
- });
112
- }
52
+ },
53
+ _web: {
54
+ transition: 'width 0.3s ease' as const,
55
+ },
56
+ }),
113
57
 
114
- /**
115
- * Create linear track styles
116
- */
117
- function createLinearTrackStyles(theme: Theme) {
118
- return () => ({
119
- backgroundColor: theme.colors.border.secondary,
120
- overflow: 'hidden' as const,
121
- position: 'relative' as const,
58
+ indeterminateBar: ({ intent = 'primary' }: ProgressDynamicProps) => ({
59
+ position: 'absolute' as const,
60
+ height: '100%' as const,
61
+ width: '40%' as const,
62
+ backgroundColor: theme.intents[intent].primary,
122
63
  variants: {
123
- size: createLinearTrackSizeVariants(theme),
124
64
  rounded: {
125
65
  true: { borderRadius: 9999 },
126
66
  false: { borderRadius: 0 },
127
67
  },
128
68
  },
129
- });
130
- }
69
+ }),
131
70
 
132
- /**
133
- * Create circular container styles
134
- */
135
- function createCircularContainerStyles(theme: Theme) {
136
- return () => ({
71
+ circularContainer: (_props: ProgressDynamicProps) => ({
137
72
  alignItems: 'center' as const,
138
73
  justifyContent: 'center' as const,
139
74
  position: 'relative' as const,
140
75
  variants: {
141
- size: createCircularContainerSizeVariants(theme),
142
- } as const,
143
- });
144
- }
76
+ size: {
77
+ width: theme.sizes.$progress.circularSize,
78
+ height: theme.sizes.$progress.circularSize,
79
+ },
80
+ },
81
+ }),
145
82
 
146
- /**
147
- * Create circular track styles
148
- */
149
- function createCircularTrackStyles(theme: Theme) {
150
- return () => ({
83
+ circularTrack: (_props: ProgressDynamicProps) => ({
151
84
  _web: {
152
85
  stroke: theme.colors.border.secondary,
153
86
  },
154
- });
155
- }
87
+ }),
156
88
 
157
- /**
158
- * Create label styles
159
- */
160
- function createLabelStyles(theme: Theme) {
161
- return () => ({
89
+ circularBar: ({ intent = 'primary' }: ProgressDynamicProps) => ({
90
+ _web: {
91
+ stroke: theme.intents[intent].primary,
92
+ },
93
+ }),
94
+
95
+ label: (_props: ProgressDynamicProps) => ({
162
96
  color: theme.colors.text.primary,
163
97
  textAlign: 'center' as const,
164
98
  variants: {
165
- size: createLabelSizeVariants(theme),
99
+ size: {
100
+ fontSize: theme.sizes.$progress.labelFontSize,
101
+ },
166
102
  },
167
- });
168
- }
103
+ }),
169
104
 
170
- /**
171
- * Create circular label styles
172
- */
173
- function createCircularLabelStyles(theme: Theme) {
174
- return () => ({
105
+ circularLabel: (_props: ProgressDynamicProps) => ({
175
106
  position: 'absolute' as const,
176
107
  fontWeight: '600' as const,
177
108
  color: theme.colors.text.primary,
178
109
  variants: {
179
- size: createCircularLabelSizeVariants(theme),
110
+ size: {
111
+ fontSize: theme.sizes.$progress.circularLabelFontSize,
112
+ },
180
113
  },
181
- });
182
- }
183
-
184
- // Styles are inlined here instead of in @idealyst/theme because Unistyles' Babel
185
- // transform on native cannot resolve function calls to extract variant structures.
186
- export const progressStyles = StyleSheet.create((theme: Theme) => {
187
- // Apply extensions to main visual elements
188
- const extended = applyExtensions('Progress', theme, {
189
- container: createContainerStyles(),
190
- linearTrack: createLinearTrackStyles(theme),
191
- linearBar: createLinearBarStyles(theme),
192
- });
193
-
194
- return {
195
- ...extended,
196
- // Minor utility styles (not extended)
197
- indeterminateBar: createIndeterminateBarStyles(theme),
198
- circularContainer: createCircularContainerStyles(theme)(),
199
- circularTrack: createCircularTrackStyles(theme)(),
200
- circularBar: createCircularBarStyles(theme),
201
- label: createLabelStyles(theme)(),
202
- circularLabel: createCircularLabelStyles(theme)(),
203
- };
204
- });
114
+ }),
115
+ }));
@@ -101,10 +101,11 @@ const RadioButton = forwardRef<ComponentRef<typeof Pressable>, RadioButtonProps>
101
101
  outputRange: [0, 1],
102
102
  });
103
103
 
104
- // Get dynamic styles
104
+ // Get dynamic styles - call as functions for theme reactivity
105
105
  const containerStyle = (radioButtonStyles.container as any)({});
106
- const radioStyle = (radioButtonStyles.radio as any)({ intent });
106
+ const radioStyle = (radioButtonStyles.radio as any)({ intent, checked, disabled });
107
107
  const radioDotStyle = (radioButtonStyles.radioDot as any)({ intent });
108
+ const labelStyle = (radioButtonStyles.label as any)({ disabled });
108
109
 
109
110
  return (
110
111
  <Pressable
@@ -127,7 +128,7 @@ const RadioButton = forwardRef<ComponentRef<typeof Pressable>, RadioButtonProps>
127
128
  />
128
129
  </View>
129
130
  {label && (
130
- <Text style={radioButtonStyles.label}>
131
+ <Text style={labelStyle}>
131
132
  {label}
132
133
  </Text>
133
134
  )}
@@ -0,0 +1,175 @@
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 { applyExtensions } from '../extensions/applyExtension';
10
+
11
+ type RadioButtonSize = Size;
12
+ type RadioButtonIntent = Intent;
13
+ type RadioGroupOrientation = 'horizontal' | 'vertical';
14
+
15
+ type RadioButtonVariants = {
16
+ size: RadioButtonSize;
17
+ intent: RadioButtonIntent;
18
+ checked: boolean;
19
+ disabled: boolean;
20
+ }
21
+
22
+ type RadioGroupVariants = {
23
+ orientation: RadioGroupOrientation;
24
+ }
25
+
26
+ export type ExpandedRadioButtonStyles = StylesheetStyles<keyof RadioButtonVariants>;
27
+ export type ExpandedRadioGroupStyles = StylesheetStyles<keyof RadioGroupVariants>;
28
+
29
+ export type RadioButtonStylesheet = {
30
+ container: ExpandedRadioButtonStyles;
31
+ radio: ExpandedRadioButtonStyles;
32
+ radioDot: ExpandedRadioButtonStyles;
33
+ label: ExpandedRadioButtonStyles;
34
+ groupContainer: ExpandedRadioGroupStyles;
35
+ }
36
+
37
+ function createRadioSizeVariants(theme: Theme) {
38
+ return buildSizeVariants(theme, 'radioButton', (size) => ({
39
+ width: size.radioSize,
40
+ height: size.radioSize,
41
+ }));
42
+ }
43
+
44
+ function createCheckedVariants(theme: Theme, intent: RadioButtonIntent) {
45
+ const intentValue = theme.intents[intent];
46
+ return {
47
+ true: {
48
+ borderColor: intentValue.primary,
49
+ },
50
+ false: {
51
+ borderColor: theme.colors.border.primary,
52
+ },
53
+ } as const;
54
+ }
55
+
56
+ function createRadioDotSizeVariants(theme: Theme) {
57
+ return buildSizeVariants(theme, 'radioButton', (size) => ({
58
+ width: size.radioDotSize,
59
+ height: size.radioDotSize,
60
+ }));
61
+ }
62
+
63
+ function createRadioDotIntentColor(theme: Theme, intent: RadioButtonIntent) {
64
+ return theme.intents[intent].primary;
65
+ }
66
+
67
+ function createRadioStyles(theme: Theme) {
68
+ return ({ intent }: Partial<RadioButtonVariants>) => {
69
+ return {
70
+ borderRadius: 9999,
71
+ borderWidth: 1.5,
72
+ borderStyle: 'solid',
73
+ alignItems: 'center',
74
+ justifyContent: 'center',
75
+ backgroundColor: theme.colors.surface.primary,
76
+ variants: {
77
+ size: createRadioSizeVariants(theme),
78
+ checked: createCheckedVariants(theme, intent),
79
+ disabled: {
80
+ true: {
81
+ opacity: 0.5,
82
+ backgroundColor: theme.colors.surface.tertiary,
83
+ _web: {
84
+ cursor: 'not-allowed',
85
+ },
86
+ },
87
+ false: {
88
+ opacity: 1,
89
+ backgroundColor: theme.colors.surface.primary,
90
+ _web: {
91
+ cursor: 'pointer',
92
+ _hover: {
93
+ opacity: 0.8,
94
+ },
95
+ _active: {
96
+ opacity: 0.6,
97
+ },
98
+ },
99
+ },
100
+ },
101
+ },
102
+ _web: {
103
+ transition: 'all 0.2s ease',
104
+ },
105
+ } as const;
106
+ }
107
+ }
108
+
109
+ function createRadioDotStyles(theme: Theme) {
110
+ return ({ intent }: Partial<RadioButtonVariants>) => {
111
+ return {
112
+ borderRadius: 9999,
113
+ backgroundColor: createRadioDotIntentColor(theme, intent),
114
+ variants: {
115
+ size: createRadioDotSizeVariants(theme),
116
+ },
117
+ } as const;
118
+ }
119
+ }
120
+
121
+ // Container style creator for extension support
122
+ function createContainerStyles(theme: Theme) {
123
+ return () => ({
124
+ flexDirection: 'row' as const,
125
+ alignItems: 'center' as const,
126
+ paddingVertical: 4,
127
+ variants: {
128
+ size: buildSizeVariants(theme, 'radioButton', (size) => ({
129
+ gap: size.gap,
130
+ })),
131
+ margin: buildMarginVariants(theme),
132
+ marginVertical: buildMarginVerticalVariants(theme),
133
+ marginHorizontal: buildMarginHorizontalVariants(theme),
134
+ } as const,
135
+ });
136
+ }
137
+
138
+ // Styles are inlined here instead of in @idealyst/theme because Unistyles' Babel
139
+ // transform on native cannot resolve function calls to extract variant structures.
140
+ export const radioButtonStyles = StyleSheet.create((theme: Theme) => {
141
+ // Apply extensions to main visual elements
142
+
143
+ return applyExtensions('RadioButton', theme, {container: createContainerStyles(theme),
144
+ radio: createRadioStyles(theme),
145
+ radioDot: createRadioDotStyles(theme),
146
+ // Additional styles (merged from return)
147
+ // Minor utility styles
148
+ label: {
149
+ color: theme.colors.text.primary,
150
+ variants: {
151
+ size: buildSizeVariants(theme, 'radioButton', (size) => ({
152
+ fontSize: size.fontSize,
153
+ })),
154
+ disabled: {
155
+ true: { opacity: 0.5 },
156
+ false: { opacity: 1 },
157
+ },
158
+ },
159
+ },
160
+ groupContainer: {
161
+ gap: 4,
162
+ variants: {
163
+ orientation: {
164
+ horizontal: {
165
+ flexDirection: 'row',
166
+ flexWrap: 'wrap',
167
+ gap: 16,
168
+ },
169
+ vertical: {
170
+ flexDirection: 'column',
171
+ },
172
+ },
173
+ },
174
+ }});
175
+ });