@fountain-ui/core 2.0.0-beta.10 → 2.0.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/build/commonjs/Tabs/TabIndicator.js +1 -5
- package/build/commonjs/Tabs/TabIndicator.js.map +1 -1
- package/build/commonjs/Tabs/Tabs.js +46 -48
- package/build/commonjs/Tabs/Tabs.js.map +1 -1
- package/build/commonjs/Tabs/useTabCoordinates.js +44 -0
- package/build/commonjs/Tabs/useTabCoordinates.js.map +1 -0
- package/build/commonjs/Tabs/useTabsWidth.js +26 -0
- package/build/commonjs/Tabs/useTabsWidth.js.map +1 -0
- package/build/commonjs/hooks/useCollapsibleAppBar.js +31 -15
- package/build/commonjs/hooks/useCollapsibleAppBar.js.map +1 -1
- package/build/commonjs/hooks/useFadeInAppBar.js +26 -8
- package/build/commonjs/hooks/useFadeInAppBar.js.map +1 -1
- package/build/commonjs/internal/hooks/index.js +0 -8
- package/build/commonjs/internal/hooks/index.js.map +1 -1
- package/build/module/Tabs/TabIndicator.js +2 -6
- package/build/module/Tabs/TabIndicator.js.map +1 -1
- package/build/module/Tabs/Tabs.js +39 -39
- package/build/module/Tabs/Tabs.js.map +1 -1
- package/build/module/Tabs/useTabCoordinates.js +30 -0
- package/build/module/Tabs/useTabCoordinates.js.map +1 -0
- package/build/module/Tabs/useTabsWidth.js +18 -0
- package/build/module/Tabs/useTabsWidth.js.map +1 -0
- package/build/module/hooks/useCollapsibleAppBar.js +31 -15
- package/build/module/hooks/useCollapsibleAppBar.js.map +1 -1
- package/build/module/hooks/useFadeInAppBar.js +26 -8
- package/build/module/hooks/useFadeInAppBar.js.map +1 -1
- package/build/module/internal/hooks/index.js +0 -1
- package/build/module/internal/hooks/index.js.map +1 -1
- package/build/typescript/Tabs/useTabCoordinates.d.ts +7 -0
- package/build/typescript/Tabs/useTabsWidth.d.ts +2 -0
- package/build/typescript/internal/hooks/index.d.ts +0 -1
- package/package.json +2 -2
- package/src/Tabs/TabIndicator.tsx +3 -7
- package/src/Tabs/Tabs.tsx +37 -39
- package/src/Tabs/useTabCoordinates.ts +36 -0
- package/src/Tabs/useTabsWidth.ts +20 -0
- package/src/hooks/useCollapsibleAppBar.ts +22 -11
- package/src/hooks/useFadeInAppBar.ts +23 -8
- package/src/internal/hooks/index.ts +0 -1
- package/build/commonjs/internal/hooks/useWidth.js +0 -29
- package/build/commonjs/internal/hooks/useWidth.js.map +0 -1
- package/build/module/internal/hooks/useWidth.js +0 -15
- package/build/module/internal/hooks/useWidth.js.map +0 -1
- package/build/typescript/internal/hooks/useWidth.d.ts +0 -2
- package/src/internal/hooks/useWidth.ts +0 -17
package/src/Tabs/Tabs.tsx
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { cloneElement, useEffect, useMemo, useRef } from 'react';
|
|
2
2
|
import { GestureResponderEvent, LayoutChangeEvent, ScrollView, View } from 'react-native';
|
|
3
|
+
import type { WithTimingConfig } from 'react-native-reanimated';
|
|
3
4
|
import { Easing, useSharedValue, withTiming } from 'react-native-reanimated';
|
|
4
5
|
import { NamedStylesStringUnion, UseStyles } from '@fountain-ui/styles';
|
|
5
|
-
import { isEveryDefined } from '@fountain-ui/utils';
|
|
6
6
|
import { css, useTheme } from '../styles';
|
|
7
|
-
import { useWidth } from '../internal/hooks';
|
|
8
7
|
import type TabsProps from './TabsProps';
|
|
9
|
-
import TabCoordinate, { defaultCoordinate } from './TabCoordinate';
|
|
10
8
|
import TabIndicator from './TabIndicator';
|
|
9
|
+
import useTabsWidth from './useTabsWidth';
|
|
10
|
+
import useTabCoordinates from './useTabCoordinates';
|
|
11
11
|
|
|
12
12
|
type TabsStyleKeys =
|
|
13
13
|
| 'root'
|
|
@@ -34,6 +34,11 @@ const useStyles: UseStyles<TabsStyles> = function (): TabsStyles {
|
|
|
34
34
|
};
|
|
35
35
|
};
|
|
36
36
|
|
|
37
|
+
const ANIMATION_CONFIG: Readonly<WithTimingConfig> = {
|
|
38
|
+
duration: 200,
|
|
39
|
+
easing: Easing.out(Easing.exp),
|
|
40
|
+
};
|
|
41
|
+
|
|
37
42
|
export default function Tabs(props: TabsProps) {
|
|
38
43
|
const {
|
|
39
44
|
children,
|
|
@@ -51,56 +56,49 @@ export default function Tabs(props: TabsProps) {
|
|
|
51
56
|
|
|
52
57
|
const styles = useStyles();
|
|
53
58
|
|
|
54
|
-
const [containerWidth, handleLayout] =
|
|
59
|
+
const [containerWidth, handleLayout] = useTabsWidth();
|
|
55
60
|
|
|
56
|
-
const scrollViewRef =
|
|
61
|
+
const scrollViewRef = useRef<ScrollView | null>(null);
|
|
57
62
|
|
|
58
|
-
const
|
|
59
|
-
const [coordinates, setCoordinates] = React.useState<TabCoordinate[]>(() => new Array(tabCount));
|
|
63
|
+
const { coordinates, updateCoordinate } = useTabCoordinates(children);
|
|
60
64
|
|
|
61
65
|
const internalScrollValue = useSharedValue(0);
|
|
62
|
-
const scrollValue = scrollValueProp
|
|
66
|
+
const scrollValue = scrollValueProp ?? internalScrollValue;
|
|
63
67
|
|
|
64
|
-
const isReadyToRenderIndicator =
|
|
68
|
+
const isReadyToRenderIndicator = coordinates.length > 0;
|
|
65
69
|
|
|
66
|
-
|
|
70
|
+
useEffect(() => {
|
|
67
71
|
const animateTab = (index: number) => {
|
|
68
|
-
|
|
69
|
-
duration: 200,
|
|
70
|
-
easing: Easing.out(Easing.exp),
|
|
71
|
-
});
|
|
72
|
+
scrollValue.value = withTiming(index, ANIMATION_CONFIG);
|
|
72
73
|
};
|
|
73
74
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
75
|
+
animateTab(indexProp);
|
|
76
|
+
}, [indexProp, scrollValue]);
|
|
77
|
+
|
|
78
|
+
const scrollPosition = useMemo<number>(() => {
|
|
79
|
+
const coordinate = coordinates[indexProp - 1];
|
|
78
80
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
81
|
+
if (coordinate) {
|
|
82
|
+
const tabWidth = coordinate.x2 - coordinate.x1;
|
|
83
|
+
return Math.floor(coordinate.x1 + tabWidth / 2);
|
|
84
|
+
}
|
|
83
85
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
const x = coordinate.x1 + tabWidth / 2;
|
|
86
|
+
return 0;
|
|
87
|
+
}, [indexProp, coordinates]);
|
|
87
88
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
};
|
|
89
|
+
useEffect(() => {
|
|
90
|
+
const scrollView = scrollViewRef.current;
|
|
91
91
|
|
|
92
|
-
|
|
93
|
-
|
|
92
|
+
if (scrollView && scrollPosition > 0) {
|
|
93
|
+
scrollView.scrollTo({ x: scrollPosition, y: 0, animated: true });
|
|
94
|
+
}
|
|
95
|
+
}, [scrollPosition, containerWidth]);
|
|
94
96
|
|
|
95
97
|
const tabElements = React.Children.map(children, (child, index) => {
|
|
96
98
|
const onLayout = (event: LayoutChangeEvent) => {
|
|
97
99
|
const { x, width } = event.nativeEvent.layout;
|
|
98
100
|
|
|
99
|
-
|
|
100
|
-
...prev.slice(0, index),
|
|
101
|
-
{ x1: x, x2: x + width },
|
|
102
|
-
...prev.slice(index + 1),
|
|
103
|
-
]));
|
|
101
|
+
updateCoordinate(index, x, width);
|
|
104
102
|
};
|
|
105
103
|
|
|
106
104
|
const onMouseDown = (e: GestureResponderEvent) => {
|
|
@@ -121,7 +119,7 @@ export default function Tabs(props: TabsProps) {
|
|
|
121
119
|
: (isReadyToRenderIndicator ? false : selected);
|
|
122
120
|
|
|
123
121
|
//@ts-ignore
|
|
124
|
-
return
|
|
122
|
+
return cloneElement(child, {
|
|
125
123
|
enableIndicator: enableIndicatorPlaceholder,
|
|
126
124
|
onLayout,
|
|
127
125
|
onPress,
|
|
@@ -169,10 +167,10 @@ export default function Tabs(props: TabsProps) {
|
|
|
169
167
|
{indicator}
|
|
170
168
|
</ScrollView>
|
|
171
169
|
) : (
|
|
172
|
-
|
|
170
|
+
<React.Fragment>
|
|
173
171
|
{tabElements}
|
|
174
172
|
{indicator}
|
|
175
|
-
|
|
173
|
+
</React.Fragment>
|
|
176
174
|
)}
|
|
177
175
|
</View>
|
|
178
176
|
);
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import React, { useRef, useState } from 'react';
|
|
2
|
+
import { isEveryDefined } from '@fountain-ui/utils';
|
|
3
|
+
import TabCoordinate from './TabCoordinate';
|
|
4
|
+
|
|
5
|
+
export interface UseTabCoordinates {
|
|
6
|
+
coordinates: TabCoordinate[];
|
|
7
|
+
updateCoordinate: (index: number, x: number, width: number) => void;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export default function useTabCoordinates(tabElements: React.ReactNode): UseTabCoordinates {
|
|
11
|
+
const incompleteCoordinatesRef = useRef<TabCoordinate[]>([]);
|
|
12
|
+
|
|
13
|
+
const [completeCoordinates, setCompleteCoordinates] = useState<TabCoordinate[]>([]);
|
|
14
|
+
|
|
15
|
+
const isAllCoordinatesDefined = (coordinates: TabCoordinate[]): boolean => {
|
|
16
|
+
const numberOfTab = React.Children.count(tabElements);
|
|
17
|
+
const numberOfCoordinates = coordinates.length;
|
|
18
|
+
|
|
19
|
+
const everyCoordinatesDefined = isEveryDefined(coordinates);
|
|
20
|
+
|
|
21
|
+
return numberOfTab === numberOfCoordinates && everyCoordinatesDefined;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const updateCoordinate = (index: number, x: number, width: number) => {
|
|
25
|
+
incompleteCoordinatesRef.current[index] = { x1: x, x2: x + width };
|
|
26
|
+
|
|
27
|
+
if (isAllCoordinatesDefined(incompleteCoordinatesRef.current)) {
|
|
28
|
+
setCompleteCoordinates(incompleteCoordinatesRef.current);
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
return {
|
|
33
|
+
coordinates: completeCoordinates,
|
|
34
|
+
updateCoordinate,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
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
|
+
}
|
|
@@ -71,17 +71,28 @@ export default function useCollapsibleAppBar(userOptions: Options = defaultOptio
|
|
|
71
71
|
|
|
72
72
|
const elevationStyle = useElevationStyle(4);
|
|
73
73
|
const animatedStyle = useAnimatedStyle(() => {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
74
|
+
if (Platform.OS === 'web') {
|
|
75
|
+
return {
|
|
76
|
+
transform: [{ translateY: translateY.value }],
|
|
77
|
+
boxShadow: overlapped.value ? elevationStyle?.boxShadow : 0,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
if (Platform.OS === 'android') {
|
|
81
|
+
return {
|
|
82
|
+
transform: [{ translateY: translateY.value }],
|
|
83
|
+
elevation: overlapped.value ? elevationStyle?.elevation : 0,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
if (Platform.OS === 'ios') {
|
|
87
|
+
return {
|
|
88
|
+
transform: [{ translateY: translateY.value }],
|
|
89
|
+
shadowColor: elevationStyle?.shadowColor,
|
|
90
|
+
shadowOffset: elevationStyle?.shadowOffset,
|
|
91
|
+
shadowRadius: elevationStyle?.shadowRadius,
|
|
92
|
+
shadowOpacity: overlapped.value ? elevationStyle?.shadowOpacity : 0,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
return {};
|
|
85
96
|
});
|
|
86
97
|
|
|
87
98
|
const indexRef = React.useRef<number>(0);
|
|
@@ -77,14 +77,29 @@ export default function useFadeInAppBar(userOptions: Options = defaultOptions):
|
|
|
77
77
|
const backgroundColor = theme.palette.background.default;
|
|
78
78
|
const [r, g, b] = React.useMemo(() => rgb(backgroundColor), [backgroundColor]);
|
|
79
79
|
|
|
80
|
-
const animatedAppBarStyle = useAnimatedStyle(() =>
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
80
|
+
const animatedAppBarStyle = useAnimatedStyle(() => {
|
|
81
|
+
if (Platform.OS === 'web') {
|
|
82
|
+
return {
|
|
83
|
+
backgroundColor: `rgba(${r}, ${g}, ${b}, ${normalized.value})`,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
if (Platform.OS === 'android') {
|
|
87
|
+
return {
|
|
88
|
+
backgroundColor: `rgba(${r}, ${g}, ${b}, ${normalized.value})`,
|
|
89
|
+
elevation: normalized.value >= 1 ? 6 : 0,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
if (Platform.OS === 'ios') {
|
|
93
|
+
return {
|
|
94
|
+
backgroundColor: `rgba(${r}, ${g}, ${b}, ${normalized.value})`,
|
|
95
|
+
shadowColor: '#000',
|
|
96
|
+
shadowOffset,
|
|
97
|
+
shadowRadius: 4.65,
|
|
98
|
+
shadowOpacity: normalized.value >= 1 ? 0.25 : 0,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
return {};
|
|
102
|
+
});
|
|
88
103
|
|
|
89
104
|
const animatedTitleStyle = useAnimatedStyle(() => ({
|
|
90
105
|
opacity: normalized.value,
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.default = useWidth;
|
|
7
|
-
|
|
8
|
-
var _react = _interopRequireDefault(require("react"));
|
|
9
|
-
|
|
10
|
-
var _reactNative = require("react-native");
|
|
11
|
-
|
|
12
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
13
|
-
|
|
14
|
-
function useWidth() {
|
|
15
|
-
const window = (0, _reactNative.useWindowDimensions)();
|
|
16
|
-
|
|
17
|
-
const [width, setWidth] = _react.default.useState(window.width);
|
|
18
|
-
|
|
19
|
-
const onLayout = _react.default.useCallback(e => {
|
|
20
|
-
const newWidth = e.nativeEvent.layout.width;
|
|
21
|
-
|
|
22
|
-
if (newWidth > 0 && Math.round(newWidth) !== Math.round(width)) {
|
|
23
|
-
setWidth(newWidth);
|
|
24
|
-
}
|
|
25
|
-
}, []);
|
|
26
|
-
|
|
27
|
-
return [width, onLayout];
|
|
28
|
-
}
|
|
29
|
-
//# sourceMappingURL=useWidth.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["useWidth","window","useWindowDimensions","width","setWidth","React","useState","onLayout","useCallback","e","newWidth","nativeEvent","layout","Math","round"],"sources":["useWidth.ts"],"sourcesContent":["import React from 'react';\nimport { LayoutChangeEvent, useWindowDimensions, ViewProps } from 'react-native';\n\nexport default function useWidth(): [number, ViewProps['onLayout']] {\n const window = useWindowDimensions();\n const [width, setWidth] = React.useState(window.width);\n\n const onLayout = React.useCallback((e: LayoutChangeEvent) => {\n const newWidth = e.nativeEvent.layout.width;\n\n if (newWidth > 0 && Math.round(newWidth) !== Math.round(width)) {\n setWidth(newWidth);\n }\n }, []);\n\n return [width, onLayout];\n}"],"mappings":";;;;;;;AAAA;;AACA;;;;AAEe,SAASA,QAAT,GAAqD;EAChE,MAAMC,MAAM,GAAG,IAAAC,gCAAA,GAAf;;EACA,MAAM,CAACC,KAAD,EAAQC,QAAR,IAAoBC,cAAA,CAAMC,QAAN,CAAeL,MAAM,CAACE,KAAtB,CAA1B;;EAEA,MAAMI,QAAQ,GAAGF,cAAA,CAAMG,WAAN,CAAmBC,CAAD,IAA0B;IACzD,MAAMC,QAAQ,GAAGD,CAAC,CAACE,WAAF,CAAcC,MAAd,CAAqBT,KAAtC;;IAEA,IAAIO,QAAQ,GAAG,CAAX,IAAgBG,IAAI,CAACC,KAAL,CAAWJ,QAAX,MAAyBG,IAAI,CAACC,KAAL,CAAWX,KAAX,CAA7C,EAAgE;MAC5DC,QAAQ,CAACM,QAAD,CAAR;IACH;EACJ,CANgB,EAMd,EANc,CAAjB;;EAQA,OAAO,CAACP,KAAD,EAAQI,QAAR,CAAP;AACH"}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { useWindowDimensions } from 'react-native';
|
|
3
|
-
export default function useWidth() {
|
|
4
|
-
const window = useWindowDimensions();
|
|
5
|
-
const [width, setWidth] = React.useState(window.width);
|
|
6
|
-
const onLayout = React.useCallback(e => {
|
|
7
|
-
const newWidth = e.nativeEvent.layout.width;
|
|
8
|
-
|
|
9
|
-
if (newWidth > 0 && Math.round(newWidth) !== Math.round(width)) {
|
|
10
|
-
setWidth(newWidth);
|
|
11
|
-
}
|
|
12
|
-
}, []);
|
|
13
|
-
return [width, onLayout];
|
|
14
|
-
}
|
|
15
|
-
//# sourceMappingURL=useWidth.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["React","useWindowDimensions","useWidth","window","width","setWidth","useState","onLayout","useCallback","e","newWidth","nativeEvent","layout","Math","round"],"sources":["useWidth.ts"],"sourcesContent":["import React from 'react';\nimport { LayoutChangeEvent, useWindowDimensions, ViewProps } from 'react-native';\n\nexport default function useWidth(): [number, ViewProps['onLayout']] {\n const window = useWindowDimensions();\n const [width, setWidth] = React.useState(window.width);\n\n const onLayout = React.useCallback((e: LayoutChangeEvent) => {\n const newWidth = e.nativeEvent.layout.width;\n\n if (newWidth > 0 && Math.round(newWidth) !== Math.round(width)) {\n setWidth(newWidth);\n }\n }, []);\n\n return [width, onLayout];\n}"],"mappings":"AAAA,OAAOA,KAAP,MAAkB,OAAlB;AACA,SAA4BC,mBAA5B,QAAkE,cAAlE;AAEA,eAAe,SAASC,QAAT,GAAqD;EAChE,MAAMC,MAAM,GAAGF,mBAAmB,EAAlC;EACA,MAAM,CAACG,KAAD,EAAQC,QAAR,IAAoBL,KAAK,CAACM,QAAN,CAAeH,MAAM,CAACC,KAAtB,CAA1B;EAEA,MAAMG,QAAQ,GAAGP,KAAK,CAACQ,WAAN,CAAmBC,CAAD,IAA0B;IACzD,MAAMC,QAAQ,GAAGD,CAAC,CAACE,WAAF,CAAcC,MAAd,CAAqBR,KAAtC;;IAEA,IAAIM,QAAQ,GAAG,CAAX,IAAgBG,IAAI,CAACC,KAAL,CAAWJ,QAAX,MAAyBG,IAAI,CAACC,KAAL,CAAWV,KAAX,CAA7C,EAAgE;MAC5DC,QAAQ,CAACK,QAAD,CAAR;IACH;EACJ,CANgB,EAMd,EANc,CAAjB;EAQA,OAAO,CAACN,KAAD,EAAQG,QAAR,CAAP;AACH"}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { LayoutChangeEvent, useWindowDimensions, ViewProps } from 'react-native';
|
|
3
|
-
|
|
4
|
-
export default function useWidth(): [number, ViewProps['onLayout']] {
|
|
5
|
-
const window = useWindowDimensions();
|
|
6
|
-
const [width, setWidth] = React.useState(window.width);
|
|
7
|
-
|
|
8
|
-
const onLayout = React.useCallback((e: LayoutChangeEvent) => {
|
|
9
|
-
const newWidth = e.nativeEvent.layout.width;
|
|
10
|
-
|
|
11
|
-
if (newWidth > 0 && Math.round(newWidth) !== Math.round(width)) {
|
|
12
|
-
setWidth(newWidth);
|
|
13
|
-
}
|
|
14
|
-
}, []);
|
|
15
|
-
|
|
16
|
-
return [width, onLayout];
|
|
17
|
-
}
|