@idealyst/components 1.1.6 → 1.1.7
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 +8 -3
- package/src/Accordion/Accordion.native.tsx +15 -9
- package/src/Accordion/Accordion.styles.tsx +193 -168
- package/src/Accordion/Accordion.web.tsx +12 -7
- package/src/ActivityIndicator/ActivityIndicator.native.tsx +3 -2
- package/src/ActivityIndicator/ActivityIndicator.styles.tsx +22 -11
- package/src/ActivityIndicator/ActivityIndicator.web.tsx +2 -2
- package/src/Alert/Alert.native.tsx +11 -10
- package/src/Alert/Alert.styles.tsx +162 -253
- package/src/Alert/Alert.web.tsx +6 -10
- package/src/Avatar/Avatar.native.tsx +5 -2
- package/src/Avatar/Avatar.styles.tsx +48 -18
- package/src/Avatar/Avatar.web.tsx +2 -2
- package/src/Badge/Badge.native.tsx +2 -2
- package/src/Badge/Badge.styles.tsx +37 -16
- package/src/Badge/Badge.web.tsx +6 -6
- package/src/Breadcrumb/Breadcrumb.native.tsx +12 -5
- package/src/Breadcrumb/Breadcrumb.styles.tsx +59 -58
- package/src/Breadcrumb/Breadcrumb.web.tsx +13 -6
- package/src/Button/Button.native.tsx +39 -14
- package/src/Button/Button.styles.tsx +106 -208
- package/src/Button/Button.web.tsx +10 -8
- package/src/Card/Card.native.tsx +14 -6
- package/src/Card/Card.styles.tsx +64 -62
- package/src/Card/Card.web.tsx +5 -4
- package/src/Checkbox/Checkbox.native.tsx +7 -3
- package/src/Checkbox/Checkbox.styles.tsx +49 -25
- package/src/Checkbox/Checkbox.web.tsx +3 -3
- package/src/Chip/Chip.native.tsx +5 -5
- package/src/Chip/Chip.styles.tsx +71 -21
- package/src/Chip/Chip.web.tsx +5 -5
- package/src/Dialog/Dialog.native.tsx +10 -4
- package/src/Dialog/Dialog.styles.tsx +130 -90
- package/src/Dialog/Dialog.web.tsx +4 -4
- package/src/Divider/Divider.native.tsx +29 -42
- package/src/Divider/Divider.styles.tsx +138 -242
- package/src/Divider/Divider.web.tsx +17 -14
- package/src/Icon/Icon.native.tsx +11 -3
- package/src/Icon/Icon.styles.tsx +10 -4
- package/src/Image/Image.styles.tsx +53 -37
- package/src/Input/Input.native.tsx +6 -7
- package/src/Input/Input.styles.tsx +194 -174
- package/src/Input/Input.web.tsx +5 -8
- package/src/Link/Link.native.tsx +4 -1
- package/src/List/List.styles.tsx +79 -105
- package/src/List/ListItem.native.tsx +5 -3
- package/src/List/ListItem.web.tsx +4 -3
- package/src/Menu/Menu.native.tsx +1 -1
- package/src/Menu/Menu.styles.tsx +53 -37
- package/src/Menu/Menu.web.tsx +2 -2
- package/src/Menu/MenuItem.native.tsx +5 -3
- package/src/Menu/MenuItem.styles.tsx +68 -69
- package/src/Menu/MenuItem.web.tsx +16 -3
- package/src/Popover/Popover.native.tsx +1 -1
- package/src/Popover/Popover.styles.tsx +40 -29
- package/src/Popover/Popover.web.tsx +1 -1
- package/src/Pressable/Pressable.native.tsx +3 -1
- package/src/Pressable/Pressable.styles.tsx +20 -13
- package/src/Pressable/Pressable.web.tsx +1 -1
- package/src/Progress/Progress.native.tsx +15 -6
- package/src/Progress/Progress.styles.tsx +125 -85
- package/src/Progress/Progress.web.tsx +10 -9
- package/src/RadioButton/RadioButton.native.tsx +8 -3
- package/src/RadioButton/RadioButton.styles.tsx +44 -37
- package/src/RadioButton/RadioButton.web.tsx +3 -3
- package/src/SVGImage/SVGImage.styles.tsx +28 -16
- package/src/Screen/Screen.native.tsx +23 -13
- package/src/Screen/Screen.styles.tsx +57 -46
- package/src/Screen/Screen.web.tsx +1 -1
- package/src/Select/Select.native.tsx +11 -5
- package/src/Select/Select.styles.tsx +72 -52
- package/src/Select/Select.web.tsx +5 -5
- package/src/Skeleton/Skeleton.styles.tsx +26 -14
- package/src/Slider/Slider.native.tsx +9 -5
- package/src/Slider/Slider.styles.tsx +59 -48
- package/src/Slider/Slider.web.tsx +5 -5
- package/src/Switch/Switch.native.tsx +6 -2
- package/src/Switch/Switch.styles.tsx +46 -19
- package/src/Switch/Switch.web.tsx +4 -4
- package/src/TabBar/TabBar.native.tsx +23 -31
- package/src/TabBar/TabBar.styles.tsx +215 -371
- package/src/TabBar/TabBar.web.tsx +21 -33
- package/src/Table/Table.native.tsx +1 -1
- package/src/Table/Table.styles.tsx +11 -4
- package/src/Table/Table.web.tsx +1 -1
- package/src/Text/Text.native.tsx +3 -4
- package/src/Text/Text.styles.tsx +7 -1
- package/src/Text/Text.web.tsx +1 -1
- package/src/TextArea/TextArea.styles.tsx +90 -58
- package/src/Tooltip/Tooltip.native.tsx +2 -2
- package/src/Tooltip/Tooltip.styles.tsx +21 -12
- package/src/Tooltip/Tooltip.web.tsx +2 -2
- package/src/Video/Video.styles.tsx +39 -23
- package/src/View/View.native.tsx +4 -2
- package/src/View/View.styles.tsx +33 -22
- package/src/View/View.web.tsx +13 -2
- package/src/extensions/applyExtension.ts +210 -0
- package/src/extensions/extendComponent.ts +377 -0
- package/src/extensions/index.ts +102 -0
- package/src/extensions/types.ts +497 -0
- package/src/globals.ts +16 -0
- package/src/index.native.ts +4 -0
- package/src/index.ts +28 -0
- package/src/utils/deepMerge.ts +54 -2
|
@@ -87,9 +87,9 @@ const RadioButton: React.FC<RadioButtonProps> = ({
|
|
|
87
87
|
marginHorizontal,
|
|
88
88
|
});
|
|
89
89
|
|
|
90
|
-
const containerProps = getWebProps([radioButtonStyles.container, style]);
|
|
91
|
-
const radioProps = getWebProps([radioButtonStyles.radio({ intent })]);
|
|
92
|
-
const dotProps = getWebProps([radioButtonStyles.radioDot({ intent })]);
|
|
90
|
+
const containerProps = getWebProps([(radioButtonStyles.container as any)({}), style]);
|
|
91
|
+
const radioProps = getWebProps([(radioButtonStyles.radio as any)({ intent })]);
|
|
92
|
+
const dotProps = getWebProps([(radioButtonStyles.radioDot as any)({ intent })]);
|
|
93
93
|
const labelProps = getWebProps([radioButtonStyles.label]);
|
|
94
94
|
|
|
95
95
|
return (
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { StyleSheet } from 'react-native-unistyles';
|
|
2
2
|
import { Theme, StylesheetStyles, Intent} from '@idealyst/theme';
|
|
3
|
+
import { applyExtensions } from '../extensions/applyExtension';
|
|
3
4
|
|
|
4
5
|
type SVGImageIntent = Intent;
|
|
5
6
|
|
|
@@ -47,14 +48,11 @@ function createContainerNativeIntentVariants(theme: Theme) {
|
|
|
47
48
|
return variants;
|
|
48
49
|
}
|
|
49
50
|
|
|
50
|
-
//
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
container: {
|
|
56
|
-
alignItems: 'center',
|
|
57
|
-
justifyContent: 'center',
|
|
51
|
+
// Style creators for extension support
|
|
52
|
+
function createContainerStyles(theme: Theme) {
|
|
53
|
+
return () => ({
|
|
54
|
+
alignItems: 'center' as const,
|
|
55
|
+
justifyContent: 'center' as const,
|
|
58
56
|
variants: {
|
|
59
57
|
intent: createContainerIntentVariants(theme),
|
|
60
58
|
},
|
|
@@ -66,13 +64,27 @@ export const svgImageStyles = StyleSheet.create((theme: Theme) => {
|
|
|
66
64
|
intent: createContainerNativeIntentVariants(theme),
|
|
67
65
|
},
|
|
68
66
|
},
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
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
|
+
const extended = applyExtensions('SVGImage', theme, {
|
|
76
|
+
container: createContainerStyles(theme),
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
return {
|
|
80
|
+
...extended,
|
|
81
|
+
// Minor utility styles (not extended)
|
|
82
|
+
image: {
|
|
83
|
+
_web: {
|
|
84
|
+
display: 'block',
|
|
85
|
+
maxWidth: '100%',
|
|
86
|
+
height: 'auto',
|
|
87
|
+
},
|
|
75
88
|
},
|
|
76
|
-
}
|
|
77
|
-
};
|
|
89
|
+
};
|
|
78
90
|
});
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React, { forwardRef } from 'react';
|
|
2
|
-
import { View as RNView, ScrollView as RNScrollView
|
|
2
|
+
import { View as RNView, ScrollView as RNScrollView } from 'react-native';
|
|
3
|
+
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
3
4
|
import { ScreenProps } from './types';
|
|
4
5
|
import { screenStyles } from './Screen.styles';
|
|
5
6
|
|
|
@@ -21,6 +22,7 @@ const Screen = forwardRef<RNView | RNScrollView, ScreenProps>(({
|
|
|
21
22
|
testID,
|
|
22
23
|
id,
|
|
23
24
|
}, ref) => {
|
|
25
|
+
const insets = useSafeAreaInsets();
|
|
24
26
|
|
|
25
27
|
screenStyles.useVariants({
|
|
26
28
|
background,
|
|
@@ -34,6 +36,14 @@ const Screen = forwardRef<RNView | RNScrollView, ScreenProps>(({
|
|
|
34
36
|
marginHorizontal,
|
|
35
37
|
});
|
|
36
38
|
|
|
39
|
+
// Calculate safe area padding
|
|
40
|
+
const safeAreaStyle = safeArea ? {
|
|
41
|
+
paddingTop: insets.top,
|
|
42
|
+
paddingBottom: insets.bottom,
|
|
43
|
+
paddingLeft: insets.left,
|
|
44
|
+
paddingRight: insets.right,
|
|
45
|
+
} : undefined;
|
|
46
|
+
|
|
37
47
|
if (scrollable) {
|
|
38
48
|
// For ScrollView, flex: 1 goes on the ScrollView style
|
|
39
49
|
// Background and padding go on contentContainerStyle (without flex: 1)
|
|
@@ -41,11 +51,12 @@ const Screen = forwardRef<RNView | RNScrollView, ScreenProps>(({
|
|
|
41
51
|
|
|
42
52
|
const contentContainerStyleArray = [
|
|
43
53
|
screenStyles.screenContent,
|
|
54
|
+
safeAreaStyle,
|
|
44
55
|
contentInset ? {
|
|
45
|
-
paddingTop: contentInset.top,
|
|
46
|
-
paddingBottom: contentInset.bottom,
|
|
47
|
-
paddingLeft: contentInset.left,
|
|
48
|
-
paddingRight: contentInset.right,
|
|
56
|
+
paddingTop: (safeArea ? insets.top : 0) + (contentInset.top ?? 0),
|
|
57
|
+
paddingBottom: (safeArea ? insets.bottom : 0) + (contentInset.bottom ?? 0),
|
|
58
|
+
paddingLeft: (safeArea ? insets.left : 0) + (contentInset.left ?? 0),
|
|
59
|
+
paddingRight: (safeArea ? insets.right : 0) + (contentInset.right ?? 0),
|
|
49
60
|
} : undefined,
|
|
50
61
|
];
|
|
51
62
|
|
|
@@ -62,19 +73,18 @@ const Screen = forwardRef<RNView | RNScrollView, ScreenProps>(({
|
|
|
62
73
|
);
|
|
63
74
|
}
|
|
64
75
|
|
|
65
|
-
const
|
|
76
|
+
const screenStyle = (screenStyles.screen as any)({});
|
|
77
|
+
const containerStyle = [
|
|
78
|
+
screenStyle,
|
|
79
|
+
safeAreaStyle,
|
|
80
|
+
style,
|
|
81
|
+
];
|
|
66
82
|
|
|
67
|
-
|
|
83
|
+
return (
|
|
68
84
|
<RNView ref={ref as any} nativeID={id} style={containerStyle} testID={testID}>
|
|
69
85
|
{children}
|
|
70
86
|
</RNView>
|
|
71
87
|
);
|
|
72
|
-
|
|
73
|
-
if (safeArea) {
|
|
74
|
-
return <SafeAreaView style={{ flex: 1 }}>{view}</SafeAreaView>;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
return view;
|
|
78
88
|
});
|
|
79
89
|
|
|
80
90
|
Screen.displayName = 'Screen';
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
buildMarginVerticalVariants,
|
|
10
10
|
buildMarginHorizontalVariants,
|
|
11
11
|
} from '../utils/buildViewStyleVariants';
|
|
12
|
+
import { applyExtensions } from '../extensions/applyExtension';
|
|
12
13
|
|
|
13
14
|
function generateBackgroundVariants(theme: Theme) {
|
|
14
15
|
return {
|
|
@@ -22,55 +23,65 @@ function generateBackgroundVariants(theme: Theme) {
|
|
|
22
23
|
};
|
|
23
24
|
}
|
|
24
25
|
|
|
26
|
+
// Style creators for extension support
|
|
27
|
+
function createScreenStyles(theme: Theme) {
|
|
28
|
+
return () => ({
|
|
29
|
+
flex: 1,
|
|
30
|
+
variants: {
|
|
31
|
+
background: generateBackgroundVariants(theme),
|
|
32
|
+
safeArea: {
|
|
33
|
+
true: {},
|
|
34
|
+
false: {},
|
|
35
|
+
},
|
|
36
|
+
// Spacing variants from ContainerStyleProps
|
|
37
|
+
gap: buildGapVariants(theme),
|
|
38
|
+
padding: buildPaddingVariants(theme),
|
|
39
|
+
paddingVertical: buildPaddingVerticalVariants(theme),
|
|
40
|
+
paddingHorizontal: buildPaddingHorizontalVariants(theme),
|
|
41
|
+
margin: buildMarginVariants(theme),
|
|
42
|
+
marginVertical: buildMarginVerticalVariants(theme),
|
|
43
|
+
marginHorizontal: buildMarginHorizontalVariants(theme),
|
|
44
|
+
},
|
|
45
|
+
_web: {
|
|
46
|
+
overflow: 'auto',
|
|
47
|
+
display: 'flex',
|
|
48
|
+
flexDirection: 'column',
|
|
49
|
+
minHeight: '100%',
|
|
50
|
+
boxSizing: 'border-box',
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
25
55
|
// Styles are inlined here instead of in @idealyst/theme because Unistyles' Babel
|
|
26
56
|
// transform on native cannot resolve function calls to extract variant structures.
|
|
27
57
|
// @ts-ignore - TS language server needs restart to pick up theme structure changes
|
|
28
58
|
export const screenStyles = StyleSheet.create((theme: Theme) => {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
},
|
|
56
|
-
// Content style for ScrollView - no flex: 1 so content can grow
|
|
57
|
-
screenContent: {
|
|
58
|
-
backgroundColor: theme.colors.surface.primary,
|
|
59
|
-
variants: {
|
|
60
|
-
background: generateBackgroundVariants(theme),
|
|
61
|
-
safeArea: {
|
|
62
|
-
true: {},
|
|
63
|
-
false: {},
|
|
59
|
+
// Apply extensions to main visual elements
|
|
60
|
+
const extended = applyExtensions('Screen', theme, {
|
|
61
|
+
screen: createScreenStyles(theme),
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
return {
|
|
65
|
+
...extended,
|
|
66
|
+
// Minor utility styles (not extended)
|
|
67
|
+
// Content style for ScrollView - no flex: 1 so content can grow
|
|
68
|
+
screenContent: {
|
|
69
|
+
backgroundColor: theme.colors.surface.primary,
|
|
70
|
+
variants: {
|
|
71
|
+
background: generateBackgroundVariants(theme),
|
|
72
|
+
safeArea: {
|
|
73
|
+
true: {},
|
|
74
|
+
false: {},
|
|
75
|
+
},
|
|
76
|
+
// Spacing variants from ContainerStyleProps
|
|
77
|
+
gap: buildGapVariants(theme),
|
|
78
|
+
padding: buildPaddingVariants(theme),
|
|
79
|
+
paddingVertical: buildPaddingVerticalVariants(theme),
|
|
80
|
+
paddingHorizontal: buildPaddingHorizontalVariants(theme),
|
|
81
|
+
margin: buildMarginVariants(theme),
|
|
82
|
+
marginVertical: buildMarginVerticalVariants(theme),
|
|
83
|
+
marginHorizontal: buildMarginHorizontalVariants(theme),
|
|
84
|
+
},
|
|
64
85
|
},
|
|
65
|
-
|
|
66
|
-
gap: buildGapVariants(theme),
|
|
67
|
-
padding: buildPaddingVariants(theme),
|
|
68
|
-
paddingVertical: buildPaddingVerticalVariants(theme),
|
|
69
|
-
paddingHorizontal: buildPaddingHorizontalVariants(theme),
|
|
70
|
-
margin: buildMarginVariants(theme),
|
|
71
|
-
marginVertical: buildMarginVerticalVariants(theme),
|
|
72
|
-
marginHorizontal: buildMarginHorizontalVariants(theme),
|
|
73
|
-
},
|
|
74
|
-
},
|
|
75
|
-
};
|
|
86
|
+
};
|
|
76
87
|
});
|
|
@@ -33,7 +33,7 @@ const Screen = forwardRef<HTMLDivElement, ScreenProps>(({
|
|
|
33
33
|
});
|
|
34
34
|
|
|
35
35
|
// Use getWebProps to generate className and ref for web
|
|
36
|
-
const webProps = getWebProps([screenStyles.screen, style as any]);
|
|
36
|
+
const webProps = getWebProps([(screenStyles.screen as any)({}), style as any]);
|
|
37
37
|
|
|
38
38
|
const mergedRef = useMergeRefs(ref, webProps.ref);
|
|
39
39
|
|
|
@@ -233,7 +233,7 @@ const Select = forwardRef<View, SelectProps>(({
|
|
|
233
233
|
>
|
|
234
234
|
<Animated.View
|
|
235
235
|
style={[
|
|
236
|
-
selectStyles.dropdown,
|
|
236
|
+
(selectStyles.dropdown as any)({}),
|
|
237
237
|
{
|
|
238
238
|
position: 'relative', // Override absolute positioning from styles
|
|
239
239
|
top: 0, // Override top: '100%' from styles
|
|
@@ -264,7 +264,7 @@ const Select = forwardRef<View, SelectProps>(({
|
|
|
264
264
|
{filteredOptions.map((option) => (
|
|
265
265
|
<Pressable
|
|
266
266
|
key={option.value}
|
|
267
|
-
style={selectStyles.option}
|
|
267
|
+
style={(selectStyles.option as any)({})}
|
|
268
268
|
onPress={() => handleOptionSelect(option)}
|
|
269
269
|
disabled={option.disabled}
|
|
270
270
|
android_ripple={{ color: 'rgba(0, 0, 0, 0.1)' }}
|
|
@@ -284,7 +284,7 @@ const Select = forwardRef<View, SelectProps>(({
|
|
|
284
284
|
))}
|
|
285
285
|
|
|
286
286
|
{filteredOptions.length === 0 && (
|
|
287
|
-
<View style={selectStyles.option}>
|
|
287
|
+
<View style={(selectStyles.option as any)({})}>
|
|
288
288
|
<Text style={selectStyles.optionText}>
|
|
289
289
|
No options found
|
|
290
290
|
</Text>
|
|
@@ -298,8 +298,14 @@ const Select = forwardRef<View, SelectProps>(({
|
|
|
298
298
|
);
|
|
299
299
|
};
|
|
300
300
|
|
|
301
|
+
// Get dynamic styles
|
|
302
|
+
const containerStyle = (selectStyles.container as any)({});
|
|
303
|
+
const triggerStyle = (selectStyles.trigger as any)({ type, intent });
|
|
304
|
+
const dropdownStyle = (selectStyles.dropdown as any)({});
|
|
305
|
+
const optionStyle = (selectStyles.option as any)({});
|
|
306
|
+
|
|
301
307
|
return (
|
|
302
|
-
<View ref={ref} nativeID={id} style={[
|
|
308
|
+
<View ref={ref} nativeID={id} style={[containerStyle, style]} testID={testID}>
|
|
303
309
|
{label && (
|
|
304
310
|
<Text style={selectStyles.label}>
|
|
305
311
|
{label}
|
|
@@ -308,7 +314,7 @@ const Select = forwardRef<View, SelectProps>(({
|
|
|
308
314
|
|
|
309
315
|
<Pressable
|
|
310
316
|
ref={mergedTriggerRef}
|
|
311
|
-
style={
|
|
317
|
+
style={triggerStyle}
|
|
312
318
|
onPress={handleTriggerPress}
|
|
313
319
|
disabled={disabled}
|
|
314
320
|
accessibilityLabel={accessibilityLabel || label}
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
buildMarginHorizontalVariants,
|
|
8
8
|
} from '../utils/buildViewStyleVariants';
|
|
9
9
|
import { SelectIntentVariant } from './types';
|
|
10
|
+
import { applyExtensions } from '../extensions/applyExtension';
|
|
10
11
|
|
|
11
12
|
// Type definitions
|
|
12
13
|
type SelectSize = Size;
|
|
@@ -137,26 +138,87 @@ function buildDynamicTriggerStyles(theme: Theme) {
|
|
|
137
138
|
}
|
|
138
139
|
}
|
|
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
|
+
|
|
140
201
|
// Styles are inlined here instead of in @idealyst/theme because Unistyles' Babel
|
|
141
202
|
// transform on native cannot resolve function calls to extract variant structures.
|
|
142
203
|
export const selectStyles = StyleSheet.create((theme: Theme) => {
|
|
204
|
+
// Apply extensions to main visual elements
|
|
205
|
+
const extendedStyles = applyExtensions('Select', theme, {
|
|
206
|
+
container: createContainerStyles(theme),
|
|
207
|
+
trigger: buildDynamicTriggerStyles(theme),
|
|
208
|
+
dropdown: createDropdownStyles(theme),
|
|
209
|
+
option: createOptionStyles(theme),
|
|
210
|
+
});
|
|
211
|
+
|
|
143
212
|
return {
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
// Spacing variants from FormInputStyleProps
|
|
148
|
-
margin: buildMarginVariants(theme),
|
|
149
|
-
marginVertical: buildMarginVerticalVariants(theme),
|
|
150
|
-
marginHorizontal: buildMarginHorizontalVariants(theme),
|
|
151
|
-
},
|
|
152
|
-
},
|
|
213
|
+
// Extended main elements
|
|
214
|
+
...extendedStyles,
|
|
215
|
+
// Minor utility styles (not extended)
|
|
153
216
|
label: {
|
|
154
217
|
fontSize: 14,
|
|
155
218
|
fontWeight: '500',
|
|
156
219
|
color: theme.colors.text.primary,
|
|
157
220
|
marginBottom: 4,
|
|
158
221
|
},
|
|
159
|
-
trigger: buildDynamicTriggerStyles(theme),
|
|
160
222
|
triggerContent: {
|
|
161
223
|
flex: 1,
|
|
162
224
|
flexDirection: 'row',
|
|
@@ -204,31 +266,6 @@ export const selectStyles = StyleSheet.create((theme: Theme) => {
|
|
|
204
266
|
transform: 'rotate(180deg)',
|
|
205
267
|
}
|
|
206
268
|
},
|
|
207
|
-
dropdown: {
|
|
208
|
-
position: 'absolute',
|
|
209
|
-
top: '100%',
|
|
210
|
-
left: 0,
|
|
211
|
-
right: 0,
|
|
212
|
-
backgroundColor: theme.colors.surface.primary,
|
|
213
|
-
borderRadius: 8,
|
|
214
|
-
borderWidth: 1,
|
|
215
|
-
borderStyle: 'solid',
|
|
216
|
-
borderColor: theme.colors.border.primary,
|
|
217
|
-
shadowColor: '#000',
|
|
218
|
-
shadowOffset: { width: 0, height: 8 },
|
|
219
|
-
shadowOpacity: 0.1,
|
|
220
|
-
shadowRadius: 24,
|
|
221
|
-
elevation: 8,
|
|
222
|
-
zIndex: 9999,
|
|
223
|
-
maxHeight: 240,
|
|
224
|
-
minWidth: 200,
|
|
225
|
-
overflow: 'hidden',
|
|
226
|
-
_web: {
|
|
227
|
-
border: `1px solid ${theme.colors.border.primary}`,
|
|
228
|
-
boxShadow: '0 8px 24px rgba(0, 0, 0, 0.1), 0 4px 8px rgba(0, 0, 0, 0.06)',
|
|
229
|
-
overflowY: 'auto',
|
|
230
|
-
},
|
|
231
|
-
},
|
|
232
269
|
searchContainer: {
|
|
233
270
|
padding: 8,
|
|
234
271
|
borderBottomWidth: 1,
|
|
@@ -261,23 +298,6 @@ export const selectStyles = StyleSheet.create((theme: Theme) => {
|
|
|
261
298
|
optionsList: {
|
|
262
299
|
paddingVertical: 4,
|
|
263
300
|
},
|
|
264
|
-
option: {
|
|
265
|
-
paddingHorizontal: 8,
|
|
266
|
-
paddingVertical: 4,
|
|
267
|
-
flexDirection: 'row',
|
|
268
|
-
alignItems: 'center',
|
|
269
|
-
minHeight: 36,
|
|
270
|
-
_web: {
|
|
271
|
-
display: 'flex',
|
|
272
|
-
cursor: 'pointer',
|
|
273
|
-
_hover: {
|
|
274
|
-
backgroundColor: theme.colors.surface.secondary,
|
|
275
|
-
},
|
|
276
|
-
_active: {
|
|
277
|
-
opacity: 0.8,
|
|
278
|
-
},
|
|
279
|
-
},
|
|
280
|
-
},
|
|
281
301
|
optionFocused: {
|
|
282
302
|
backgroundColor: theme.interaction.focusedBackground,
|
|
283
303
|
_web: {
|
|
@@ -176,12 +176,12 @@ const Select = forwardRef<HTMLDivElement, SelectProps>(({
|
|
|
176
176
|
};
|
|
177
177
|
|
|
178
178
|
const containerWebProps = getWebProps([
|
|
179
|
-
selectStyles.container,
|
|
179
|
+
(selectStyles.container as any)({}),
|
|
180
180
|
style as any
|
|
181
181
|
]);
|
|
182
182
|
|
|
183
183
|
const triggerWebProps = getWebProps([
|
|
184
|
-
selectStyles.trigger({ type, intent }),
|
|
184
|
+
(selectStyles.trigger as any)({ type, intent }),
|
|
185
185
|
]);
|
|
186
186
|
|
|
187
187
|
const handleClose = () => {
|
|
@@ -247,7 +247,7 @@ const Select = forwardRef<HTMLDivElement, SelectProps>(({
|
|
|
247
247
|
zIndex={1000}
|
|
248
248
|
>
|
|
249
249
|
<div
|
|
250
|
-
{...getWebProps([selectStyles.dropdown])}
|
|
250
|
+
{...getWebProps([(selectStyles.dropdown as any)({})])}
|
|
251
251
|
style={{
|
|
252
252
|
maxHeight: maxHeight,
|
|
253
253
|
position: 'relative',
|
|
@@ -282,7 +282,7 @@ const Select = forwardRef<HTMLDivElement, SelectProps>(({
|
|
|
282
282
|
aria-selected={option.value === value}
|
|
283
283
|
onMouseEnter={() => setFocusedIndex(index)}
|
|
284
284
|
{...getWebProps([
|
|
285
|
-
selectStyles.option,
|
|
285
|
+
(selectStyles.option as any)({}),
|
|
286
286
|
isFocused && selectStyles.optionFocused,
|
|
287
287
|
option.disabled && selectStyles.optionDisabled,
|
|
288
288
|
])}
|
|
@@ -305,7 +305,7 @@ const Select = forwardRef<HTMLDivElement, SelectProps>(({
|
|
|
305
305
|
})}
|
|
306
306
|
|
|
307
307
|
{filteredOptions.length === 0 && (
|
|
308
|
-
<div {...getWebProps([selectStyles.option])} style={{ cursor: 'default' }}>
|
|
308
|
+
<div {...getWebProps([(selectStyles.option as any)({})])} style={{ cursor: 'default' }}>
|
|
309
309
|
<span {...getWebProps([selectStyles.optionText])}>
|
|
310
310
|
No options found
|
|
311
311
|
</span>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { StyleSheet } from 'react-native-unistyles';
|
|
2
|
-
import { Theme, StylesheetStyles} from '@idealyst/theme';
|
|
2
|
+
import { Theme, StylesheetStyles } from '@idealyst/theme';
|
|
3
|
+
import { applyExtensions } from '../extensions/applyExtension';
|
|
3
4
|
|
|
4
5
|
type SkeletonShape = 'rectangle' | 'rounded' | 'circle';
|
|
5
6
|
type SkeletonAnimation = 'pulse' | 'wave' | 'none';
|
|
@@ -34,14 +35,11 @@ function createShapeVariants(theme: Theme) {
|
|
|
34
35
|
} as const;
|
|
35
36
|
}
|
|
36
37
|
|
|
37
|
-
//
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
export const skeletonStyles = StyleSheet.create((theme: Theme) => {
|
|
41
|
-
return {
|
|
42
|
-
skeleton: {
|
|
38
|
+
// Style creators for extension support
|
|
39
|
+
function createSkeletonStyles(theme: Theme) {
|
|
40
|
+
return () => ({
|
|
43
41
|
backgroundColor: theme.colors.surface.tertiary,
|
|
44
|
-
overflow: 'hidden',
|
|
42
|
+
overflow: 'hidden' as const,
|
|
45
43
|
variants: {
|
|
46
44
|
shape: createShapeVariants(theme),
|
|
47
45
|
animation: {
|
|
@@ -50,10 +48,24 @@ export const skeletonStyles = StyleSheet.create((theme: Theme) => {
|
|
|
50
48
|
none: {},
|
|
51
49
|
},
|
|
52
50
|
},
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Styles are inlined here instead of in @idealyst/theme because Unistyles' Babel
|
|
55
|
+
// transform on native cannot resolve function calls to extract variant structures.
|
|
56
|
+
// @ts-ignore - TS language server needs restart to pick up theme structure changes
|
|
57
|
+
export const skeletonStyles = StyleSheet.create((theme: Theme) => {
|
|
58
|
+
// Apply extensions to main visual elements
|
|
59
|
+
const extended = applyExtensions('Skeleton', theme, {
|
|
60
|
+
skeleton: createSkeletonStyles(theme),
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
return {
|
|
64
|
+
...extended,
|
|
65
|
+
// Minor utility styles (not extended)
|
|
66
|
+
group: {
|
|
67
|
+
display: 'flex',
|
|
68
|
+
flexDirection: 'column',
|
|
69
|
+
},
|
|
70
|
+
};
|
|
59
71
|
});
|
|
@@ -193,7 +193,7 @@ const Slider = forwardRef<View, SliderProps>(({
|
|
|
193
193
|
if (!icon) return null;
|
|
194
194
|
|
|
195
195
|
if (typeof icon === 'string' && isIconName(icon)) {
|
|
196
|
-
const iconStyle = sliderStyles.thumbIcon({ intent });
|
|
196
|
+
const iconStyle = (sliderStyles.thumbIcon as any)({ intent });
|
|
197
197
|
return (
|
|
198
198
|
<MaterialCommunityIcons
|
|
199
199
|
name={icon}
|
|
@@ -206,8 +206,12 @@ const Slider = forwardRef<View, SliderProps>(({
|
|
|
206
206
|
return icon;
|
|
207
207
|
};
|
|
208
208
|
|
|
209
|
+
// Get dynamic styles
|
|
210
|
+
const containerStyle = (sliderStyles.container as any)({});
|
|
211
|
+
const trackStyle = (sliderStyles.track as any)({});
|
|
212
|
+
|
|
209
213
|
return (
|
|
210
|
-
<View ref={ref} nativeID={id} style={[
|
|
214
|
+
<View ref={ref} nativeID={id} style={[containerStyle, style]} testID={testID} {...nativeA11yProps}>
|
|
211
215
|
{showValue && (
|
|
212
216
|
<View style={sliderStyles.valueLabel as any}>
|
|
213
217
|
<Text>{value}</Text>
|
|
@@ -217,7 +221,7 @@ const Slider = forwardRef<View, SliderProps>(({
|
|
|
217
221
|
<View style={sliderStyles.sliderWrapper}>
|
|
218
222
|
<GestureDetector gesture={composedGesture}>
|
|
219
223
|
<View
|
|
220
|
-
style={
|
|
224
|
+
style={trackStyle}
|
|
221
225
|
onLayout={(e) => {
|
|
222
226
|
const width = e.nativeEvent.layout.width;
|
|
223
227
|
trackWidth.value = width;
|
|
@@ -226,7 +230,7 @@ const Slider = forwardRef<View, SliderProps>(({
|
|
|
226
230
|
>
|
|
227
231
|
{/* Filled track */}
|
|
228
232
|
<Animated.View
|
|
229
|
-
style={[sliderStyles.filledTrack({ intent }), filledTrackAnimatedStyle]}
|
|
233
|
+
style={[(sliderStyles.filledTrack as any)({ intent }), filledTrackAnimatedStyle]}
|
|
230
234
|
/>
|
|
231
235
|
|
|
232
236
|
{/* Marks */}
|
|
@@ -262,7 +266,7 @@ const Slider = forwardRef<View, SliderProps>(({
|
|
|
262
266
|
{/* Thumb */}
|
|
263
267
|
<Animated.View
|
|
264
268
|
style={[
|
|
265
|
-
sliderStyles.thumb({ intent, disabled }),
|
|
269
|
+
(sliderStyles.thumb as any)({ intent, disabled }),
|
|
266
270
|
{
|
|
267
271
|
// Manual positioning/sizing for native layout
|
|
268
272
|
position: 'absolute',
|