@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.
- package/package.json +3 -3
- package/src/Accordion/Accordion.native.tsx +8 -6
- package/src/Accordion/Accordion.styles.old.tsx +298 -0
- package/src/Accordion/Accordion.styles.tsx +102 -236
- package/src/ActivityIndicator/ActivityIndicator.styles.old.tsx +94 -0
- package/src/ActivityIndicator/ActivityIndicator.styles.tsx +44 -74
- package/src/Alert/Alert.native.tsx +16 -6
- package/src/Alert/Alert.styles.old.tsx +209 -0
- package/src/Alert/Alert.styles.tsx +67 -149
- package/src/Avatar/Avatar.styles.old.tsx +99 -0
- package/src/Avatar/Avatar.styles.tsx +35 -80
- package/src/Badge/Badge.styles.old.tsx +157 -0
- package/src/Badge/Badge.styles.tsx +61 -121
- package/src/Breadcrumb/Breadcrumb.styles.old.tsx +231 -0
- package/src/Breadcrumb/Breadcrumb.styles.tsx +83 -200
- package/src/Breadcrumb/Breadcrumb.web.tsx +28 -23
- package/src/Button/Button.styles.tsx +89 -141
- package/src/Card/Card.native.tsx +7 -11
- package/src/Card/Card.styles.old.tsx +160 -0
- package/src/Card/Card.styles.tsx +105 -142
- package/src/Card/Card.web.tsx +5 -4
- package/src/Checkbox/Checkbox.native.tsx +9 -5
- package/src/Checkbox/Checkbox.styles.old.tsx +271 -0
- package/src/Checkbox/Checkbox.styles.tsx +104 -216
- package/src/Checkbox/Checkbox.web.tsx +6 -6
- package/src/Chip/Chip.styles.old.tsx +184 -0
- package/src/Chip/Chip.styles.tsx +34 -72
- package/src/Dialog/Dialog.native.tsx +7 -4
- package/src/Dialog/Dialog.styles.old.tsx +202 -0
- package/src/Dialog/Dialog.styles.tsx +69 -133
- package/src/Divider/Divider.styles.old.tsx +172 -0
- package/src/Divider/Divider.styles.tsx +62 -84
- package/src/Icon/Icon.native.tsx +8 -8
- package/src/Icon/Icon.styles.old.tsx +81 -0
- package/src/Icon/Icon.styles.tsx +52 -66
- package/src/Icon/Icon.web.tsx +43 -7
- package/src/Icon/IconSvg/IconSvg.web.tsx +2 -0
- package/src/Image/Image.styles.old.tsx +69 -0
- package/src/Image/Image.styles.tsx +46 -60
- package/src/Input/Input.native.tsx +138 -53
- package/src/Input/Input.styles.old.tsx +289 -0
- package/src/Input/Input.styles.tsx +127 -198
- package/src/List/List.native.tsx +5 -2
- package/src/List/List.styles.old.tsx +242 -0
- package/src/List/List.styles.tsx +179 -215
- package/src/List/ListItem.native.tsx +12 -6
- package/src/List/ListItem.web.tsx +23 -13
- package/src/Menu/Menu.styles.old.tsx +197 -0
- package/src/Menu/Menu.styles.tsx +68 -150
- package/src/Menu/MenuItem.native.tsx +5 -3
- package/src/Menu/MenuItem.styles.old.tsx +114 -0
- package/src/Menu/MenuItem.styles.tsx +57 -89
- package/src/Menu/MenuItem.web.tsx +8 -3
- package/src/Popover/Popover.native.tsx +10 -4
- package/src/Popover/Popover.styles.old.tsx +135 -0
- package/src/Popover/Popover.styles.tsx +51 -112
- package/src/Pressable/Pressable.styles.old.tsx +27 -0
- package/src/Pressable/Pressable.styles.tsx +35 -27
- package/src/Progress/Progress.styles.old.tsx +200 -0
- package/src/Progress/Progress.styles.tsx +75 -164
- package/src/RadioButton/RadioButton.native.tsx +4 -3
- package/src/RadioButton/RadioButton.styles.old.tsx +175 -0
- package/src/RadioButton/RadioButton.styles.tsx +83 -154
- package/src/RadioButton/RadioButton.web.tsx +2 -2
- package/src/SVGImage/SVGImage.styles.old.tsx +86 -0
- package/src/SVGImage/SVGImage.styles.tsx +35 -78
- package/src/Screen/Screen.native.tsx +18 -25
- package/src/Screen/Screen.styles.old.tsx +87 -0
- package/src/Screen/Screen.styles.tsx +105 -67
- package/src/Screen/Screen.web.tsx +1 -1
- package/src/Select/Select.native.tsx +42 -33
- package/src/Select/Select.styles.old.tsx +353 -0
- package/src/Select/Select.styles.tsx +223 -292
- package/src/Skeleton/Skeleton.styles.old.tsx +67 -0
- package/src/Skeleton/Skeleton.styles.tsx +29 -53
- package/src/Slider/Slider.styles.old.tsx +259 -0
- package/src/Slider/Slider.styles.tsx +153 -234
- package/src/Switch/Switch.native.tsx +7 -5
- package/src/Switch/Switch.styles.old.tsx +203 -0
- package/src/Switch/Switch.styles.tsx +101 -174
- package/src/Switch/Switch.web.tsx +5 -5
- package/src/TabBar/TabBar.native.tsx +3 -2
- package/src/TabBar/TabBar.styles.old.tsx +343 -0
- package/src/TabBar/TabBar.styles.tsx +145 -279
- package/src/Table/Table.native.tsx +18 -9
- package/src/Table/Table.styles.old.tsx +311 -0
- package/src/Table/Table.styles.tsx +152 -286
- package/src/Text/Text.native.tsx +1 -3
- package/src/Text/Text.style.demo.tsx +16 -0
- package/src/Text/Text.styles.old.tsx +219 -0
- package/src/Text/Text.styles.tsx +94 -84
- package/src/Text/Text.web.tsx +2 -2
- package/src/Text/index.ts +1 -0
- package/src/TextArea/TextArea.styles.old.tsx +213 -0
- package/src/TextArea/TextArea.styles.tsx +93 -181
- package/src/Tooltip/Tooltip.styles.old.tsx +82 -0
- package/src/Tooltip/Tooltip.styles.tsx +32 -56
- package/src/Video/Video.styles.old.tsx +51 -0
- package/src/Video/Video.styles.tsx +32 -44
- package/src/View/View.native.tsx +12 -14
- package/src/View/View.styles.old.tsx +125 -0
- package/src/View/View.styles.tsx +76 -106
- package/src/View/View.web.tsx +1 -0
- package/src/examples/CardExamples.tsx +0 -6
- package/src/extensions/extendComponent.ts +61 -0
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import { StyleSheet } from 'react-native-unistyles';
|
|
2
|
+
import { Theme, StylesheetStyles, CompoundVariants, Intent, Size } from '@idealyst/theme';
|
|
3
|
+
import { buildSizeVariants } from '../utils/buildSizeVariants';
|
|
4
|
+
import { applyExtensions } from '../extensions/applyExtension';
|
|
5
|
+
|
|
6
|
+
type MenuSize = Size;
|
|
7
|
+
type MenuIntent = Intent;
|
|
8
|
+
|
|
9
|
+
type MenuVariants = {
|
|
10
|
+
size: MenuSize;
|
|
11
|
+
intent: MenuIntent;
|
|
12
|
+
disabled: boolean;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export type ExpandedMenuStyles = StylesheetStyles<keyof MenuVariants>;
|
|
16
|
+
|
|
17
|
+
export type MenuStylesheet = {
|
|
18
|
+
overlay: ExpandedMenuStyles;
|
|
19
|
+
menu: ExpandedMenuStyles;
|
|
20
|
+
separator: ExpandedMenuStyles;
|
|
21
|
+
item: ExpandedMenuStyles;
|
|
22
|
+
icon: ExpandedMenuStyles;
|
|
23
|
+
label: ExpandedMenuStyles;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Create size variants for menu item
|
|
28
|
+
*/
|
|
29
|
+
function createItemSizeVariants(theme: Theme) {
|
|
30
|
+
return buildSizeVariants(theme, 'menu', (size) => ({
|
|
31
|
+
paddingVertical: size.paddingVertical,
|
|
32
|
+
paddingHorizontal: size.paddingHorizontal,
|
|
33
|
+
}));
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Get hover styles for menu item based on intent
|
|
38
|
+
*/
|
|
39
|
+
function getItemHoverStyles(theme: Theme, intent: MenuIntent) {
|
|
40
|
+
if (intent === 'neutral') {
|
|
41
|
+
return {};
|
|
42
|
+
}
|
|
43
|
+
const intentValue = theme.intents[intent];
|
|
44
|
+
return {
|
|
45
|
+
_web: {
|
|
46
|
+
_hover: {
|
|
47
|
+
backgroundColor: intentValue.light + '20',
|
|
48
|
+
color: intentValue.primary,
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
} as const;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Create compound variants for menu item
|
|
56
|
+
*/
|
|
57
|
+
function createItemCompoundVariants(theme: Theme): CompoundVariants<keyof MenuVariants> {
|
|
58
|
+
return [
|
|
59
|
+
{
|
|
60
|
+
disabled: true,
|
|
61
|
+
styles: {
|
|
62
|
+
_web: {
|
|
63
|
+
_hover: {
|
|
64
|
+
backgroundColor: 'transparent',
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
] as const;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Create size variants for icon
|
|
74
|
+
*/
|
|
75
|
+
function createIconSizeVariants(theme: Theme) {
|
|
76
|
+
return buildSizeVariants(theme, 'menu', (size) => ({
|
|
77
|
+
width: size.iconSize,
|
|
78
|
+
height: size.iconSize,
|
|
79
|
+
fontSize: size.iconSize,
|
|
80
|
+
}));
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Create size variants for label
|
|
85
|
+
*/
|
|
86
|
+
function createLabelSizeVariants(theme: Theme) {
|
|
87
|
+
return buildSizeVariants(theme, 'menu', (size) => ({
|
|
88
|
+
fontSize: size.labelFontSize,
|
|
89
|
+
}));
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Main element style creators (for extension support)
|
|
93
|
+
function createOverlayStyles(theme: Theme) {
|
|
94
|
+
return () => ({
|
|
95
|
+
backgroundColor: 'transparent',
|
|
96
|
+
_web: {
|
|
97
|
+
position: 'fixed' as const,
|
|
98
|
+
top: 0,
|
|
99
|
+
left: 0,
|
|
100
|
+
right: 0,
|
|
101
|
+
bottom: 0,
|
|
102
|
+
zIndex: 999,
|
|
103
|
+
},
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function createMenuStyles(theme: Theme) {
|
|
108
|
+
return () => ({
|
|
109
|
+
position: 'absolute' as const,
|
|
110
|
+
zIndex: 1000,
|
|
111
|
+
backgroundColor: theme.colors.surface.primary,
|
|
112
|
+
borderWidth: 1,
|
|
113
|
+
borderStyle: 'solid' as const,
|
|
114
|
+
borderColor: theme.colors.border.primary,
|
|
115
|
+
borderRadius: 8,
|
|
116
|
+
minWidth: 120,
|
|
117
|
+
maxWidth: 400,
|
|
118
|
+
padding: 4,
|
|
119
|
+
display: 'flex' as const,
|
|
120
|
+
flexDirection: 'column' as const,
|
|
121
|
+
_web: {
|
|
122
|
+
border: `1px solid ${theme.colors.border.primary}`,
|
|
123
|
+
boxShadow: '0 4px 12px rgba(0, 0, 0, 0.15)',
|
|
124
|
+
width: 'fit-content',
|
|
125
|
+
},
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function createItemStyles(theme: Theme) {
|
|
130
|
+
return ({ intent }: Partial<MenuVariants>) => {
|
|
131
|
+
const hoverStyles = getItemHoverStyles(theme, intent ?? 'neutral');
|
|
132
|
+
return {
|
|
133
|
+
flexDirection: 'row',
|
|
134
|
+
alignItems: 'center',
|
|
135
|
+
backgroundColor: 'transparent',
|
|
136
|
+
borderRadius: 4,
|
|
137
|
+
minHeight: 44,
|
|
138
|
+
variants: {
|
|
139
|
+
size: createItemSizeVariants(theme),
|
|
140
|
+
disabled: {
|
|
141
|
+
true: {
|
|
142
|
+
opacity: 0.5,
|
|
143
|
+
_web: {
|
|
144
|
+
cursor: 'not-allowed',
|
|
145
|
+
},
|
|
146
|
+
},
|
|
147
|
+
false: {},
|
|
148
|
+
},
|
|
149
|
+
},
|
|
150
|
+
compoundVariants: createItemCompoundVariants(theme),
|
|
151
|
+
_web: {
|
|
152
|
+
cursor: 'pointer',
|
|
153
|
+
border: 'none',
|
|
154
|
+
outline: 'none',
|
|
155
|
+
transition: 'background-color 0.2s ease',
|
|
156
|
+
textAlign: 'left',
|
|
157
|
+
_hover: {
|
|
158
|
+
backgroundColor: theme.colors.surface.secondary,
|
|
159
|
+
},
|
|
160
|
+
},
|
|
161
|
+
...hoverStyles,
|
|
162
|
+
} as const;
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Styles are inlined here instead of in @idealyst/theme because Unistyles' Babel transform on native cannot resolve function calls to extract variant structures.
|
|
167
|
+
export const menuStyles = StyleSheet.create((theme: Theme) => {
|
|
168
|
+
// Apply extensions to main visual elements
|
|
169
|
+
|
|
170
|
+
return applyExtensions('Menu', theme, {overlay: createOverlayStyles(theme),
|
|
171
|
+
menu: createMenuStyles(theme),
|
|
172
|
+
item: createItemStyles(theme),
|
|
173
|
+
// Additional styles (merged from return)
|
|
174
|
+
// Minor utility styles (not extended)
|
|
175
|
+
separator: {
|
|
176
|
+
height: 1,
|
|
177
|
+
backgroundColor: theme.colors.border.primary,
|
|
178
|
+
marginTop: 4,
|
|
179
|
+
marginBottom: 4,
|
|
180
|
+
},
|
|
181
|
+
icon: {
|
|
182
|
+
alignItems: 'center',
|
|
183
|
+
justifyContent: 'center',
|
|
184
|
+
flexShrink: 0,
|
|
185
|
+
marginRight: 8,
|
|
186
|
+
variants: {
|
|
187
|
+
size: createIconSizeVariants(theme),
|
|
188
|
+
} as const,
|
|
189
|
+
} as const,
|
|
190
|
+
label: {
|
|
191
|
+
flex: 1,
|
|
192
|
+
color: theme.colors.text.primary,
|
|
193
|
+
variants: {
|
|
194
|
+
size: createLabelSizeVariants(theme),
|
|
195
|
+
} as const,
|
|
196
|
+
} as const});
|
|
197
|
+
});
|
package/src/Menu/Menu.styles.tsx
CHANGED
|
@@ -1,98 +1,28 @@
|
|
|
1
|
-
import { StyleSheet } from 'react-native-unistyles';
|
|
2
|
-
import { Theme, StylesheetStyles, CompoundVariants, Intent, Size } from '@idealyst/theme';
|
|
3
|
-
import { buildSizeVariants } from '../utils/buildSizeVariants';
|
|
4
|
-
import { applyExtensions } from '../extensions/applyExtension';
|
|
5
|
-
|
|
6
|
-
type MenuSize = Size;
|
|
7
|
-
type MenuIntent = Intent;
|
|
8
|
-
|
|
9
|
-
type MenuVariants = {
|
|
10
|
-
size: MenuSize;
|
|
11
|
-
intent: MenuIntent;
|
|
12
|
-
disabled: boolean;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export type ExpandedMenuStyles = StylesheetStyles<keyof MenuVariants>;
|
|
16
|
-
|
|
17
|
-
export type MenuStylesheet = {
|
|
18
|
-
overlay: ExpandedMenuStyles;
|
|
19
|
-
menu: ExpandedMenuStyles;
|
|
20
|
-
separator: ExpandedMenuStyles;
|
|
21
|
-
item: ExpandedMenuStyles;
|
|
22
|
-
icon: ExpandedMenuStyles;
|
|
23
|
-
label: ExpandedMenuStyles;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
1
|
/**
|
|
27
|
-
*
|
|
2
|
+
* Menu styles using defineStyle with dynamic props.
|
|
28
3
|
*/
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
paddingHorizontal: size.paddingHorizontal,
|
|
33
|
-
}));
|
|
34
|
-
}
|
|
4
|
+
import { StyleSheet } from 'react-native-unistyles';
|
|
5
|
+
import { defineStyle, ThemeStyleWrapper } from '@idealyst/theme';
|
|
6
|
+
import type { Theme as BaseTheme, Intent, Size } from '@idealyst/theme';
|
|
35
7
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
*/
|
|
39
|
-
function getItemHoverStyles(theme: Theme, intent: MenuIntent) {
|
|
40
|
-
if (intent === 'neutral') {
|
|
41
|
-
return {};
|
|
42
|
-
}
|
|
43
|
-
const intentValue = theme.intents[intent];
|
|
44
|
-
return {
|
|
45
|
-
_web: {
|
|
46
|
-
_hover: {
|
|
47
|
-
backgroundColor: intentValue.light + '20',
|
|
48
|
-
color: intentValue.primary,
|
|
49
|
-
},
|
|
50
|
-
},
|
|
51
|
-
} as const;
|
|
52
|
-
}
|
|
8
|
+
// Required: Unistyles must see StyleSheet usage in original source to process this file
|
|
9
|
+
void StyleSheet;
|
|
53
10
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
*/
|
|
57
|
-
function createItemCompoundVariants(theme: Theme): CompoundVariants<keyof MenuVariants> {
|
|
58
|
-
return [
|
|
59
|
-
{
|
|
60
|
-
disabled: true,
|
|
61
|
-
styles: {
|
|
62
|
-
_web: {
|
|
63
|
-
_hover: {
|
|
64
|
-
backgroundColor: 'transparent',
|
|
65
|
-
},
|
|
66
|
-
},
|
|
67
|
-
},
|
|
68
|
-
},
|
|
69
|
-
] as const;
|
|
70
|
-
}
|
|
11
|
+
// Wrap theme for $iterator support
|
|
12
|
+
type Theme = ThemeStyleWrapper<BaseTheme>;
|
|
71
13
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
width: size.iconSize,
|
|
78
|
-
height: size.iconSize,
|
|
79
|
-
fontSize: size.iconSize,
|
|
80
|
-
}));
|
|
81
|
-
}
|
|
14
|
+
export type MenuDynamicProps = {
|
|
15
|
+
size?: Size;
|
|
16
|
+
intent?: Intent;
|
|
17
|
+
disabled?: boolean;
|
|
18
|
+
};
|
|
82
19
|
|
|
83
20
|
/**
|
|
84
|
-
*
|
|
21
|
+
* Menu styles with intent/disabled handling.
|
|
85
22
|
*/
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
}));
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
// Main element style creators (for extension support)
|
|
93
|
-
function createOverlayStyles(theme: Theme) {
|
|
94
|
-
return () => ({
|
|
95
|
-
backgroundColor: 'transparent',
|
|
23
|
+
export const menuStyles = defineStyle('Menu', (theme: Theme) => ({
|
|
24
|
+
overlay: (_props: MenuDynamicProps) => ({
|
|
25
|
+
backgroundColor: 'transparent' as const,
|
|
96
26
|
_web: {
|
|
97
27
|
position: 'fixed' as const,
|
|
98
28
|
top: 0,
|
|
@@ -101,11 +31,9 @@ function createOverlayStyles(theme: Theme) {
|
|
|
101
31
|
bottom: 0,
|
|
102
32
|
zIndex: 999,
|
|
103
33
|
},
|
|
104
|
-
})
|
|
105
|
-
}
|
|
34
|
+
}),
|
|
106
35
|
|
|
107
|
-
|
|
108
|
-
return () => ({
|
|
36
|
+
menu: (_props: MenuDynamicProps) => ({
|
|
109
37
|
position: 'absolute' as const,
|
|
110
38
|
zIndex: 1000,
|
|
111
39
|
backgroundColor: theme.colors.surface.primary,
|
|
@@ -123,79 +51,69 @@ function createMenuStyles(theme: Theme) {
|
|
|
123
51
|
boxShadow: '0 4px 12px rgba(0, 0, 0, 0.15)',
|
|
124
52
|
width: 'fit-content',
|
|
125
53
|
},
|
|
126
|
-
})
|
|
127
|
-
|
|
54
|
+
}),
|
|
55
|
+
|
|
56
|
+
item: ({ intent = 'neutral', disabled = false }: MenuDynamicProps) => {
|
|
57
|
+
const intentValue = theme.intents[intent];
|
|
58
|
+
const hoverStyles = intent !== 'neutral' ? {
|
|
59
|
+
backgroundColor: intentValue.light + '20',
|
|
60
|
+
color: intentValue.primary,
|
|
61
|
+
} : {
|
|
62
|
+
backgroundColor: theme.colors.surface.secondary,
|
|
63
|
+
};
|
|
128
64
|
|
|
129
|
-
function createItemStyles(theme: Theme) {
|
|
130
|
-
return ({ intent }: Partial<MenuVariants>) => {
|
|
131
|
-
const hoverStyles = getItemHoverStyles(theme, intent ?? 'neutral');
|
|
132
65
|
return {
|
|
133
|
-
flexDirection: 'row',
|
|
134
|
-
alignItems: 'center',
|
|
135
|
-
backgroundColor: 'transparent',
|
|
66
|
+
flexDirection: 'row' as const,
|
|
67
|
+
alignItems: 'center' as const,
|
|
68
|
+
backgroundColor: 'transparent' as const,
|
|
136
69
|
borderRadius: 4,
|
|
137
70
|
minHeight: 44,
|
|
71
|
+
opacity: disabled ? 0.5 : 1,
|
|
138
72
|
variants: {
|
|
139
|
-
size:
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
opacity: 0.5,
|
|
143
|
-
_web: {
|
|
144
|
-
cursor: 'not-allowed',
|
|
145
|
-
},
|
|
146
|
-
},
|
|
147
|
-
false: {},
|
|
73
|
+
size: {
|
|
74
|
+
paddingVertical: theme.sizes.$menu.paddingVertical,
|
|
75
|
+
paddingHorizontal: theme.sizes.$menu.paddingHorizontal,
|
|
148
76
|
},
|
|
149
77
|
},
|
|
150
|
-
compoundVariants: createItemCompoundVariants(theme),
|
|
151
78
|
_web: {
|
|
152
|
-
cursor: 'pointer',
|
|
79
|
+
cursor: disabled ? 'not-allowed' : 'pointer',
|
|
153
80
|
border: 'none',
|
|
154
81
|
outline: 'none',
|
|
155
82
|
transition: 'background-color 0.2s ease',
|
|
156
83
|
textAlign: 'left',
|
|
157
|
-
_hover: {
|
|
158
|
-
backgroundColor: theme.colors.surface.secondary,
|
|
159
|
-
},
|
|
84
|
+
_hover: disabled ? { backgroundColor: 'transparent' } : hoverStyles,
|
|
160
85
|
},
|
|
161
|
-
...hoverStyles,
|
|
162
86
|
} as const;
|
|
163
|
-
}
|
|
164
|
-
}
|
|
87
|
+
},
|
|
165
88
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
item: createItemStyles(theme),
|
|
173
|
-
});
|
|
89
|
+
separator: (_props: MenuDynamicProps) => ({
|
|
90
|
+
height: 1,
|
|
91
|
+
backgroundColor: theme.colors.border.primary,
|
|
92
|
+
marginTop: 4,
|
|
93
|
+
marginBottom: 4,
|
|
94
|
+
}),
|
|
174
95
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
96
|
+
icon: (_props: MenuDynamicProps) => ({
|
|
97
|
+
alignItems: 'center' as const,
|
|
98
|
+
justifyContent: 'center' as const,
|
|
99
|
+
flexShrink: 0,
|
|
100
|
+
marginRight: 8,
|
|
101
|
+
variants: {
|
|
102
|
+
size: {
|
|
103
|
+
width: theme.sizes.$menu.iconSize,
|
|
104
|
+
height: theme.sizes.$menu.iconSize,
|
|
105
|
+
fontSize: theme.sizes.$menu.iconSize,
|
|
106
|
+
},
|
|
183
107
|
},
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
variants: {
|
|
197
|
-
size: createLabelSizeVariants(theme),
|
|
198
|
-
} as const,
|
|
199
|
-
} as const,
|
|
200
|
-
};
|
|
201
|
-
});
|
|
108
|
+
}),
|
|
109
|
+
|
|
110
|
+
label: (_props: MenuDynamicProps) => ({
|
|
111
|
+
flex: 1,
|
|
112
|
+
color: theme.colors.text.primary,
|
|
113
|
+
variants: {
|
|
114
|
+
size: {
|
|
115
|
+
fontSize: theme.sizes.$menu.labelFontSize,
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
}),
|
|
119
|
+
}));
|
|
@@ -19,8 +19,10 @@ const MenuItem = forwardRef<ComponentRef<typeof Pressable>, MenuItemProps>(({ it
|
|
|
19
19
|
disabled: Boolean(item.disabled),
|
|
20
20
|
});
|
|
21
21
|
|
|
22
|
-
//
|
|
22
|
+
// Call styles as functions to get theme-reactive styles
|
|
23
23
|
const itemStyle = (menuItemStyles.item as any)({ intent: item.intent || 'neutral' });
|
|
24
|
+
const iconStyle = (menuItemStyles.icon as any)({});
|
|
25
|
+
const labelStyle = (menuItemStyles.label as any)({});
|
|
24
26
|
|
|
25
27
|
const renderIcon = () => {
|
|
26
28
|
if (!item.icon) return null;
|
|
@@ -29,7 +31,7 @@ const MenuItem = forwardRef<ComponentRef<typeof Pressable>, MenuItemProps>(({ it
|
|
|
29
31
|
return (
|
|
30
32
|
<MaterialDesignIcons
|
|
31
33
|
name={item.icon as any}
|
|
32
|
-
style={
|
|
34
|
+
style={iconStyle}
|
|
33
35
|
/>
|
|
34
36
|
);
|
|
35
37
|
} else if (isValidElement(item.icon)) {
|
|
@@ -56,7 +58,7 @@ const MenuItem = forwardRef<ComponentRef<typeof Pressable>, MenuItemProps>(({ it
|
|
|
56
58
|
{renderIcon()}
|
|
57
59
|
</View>
|
|
58
60
|
)}
|
|
59
|
-
<Text style={
|
|
61
|
+
<Text style={labelStyle}>
|
|
60
62
|
{item.label}
|
|
61
63
|
</Text>
|
|
62
64
|
</Pressable>
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { StyleSheet } from 'react-native-unistyles';
|
|
2
|
+
import { Theme, Intent } from '@idealyst/theme';
|
|
3
|
+
import { buildSizeVariants } from '../utils/buildSizeVariants';
|
|
4
|
+
import { applyExtensions } from '../extensions/applyExtension';
|
|
5
|
+
|
|
6
|
+
type MenuItemDynamicProps = {
|
|
7
|
+
intent?: Intent;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Get hover styles for menu item based on intent
|
|
12
|
+
*/
|
|
13
|
+
function getItemHoverStyles(theme: Theme, intent: Intent) {
|
|
14
|
+
if (intent === 'neutral') {
|
|
15
|
+
return {
|
|
16
|
+
_web: {
|
|
17
|
+
_hover: {
|
|
18
|
+
backgroundColor: theme.colors.surface.secondary,
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
} as const;
|
|
22
|
+
}
|
|
23
|
+
const intentValue = theme.intents[intent];
|
|
24
|
+
return {
|
|
25
|
+
_web: {
|
|
26
|
+
_hover: {
|
|
27
|
+
backgroundColor: intentValue.light,
|
|
28
|
+
color: intentValue.primary,
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
} as const;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Create dynamic item styles
|
|
36
|
+
*/
|
|
37
|
+
function createItemStyles(theme: Theme) {
|
|
38
|
+
return ({ intent = 'neutral' }: MenuItemDynamicProps) => {
|
|
39
|
+
const hoverStyles = getItemHoverStyles(theme, intent);
|
|
40
|
+
return {
|
|
41
|
+
flexDirection: 'row',
|
|
42
|
+
alignItems: 'center',
|
|
43
|
+
backgroundColor: 'transparent',
|
|
44
|
+
borderRadius: 4,
|
|
45
|
+
minHeight: 44,
|
|
46
|
+
variants: {
|
|
47
|
+
size: buildSizeVariants(theme, 'menu', (size) => ({
|
|
48
|
+
paddingVertical: size.paddingVertical,
|
|
49
|
+
paddingHorizontal: size.paddingHorizontal,
|
|
50
|
+
})),
|
|
51
|
+
disabled: {
|
|
52
|
+
true: {
|
|
53
|
+
opacity: 0.5,
|
|
54
|
+
_web: {
|
|
55
|
+
cursor: 'not-allowed',
|
|
56
|
+
_hover: {
|
|
57
|
+
backgroundColor: 'transparent',
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
false: {},
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
_web: {
|
|
65
|
+
display: 'flex',
|
|
66
|
+
width: '100%',
|
|
67
|
+
cursor: 'pointer',
|
|
68
|
+
border: 'none',
|
|
69
|
+
borderWidth: 0,
|
|
70
|
+
outline: 'none',
|
|
71
|
+
transition: 'background-color 0.2s ease',
|
|
72
|
+
textAlign: 'left',
|
|
73
|
+
_hover: {
|
|
74
|
+
backgroundColor: theme.colors.surface.secondary,
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
...hoverStyles,
|
|
78
|
+
} as const;
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Styles are inlined here instead of in @idealyst/theme because Unistyles' Babel transform on native cannot resolve function calls to extract variant structures.
|
|
83
|
+
export const menuItemStyles = StyleSheet.create((theme: Theme) => {
|
|
84
|
+
// Apply extensions to main visual elements
|
|
85
|
+
|
|
86
|
+
return applyExtensions('MenuItem', theme, {item: createItemStyles(theme),
|
|
87
|
+
// Additional styles (merged from return)
|
|
88
|
+
// Minor utility styles (not extended)
|
|
89
|
+
icon: {
|
|
90
|
+
alignItems: 'center',
|
|
91
|
+
justifyContent: 'center',
|
|
92
|
+
flexShrink: 0,
|
|
93
|
+
marginRight: 12,
|
|
94
|
+
variants: {
|
|
95
|
+
size: buildSizeVariants(theme, 'menu', (size) => ({
|
|
96
|
+
width: size.iconSize,
|
|
97
|
+
height: size.iconSize,
|
|
98
|
+
fontSize: size.iconSize,
|
|
99
|
+
}))
|
|
100
|
+
},
|
|
101
|
+
_web: {
|
|
102
|
+
display: 'flex',
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
label: {
|
|
106
|
+
flex: 1,
|
|
107
|
+
color: theme.colors.text.primary,
|
|
108
|
+
variants: {
|
|
109
|
+
size: buildSizeVariants(theme, 'menu', (size) => ({
|
|
110
|
+
fontSize: size.labelFontSize,
|
|
111
|
+
})),
|
|
112
|
+
},
|
|
113
|
+
}});
|
|
114
|
+
});
|