@fountain-ui/core 2.0.0-beta.13 → 2.0.0-beta.14
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/build/commonjs/Tab/Tab.js +9 -5
- package/build/commonjs/Tab/Tab.js.map +1 -1
- package/build/commonjs/Tabs/IndexAwareTab.js +28 -0
- package/build/commonjs/Tabs/IndexAwareTab.js.map +1 -0
- package/build/commonjs/Tabs/TabIndicator.js +18 -12
- package/build/commonjs/Tabs/TabIndicator.js.map +1 -1
- package/build/commonjs/Tabs/TabIndicatorProps.js.map +1 -1
- package/build/commonjs/Tabs/Tabs.js +41 -61
- package/build/commonjs/Tabs/Tabs.js.map +1 -1
- package/build/commonjs/Tabs/TabsProps.js.map +1 -1
- package/build/commonjs/Tabs/index.js.map +1 -1
- package/build/commonjs/Tabs/useScrollViewReaction.js +54 -0
- package/build/commonjs/Tabs/useScrollViewReaction.js.map +1 -0
- package/build/module/Tab/Tab.js +5 -5
- package/build/module/Tab/Tab.js.map +1 -1
- package/build/module/Tabs/IndexAwareTab.js +18 -0
- package/build/module/Tabs/IndexAwareTab.js.map +1 -0
- package/build/module/Tabs/TabIndicator.js +18 -13
- package/build/module/Tabs/TabIndicator.js.map +1 -1
- package/build/module/Tabs/TabIndicatorProps.js.map +1 -1
- package/build/module/Tabs/Tabs.js +40 -60
- package/build/module/Tabs/Tabs.js.map +1 -1
- package/build/module/Tabs/TabsProps.js.map +1 -1
- package/build/module/Tabs/index.js.map +1 -1
- package/build/module/Tabs/useScrollViewReaction.js +44 -0
- package/build/module/Tabs/useScrollViewReaction.js.map +1 -0
- package/build/typescript/Tabs/IndexAwareTab.d.ts +9 -0
- package/build/typescript/Tabs/TabIndicatorProps.d.ts +2 -2
- package/build/typescript/Tabs/Tabs.d.ts +4 -1
- package/build/typescript/Tabs/TabsProps.d.ts +19 -11
- package/build/typescript/Tabs/index.d.ts +1 -1
- package/build/typescript/Tabs/useScrollViewReaction.d.ts +9 -0
- package/package.json +2 -2
- package/src/Tab/Tab.tsx +5 -5
- package/src/Tabs/IndexAwareTab.tsx +30 -0
- package/src/Tabs/TabIndicator.tsx +17 -13
- package/src/Tabs/TabIndicatorProps.ts +2 -2
- package/src/Tabs/Tabs.tsx +47 -62
- package/src/Tabs/TabsProps.ts +22 -12
- package/src/Tabs/index.ts +1 -1
- package/src/Tabs/useScrollViewReaction.ts +55 -0
- package/build/commonjs/Tabs/useTabsWidth.js +0 -26
- package/build/commonjs/Tabs/useTabsWidth.js.map +0 -1
- package/build/module/Tabs/useTabsWidth.js +0 -18
- package/build/module/Tabs/useTabsWidth.js.map +0 -1
- package/build/typescript/Tabs/useTabsWidth.d.ts +0 -2
- package/src/Tabs/useTabsWidth.ts +0 -20
package/src/Tabs/Tabs.tsx
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
import React, { cloneElement,
|
|
2
|
-
import { GestureResponderEvent, LayoutChangeEvent
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
1
|
+
import React, { cloneElement, forwardRef, useImperativeHandle } from 'react';
|
|
2
|
+
import type { GestureResponderEvent, LayoutChangeEvent } from 'react-native';
|
|
3
|
+
import { ScrollView, View } from 'react-native';
|
|
4
|
+
import { useSharedValue } from 'react-native-reanimated';
|
|
5
5
|
import { NamedStylesStringUnion, UseStyles } from '@fountain-ui/styles';
|
|
6
6
|
import { css, useTheme } from '../styles';
|
|
7
7
|
import type TabsProps from './TabsProps';
|
|
8
|
+
import type { TabsInstance } from './TabsProps';
|
|
8
9
|
import TabIndicator from './TabIndicator';
|
|
9
|
-
import
|
|
10
|
+
import IndexAwareTab from './IndexAwareTab';
|
|
10
11
|
import useTabCoordinates from './useTabCoordinates';
|
|
12
|
+
import useScrollViewReaction from './useScrollViewReaction';
|
|
11
13
|
|
|
12
14
|
type TabsStyleKeys =
|
|
13
15
|
| 'root'
|
|
@@ -34,65 +36,43 @@ const useStyles: UseStyles<TabsStyles> = function (): TabsStyles {
|
|
|
34
36
|
};
|
|
35
37
|
};
|
|
36
38
|
|
|
37
|
-
const
|
|
38
|
-
duration: 200,
|
|
39
|
-
easing: Easing.out(Easing.exp),
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
export default function Tabs(props: TabsProps) {
|
|
39
|
+
const Tabs = forwardRef<TabsInstance, TabsProps>(function Tabs(props, ref) {
|
|
43
40
|
const {
|
|
44
41
|
children,
|
|
45
|
-
|
|
42
|
+
initialIndex = 0,
|
|
46
43
|
disableIndicator = false,
|
|
47
44
|
keyboardDismissMode = 'none',
|
|
48
45
|
keyboardShouldPersistTaps = 'never',
|
|
49
46
|
onChange,
|
|
50
47
|
scrollable = false,
|
|
51
|
-
scrollValue: scrollValueProp,
|
|
52
48
|
style,
|
|
53
49
|
variant = 'primary',
|
|
54
|
-
...otherProps
|
|
55
50
|
} = props;
|
|
56
51
|
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
const [containerWidth, handleLayout] = useTabsWidth();
|
|
60
|
-
|
|
61
|
-
const scrollViewRef = useRef<ScrollView | null>(null);
|
|
52
|
+
const sharedIndex = useSharedValue<number>(initialIndex);
|
|
62
53
|
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
const internalScrollValue = useSharedValue(0);
|
|
66
|
-
const scrollValue = scrollValueProp ?? internalScrollValue;
|
|
67
|
-
|
|
68
|
-
const isReadyToRenderIndicator = coordinates.length > 0;
|
|
69
|
-
|
|
70
|
-
useEffect(() => {
|
|
71
|
-
const animateTab = (index: number) => {
|
|
72
|
-
scrollValue.value = withTiming(index, ANIMATION_CONFIG);
|
|
73
|
-
};
|
|
54
|
+
const getCurrentIndex = (): number => sharedIndex.value;
|
|
74
55
|
|
|
75
|
-
|
|
76
|
-
|
|
56
|
+
const setTab = (newIndex: number) => {
|
|
57
|
+
sharedIndex.value = newIndex;
|
|
58
|
+
};
|
|
77
59
|
|
|
78
|
-
|
|
79
|
-
|
|
60
|
+
useImperativeHandle(
|
|
61
|
+
ref,
|
|
62
|
+
() => ({
|
|
63
|
+
getCurrentIndex,
|
|
64
|
+
setTab,
|
|
65
|
+
}),
|
|
66
|
+
[sharedIndex],
|
|
67
|
+
);
|
|
80
68
|
|
|
81
|
-
|
|
82
|
-
const tabWidth = coordinate.x2 - coordinate.x1;
|
|
83
|
-
return Math.floor(coordinate.x1 + tabWidth / 2);
|
|
84
|
-
}
|
|
69
|
+
const styles = useStyles();
|
|
85
70
|
|
|
86
|
-
|
|
87
|
-
}, [indexProp, coordinates]);
|
|
71
|
+
const { coordinates, updateCoordinate } = useTabCoordinates(children);
|
|
88
72
|
|
|
89
|
-
|
|
90
|
-
const scrollView = scrollViewRef.current;
|
|
73
|
+
const { scrollViewRef, onLayout } = useScrollViewReaction(sharedIndex, coordinates);
|
|
91
74
|
|
|
92
|
-
|
|
93
|
-
scrollView.scrollTo({ x: scrollPosition, y: 0, animated: true });
|
|
94
|
-
}
|
|
95
|
-
}, [scrollPosition, containerWidth]);
|
|
75
|
+
const isReadyToRenderIndicator = coordinates.length > 0;
|
|
96
76
|
|
|
97
77
|
const tabElements = React.Children.map(children, (child, index) => {
|
|
98
78
|
const onLayout = (event: LayoutChangeEvent) => {
|
|
@@ -108,46 +88,49 @@ export default function Tabs(props: TabsProps) {
|
|
|
108
88
|
};
|
|
109
89
|
|
|
110
90
|
const onPress = () => {
|
|
91
|
+
setTab(index);
|
|
92
|
+
|
|
111
93
|
onChange?.(index);
|
|
112
94
|
// @ts-ignore
|
|
113
95
|
child.props.onPress?.();
|
|
114
96
|
};
|
|
115
97
|
|
|
116
|
-
|
|
117
|
-
const
|
|
118
|
-
|
|
119
|
-
: (isReadyToRenderIndicator ? false : selected);
|
|
120
|
-
|
|
121
|
-
//@ts-ignore
|
|
122
|
-
return cloneElement(child, {
|
|
123
|
-
enableIndicator: enableIndicatorPlaceholder,
|
|
98
|
+
// @ts-ignore
|
|
99
|
+
const tabElement = cloneElement(child, {
|
|
100
|
+
enableIndicator: !disableIndicator && isReadyToRenderIndicator,
|
|
124
101
|
onLayout,
|
|
125
102
|
onPress,
|
|
126
103
|
onMouseDown,
|
|
127
104
|
variant,
|
|
128
|
-
selected,
|
|
129
105
|
style: scrollable ? undefined : styles.fixedTab,
|
|
130
106
|
});
|
|
107
|
+
|
|
108
|
+
return (
|
|
109
|
+
<IndexAwareTab
|
|
110
|
+
children={tabElement}
|
|
111
|
+
index={index}
|
|
112
|
+
sharedIndex={sharedIndex}
|
|
113
|
+
/>
|
|
114
|
+
);
|
|
131
115
|
});
|
|
132
116
|
|
|
133
|
-
const
|
|
117
|
+
const tabIndicator = (
|
|
134
118
|
<TabIndicator
|
|
135
119
|
coordinates={coordinates}
|
|
136
120
|
disabled={disableIndicator}
|
|
137
121
|
scrollable={scrollable}
|
|
138
|
-
|
|
122
|
+
sharedIndex={sharedIndex}
|
|
139
123
|
/>
|
|
140
124
|
);
|
|
141
125
|
|
|
142
126
|
return (
|
|
143
127
|
<View
|
|
144
|
-
onLayout={
|
|
128
|
+
onLayout={onLayout}
|
|
145
129
|
style={css([
|
|
146
130
|
styles.root,
|
|
147
131
|
scrollable ? undefined : styles.fixedRoot,
|
|
148
132
|
style,
|
|
149
133
|
])}
|
|
150
|
-
{...otherProps}
|
|
151
134
|
>
|
|
152
135
|
{scrollable ? (
|
|
153
136
|
<ScrollView
|
|
@@ -164,14 +147,16 @@ export default function Tabs(props: TabsProps) {
|
|
|
164
147
|
keyboardShouldPersistTaps={keyboardShouldPersistTaps}
|
|
165
148
|
>
|
|
166
149
|
{tabElements}
|
|
167
|
-
{
|
|
150
|
+
{tabIndicator}
|
|
168
151
|
</ScrollView>
|
|
169
152
|
) : (
|
|
170
153
|
<React.Fragment>
|
|
171
154
|
{tabElements}
|
|
172
|
-
{
|
|
155
|
+
{tabIndicator}
|
|
173
156
|
</React.Fragment>
|
|
174
157
|
)}
|
|
175
158
|
</View>
|
|
176
159
|
);
|
|
177
|
-
};
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
export default Tabs;
|
package/src/Tabs/TabsProps.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import type { ReactNode, Ref } from 'react';
|
|
2
2
|
import type { ViewProps } from 'react-native';
|
|
3
|
-
import Animated from 'react-native-reanimated';
|
|
4
3
|
import type { TabVariant } from '../Tab';
|
|
5
4
|
import type { OverridableComponentProps } from '../types';
|
|
6
5
|
|
|
@@ -15,16 +14,26 @@ export type KeyboardShouldPersistTaps =
|
|
|
15
14
|
| 'always'
|
|
16
15
|
| 'handled'; // app only
|
|
17
16
|
|
|
18
|
-
export
|
|
17
|
+
export interface TabsInstance {
|
|
19
18
|
/**
|
|
20
|
-
*
|
|
19
|
+
* Get current tab index.
|
|
21
20
|
*/
|
|
22
|
-
|
|
21
|
+
getCurrentIndex: () => number;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Function to scroll to a specific tab. Invalid index is ignored.
|
|
25
|
+
* @param index
|
|
26
|
+
*/
|
|
27
|
+
setTab: (index: number) => void;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export default interface TabsProps extends OverridableComponentProps<ViewProps, {
|
|
31
|
+
ref?: Ref<TabsInstance>;
|
|
23
32
|
|
|
24
33
|
/**
|
|
25
|
-
*
|
|
34
|
+
* Collection of Tab components.
|
|
26
35
|
*/
|
|
27
|
-
|
|
36
|
+
children: ReactNode;
|
|
28
37
|
|
|
29
38
|
/**
|
|
30
39
|
* If `true`, the indicator is disabled.
|
|
@@ -32,6 +41,12 @@ export default interface TabsProps extends OverridableComponentProps<ViewProps,
|
|
|
32
41
|
*/
|
|
33
42
|
disableIndicator?: boolean;
|
|
34
43
|
|
|
44
|
+
/**
|
|
45
|
+
* Index of initial tab that should be selected.
|
|
46
|
+
* @default 0
|
|
47
|
+
*/
|
|
48
|
+
initialIndex?: number;
|
|
49
|
+
|
|
35
50
|
/**
|
|
36
51
|
* keyboard dismissing condition of dragging.
|
|
37
52
|
* @default 'none'
|
|
@@ -55,11 +70,6 @@ export default interface TabsProps extends OverridableComponentProps<ViewProps,
|
|
|
55
70
|
*/
|
|
56
71
|
scrollable?: boolean;
|
|
57
72
|
|
|
58
|
-
/**
|
|
59
|
-
* Scrollable value for using animated interpolation.
|
|
60
|
-
*/
|
|
61
|
-
scrollValue?: Animated.SharedValue<number>;
|
|
62
|
-
|
|
63
73
|
/**
|
|
64
74
|
* The variant to use.
|
|
65
75
|
* @default 'primary'
|
package/src/Tabs/index.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { default } from './Tabs';
|
|
2
|
-
export type { default as TabsProps } from './TabsProps';
|
|
2
|
+
export type { default as TabsProps, TabsInstance } from './TabsProps';
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { MutableRefObject } from 'react';
|
|
2
|
+
import { useCallback, useRef } from 'react';
|
|
3
|
+
import type { ScrollView, ViewProps } from 'react-native';
|
|
4
|
+
import { runOnJS, SharedValue, useAnimatedReaction } from 'react-native-reanimated';
|
|
5
|
+
import type TabCoordinate from './TabCoordinate';
|
|
6
|
+
|
|
7
|
+
export interface UseScrollViewReaction {
|
|
8
|
+
scrollViewRef: MutableRefObject<ScrollView | null>;
|
|
9
|
+
onLayout: ViewProps['onLayout'];
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export default function useScrollViewReaction(
|
|
13
|
+
sharedIndex: SharedValue<number>,
|
|
14
|
+
coordinates: TabCoordinate[],
|
|
15
|
+
): UseScrollViewReaction {
|
|
16
|
+
const scrollViewRef = useRef<ScrollView | null>(null);
|
|
17
|
+
|
|
18
|
+
const lastScrolledPositionRef = useRef<number>(NaN);
|
|
19
|
+
|
|
20
|
+
const scrollTo = (scrollPosition: number) => {
|
|
21
|
+
const scrollView = scrollViewRef.current;
|
|
22
|
+
|
|
23
|
+
if (scrollView && Number.isFinite(scrollPosition)) {
|
|
24
|
+
scrollView.scrollTo({ x: scrollPosition, y: 0, animated: true });
|
|
25
|
+
|
|
26
|
+
lastScrolledPositionRef.current = scrollPosition;
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const onLayout = useCallback(() => {
|
|
31
|
+
scrollTo(lastScrolledPositionRef.current);
|
|
32
|
+
}, []);
|
|
33
|
+
|
|
34
|
+
useAnimatedReaction(
|
|
35
|
+
() => {
|
|
36
|
+
const prevIndex = sharedIndex.value - 1;
|
|
37
|
+
const prevCoordinate = coordinates[prevIndex];
|
|
38
|
+
|
|
39
|
+
if (prevCoordinate) {
|
|
40
|
+
const prevTabWidth = prevCoordinate.x2 - prevCoordinate.x1;
|
|
41
|
+
return Math.floor(prevCoordinate.x1 + prevTabWidth / 2);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return 0;
|
|
45
|
+
},
|
|
46
|
+
(scrollPosition, prevScrollPosition) => {
|
|
47
|
+
if (scrollPosition !== prevScrollPosition) {
|
|
48
|
+
runOnJS(scrollTo)(scrollPosition);
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
[coordinates],
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
return { scrollViewRef, onLayout };
|
|
55
|
+
};
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.default = useTabsWidth;
|
|
7
|
-
|
|
8
|
-
var _react = require("react");
|
|
9
|
-
|
|
10
|
-
var _reactNative = require("react-native");
|
|
11
|
-
|
|
12
|
-
const assumeInitialWidth = () => _reactNative.Dimensions.get('window').width;
|
|
13
|
-
|
|
14
|
-
const isIntegerPartEquals = (a, b) => Math.round(a) === Math.round(b);
|
|
15
|
-
|
|
16
|
-
const isIntegerPartDifferent = (a, b) => !isIntegerPartEquals(a, b);
|
|
17
|
-
|
|
18
|
-
function useTabsWidth() {
|
|
19
|
-
const [width, setWidth] = (0, _react.useState)(assumeInitialWidth);
|
|
20
|
-
const onLayout = (0, _react.useCallback)(e => {
|
|
21
|
-
const newWidth = e.nativeEvent.layout.width;
|
|
22
|
-
setWidth(prevWidth => isIntegerPartDifferent(prevWidth, newWidth) ? newWidth : prevWidth);
|
|
23
|
-
}, []);
|
|
24
|
-
return [width, onLayout];
|
|
25
|
-
}
|
|
26
|
-
//# sourceMappingURL=useTabsWidth.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["assumeInitialWidth","Dimensions","get","width","isIntegerPartEquals","a","b","Math","round","isIntegerPartDifferent","useTabsWidth","setWidth","useState","onLayout","useCallback","e","newWidth","nativeEvent","layout","prevWidth"],"sources":["useTabsWidth.ts"],"sourcesContent":["import { useCallback, useState } from 'react';\nimport { Dimensions, LayoutChangeEvent, ViewProps } from 'react-native';\n\nconst assumeInitialWidth = (): number => Dimensions.get('window').width;\n\nconst isIntegerPartEquals = (a: number, b: number) => Math.round(a) === Math.round(b);\n\nconst isIntegerPartDifferent = (a: number, b: number) => !isIntegerPartEquals(a, b);\n\nexport default function useTabsWidth(): [number, ViewProps['onLayout']] {\n const [width, setWidth] = useState(assumeInitialWidth);\n\n const onLayout = useCallback((e: LayoutChangeEvent) => {\n const newWidth = e.nativeEvent.layout.width;\n\n setWidth((prevWidth) => isIntegerPartDifferent(prevWidth, newWidth) ? newWidth : prevWidth);\n }, []);\n\n return [width, onLayout];\n}\n"],"mappings":";;;;;;;AAAA;;AACA;;AAEA,MAAMA,kBAAkB,GAAG,MAAcC,uBAAA,CAAWC,GAAX,CAAe,QAAf,EAAyBC,KAAlE;;AAEA,MAAMC,mBAAmB,GAAG,CAACC,CAAD,EAAYC,CAAZ,KAA0BC,IAAI,CAACC,KAAL,CAAWH,CAAX,MAAkBE,IAAI,CAACC,KAAL,CAAWF,CAAX,CAAxE;;AAEA,MAAMG,sBAAsB,GAAG,CAACJ,CAAD,EAAYC,CAAZ,KAA0B,CAACF,mBAAmB,CAACC,CAAD,EAAIC,CAAJ,CAA7E;;AAEe,SAASI,YAAT,GAAyD;EACpE,MAAM,CAACP,KAAD,EAAQQ,QAAR,IAAoB,IAAAC,eAAA,EAASZ,kBAAT,CAA1B;EAEA,MAAMa,QAAQ,GAAG,IAAAC,kBAAA,EAAaC,CAAD,IAA0B;IACnD,MAAMC,QAAQ,GAAGD,CAAC,CAACE,WAAF,CAAcC,MAAd,CAAqBf,KAAtC;IAEAQ,QAAQ,CAAEQ,SAAD,IAAeV,sBAAsB,CAACU,SAAD,EAAYH,QAAZ,CAAtB,GAA8CA,QAA9C,GAAyDG,SAAzE,CAAR;EACH,CAJgB,EAId,EAJc,CAAjB;EAMA,OAAO,CAAChB,KAAD,EAAQU,QAAR,CAAP;AACH"}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { useCallback, useState } from 'react';
|
|
2
|
-
import { Dimensions } from 'react-native';
|
|
3
|
-
|
|
4
|
-
const assumeInitialWidth = () => Dimensions.get('window').width;
|
|
5
|
-
|
|
6
|
-
const isIntegerPartEquals = (a, b) => Math.round(a) === Math.round(b);
|
|
7
|
-
|
|
8
|
-
const isIntegerPartDifferent = (a, b) => !isIntegerPartEquals(a, b);
|
|
9
|
-
|
|
10
|
-
export default function useTabsWidth() {
|
|
11
|
-
const [width, setWidth] = useState(assumeInitialWidth);
|
|
12
|
-
const onLayout = useCallback(e => {
|
|
13
|
-
const newWidth = e.nativeEvent.layout.width;
|
|
14
|
-
setWidth(prevWidth => isIntegerPartDifferent(prevWidth, newWidth) ? newWidth : prevWidth);
|
|
15
|
-
}, []);
|
|
16
|
-
return [width, onLayout];
|
|
17
|
-
}
|
|
18
|
-
//# sourceMappingURL=useTabsWidth.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["useCallback","useState","Dimensions","assumeInitialWidth","get","width","isIntegerPartEquals","a","b","Math","round","isIntegerPartDifferent","useTabsWidth","setWidth","onLayout","e","newWidth","nativeEvent","layout","prevWidth"],"sources":["useTabsWidth.ts"],"sourcesContent":["import { useCallback, useState } from 'react';\nimport { Dimensions, LayoutChangeEvent, ViewProps } from 'react-native';\n\nconst assumeInitialWidth = (): number => Dimensions.get('window').width;\n\nconst isIntegerPartEquals = (a: number, b: number) => Math.round(a) === Math.round(b);\n\nconst isIntegerPartDifferent = (a: number, b: number) => !isIntegerPartEquals(a, b);\n\nexport default function useTabsWidth(): [number, ViewProps['onLayout']] {\n const [width, setWidth] = useState(assumeInitialWidth);\n\n const onLayout = useCallback((e: LayoutChangeEvent) => {\n const newWidth = e.nativeEvent.layout.width;\n\n setWidth((prevWidth) => isIntegerPartDifferent(prevWidth, newWidth) ? newWidth : prevWidth);\n }, []);\n\n return [width, onLayout];\n}\n"],"mappings":"AAAA,SAASA,WAAT,EAAsBC,QAAtB,QAAsC,OAAtC;AACA,SAASC,UAAT,QAAyD,cAAzD;;AAEA,MAAMC,kBAAkB,GAAG,MAAcD,UAAU,CAACE,GAAX,CAAe,QAAf,EAAyBC,KAAlE;;AAEA,MAAMC,mBAAmB,GAAG,CAACC,CAAD,EAAYC,CAAZ,KAA0BC,IAAI,CAACC,KAAL,CAAWH,CAAX,MAAkBE,IAAI,CAACC,KAAL,CAAWF,CAAX,CAAxE;;AAEA,MAAMG,sBAAsB,GAAG,CAACJ,CAAD,EAAYC,CAAZ,KAA0B,CAACF,mBAAmB,CAACC,CAAD,EAAIC,CAAJ,CAA7E;;AAEA,eAAe,SAASI,YAAT,GAAyD;EACpE,MAAM,CAACP,KAAD,EAAQQ,QAAR,IAAoBZ,QAAQ,CAACE,kBAAD,CAAlC;EAEA,MAAMW,QAAQ,GAAGd,WAAW,CAAEe,CAAD,IAA0B;IACnD,MAAMC,QAAQ,GAAGD,CAAC,CAACE,WAAF,CAAcC,MAAd,CAAqBb,KAAtC;IAEAQ,QAAQ,CAAEM,SAAD,IAAeR,sBAAsB,CAACQ,SAAD,EAAYH,QAAZ,CAAtB,GAA8CA,QAA9C,GAAyDG,SAAzE,CAAR;EACH,CAJ2B,EAIzB,EAJyB,CAA5B;EAMA,OAAO,CAACd,KAAD,EAAQS,QAAR,CAAP;AACH"}
|
package/src/Tabs/useTabsWidth.ts
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { useCallback, useState } from 'react';
|
|
2
|
-
import { Dimensions, LayoutChangeEvent, ViewProps } from 'react-native';
|
|
3
|
-
|
|
4
|
-
const assumeInitialWidth = (): number => Dimensions.get('window').width;
|
|
5
|
-
|
|
6
|
-
const isIntegerPartEquals = (a: number, b: number) => Math.round(a) === Math.round(b);
|
|
7
|
-
|
|
8
|
-
const isIntegerPartDifferent = (a: number, b: number) => !isIntegerPartEquals(a, b);
|
|
9
|
-
|
|
10
|
-
export default function useTabsWidth(): [number, ViewProps['onLayout']] {
|
|
11
|
-
const [width, setWidth] = useState(assumeInitialWidth);
|
|
12
|
-
|
|
13
|
-
const onLayout = useCallback((e: LayoutChangeEvent) => {
|
|
14
|
-
const newWidth = e.nativeEvent.layout.width;
|
|
15
|
-
|
|
16
|
-
setWidth((prevWidth) => isIntegerPartDifferent(prevWidth, newWidth) ? newWidth : prevWidth);
|
|
17
|
-
}, []);
|
|
18
|
-
|
|
19
|
-
return [width, onLayout];
|
|
20
|
-
}
|