react-native-molecules 0.5.0-beta.10 → 0.5.0-beta.11
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/components/Checkbox/CheckboxBase.tsx +23 -128
- package/components/Checkbox/utils.ts +0 -25
- package/components/DatePickerInput/DatePickerInput.tsx +4 -2
- package/components/DatePickerInput/DatePickerInputWithoutModal.tsx +0 -4
- package/components/DatePickerInput/types.ts +1 -3
- package/components/DatePickerModal/CalendarEdit.tsx +10 -9
- package/components/FilePicker/FilePicker.tsx +47 -76
- package/components/HelperText/HelperText.tsx +0 -35
- package/components/IconButton/utils.ts +140 -25
- package/components/Select/Select.tsx +12 -9
- package/components/Tabs/TabItem.tsx +35 -58
- package/components/Tabs/TabLabel.tsx +5 -9
- package/components/Tabs/Tabs.tsx +154 -149
- package/components/Tabs/utils.ts +15 -2
- package/components/TextInput/TextInput.tsx +657 -574
- package/components/TextInput/index.tsx +19 -3
- package/components/TextInput/types.ts +76 -27
- package/components/TextInput/utils.ts +225 -145
- package/components/TimePickerField/TimePickerField.tsx +7 -5
- package/components/TouchableRipple/TouchableRipple.native.tsx +1 -1
- package/components/TouchableRipple/TouchableRipple.tsx +1 -1
- package/hooks/index.tsx +0 -5
- package/hooks/useSubcomponents.tsx +31 -33
- package/package.json +3 -3
- package/hooks/useSearchable.tsx +0 -74
package/components/Tabs/Tabs.tsx
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
|
-
Children,
|
|
3
2
|
cloneElement,
|
|
4
|
-
type
|
|
5
|
-
isValidElement,
|
|
6
|
-
memo,
|
|
3
|
+
type ComponentType,
|
|
7
4
|
type ReactElement,
|
|
8
5
|
useCallback,
|
|
9
6
|
useEffect,
|
|
@@ -24,21 +21,21 @@ import {
|
|
|
24
21
|
type ViewStyle,
|
|
25
22
|
} from 'react-native';
|
|
26
23
|
|
|
27
|
-
import {
|
|
24
|
+
import { typedMemo } from '../../hocs';
|
|
25
|
+
import { useControlledValue, useSubcomponents } from '../../hooks';
|
|
28
26
|
import { noop } from '../../utils/lodash';
|
|
29
|
-
import { HorizontalDivider, type HorizontalDividerProps } from '../HorizontalDivider';
|
|
30
27
|
import type { TabItemProps } from './TabItem';
|
|
31
28
|
import { tabsStyles } from './utils';
|
|
32
29
|
|
|
33
|
-
export type TabsProps = ViewProps & {
|
|
30
|
+
export type TabsProps<T extends string | number> = ViewProps & {
|
|
34
31
|
/**
|
|
35
32
|
* child tab name
|
|
36
33
|
* */
|
|
37
|
-
value?:
|
|
34
|
+
value?: T;
|
|
38
35
|
/**
|
|
39
36
|
* defaultValue to preselected for uncontrolled mode
|
|
40
37
|
* */
|
|
41
|
-
defaultValue?:
|
|
38
|
+
defaultValue?: T;
|
|
42
39
|
/**
|
|
43
40
|
* to enable scroll
|
|
44
41
|
* */
|
|
@@ -46,7 +43,7 @@ export type TabsProps = ViewProps & {
|
|
|
46
43
|
/**
|
|
47
44
|
* on name change callback.
|
|
48
45
|
* */
|
|
49
|
-
onChange?: (value:
|
|
46
|
+
onChange?: (value: T) => void;
|
|
50
47
|
/**
|
|
51
48
|
* Disable the active indicator below.
|
|
52
49
|
* */
|
|
@@ -58,10 +55,6 @@ export type TabsProps = ViewProps & {
|
|
|
58
55
|
|
|
59
56
|
indicatorProps?: Omit<ViewStyle, 'style'>;
|
|
60
57
|
|
|
61
|
-
dividerStyle?: ViewStyle;
|
|
62
|
-
|
|
63
|
-
dividerProps?: Omit<HorizontalDividerProps, 'style'>;
|
|
64
|
-
|
|
65
58
|
/** Define the background Variant. */
|
|
66
59
|
variant?: 'primary' | 'secondary';
|
|
67
60
|
activeColor?: string;
|
|
@@ -69,7 +62,7 @@ export type TabsProps = ViewProps & {
|
|
|
69
62
|
|
|
70
63
|
const emptyObj = {};
|
|
71
64
|
|
|
72
|
-
export const TabBase = ({
|
|
65
|
+
export const TabBase = <T extends string | number>({
|
|
73
66
|
children,
|
|
74
67
|
value: valueProp,
|
|
75
68
|
defaultValue,
|
|
@@ -80,84 +73,75 @@ export const TabBase = ({
|
|
|
80
73
|
style,
|
|
81
74
|
variant = 'primary',
|
|
82
75
|
indicatorProps,
|
|
83
|
-
dividerStyle: dividerStyleProp = emptyObj,
|
|
84
|
-
dividerProps,
|
|
85
76
|
activeColor: activeColorProp,
|
|
86
77
|
testID,
|
|
87
78
|
...rest
|
|
88
|
-
}: TabsProps) => {
|
|
79
|
+
}: TabsProps<T>) => {
|
|
89
80
|
tabsStyles.useVariants({
|
|
90
81
|
variant,
|
|
91
82
|
});
|
|
92
83
|
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
),
|
|
98
|
-
[children],
|
|
99
|
-
);
|
|
100
|
-
|
|
101
|
-
const nameToIndexMap = useMemo(
|
|
102
|
-
() =>
|
|
103
|
-
validChildren.reduce((acc, child, currentIndex) => {
|
|
104
|
-
acc[(child as ReactElement<TabItemProps>).props?.name] = currentIndex;
|
|
84
|
+
const { Tabs_Item: tabItems } = useSubcomponents({
|
|
85
|
+
children,
|
|
86
|
+
allowedChildren: ['Tabs_Item'],
|
|
87
|
+
});
|
|
105
88
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
89
|
+
// Get ordered list of tab names for current children
|
|
90
|
+
const tabNames = useMemo(
|
|
91
|
+
() => tabItems.map(child => (child as ReactElement<TabItemProps<T>>).props?.name),
|
|
92
|
+
[tabItems],
|
|
109
93
|
);
|
|
110
94
|
|
|
111
95
|
const [value, onChange] = useControlledValue({
|
|
112
96
|
value: valueProp,
|
|
113
97
|
onChange: onChangeProp,
|
|
114
|
-
defaultValue: defaultValue ||
|
|
98
|
+
defaultValue: defaultValue || tabNames[0],
|
|
115
99
|
});
|
|
116
100
|
|
|
117
|
-
const valueIndex =
|
|
101
|
+
const valueIndex = useMemo(() => tabNames.indexOf(value), [value, tabNames]);
|
|
102
|
+
const previousTabCountRef = useRef(tabNames.length);
|
|
118
103
|
|
|
119
104
|
const positionAnimationRef = useRef(new Animated.Value(0));
|
|
120
105
|
const widthAnimationRef = useRef(new Animated.Value(0));
|
|
121
106
|
const scrollViewRef = useRef<RNScrollView>(null);
|
|
122
107
|
const scrollViewPosition = useRef(0);
|
|
123
108
|
|
|
124
|
-
const tabItemPositions = useRef<
|
|
109
|
+
const tabItemPositions = useRef<Map<T, { width: number; contentWidth: number }>>(new Map());
|
|
125
110
|
const [tabContainerWidth, setTabContainerWidth] = useState(0);
|
|
111
|
+
const [layoutVersion, setLayoutVersion] = useState(0);
|
|
126
112
|
|
|
127
113
|
const itemPositionsMap = useMemo(() => {
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
return totalWidth;
|
|
135
|
-
}, 0);
|
|
114
|
+
// Build positions based on current render order
|
|
115
|
+
let accumulatedWidth = 0;
|
|
116
|
+
return tabNames.reduce((acc, name, index) => {
|
|
117
|
+
const itemData = tabItemPositions.current.get(name);
|
|
118
|
+
if (!itemData) return acc;
|
|
136
119
|
|
|
137
120
|
acc[index] =
|
|
138
121
|
variant === 'primary'
|
|
139
|
-
?
|
|
140
|
-
:
|
|
122
|
+
? accumulatedWidth + (itemData.width - itemData.contentWidth) / 2
|
|
123
|
+
: accumulatedWidth;
|
|
141
124
|
|
|
125
|
+
accumulatedWidth += itemData.width || 0;
|
|
142
126
|
return acc;
|
|
143
127
|
}, {} as Record<number, number>);
|
|
144
|
-
// to make useMemo in sync with the ref
|
|
145
128
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
146
|
-
}, [variant,
|
|
129
|
+
}, [variant, tabNames, layoutVersion]);
|
|
147
130
|
|
|
148
131
|
const itemWidthsMap = useMemo(() => {
|
|
149
|
-
return
|
|
150
|
-
|
|
132
|
+
return tabNames.reduce((acc, name, index) => {
|
|
133
|
+
const itemData = tabItemPositions.current.get(name);
|
|
134
|
+
if (!itemData) return acc;
|
|
151
135
|
|
|
136
|
+
acc[index] = variant === 'primary' ? itemData.contentWidth : itemData.width;
|
|
152
137
|
return acc;
|
|
153
138
|
}, {} as Record<number, number>);
|
|
154
|
-
// to make useMemo in sync with the ref
|
|
155
139
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
156
|
-
}, [variant,
|
|
140
|
+
}, [variant, tabNames, layoutVersion]);
|
|
157
141
|
|
|
158
142
|
const scrollHandler = useCallback(
|
|
159
143
|
(currValue: number) => {
|
|
160
|
-
if (tabItemPositions.current.
|
|
144
|
+
if (tabItemPositions.current.size > currValue) {
|
|
161
145
|
const itemStartPosition = currValue === 0 ? 0 : itemPositionsMap[currValue - 1];
|
|
162
146
|
const itemEndPosition = itemPositionsMap[currValue];
|
|
163
147
|
|
|
@@ -182,45 +166,76 @@ export const TabBase = ({
|
|
|
182
166
|
[itemPositionsMap, tabContainerWidth],
|
|
183
167
|
);
|
|
184
168
|
|
|
169
|
+
// Animate indicator position and width when value changes
|
|
170
|
+
useEffect(() => {
|
|
171
|
+
Animated.parallel([
|
|
172
|
+
Animated.timing(positionAnimationRef.current, {
|
|
173
|
+
toValue: valueIndex,
|
|
174
|
+
useNativeDriver: false,
|
|
175
|
+
duration: 170,
|
|
176
|
+
}),
|
|
177
|
+
Animated.timing(widthAnimationRef.current, {
|
|
178
|
+
toValue: valueIndex,
|
|
179
|
+
useNativeDriver: false,
|
|
180
|
+
duration: 170,
|
|
181
|
+
}),
|
|
182
|
+
]).start();
|
|
183
|
+
|
|
184
|
+
if (scrollable) {
|
|
185
|
+
requestAnimationFrame(() => scrollHandler(valueIndex));
|
|
186
|
+
}
|
|
187
|
+
}, [scrollHandler, valueIndex, scrollable]);
|
|
188
|
+
|
|
189
|
+
// Handle tab count changes
|
|
185
190
|
useEffect(() => {
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
+
const currentTabCount = tabNames.length;
|
|
192
|
+
|
|
193
|
+
if (currentTabCount !== previousTabCountRef.current) {
|
|
194
|
+
// Clean up positions for removed tabs
|
|
195
|
+
const currentTabNamesSet = new Set(tabNames);
|
|
196
|
+
tabItemPositions.current.forEach((_, name) => {
|
|
197
|
+
if (!currentTabNamesSet.has(name)) {
|
|
198
|
+
tabItemPositions.current.delete(name);
|
|
199
|
+
}
|
|
200
|
+
});
|
|
191
201
|
|
|
192
|
-
|
|
193
|
-
|
|
202
|
+
// Trigger re-calculation
|
|
203
|
+
setLayoutVersion(v => v + 1);
|
|
194
204
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
205
|
+
// Clamp animated values when tabs are removed
|
|
206
|
+
if (currentTabCount < previousTabCountRef.current) {
|
|
207
|
+
const maxValidIndex = Math.max(0, currentTabCount - 1);
|
|
208
|
+
positionAnimationRef.current.setValue(Math.min(valueIndex, maxValidIndex));
|
|
209
|
+
widthAnimationRef.current.setValue(Math.min(valueIndex, maxValidIndex));
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
previousTabCountRef.current = currentTabCount;
|
|
214
|
+
}, [tabNames, valueIndex]);
|
|
202
215
|
|
|
203
216
|
const onScrollHandler = useCallback((event: NativeSyntheticEvent<NativeScrollEvent>) => {
|
|
204
217
|
scrollViewPosition.current = event.nativeEvent.contentOffset.x;
|
|
205
218
|
}, []);
|
|
206
219
|
|
|
207
|
-
const transitionInterpolateWithMap = useCallback(
|
|
208
|
-
(obj
|
|
209
|
-
|
|
210
|
-
if (countItems < 2 || !tabItemPositions.current.length) {
|
|
211
|
-
// if there's only one item, use the value of that
|
|
212
|
-
return Object.values(obj)[0] || 0;
|
|
213
|
-
}
|
|
214
|
-
const inputRange = Array.from(Array(countItems).keys());
|
|
215
|
-
const outputRange = Object.values(obj);
|
|
220
|
+
const transitionInterpolateWithMap = useCallback((obj: Record<number, number>) => {
|
|
221
|
+
const entries = Object.entries(obj);
|
|
222
|
+
const countItems = entries.length;
|
|
216
223
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
+
if (countItems < 2 || !tabItemPositions.current.size) {
|
|
225
|
+
// If there's only one item or no layout data, use the first value
|
|
226
|
+
return Object.values(obj)[0] || 0;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// Use indices from the map entries to ensure inputRange matches outputRange
|
|
230
|
+
const inputRange = entries.map(([key]) => Number(key));
|
|
231
|
+
const outputRange = entries.map(([, val]) => val);
|
|
232
|
+
|
|
233
|
+
return positionAnimationRef.current.interpolate({
|
|
234
|
+
inputRange,
|
|
235
|
+
outputRange,
|
|
236
|
+
extrapolate: 'clamp',
|
|
237
|
+
});
|
|
238
|
+
}, []);
|
|
224
239
|
|
|
225
240
|
const indicatorTransitionInterpolate = useMemo(() => {
|
|
226
241
|
return transitionInterpolateWithMap(itemPositionsMap);
|
|
@@ -230,14 +245,12 @@ export const TabBase = ({
|
|
|
230
245
|
return transitionInterpolateWithMap(itemWidthsMap);
|
|
231
246
|
}, [transitionInterpolateWithMap, itemWidthsMap]);
|
|
232
247
|
|
|
233
|
-
const { containerStyle,
|
|
234
|
-
const { indicator, itemsContainer
|
|
248
|
+
const { containerStyle, indicatorStyle } = useMemo(() => {
|
|
249
|
+
const { indicator, itemsContainer } = tabsStyles;
|
|
235
250
|
const { activeColor, ...restStyle } = tabsStyles.root;
|
|
236
251
|
|
|
237
252
|
return {
|
|
238
|
-
containerStyle: [restStyle, style],
|
|
239
|
-
itemsContainerStyle: itemsContainer,
|
|
240
|
-
dividerStyle: [divider, dividerStyleProp],
|
|
253
|
+
containerStyle: [restStyle, itemsContainer, style],
|
|
241
254
|
indicatorStyle: [
|
|
242
255
|
indicator,
|
|
243
256
|
{
|
|
@@ -254,7 +267,6 @@ export const TabBase = ({
|
|
|
254
267
|
};
|
|
255
268
|
}, [
|
|
256
269
|
style,
|
|
257
|
-
dividerStyleProp,
|
|
258
270
|
activeColorProp,
|
|
259
271
|
indicatorTransitionInterpolate,
|
|
260
272
|
widthTransitionInterpolate,
|
|
@@ -268,7 +280,6 @@ export const TabBase = ({
|
|
|
268
280
|
ref: scrollViewRef,
|
|
269
281
|
onScroll: onScrollHandler,
|
|
270
282
|
showsHorizontalScrollIndicator: false,
|
|
271
|
-
style: itemsContainerStyle,
|
|
272
283
|
}
|
|
273
284
|
: {};
|
|
274
285
|
|
|
@@ -276,95 +287,88 @@ export const TabBase = ({
|
|
|
276
287
|
setTabContainerWidth(layout.width);
|
|
277
288
|
}, []);
|
|
278
289
|
|
|
279
|
-
const onLayoutItem = useCallback((event: LayoutChangeEvent,
|
|
290
|
+
const onLayoutItem = useCallback((event: LayoutChangeEvent, name: T) => {
|
|
280
291
|
const { width } = event.nativeEvent.layout;
|
|
281
292
|
|
|
282
|
-
const currentItemPosition = tabItemPositions.current
|
|
293
|
+
const currentItemPosition = tabItemPositions.current.get(name) || {
|
|
294
|
+
width: 0,
|
|
295
|
+
contentWidth: 0,
|
|
296
|
+
};
|
|
283
297
|
|
|
284
|
-
tabItemPositions.current
|
|
298
|
+
tabItemPositions.current.set(name, {
|
|
285
299
|
...currentItemPosition,
|
|
286
300
|
width: width,
|
|
287
|
-
};
|
|
301
|
+
});
|
|
302
|
+
setLayoutVersion(v => v + 1);
|
|
288
303
|
}, []);
|
|
289
304
|
|
|
290
|
-
const onLayoutText = useCallback((event: LayoutChangeEvent,
|
|
305
|
+
const onLayoutText = useCallback((event: LayoutChangeEvent, name: T) => {
|
|
291
306
|
const { width } = event.nativeEvent.layout;
|
|
292
307
|
|
|
293
|
-
const currentItemPosition = tabItemPositions.current
|
|
308
|
+
const currentItemPosition = tabItemPositions.current.get(name) || {
|
|
309
|
+
width: 0,
|
|
310
|
+
contentWidth: 0,
|
|
311
|
+
};
|
|
294
312
|
|
|
295
|
-
tabItemPositions.current
|
|
313
|
+
tabItemPositions.current.set(name, {
|
|
296
314
|
...currentItemPosition,
|
|
297
315
|
contentWidth: width,
|
|
298
|
-
};
|
|
316
|
+
});
|
|
317
|
+
setLayoutVersion(v => v + 1);
|
|
299
318
|
}, []);
|
|
300
319
|
|
|
301
320
|
return (
|
|
302
|
-
<
|
|
321
|
+
<Container
|
|
303
322
|
{...rest}
|
|
304
323
|
testID={testID}
|
|
324
|
+
{...containerProps}
|
|
305
325
|
style={containerStyle}
|
|
306
326
|
accessibilityRole="tablist"
|
|
307
327
|
onLayout={onLayout}>
|
|
308
|
-
|
|
309
|
-
<
|
|
310
|
-
|
|
311
|
-
{
|
|
312
|
-
|
|
313
|
-
{
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
{!disableIndicator && (
|
|
328
|
-
<Animated.View
|
|
329
|
-
testID={testID && `${testID}--active-indicator`}
|
|
330
|
-
{...indicatorProps}
|
|
331
|
-
style={indicatorStyle}
|
|
332
|
-
/>
|
|
333
|
-
)}
|
|
334
|
-
</Container>
|
|
335
|
-
|
|
336
|
-
<HorizontalDivider
|
|
337
|
-
testID={testID && `${testID}--divider`}
|
|
338
|
-
{...dividerProps}
|
|
339
|
-
style={dividerStyle}
|
|
328
|
+
{tabItems.map(child => (
|
|
329
|
+
<ChildItem
|
|
330
|
+
key={(child as ReactElement<TabItemProps<T>>).props?.name}
|
|
331
|
+
testID={testID && `${testID}--tab-item`}
|
|
332
|
+
value={value}
|
|
333
|
+
child={child as ReactElement<TabItemProps<T>>}
|
|
334
|
+
onChange={onChange}
|
|
335
|
+
onLayout={onLayoutItem}
|
|
336
|
+
onLayoutContent={onLayoutText}
|
|
337
|
+
variant={variant}
|
|
338
|
+
/>
|
|
339
|
+
))}
|
|
340
|
+
|
|
341
|
+
{!disableIndicator && (
|
|
342
|
+
<Animated.View
|
|
343
|
+
testID={testID && `${testID}--active-indicator`}
|
|
344
|
+
{...indicatorProps}
|
|
345
|
+
style={indicatorStyle}
|
|
340
346
|
/>
|
|
341
|
-
|
|
342
|
-
</
|
|
347
|
+
)}
|
|
348
|
+
</Container>
|
|
343
349
|
);
|
|
344
350
|
};
|
|
345
351
|
|
|
346
|
-
type ChildItemProps = {
|
|
347
|
-
variant: TabsProps['variant'];
|
|
348
|
-
child: ReactElement<TabItemProps
|
|
349
|
-
onChange: TabsProps['onChange'];
|
|
350
|
-
onLayout: (event: LayoutChangeEvent,
|
|
351
|
-
onLayoutContent: (event: LayoutChangeEvent,
|
|
352
|
-
value: string;
|
|
353
|
-
index: number;
|
|
352
|
+
type ChildItemProps<T extends string | number> = {
|
|
353
|
+
variant: TabsProps<T>['variant'];
|
|
354
|
+
child: ReactElement<TabItemProps<T>>;
|
|
355
|
+
onChange: TabsProps<T>['onChange'];
|
|
356
|
+
onLayout: (event: LayoutChangeEvent, name: T) => void;
|
|
357
|
+
onLayoutContent: (event: LayoutChangeEvent, name: T) => void;
|
|
358
|
+
value: string | number;
|
|
354
359
|
testID?: string;
|
|
355
360
|
};
|
|
356
361
|
|
|
357
|
-
const ChildItem =
|
|
358
|
-
({
|
|
362
|
+
const ChildItem = typedMemo(
|
|
363
|
+
<T extends string | number>({
|
|
359
364
|
value,
|
|
360
365
|
child,
|
|
361
366
|
onChange,
|
|
362
367
|
onLayout: onLayoutProp,
|
|
363
368
|
onLayoutContent: onLayoutContentProp,
|
|
364
369
|
variant,
|
|
365
|
-
index,
|
|
366
370
|
testID,
|
|
367
|
-
}: ChildItemProps) => {
|
|
371
|
+
}: ChildItemProps<T>) => {
|
|
368
372
|
const name = child.props?.name;
|
|
369
373
|
|
|
370
374
|
const onPress = useCallback(() => {
|
|
@@ -373,16 +377,16 @@ const ChildItem = memo(
|
|
|
373
377
|
|
|
374
378
|
const onLayout = useCallback(
|
|
375
379
|
(e: LayoutChangeEvent) => {
|
|
376
|
-
onLayoutProp(e,
|
|
380
|
+
onLayoutProp(e, name);
|
|
377
381
|
},
|
|
378
|
-
[
|
|
382
|
+
[name, onLayoutProp],
|
|
379
383
|
);
|
|
380
384
|
|
|
381
385
|
const onLayoutContent = useCallback(
|
|
382
386
|
(e: LayoutChangeEvent) => {
|
|
383
|
-
onLayoutContentProp(e,
|
|
387
|
+
onLayoutContentProp(e, name);
|
|
384
388
|
},
|
|
385
|
-
[
|
|
389
|
+
[name, onLayoutContentProp],
|
|
386
390
|
);
|
|
387
391
|
|
|
388
392
|
return cloneElement(child, {
|
|
@@ -396,4 +400,5 @@ const ChildItem = memo(
|
|
|
396
400
|
},
|
|
397
401
|
);
|
|
398
402
|
|
|
403
|
+
(ChildItem as ComponentType).displayName = 'Tabs_ChildItem';
|
|
399
404
|
TabBase.displayName = 'Tabs';
|
package/components/Tabs/utils.ts
CHANGED
|
@@ -1,10 +1,25 @@
|
|
|
1
|
+
import { createContext } from 'react';
|
|
1
2
|
import { StyleSheet } from 'react-native-unistyles';
|
|
2
3
|
|
|
3
4
|
import { getRegisteredComponentStylesWithFallback } from '../../core';
|
|
4
5
|
|
|
6
|
+
export type TabItemContextType = {
|
|
7
|
+
active: boolean;
|
|
8
|
+
hovered: boolean;
|
|
9
|
+
variant: 'primary' | 'secondary';
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export const TabItemContext = createContext<TabItemContextType>({
|
|
13
|
+
active: false,
|
|
14
|
+
hovered: false,
|
|
15
|
+
variant: 'primary',
|
|
16
|
+
});
|
|
17
|
+
|
|
5
18
|
const tabsStylesDefault = StyleSheet.create(theme => ({
|
|
6
19
|
root: {
|
|
7
20
|
activeColor: theme.colors.primary,
|
|
21
|
+
borderBottomWidth: 1,
|
|
22
|
+
borderBottomColor: theme.colors.outlineVariant,
|
|
8
23
|
} as any,
|
|
9
24
|
|
|
10
25
|
itemsContainer: {
|
|
@@ -30,8 +45,6 @@ const tabsStylesDefault = StyleSheet.create(theme => ({
|
|
|
30
45
|
},
|
|
31
46
|
},
|
|
32
47
|
},
|
|
33
|
-
|
|
34
|
-
divider: {},
|
|
35
48
|
}));
|
|
36
49
|
|
|
37
50
|
const tabsItemStylesDefault = StyleSheet.create(theme => ({
|