@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,289 @@
|
|
|
1
|
+
import { StyleSheet } from 'react-native-unistyles';
|
|
2
|
+
import { Theme, Size } from '@idealyst/theme';
|
|
3
|
+
import { buildSizeVariants } from '../utils/buildSizeVariants';
|
|
4
|
+
import {
|
|
5
|
+
buildMarginVariants,
|
|
6
|
+
buildMarginVerticalVariants,
|
|
7
|
+
buildMarginHorizontalVariants,
|
|
8
|
+
} from '../utils/buildViewStyleVariants';
|
|
9
|
+
import { InputSize, InputType } from './types';
|
|
10
|
+
import { applyExtensions } from '../extensions/applyExtension';
|
|
11
|
+
|
|
12
|
+
export type InputVariants = {
|
|
13
|
+
size: InputSize;
|
|
14
|
+
type: InputType;
|
|
15
|
+
focused: boolean;
|
|
16
|
+
hasError: boolean;
|
|
17
|
+
disabled: boolean;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
type InputDynamicProps = {
|
|
21
|
+
type?: InputType;
|
|
22
|
+
focused?: boolean;
|
|
23
|
+
hasError?: boolean;
|
|
24
|
+
disabled?: boolean;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Get container border/background styles based on type, focused, hasError, disabled
|
|
29
|
+
*/
|
|
30
|
+
function getContainerDynamicStyles(theme: Theme, props: InputDynamicProps) {
|
|
31
|
+
const { type = 'outlined', focused = false, hasError = false, disabled = false } = props;
|
|
32
|
+
const focusColor = theme.intents.primary.primary;
|
|
33
|
+
const errorColor = theme.intents.error.primary;
|
|
34
|
+
|
|
35
|
+
// Base styles by type
|
|
36
|
+
let backgroundColor = 'transparent';
|
|
37
|
+
let borderWidth = 1;
|
|
38
|
+
let borderColor = theme.colors.border.primary;
|
|
39
|
+
let borderStyle = 'solid' as const;
|
|
40
|
+
|
|
41
|
+
if (type === 'filled') {
|
|
42
|
+
backgroundColor = theme.colors.surface.secondary;
|
|
43
|
+
borderWidth = 0;
|
|
44
|
+
} else if (type === 'bare') {
|
|
45
|
+
backgroundColor = 'transparent';
|
|
46
|
+
borderWidth = 0;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Error state takes precedence
|
|
50
|
+
if (hasError) {
|
|
51
|
+
borderColor = errorColor;
|
|
52
|
+
borderWidth = 1;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Focus state (error still takes precedence for color)
|
|
56
|
+
if (focused && !hasError) {
|
|
57
|
+
borderColor = focusColor;
|
|
58
|
+
borderWidth = 1;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Disabled state
|
|
62
|
+
if (disabled) {
|
|
63
|
+
backgroundColor = theme.colors.surface.secondary;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return {
|
|
67
|
+
backgroundColor,
|
|
68
|
+
borderWidth,
|
|
69
|
+
borderColor,
|
|
70
|
+
borderStyle,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Create dynamic container styles
|
|
76
|
+
*/
|
|
77
|
+
function createContainerStyles(theme: Theme) {
|
|
78
|
+
return (props: InputDynamicProps) => {
|
|
79
|
+
const { type = 'outlined', focused = false, hasError = false, disabled = false } = props;
|
|
80
|
+
const dynamicStyles = getContainerDynamicStyles(theme, props);
|
|
81
|
+
const focusColor = theme.intents.primary.primary;
|
|
82
|
+
const errorColor = theme.intents.error.primary;
|
|
83
|
+
|
|
84
|
+
// Web-specific border and shadow
|
|
85
|
+
let webBorder = `1px solid ${dynamicStyles.borderColor}`;
|
|
86
|
+
let webBoxShadow = 'none';
|
|
87
|
+
|
|
88
|
+
if (type === 'filled' || type === 'bare') {
|
|
89
|
+
webBorder = 'none';
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (hasError) {
|
|
93
|
+
webBorder = `1px solid ${errorColor}`;
|
|
94
|
+
if (focused) {
|
|
95
|
+
webBoxShadow = `0 0 0 2px ${errorColor}20`;
|
|
96
|
+
}
|
|
97
|
+
} else if (focused) {
|
|
98
|
+
webBorder = `1px solid ${focusColor}`;
|
|
99
|
+
webBoxShadow = `0 0 0 2px ${focusColor}20`;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return {
|
|
103
|
+
display: 'flex',
|
|
104
|
+
flexDirection: 'row',
|
|
105
|
+
alignItems: 'center',
|
|
106
|
+
width: '100%',
|
|
107
|
+
minWidth: 0,
|
|
108
|
+
borderRadius: 8,
|
|
109
|
+
...dynamicStyles,
|
|
110
|
+
opacity: disabled ? 0.6 : 1,
|
|
111
|
+
variants: {
|
|
112
|
+
size: buildSizeVariants(theme, 'input', (size) => ({
|
|
113
|
+
height: size.height,
|
|
114
|
+
paddingHorizontal: size.paddingHorizontal,
|
|
115
|
+
})),
|
|
116
|
+
// Spacing variants from FormInputStyleProps
|
|
117
|
+
margin: buildMarginVariants(theme),
|
|
118
|
+
marginVertical: buildMarginVerticalVariants(theme),
|
|
119
|
+
marginHorizontal: buildMarginHorizontalVariants(theme),
|
|
120
|
+
},
|
|
121
|
+
_web: {
|
|
122
|
+
boxSizing: 'border-box',
|
|
123
|
+
transition: 'border-color 0.2s ease, box-shadow 0.2s ease',
|
|
124
|
+
border: webBorder,
|
|
125
|
+
boxShadow: webBoxShadow,
|
|
126
|
+
cursor: disabled ? 'not-allowed' : 'text',
|
|
127
|
+
},
|
|
128
|
+
} as const;
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Create left icon container styles
|
|
134
|
+
*/
|
|
135
|
+
function createLeftIconContainerStyles(theme: Theme) {
|
|
136
|
+
return () => ({
|
|
137
|
+
display: 'flex' as const,
|
|
138
|
+
alignItems: 'center' as const,
|
|
139
|
+
justifyContent: 'center' as const,
|
|
140
|
+
flexShrink: 0,
|
|
141
|
+
variants: {
|
|
142
|
+
size: buildSizeVariants(theme, 'input', (size) => ({
|
|
143
|
+
marginRight: size.iconMargin,
|
|
144
|
+
})),
|
|
145
|
+
},
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Create right icon container styles
|
|
151
|
+
*/
|
|
152
|
+
function createRightIconContainerStyles(theme: Theme) {
|
|
153
|
+
return () => ({
|
|
154
|
+
display: 'flex' as const,
|
|
155
|
+
alignItems: 'center' as const,
|
|
156
|
+
justifyContent: 'center' as const,
|
|
157
|
+
flexShrink: 0,
|
|
158
|
+
variants: {
|
|
159
|
+
size: buildSizeVariants(theme, 'input', (size) => ({
|
|
160
|
+
marginLeft: size.iconMargin,
|
|
161
|
+
})),
|
|
162
|
+
},
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Create left icon styles
|
|
168
|
+
*/
|
|
169
|
+
function createLeftIconStyles(theme: Theme) {
|
|
170
|
+
return () => ({
|
|
171
|
+
color: theme.colors.text.secondary,
|
|
172
|
+
variants: {
|
|
173
|
+
size: buildSizeVariants(theme, 'input', (size) => ({
|
|
174
|
+
fontSize: size.iconSize,
|
|
175
|
+
width: size.iconSize,
|
|
176
|
+
height: size.iconSize,
|
|
177
|
+
})),
|
|
178
|
+
},
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Create right icon styles
|
|
184
|
+
*/
|
|
185
|
+
function createRightIconStyles(theme: Theme) {
|
|
186
|
+
return () => ({
|
|
187
|
+
display: 'flex' as const,
|
|
188
|
+
alignItems: 'center' as const,
|
|
189
|
+
justifyContent: 'center' as const,
|
|
190
|
+
flexShrink: 0,
|
|
191
|
+
color: theme.colors.text.secondary,
|
|
192
|
+
variants: {
|
|
193
|
+
size: buildSizeVariants(theme, 'input', (size) => ({
|
|
194
|
+
fontSize: size.iconSize,
|
|
195
|
+
width: size.iconSize,
|
|
196
|
+
height: size.iconSize,
|
|
197
|
+
})),
|
|
198
|
+
},
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Create password toggle styles
|
|
204
|
+
*/
|
|
205
|
+
function createPasswordToggleStyles(theme: Theme) {
|
|
206
|
+
return () => ({
|
|
207
|
+
display: 'flex' as const,
|
|
208
|
+
alignItems: 'center' as const,
|
|
209
|
+
justifyContent: 'center' as const,
|
|
210
|
+
flexShrink: 0,
|
|
211
|
+
padding: 0,
|
|
212
|
+
variants: {
|
|
213
|
+
size: buildSizeVariants(theme, 'input', (size) => ({
|
|
214
|
+
marginLeft: size.iconMargin,
|
|
215
|
+
})),
|
|
216
|
+
},
|
|
217
|
+
_web: {
|
|
218
|
+
background: 'transparent',
|
|
219
|
+
border: 'none',
|
|
220
|
+
cursor: 'pointer',
|
|
221
|
+
_hover: {
|
|
222
|
+
opacity: 0.7,
|
|
223
|
+
},
|
|
224
|
+
_active: {
|
|
225
|
+
opacity: 0.5,
|
|
226
|
+
},
|
|
227
|
+
},
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Create password toggle icon styles
|
|
233
|
+
*/
|
|
234
|
+
function createPasswordToggleIconStyles(theme: Theme) {
|
|
235
|
+
return () => ({
|
|
236
|
+
display: 'flex' as const,
|
|
237
|
+
alignItems: 'center' as const,
|
|
238
|
+
justifyContent: 'center' as const,
|
|
239
|
+
flexShrink: 0,
|
|
240
|
+
color: theme.colors.text.secondary,
|
|
241
|
+
variants: {
|
|
242
|
+
size: buildSizeVariants(theme, 'input', (size) => ({
|
|
243
|
+
fontSize: size.iconSize,
|
|
244
|
+
width: size.iconSize,
|
|
245
|
+
height: size.iconSize,
|
|
246
|
+
})),
|
|
247
|
+
},
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Create input styles
|
|
253
|
+
*/
|
|
254
|
+
function createInputStyles(theme: Theme) {
|
|
255
|
+
return () => ({
|
|
256
|
+
flex: 1,
|
|
257
|
+
minWidth: 0,
|
|
258
|
+
backgroundColor: 'transparent',
|
|
259
|
+
color: theme.colors.text.primary,
|
|
260
|
+
fontWeight: '400' as const,
|
|
261
|
+
variants: {
|
|
262
|
+
size: buildSizeVariants(theme, 'input', (size) => ({
|
|
263
|
+
fontSize: size.fontSize,
|
|
264
|
+
})),
|
|
265
|
+
},
|
|
266
|
+
_web: {
|
|
267
|
+
border: 'none',
|
|
268
|
+
outline: 'none',
|
|
269
|
+
fontFamily: 'inherit',
|
|
270
|
+
},
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
// Styles are inlined here instead of in @idealyst/theme because Unistyles' Babel
|
|
275
|
+
// transform on native cannot resolve function calls to extract variant structures.
|
|
276
|
+
export const inputStyles = StyleSheet.create((theme: Theme) => {
|
|
277
|
+
// Apply extensions to main visual elements
|
|
278
|
+
|
|
279
|
+
return applyExtensions('Input', theme, {container: createContainerStyles(theme),
|
|
280
|
+
input: createInputStyles(theme),
|
|
281
|
+
// Additional styles (merged from return)
|
|
282
|
+
// Minor utility styles (not extended)
|
|
283
|
+
leftIconContainer: createLeftIconContainerStyles(theme)(),
|
|
284
|
+
rightIconContainer: createRightIconContainerStyles(theme)(),
|
|
285
|
+
leftIcon: createLeftIconStyles(theme)(),
|
|
286
|
+
rightIcon: createRightIconStyles(theme)(),
|
|
287
|
+
passwordToggle: createPasswordToggleStyles(theme)(),
|
|
288
|
+
passwordToggleIcon: createPasswordToggleIconStyles(theme)()});
|
|
289
|
+
});
|
|
@@ -1,89 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Input styles using defineStyle with $iterator expansion.
|
|
3
|
+
*/
|
|
1
4
|
import { StyleSheet } from 'react-native-unistyles';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
} from '../utils/buildViewStyleVariants';
|
|
9
|
-
import { InputSize, InputType } from './types';
|
|
10
|
-
import { applyExtensions } from '../extensions/applyExtension';
|
|
5
|
+
import { defineStyle, ThemeStyleWrapper } from '@idealyst/theme';
|
|
6
|
+
import type { Theme as BaseTheme } from '@idealyst/theme';
|
|
7
|
+
import { ViewStyleSize } from '../utils/viewStyleProps';
|
|
8
|
+
|
|
9
|
+
// Required: Unistyles must see StyleSheet usage in original source to process this file
|
|
10
|
+
void StyleSheet;
|
|
11
11
|
|
|
12
|
+
// Wrap theme for $iterator support
|
|
13
|
+
type Theme = ThemeStyleWrapper<BaseTheme>;
|
|
12
14
|
|
|
13
|
-
|
|
14
|
-
size: InputSize;
|
|
15
|
-
type: InputType;
|
|
16
|
-
focused: boolean;
|
|
17
|
-
hasError: boolean;
|
|
18
|
-
disabled: boolean;
|
|
19
|
-
}
|
|
15
|
+
type InputType = 'outlined' | 'filled' | 'bare';
|
|
20
16
|
|
|
21
|
-
type InputDynamicProps = {
|
|
17
|
+
export type InputDynamicProps = {
|
|
22
18
|
type?: InputType;
|
|
23
19
|
focused?: boolean;
|
|
24
20
|
hasError?: boolean;
|
|
25
21
|
disabled?: boolean;
|
|
22
|
+
margin?: ViewStyleSize;
|
|
23
|
+
marginVertical?: ViewStyleSize;
|
|
24
|
+
marginHorizontal?: ViewStyleSize;
|
|
26
25
|
};
|
|
27
26
|
|
|
28
27
|
/**
|
|
29
|
-
*
|
|
28
|
+
* Input styles with type/state handling.
|
|
30
29
|
*/
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
// Base styles by type
|
|
37
|
-
let backgroundColor = 'transparent';
|
|
38
|
-
let borderWidth = 1;
|
|
39
|
-
let borderColor = theme.colors.border.primary;
|
|
40
|
-
let borderStyle = 'solid' as const;
|
|
41
|
-
|
|
42
|
-
if (type === 'filled') {
|
|
43
|
-
backgroundColor = theme.colors.surface.secondary;
|
|
44
|
-
borderWidth = 0;
|
|
45
|
-
} else if (type === 'bare') {
|
|
46
|
-
backgroundColor = 'transparent';
|
|
47
|
-
borderWidth = 0;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// Error state takes precedence
|
|
51
|
-
if (hasError) {
|
|
52
|
-
borderColor = errorColor;
|
|
53
|
-
borderWidth = 1;
|
|
54
|
-
}
|
|
30
|
+
export const inputStyles = defineStyle('Input', (theme: Theme) => ({
|
|
31
|
+
container: ({ type = 'outlined', focused = false, hasError = false, disabled = false }: InputDynamicProps) => {
|
|
32
|
+
const focusColor = theme.intents.primary.primary;
|
|
33
|
+
const errorColor = theme.intents.error.primary;
|
|
55
34
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
35
|
+
// Base styles by type
|
|
36
|
+
let backgroundColor = 'transparent';
|
|
37
|
+
let borderWidth = 1;
|
|
38
|
+
let borderColor = theme.colors.border.primary;
|
|
39
|
+
|
|
40
|
+
if (type === 'filled') {
|
|
41
|
+
backgroundColor = theme.colors.surface.secondary;
|
|
42
|
+
borderWidth = 0;
|
|
43
|
+
} else if (type === 'bare') {
|
|
44
|
+
backgroundColor = 'transparent';
|
|
45
|
+
borderWidth = 0;
|
|
46
|
+
}
|
|
61
47
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
48
|
+
// Error state takes precedence
|
|
49
|
+
if (hasError) {
|
|
50
|
+
borderColor = errorColor;
|
|
51
|
+
borderWidth = 1;
|
|
52
|
+
}
|
|
66
53
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
};
|
|
73
|
-
}
|
|
54
|
+
// Focus state (error still takes precedence for color)
|
|
55
|
+
if (focused && !hasError) {
|
|
56
|
+
borderColor = focusColor;
|
|
57
|
+
borderWidth = 1;
|
|
58
|
+
}
|
|
74
59
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
return (props: InputDynamicProps) => {
|
|
80
|
-
const { type = 'outlined', focused = false, hasError = false, disabled = false } = props;
|
|
81
|
-
const dynamicStyles = getContainerDynamicStyles(theme, props);
|
|
82
|
-
const focusColor = theme.intents.primary.primary;
|
|
83
|
-
const errorColor = theme.intents.error.primary;
|
|
60
|
+
// Disabled state
|
|
61
|
+
if (disabled) {
|
|
62
|
+
backgroundColor = theme.colors.surface.secondary;
|
|
63
|
+
}
|
|
84
64
|
|
|
85
65
|
// Web-specific border and shadow
|
|
86
|
-
let webBorder = `1px solid ${
|
|
66
|
+
let webBorder = `1px solid ${borderColor}`;
|
|
87
67
|
let webBoxShadow = 'none';
|
|
88
68
|
|
|
89
69
|
if (type === 'filled' || type === 'bare') {
|
|
@@ -101,23 +81,32 @@ function createContainerStyles(theme: Theme) {
|
|
|
101
81
|
}
|
|
102
82
|
|
|
103
83
|
return {
|
|
104
|
-
display: 'flex',
|
|
105
|
-
flexDirection: 'row',
|
|
106
|
-
alignItems: 'center',
|
|
84
|
+
display: 'flex' as const,
|
|
85
|
+
flexDirection: 'row' as const,
|
|
86
|
+
alignItems: 'center' as const,
|
|
107
87
|
width: '100%',
|
|
108
88
|
minWidth: 0,
|
|
109
89
|
borderRadius: 8,
|
|
110
|
-
|
|
90
|
+
backgroundColor,
|
|
91
|
+
borderWidth,
|
|
92
|
+
borderColor,
|
|
93
|
+
borderStyle: 'solid' as const,
|
|
111
94
|
opacity: disabled ? 0.6 : 1,
|
|
112
95
|
variants: {
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
margin:
|
|
119
|
-
|
|
120
|
-
|
|
96
|
+
// $iterator expands for each input size
|
|
97
|
+
size: {
|
|
98
|
+
height: theme.sizes.$input.height,
|
|
99
|
+
paddingHorizontal: theme.sizes.$input.paddingHorizontal,
|
|
100
|
+
},
|
|
101
|
+
margin: {
|
|
102
|
+
margin: theme.sizes.$view.padding,
|
|
103
|
+
},
|
|
104
|
+
marginVertical: {
|
|
105
|
+
marginVertical: theme.sizes.$view.padding,
|
|
106
|
+
},
|
|
107
|
+
marginHorizontal: {
|
|
108
|
+
marginHorizontal: theme.sizes.$view.padding,
|
|
109
|
+
},
|
|
121
110
|
},
|
|
122
111
|
_web: {
|
|
123
112
|
boxSizing: 'border-box',
|
|
@@ -127,168 +116,108 @@ function createContainerStyles(theme: Theme) {
|
|
|
127
116
|
cursor: disabled ? 'not-allowed' : 'text',
|
|
128
117
|
},
|
|
129
118
|
} as const;
|
|
130
|
-
}
|
|
131
|
-
}
|
|
119
|
+
},
|
|
132
120
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
121
|
+
input: (_props: InputDynamicProps) => ({
|
|
122
|
+
flex: 1,
|
|
123
|
+
minWidth: 0,
|
|
124
|
+
backgroundColor: 'transparent' as const,
|
|
125
|
+
color: theme.colors.text.primary,
|
|
126
|
+
fontWeight: '400' as const,
|
|
127
|
+
variants: {
|
|
128
|
+
size: {
|
|
129
|
+
fontSize: theme.sizes.$input.fontSize,
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
_web: {
|
|
133
|
+
border: 'none',
|
|
134
|
+
outline: 'none',
|
|
135
|
+
fontFamily: 'inherit',
|
|
136
|
+
},
|
|
137
|
+
}),
|
|
138
|
+
|
|
139
|
+
leftIconContainer: (_props: InputDynamicProps) => ({
|
|
138
140
|
display: 'flex' as const,
|
|
139
141
|
alignItems: 'center' as const,
|
|
140
142
|
justifyContent: 'center' as const,
|
|
141
143
|
flexShrink: 0,
|
|
142
144
|
variants: {
|
|
143
|
-
size:
|
|
144
|
-
marginRight:
|
|
145
|
-
}
|
|
145
|
+
size: {
|
|
146
|
+
marginRight: theme.sizes.$input.iconMargin,
|
|
147
|
+
},
|
|
146
148
|
},
|
|
147
|
-
})
|
|
148
|
-
}
|
|
149
|
+
}),
|
|
149
150
|
|
|
150
|
-
|
|
151
|
-
* Create right icon container styles
|
|
152
|
-
*/
|
|
153
|
-
function createRightIconContainerStyles(theme: Theme) {
|
|
154
|
-
return () => ({
|
|
151
|
+
rightIconContainer: (_props: InputDynamicProps) => ({
|
|
155
152
|
display: 'flex' as const,
|
|
156
153
|
alignItems: 'center' as const,
|
|
157
154
|
justifyContent: 'center' as const,
|
|
158
155
|
flexShrink: 0,
|
|
159
156
|
variants: {
|
|
160
|
-
size:
|
|
161
|
-
marginLeft:
|
|
162
|
-
}
|
|
157
|
+
size: {
|
|
158
|
+
marginLeft: theme.sizes.$input.iconMargin,
|
|
159
|
+
},
|
|
163
160
|
},
|
|
164
|
-
})
|
|
165
|
-
}
|
|
161
|
+
}),
|
|
166
162
|
|
|
167
|
-
|
|
168
|
-
* Create left icon styles
|
|
169
|
-
*/
|
|
170
|
-
function createLeftIconStyles(theme: Theme) {
|
|
171
|
-
return () => ({
|
|
163
|
+
leftIcon: (_props: InputDynamicProps) => ({
|
|
172
164
|
color: theme.colors.text.secondary,
|
|
173
165
|
variants: {
|
|
174
|
-
size:
|
|
175
|
-
fontSize:
|
|
176
|
-
width:
|
|
177
|
-
height:
|
|
178
|
-
}
|
|
166
|
+
size: {
|
|
167
|
+
fontSize: theme.sizes.$input.iconSize,
|
|
168
|
+
width: theme.sizes.$input.iconSize,
|
|
169
|
+
height: theme.sizes.$input.iconSize,
|
|
170
|
+
},
|
|
179
171
|
},
|
|
180
|
-
})
|
|
181
|
-
}
|
|
172
|
+
}),
|
|
182
173
|
|
|
183
|
-
|
|
184
|
-
* Create right icon styles
|
|
185
|
-
*/
|
|
186
|
-
function createRightIconStyles(theme: Theme) {
|
|
187
|
-
return () => ({
|
|
174
|
+
rightIcon: (_props: InputDynamicProps) => ({
|
|
188
175
|
display: 'flex' as const,
|
|
189
176
|
alignItems: 'center' as const,
|
|
190
177
|
justifyContent: 'center' as const,
|
|
191
178
|
flexShrink: 0,
|
|
192
179
|
color: theme.colors.text.secondary,
|
|
193
180
|
variants: {
|
|
194
|
-
size:
|
|
195
|
-
fontSize:
|
|
196
|
-
width:
|
|
197
|
-
height:
|
|
198
|
-
}
|
|
181
|
+
size: {
|
|
182
|
+
fontSize: theme.sizes.$input.iconSize,
|
|
183
|
+
width: theme.sizes.$input.iconSize,
|
|
184
|
+
height: theme.sizes.$input.iconSize,
|
|
185
|
+
},
|
|
199
186
|
},
|
|
200
|
-
})
|
|
201
|
-
}
|
|
187
|
+
}),
|
|
202
188
|
|
|
203
|
-
|
|
204
|
-
* Create password toggle styles
|
|
205
|
-
*/
|
|
206
|
-
function createPasswordToggleStyles(theme: Theme) {
|
|
207
|
-
return () => ({
|
|
189
|
+
passwordToggle: (_props: InputDynamicProps) => ({
|
|
208
190
|
display: 'flex' as const,
|
|
209
191
|
alignItems: 'center' as const,
|
|
210
192
|
justifyContent: 'center' as const,
|
|
211
193
|
flexShrink: 0,
|
|
212
194
|
padding: 0,
|
|
213
195
|
variants: {
|
|
214
|
-
size:
|
|
215
|
-
marginLeft:
|
|
216
|
-
}
|
|
196
|
+
size: {
|
|
197
|
+
marginLeft: theme.sizes.$input.iconMargin,
|
|
198
|
+
},
|
|
217
199
|
},
|
|
218
200
|
_web: {
|
|
219
201
|
background: 'transparent',
|
|
220
202
|
border: 'none',
|
|
221
203
|
cursor: 'pointer',
|
|
222
|
-
_hover: {
|
|
223
|
-
|
|
224
|
-
},
|
|
225
|
-
_active: {
|
|
226
|
-
opacity: 0.5,
|
|
227
|
-
},
|
|
204
|
+
_hover: { opacity: 0.7 },
|
|
205
|
+
_active: { opacity: 0.5 },
|
|
228
206
|
},
|
|
229
|
-
})
|
|
230
|
-
}
|
|
207
|
+
}),
|
|
231
208
|
|
|
232
|
-
|
|
233
|
-
* Create password toggle icon styles
|
|
234
|
-
*/
|
|
235
|
-
function createPasswordToggleIconStyles(theme: Theme) {
|
|
236
|
-
return () => ({
|
|
209
|
+
passwordToggleIcon: (_props: InputDynamicProps) => ({
|
|
237
210
|
display: 'flex' as const,
|
|
238
211
|
alignItems: 'center' as const,
|
|
239
212
|
justifyContent: 'center' as const,
|
|
240
213
|
flexShrink: 0,
|
|
241
214
|
color: theme.colors.text.secondary,
|
|
242
215
|
variants: {
|
|
243
|
-
size:
|
|
244
|
-
fontSize:
|
|
245
|
-
width:
|
|
246
|
-
height:
|
|
247
|
-
}
|
|
248
|
-
},
|
|
249
|
-
});
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
/**
|
|
253
|
-
* Create input styles
|
|
254
|
-
*/
|
|
255
|
-
function createInputStyles(theme: Theme) {
|
|
256
|
-
return () => ({
|
|
257
|
-
flex: 1,
|
|
258
|
-
minWidth: 0,
|
|
259
|
-
backgroundColor: 'transparent',
|
|
260
|
-
color: theme.colors.text.primary,
|
|
261
|
-
fontWeight: '400' as const,
|
|
262
|
-
variants: {
|
|
263
|
-
size: buildSizeVariants(theme, 'input', (size) => ({
|
|
264
|
-
fontSize: size.fontSize,
|
|
265
|
-
})),
|
|
266
|
-
},
|
|
267
|
-
_web: {
|
|
268
|
-
border: 'none',
|
|
269
|
-
outline: 'none',
|
|
270
|
-
fontFamily: 'inherit',
|
|
216
|
+
size: {
|
|
217
|
+
fontSize: theme.sizes.$input.iconSize,
|
|
218
|
+
width: theme.sizes.$input.iconSize,
|
|
219
|
+
height: theme.sizes.$input.iconSize,
|
|
220
|
+
},
|
|
271
221
|
},
|
|
272
|
-
})
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
// Styles are inlined here instead of in @idealyst/theme because Unistyles' Babel
|
|
276
|
-
// transform on native cannot resolve function calls to extract variant structures.
|
|
277
|
-
export const inputStyles = StyleSheet.create((theme: Theme) => {
|
|
278
|
-
// Apply extensions to main visual elements
|
|
279
|
-
const extended = applyExtensions('Input', theme, {
|
|
280
|
-
container: createContainerStyles(theme),
|
|
281
|
-
input: createInputStyles(theme),
|
|
282
|
-
});
|
|
283
|
-
|
|
284
|
-
return {
|
|
285
|
-
...extended,
|
|
286
|
-
// Minor utility styles (not extended)
|
|
287
|
-
leftIconContainer: createLeftIconContainerStyles(theme)(),
|
|
288
|
-
rightIconContainer: createRightIconContainerStyles(theme)(),
|
|
289
|
-
leftIcon: createLeftIconStyles(theme)(),
|
|
290
|
-
rightIcon: createRightIconStyles(theme)(),
|
|
291
|
-
passwordToggle: createPasswordToggleStyles(theme)(),
|
|
292
|
-
passwordToggleIcon: createPasswordToggleIconStyles(theme)(),
|
|
293
|
-
};
|
|
294
|
-
});
|
|
222
|
+
}),
|
|
223
|
+
}));
|