rnnovaui 0.9.1 → 0.9.2
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 +1 -1
- package/src/components/Accordion/UIAccordionContent.js +145 -29
- package/src/components/Tabs/UITabs.js +105 -35
- package/src/components/Tabs/UITabsContent.js +116 -48
- package/src/components/Tabs/UITabsIndicator.js +2 -1
- package/src/components/Tabs/UITabsList.js +29 -10
- package/src/components/Tabs/UITabsTrigger.js +201 -101
- package/src/components/Tabs/index.js +12 -5
- package/src/components/index.js +0 -2
- package/src/index.js +0 -2
package/package.json
CHANGED
|
@@ -3,7 +3,6 @@ import React, { memo, useEffect, useRef, useState } from "react";
|
|
|
3
3
|
import { Animated, StyleSheet, View } from "react-native";
|
|
4
4
|
|
|
5
5
|
import { useUIAccordion } from "./UIAccordion";
|
|
6
|
-
|
|
7
6
|
import { useUIAccordionItem } from "./UIAccordionItem";
|
|
8
7
|
|
|
9
8
|
export const UIAccordionContent = memo(function UIAccordionContent({
|
|
@@ -14,88 +13,205 @@ export const UIAccordionContent = memo(function UIAccordionContent({
|
|
|
14
13
|
innerStyle,
|
|
15
14
|
|
|
16
15
|
testID,
|
|
16
|
+
|
|
17
|
+
onLayout,
|
|
17
18
|
}) {
|
|
18
19
|
const accordion = useUIAccordion();
|
|
19
20
|
|
|
20
21
|
const item = useUIAccordionItem();
|
|
21
22
|
|
|
22
|
-
const
|
|
23
|
+
const heightAnimation = useRef(new Animated.Value(item.open ? 1 : 0)).current;
|
|
24
|
+
|
|
25
|
+
const opacityAnimation = useRef(
|
|
26
|
+
new Animated.Value(item.open ? 1 : 0),
|
|
27
|
+
).current;
|
|
28
|
+
|
|
29
|
+
const [contentHeight, setContentHeight] = useState(0);
|
|
23
30
|
|
|
24
31
|
const [mounted, setMounted] = useState(item.open);
|
|
25
32
|
|
|
33
|
+
/*
|
|
34
|
+
* ------------------------------------------------
|
|
35
|
+
* MEASURE CONTENT
|
|
36
|
+
* ------------------------------------------------
|
|
37
|
+
*/
|
|
38
|
+
|
|
39
|
+
const handleLayout = (event) => {
|
|
40
|
+
const height = event.nativeEvent.layout.height;
|
|
41
|
+
|
|
42
|
+
if (height !== contentHeight) {
|
|
43
|
+
setContentHeight(height);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
onLayout?.(event);
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
/*
|
|
50
|
+
* ------------------------------------------------
|
|
51
|
+
* OPEN / CLOSE
|
|
52
|
+
* ------------------------------------------------
|
|
53
|
+
*/
|
|
54
|
+
|
|
26
55
|
useEffect(() => {
|
|
27
56
|
if (item.open) {
|
|
57
|
+
/*
|
|
58
|
+
* Mount before opening.
|
|
59
|
+
*/
|
|
28
60
|
setMounted(true);
|
|
29
61
|
|
|
30
62
|
if (!accordion.animated) {
|
|
31
|
-
|
|
63
|
+
heightAnimation.setValue(1);
|
|
64
|
+
|
|
65
|
+
opacityAnimation.setValue(1);
|
|
66
|
+
|
|
32
67
|
return;
|
|
33
68
|
}
|
|
34
69
|
|
|
35
|
-
|
|
36
|
-
|
|
70
|
+
/*
|
|
71
|
+
* Smooth opening.
|
|
72
|
+
*/
|
|
73
|
+
Animated.parallel([
|
|
74
|
+
Animated.timing(heightAnimation, {
|
|
75
|
+
toValue: 1,
|
|
37
76
|
|
|
38
|
-
|
|
77
|
+
duration: accordion.animationDuration,
|
|
39
78
|
|
|
40
|
-
|
|
41
|
-
|
|
79
|
+
useNativeDriver: false,
|
|
80
|
+
}),
|
|
81
|
+
|
|
82
|
+
Animated.timing(opacityAnimation, {
|
|
83
|
+
toValue: 1,
|
|
84
|
+
|
|
85
|
+
duration: Math.min(accordion.animationDuration, 180),
|
|
86
|
+
|
|
87
|
+
useNativeDriver: false,
|
|
88
|
+
}),
|
|
89
|
+
]).start();
|
|
42
90
|
|
|
43
91
|
return;
|
|
44
92
|
}
|
|
45
93
|
|
|
94
|
+
/*
|
|
95
|
+
* ------------------------------------------------
|
|
96
|
+
* CLOSE
|
|
97
|
+
* ------------------------------------------------
|
|
98
|
+
*/
|
|
99
|
+
|
|
46
100
|
if (!accordion.animated) {
|
|
47
|
-
|
|
101
|
+
heightAnimation.setValue(0);
|
|
102
|
+
|
|
103
|
+
opacityAnimation.setValue(0);
|
|
104
|
+
|
|
48
105
|
setMounted(false);
|
|
106
|
+
|
|
49
107
|
return;
|
|
50
108
|
}
|
|
51
109
|
|
|
52
|
-
|
|
53
|
-
|
|
110
|
+
/*
|
|
111
|
+
* Animate to zero first.
|
|
112
|
+
*/
|
|
113
|
+
Animated.parallel([
|
|
114
|
+
Animated.timing(heightAnimation, {
|
|
115
|
+
toValue: 0,
|
|
54
116
|
|
|
55
|
-
|
|
117
|
+
duration: accordion.animationDuration,
|
|
56
118
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
119
|
+
useNativeDriver: false,
|
|
120
|
+
}),
|
|
121
|
+
|
|
122
|
+
Animated.timing(opacityAnimation, {
|
|
123
|
+
toValue: 0,
|
|
124
|
+
|
|
125
|
+
duration: Math.min(accordion.animationDuration, 160),
|
|
62
126
|
|
|
63
|
-
|
|
64
|
-
|
|
127
|
+
useNativeDriver: false,
|
|
128
|
+
}),
|
|
129
|
+
]).start(({ finished }) => {
|
|
130
|
+
if (finished) {
|
|
131
|
+
setMounted(false);
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
}, [
|
|
135
|
+
item.open,
|
|
136
|
+
accordion.animated,
|
|
137
|
+
accordion.animationDuration,
|
|
138
|
+
heightAnimation,
|
|
139
|
+
opacityAnimation,
|
|
140
|
+
]);
|
|
141
|
+
|
|
142
|
+
/*
|
|
143
|
+
* ------------------------------------------------
|
|
144
|
+
* CLOSED
|
|
145
|
+
* ------------------------------------------------
|
|
146
|
+
*/
|
|
147
|
+
|
|
148
|
+
if (!mounted && !item.open) {
|
|
149
|
+
return (
|
|
150
|
+
<View
|
|
151
|
+
style={{
|
|
152
|
+
position: "absolute",
|
|
153
|
+
|
|
154
|
+
opacity: 0,
|
|
155
|
+
|
|
156
|
+
pointerEvents: "none",
|
|
157
|
+
}}
|
|
158
|
+
>
|
|
159
|
+
<View onLayout={handleLayout}>{children}</View>
|
|
160
|
+
</View>
|
|
161
|
+
);
|
|
65
162
|
}
|
|
66
163
|
|
|
164
|
+
/*
|
|
165
|
+
* ------------------------------------------------
|
|
166
|
+
* ANIMATED HEIGHT
|
|
167
|
+
* ------------------------------------------------
|
|
168
|
+
*/
|
|
169
|
+
|
|
170
|
+
const animatedHeight =
|
|
171
|
+
contentHeight > 0
|
|
172
|
+
? heightAnimation.interpolate({
|
|
173
|
+
inputRange: [0, 1],
|
|
174
|
+
|
|
175
|
+
outputRange: [0, contentHeight],
|
|
176
|
+
})
|
|
177
|
+
: undefined;
|
|
178
|
+
|
|
179
|
+
/*
|
|
180
|
+
* ------------------------------------------------
|
|
181
|
+
* RENDER
|
|
182
|
+
* ------------------------------------------------
|
|
183
|
+
*/
|
|
184
|
+
|
|
67
185
|
return (
|
|
68
186
|
<Animated.View
|
|
69
187
|
testID={testID}
|
|
70
188
|
style={[
|
|
71
|
-
styles.
|
|
189
|
+
styles.container,
|
|
72
190
|
|
|
73
191
|
{
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
maxHeight: progress.interpolate({
|
|
77
|
-
inputRange: [0, 1],
|
|
192
|
+
height: animatedHeight,
|
|
78
193
|
|
|
79
|
-
|
|
80
|
-
}),
|
|
194
|
+
opacity: opacityAnimation,
|
|
81
195
|
},
|
|
82
196
|
|
|
83
197
|
style,
|
|
84
198
|
]}
|
|
85
199
|
>
|
|
86
|
-
<View style={[styles.
|
|
200
|
+
<View style={[styles.content, innerStyle]} onLayout={handleLayout}>
|
|
201
|
+
{children}
|
|
202
|
+
</View>
|
|
87
203
|
</Animated.View>
|
|
88
204
|
);
|
|
89
205
|
});
|
|
90
206
|
|
|
91
207
|
const styles = StyleSheet.create({
|
|
92
|
-
|
|
208
|
+
container: {
|
|
93
209
|
width: "100%",
|
|
94
210
|
|
|
95
211
|
overflow: "hidden",
|
|
96
212
|
},
|
|
97
213
|
|
|
98
|
-
|
|
214
|
+
content: {
|
|
99
215
|
width: "100%",
|
|
100
216
|
},
|
|
101
217
|
});
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import React, {
|
|
2
|
-
Children,
|
|
3
2
|
createContext,
|
|
4
|
-
isValidElement,
|
|
5
3
|
memo,
|
|
6
4
|
useCallback,
|
|
7
5
|
useContext,
|
|
@@ -12,31 +10,80 @@ import React, {
|
|
|
12
10
|
import { StyleSheet, View } from "react-native";
|
|
13
11
|
|
|
14
12
|
import { useUITheme } from "../../theme";
|
|
15
|
-
import { UITabsList } from "./UITabsList";
|
|
16
|
-
import { UITabsTrigger } from "./UITabsTrigger";
|
|
17
|
-
import { UITabsContent } from "./UITabsContent";
|
|
18
|
-
import { UITabsIndicator } from "./UITabsIndicator";
|
|
19
13
|
|
|
20
|
-
const
|
|
14
|
+
const UITabsContext = createContext(null);
|
|
21
15
|
|
|
22
|
-
const
|
|
16
|
+
const TAB_SIZES = {
|
|
23
17
|
sm: "sm",
|
|
24
18
|
md: "md",
|
|
25
19
|
lg: "lg",
|
|
26
20
|
};
|
|
27
21
|
|
|
22
|
+
const ANIMATION_PRESETS = {
|
|
23
|
+
none: {
|
|
24
|
+
indicator: "none",
|
|
25
|
+
content: "none",
|
|
26
|
+
press: "none",
|
|
27
|
+
},
|
|
28
|
+
|
|
29
|
+
subtle: {
|
|
30
|
+
indicator: "slide",
|
|
31
|
+
content: "fade",
|
|
32
|
+
press: "scale",
|
|
33
|
+
},
|
|
34
|
+
|
|
35
|
+
smooth: {
|
|
36
|
+
indicator: "slide",
|
|
37
|
+
content: "fadeSlide",
|
|
38
|
+
press: "scale",
|
|
39
|
+
},
|
|
40
|
+
|
|
41
|
+
snappy: {
|
|
42
|
+
indicator: "spring",
|
|
43
|
+
content: "slideFade",
|
|
44
|
+
press: "scale",
|
|
45
|
+
},
|
|
46
|
+
|
|
47
|
+
spring: {
|
|
48
|
+
indicator: "spring",
|
|
49
|
+
content: "slideScale",
|
|
50
|
+
press: "scale",
|
|
51
|
+
},
|
|
52
|
+
|
|
53
|
+
bouncy: {
|
|
54
|
+
indicator: "spring",
|
|
55
|
+
content: "springScale",
|
|
56
|
+
press: "scale",
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
|
|
28
60
|
export const UITabs = memo(function UITabs({
|
|
29
61
|
children,
|
|
30
62
|
|
|
31
63
|
value,
|
|
32
|
-
defaultValue,
|
|
64
|
+
defaultValue = null,
|
|
33
65
|
|
|
34
66
|
onValueChange,
|
|
35
67
|
|
|
36
68
|
size = "md",
|
|
37
69
|
|
|
38
70
|
animated = true,
|
|
39
|
-
|
|
71
|
+
|
|
72
|
+
animationPreset = "smooth",
|
|
73
|
+
|
|
74
|
+
indicatorAnimation,
|
|
75
|
+
contentAnimation,
|
|
76
|
+
pressAnimation,
|
|
77
|
+
|
|
78
|
+
animationDuration = 260,
|
|
79
|
+
|
|
80
|
+
spring = {
|
|
81
|
+
damping: 18,
|
|
82
|
+
stiffness: 180,
|
|
83
|
+
mass: 0.8,
|
|
84
|
+
},
|
|
85
|
+
|
|
86
|
+
directionAware = true,
|
|
40
87
|
|
|
41
88
|
variant = "default",
|
|
42
89
|
|
|
@@ -44,12 +91,14 @@ export const UITabs = memo(function UITabs({
|
|
|
44
91
|
inactiveColor,
|
|
45
92
|
|
|
46
93
|
indicatorColor,
|
|
94
|
+
|
|
47
95
|
indicatorHeight = 2,
|
|
48
96
|
|
|
49
97
|
indicatorWidth = "content",
|
|
50
98
|
|
|
51
99
|
disabled = false,
|
|
52
100
|
|
|
101
|
+
style,
|
|
53
102
|
containerStyle,
|
|
54
103
|
|
|
55
104
|
testID,
|
|
@@ -60,25 +109,38 @@ export const UITabs = memo(function UITabs({
|
|
|
60
109
|
|
|
61
110
|
const controlled = value !== undefined;
|
|
62
111
|
|
|
63
|
-
const [internalValue, setInternalValue] = useState(defaultValue
|
|
112
|
+
const [internalValue, setInternalValue] = useState(defaultValue);
|
|
64
113
|
|
|
65
114
|
const currentValue = controlled ? value : internalValue;
|
|
66
115
|
|
|
67
|
-
const
|
|
116
|
+
const [previousValue, setPreviousValue] = useState(currentValue);
|
|
117
|
+
|
|
118
|
+
const safeSize = TAB_SIZES[size] ? size : "md";
|
|
119
|
+
|
|
120
|
+
const safePreset =
|
|
121
|
+
ANIMATION_PRESETS[animationPreset] || ANIMATION_PRESETS.smooth;
|
|
122
|
+
|
|
123
|
+
const resolvedIndicatorAnimation = indicatorAnimation ?? safePreset.indicator;
|
|
124
|
+
|
|
125
|
+
const resolvedContentAnimation = contentAnimation ?? safePreset.content;
|
|
126
|
+
|
|
127
|
+
const resolvedPressAnimation = pressAnimation ?? safePreset.press;
|
|
68
128
|
|
|
69
129
|
const changeValue = useCallback(
|
|
70
130
|
(nextValue) => {
|
|
71
|
-
if (disabled) {
|
|
131
|
+
if (disabled || nextValue === currentValue) {
|
|
72
132
|
return;
|
|
73
133
|
}
|
|
74
134
|
|
|
135
|
+
setPreviousValue(currentValue);
|
|
136
|
+
|
|
75
137
|
if (!controlled) {
|
|
76
138
|
setInternalValue(nextValue);
|
|
77
139
|
}
|
|
78
140
|
|
|
79
141
|
onValueChange?.(nextValue);
|
|
80
142
|
},
|
|
81
|
-
[disabled, controlled, onValueChange],
|
|
143
|
+
[disabled, currentValue, controlled, onValueChange],
|
|
82
144
|
);
|
|
83
145
|
|
|
84
146
|
const contextValue = useMemo(
|
|
@@ -87,6 +149,8 @@ export const UITabs = memo(function UITabs({
|
|
|
87
149
|
|
|
88
150
|
value: currentValue,
|
|
89
151
|
|
|
152
|
+
previousValue,
|
|
153
|
+
|
|
90
154
|
setValue: changeValue,
|
|
91
155
|
|
|
92
156
|
size: safeSize,
|
|
@@ -95,11 +159,21 @@ export const UITabs = memo(function UITabs({
|
|
|
95
159
|
|
|
96
160
|
animationDuration,
|
|
97
161
|
|
|
162
|
+
spring,
|
|
163
|
+
|
|
164
|
+
directionAware,
|
|
165
|
+
|
|
166
|
+
indicatorAnimation: animated ? resolvedIndicatorAnimation : "none",
|
|
167
|
+
|
|
168
|
+
contentAnimation: animated ? resolvedContentAnimation : "none",
|
|
169
|
+
|
|
170
|
+
pressAnimation: animated ? resolvedPressAnimation : "none",
|
|
171
|
+
|
|
98
172
|
variant,
|
|
99
173
|
|
|
100
174
|
activeColor: activeColor || colors.primary || "#FF5A1F",
|
|
101
175
|
|
|
102
|
-
inactiveColor: inactiveColor || colors.textSecondary || "#
|
|
176
|
+
inactiveColor: inactiveColor || colors.textSecondary || "#737373",
|
|
103
177
|
|
|
104
178
|
indicatorColor:
|
|
105
179
|
indicatorColor || activeColor || colors.primary || "#FF5A1F",
|
|
@@ -113,10 +187,16 @@ export const UITabs = memo(function UITabs({
|
|
|
113
187
|
[
|
|
114
188
|
colors,
|
|
115
189
|
currentValue,
|
|
190
|
+
previousValue,
|
|
116
191
|
changeValue,
|
|
117
192
|
safeSize,
|
|
118
193
|
animated,
|
|
119
194
|
animationDuration,
|
|
195
|
+
spring,
|
|
196
|
+
directionAware,
|
|
197
|
+
resolvedIndicatorAnimation,
|
|
198
|
+
resolvedContentAnimation,
|
|
199
|
+
resolvedPressAnimation,
|
|
120
200
|
variant,
|
|
121
201
|
activeColor,
|
|
122
202
|
inactiveColor,
|
|
@@ -128,31 +208,28 @@ export const UITabs = memo(function UITabs({
|
|
|
128
208
|
);
|
|
129
209
|
|
|
130
210
|
return (
|
|
131
|
-
<
|
|
132
|
-
<View testID={testID} style={[styles.container, containerStyle]}>
|
|
133
|
-
{
|
|
134
|
-
if (!isValidElement(child)) {
|
|
135
|
-
return child;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
return child;
|
|
139
|
-
})}
|
|
211
|
+
<UITabsContext.Provider value={contextValue}>
|
|
212
|
+
<View testID={testID} style={[styles.container, containerStyle, style]}>
|
|
213
|
+
{children}
|
|
140
214
|
</View>
|
|
141
|
-
</
|
|
215
|
+
</UITabsContext.Provider>
|
|
142
216
|
);
|
|
143
217
|
});
|
|
144
218
|
|
|
145
219
|
export function useUITabs() {
|
|
146
|
-
const context = useContext(
|
|
220
|
+
const context = useContext(UITabsContext);
|
|
147
221
|
|
|
148
222
|
if (!context) {
|
|
149
|
-
throw new Error("UITabs components must be used inside UITabs
|
|
223
|
+
throw new Error("UITabs components must be used inside <UITabs>.");
|
|
150
224
|
}
|
|
151
225
|
|
|
152
226
|
return context;
|
|
153
227
|
}
|
|
154
228
|
|
|
155
|
-
export
|
|
229
|
+
export {
|
|
230
|
+
TAB_SIZES as UITabsSizes,
|
|
231
|
+
ANIMATION_PRESETS as UITabsAnimationPresets,
|
|
232
|
+
};
|
|
156
233
|
|
|
157
234
|
const styles = StyleSheet.create({
|
|
158
235
|
container: {
|
|
@@ -161,10 +238,3 @@ const styles = StyleSheet.create({
|
|
|
161
238
|
});
|
|
162
239
|
|
|
163
240
|
UITabs.displayName = "UITabs";
|
|
164
|
-
UITabs.List = UITabsList;
|
|
165
|
-
|
|
166
|
-
UITabs.Trigger = UITabsTrigger;
|
|
167
|
-
|
|
168
|
-
UITabs.Content = UITabsContent;
|
|
169
|
-
|
|
170
|
-
UITabs.Indicator = UITabsIndicator;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { memo, useEffect, useRef, useState } from "react";
|
|
2
2
|
|
|
3
|
-
import { Animated,
|
|
3
|
+
import { Animated, StyleSheet } from "react-native";
|
|
4
4
|
|
|
5
5
|
import { useUITabs } from "./UITabs";
|
|
6
6
|
|
|
@@ -11,6 +11,7 @@ export const UITabsContent = memo(function UITabsContent({
|
|
|
11
11
|
|
|
12
12
|
style,
|
|
13
13
|
|
|
14
|
+
animation,
|
|
14
15
|
animationDuration,
|
|
15
16
|
|
|
16
17
|
testID,
|
|
@@ -19,96 +20,81 @@ export const UITabsContent = memo(function UITabsContent({
|
|
|
19
20
|
|
|
20
21
|
const active = tabs.value === value;
|
|
21
22
|
|
|
23
|
+
const animationType = animation ?? tabs.contentAnimation;
|
|
24
|
+
|
|
22
25
|
const [mounted, setMounted] = useState(active);
|
|
23
26
|
|
|
24
|
-
const
|
|
27
|
+
const progress = useRef(new Animated.Value(active ? 1 : 0)).current;
|
|
25
28
|
|
|
26
|
-
const
|
|
29
|
+
const direction = getDirection(tabs, value);
|
|
27
30
|
|
|
28
31
|
useEffect(() => {
|
|
32
|
+
const duration = animationDuration ?? tabs.animationDuration;
|
|
33
|
+
|
|
29
34
|
if (active) {
|
|
30
35
|
setMounted(true);
|
|
31
36
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
37
|
+
progress.setValue(0);
|
|
38
|
+
|
|
39
|
+
if (animationType === "none") {
|
|
40
|
+
progress.setValue(1);
|
|
35
41
|
|
|
36
42
|
return;
|
|
37
43
|
}
|
|
38
44
|
|
|
39
|
-
Animated.
|
|
40
|
-
|
|
41
|
-
toValue: 1,
|
|
42
|
-
|
|
43
|
-
duration: animationDuration ?? tabs.animationDuration,
|
|
44
|
-
|
|
45
|
-
useNativeDriver: true,
|
|
46
|
-
}),
|
|
47
|
-
|
|
48
|
-
Animated.timing(translateY, {
|
|
49
|
-
toValue: 0,
|
|
45
|
+
Animated.timing(progress, {
|
|
46
|
+
toValue: 1,
|
|
50
47
|
|
|
51
|
-
|
|
48
|
+
duration,
|
|
52
49
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
]).start();
|
|
50
|
+
useNativeDriver: true,
|
|
51
|
+
}).start();
|
|
56
52
|
|
|
57
53
|
return;
|
|
58
54
|
}
|
|
59
55
|
|
|
60
|
-
if (
|
|
61
|
-
|
|
56
|
+
if (animationType === "none") {
|
|
57
|
+
progress.setValue(0);
|
|
58
|
+
|
|
62
59
|
setMounted(false);
|
|
63
60
|
|
|
64
61
|
return;
|
|
65
62
|
}
|
|
66
63
|
|
|
67
|
-
Animated.
|
|
68
|
-
|
|
69
|
-
toValue: 0,
|
|
70
|
-
|
|
71
|
-
duration: animationDuration ?? tabs.animationDuration,
|
|
72
|
-
|
|
73
|
-
useNativeDriver: true,
|
|
74
|
-
}),
|
|
75
|
-
|
|
76
|
-
Animated.timing(translateY, {
|
|
77
|
-
toValue: 5,
|
|
64
|
+
Animated.timing(progress, {
|
|
65
|
+
toValue: 0,
|
|
78
66
|
|
|
79
|
-
|
|
67
|
+
duration,
|
|
80
68
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
]).start(() => {
|
|
69
|
+
useNativeDriver: true,
|
|
70
|
+
}).start(() => {
|
|
84
71
|
setMounted(false);
|
|
85
72
|
});
|
|
86
73
|
}, [
|
|
87
74
|
active,
|
|
88
|
-
|
|
89
|
-
tabs.animationDuration,
|
|
75
|
+
animationType,
|
|
90
76
|
animationDuration,
|
|
91
|
-
|
|
92
|
-
|
|
77
|
+
tabs.animationDuration,
|
|
78
|
+
progress,
|
|
93
79
|
]);
|
|
94
80
|
|
|
95
81
|
if (!mounted) {
|
|
96
82
|
return null;
|
|
97
83
|
}
|
|
98
84
|
|
|
85
|
+
const transforms = getContentTransforms(animationType, progress, direction);
|
|
86
|
+
|
|
99
87
|
return (
|
|
100
88
|
<Animated.View
|
|
101
89
|
testID={testID}
|
|
102
90
|
accessibilityRole="tabpanel"
|
|
103
91
|
style={[
|
|
92
|
+
styles.container,
|
|
93
|
+
|
|
104
94
|
{
|
|
105
|
-
opacity,
|
|
95
|
+
opacity: getOpacity(animationType, progress),
|
|
106
96
|
|
|
107
|
-
transform:
|
|
108
|
-
{
|
|
109
|
-
translateY,
|
|
110
|
-
},
|
|
111
|
-
],
|
|
97
|
+
transform: transforms,
|
|
112
98
|
},
|
|
113
99
|
|
|
114
100
|
style,
|
|
@@ -119,4 +105,86 @@ export const UITabsContent = memo(function UITabsContent({
|
|
|
119
105
|
);
|
|
120
106
|
});
|
|
121
107
|
|
|
108
|
+
function getDirection(tabs, value) {
|
|
109
|
+
if (!tabs.directionAware) {
|
|
110
|
+
return 1;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (tabs.previousValue === null || tabs.previousValue === undefined) {
|
|
114
|
+
return 1;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return String(value) > String(tabs.previousValue) ? 1 : -1;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function getOpacity(type, progress) {
|
|
121
|
+
if (type === "slide" || type === "scale") {
|
|
122
|
+
return 1;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return progress;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function getContentTransforms(type, progress, direction) {
|
|
129
|
+
switch (type) {
|
|
130
|
+
case "slide":
|
|
131
|
+
return [
|
|
132
|
+
{
|
|
133
|
+
translateX: progress.interpolate({
|
|
134
|
+
inputRange: [0, 1],
|
|
135
|
+
outputRange: [24 * direction, 0],
|
|
136
|
+
}),
|
|
137
|
+
},
|
|
138
|
+
];
|
|
139
|
+
|
|
140
|
+
case "fadeSlide":
|
|
141
|
+
case "slideFade":
|
|
142
|
+
return [
|
|
143
|
+
{
|
|
144
|
+
translateX: progress.interpolate({
|
|
145
|
+
inputRange: [0, 1],
|
|
146
|
+
outputRange: [20 * direction, 0],
|
|
147
|
+
}),
|
|
148
|
+
},
|
|
149
|
+
];
|
|
150
|
+
|
|
151
|
+
case "scale":
|
|
152
|
+
return [
|
|
153
|
+
{
|
|
154
|
+
scale: progress.interpolate({
|
|
155
|
+
inputRange: [0, 1],
|
|
156
|
+
outputRange: [0.96, 1],
|
|
157
|
+
}),
|
|
158
|
+
},
|
|
159
|
+
];
|
|
160
|
+
|
|
161
|
+
case "slideScale":
|
|
162
|
+
case "springScale":
|
|
163
|
+
return [
|
|
164
|
+
{
|
|
165
|
+
translateX: progress.interpolate({
|
|
166
|
+
inputRange: [0, 1],
|
|
167
|
+
outputRange: [18 * direction, 0],
|
|
168
|
+
}),
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
scale: progress.interpolate({
|
|
172
|
+
inputRange: [0, 1],
|
|
173
|
+
outputRange: [0.97, 1],
|
|
174
|
+
}),
|
|
175
|
+
},
|
|
176
|
+
];
|
|
177
|
+
|
|
178
|
+
case "fade":
|
|
179
|
+
default:
|
|
180
|
+
return [];
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
const styles = StyleSheet.create({
|
|
185
|
+
container: {
|
|
186
|
+
width: "100%",
|
|
187
|
+
},
|
|
188
|
+
});
|
|
189
|
+
|
|
122
190
|
UITabsContent.displayName = "UITabs.Content";
|
|
@@ -15,19 +15,25 @@ export const UITabsList = memo(function UITabsList({
|
|
|
15
15
|
|
|
16
16
|
style,
|
|
17
17
|
|
|
18
|
+
backgroundColor,
|
|
19
|
+
|
|
20
|
+
borderBottomWidth = 0,
|
|
21
|
+
|
|
22
|
+
borderBottomColor,
|
|
23
|
+
|
|
18
24
|
testID,
|
|
19
25
|
}) {
|
|
20
26
|
const tabs = useUITabs();
|
|
21
27
|
|
|
22
|
-
const
|
|
28
|
+
const horizontalPadding =
|
|
29
|
+
tabs.size === "sm" ? 6 : tabs.size === "lg" ? 14 : 10;
|
|
23
30
|
|
|
24
|
-
const
|
|
31
|
+
const row = (
|
|
25
32
|
<View
|
|
26
33
|
style={[
|
|
27
34
|
styles.row,
|
|
28
|
-
|
|
29
35
|
{
|
|
30
|
-
paddingHorizontal:
|
|
36
|
+
paddingHorizontal: horizontalPadding,
|
|
31
37
|
},
|
|
32
38
|
]}
|
|
33
39
|
>
|
|
@@ -35,25 +41,39 @@ export const UITabsList = memo(function UITabsList({
|
|
|
35
41
|
</View>
|
|
36
42
|
);
|
|
37
43
|
|
|
44
|
+
const containerStyle = [
|
|
45
|
+
styles.container,
|
|
46
|
+
|
|
47
|
+
{
|
|
48
|
+
backgroundColor: backgroundColor || "transparent",
|
|
49
|
+
|
|
50
|
+
borderBottomWidth,
|
|
51
|
+
|
|
52
|
+
borderBottomColor: borderBottomColor || tabs.colors.border || "#E5E5E5",
|
|
53
|
+
},
|
|
54
|
+
|
|
55
|
+
style,
|
|
56
|
+
];
|
|
57
|
+
|
|
38
58
|
if (scrollable) {
|
|
39
59
|
return (
|
|
40
60
|
<ScrollView
|
|
41
61
|
testID={testID}
|
|
42
62
|
horizontal
|
|
43
63
|
showsHorizontalScrollIndicator={showsHorizontalScrollIndicator}
|
|
44
|
-
bounces
|
|
45
64
|
keyboardShouldPersistTaps="handled"
|
|
65
|
+
bounces
|
|
46
66
|
contentContainerStyle={[styles.scrollContent, contentContainerStyle]}
|
|
47
|
-
style={
|
|
67
|
+
style={containerStyle}
|
|
48
68
|
>
|
|
49
|
-
{
|
|
69
|
+
{row}
|
|
50
70
|
</ScrollView>
|
|
51
71
|
);
|
|
52
72
|
}
|
|
53
73
|
|
|
54
74
|
return (
|
|
55
|
-
<View testID={testID} style={
|
|
56
|
-
{
|
|
75
|
+
<View testID={testID} style={containerStyle}>
|
|
76
|
+
{row}
|
|
57
77
|
</View>
|
|
58
78
|
);
|
|
59
79
|
});
|
|
@@ -61,7 +81,6 @@ export const UITabsList = memo(function UITabsList({
|
|
|
61
81
|
const styles = StyleSheet.create({
|
|
62
82
|
container: {
|
|
63
83
|
width: "100%",
|
|
64
|
-
overflow: "hidden",
|
|
65
84
|
},
|
|
66
85
|
|
|
67
86
|
scrollContent: {
|
|
@@ -22,13 +22,26 @@ export const UITabsTrigger = memo(function UITabsTrigger({
|
|
|
22
22
|
inactiveColor,
|
|
23
23
|
|
|
24
24
|
style,
|
|
25
|
+
activeStyle,
|
|
26
|
+
inactiveStyle,
|
|
27
|
+
|
|
25
28
|
contentStyle,
|
|
29
|
+
|
|
26
30
|
textStyle,
|
|
31
|
+
activeTextStyle,
|
|
32
|
+
inactiveTextStyle,
|
|
33
|
+
|
|
27
34
|
iconStyle,
|
|
35
|
+
|
|
28
36
|
badgeStyle,
|
|
37
|
+
badgeTextStyle,
|
|
29
38
|
|
|
30
|
-
|
|
39
|
+
pressAnimation,
|
|
40
|
+
pressScale = 0.96,
|
|
41
|
+
|
|
42
|
+
indicator = true,
|
|
31
43
|
|
|
44
|
+
testID,
|
|
32
45
|
accessibilityLabel,
|
|
33
46
|
}) {
|
|
34
47
|
const tabs = useUITabs();
|
|
@@ -37,23 +50,45 @@ export const UITabsTrigger = memo(function UITabsTrigger({
|
|
|
37
50
|
|
|
38
51
|
const isDisabled = disabled || tabs.disabled;
|
|
39
52
|
|
|
40
|
-
const
|
|
53
|
+
const scale = useRef(new Animated.Value(1)).current;
|
|
54
|
+
|
|
55
|
+
const resolvedPressAnimation = pressAnimation ?? tabs.pressAnimation;
|
|
41
56
|
|
|
42
57
|
useEffect(() => {
|
|
43
|
-
if (
|
|
44
|
-
|
|
58
|
+
if (resolvedPressAnimation === "none") {
|
|
59
|
+
scale.setValue(1);
|
|
60
|
+
}
|
|
61
|
+
}, [resolvedPressAnimation, scale]);
|
|
45
62
|
|
|
63
|
+
const animatePressIn = () => {
|
|
64
|
+
if (resolvedPressAnimation === "none") {
|
|
46
65
|
return;
|
|
47
66
|
}
|
|
48
67
|
|
|
49
|
-
|
|
50
|
-
|
|
68
|
+
if (resolvedPressAnimation === "scale") {
|
|
69
|
+
Animated.spring(scale, {
|
|
70
|
+
toValue: pressScale,
|
|
51
71
|
|
|
52
|
-
|
|
72
|
+
...tabs.spring,
|
|
73
|
+
|
|
74
|
+
useNativeDriver: true,
|
|
75
|
+
}).start();
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
const animatePressOut = () => {
|
|
80
|
+
if (resolvedPressAnimation === "none") {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
Animated.spring(scale, {
|
|
85
|
+
toValue: 1,
|
|
86
|
+
|
|
87
|
+
...tabs.spring,
|
|
53
88
|
|
|
54
89
|
useNativeDriver: true,
|
|
55
90
|
}).start();
|
|
56
|
-
}
|
|
91
|
+
};
|
|
57
92
|
|
|
58
93
|
const handlePress = (event) => {
|
|
59
94
|
if (isDisabled) {
|
|
@@ -65,9 +100,9 @@ export const UITabsTrigger = memo(function UITabsTrigger({
|
|
|
65
100
|
onPress?.(event);
|
|
66
101
|
};
|
|
67
102
|
|
|
68
|
-
const
|
|
103
|
+
const activeTextColor = activeColor || tabs.activeColor;
|
|
69
104
|
|
|
70
|
-
const
|
|
105
|
+
const inactiveTextColor = inactiveColor || tabs.inactiveColor;
|
|
71
106
|
|
|
72
107
|
const iconElement = icon ? (
|
|
73
108
|
<View
|
|
@@ -83,124 +118,189 @@ export const UITabsTrigger = memo(function UITabsTrigger({
|
|
|
83
118
|
</View>
|
|
84
119
|
) : null;
|
|
85
120
|
|
|
86
|
-
|
|
87
|
-
<
|
|
88
|
-
numberOfLines={1}
|
|
121
|
+
return (
|
|
122
|
+
<Animated.View
|
|
89
123
|
style={[
|
|
90
|
-
styles.
|
|
124
|
+
styles.animatedWrapper,
|
|
91
125
|
|
|
92
126
|
{
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
127
|
+
transform: [
|
|
128
|
+
{
|
|
129
|
+
scale,
|
|
130
|
+
},
|
|
131
|
+
],
|
|
98
132
|
},
|
|
99
|
-
|
|
100
|
-
textStyle,
|
|
101
133
|
]}
|
|
102
134
|
>
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
accessibilityLabel={accessibilityLabel}
|
|
118
|
-
style={({ pressed }) => [
|
|
119
|
-
styles.trigger,
|
|
135
|
+
<Pressable
|
|
136
|
+
testID={testID}
|
|
137
|
+
disabled={isDisabled}
|
|
138
|
+
onPress={handlePress}
|
|
139
|
+
onPressIn={animatePressIn}
|
|
140
|
+
onPressOut={animatePressOut}
|
|
141
|
+
accessibilityRole="tab"
|
|
142
|
+
accessibilityState={{
|
|
143
|
+
selected: active,
|
|
144
|
+
disabled: isDisabled,
|
|
145
|
+
}}
|
|
146
|
+
accessibilityLabel={accessibilityLabel}
|
|
147
|
+
style={[
|
|
148
|
+
styles.trigger,
|
|
120
149
|
|
|
121
|
-
|
|
122
|
-
|
|
150
|
+
{
|
|
151
|
+
minHeight: tabs.size === "sm" ? 42 : tabs.size === "lg" ? 58 : 50,
|
|
123
152
|
|
|
124
|
-
|
|
125
|
-
|
|
153
|
+
opacity: isDisabled ? 0.45 : 1,
|
|
154
|
+
},
|
|
126
155
|
|
|
127
|
-
|
|
128
|
-
]}
|
|
129
|
-
>
|
|
130
|
-
<View
|
|
131
|
-
style={[
|
|
132
|
-
styles.content,
|
|
156
|
+
inactiveStyle,
|
|
133
157
|
|
|
134
|
-
|
|
158
|
+
active ? activeStyle : null,
|
|
135
159
|
|
|
136
|
-
|
|
160
|
+
style,
|
|
137
161
|
]}
|
|
138
162
|
>
|
|
139
|
-
{
|
|
140
|
-
|
|
141
|
-
{textElement}
|
|
142
|
-
|
|
143
|
-
{iconPosition === "right" ? iconElement : null}
|
|
163
|
+
<View style={[styles.content, contentStyle]}>
|
|
164
|
+
{iconPosition === "left" ? iconElement : null}
|
|
144
165
|
|
|
145
|
-
|
|
146
|
-
|
|
166
|
+
<Text
|
|
167
|
+
numberOfLines={1}
|
|
147
168
|
style={[
|
|
148
|
-
styles.
|
|
169
|
+
styles.text,
|
|
149
170
|
|
|
150
171
|
{
|
|
151
|
-
|
|
152
|
-
?
|
|
153
|
-
|
|
172
|
+
fontSize:
|
|
173
|
+
tabs.size === "sm" ? 12 : tabs.size === "lg" ? 16 : 14,
|
|
174
|
+
|
|
175
|
+
color: active ? activeTextColor : inactiveTextColor,
|
|
154
176
|
},
|
|
155
177
|
|
|
156
|
-
|
|
178
|
+
textStyle,
|
|
179
|
+
|
|
180
|
+
inactiveTextStyle,
|
|
181
|
+
|
|
182
|
+
active ? activeTextStyle : null,
|
|
157
183
|
]}
|
|
158
184
|
>
|
|
159
|
-
|
|
185
|
+
{children}
|
|
186
|
+
</Text>
|
|
187
|
+
|
|
188
|
+
{iconPosition === "right" ? iconElement : null}
|
|
189
|
+
|
|
190
|
+
{badge !== undefined ? (
|
|
191
|
+
<View
|
|
160
192
|
style={[
|
|
161
|
-
styles.
|
|
193
|
+
styles.badge,
|
|
162
194
|
|
|
163
195
|
{
|
|
164
|
-
|
|
165
|
-
?
|
|
166
|
-
: tabs.colors.
|
|
196
|
+
backgroundColor: active
|
|
197
|
+
? activeTextColor
|
|
198
|
+
: tabs.colors.surfaceSecondary || "#EEEEEE",
|
|
167
199
|
},
|
|
200
|
+
|
|
201
|
+
badgeStyle,
|
|
168
202
|
]}
|
|
169
203
|
>
|
|
170
|
-
|
|
171
|
-
|
|
204
|
+
<Text
|
|
205
|
+
style={[
|
|
206
|
+
styles.badgeText,
|
|
207
|
+
|
|
208
|
+
{
|
|
209
|
+
color: active
|
|
210
|
+
? tabs.colors.onPrimary || "#FFFFFF"
|
|
211
|
+
: tabs.colors.textSecondary || "#525252",
|
|
212
|
+
},
|
|
213
|
+
|
|
214
|
+
badgeTextStyle,
|
|
215
|
+
]}
|
|
216
|
+
>
|
|
217
|
+
{badge}
|
|
218
|
+
</Text>
|
|
219
|
+
</View>
|
|
220
|
+
) : null}
|
|
221
|
+
</View>
|
|
222
|
+
|
|
223
|
+
{indicator ? (
|
|
224
|
+
<View style={styles.indicatorContainer}>
|
|
225
|
+
<AnimatedIndicator active={active} />
|
|
172
226
|
</View>
|
|
173
227
|
) : null}
|
|
174
|
-
</
|
|
228
|
+
</Pressable>
|
|
229
|
+
</Animated.View>
|
|
230
|
+
);
|
|
231
|
+
});
|
|
175
232
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
styles.indicator,
|
|
233
|
+
function AnimatedIndicator({ active }) {
|
|
234
|
+
const tabs = useUITabs();
|
|
179
235
|
|
|
180
|
-
|
|
181
|
-
|
|
236
|
+
const progress = useRef(new Animated.Value(active ? 1 : 0)).current;
|
|
237
|
+
|
|
238
|
+
useEffect(() => {
|
|
239
|
+
if (tabs.indicatorAnimation === "none") {
|
|
240
|
+
progress.setValue(active ? 1 : 0);
|
|
182
241
|
|
|
183
|
-
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
184
244
|
|
|
185
|
-
|
|
245
|
+
if (tabs.indicatorAnimation === "spring") {
|
|
246
|
+
Animated.spring(progress, {
|
|
247
|
+
toValue: active ? 1 : 0,
|
|
186
248
|
|
|
187
|
-
|
|
188
|
-
{
|
|
189
|
-
scaleX: progress,
|
|
190
|
-
},
|
|
191
|
-
],
|
|
192
|
-
},
|
|
249
|
+
...tabs.spring,
|
|
193
250
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
251
|
+
useNativeDriver: true,
|
|
252
|
+
}).start();
|
|
253
|
+
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
Animated.timing(progress, {
|
|
258
|
+
toValue: active ? 1 : 0,
|
|
259
|
+
|
|
260
|
+
duration: tabs.animationDuration,
|
|
261
|
+
|
|
262
|
+
useNativeDriver: true,
|
|
263
|
+
}).start();
|
|
264
|
+
}, [
|
|
265
|
+
active,
|
|
266
|
+
tabs.indicatorAnimation,
|
|
267
|
+
tabs.animationDuration,
|
|
268
|
+
tabs.spring,
|
|
269
|
+
progress,
|
|
270
|
+
]);
|
|
271
|
+
|
|
272
|
+
return (
|
|
273
|
+
<Animated.View
|
|
274
|
+
style={[
|
|
275
|
+
styles.indicator,
|
|
276
|
+
|
|
277
|
+
{
|
|
278
|
+
height: tabs.indicatorHeight,
|
|
279
|
+
|
|
280
|
+
backgroundColor: tabs.indicatorColor,
|
|
281
|
+
|
|
282
|
+
opacity: progress,
|
|
283
|
+
|
|
284
|
+
transform: [
|
|
285
|
+
{
|
|
286
|
+
scaleX: progress,
|
|
287
|
+
},
|
|
288
|
+
],
|
|
289
|
+
},
|
|
290
|
+
|
|
291
|
+
tabs.indicatorWidth === "full"
|
|
292
|
+
? styles.indicatorFull
|
|
293
|
+
: styles.indicatorContent,
|
|
294
|
+
]}
|
|
295
|
+
/>
|
|
200
296
|
);
|
|
201
|
-
}
|
|
297
|
+
}
|
|
202
298
|
|
|
203
299
|
const styles = StyleSheet.create({
|
|
300
|
+
animatedWrapper: {
|
|
301
|
+
flexShrink: 0,
|
|
302
|
+
},
|
|
303
|
+
|
|
204
304
|
trigger: {
|
|
205
305
|
position: "relative",
|
|
206
306
|
|
|
@@ -219,8 +319,10 @@ const styles = StyleSheet.create({
|
|
|
219
319
|
gap: 6,
|
|
220
320
|
},
|
|
221
321
|
|
|
222
|
-
|
|
223
|
-
|
|
322
|
+
text: {
|
|
323
|
+
fontWeight: "600",
|
|
324
|
+
|
|
325
|
+
includeFontPadding: false,
|
|
224
326
|
},
|
|
225
327
|
|
|
226
328
|
icon: {
|
|
@@ -237,12 +339,6 @@ const styles = StyleSheet.create({
|
|
|
237
339
|
marginLeft: 2,
|
|
238
340
|
},
|
|
239
341
|
|
|
240
|
-
text: {
|
|
241
|
-
fontWeight: "600",
|
|
242
|
-
|
|
243
|
-
includeFontPadding: false,
|
|
244
|
-
},
|
|
245
|
-
|
|
246
342
|
badge: {
|
|
247
343
|
minWidth: 18,
|
|
248
344
|
height: 18,
|
|
@@ -264,14 +360,18 @@ const styles = StyleSheet.create({
|
|
|
264
360
|
includeFontPadding: false,
|
|
265
361
|
},
|
|
266
362
|
|
|
267
|
-
|
|
363
|
+
indicatorContainer: {
|
|
268
364
|
position: "absolute",
|
|
269
365
|
|
|
366
|
+
left: 0,
|
|
367
|
+
right: 0,
|
|
270
368
|
bottom: 0,
|
|
369
|
+
},
|
|
271
370
|
|
|
272
|
-
|
|
371
|
+
indicator: {
|
|
372
|
+
position: "absolute",
|
|
273
373
|
|
|
274
|
-
|
|
374
|
+
bottom: 0,
|
|
275
375
|
},
|
|
276
376
|
|
|
277
377
|
indicatorFull: {
|
|
@@ -1,9 +1,16 @@
|
|
|
1
|
-
|
|
1
|
+
import { UITabs } from "./UITabs";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
import { UITabsList } from "./UITabsList";
|
|
4
|
+
import { UITabsTrigger } from "./UITabsTrigger";
|
|
5
|
+
import { UITabsContent } from "./UITabsContent";
|
|
6
|
+
import { UITabsIndicator } from "./UITabsIndicator";
|
|
4
7
|
|
|
5
|
-
|
|
8
|
+
UITabs.List = UITabsList;
|
|
6
9
|
|
|
7
|
-
|
|
10
|
+
UITabs.Trigger = UITabsTrigger;
|
|
8
11
|
|
|
9
|
-
|
|
12
|
+
UITabs.Content = UITabsContent;
|
|
13
|
+
|
|
14
|
+
UITabs.Indicator = UITabsIndicator;
|
|
15
|
+
|
|
16
|
+
export { UITabs, UITabsList, UITabsTrigger, UITabsContent, UITabsIndicator };
|
package/src/components/index.js
CHANGED