@fountain-ui/core 2.0.0-beta.13 → 2.0.0-beta.16

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.
Files changed (64) hide show
  1. package/build/commonjs/ButtonBase/ButtonBase.js +3 -2
  2. package/build/commonjs/ButtonBase/ButtonBase.js.map +1 -1
  3. package/build/commonjs/CircularProgress/CircularProgress.js +15 -11
  4. package/build/commonjs/CircularProgress/CircularProgress.js.map +1 -1
  5. package/build/commonjs/Tab/Tab.js +9 -5
  6. package/build/commonjs/Tab/Tab.js.map +1 -1
  7. package/build/commonjs/Tabs/IndexAwareTab.js +28 -0
  8. package/build/commonjs/Tabs/IndexAwareTab.js.map +1 -0
  9. package/build/commonjs/Tabs/TabIndicator.js +27 -13
  10. package/build/commonjs/Tabs/TabIndicator.js.map +1 -1
  11. package/build/commonjs/Tabs/TabIndicatorProps.js.map +1 -1
  12. package/build/commonjs/Tabs/Tabs.js +43 -62
  13. package/build/commonjs/Tabs/Tabs.js.map +1 -1
  14. package/build/commonjs/Tabs/TabsProps.js.map +1 -1
  15. package/build/commonjs/Tabs/index.js.map +1 -1
  16. package/build/commonjs/Tabs/useScrollViewReaction.js +65 -0
  17. package/build/commonjs/Tabs/useScrollViewReaction.js.map +1 -0
  18. package/build/commonjs/hooks/useValidWindowDimensions/index.ios.js +14 -7
  19. package/build/commonjs/hooks/useValidWindowDimensions/index.ios.js.map +1 -1
  20. package/build/module/ButtonBase/ButtonBase.js +3 -2
  21. package/build/module/ButtonBase/ButtonBase.js.map +1 -1
  22. package/build/module/CircularProgress/CircularProgress.js +15 -11
  23. package/build/module/CircularProgress/CircularProgress.js.map +1 -1
  24. package/build/module/Tab/Tab.js +5 -5
  25. package/build/module/Tab/Tab.js.map +1 -1
  26. package/build/module/Tabs/IndexAwareTab.js +18 -0
  27. package/build/module/Tabs/IndexAwareTab.js.map +1 -0
  28. package/build/module/Tabs/TabIndicator.js +26 -14
  29. package/build/module/Tabs/TabIndicator.js.map +1 -1
  30. package/build/module/Tabs/TabIndicatorProps.js.map +1 -1
  31. package/build/module/Tabs/Tabs.js +42 -60
  32. package/build/module/Tabs/Tabs.js.map +1 -1
  33. package/build/module/Tabs/TabsProps.js.map +1 -1
  34. package/build/module/Tabs/index.js.map +1 -1
  35. package/build/module/Tabs/useScrollViewReaction.js +54 -0
  36. package/build/module/Tabs/useScrollViewReaction.js.map +1 -0
  37. package/build/module/hooks/useValidWindowDimensions/index.ios.js +15 -9
  38. package/build/module/hooks/useValidWindowDimensions/index.ios.js.map +1 -1
  39. package/build/typescript/CircularProgress/CircularProgress.d.ts +1 -1
  40. package/build/typescript/Tabs/IndexAwareTab.d.ts +9 -0
  41. package/build/typescript/Tabs/TabIndicatorProps.d.ts +2 -2
  42. package/build/typescript/Tabs/Tabs.d.ts +4 -1
  43. package/build/typescript/Tabs/TabsProps.d.ts +22 -9
  44. package/build/typescript/Tabs/index.d.ts +1 -1
  45. package/build/typescript/Tabs/useScrollViewReaction.d.ts +9 -0
  46. package/build/typescript/hooks/useValidWindowDimensions/index.ios.d.ts +2 -1
  47. package/package.json +2 -2
  48. package/src/ButtonBase/ButtonBase.tsx +6 -2
  49. package/src/CircularProgress/CircularProgress.tsx +23 -15
  50. package/src/Tab/Tab.tsx +5 -5
  51. package/src/Tabs/IndexAwareTab.tsx +30 -0
  52. package/src/Tabs/TabIndicator.tsx +26 -14
  53. package/src/Tabs/TabIndicatorProps.ts +2 -2
  54. package/src/Tabs/Tabs.tsx +50 -62
  55. package/src/Tabs/TabsProps.ts +25 -9
  56. package/src/Tabs/index.ts +1 -1
  57. package/src/Tabs/useScrollViewReaction.ts +63 -0
  58. package/src/hooks/useValidWindowDimensions/index.ios.ts +16 -10
  59. package/build/commonjs/Tabs/useTabsWidth.js +0 -26
  60. package/build/commonjs/Tabs/useTabsWidth.js.map +0 -1
  61. package/build/module/Tabs/useTabsWidth.js +0 -18
  62. package/build/module/Tabs/useTabsWidth.js.map +0 -1
  63. package/build/typescript/Tabs/useTabsWidth.d.ts +0 -2
  64. package/src/Tabs/useTabsWidth.ts +0 -20
package/src/Tabs/Tabs.tsx CHANGED
@@ -1,13 +1,15 @@
1
- import React, { cloneElement, useEffect, useMemo, useRef } from 'react';
2
- import { GestureResponderEvent, LayoutChangeEvent, ScrollView, View } from 'react-native';
3
- import type { WithTimingConfig } from 'react-native-reanimated';
4
- import { Easing, useSharedValue, withTiming } from 'react-native-reanimated';
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 useTabsWidth from './useTabsWidth';
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,46 @@ const useStyles: UseStyles<TabsStyles> = function (): TabsStyles {
34
36
  };
35
37
  };
36
38
 
37
- const ANIMATION_CONFIG: Readonly<WithTimingConfig> = {
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
- index: indexProp,
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
50
+ UNSTABLE_sharedIndex,
55
51
  } = props;
56
52
 
57
- const styles = useStyles();
58
-
59
- const [containerWidth, handleLayout] = useTabsWidth();
60
-
61
- const scrollViewRef = useRef<ScrollView | null>(null);
53
+ const fallbackSharedIndex = useSharedValue<number>(initialIndex);
62
54
 
63
- const { coordinates, updateCoordinate } = useTabCoordinates(children);
55
+ const sharedIndex = UNSTABLE_sharedIndex ?? fallbackSharedIndex;
64
56
 
65
- const internalScrollValue = useSharedValue(0);
66
- const scrollValue = scrollValueProp ?? internalScrollValue;
57
+ const getCurrentIndex = (): number => sharedIndex.value;
67
58
 
68
- const isReadyToRenderIndicator = coordinates.length > 0;
69
-
70
- useEffect(() => {
71
- const animateTab = (index: number) => {
72
- scrollValue.value = withTiming(index, ANIMATION_CONFIG);
73
- };
74
-
75
- animateTab(indexProp);
76
- }, [indexProp, scrollValue]);
59
+ const setTab = (newIndex: number) => {
60
+ sharedIndex.value = newIndex;
61
+ };
77
62
 
78
- const scrollPosition = useMemo<number>(() => {
79
- const coordinate = coordinates[indexProp - 1];
63
+ useImperativeHandle(
64
+ ref,
65
+ () => ({
66
+ getCurrentIndex,
67
+ setTab,
68
+ }),
69
+ [sharedIndex],
70
+ );
80
71
 
81
- if (coordinate) {
82
- const tabWidth = coordinate.x2 - coordinate.x1;
83
- return Math.floor(coordinate.x1 + tabWidth / 2);
84
- }
72
+ const styles = useStyles();
85
73
 
86
- return 0;
87
- }, [indexProp, coordinates]);
74
+ const { coordinates, updateCoordinate } = useTabCoordinates(children);
88
75
 
89
- useEffect(() => {
90
- const scrollView = scrollViewRef.current;
76
+ const { scrollViewRef, onLayout } = useScrollViewReaction(sharedIndex, coordinates);
91
77
 
92
- if (scrollView) {
93
- scrollView.scrollTo({ x: scrollPosition, y: 0, animated: true });
94
- }
95
- }, [scrollPosition, containerWidth]);
78
+ const isReadyToRenderIndicator = coordinates.length > 0;
96
79
 
97
80
  const tabElements = React.Children.map(children, (child, index) => {
98
81
  const onLayout = (event: LayoutChangeEvent) => {
@@ -108,46 +91,49 @@ export default function Tabs(props: TabsProps) {
108
91
  };
109
92
 
110
93
  const onPress = () => {
94
+ setTab(index);
95
+
111
96
  onChange?.(index);
112
97
  // @ts-ignore
113
98
  child.props.onPress?.();
114
99
  };
115
100
 
116
- const selected = index === indexProp;
117
- const enableIndicatorPlaceholder = disableIndicator
118
- ? false
119
- : (isReadyToRenderIndicator ? false : selected);
120
-
121
- //@ts-ignore
122
- return cloneElement(child, {
123
- enableIndicator: enableIndicatorPlaceholder,
101
+ // @ts-ignore
102
+ const tabElement = cloneElement(child, {
103
+ enableIndicator: !disableIndicator && !isReadyToRenderIndicator,
124
104
  onLayout,
125
105
  onPress,
126
106
  onMouseDown,
127
107
  variant,
128
- selected,
129
108
  style: scrollable ? undefined : styles.fixedTab,
130
109
  });
110
+
111
+ return (
112
+ <IndexAwareTab
113
+ children={tabElement}
114
+ index={index}
115
+ sharedIndex={sharedIndex}
116
+ />
117
+ );
131
118
  });
132
119
 
133
- const indicator = (
120
+ const tabIndicator = isReadyToRenderIndicator ? (
134
121
  <TabIndicator
135
122
  coordinates={coordinates}
136
123
  disabled={disableIndicator}
137
124
  scrollable={scrollable}
138
- scrollValue={scrollValue}
125
+ sharedIndex={sharedIndex}
139
126
  />
140
- );
127
+ ) : null;
141
128
 
142
129
  return (
143
130
  <View
144
- onLayout={handleLayout}
131
+ onLayout={onLayout}
145
132
  style={css([
146
133
  styles.root,
147
134
  scrollable ? undefined : styles.fixedRoot,
148
135
  style,
149
136
  ])}
150
- {...otherProps}
151
137
  >
152
138
  {scrollable ? (
153
139
  <ScrollView
@@ -164,14 +150,16 @@ export default function Tabs(props: TabsProps) {
164
150
  keyboardShouldPersistTaps={keyboardShouldPersistTaps}
165
151
  >
166
152
  {tabElements}
167
- {indicator}
153
+ {tabIndicator}
168
154
  </ScrollView>
169
155
  ) : (
170
156
  <React.Fragment>
171
157
  {tabElements}
172
- {indicator}
158
+ {tabIndicator}
173
159
  </React.Fragment>
174
160
  )}
175
161
  </View>
176
162
  );
177
- };
163
+ });
164
+
165
+ export default Tabs;
@@ -1,6 +1,6 @@
1
- import React from 'react';
1
+ import type { ReactNode, Ref } from 'react';
2
2
  import type { ViewProps } from 'react-native';
3
- import Animated from 'react-native-reanimated';
3
+ import type { SharedValue } from 'react-native-reanimated';
4
4
  import type { TabVariant } from '../Tab';
5
5
  import type { OverridableComponentProps } from '../types';
6
6
 
@@ -15,16 +15,26 @@ export type KeyboardShouldPersistTaps =
15
15
  | 'always'
16
16
  | 'handled'; // app only
17
17
 
18
- export default interface TabsProps extends OverridableComponentProps<ViewProps, {
18
+ export interface TabsInstance {
19
19
  /**
20
- * Collection of Tab components.
20
+ * Get current tab index.
21
21
  */
22
- children: React.ReactNode;
22
+ getCurrentIndex: () => number;
23
23
 
24
24
  /**
25
- * Selected index.
25
+ * Function to scroll to a specific tab. Invalid index is ignored.
26
+ * @param index
26
27
  */
27
- index: number;
28
+ setTab: (index: number) => void;
29
+ }
30
+
31
+ export default interface TabsProps extends OverridableComponentProps<ViewProps, {
32
+ ref?: Ref<TabsInstance>;
33
+
34
+ /**
35
+ * Collection of Tab components.
36
+ */
37
+ children: ReactNode;
28
38
 
29
39
  /**
30
40
  * If `true`, the indicator is disabled.
@@ -32,6 +42,12 @@ export default interface TabsProps extends OverridableComponentProps<ViewProps,
32
42
  */
33
43
  disableIndicator?: boolean;
34
44
 
45
+ /**
46
+ * Index of initial tab that should be selected.
47
+ * @default 0
48
+ */
49
+ initialIndex?: number;
50
+
35
51
  /**
36
52
  * keyboard dismissing condition of dragging.
37
53
  * @default 'none'
@@ -56,9 +72,9 @@ export default interface TabsProps extends OverridableComponentProps<ViewProps,
56
72
  scrollable?: boolean;
57
73
 
58
74
  /**
59
- * Scrollable value for using animated interpolation.
75
+ * Unstable API.
60
76
  */
61
- scrollValue?: Animated.SharedValue<number>;
77
+ UNSTABLE_sharedIndex?: SharedValue<number>;
62
78
 
63
79
  /**
64
80
  * The variant to use.
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,63 @@
1
+ import type { MutableRefObject } from 'react';
2
+ import { useCallback, useRef } from 'react';
3
+ import type { ScrollView, ViewProps } from 'react-native';
4
+ import { Platform } from 'react-native';
5
+ import { runOnJS, scrollTo, SharedValue, useAnimatedReaction, useAnimatedRef } from 'react-native-reanimated';
6
+ import type TabCoordinate from './TabCoordinate';
7
+
8
+ export interface UseScrollViewReaction {
9
+ scrollViewRef: MutableRefObject<ScrollView | null>;
10
+ onLayout: ViewProps['onLayout'];
11
+ }
12
+
13
+ export default function useScrollViewReaction(
14
+ sharedIndex: SharedValue<number>,
15
+ coordinates: TabCoordinate[],
16
+ ): UseScrollViewReaction {
17
+ const scrollViewRef = useAnimatedRef<ScrollView>();
18
+
19
+ const lastScrolledXRef = useRef<number>(NaN);
20
+
21
+ const scrollToX = (x: number) => {
22
+ if (Number.isFinite(x)) {
23
+ scrollViewRef.current?.scrollTo({ x, y: 0, animated: true });
24
+
25
+ didScrollToX(x);
26
+ }
27
+ };
28
+
29
+ const didScrollToX = (x: number) => {
30
+ lastScrolledXRef.current = x;
31
+ };
32
+
33
+ const onLayout = useCallback(() => {
34
+ scrollToX(lastScrolledXRef.current);
35
+ }, []);
36
+
37
+ useAnimatedReaction(
38
+ () => {
39
+ const prevIndex = sharedIndex.value - 1;
40
+ const prevCoordinate = coordinates[prevIndex];
41
+
42
+ if (prevCoordinate) {
43
+ const prevTabWidth = prevCoordinate.x2 - prevCoordinate.x1;
44
+ return Math.floor(prevCoordinate.x1 + prevTabWidth / 2);
45
+ }
46
+
47
+ return 0;
48
+ },
49
+ (x, prevX) => {
50
+ if (x !== prevX) {
51
+ if (Platform.OS === 'web') {
52
+ runOnJS(scrollToX)(x);
53
+ } else {
54
+ scrollTo(scrollViewRef, x, 0, true);
55
+ runOnJS(didScrollToX)(x);
56
+ }
57
+ }
58
+ },
59
+ [coordinates],
60
+ );
61
+
62
+ return { scrollViewRef, onLayout };
63
+ };
@@ -1,15 +1,21 @@
1
- import { useState, useEffect } from 'react';
2
- import { useWindowDimensions } from 'react-native';
1
+ import { useEffect, useState } from 'react';
2
+ import type { ScaledSize } from 'react-native';
3
+ import { Dimensions } from 'react-native';
3
4
 
4
- export default function useValidWindowDimensions() {
5
- const window = useWindowDimensions();
6
- const [validWindow, setValidWindow] = useState(window);
5
+ export default function useValidWindowDimensions(): ScaledSize {
6
+ const [window, setWindow] = useState<ScaledSize>(() => Dimensions.get('window'));
7
7
 
8
8
  useEffect(() => {
9
- if (window.width !== 0 && window.height !== 0) {
10
- setValidWindow(window);
11
- }
12
- }, [window]);
9
+ const subscription = Dimensions.addEventListener('change', (newDimension) => {
10
+ const { window: newWindow } = newDimension;
13
11
 
14
- return validWindow;
12
+ if (newWindow.width !== 0 && newWindow.height !== 0) {
13
+ setWindow(newWindow);
14
+ }
15
+ });
16
+
17
+ return subscription.remove;
18
+ }, []);
19
+
20
+ return window;
15
21
  }
@@ -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"}
@@ -1,2 +0,0 @@
1
- import { ViewProps } from 'react-native';
2
- export default function useTabsWidth(): [number, ViewProps['onLayout']];
@@ -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
- }