@idealyst/components 1.2.13 → 1.2.15

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 (95) hide show
  1. package/package.json +3 -3
  2. package/src/Accordion/Accordion.web.tsx +1 -1
  3. package/src/ActivityIndicator/ActivityIndicator.native.tsx +3 -3
  4. package/src/ActivityIndicator/ActivityIndicator.web.tsx +3 -3
  5. package/src/Alert/Alert.native.tsx +1 -1
  6. package/src/Alert/Alert.web.tsx +1 -1
  7. package/src/Avatar/Avatar.native.tsx +1 -1
  8. package/src/Badge/Badge.web.tsx +6 -2
  9. package/src/Badge/types.ts +5 -0
  10. package/src/Breadcrumb/Breadcrumb.native.tsx +20 -21
  11. package/src/Button/Button.native.tsx +3 -3
  12. package/src/Button/Button.web.tsx +5 -1
  13. package/src/Button/types.ts +5 -0
  14. package/src/Card/Card.web.tsx +4 -1
  15. package/src/Card/types.ts +5 -0
  16. package/src/Dialog/Dialog.native.tsx +3 -3
  17. package/src/Divider/Divider.web.tsx +2 -2
  18. package/src/Icon/Icon.web.tsx +2 -2
  19. package/src/Icon/types.ts +3 -0
  20. package/src/Image/Image.styles.tsx +5 -5
  21. package/src/Image/Image.web.tsx +3 -3
  22. package/src/List/List.native.tsx +1 -2
  23. package/src/List/List.web.tsx +1 -2
  24. package/src/List/ListSection.web.tsx +3 -3
  25. package/src/Menu/Menu.web.tsx +8 -10
  26. package/src/Menu/MenuItem.web.tsx +1 -1
  27. package/src/Popover/Popover.web.tsx +1 -1
  28. package/src/Pressable/Pressable.web.tsx +1 -1
  29. package/src/Progress/Progress.styles.tsx +76 -30
  30. package/src/Progress/Progress.web.tsx +13 -15
  31. package/src/SVGImage/SVGImage.web.tsx +1 -1
  32. package/src/Select/Select.web.tsx +2 -2
  33. package/src/Skeleton/Skeleton.native.tsx +3 -3
  34. package/src/Skeleton/Skeleton.web.tsx +3 -3
  35. package/src/Slider/Slider.native.tsx +2 -2
  36. package/src/Slider/Slider.styles.tsx +131 -44
  37. package/src/Slider/Slider.web.tsx +22 -22
  38. package/src/TabBar/TabBar.native.tsx +2 -2
  39. package/src/Text/Text.web.tsx +29 -3
  40. package/src/Text/types.ts +14 -1
  41. package/src/TextArea/TextArea.styles.tsx +96 -57
  42. package/src/TextArea/TextArea.web.tsx +19 -28
  43. package/src/Tooltip/Tooltip.web.tsx +3 -3
  44. package/src/Video/Video.styles.tsx +3 -3
  45. package/src/Video/Video.web.tsx +1 -1
  46. package/src/View/View.styles.tsx +2 -2
  47. package/src/View/View.web.tsx +93 -9
  48. package/src/View/types.ts +5 -1
  49. package/src/examples/ViewExamples.tsx +34 -0
  50. package/src/extensions/index.ts +0 -7
  51. package/src/hooks/useMergeRefs.ts +12 -6
  52. package/src/index.native.ts +1 -1
  53. package/src/index.ts +1 -1
  54. package/src/utils/accessibility/keyboardPatterns.ts +4 -0
  55. package/src/utils/accessibility/types.ts +5 -1
  56. package/src/utils/accessibility/useAnnounce.ts +1 -1
  57. package/src/utils/accessibility/useKeyboardNavigation.ts +1 -1
  58. package/src/utils/index.ts +0 -3
  59. package/src/utils/viewStyleProps.ts +2 -0
  60. package/src/Accordion/Accordion.styles.old.tsx +0 -298
  61. package/src/ActivityIndicator/ActivityIndicator.styles.old.tsx +0 -94
  62. package/src/Alert/Alert.styles.old.tsx +0 -209
  63. package/src/Avatar/Avatar.styles.old.tsx +0 -99
  64. package/src/Badge/Badge.styles.old.tsx +0 -157
  65. package/src/Breadcrumb/Breadcrumb.styles.old.tsx +0 -231
  66. package/src/Card/Card.styles.old.tsx +0 -160
  67. package/src/Checkbox/Checkbox.styles.old.tsx +0 -271
  68. package/src/Chip/Chip.styles.old.tsx +0 -184
  69. package/src/Dialog/Dialog.styles.old.tsx +0 -202
  70. package/src/Divider/Divider.styles.old.tsx +0 -172
  71. package/src/Icon/Icon.styles.old.tsx +0 -81
  72. package/src/Image/Image.styles.old.tsx +0 -69
  73. package/src/Input/Input.styles.old.tsx +0 -289
  74. package/src/List/List.styles.old.tsx +0 -242
  75. package/src/Menu/Menu.styles.old.tsx +0 -197
  76. package/src/Menu/MenuItem.styles.old.tsx +0 -114
  77. package/src/Popover/Popover.styles.old.tsx +0 -135
  78. package/src/Pressable/Pressable.styles.old.tsx +0 -27
  79. package/src/Progress/Progress.styles.old.tsx +0 -200
  80. package/src/RadioButton/RadioButton.styles.old.tsx +0 -175
  81. package/src/SVGImage/SVGImage.styles.old.tsx +0 -86
  82. package/src/Screen/Screen.styles.old.tsx +0 -87
  83. package/src/Select/Select.styles.old.tsx +0 -353
  84. package/src/Skeleton/Skeleton.styles.old.tsx +0 -67
  85. package/src/Slider/Slider.styles.old.tsx +0 -259
  86. package/src/Switch/Switch.styles.old.tsx +0 -203
  87. package/src/TabBar/TabBar.styles.old.tsx +0 -343
  88. package/src/Table/Table.styles.old.tsx +0 -311
  89. package/src/Text/Text.styles.old.tsx +0 -219
  90. package/src/TextArea/TextArea.styles.old.tsx +0 -213
  91. package/src/Tooltip/Tooltip.styles.old.tsx +0 -82
  92. package/src/Video/Video.styles.old.tsx +0 -51
  93. package/src/View/View.styles.old.tsx +0 -125
  94. package/src/extensions/applyExtension.ts +0 -210
  95. package/src/utils/buildSizeVariants.ts +0 -16
@@ -1,175 +0,0 @@
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
- });
@@ -1,86 +0,0 @@
1
- import { StyleSheet } from 'react-native-unistyles';
2
- import { Theme, StylesheetStyles, Intent} from '@idealyst/theme';
3
- import { applyExtensions } from '../extensions/applyExtension';
4
-
5
- type SVGImageIntent = Intent;
6
-
7
- type SVGImageVariants = {
8
- intent: SVGImageIntent;
9
- }
10
-
11
- export type ExpandedSVGImageStyles = StylesheetStyles<keyof SVGImageVariants>;
12
-
13
- export type SVGImageStylesheet = {
14
- container: ExpandedSVGImageStyles;
15
- image: ExpandedSVGImageStyles;
16
- }
17
-
18
- function createContainerIntentVariants(theme: Theme) {
19
- return {
20
- primary: {
21
- filter: `brightness(0) saturate(100%) invert(27%) sepia(51%) saturate(2878%) hue-rotate(346deg) brightness(104%) contrast(97%)`,
22
- },
23
- success: {
24
- filter: `brightness(0) saturate(100%) invert(64%) sepia(88%) saturate(3323%) hue-rotate(84deg) brightness(119%) contrast(119%)`,
25
- },
26
- error: {
27
- filter: `brightness(0) saturate(100%) invert(23%) sepia(89%) saturate(7395%) hue-rotate(4deg) brightness(102%) contrast(118%)`,
28
- },
29
- warning: {
30
- filter: `brightness(0) saturate(100%) invert(54%) sepia(98%) saturate(4341%) hue-rotate(21deg) brightness(101%) contrast(101%)`,
31
- },
32
- neutral: {
33
- filter: `brightness(0) saturate(100%) invert(52%) sepia(23%) saturate(3207%) hue-rotate(314deg) brightness(99%) contrast(96%)`,
34
- },
35
- info: {
36
- filter: `brightness(0) saturate(100%) invert(58%) sepia(96%) saturate(2582%) hue-rotate(165deg) brightness(99%) contrast(91%)`,
37
- },
38
- };
39
- }
40
-
41
- function createContainerNativeIntentVariants(theme: Theme) {
42
- const variants: Record<SVGImageIntent, any> = {} as any;
43
- for (const intent in theme.intents) {
44
- variants[intent as SVGImageIntent] = {
45
- tintColor: theme.intents[intent as SVGImageIntent].primary,
46
- };
47
- }
48
- return variants;
49
- }
50
-
51
- // Style creators for extension support
52
- function createContainerStyles(theme: Theme) {
53
- return () => ({
54
- alignItems: 'center' as const,
55
- justifyContent: 'center' as const,
56
- variants: {
57
- intent: createContainerIntentVariants(theme),
58
- },
59
- _web: {
60
- userSelect: 'none',
61
- },
62
- _native: {
63
- variants: {
64
- intent: createContainerNativeIntentVariants(theme),
65
- },
66
- },
67
- });
68
- }
69
-
70
- // Styles are inlined here instead of in @idealyst/theme because Unistyles' Babel
71
- // transform on native cannot resolve function calls to extract variant structures.
72
- // @ts-ignore - TS language server needs restart to pick up theme structure changes
73
- export const svgImageStyles = StyleSheet.create((theme: Theme) => {
74
- // Apply extensions to main visual elements
75
-
76
- return applyExtensions('SVGImage', theme, {container: createContainerStyles(theme),
77
- // Additional styles (merged from return)
78
- // Minor utility styles (not extended)
79
- image: {
80
- _web: {
81
- display: 'block',
82
- maxWidth: '100%',
83
- height: 'auto',
84
- },
85
- }});
86
- });
@@ -1,87 +0,0 @@
1
- import { StyleSheet } from 'react-native-unistyles';
2
- import { Theme } from '@idealyst/theme';
3
- import {
4
- buildGapVariants,
5
- buildPaddingVariants,
6
- buildPaddingVerticalVariants,
7
- buildPaddingHorizontalVariants,
8
- buildMarginVariants,
9
- buildMarginVerticalVariants,
10
- buildMarginHorizontalVariants,
11
- } from '../utils/buildViewStyleVariants';
12
- import { applyExtensions } from '../extensions/applyExtension';
13
-
14
- function generateBackgroundVariants(theme: Theme) {
15
- return {
16
- primary: { backgroundColor: theme.colors.surface.primary },
17
- secondary: { backgroundColor: theme.colors.surface.secondary },
18
- tertiary: { backgroundColor: theme.colors.surface.tertiary },
19
- inverse: { backgroundColor: theme.colors.surface.inverse },
20
- 'inverse-secondary': { backgroundColor: theme.colors.surface['inverse-secondary'] },
21
- 'inverse-tertiary': { backgroundColor: theme.colors.surface['inverse-tertiary'] },
22
- transparent: { backgroundColor: 'transparent' },
23
- };
24
- }
25
-
26
- /**
27
- * Create dynamic screen styles.
28
- * Returns a function to ensure Unistyles can track theme changes.
29
- */
30
- function createScreenStyles(theme: Theme) {
31
- return (_props?: {}) => ({
32
- flex: 1,
33
- variants: {
34
- background: generateBackgroundVariants(theme),
35
- safeArea: {
36
- true: {},
37
- false: {},
38
- },
39
- gap: buildGapVariants(theme),
40
- padding: buildPaddingVariants(theme),
41
- paddingVertical: buildPaddingVerticalVariants(theme),
42
- paddingHorizontal: buildPaddingHorizontalVariants(theme),
43
- margin: buildMarginVariants(theme),
44
- marginVertical: buildMarginVerticalVariants(theme),
45
- marginHorizontal: buildMarginHorizontalVariants(theme),
46
- },
47
- _web: {
48
- overflow: 'auto',
49
- display: 'flex',
50
- flexDirection: 'column',
51
- minHeight: '100%',
52
- boxSizing: 'border-box',
53
- },
54
- });
55
- }
56
-
57
- /**
58
- * Create dynamic screen content styles for ScrollView.
59
- * No flex: 1 so content can grow beyond screen height.
60
- */
61
- function createScreenContentStyles(theme: Theme) {
62
- return (_props?: {}) => ({
63
- variants: {
64
- background: generateBackgroundVariants(theme),
65
- safeArea: {
66
- true: {},
67
- false: {},
68
- },
69
- gap: buildGapVariants(theme),
70
- padding: buildPaddingVariants(theme),
71
- paddingVertical: buildPaddingVerticalVariants(theme),
72
- paddingHorizontal: buildPaddingHorizontalVariants(theme),
73
- margin: buildMarginVariants(theme),
74
- marginVertical: buildMarginVerticalVariants(theme),
75
- marginHorizontal: buildMarginHorizontalVariants(theme),
76
- },
77
- });
78
- }
79
-
80
- // Styles use applyExtensions to enable theme extensions and ensure proper
81
- // reactivity with Unistyles' native Shadow Tree updates.
82
- export const screenStyles = StyleSheet.create((theme: Theme) => {
83
- return applyExtensions('Screen', theme, {
84
- screen: createScreenStyles(theme),
85
- screenContent: createScreenContentStyles(theme),
86
- });
87
- });
@@ -1,353 +0,0 @@
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 { SelectIntentVariant } from './types';
10
- import { applyExtensions } from '../extensions/applyExtension';
11
-
12
- // Type definitions
13
- type SelectSize = Size;
14
- type SelectType = 'outlined' | 'filled';
15
-
16
- type SelectTriggerVariants = {
17
- type: SelectType;
18
- size: SelectSize;
19
- intent: SelectIntentVariant;
20
- disabled: boolean;
21
- error: boolean;
22
- focused: boolean;
23
- }
24
-
25
-
26
- export type ExpandedSelectTriggerStyles = StylesheetStyles<keyof SelectTriggerVariants>;
27
- export type ExpandedSelectStyles = StylesheetStyles<never>;
28
-
29
- function createTriggerTypeVariants(theme: Theme) {
30
- return {
31
- outlined: {
32
- backgroundColor: theme.colors.surface.primary,
33
- borderColor: theme.colors.border.primary,
34
- _web: {
35
- border: `1px solid ${theme.colors.border.primary}`,
36
- },
37
- },
38
- filled: {
39
- backgroundColor: theme.colors.surface.secondary,
40
- borderColor: 'transparent',
41
- _web: {
42
- border: '1px solid transparent',
43
- },
44
- },
45
- } as const;
46
- }
47
-
48
- function createTriggerSizeVariants(theme: Theme) {
49
- return buildSizeVariants(theme, 'select', (size) => ({
50
- paddingHorizontal: size.paddingHorizontal,
51
- minHeight: size.minHeight,
52
- }));
53
- }
54
-
55
- function createIntentVariants(theme: Theme, type: SelectType, intent: SelectIntentVariant) {
56
- if (intent === 'neutral') {
57
- return {};
58
- }
59
-
60
- const intentValue = (theme.intents as any)[intent];
61
-
62
- if (type === 'outlined') {
63
- return {
64
- borderColor: intentValue.primary,
65
- _web: {
66
- border: `1px solid ${intentValue.primary}`,
67
- },
68
- } as const;
69
- }
70
-
71
- return {} as const;
72
- }
73
-
74
- function buildDynamicTriggerStyles(theme: Theme) {
75
- return ({ type, intent }: Partial<SelectTriggerVariants>) => {
76
- const intentStyles = createIntentVariants(theme, type, intent);
77
-
78
- return {
79
- position: 'relative',
80
- flexDirection: 'row',
81
- alignItems: 'center',
82
- justifyContent: 'space-between',
83
- borderRadius: 8,
84
- borderWidth: 1,
85
- borderStyle: 'solid',
86
- ...intentStyles,
87
- variants: {
88
- type: createTriggerTypeVariants(theme),
89
- size: createTriggerSizeVariants(theme),
90
- disabled: {
91
- true: {
92
- opacity: 0.6,
93
- _web: {
94
- cursor: 'not-allowed',
95
- },
96
- },
97
- false: {
98
- _web: {
99
- cursor: 'pointer',
100
- _hover: {
101
- opacity: 0.9,
102
- },
103
- _active: {
104
- opacity: 0.8,
105
- },
106
- },
107
- },
108
- },
109
- error: {
110
- true: {
111
- borderColor: theme.intents.error.primary,
112
- _web: {
113
- border: `1px solid ${theme.intents.error.primary}`,
114
- },
115
- },
116
- false: {},
117
- },
118
- focused: {
119
- true: {
120
- borderColor: theme.intents.primary.primary,
121
- _web: {
122
- border: `1px solid ${theme.intents.primary.primary}`,
123
- boxShadow: `0 0 0 2px ${theme.intents.primary.primary}20`,
124
- outline: 'none',
125
- },
126
- },
127
- false: {},
128
- },
129
- },
130
- _web: {
131
- display: 'flex',
132
- boxSizing: 'border-box',
133
- _focus: {
134
- outline: 'none',
135
- },
136
- },
137
- } as const;
138
- }
139
- }
140
-
141
- // Main element style creators (wrapped for extension support)
142
- function createContainerStyles(theme: Theme) {
143
- return () => ({
144
- position: 'relative' as const,
145
- variants: {
146
- margin: buildMarginVariants(theme),
147
- marginVertical: buildMarginVerticalVariants(theme),
148
- marginHorizontal: buildMarginHorizontalVariants(theme),
149
- },
150
- });
151
- }
152
-
153
- function createDropdownStyles(theme: Theme) {
154
- return () => ({
155
- position: 'absolute' as const,
156
- top: '100%',
157
- left: 0,
158
- right: 0,
159
- backgroundColor: theme.colors.surface.primary,
160
- borderRadius: 8,
161
- borderWidth: 1,
162
- borderStyle: 'solid' as const,
163
- borderColor: theme.colors.border.primary,
164
- shadowColor: '#000',
165
- shadowOffset: { width: 0, height: 8 },
166
- shadowOpacity: 0.1,
167
- shadowRadius: 24,
168
- elevation: 8,
169
- zIndex: 9999,
170
- maxHeight: 240,
171
- minWidth: 200,
172
- overflow: 'hidden' as const,
173
- _web: {
174
- border: `1px solid ${theme.colors.border.primary}`,
175
- boxShadow: '0 8px 24px rgba(0, 0, 0, 0.1), 0 4px 8px rgba(0, 0, 0, 0.06)',
176
- overflowY: 'auto',
177
- },
178
- });
179
- }
180
-
181
- function createOptionStyles(theme: Theme) {
182
- return () => ({
183
- paddingHorizontal: 8,
184
- paddingVertical: 4,
185
- flexDirection: 'row' as const,
186
- alignItems: 'center' as const,
187
- minHeight: 36,
188
- _web: {
189
- display: 'flex',
190
- cursor: 'pointer',
191
- _hover: {
192
- backgroundColor: theme.colors.surface.secondary,
193
- },
194
- _active: {
195
- opacity: 0.8,
196
- },
197
- },
198
- });
199
- }
200
-
201
- // Styles are inlined here instead of in @idealyst/theme because Unistyles' Babel
202
- // transform on native cannot resolve function calls to extract variant structures.
203
- export const selectStyles = StyleSheet.create((theme: Theme) => {
204
- return applyExtensions('Select', theme, {
205
- container: createContainerStyles(theme),
206
- trigger: buildDynamicTriggerStyles(theme),
207
- dropdown: createDropdownStyles(theme),
208
- option: createOptionStyles(theme),
209
- // Minor utility styles
210
- label: {
211
- fontSize: 14,
212
- fontWeight: '500',
213
- color: theme.colors.text.primary,
214
- marginBottom: 4,
215
- },
216
- triggerContent: {
217
- flex: 1,
218
- flexDirection: 'row',
219
- alignItems: 'center',
220
- },
221
- triggerText: {
222
- color: theme.colors.text.primary,
223
- flex: 1,
224
- variants: {
225
- size: buildSizeVariants(theme, 'select', (size: any) => ({
226
- fontSize: size.fontSize,
227
- })),
228
- },
229
- },
230
- placeholder: {
231
- color: theme.colors.text.secondary,
232
- variants: {
233
- size: buildSizeVariants(theme, 'select', (size: any) => ({
234
- fontSize: size.fontSize,
235
- })),
236
- },
237
- },
238
- icon: {
239
- marginLeft: 4,
240
- color: theme.colors.text.secondary,
241
- },
242
- chevron: {
243
- display: 'flex',
244
- alignItems: 'center',
245
- justifyContent: 'center',
246
- marginLeft: 4,
247
- color: theme.colors.text.secondary,
248
- variants: {
249
- size: buildSizeVariants(theme, 'select', (size: any) => ({
250
- width: size.iconSize,
251
- height: size.iconSize,
252
- })),
253
- },
254
- _web: {
255
- transition: 'transform 0.2s ease',
256
- },
257
- },
258
- chevronOpen: {
259
- _web: {
260
- transform: 'rotate(180deg)',
261
- }
262
- },
263
- searchContainer: {
264
- padding: 8,
265
- borderBottomWidth: 1,
266
- borderBottomStyle: 'solid',
267
- borderBottomColor: theme.colors.border.primary,
268
- _web: {
269
- borderBottom: `1px solid ${theme.colors.border.primary}`,
270
- },
271
- },
272
- searchInput: {
273
- padding: 4,
274
- borderRadius: 4,
275
- borderWidth: 1,
276
- borderStyle: 'solid',
277
- borderColor: theme.colors.border.primary,
278
- backgroundColor: theme.colors.surface.primary,
279
- variants: {
280
- size: buildSizeVariants(theme, 'select', (size: any) => ({
281
- fontSize: size.fontSize,
282
- })),
283
- },
284
- _web: {
285
- border: `1px solid ${theme.colors.border.primary}`,
286
- outline: 'none',
287
- _focus: {
288
- borderColor: theme.intents.primary.primary,
289
- },
290
- },
291
- },
292
- optionsList: {
293
- paddingVertical: 4,
294
- },
295
- optionFocused: {
296
- backgroundColor: theme.interaction.focusedBackground,
297
- _web: {
298
- outline: `1px solid ${theme.interaction.focusBorder}`,
299
- outlineOffset: -1,
300
- },
301
- },
302
- optionDisabled: {
303
- opacity: theme.interaction.opacity.disabled,
304
- _web: {
305
- cursor: 'not-allowed',
306
- },
307
- },
308
- optionContent: {
309
- flexDirection: 'row',
310
- alignItems: 'center',
311
- flex: 1,
312
- },
313
- optionIcon: {
314
- marginRight: 4,
315
- },
316
- optionText: {
317
- color: theme.colors.text.primary,
318
- flex: 1,
319
- variants: {
320
- size: buildSizeVariants(theme, 'select', (size: any) => ({
321
- fontSize: size.fontSize,
322
- })),
323
- },
324
- },
325
- optionTextDisabled: {
326
- color: theme.colors.text.secondary,
327
- },
328
- helperText: {
329
- fontSize: 12,
330
- marginTop: 4,
331
- color: theme.colors.text.secondary,
332
- variants: {
333
- error: {
334
- true: {
335
- color: theme.intents.error.primary,
336
- },
337
- false: {},
338
- },
339
- },
340
- },
341
- overlay: {
342
- position: 'absolute',
343
- top: 0,
344
- left: 0,
345
- right: 0,
346
- bottom: 0,
347
- zIndex: 999,
348
- _web: {
349
- position: 'fixed',
350
- },
351
- },
352
- });
353
- });