@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,172 @@
|
|
|
1
|
+
import { StyleSheet } from 'react-native-unistyles';
|
|
2
|
+
import { Theme, Intent } from '@idealyst/theme';
|
|
3
|
+
import { applyExtensions } from '../extensions/applyExtension';
|
|
4
|
+
|
|
5
|
+
type DividerOrientation = 'horizontal' | 'vertical';
|
|
6
|
+
type DividerThickness = 'thin' | 'md' | 'thick';
|
|
7
|
+
type DividerType = 'solid' | 'dashed' | 'dotted';
|
|
8
|
+
type DividerIntent = Intent | 'secondary' | 'neutral' | 'info';
|
|
9
|
+
type DividerLength = 'full' | 'auto';
|
|
10
|
+
type DividerSpacing = 'none' | 'sm' | 'md' | 'lg';
|
|
11
|
+
|
|
12
|
+
type DividerDynamicProps = {
|
|
13
|
+
orientation?: DividerOrientation;
|
|
14
|
+
thickness?: DividerThickness;
|
|
15
|
+
type?: DividerType;
|
|
16
|
+
intent?: DividerIntent;
|
|
17
|
+
spacing?: DividerSpacing;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
type LineDynamicProps = {
|
|
21
|
+
orientation?: DividerOrientation;
|
|
22
|
+
thickness?: DividerThickness;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
function getIntentColor(theme: Theme, intent: DividerIntent): string {
|
|
26
|
+
if (intent === 'secondary') return theme.colors.border.primary;
|
|
27
|
+
if (intent === 'neutral') return theme.colors.border.secondary;
|
|
28
|
+
if (intent === 'info') return theme.intents.primary.primary;
|
|
29
|
+
return theme.intents[intent as Intent].primary;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function getThicknessValue(thickness: DividerThickness): number {
|
|
33
|
+
switch (thickness) {
|
|
34
|
+
case 'thin': return 1;
|
|
35
|
+
case 'md': return 2;
|
|
36
|
+
case 'thick': return 4;
|
|
37
|
+
default: return 1;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function getSpacingValue(spacing: DividerSpacing): number {
|
|
42
|
+
switch (spacing) {
|
|
43
|
+
case 'none': return 0;
|
|
44
|
+
case 'sm': return 8;
|
|
45
|
+
case 'md': return 16;
|
|
46
|
+
case 'lg': return 24;
|
|
47
|
+
default: return 0;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Create dynamic divider styles
|
|
53
|
+
*/
|
|
54
|
+
function createDividerStyles(theme: Theme) {
|
|
55
|
+
return ({
|
|
56
|
+
orientation = 'horizontal',
|
|
57
|
+
thickness = 'thin',
|
|
58
|
+
type = 'solid',
|
|
59
|
+
intent = 'neutral',
|
|
60
|
+
spacing = 'md'
|
|
61
|
+
}: DividerDynamicProps) => {
|
|
62
|
+
const color = getIntentColor(theme, intent);
|
|
63
|
+
const thicknessValue = getThicknessValue(thickness);
|
|
64
|
+
const spacingValue = getSpacingValue(spacing);
|
|
65
|
+
|
|
66
|
+
const isHorizontal = orientation === 'horizontal';
|
|
67
|
+
const isDashedOrDotted = type === 'dashed' || type === 'dotted';
|
|
68
|
+
|
|
69
|
+
// Base dimension styles based on orientation and thickness
|
|
70
|
+
const dimensionStyles = isHorizontal
|
|
71
|
+
? { width: '100%', height: thicknessValue, flexDirection: 'row' as const }
|
|
72
|
+
: { width: thicknessValue, height: '100%', flexDirection: 'column' as const };
|
|
73
|
+
|
|
74
|
+
// Spacing styles based on orientation
|
|
75
|
+
const spacingStyles = isHorizontal
|
|
76
|
+
? { marginVertical: spacingValue }
|
|
77
|
+
: { marginHorizontal: spacingValue };
|
|
78
|
+
|
|
79
|
+
// Web-specific border styles for dashed/dotted
|
|
80
|
+
const webBorderStyles = isDashedOrDotted ? {
|
|
81
|
+
border: 'none',
|
|
82
|
+
backgroundColor: 'transparent',
|
|
83
|
+
...(isHorizontal
|
|
84
|
+
? { borderTop: `${thicknessValue}px ${type} ${color}` }
|
|
85
|
+
: { borderLeft: `${thicknessValue}px ${type} ${color}` }
|
|
86
|
+
),
|
|
87
|
+
} : {};
|
|
88
|
+
|
|
89
|
+
return {
|
|
90
|
+
backgroundColor: isDashedOrDotted ? 'transparent' : color,
|
|
91
|
+
...dimensionStyles,
|
|
92
|
+
...spacingStyles,
|
|
93
|
+
variants: {
|
|
94
|
+
length: {
|
|
95
|
+
full: {},
|
|
96
|
+
auto: {},
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
_web: webBorderStyles,
|
|
100
|
+
} as const;
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Create dynamic line styles (for dividers with content)
|
|
106
|
+
*/
|
|
107
|
+
function createLineStyles(theme: Theme) {
|
|
108
|
+
return ({ orientation = 'horizontal', thickness = 'thin' }: LineDynamicProps) => {
|
|
109
|
+
const thicknessValue = getThicknessValue(thickness);
|
|
110
|
+
const isHorizontal = orientation === 'horizontal';
|
|
111
|
+
|
|
112
|
+
return {
|
|
113
|
+
backgroundColor: theme.colors.border.secondary,
|
|
114
|
+
flex: 1,
|
|
115
|
+
...(isHorizontal
|
|
116
|
+
? { height: thicknessValue }
|
|
117
|
+
: { width: thicknessValue }
|
|
118
|
+
),
|
|
119
|
+
} as const;
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Styles are inlined here instead of in @idealyst/theme because Unistyles' Babel
|
|
124
|
+
// transform on native cannot resolve function calls to extract variant structures.
|
|
125
|
+
export const dividerStyles = StyleSheet.create((theme: Theme) => {
|
|
126
|
+
// Apply extensions to main visual elements
|
|
127
|
+
|
|
128
|
+
return applyExtensions('Divider', theme, {divider: createDividerStyles(theme),
|
|
129
|
+
// Additional styles (merged from return)
|
|
130
|
+
// Minor utility styles (not extended)
|
|
131
|
+
container: {
|
|
132
|
+
alignItems: 'center',
|
|
133
|
+
justifyContent: 'center',
|
|
134
|
+
display: 'flex',
|
|
135
|
+
variants: {
|
|
136
|
+
orientation: {
|
|
137
|
+
horizontal: {
|
|
138
|
+
flexDirection: 'row',
|
|
139
|
+
width: '100%',
|
|
140
|
+
},
|
|
141
|
+
vertical: {
|
|
142
|
+
flexDirection: 'column',
|
|
143
|
+
height: '100%',
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
spacing: {
|
|
147
|
+
none: { gap: 0 },
|
|
148
|
+
xs: { gap: 4 },
|
|
149
|
+
sm: { gap: 8 },
|
|
150
|
+
md: { gap: 16 },
|
|
151
|
+
lg: { gap: 24 },
|
|
152
|
+
xl: { gap: 32 },
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
},
|
|
156
|
+
content: {
|
|
157
|
+
backgroundColor: theme.colors.surface.primary,
|
|
158
|
+
color: theme.colors.text.secondary,
|
|
159
|
+
fontSize: 14,
|
|
160
|
+
variants: {
|
|
161
|
+
orientation: {
|
|
162
|
+
horizontal: {
|
|
163
|
+
paddingHorizontal: 8,
|
|
164
|
+
},
|
|
165
|
+
vertical: {
|
|
166
|
+
paddingVertical: 8,
|
|
167
|
+
},
|
|
168
|
+
},
|
|
169
|
+
},
|
|
170
|
+
},
|
|
171
|
+
line: createLineStyles(theme)});
|
|
172
|
+
});
|
|
@@ -1,15 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Divider styles using defineStyle with dynamic functions.
|
|
3
|
+
*/
|
|
1
4
|
import { StyleSheet } from 'react-native-unistyles';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
5
|
+
import { defineStyle, ThemeStyleWrapper } from '@idealyst/theme';
|
|
6
|
+
import type { Theme as BaseTheme, Intent } from '@idealyst/theme';
|
|
7
|
+
|
|
8
|
+
// Required: Unistyles must see StyleSheet usage in original source to process this file
|
|
9
|
+
void StyleSheet;
|
|
10
|
+
|
|
11
|
+
// Wrap theme for $iterator support
|
|
12
|
+
type Theme = ThemeStyleWrapper<BaseTheme>;
|
|
4
13
|
|
|
5
14
|
type DividerOrientation = 'horizontal' | 'vertical';
|
|
6
15
|
type DividerThickness = 'thin' | 'md' | 'thick';
|
|
7
16
|
type DividerType = 'solid' | 'dashed' | 'dotted';
|
|
8
17
|
type DividerIntent = Intent | 'secondary' | 'neutral' | 'info';
|
|
9
|
-
type DividerLength = 'full' | 'auto';
|
|
10
18
|
type DividerSpacing = 'none' | 'sm' | 'md' | 'lg';
|
|
19
|
+
type DividerLength = 'full' | 'auto';
|
|
11
20
|
|
|
12
|
-
type DividerDynamicProps = {
|
|
21
|
+
export type DividerDynamicProps = {
|
|
13
22
|
orientation?: DividerOrientation;
|
|
14
23
|
thickness?: DividerThickness;
|
|
15
24
|
type?: DividerType;
|
|
@@ -17,18 +26,11 @@ type DividerDynamicProps = {
|
|
|
17
26
|
spacing?: DividerSpacing;
|
|
18
27
|
};
|
|
19
28
|
|
|
20
|
-
type LineDynamicProps = {
|
|
29
|
+
export type LineDynamicProps = {
|
|
21
30
|
orientation?: DividerOrientation;
|
|
22
31
|
thickness?: DividerThickness;
|
|
23
32
|
};
|
|
24
33
|
|
|
25
|
-
function getIntentColor(theme: Theme, intent: DividerIntent): string {
|
|
26
|
-
if (intent === 'secondary') return theme.colors.border.primary;
|
|
27
|
-
if (intent === 'neutral') return theme.colors.border.secondary;
|
|
28
|
-
if (intent === 'info') return theme.intents.primary.primary;
|
|
29
|
-
return theme.intents[intent as Intent].primary;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
34
|
function getThicknessValue(thickness: DividerThickness): number {
|
|
33
35
|
switch (thickness) {
|
|
34
36
|
case 'thin': return 1;
|
|
@@ -49,34 +51,38 @@ function getSpacingValue(spacing: DividerSpacing): number {
|
|
|
49
51
|
}
|
|
50
52
|
|
|
51
53
|
/**
|
|
52
|
-
*
|
|
54
|
+
* Divider styles with dynamic functions for orientation/thickness/intent combinations.
|
|
53
55
|
*/
|
|
54
|
-
|
|
55
|
-
|
|
56
|
+
export const dividerStyles = defineStyle('Divider', (theme: Theme) => ({
|
|
57
|
+
divider: ({
|
|
56
58
|
orientation = 'horizontal',
|
|
57
59
|
thickness = 'thin',
|
|
58
60
|
type = 'solid',
|
|
59
61
|
intent = 'neutral',
|
|
60
62
|
spacing = 'md'
|
|
61
63
|
}: DividerDynamicProps) => {
|
|
62
|
-
const color = getIntentColor(theme, intent);
|
|
63
64
|
const thicknessValue = getThicknessValue(thickness);
|
|
64
65
|
const spacingValue = getSpacingValue(spacing);
|
|
65
|
-
|
|
66
66
|
const isHorizontal = orientation === 'horizontal';
|
|
67
67
|
const isDashedOrDotted = type === 'dashed' || type === 'dotted';
|
|
68
68
|
|
|
69
|
-
//
|
|
69
|
+
// Get color based on intent - inline for Unistyles to trace
|
|
70
|
+
const color = intent === 'secondary'
|
|
71
|
+
? theme.colors.border.primary
|
|
72
|
+
: intent === 'neutral'
|
|
73
|
+
? theme.colors.border.secondary
|
|
74
|
+
: intent === 'info'
|
|
75
|
+
? theme.intents.primary.primary
|
|
76
|
+
: theme.intents[intent as Intent].primary;
|
|
77
|
+
|
|
70
78
|
const dimensionStyles = isHorizontal
|
|
71
79
|
? { width: '100%', height: thicknessValue, flexDirection: 'row' as const }
|
|
72
80
|
: { width: thicknessValue, height: '100%', flexDirection: 'column' as const };
|
|
73
81
|
|
|
74
|
-
// Spacing styles based on orientation
|
|
75
82
|
const spacingStyles = isHorizontal
|
|
76
83
|
? { marginVertical: spacingValue }
|
|
77
84
|
: { marginHorizontal: spacingValue };
|
|
78
85
|
|
|
79
|
-
// Web-specific border styles for dashed/dotted
|
|
80
86
|
const webBorderStyles = isDashedOrDotted ? {
|
|
81
87
|
border: 'none',
|
|
82
88
|
backgroundColor: 'transparent',
|
|
@@ -98,14 +104,41 @@ function createDividerStyles(theme: Theme) {
|
|
|
98
104
|
},
|
|
99
105
|
_web: webBorderStyles,
|
|
100
106
|
} as const;
|
|
101
|
-
}
|
|
102
|
-
|
|
107
|
+
},
|
|
108
|
+
|
|
109
|
+
container: (_props: { orientation?: DividerOrientation; spacing?: DividerSpacing }) => ({
|
|
110
|
+
alignItems: 'center',
|
|
111
|
+
justifyContent: 'center',
|
|
112
|
+
display: 'flex',
|
|
113
|
+
variants: {
|
|
114
|
+
orientation: {
|
|
115
|
+
horizontal: { flexDirection: 'row', width: '100%' },
|
|
116
|
+
vertical: { flexDirection: 'column', height: '100%' },
|
|
117
|
+
},
|
|
118
|
+
spacing: {
|
|
119
|
+
none: { gap: 0 },
|
|
120
|
+
xs: { gap: 4 },
|
|
121
|
+
sm: { gap: 8 },
|
|
122
|
+
md: { gap: 16 },
|
|
123
|
+
lg: { gap: 24 },
|
|
124
|
+
xl: { gap: 32 },
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
}),
|
|
128
|
+
|
|
129
|
+
content: (_props: { orientation?: DividerOrientation }) => ({
|
|
130
|
+
backgroundColor: theme.colors.surface.primary,
|
|
131
|
+
color: theme.colors.text.secondary,
|
|
132
|
+
fontSize: 14,
|
|
133
|
+
variants: {
|
|
134
|
+
orientation: {
|
|
135
|
+
horizontal: { paddingHorizontal: 8 },
|
|
136
|
+
vertical: { paddingVertical: 8 },
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
}),
|
|
103
140
|
|
|
104
|
-
|
|
105
|
-
* Create dynamic line styles (for dividers with content)
|
|
106
|
-
*/
|
|
107
|
-
function createLineStyles(theme: Theme) {
|
|
108
|
-
return ({ orientation = 'horizontal', thickness = 'thin' }: LineDynamicProps) => {
|
|
141
|
+
line: ({ orientation = 'horizontal', thickness = 'thin' }: LineDynamicProps) => {
|
|
109
142
|
const thicknessValue = getThicknessValue(thickness);
|
|
110
143
|
const isHorizontal = orientation === 'horizontal';
|
|
111
144
|
|
|
@@ -117,60 +150,5 @@ function createLineStyles(theme: Theme) {
|
|
|
117
150
|
: { width: thicknessValue }
|
|
118
151
|
),
|
|
119
152
|
} as const;
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
// Styles are inlined here instead of in @idealyst/theme because Unistyles' Babel
|
|
124
|
-
// transform on native cannot resolve function calls to extract variant structures.
|
|
125
|
-
export const dividerStyles = StyleSheet.create((theme: Theme) => {
|
|
126
|
-
// Apply extensions to main visual elements
|
|
127
|
-
const extended = applyExtensions('Divider', theme, {
|
|
128
|
-
divider: createDividerStyles(theme),
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
return {
|
|
132
|
-
...extended,
|
|
133
|
-
// Minor utility styles (not extended)
|
|
134
|
-
container: {
|
|
135
|
-
alignItems: 'center',
|
|
136
|
-
justifyContent: 'center',
|
|
137
|
-
display: 'flex',
|
|
138
|
-
variants: {
|
|
139
|
-
orientation: {
|
|
140
|
-
horizontal: {
|
|
141
|
-
flexDirection: 'row',
|
|
142
|
-
width: '100%',
|
|
143
|
-
},
|
|
144
|
-
vertical: {
|
|
145
|
-
flexDirection: 'column',
|
|
146
|
-
height: '100%',
|
|
147
|
-
},
|
|
148
|
-
},
|
|
149
|
-
spacing: {
|
|
150
|
-
none: { gap: 0 },
|
|
151
|
-
xs: { gap: 4 },
|
|
152
|
-
sm: { gap: 8 },
|
|
153
|
-
md: { gap: 16 },
|
|
154
|
-
lg: { gap: 24 },
|
|
155
|
-
xl: { gap: 32 },
|
|
156
|
-
},
|
|
157
|
-
},
|
|
158
|
-
},
|
|
159
|
-
content: {
|
|
160
|
-
backgroundColor: theme.colors.surface.primary,
|
|
161
|
-
color: theme.colors.text.secondary,
|
|
162
|
-
fontSize: 14,
|
|
163
|
-
variants: {
|
|
164
|
-
orientation: {
|
|
165
|
-
horizontal: {
|
|
166
|
-
paddingHorizontal: 8,
|
|
167
|
-
},
|
|
168
|
-
vertical: {
|
|
169
|
-
paddingVertical: 8,
|
|
170
|
-
},
|
|
171
|
-
},
|
|
172
|
-
},
|
|
173
|
-
},
|
|
174
|
-
line: createLineStyles(theme),
|
|
175
|
-
};
|
|
176
|
-
});
|
|
153
|
+
},
|
|
154
|
+
}));
|
package/src/Icon/Icon.native.tsx
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { forwardRef, useMemo } from 'react';
|
|
2
2
|
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
|
|
3
3
|
import { IconProps } from './types';
|
|
4
|
-
import { iconStyles
|
|
4
|
+
import { iconStyles } from './Icon.styles';
|
|
5
5
|
import { useUnistyles } from 'react-native-unistyles';
|
|
6
6
|
|
|
7
7
|
const Icon = forwardRef<any, IconProps>(({
|
|
@@ -14,18 +14,17 @@ const Icon = forwardRef<any, IconProps>(({
|
|
|
14
14
|
accessibilityLabel,
|
|
15
15
|
id,
|
|
16
16
|
}: IconProps, ref) => {
|
|
17
|
+
const { theme } = useUnistyles();
|
|
17
18
|
|
|
18
|
-
|
|
19
|
-
// Call dynamic style with variants
|
|
19
|
+
// Call dynamic style with variants - includes theme-reactive color
|
|
20
20
|
const iconStyle = (iconStyles.icon as any)({ color, intent, size });
|
|
21
21
|
|
|
22
|
-
const { theme } = useUnistyles();
|
|
23
|
-
|
|
24
22
|
const iconSize = useMemo(() => {
|
|
25
|
-
return
|
|
26
|
-
}, [
|
|
23
|
+
return iconStyle.width;
|
|
24
|
+
}, [iconStyle]);
|
|
27
25
|
|
|
28
|
-
//
|
|
26
|
+
// Extract color from iconStyle for explicit color prop (RN vector icons need this)
|
|
27
|
+
const iconColor = iconStyle.color;
|
|
29
28
|
|
|
30
29
|
return (
|
|
31
30
|
<MaterialCommunityIcons
|
|
@@ -33,6 +32,7 @@ const Icon = forwardRef<any, IconProps>(({
|
|
|
33
32
|
nativeID={id}
|
|
34
33
|
size={iconSize}
|
|
35
34
|
name={name}
|
|
35
|
+
color={iconColor}
|
|
36
36
|
style={[iconStyle, style]}
|
|
37
37
|
testID={testID}
|
|
38
38
|
accessibilityLabel={accessibilityLabel}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { StyleSheet } from 'react-native-unistyles';
|
|
2
|
+
import { Theme, StylesheetStyles, Intent, Color, getColorFromString } from '@idealyst/theme';
|
|
3
|
+
import { buildSizeVariants } from '../utils/buildSizeVariants';
|
|
4
|
+
import { IconSizeVariant } from './types';
|
|
5
|
+
import { applyExtensions } from '../extensions/applyExtension';
|
|
6
|
+
|
|
7
|
+
type IconVariants = {
|
|
8
|
+
size: IconSizeVariant;
|
|
9
|
+
intent?: Intent;
|
|
10
|
+
color?: Color;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export type ExpandedIconStyles = StylesheetStyles<keyof IconVariants>;
|
|
14
|
+
|
|
15
|
+
export type IconStylesheet = {
|
|
16
|
+
icon: ExpandedIconStyles;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Create color variants for icon
|
|
21
|
+
*/
|
|
22
|
+
function getIconColor(theme: Theme, color?: Color, intent?: Intent): string {
|
|
23
|
+
if (intent) {
|
|
24
|
+
return theme.intents[intent]?.primary
|
|
25
|
+
} else if (color) {
|
|
26
|
+
return getColorFromString(theme, color);
|
|
27
|
+
}
|
|
28
|
+
return theme.colors.text.primary;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function buildIconSize(theme: Theme, size?: IconSizeVariant) {
|
|
32
|
+
// Handle direct numeric sizes
|
|
33
|
+
if (typeof size === 'number') {
|
|
34
|
+
return {
|
|
35
|
+
width: size,
|
|
36
|
+
height: size,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Default to 'md' if size is undefined
|
|
41
|
+
const sizeKey = size || 'md';
|
|
42
|
+
const iconSize = theme.sizes.icon[sizeKey];
|
|
43
|
+
|
|
44
|
+
if (typeof iconSize === 'number') {
|
|
45
|
+
return {
|
|
46
|
+
width: iconSize,
|
|
47
|
+
height: iconSize,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return buildSizeVariants(theme, 'icon', (size) => ({
|
|
52
|
+
width: size.width,
|
|
53
|
+
height: size.height,
|
|
54
|
+
}))[sizeKey];
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function createIconStyles(theme: Theme) {
|
|
58
|
+
return ({ color, intent, size }: Partial<IconVariants>) => {
|
|
59
|
+
const iconSize = buildIconSize(theme, size);
|
|
60
|
+
return {
|
|
61
|
+
width: iconSize.width,
|
|
62
|
+
height: iconSize.height,
|
|
63
|
+
color: getIconColor(theme, color, intent),
|
|
64
|
+
_web: {
|
|
65
|
+
display: 'inline-block',
|
|
66
|
+
verticalAlign: 'middle',
|
|
67
|
+
flexShrink: 0,
|
|
68
|
+
lineHeight: 0,
|
|
69
|
+
},
|
|
70
|
+
} as const;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Styles are inlined here instead of in @idealyst/theme because Unistyles' Babel
|
|
75
|
+
// transform on native cannot resolve function calls to extract variant structures.
|
|
76
|
+
export const iconStyles = StyleSheet.create((theme: Theme) => {
|
|
77
|
+
// Apply extensions to main visual elements
|
|
78
|
+
return applyExtensions('Icon', theme, {
|
|
79
|
+
icon: createIconStyles(theme),
|
|
80
|
+
});
|
|
81
|
+
});
|
package/src/Icon/Icon.styles.tsx
CHANGED
|
@@ -1,85 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Icon styles using defineStyle with dynamic functions.
|
|
3
|
+
*/
|
|
1
4
|
import { StyleSheet } from 'react-native-unistyles';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
5
|
+
import { defineStyle, ThemeStyleWrapper, getColorFromString } from '@idealyst/theme';
|
|
6
|
+
import type { Theme as BaseTheme, Intent, Color } from '@idealyst/theme';
|
|
4
7
|
import { IconSizeVariant } from './types';
|
|
5
|
-
import { applyExtensions } from '../extensions/applyExtension';
|
|
6
8
|
|
|
7
|
-
|
|
9
|
+
// Required: Unistyles must see StyleSheet usage in original source to process this file
|
|
10
|
+
void StyleSheet;
|
|
11
|
+
|
|
12
|
+
// Wrap theme for $iterator support
|
|
13
|
+
type Theme = ThemeStyleWrapper<BaseTheme>;
|
|
14
|
+
|
|
15
|
+
export type IconVariants = {
|
|
8
16
|
size: IconSizeVariant;
|
|
9
17
|
intent?: Intent;
|
|
10
18
|
color?: Color;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export type ExpandedIconStyles = StylesheetStyles<keyof IconVariants>;
|
|
19
|
+
};
|
|
14
20
|
|
|
15
|
-
export type
|
|
16
|
-
icon: ExpandedIconStyles;
|
|
17
|
-
}
|
|
21
|
+
export type IconDynamicProps = Partial<IconVariants>;
|
|
18
22
|
|
|
19
23
|
/**
|
|
20
|
-
*
|
|
24
|
+
* Icon styles with dynamic color/size handling.
|
|
21
25
|
*/
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
}
|
|
28
|
-
return theme.colors.text.primary;
|
|
29
|
-
}
|
|
26
|
+
export const iconStyles = defineStyle('Icon', (theme: Theme) => ({
|
|
27
|
+
icon: ({ color, intent, size = 'md' }: IconDynamicProps) => {
|
|
28
|
+
// Handle size - can be a named size or number
|
|
29
|
+
let iconWidth: number;
|
|
30
|
+
let iconHeight: number;
|
|
30
31
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
32
|
+
if (typeof size === 'number') {
|
|
33
|
+
iconWidth = size;
|
|
34
|
+
iconHeight = size;
|
|
35
|
+
} else {
|
|
36
|
+
const sizeKey = size || 'md';
|
|
37
|
+
const iconSize = theme.sizes.icon[sizeKey];
|
|
38
|
+
if (typeof iconSize === 'number') {
|
|
39
|
+
iconWidth = iconSize;
|
|
40
|
+
iconHeight = iconSize;
|
|
41
|
+
} else {
|
|
42
|
+
iconWidth = (iconSize?.width as number) ?? 24;
|
|
43
|
+
iconHeight = (iconSize?.height as number) ?? 24;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
39
46
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
47
|
+
// Get color - intent takes priority, then color prop, then default
|
|
48
|
+
const iconColor = intent
|
|
49
|
+
? theme.intents[intent]?.primary
|
|
50
|
+
: color
|
|
51
|
+
? getColorFromString(theme as unknown as BaseTheme, color)
|
|
52
|
+
: theme.colors.text.primary;
|
|
43
53
|
|
|
44
|
-
if (typeof iconSize === 'number') {
|
|
45
54
|
return {
|
|
46
|
-
width:
|
|
47
|
-
height:
|
|
48
|
-
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
return buildSizeVariants(theme, 'icon', (size) => ({
|
|
52
|
-
width: size.width,
|
|
53
|
-
height: size.height,
|
|
54
|
-
}))[sizeKey];
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
function createIconStyles(theme: Theme) {
|
|
58
|
-
return ({ color, intent, size }: Partial<IconVariants>) => {
|
|
59
|
-
const iconSize = buildIconSize(theme, size);
|
|
60
|
-
return {
|
|
61
|
-
width: iconSize.width,
|
|
62
|
-
height: iconSize.height,
|
|
63
|
-
color: getIconColor(theme, color, intent),
|
|
55
|
+
width: iconWidth,
|
|
56
|
+
height: iconHeight,
|
|
57
|
+
color: iconColor,
|
|
64
58
|
_web: {
|
|
65
|
-
|
|
59
|
+
fontSize: iconWidth,
|
|
60
|
+
width: '1em',
|
|
61
|
+
height: '1em',
|
|
62
|
+
display: 'inline-flex',
|
|
63
|
+
alignItems: 'center',
|
|
64
|
+
justifyContent: 'center',
|
|
66
65
|
verticalAlign: 'middle',
|
|
67
66
|
flexShrink: 0,
|
|
68
|
-
lineHeight:
|
|
67
|
+
lineHeight: 1,
|
|
69
68
|
},
|
|
70
69
|
} as const;
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
// Styles are inlined here instead of in @idealyst/theme because Unistyles' Babel
|
|
75
|
-
// transform on native cannot resolve function calls to extract variant structures.
|
|
76
|
-
export const iconStyles = StyleSheet.create((theme: Theme) => {
|
|
77
|
-
// Apply extensions to main visual elements
|
|
78
|
-
const extended = applyExtensions('Icon', theme, {
|
|
79
|
-
icon: createIconStyles(theme),
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
return {
|
|
83
|
-
...extended,
|
|
84
|
-
};
|
|
85
|
-
});
|
|
70
|
+
},
|
|
71
|
+
}));
|