@idealyst/components 1.1.6 → 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 +8 -3
- package/src/Accordion/Accordion.native.tsx +22 -14
- package/src/Accordion/Accordion.styles.old.tsx +298 -0
- package/src/Accordion/Accordion.styles.tsx +139 -248
- package/src/Accordion/Accordion.web.tsx +12 -7
- package/src/ActivityIndicator/ActivityIndicator.native.tsx +3 -2
- package/src/ActivityIndicator/ActivityIndicator.styles.old.tsx +94 -0
- package/src/ActivityIndicator/ActivityIndicator.styles.tsx +43 -62
- package/src/ActivityIndicator/ActivityIndicator.web.tsx +2 -2
- package/src/Alert/Alert.native.tsx +26 -15
- package/src/Alert/Alert.styles.old.tsx +209 -0
- package/src/Alert/Alert.styles.tsx +108 -281
- package/src/Alert/Alert.web.tsx +6 -10
- package/src/Avatar/Avatar.native.tsx +5 -2
- package/src/Avatar/Avatar.styles.old.tsx +99 -0
- package/src/Avatar/Avatar.styles.tsx +47 -62
- package/src/Avatar/Avatar.web.tsx +2 -2
- package/src/Badge/Badge.native.tsx +2 -2
- package/src/Badge/Badge.styles.old.tsx +157 -0
- package/src/Badge/Badge.styles.tsx +69 -108
- package/src/Badge/Badge.web.tsx +6 -6
- package/src/Breadcrumb/Breadcrumb.native.tsx +12 -5
- package/src/Breadcrumb/Breadcrumb.styles.old.tsx +231 -0
- package/src/Breadcrumb/Breadcrumb.styles.tsx +93 -209
- package/src/Breadcrumb/Breadcrumb.web.tsx +39 -27
- package/src/Button/Button.native.tsx +39 -14
- package/src/Button/Button.styles.tsx +99 -253
- package/src/Button/Button.web.tsx +10 -8
- package/src/Card/Card.native.tsx +8 -4
- package/src/Card/Card.styles.old.tsx +160 -0
- package/src/Card/Card.styles.tsx +107 -142
- package/src/Card/Card.web.tsx +6 -4
- package/src/Checkbox/Checkbox.native.tsx +14 -6
- package/src/Checkbox/Checkbox.styles.old.tsx +271 -0
- package/src/Checkbox/Checkbox.styles.tsx +109 -197
- package/src/Checkbox/Checkbox.web.tsx +7 -7
- package/src/Chip/Chip.native.tsx +5 -5
- package/src/Chip/Chip.styles.old.tsx +184 -0
- package/src/Chip/Chip.styles.tsx +34 -22
- package/src/Chip/Chip.web.tsx +5 -5
- package/src/Dialog/Dialog.native.tsx +16 -7
- package/src/Dialog/Dialog.styles.old.tsx +202 -0
- package/src/Dialog/Dialog.styles.tsx +108 -132
- package/src/Dialog/Dialog.web.tsx +4 -4
- package/src/Divider/Divider.native.tsx +29 -42
- package/src/Divider/Divider.styles.old.tsx +172 -0
- package/src/Divider/Divider.styles.tsx +116 -242
- package/src/Divider/Divider.web.tsx +17 -14
- package/src/Icon/Icon.native.tsx +12 -4
- package/src/Icon/Icon.styles.old.tsx +81 -0
- package/src/Icon/Icon.styles.tsx +52 -60
- 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 +45 -43
- package/src/Input/Input.native.tsx +140 -56
- package/src/Input/Input.styles.old.tsx +289 -0
- package/src/Input/Input.styles.tsx +177 -228
- package/src/Input/Input.web.tsx +5 -8
- package/src/Link/Link.native.tsx +4 -1
- package/src/List/List.native.tsx +5 -2
- package/src/List/List.styles.old.tsx +242 -0
- package/src/List/List.styles.tsx +178 -240
- package/src/List/ListItem.native.tsx +16 -8
- package/src/List/ListItem.web.tsx +26 -15
- package/src/Menu/Menu.native.tsx +1 -1
- package/src/Menu/Menu.styles.old.tsx +197 -0
- package/src/Menu/Menu.styles.tsx +90 -156
- package/src/Menu/Menu.web.tsx +2 -2
- package/src/Menu/MenuItem.native.tsx +9 -5
- package/src/Menu/MenuItem.styles.old.tsx +114 -0
- package/src/Menu/MenuItem.styles.tsx +71 -104
- package/src/Menu/MenuItem.web.tsx +23 -5
- package/src/Popover/Popover.native.tsx +10 -4
- package/src/Popover/Popover.styles.old.tsx +135 -0
- package/src/Popover/Popover.styles.tsx +46 -96
- package/src/Popover/Popover.web.tsx +1 -1
- package/src/Pressable/Pressable.native.tsx +3 -1
- package/src/Pressable/Pressable.styles.old.tsx +27 -0
- package/src/Pressable/Pressable.styles.tsx +35 -20
- package/src/Pressable/Pressable.web.tsx +1 -1
- package/src/Progress/Progress.native.tsx +15 -6
- package/src/Progress/Progress.styles.old.tsx +200 -0
- package/src/Progress/Progress.styles.tsx +69 -118
- package/src/Progress/Progress.web.tsx +10 -9
- package/src/RadioButton/RadioButton.native.tsx +10 -4
- package/src/RadioButton/RadioButton.styles.old.tsx +175 -0
- package/src/RadioButton/RadioButton.styles.tsx +81 -145
- package/src/RadioButton/RadioButton.web.tsx +4 -4
- package/src/SVGImage/SVGImage.styles.old.tsx +86 -0
- package/src/SVGImage/SVGImage.styles.tsx +35 -66
- package/src/Screen/Screen.native.tsx +30 -27
- package/src/Screen/Screen.styles.old.tsx +87 -0
- package/src/Screen/Screen.styles.tsx +120 -71
- package/src/Screen/Screen.web.tsx +2 -2
- package/src/Select/Select.native.tsx +44 -29
- package/src/Select/Select.styles.old.tsx +353 -0
- package/src/Select/Select.styles.tsx +244 -293
- package/src/Select/Select.web.tsx +5 -5
- package/src/Skeleton/Skeleton.styles.old.tsx +67 -0
- package/src/Skeleton/Skeleton.styles.tsx +31 -43
- package/src/Slider/Slider.native.tsx +9 -5
- package/src/Slider/Slider.styles.old.tsx +259 -0
- package/src/Slider/Slider.styles.tsx +157 -227
- package/src/Slider/Slider.web.tsx +5 -5
- package/src/Switch/Switch.native.tsx +11 -5
- package/src/Switch/Switch.styles.old.tsx +203 -0
- package/src/Switch/Switch.styles.tsx +103 -149
- package/src/Switch/Switch.web.tsx +8 -8
- package/src/TabBar/TabBar.native.tsx +24 -31
- package/src/TabBar/TabBar.styles.old.tsx +343 -0
- package/src/TabBar/TabBar.styles.tsx +204 -494
- package/src/TabBar/TabBar.web.tsx +21 -33
- package/src/Table/Table.native.tsx +18 -9
- package/src/Table/Table.styles.old.tsx +311 -0
- package/src/Table/Table.styles.tsx +151 -278
- package/src/Table/Table.web.tsx +1 -1
- package/src/Text/Text.native.tsx +1 -4
- 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 -78
- 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 +101 -157
- package/src/Tooltip/Tooltip.native.tsx +2 -2
- package/src/Tooltip/Tooltip.styles.old.tsx +82 -0
- package/src/Tooltip/Tooltip.styles.tsx +38 -53
- package/src/Tooltip/Tooltip.web.tsx +2 -2
- package/src/Video/Video.styles.old.tsx +51 -0
- package/src/Video/Video.styles.tsx +32 -28
- package/src/View/View.native.tsx +12 -12
- package/src/View/View.styles.old.tsx +125 -0
- package/src/View/View.styles.tsx +84 -103
- package/src/View/View.web.tsx +14 -2
- package/src/examples/CardExamples.tsx +0 -6
- package/src/extensions/applyExtension.ts +210 -0
- package/src/extensions/extendComponent.ts +438 -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
|
@@ -1,180 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Switch styles using defineStyle with dynamic props.
|
|
3
|
+
*/
|
|
1
4
|
import { StyleSheet } from 'react-native-unistyles';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
buildMarginVariants,
|
|
6
|
-
buildMarginVerticalVariants,
|
|
7
|
-
buildMarginHorizontalVariants,
|
|
8
|
-
} from '../utils/buildViewStyleVariants';
|
|
9
|
-
import { SwitchIntentVariant, SwitchSizeVariant } from './types';
|
|
5
|
+
import { defineStyle, ThemeStyleWrapper } from '@idealyst/theme';
|
|
6
|
+
import type { Theme as BaseTheme, Intent, Size } from '@idealyst/theme';
|
|
7
|
+
import { ViewStyleSize } from '../utils/viewStyleProps';
|
|
10
8
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
width: size.trackWidth,
|
|
14
|
-
height: size.trackHeight,
|
|
15
|
-
}));
|
|
16
|
-
}
|
|
9
|
+
// Required: Unistyles must see StyleSheet usage in original source to process this file
|
|
10
|
+
void StyleSheet;
|
|
17
11
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
return theme.intents[intent].primary;
|
|
21
|
-
}
|
|
22
|
-
return theme.colors.border.secondary;
|
|
23
|
-
}
|
|
12
|
+
// Wrap theme for $iterator support
|
|
13
|
+
type Theme = ThemeStyleWrapper<BaseTheme>;
|
|
24
14
|
|
|
25
|
-
|
|
26
|
-
return buildSizeVariants(theme, 'switch', (size) => ({
|
|
27
|
-
width: size.thumbSize,
|
|
28
|
-
height: size.thumbSize,
|
|
29
|
-
left: 2,
|
|
30
|
-
}));
|
|
31
|
-
}
|
|
15
|
+
type LabelPosition = 'left' | 'right';
|
|
32
16
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
17
|
+
export type SwitchDynamicProps = {
|
|
18
|
+
size?: Size;
|
|
19
|
+
intent?: Intent;
|
|
20
|
+
checked?: boolean;
|
|
21
|
+
disabled?: boolean;
|
|
22
|
+
labelPosition?: LabelPosition;
|
|
23
|
+
margin?: ViewStyleSize;
|
|
24
|
+
marginVertical?: ViewStyleSize;
|
|
25
|
+
marginHorizontal?: ViewStyleSize;
|
|
26
|
+
};
|
|
38
27
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
28
|
+
/**
|
|
29
|
+
* Switch styles with intent/checked/disabled handling.
|
|
30
|
+
*/
|
|
31
|
+
export const switchStyles = defineStyle('Switch', (theme: Theme) => ({
|
|
32
|
+
container: (_props: SwitchDynamicProps) => ({
|
|
33
|
+
flexDirection: 'row' as const,
|
|
34
|
+
alignItems: 'center' as const,
|
|
35
|
+
gap: 8,
|
|
36
|
+
variants: {
|
|
37
|
+
margin: {
|
|
38
|
+
margin: theme.sizes.$view.padding,
|
|
39
|
+
},
|
|
40
|
+
marginVertical: {
|
|
41
|
+
marginVertical: theme.sizes.$view.padding,
|
|
42
|
+
},
|
|
43
|
+
marginHorizontal: {
|
|
44
|
+
marginHorizontal: theme.sizes.$view.padding,
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
}),
|
|
45
48
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
49
|
+
switchContainer: (_props: SwitchDynamicProps) => ({
|
|
50
|
+
justifyContent: 'center' as const,
|
|
51
|
+
_web: {
|
|
52
|
+
border: 'none',
|
|
53
|
+
padding: 0,
|
|
54
|
+
backgroundColor: 'transparent',
|
|
55
|
+
width: 'fit-content',
|
|
56
|
+
},
|
|
57
|
+
}),
|
|
52
58
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
_web: {
|
|
65
|
-
cursor: 'not-allowed',
|
|
66
|
-
},
|
|
67
|
-
},
|
|
68
|
-
false: {
|
|
69
|
-
opacity: 1,
|
|
70
|
-
_web: {
|
|
71
|
-
cursor: 'pointer',
|
|
72
|
-
_hover: {
|
|
73
|
-
opacity: 0.9,
|
|
74
|
-
},
|
|
75
|
-
_active: {
|
|
76
|
-
opacity: 0.8,
|
|
77
|
-
},
|
|
78
|
-
},
|
|
79
|
-
},
|
|
80
|
-
},
|
|
81
|
-
} as const,
|
|
82
|
-
_web: {
|
|
83
|
-
transition: 'background-color 0.2s ease',
|
|
59
|
+
switchTrack: ({ intent = 'primary', checked = false, disabled = false }: SwitchDynamicProps) => ({
|
|
60
|
+
borderRadius: 9999,
|
|
61
|
+
position: 'relative' as const,
|
|
62
|
+
backgroundColor: checked
|
|
63
|
+
? theme.intents[intent].primary
|
|
64
|
+
: theme.colors.border.secondary,
|
|
65
|
+
opacity: disabled ? 0.5 : 1,
|
|
66
|
+
variants: {
|
|
67
|
+
size: {
|
|
68
|
+
width: theme.sizes.$switch.trackWidth,
|
|
69
|
+
height: theme.sizes.$switch.trackHeight,
|
|
84
70
|
},
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
|
|
71
|
+
},
|
|
72
|
+
_web: {
|
|
73
|
+
transition: 'background-color 0.2s ease',
|
|
74
|
+
cursor: disabled ? 'not-allowed' : 'pointer',
|
|
75
|
+
_hover: disabled ? {} : { opacity: 0.9 },
|
|
76
|
+
_active: disabled ? {} : { opacity: 0.8 },
|
|
77
|
+
},
|
|
78
|
+
}),
|
|
79
|
+
|
|
80
|
+
switchThumb: ({ size = 'md', checked = false }: SwitchDynamicProps) => {
|
|
81
|
+
const sizeValue = theme.sizes.switch[size];
|
|
82
|
+
const translateX = checked ? sizeValue.translateX : 0;
|
|
88
83
|
|
|
89
|
-
function createSwitchThumbStyles(theme: Theme) {
|
|
90
|
-
return ({ size, checked }: { size: SwitchSizeVariant, checked: boolean }) => {
|
|
91
84
|
return {
|
|
92
|
-
position: 'absolute',
|
|
85
|
+
position: 'absolute' as const,
|
|
93
86
|
backgroundColor: theme.colors.surface.primary,
|
|
94
87
|
borderRadius: 9999,
|
|
95
88
|
top: '50%',
|
|
96
|
-
display: 'flex',
|
|
97
|
-
alignItems: 'center',
|
|
98
|
-
justifyContent: 'center',
|
|
89
|
+
display: 'flex' as const,
|
|
90
|
+
alignItems: 'center' as const,
|
|
91
|
+
justifyContent: 'center' as const,
|
|
99
92
|
shadowColor: '#000',
|
|
100
93
|
shadowOffset: { width: 0, height: 1 },
|
|
101
94
|
shadowOpacity: 0.2,
|
|
102
95
|
shadowRadius: 3,
|
|
103
96
|
elevation: 2,
|
|
104
97
|
variants: {
|
|
105
|
-
size:
|
|
98
|
+
size: {
|
|
99
|
+
width: theme.sizes.$switch.thumbSize,
|
|
100
|
+
height: theme.sizes.$switch.thumbSize,
|
|
101
|
+
left: 2,
|
|
102
|
+
},
|
|
106
103
|
},
|
|
107
104
|
_web: {
|
|
108
105
|
boxShadow: '0 1px 3px rgba(0, 0, 0, 0.2)',
|
|
109
106
|
transition: 'transform 0.2s ease',
|
|
110
|
-
transform:
|
|
107
|
+
transform: `translateY(-50%) translateX(${translateX}px)`,
|
|
111
108
|
},
|
|
112
109
|
} as const;
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
function createThumbIconStyles(theme: Theme) {
|
|
117
|
-
return ({ checked, intent }: { checked: boolean, intent: SwitchIntentVariant }) => {
|
|
118
|
-
return {
|
|
119
|
-
display: 'flex',
|
|
120
|
-
alignItems: 'center',
|
|
121
|
-
justifyContent: 'center',
|
|
122
|
-
color: getThumbIconColor(theme, checked, intent),
|
|
123
|
-
variants: {
|
|
124
|
-
size: createThumbIconSizeVariants(theme),
|
|
125
|
-
},
|
|
126
|
-
} as const;
|
|
127
|
-
}
|
|
128
|
-
}
|
|
110
|
+
},
|
|
129
111
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
gap: 8,
|
|
112
|
+
thumbIcon: ({ intent = 'primary', checked = false }: SwitchDynamicProps) => ({
|
|
113
|
+
display: 'flex' as const,
|
|
114
|
+
alignItems: 'center' as const,
|
|
115
|
+
justifyContent: 'center' as const,
|
|
116
|
+
color: checked
|
|
117
|
+
? theme.intents[intent].primary
|
|
118
|
+
: theme.colors.border.secondary,
|
|
138
119
|
variants: {
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
120
|
+
size: {
|
|
121
|
+
width: theme.sizes.$switch.thumbIconSize,
|
|
122
|
+
height: theme.sizes.$switch.thumbIconSize,
|
|
123
|
+
},
|
|
143
124
|
},
|
|
144
|
-
},
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
_web: {
|
|
148
|
-
border: 'none',
|
|
149
|
-
padding: 0,
|
|
150
|
-
backgroundColor: 'transparent',
|
|
151
|
-
width: 'fit-content',
|
|
152
|
-
}
|
|
153
|
-
},
|
|
154
|
-
switchTrack: createSwitchTrackStyles(theme),
|
|
155
|
-
switchThumb: createSwitchThumbStyles(theme),
|
|
156
|
-
thumbIcon: createThumbIconStyles(theme),
|
|
157
|
-
label: {
|
|
125
|
+
}),
|
|
126
|
+
|
|
127
|
+
label: ({ disabled = false, labelPosition = 'right' }: SwitchDynamicProps) => ({
|
|
158
128
|
fontSize: 14,
|
|
159
129
|
color: theme.colors.text.primary,
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
false: {
|
|
166
|
-
opacity: 1,
|
|
167
|
-
},
|
|
168
|
-
},
|
|
169
|
-
position: {
|
|
170
|
-
left: {
|
|
171
|
-
marginRight: 8,
|
|
172
|
-
},
|
|
173
|
-
right: {
|
|
174
|
-
marginLeft: 8,
|
|
175
|
-
},
|
|
176
|
-
},
|
|
177
|
-
} as const,
|
|
178
|
-
} as const,
|
|
179
|
-
};
|
|
180
|
-
});
|
|
130
|
+
opacity: disabled ? 0.5 : 1,
|
|
131
|
+
marginRight: labelPosition === 'left' ? 8 : 0,
|
|
132
|
+
marginLeft: labelPosition === 'right' ? 8 : 0,
|
|
133
|
+
}),
|
|
134
|
+
}));
|
|
@@ -82,10 +82,10 @@ const Switch = forwardRef<HTMLDivElement | HTMLButtonElement, SwitchProps>(({
|
|
|
82
82
|
marginHorizontal,
|
|
83
83
|
});
|
|
84
84
|
|
|
85
|
-
const trackProps = getWebProps([switchStyles.switchTrack({ checked, intent })]);
|
|
86
|
-
const thumbProps = getWebProps([switchStyles.switchThumb({ size, checked })]);
|
|
87
|
-
const thumbIconProps = getWebProps([switchStyles.thumbIcon({ checked, intent })]);
|
|
88
|
-
const labelProps = getWebProps([switchStyles.label]);
|
|
85
|
+
const trackProps = getWebProps([(switchStyles.switchTrack as any)({ checked, intent, disabled })]);
|
|
86
|
+
const thumbProps = getWebProps([(switchStyles.switchThumb as any)({ size, checked })]);
|
|
87
|
+
const thumbIconProps = getWebProps([(switchStyles.thumbIcon as any)({ checked, intent })]);
|
|
88
|
+
const labelProps = getWebProps([(switchStyles.label as any)({ disabled, labelPosition })]);
|
|
89
89
|
|
|
90
90
|
// Helper to render icon
|
|
91
91
|
const renderIcon = () => {
|
|
@@ -109,13 +109,13 @@ const Switch = forwardRef<HTMLDivElement | HTMLButtonElement, SwitchProps>(({
|
|
|
109
109
|
};
|
|
110
110
|
|
|
111
111
|
// Computed button props with dynamic styles
|
|
112
|
-
const computedButtonProps = getWebProps(
|
|
113
|
-
switchStyles.switchContainer
|
|
114
|
-
);
|
|
112
|
+
const computedButtonProps = getWebProps([
|
|
113
|
+
(switchStyles.switchContainer as any)({})
|
|
114
|
+
]);
|
|
115
115
|
|
|
116
116
|
// Computed container props with dynamic styles (for when label exists)
|
|
117
117
|
const computedContainerProps = getWebProps([
|
|
118
|
-
switchStyles.container,
|
|
118
|
+
(switchStyles.container as any)({}),
|
|
119
119
|
style as any,
|
|
120
120
|
{
|
|
121
121
|
cursor: disabled ? 'not-allowed' : 'pointer',
|
|
@@ -88,11 +88,11 @@ const TabBar = forwardRef<View, TabBarProps>(({
|
|
|
88
88
|
const containerPadding = type === 'pills' ? 4 : 0;
|
|
89
89
|
|
|
90
90
|
indicatorPosition.value = withSpring(layout.x + containerPadding, {
|
|
91
|
-
damping:
|
|
91
|
+
damping: 100,
|
|
92
92
|
stiffness: 300,
|
|
93
93
|
});
|
|
94
94
|
indicatorWidth.value = withSpring(layout.width, {
|
|
95
|
-
damping:
|
|
95
|
+
damping: 100,
|
|
96
96
|
stiffness: 300,
|
|
97
97
|
});
|
|
98
98
|
}
|
|
@@ -128,11 +128,8 @@ const TabBar = forwardRef<View, TabBarProps>(({
|
|
|
128
128
|
};
|
|
129
129
|
});
|
|
130
130
|
|
|
131
|
-
// Apply container
|
|
131
|
+
// Apply container variants (for spacing only)
|
|
132
132
|
tabBarContainerStyles.useVariants({
|
|
133
|
-
type,
|
|
134
|
-
size,
|
|
135
|
-
pillMode,
|
|
136
133
|
justify,
|
|
137
134
|
gap,
|
|
138
135
|
padding,
|
|
@@ -142,46 +139,37 @@ const TabBar = forwardRef<View, TabBarProps>(({
|
|
|
142
139
|
marginVertical,
|
|
143
140
|
marginHorizontal,
|
|
144
141
|
});
|
|
145
|
-
|
|
142
|
+
|
|
143
|
+
// Compute dynamic container and indicator styles
|
|
144
|
+
const containerStyle = (tabBarContainerStyles.container as any)({ type, pillMode });
|
|
145
|
+
const indicatorStyle = (tabBarIndicatorStyles.indicator as any)({ type, pillMode });
|
|
146
146
|
|
|
147
147
|
return (
|
|
148
148
|
<ScrollView
|
|
149
149
|
horizontal
|
|
150
150
|
showsHorizontalScrollIndicator={false}
|
|
151
|
-
contentContainerStyle={{
|
|
151
|
+
contentContainerStyle={{
|
|
152
|
+
position: 'relative',
|
|
153
|
+
flexGrow: 1,
|
|
154
|
+
}}
|
|
155
|
+
style={{ width: '100%' }}
|
|
152
156
|
>
|
|
153
|
-
<View ref={ref} nativeID={id} style={[
|
|
157
|
+
<View ref={ref} nativeID={id} style={[containerStyle, style]} testID={testID} {...nativeA11yProps}>
|
|
154
158
|
{/* Animated indicator - render first so it's behind */}
|
|
155
159
|
<Animated.View
|
|
156
160
|
style={[
|
|
157
|
-
|
|
161
|
+
indicatorStyle,
|
|
158
162
|
indicatorAnimatedStyle,
|
|
159
163
|
]}
|
|
160
164
|
/>
|
|
161
165
|
|
|
162
166
|
{/* Tabs - render second so they're on top */}
|
|
163
|
-
<View style={{ flexDirection: 'row' }}>
|
|
167
|
+
<View style={{ flexDirection: 'row', flex: 1 }}>
|
|
164
168
|
{items.map((item) => {
|
|
165
169
|
const isActive = value === item.value;
|
|
166
170
|
const iconSize = ICON_SIZES[size] || 18;
|
|
167
171
|
|
|
168
|
-
// Apply
|
|
169
|
-
tabBarTabStyles.useVariants({
|
|
170
|
-
size,
|
|
171
|
-
type,
|
|
172
|
-
active: isActive,
|
|
173
|
-
disabled: Boolean(item.disabled),
|
|
174
|
-
pillMode,
|
|
175
|
-
iconPosition,
|
|
176
|
-
justify,
|
|
177
|
-
});
|
|
178
|
-
tabBarLabelStyles.useVariants({
|
|
179
|
-
size,
|
|
180
|
-
type,
|
|
181
|
-
pillMode,
|
|
182
|
-
active: isActive,
|
|
183
|
-
disabled: Boolean(item.disabled),
|
|
184
|
-
});
|
|
172
|
+
// Apply icon variants (size, disabled, iconPosition)
|
|
185
173
|
tabBarIconStyles.useVariants({
|
|
186
174
|
size,
|
|
187
175
|
active: isActive,
|
|
@@ -189,6 +177,11 @@ const TabBar = forwardRef<View, TabBarProps>(({
|
|
|
189
177
|
iconPosition,
|
|
190
178
|
});
|
|
191
179
|
|
|
180
|
+
// Compute dynamic styles for this tab - call as functions for theme reactivity
|
|
181
|
+
const tabStyle = (tabBarTabStyles.tab as any)({ type, size, active: isActive, pillMode, justify });
|
|
182
|
+
const labelStyle = (tabBarLabelStyles.tabLabel as any)({ type, active: isActive, pillMode });
|
|
183
|
+
const iconContainerStyle = (tabBarIconStyles.tabIcon as any)({});
|
|
184
|
+
|
|
192
185
|
const icon = renderIcon(item.icon, isActive, iconSize);
|
|
193
186
|
|
|
194
187
|
return (
|
|
@@ -198,7 +191,7 @@ const TabBar = forwardRef<View, TabBarProps>(({
|
|
|
198
191
|
const { x, width } = event.nativeEvent.layout;
|
|
199
192
|
handleTabLayout(item.value, x, width);
|
|
200
193
|
}}
|
|
201
|
-
style={
|
|
194
|
+
style={tabStyle}
|
|
202
195
|
onPress={() => handleTabClick(item.value, item.disabled)}
|
|
203
196
|
disabled={item.disabled}
|
|
204
197
|
activeOpacity={0.7}
|
|
@@ -207,8 +200,8 @@ const TabBar = forwardRef<View, TabBarProps>(({
|
|
|
207
200
|
accessibilityLabel={item.label}
|
|
208
201
|
accessibilityState={{ selected: isActive, disabled: item.disabled }}
|
|
209
202
|
>
|
|
210
|
-
{icon && <View style={
|
|
211
|
-
<Text style={
|
|
203
|
+
{icon && <View style={iconContainerStyle}>{icon}</View>}
|
|
204
|
+
<Text style={labelStyle}>{item.label}</Text>
|
|
212
205
|
</TouchableOpacity>
|
|
213
206
|
);
|
|
214
207
|
})}
|