@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
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = useScrollViewReaction;
7
+
8
+ var _react = require("react");
9
+
10
+ var _reactNative = require("react-native");
11
+
12
+ var _reactNativeReanimated = require("react-native-reanimated");
13
+
14
+ function useScrollViewReaction(sharedIndex, coordinates) {
15
+ const scrollViewRef = (0, _reactNativeReanimated.useAnimatedRef)();
16
+ const lastScrolledXRef = (0, _react.useRef)(NaN);
17
+
18
+ const scrollToX = x => {
19
+ if (Number.isFinite(x)) {
20
+ var _scrollViewRef$curren;
21
+
22
+ (_scrollViewRef$curren = scrollViewRef.current) === null || _scrollViewRef$curren === void 0 ? void 0 : _scrollViewRef$curren.scrollTo({
23
+ x,
24
+ y: 0,
25
+ animated: true
26
+ });
27
+ didScrollToX(x);
28
+ }
29
+ };
30
+
31
+ const didScrollToX = x => {
32
+ lastScrolledXRef.current = x;
33
+ };
34
+
35
+ const onLayout = (0, _react.useCallback)(() => {
36
+ scrollToX(lastScrolledXRef.current);
37
+ }, []);
38
+ (0, _reactNativeReanimated.useAnimatedReaction)(() => {
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
+ }, (x, prevX) => {
49
+ if (x !== prevX) {
50
+ if (_reactNative.Platform.OS === 'web') {
51
+ (0, _reactNativeReanimated.runOnJS)(scrollToX)(x);
52
+ } else {
53
+ (0, _reactNativeReanimated.scrollTo)(scrollViewRef, x, 0, true);
54
+ (0, _reactNativeReanimated.runOnJS)(didScrollToX)(x);
55
+ }
56
+ }
57
+ }, [coordinates]);
58
+ return {
59
+ scrollViewRef,
60
+ onLayout
61
+ };
62
+ }
63
+
64
+ ;
65
+ //# sourceMappingURL=useScrollViewReaction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["useScrollViewReaction","sharedIndex","coordinates","scrollViewRef","useAnimatedRef","lastScrolledXRef","useRef","NaN","scrollToX","x","Number","isFinite","current","scrollTo","y","animated","didScrollToX","onLayout","useCallback","useAnimatedReaction","prevIndex","value","prevCoordinate","prevTabWidth","x2","x1","Math","floor","prevX","Platform","OS","runOnJS"],"sources":["useScrollViewReaction.ts"],"sourcesContent":["import type { MutableRefObject } from 'react';\nimport { useCallback, useRef } from 'react';\nimport type { ScrollView, ViewProps } from 'react-native';\nimport { Platform } from 'react-native';\nimport { runOnJS, scrollTo, SharedValue, useAnimatedReaction, useAnimatedRef } from 'react-native-reanimated';\nimport type TabCoordinate from './TabCoordinate';\n\nexport interface UseScrollViewReaction {\n scrollViewRef: MutableRefObject<ScrollView | null>;\n onLayout: ViewProps['onLayout'];\n}\n\nexport default function useScrollViewReaction(\n sharedIndex: SharedValue<number>,\n coordinates: TabCoordinate[],\n): UseScrollViewReaction {\n const scrollViewRef = useAnimatedRef<ScrollView>();\n\n const lastScrolledXRef = useRef<number>(NaN);\n\n const scrollToX = (x: number) => {\n if (Number.isFinite(x)) {\n scrollViewRef.current?.scrollTo({ x, y: 0, animated: true });\n\n didScrollToX(x);\n }\n };\n\n const didScrollToX = (x: number) => {\n lastScrolledXRef.current = x;\n };\n\n const onLayout = useCallback(() => {\n scrollToX(lastScrolledXRef.current);\n }, []);\n\n useAnimatedReaction(\n () => {\n const prevIndex = sharedIndex.value - 1;\n const prevCoordinate = coordinates[prevIndex];\n\n if (prevCoordinate) {\n const prevTabWidth = prevCoordinate.x2 - prevCoordinate.x1;\n return Math.floor(prevCoordinate.x1 + prevTabWidth / 2);\n }\n\n return 0;\n },\n (x, prevX) => {\n if (x !== prevX) {\n if (Platform.OS === 'web') {\n runOnJS(scrollToX)(x);\n } else {\n scrollTo(scrollViewRef, x, 0, true);\n runOnJS(didScrollToX)(x);\n }\n }\n },\n [coordinates],\n );\n\n return { scrollViewRef, onLayout };\n};\n"],"mappings":";;;;;;;AACA;;AAEA;;AACA;;AAQe,SAASA,qBAAT,CACXC,WADW,EAEXC,WAFW,EAGU;EACrB,MAAMC,aAAa,GAAG,IAAAC,qCAAA,GAAtB;EAEA,MAAMC,gBAAgB,GAAG,IAAAC,aAAA,EAAeC,GAAf,CAAzB;;EAEA,MAAMC,SAAS,GAAIC,CAAD,IAAe;IAC7B,IAAIC,MAAM,CAACC,QAAP,CAAgBF,CAAhB,CAAJ,EAAwB;MAAA;;MACpB,yBAAAN,aAAa,CAACS,OAAd,gFAAuBC,QAAvB,CAAgC;QAAEJ,CAAF;QAAKK,CAAC,EAAE,CAAR;QAAWC,QAAQ,EAAE;MAArB,CAAhC;MAEAC,YAAY,CAACP,CAAD,CAAZ;IACH;EACJ,CAND;;EAQA,MAAMO,YAAY,GAAIP,CAAD,IAAe;IAChCJ,gBAAgB,CAACO,OAAjB,GAA2BH,CAA3B;EACH,CAFD;;EAIA,MAAMQ,QAAQ,GAAG,IAAAC,kBAAA,EAAY,MAAM;IAC/BV,SAAS,CAACH,gBAAgB,CAACO,OAAlB,CAAT;EACH,CAFgB,EAEd,EAFc,CAAjB;EAIA,IAAAO,0CAAA,EACI,MAAM;IACF,MAAMC,SAAS,GAAGnB,WAAW,CAACoB,KAAZ,GAAoB,CAAtC;IACA,MAAMC,cAAc,GAAGpB,WAAW,CAACkB,SAAD,CAAlC;;IAEA,IAAIE,cAAJ,EAAoB;MAChB,MAAMC,YAAY,GAAGD,cAAc,CAACE,EAAf,GAAoBF,cAAc,CAACG,EAAxD;MACA,OAAOC,IAAI,CAACC,KAAL,CAAWL,cAAc,CAACG,EAAf,GAAoBF,YAAY,GAAG,CAA9C,CAAP;IACH;;IAED,OAAO,CAAP;EACH,CAXL,EAYI,CAACd,CAAD,EAAImB,KAAJ,KAAc;IACV,IAAInB,CAAC,KAAKmB,KAAV,EAAiB;MACb,IAAIC,qBAAA,CAASC,EAAT,KAAgB,KAApB,EAA2B;QACvB,IAAAC,8BAAA,EAAQvB,SAAR,EAAmBC,CAAnB;MACH,CAFD,MAEO;QACH,IAAAI,+BAAA,EAASV,aAAT,EAAwBM,CAAxB,EAA2B,CAA3B,EAA8B,IAA9B;QACA,IAAAsB,8BAAA,EAAQf,YAAR,EAAsBP,CAAtB;MACH;IACJ;EACJ,CArBL,EAsBI,CAACP,WAAD,CAtBJ;EAyBA,OAAO;IAAEC,aAAF;IAAiBc;EAAjB,CAAP;AACH;;AAAA"}
@@ -10,13 +10,20 @@ var _react = require("react");
10
10
  var _reactNative = require("react-native");
11
11
 
12
12
  function useValidWindowDimensions() {
13
- const window = (0, _reactNative.useWindowDimensions)();
14
- const [validWindow, setValidWindow] = (0, _react.useState)(window);
13
+ const [window, setWindow] = (0, _react.useState)(() => _reactNative.Dimensions.get('window'));
15
14
  (0, _react.useEffect)(() => {
16
- if (window.width !== 0 && window.height !== 0) {
17
- setValidWindow(window);
18
- }
19
- }, [window]);
20
- return validWindow;
15
+ const subscription = _reactNative.Dimensions.addEventListener('change', newDimension => {
16
+ const {
17
+ window: newWindow
18
+ } = newDimension;
19
+
20
+ if (newWindow.width !== 0 && newWindow.height !== 0) {
21
+ setWindow(newWindow);
22
+ }
23
+ });
24
+
25
+ return subscription.remove;
26
+ }, []);
27
+ return window;
21
28
  }
22
29
  //# sourceMappingURL=index.ios.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["useValidWindowDimensions","window","useWindowDimensions","validWindow","setValidWindow","useState","useEffect","width","height"],"sources":["index.ios.ts"],"sourcesContent":["import { useState, useEffect } from 'react';\nimport { useWindowDimensions } from 'react-native';\n\nexport default function useValidWindowDimensions() {\n const window = useWindowDimensions();\n const [validWindow, setValidWindow] = useState(window);\n\n useEffect(() => {\n if (window.width !== 0 && window.height !== 0) {\n setValidWindow(window);\n }\n }, [window]);\n\n return validWindow;\n}\n"],"mappings":";;;;;;;AAAA;;AACA;;AAEe,SAASA,wBAAT,GAAoC;EAC/C,MAAMC,MAAM,GAAG,IAAAC,gCAAA,GAAf;EACA,MAAM,CAACC,WAAD,EAAcC,cAAd,IAAgC,IAAAC,eAAA,EAASJ,MAAT,CAAtC;EAEA,IAAAK,gBAAA,EAAU,MAAM;IACZ,IAAIL,MAAM,CAACM,KAAP,KAAiB,CAAjB,IAAsBN,MAAM,CAACO,MAAP,KAAkB,CAA5C,EAA+C;MAC3CJ,cAAc,CAACH,MAAD,CAAd;IACH;EACJ,CAJD,EAIG,CAACA,MAAD,CAJH;EAMA,OAAOE,WAAP;AACH"}
1
+ {"version":3,"names":["useValidWindowDimensions","window","setWindow","useState","Dimensions","get","useEffect","subscription","addEventListener","newDimension","newWindow","width","height","remove"],"sources":["index.ios.ts"],"sourcesContent":["import { useEffect, useState } from 'react';\nimport type { ScaledSize } from 'react-native';\nimport { Dimensions } from 'react-native';\n\nexport default function useValidWindowDimensions(): ScaledSize {\n const [window, setWindow] = useState<ScaledSize>(() => Dimensions.get('window'));\n\n useEffect(() => {\n const subscription = Dimensions.addEventListener('change', (newDimension) => {\n const { window: newWindow } = newDimension;\n\n if (newWindow.width !== 0 && newWindow.height !== 0) {\n setWindow(newWindow);\n }\n });\n\n return subscription.remove;\n }, []);\n\n return window;\n}\n"],"mappings":";;;;;;;AAAA;;AAEA;;AAEe,SAASA,wBAAT,GAAgD;EAC3D,MAAM,CAACC,MAAD,EAASC,SAAT,IAAsB,IAAAC,eAAA,EAAqB,MAAMC,uBAAA,CAAWC,GAAX,CAAe,QAAf,CAA3B,CAA5B;EAEA,IAAAC,gBAAA,EAAU,MAAM;IACZ,MAAMC,YAAY,GAAGH,uBAAA,CAAWI,gBAAX,CAA4B,QAA5B,EAAuCC,YAAD,IAAkB;MACzE,MAAM;QAAER,MAAM,EAAES;MAAV,IAAwBD,YAA9B;;MAEA,IAAIC,SAAS,CAACC,KAAV,KAAoB,CAApB,IAAyBD,SAAS,CAACE,MAAV,KAAqB,CAAlD,EAAqD;QACjDV,SAAS,CAACQ,SAAD,CAAT;MACH;IACJ,CANoB,CAArB;;IAQA,OAAOH,YAAY,CAACM,MAApB;EACH,CAVD,EAUG,EAVH;EAYA,OAAOZ,MAAP;AACH"}
@@ -11,7 +11,7 @@ const ORIGINAL_SCALE = 1;
11
11
  const MINIFIED_SCALE = .96; // at "node_modules/react-native/Libraries/Pressability.js"
12
12
  // const DEFAULT_MIN_PRESS_DURATION = 130;
13
13
 
14
- const PRESS_IN_DELAY = 130;
14
+ const SCALE_EFFECT_PRESS_IN_DELAY = 130;
15
15
 
16
16
  const startTimingAnimationWithDefaults = (value, toValue) => {
17
17
  Animated.timing(value, {
@@ -74,13 +74,14 @@ export default function ButtonBase(props) {
74
74
  scale
75
75
  }]
76
76
  };
77
+ const pressDelay = pressEffect === 'scale' ? SCALE_EFFECT_PRESS_IN_DELAY : 0;
77
78
  return /*#__PURE__*/React.createElement(AnimatedPressable, _extends({
78
79
  disabled: disabled,
79
80
  onPress: handlePress,
80
81
  onPressIn: handlePressIn,
81
82
  onPressOut: handlePressOut,
82
83
  style: [animatedStyle, styleProp],
83
- unstable_pressDelay: PRESS_IN_DELAY
84
+ unstable_pressDelay: pressDelay
84
85
  }, otherProps), typeof children !== 'function' ? _ref => {
85
86
  let {
86
87
  hovered
@@ -1 +1 @@
1
- {"version":3,"names":["React","useCallback","useEffect","useRef","Animated","useThrottle","AnimatedPressable","ORIGINAL_OPACITY","DISABLED_OPACITY","ACTIVE_OPACITY","ORIGINAL_SCALE","MINIFIED_SCALE","PRESS_IN_DELAY","startTimingAnimationWithDefaults","value","toValue","timing","duration","useNativeDriver","start","ButtonBase","props","children","disabled","disableThrottle","onPress","pressEffect","style","styleProp","throttleMillis","otherProps","handlePress","periodMillis","callback","opacity","Value","current","scale","setValue","startScaleAnimation","pressIn","isHover","startOpacityAnimation","startPressAnimation","handlePressIn","handlePressOut","animatedStyle","transform","hovered","undefined"],"sources":["ButtonBase.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useRef } from 'react';\nimport { Animated } from 'react-native';\nimport { useThrottle } from '../hooks';\nimport { AnimatedPressable } from '../animated';\nimport type ButtonBaseProps from './ButtonBaseProps';\n\ninterface StartPressAnimation {\n (pressIn: boolean, isHover: boolean): void;\n}\n\nexport const ORIGINAL_OPACITY = 1;\nexport const DISABLED_OPACITY = .3;\nconst ACTIVE_OPACITY = .65;\n\nconst ORIGINAL_SCALE = 1;\nconst MINIFIED_SCALE = .96;\n\n// at \"node_modules/react-native/Libraries/Pressability.js\"\n// const DEFAULT_MIN_PRESS_DURATION = 130;\nconst PRESS_IN_DELAY = 130;\n\ntype TimingAnimationValue = Animated.Value | Animated.ValueXY;\ntype TimingAnimationToValue = Animated.TimingAnimationConfig['toValue'];\n\nconst startTimingAnimationWithDefaults = (\n value: TimingAnimationValue,\n toValue: TimingAnimationToValue,\n) => {\n Animated.timing(value, {\n toValue,\n duration: 150,\n useNativeDriver: true,\n }).start();\n};\n\nexport default function ButtonBase(props: ButtonBaseProps) {\n const {\n children,\n disabled = false,\n disableThrottle = false,\n onPress,\n pressEffect = 'opacity',\n style: styleProp,\n throttleMillis = 650,\n ...otherProps\n } = props;\n\n const handlePress = useThrottle({\n periodMillis: disableThrottle ? 0 : throttleMillis,\n callback: onPress,\n });\n\n const opacity = useRef<Animated.Value>(new Animated.Value(ORIGINAL_OPACITY)).current;\n const scale = useRef<Animated.Value>(new Animated.Value(ORIGINAL_SCALE)).current;\n\n useEffect(() => {\n opacity.setValue(disabled ? DISABLED_OPACITY : ORIGINAL_OPACITY);\n }, [disabled]);\n\n const startScaleAnimation = useCallback<StartPressAnimation>((pressIn, isHover) => {\n if (!isHover) {\n startTimingAnimationWithDefaults(\n scale,\n pressIn ? MINIFIED_SCALE : ORIGINAL_SCALE,\n );\n }\n }, []);\n\n const startOpacityAnimation = useCallback<StartPressAnimation>((pressIn) => {\n if (pressIn) {\n opacity.setValue(ACTIVE_OPACITY);\n } else {\n startTimingAnimationWithDefaults(opacity, ORIGINAL_OPACITY);\n }\n }, []);\n\n const startPressAnimation = useCallback<StartPressAnimation>((pressIn, isHover = false) => {\n if (pressEffect === 'scale') {\n startScaleAnimation(pressIn, isHover);\n } else if (pressEffect === 'opacity') {\n startOpacityAnimation(pressIn, isHover);\n }\n }, [pressEffect]);\n\n const handlePressIn = useCallback(() => {\n startPressAnimation(true, false);\n }, [startPressAnimation]);\n\n const handlePressOut = useCallback(() => {\n startPressAnimation(false, false);\n }, [startPressAnimation]);\n\n const animatedStyle = {\n opacity,\n transform: [{ scale }],\n };\n\n return (\n <AnimatedPressable\n disabled={disabled}\n onPress={handlePress}\n onPressIn={handlePressIn}\n onPressOut={handlePressOut}\n style={[\n animatedStyle,\n styleProp,\n ]}\n unstable_pressDelay={PRESS_IN_DELAY}\n {...otherProps}\n >\n {typeof children !== 'function' ? (\n ({ hovered }) => {\n if (hovered !== undefined && !disabled) {\n startPressAnimation(hovered, true);\n }\n\n return children;\n }\n ) : children}\n </AnimatedPressable>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"names":["React","useCallback","useEffect","useRef","Animated","useThrottle","AnimatedPressable","ORIGINAL_OPACITY","DISABLED_OPACITY","ACTIVE_OPACITY","ORIGINAL_SCALE","MINIFIED_SCALE","SCALE_EFFECT_PRESS_IN_DELAY","startTimingAnimationWithDefaults","value","toValue","timing","duration","useNativeDriver","start","ButtonBase","props","children","disabled","disableThrottle","onPress","pressEffect","style","styleProp","throttleMillis","otherProps","handlePress","periodMillis","callback","opacity","Value","current","scale","setValue","startScaleAnimation","pressIn","isHover","startOpacityAnimation","startPressAnimation","handlePressIn","handlePressOut","animatedStyle","transform","pressDelay","hovered","undefined"],"sources":["ButtonBase.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useRef } from 'react';\nimport { Animated } from 'react-native';\nimport { useThrottle } from '../hooks';\nimport { AnimatedPressable } from '../animated';\nimport type ButtonBaseProps from './ButtonBaseProps';\n\ninterface StartPressAnimation {\n (pressIn: boolean, isHover: boolean): void;\n}\n\nexport const ORIGINAL_OPACITY = 1;\nexport const DISABLED_OPACITY = .3;\nconst ACTIVE_OPACITY = .65;\n\nconst ORIGINAL_SCALE = 1;\nconst MINIFIED_SCALE = .96;\n\n// at \"node_modules/react-native/Libraries/Pressability.js\"\n// const DEFAULT_MIN_PRESS_DURATION = 130;\nconst SCALE_EFFECT_PRESS_IN_DELAY = 130;\n\ntype TimingAnimationValue = Animated.Value | Animated.ValueXY;\ntype TimingAnimationToValue = Animated.TimingAnimationConfig['toValue'];\n\nconst startTimingAnimationWithDefaults = (\n value: TimingAnimationValue,\n toValue: TimingAnimationToValue,\n) => {\n Animated.timing(value, {\n toValue,\n duration: 150,\n useNativeDriver: true,\n }).start();\n};\n\nexport default function ButtonBase(props: ButtonBaseProps) {\n const {\n children,\n disabled = false,\n disableThrottle = false,\n onPress,\n pressEffect = 'opacity',\n style: styleProp,\n throttleMillis = 650,\n ...otherProps\n } = props;\n\n const handlePress = useThrottle({\n periodMillis: disableThrottle ? 0 : throttleMillis,\n callback: onPress,\n });\n\n const opacity = useRef<Animated.Value>(new Animated.Value(ORIGINAL_OPACITY)).current;\n const scale = useRef<Animated.Value>(new Animated.Value(ORIGINAL_SCALE)).current;\n\n useEffect(() => {\n opacity.setValue(disabled ? DISABLED_OPACITY : ORIGINAL_OPACITY);\n }, [disabled]);\n\n const startScaleAnimation = useCallback<StartPressAnimation>((pressIn, isHover) => {\n if (!isHover) {\n startTimingAnimationWithDefaults(\n scale,\n pressIn ? MINIFIED_SCALE : ORIGINAL_SCALE,\n );\n }\n }, []);\n\n const startOpacityAnimation = useCallback<StartPressAnimation>((pressIn) => {\n if (pressIn) {\n opacity.setValue(ACTIVE_OPACITY);\n } else {\n startTimingAnimationWithDefaults(opacity, ORIGINAL_OPACITY);\n }\n }, []);\n\n const startPressAnimation = useCallback<StartPressAnimation>((pressIn, isHover = false) => {\n if (pressEffect === 'scale') {\n startScaleAnimation(pressIn, isHover);\n } else if (pressEffect === 'opacity') {\n startOpacityAnimation(pressIn, isHover);\n }\n }, [pressEffect]);\n\n const handlePressIn = useCallback(() => {\n startPressAnimation(true, false);\n }, [startPressAnimation]);\n\n const handlePressOut = useCallback(() => {\n startPressAnimation(false, false);\n }, [startPressAnimation]);\n\n const animatedStyle = {\n opacity,\n transform: [{ scale }],\n };\n\n const pressDelay = pressEffect === 'scale'\n ? SCALE_EFFECT_PRESS_IN_DELAY\n : 0;\n\n return (\n <AnimatedPressable\n disabled={disabled}\n onPress={handlePress}\n onPressIn={handlePressIn}\n onPressOut={handlePressOut}\n style={[\n animatedStyle,\n styleProp,\n ]}\n unstable_pressDelay={pressDelay}\n {...otherProps}\n >\n {typeof children !== 'function' ? (\n ({ hovered }) => {\n if (hovered !== undefined && !disabled) {\n startPressAnimation(hovered, true);\n }\n\n return children;\n }\n ) : children}\n </AnimatedPressable>\n );\n};\n"],"mappings":"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"}
@@ -1,10 +1,6 @@
1
- import React, { useEffect } from 'react';
2
- import Animated, { Easing, useAnimatedStyle, useSharedValue, withRepeat, withTiming } from 'react-native-reanimated';
1
+ import React, { useEffect, useRef } from 'react';
2
+ import { Animated, Easing } from 'react-native';
3
3
  import { CircularProgress as CircularProgressIcon } from '../internal/icons';
4
- const ANIMATION_CONFIG = {
5
- duration: 900,
6
- easing: Easing.linear
7
- };
8
4
  const MIN_ROTATE_DEGREE = 0;
9
5
  const MAX_ROTATE_DEGREE = 360;
10
6
 
@@ -22,14 +18,22 @@ export default function CircularProgress(props) {
22
18
  style: styleProp
23
19
  } = props;
24
20
  const styles = useStyles();
25
- const rotate = useSharedValue(MIN_ROTATE_DEGREE);
26
- const animatedStyle = useAnimatedStyle(() => ({
21
+ const rotate = useRef(new Animated.Value(MIN_ROTATE_DEGREE)).current;
22
+ const animatedStyle = {
27
23
  transform: [{
28
- rotate: `${rotate.value}deg`
24
+ rotate: rotate.interpolate({
25
+ inputRange: [MIN_ROTATE_DEGREE, MAX_ROTATE_DEGREE],
26
+ outputRange: [`${MIN_ROTATE_DEGREE}deg`, `${MAX_ROTATE_DEGREE}deg`]
27
+ })
29
28
  }]
30
- }), []);
29
+ };
31
30
  useEffect(() => {
32
- rotate.value = withRepeat(withTiming(MAX_ROTATE_DEGREE, ANIMATION_CONFIG), -1, false);
31
+ Animated.loop(Animated.timing(rotate, {
32
+ toValue: MAX_ROTATE_DEGREE,
33
+ duration: 900,
34
+ easing: Easing.linear,
35
+ useNativeDriver: true
36
+ })).start();
33
37
  }, []);
34
38
  return /*#__PURE__*/React.createElement(Animated.View, {
35
39
  children: /*#__PURE__*/React.createElement(CircularProgressIcon, null),
@@ -1 +1 @@
1
- {"version":3,"names":["React","useEffect","Animated","Easing","useAnimatedStyle","useSharedValue","withRepeat","withTiming","CircularProgress","CircularProgressIcon","ANIMATION_CONFIG","duration","easing","linear","MIN_ROTATE_DEGREE","MAX_ROTATE_DEGREE","useStyles","root","alignItems","justifyContent","props","style","styleProp","styles","rotate","animatedStyle","transform","value"],"sources":["CircularProgress.tsx"],"sourcesContent":["import React, { useEffect } from 'react';\nimport { ViewProps } from 'react-native';\nimport { NamedStylesStringUnion, UseStyles } from '@fountain-ui/styles';\nimport type { WithTimingConfig } from 'react-native-reanimated';\nimport Animated, { Easing, useAnimatedStyle, useSharedValue, withRepeat, withTiming } from 'react-native-reanimated';\nimport { CircularProgress as CircularProgressIcon } from '../internal/icons';\nimport { OverridableComponentProps } from '../types';\n\ntype CircularProgressStyles = NamedStylesStringUnion<'root'>;\n\nconst ANIMATION_CONFIG: Readonly<WithTimingConfig> = { duration: 900, easing: Easing.linear };\n\nconst MIN_ROTATE_DEGREE = 0;\nconst MAX_ROTATE_DEGREE = 360;\n\nconst useStyles: UseStyles<CircularProgressStyles> = function (): CircularProgressStyles {\n return {\n root: {\n alignItems: 'center',\n justifyContent: 'center',\n },\n };\n};\n\nexport default function CircularProgress(props: OverridableComponentProps<ViewProps>) {\n const { style: styleProp } = props;\n\n const styles = useStyles();\n\n const rotate = useSharedValue(MIN_ROTATE_DEGREE);\n\n const animatedStyle = useAnimatedStyle(() => ({\n transform: [{ rotate: `${rotate.value}deg` }],\n }), []);\n\n useEffect(() => {\n rotate.value = withRepeat(\n withTiming(MAX_ROTATE_DEGREE, ANIMATION_CONFIG),\n -1,\n false,\n );\n }, []);\n\n return (\n <Animated.View\n children={<CircularProgressIcon/>}\n style={[\n animatedStyle,\n styles.root,\n styleProp,\n ]}\n />\n );\n};\n"],"mappings":"AAAA,OAAOA,KAAP,IAAgBC,SAAhB,QAAiC,OAAjC;AAIA,OAAOC,QAAP,IAAmBC,MAAnB,EAA2BC,gBAA3B,EAA6CC,cAA7C,EAA6DC,UAA7D,EAAyEC,UAAzE,QAA2F,yBAA3F;AACA,SAASC,gBAAgB,IAAIC,oBAA7B,QAAyD,mBAAzD;AAKA,MAAMC,gBAA4C,GAAG;EAAEC,QAAQ,EAAE,GAAZ;EAAiBC,MAAM,EAAET,MAAM,CAACU;AAAhC,CAArD;AAEA,MAAMC,iBAAiB,GAAG,CAA1B;AACA,MAAMC,iBAAiB,GAAG,GAA1B;;AAEA,MAAMC,SAA4C,GAAG,YAAoC;EACrF,OAAO;IACHC,IAAI,EAAE;MACFC,UAAU,EAAE,QADV;MAEFC,cAAc,EAAE;IAFd;EADH,CAAP;AAMH,CAPD;;AASA,eAAe,SAASX,gBAAT,CAA0BY,KAA1B,EAAuE;EAClF,MAAM;IAAEC,KAAK,EAAEC;EAAT,IAAuBF,KAA7B;EAEA,MAAMG,MAAM,GAAGP,SAAS,EAAxB;EAEA,MAAMQ,MAAM,GAAGnB,cAAc,CAACS,iBAAD,CAA7B;EAEA,MAAMW,aAAa,GAAGrB,gBAAgB,CAAC,OAAO;IAC1CsB,SAAS,EAAE,CAAC;MAAEF,MAAM,EAAG,GAAEA,MAAM,CAACG,KAAM;IAA1B,CAAD;EAD+B,CAAP,CAAD,EAElC,EAFkC,CAAtC;EAIA1B,SAAS,CAAC,MAAM;IACZuB,MAAM,CAACG,KAAP,GAAerB,UAAU,CACrBC,UAAU,CAACQ,iBAAD,EAAoBL,gBAApB,CADW,EAErB,CAAC,CAFoB,EAGrB,KAHqB,CAAzB;EAKH,CANQ,EAMN,EANM,CAAT;EAQA,oBACI,oBAAC,QAAD,CAAU,IAAV;IACI,QAAQ,eAAE,oBAAC,oBAAD,OADd;IAEI,KAAK,EAAE,CACHe,aADG,EAEHF,MAAM,CAACN,IAFJ,EAGHK,SAHG;EAFX,EADJ;AAUH;AAAA"}
1
+ {"version":3,"names":["React","useEffect","useRef","Animated","Easing","CircularProgress","CircularProgressIcon","MIN_ROTATE_DEGREE","MAX_ROTATE_DEGREE","useStyles","root","alignItems","justifyContent","props","style","styleProp","styles","rotate","Value","current","animatedStyle","transform","interpolate","inputRange","outputRange","loop","timing","toValue","duration","easing","linear","useNativeDriver","start"],"sources":["CircularProgress.tsx"],"sourcesContent":["import React, { useEffect, useRef } from 'react';\nimport type { ViewProps } from 'react-native';\nimport { Animated, Easing } from 'react-native';\nimport { NamedStylesStringUnion, UseStyles } from '@fountain-ui/styles';\nimport { CircularProgress as CircularProgressIcon } from '../internal/icons';\nimport { OverridableComponentProps } from '../types';\n\ntype CircularProgressStyles = NamedStylesStringUnion<'root'>;\n\nconst MIN_ROTATE_DEGREE = 0;\nconst MAX_ROTATE_DEGREE = 360;\n\nconst useStyles: UseStyles<CircularProgressStyles> = function (): CircularProgressStyles {\n return {\n root: {\n alignItems: 'center',\n justifyContent: 'center',\n },\n };\n};\n\nexport default function CircularProgress(props: OverridableComponentProps<ViewProps>) {\n const { style: styleProp } = props;\n\n const styles = useStyles();\n\n const rotate = useRef(new Animated.Value(MIN_ROTATE_DEGREE)).current;\n\n const animatedStyle = {\n transform: [{\n rotate: rotate.interpolate({\n inputRange: [MIN_ROTATE_DEGREE, MAX_ROTATE_DEGREE],\n outputRange: [`${MIN_ROTATE_DEGREE}deg`, `${MAX_ROTATE_DEGREE}deg`],\n }),\n }],\n };\n\n useEffect(() => {\n Animated.loop(\n Animated.timing(\n rotate,\n {\n toValue: MAX_ROTATE_DEGREE,\n duration: 900,\n easing: Easing.linear,\n useNativeDriver: true,\n },\n ),\n ).start();\n }, []);\n\n return (\n <Animated.View\n children={<CircularProgressIcon/>}\n style={[\n animatedStyle,\n styles.root,\n styleProp,\n ]}\n />\n );\n};\n"],"mappings":"AAAA,OAAOA,KAAP,IAAgBC,SAAhB,EAA2BC,MAA3B,QAAyC,OAAzC;AAEA,SAASC,QAAT,EAAmBC,MAAnB,QAAiC,cAAjC;AAEA,SAASC,gBAAgB,IAAIC,oBAA7B,QAAyD,mBAAzD;AAKA,MAAMC,iBAAiB,GAAG,CAA1B;AACA,MAAMC,iBAAiB,GAAG,GAA1B;;AAEA,MAAMC,SAA4C,GAAG,YAAoC;EACrF,OAAO;IACHC,IAAI,EAAE;MACFC,UAAU,EAAE,QADV;MAEFC,cAAc,EAAE;IAFd;EADH,CAAP;AAMH,CAPD;;AASA,eAAe,SAASP,gBAAT,CAA0BQ,KAA1B,EAAuE;EAClF,MAAM;IAAEC,KAAK,EAAEC;EAAT,IAAuBF,KAA7B;EAEA,MAAMG,MAAM,GAAGP,SAAS,EAAxB;EAEA,MAAMQ,MAAM,GAAGf,MAAM,CAAC,IAAIC,QAAQ,CAACe,KAAb,CAAmBX,iBAAnB,CAAD,CAAN,CAA8CY,OAA7D;EAEA,MAAMC,aAAa,GAAG;IAClBC,SAAS,EAAE,CAAC;MACRJ,MAAM,EAAEA,MAAM,CAACK,WAAP,CAAmB;QACvBC,UAAU,EAAE,CAAChB,iBAAD,EAAoBC,iBAApB,CADW;QAEvBgB,WAAW,EAAE,CAAE,GAAEjB,iBAAkB,KAAtB,EAA6B,GAAEC,iBAAkB,KAAjD;MAFU,CAAnB;IADA,CAAD;EADO,CAAtB;EASAP,SAAS,CAAC,MAAM;IACZE,QAAQ,CAACsB,IAAT,CACItB,QAAQ,CAACuB,MAAT,CACIT,MADJ,EAEI;MACIU,OAAO,EAAEnB,iBADb;MAEIoB,QAAQ,EAAE,GAFd;MAGIC,MAAM,EAAEzB,MAAM,CAAC0B,MAHnB;MAIIC,eAAe,EAAE;IAJrB,CAFJ,CADJ,EAUEC,KAVF;EAWH,CAZQ,EAYN,EAZM,CAAT;EAcA,oBACI,oBAAC,QAAD,CAAU,IAAV;IACI,QAAQ,eAAE,oBAAC,oBAAD,OADd;IAEI,KAAK,EAAE,CACHZ,aADG,EAEHJ,MAAM,CAACN,IAFJ,EAGHK,SAHG;EAFX,EADJ;AAUH;AAAA"}
@@ -1,6 +1,6 @@
1
1
  function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
2
2
 
3
- import React from 'react';
3
+ import React, { cloneElement } from 'react';
4
4
  import { Platform, Text } from 'react-native';
5
5
  import Badge from '../Badge';
6
6
  import TabBase from '../TabBase';
@@ -26,9 +26,9 @@ export default function Tab(props) {
26
26
  const {
27
27
  badgeVisible = false,
28
28
  children,
29
- enableIndicator,
29
+ enableIndicator = false,
30
30
  icon: defaultIcon,
31
- selected,
31
+ selected = false,
32
32
  selectedIcon,
33
33
  variant = 'primary',
34
34
  style,
@@ -44,7 +44,7 @@ export default function Tab(props) {
44
44
  });
45
45
  const pressEffect = selected ? 'none' : 'opacity';
46
46
  const icon = selected ? selectedIcon || defaultIcon : defaultIcon;
47
- const iconElement = icon ? /*#__PURE__*/React.cloneElement(icon, {
47
+ const iconElement = icon ? /*#__PURE__*/cloneElement(icon, {
48
48
  fill: color
49
49
  }) : null;
50
50
  return /*#__PURE__*/React.createElement(TabBase, _extends({
@@ -57,7 +57,7 @@ export default function Tab(props) {
57
57
  }), /*#__PURE__*/React.createElement(Text, {
58
58
  children: children,
59
59
  style: css(fontStyle)
60
- }), enableIndicator ? /*#__PURE__*/React.createElement(TabIndicator, null) : null);
60
+ }), enableIndicator && selected ? /*#__PURE__*/React.createElement(TabIndicator, null) : null);
61
61
  }
62
62
  ;
63
63
  //# sourceMappingURL=Tab.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["React","Platform","Text","Badge","TabBase","createFontStyle","css","StyleSheet","useTheme","TabIndicator","styles","create","root","OS","minWidth","primary","minHeight","secondary","bottomNavigation","Tab","props","badgeVisible","children","enableIndicator","icon","defaultIcon","selected","selectedIcon","variant","style","otherProps","theme","vertical","color","palette","text","hint","tabBaseStyle","fontStyle","selector","typo","h2","button2","flag","pressEffect","iconElement","cloneElement","fill"],"sources":["Tab.tsx"],"sourcesContent":["import React from 'react';\nimport { Platform, Text } from 'react-native';\nimport Badge from '../Badge';\nimport TabBase from '../TabBase';\nimport type TabProps from './TabProps';\nimport { createFontStyle, css, StyleSheet, useTheme } from '../styles';\nimport TabIndicator from './TabIndicator';\n\nconst styles = StyleSheet.create({\n root: {\n // TODO: Remove redundant platform checking\n ...(Platform.OS === 'web' ? { minWidth: 'auto' } : {}),\n },\n primary: {\n minHeight: 48,\n },\n secondary: {\n minHeight: 48,\n },\n bottomNavigation: {\n minHeight: 56,\n },\n});\n\nexport default function Tab(props: TabProps) {\n const {\n badgeVisible = false,\n children,\n enableIndicator,\n icon: defaultIcon,\n selected,\n selectedIcon,\n variant = 'primary',\n style,\n ...otherProps\n } = props;\n\n const theme = useTheme();\n\n const vertical = variant === 'bottom-navigation';\n\n const color = selected ? theme.palette.text.primary : theme.palette.text.hint;\n\n const tabBaseStyle = css([\n styles.root,\n variant === 'primary'\n ? styles.primary\n : (variant === 'secondary' ? styles.secondary : styles.bottomNavigation),\n style,\n ]);\n\n const fontStyle = createFontStyle(theme, {\n selector: (typo) => variant === 'primary'\n ? typo.h2\n : (variant === 'secondary' ? typo.button2 : typo.flag),\n color,\n });\n\n const pressEffect = selected ? 'none' : 'opacity';\n\n const icon = selected ? (selectedIcon || defaultIcon) : defaultIcon;\n const iconElement = icon ? React.cloneElement(icon, { fill: color }) : null;\n\n return (\n <TabBase\n pressEffect={pressEffect}\n style={tabBaseStyle}\n vertical={vertical}\n {...otherProps}\n >\n <Badge\n children={iconElement}\n invisible={!badgeVisible}\n />\n\n <Text\n children={children}\n style={css(fontStyle)}\n />\n\n {enableIndicator ? <TabIndicator/> : null}\n </TabBase>\n );\n};\n"],"mappings":";;AAAA,OAAOA,KAAP,MAAkB,OAAlB;AACA,SAASC,QAAT,EAAmBC,IAAnB,QAA+B,cAA/B;AACA,OAAOC,KAAP,MAAkB,UAAlB;AACA,OAAOC,OAAP,MAAoB,YAApB;AAEA,SAASC,eAAT,EAA0BC,GAA1B,EAA+BC,UAA/B,EAA2CC,QAA3C,QAA2D,WAA3D;AACA,OAAOC,YAAP,MAAyB,gBAAzB;AAEA,MAAMC,MAAM,GAAGH,UAAU,CAACI,MAAX,CAAkB;EAC7BC,IAAI,EAAE,EACF;IACA,IAAIX,QAAQ,CAACY,EAAT,KAAgB,KAAhB,GAAwB;MAAEC,QAAQ,EAAE;IAAZ,CAAxB,GAA+C,EAAnD;EAFE,CADuB;EAK7BC,OAAO,EAAE;IACLC,SAAS,EAAE;EADN,CALoB;EAQ7BC,SAAS,EAAE;IACPD,SAAS,EAAE;EADJ,CARkB;EAW7BE,gBAAgB,EAAE;IACdF,SAAS,EAAE;EADG;AAXW,CAAlB,CAAf;AAgBA,eAAe,SAASG,GAAT,CAAaC,KAAb,EAA8B;EACzC,MAAM;IACFC,YAAY,GAAG,KADb;IAEFC,QAFE;IAGFC,eAHE;IAIFC,IAAI,EAAEC,WAJJ;IAKFC,QALE;IAMFC,YANE;IAOFC,OAAO,GAAG,SAPR;IAQFC,KARE;IASF,GAAGC;EATD,IAUFV,KAVJ;EAYA,MAAMW,KAAK,GAAGvB,QAAQ,EAAtB;EAEA,MAAMwB,QAAQ,GAAGJ,OAAO,KAAK,mBAA7B;EAEA,MAAMK,KAAK,GAAGP,QAAQ,GAAGK,KAAK,CAACG,OAAN,CAAcC,IAAd,CAAmBpB,OAAtB,GAAgCgB,KAAK,CAACG,OAAN,CAAcC,IAAd,CAAmBC,IAAzE;EAEA,MAAMC,YAAY,GAAG/B,GAAG,CAAC,CACrBI,MAAM,CAACE,IADc,EAErBgB,OAAO,KAAK,SAAZ,GACMlB,MAAM,CAACK,OADb,GAEOa,OAAO,KAAK,WAAZ,GAA0BlB,MAAM,CAACO,SAAjC,GAA6CP,MAAM,CAACQ,gBAJtC,EAKrBW,KALqB,CAAD,CAAxB;EAQA,MAAMS,SAAS,GAAGjC,eAAe,CAAC0B,KAAD,EAAQ;IACrCQ,QAAQ,EAAGC,IAAD,IAAUZ,OAAO,KAAK,SAAZ,GACdY,IAAI,CAACC,EADS,GAEbb,OAAO,KAAK,WAAZ,GAA0BY,IAAI,CAACE,OAA/B,GAAyCF,IAAI,CAACG,IAHhB;IAIrCV;EAJqC,CAAR,CAAjC;EAOA,MAAMW,WAAW,GAAGlB,QAAQ,GAAG,MAAH,GAAY,SAAxC;EAEA,MAAMF,IAAI,GAAGE,QAAQ,GAAIC,YAAY,IAAIF,WAApB,GAAmCA,WAAxD;EACA,MAAMoB,WAAW,GAAGrB,IAAI,gBAAGxB,KAAK,CAAC8C,YAAN,CAAmBtB,IAAnB,EAAyB;IAAEuB,IAAI,EAAEd;EAAR,CAAzB,CAAH,GAA+C,IAAvE;EAEA,oBACI,oBAAC,OAAD;IACI,WAAW,EAAEW,WADjB;IAEI,KAAK,EAAEP,YAFX;IAGI,QAAQ,EAAEL;EAHd,GAIQF,UAJR,gBAMI,oBAAC,KAAD;IACI,QAAQ,EAAEe,WADd;IAEI,SAAS,EAAE,CAACxB;EAFhB,EANJ,eAWI,oBAAC,IAAD;IACI,QAAQ,EAAEC,QADd;IAEI,KAAK,EAAEhB,GAAG,CAACgC,SAAD;EAFd,EAXJ,EAgBKf,eAAe,gBAAG,oBAAC,YAAD,OAAH,GAAqB,IAhBzC,CADJ;AAoBH;AAAA"}
1
+ {"version":3,"names":["React","cloneElement","Platform","Text","Badge","TabBase","createFontStyle","css","StyleSheet","useTheme","TabIndicator","styles","create","root","OS","minWidth","primary","minHeight","secondary","bottomNavigation","Tab","props","badgeVisible","children","enableIndicator","icon","defaultIcon","selected","selectedIcon","variant","style","otherProps","theme","vertical","color","palette","text","hint","tabBaseStyle","fontStyle","selector","typo","h2","button2","flag","pressEffect","iconElement","fill"],"sources":["Tab.tsx"],"sourcesContent":["import React, { cloneElement } from 'react';\nimport { Platform, Text } from 'react-native';\nimport Badge from '../Badge';\nimport TabBase from '../TabBase';\nimport type TabProps from './TabProps';\nimport { createFontStyle, css, StyleSheet, useTheme } from '../styles';\nimport TabIndicator from './TabIndicator';\n\nconst styles = StyleSheet.create({\n root: {\n // TODO: Remove redundant platform checking\n ...(Platform.OS === 'web' ? { minWidth: 'auto' } : {}),\n },\n primary: {\n minHeight: 48,\n },\n secondary: {\n minHeight: 48,\n },\n bottomNavigation: {\n minHeight: 56,\n },\n});\n\nexport default function Tab(props: TabProps) {\n const {\n badgeVisible = false,\n children,\n enableIndicator = false,\n icon: defaultIcon,\n selected = false,\n selectedIcon,\n variant = 'primary',\n style,\n ...otherProps\n } = props;\n\n const theme = useTheme();\n\n const vertical = variant === 'bottom-navigation';\n\n const color = selected ? theme.palette.text.primary : theme.palette.text.hint;\n\n const tabBaseStyle = css([\n styles.root,\n variant === 'primary'\n ? styles.primary\n : (variant === 'secondary' ? styles.secondary : styles.bottomNavigation),\n style,\n ]);\n\n const fontStyle = createFontStyle(theme, {\n selector: (typo) => variant === 'primary'\n ? typo.h2\n : (variant === 'secondary' ? typo.button2 : typo.flag),\n color,\n });\n\n const pressEffect = selected ? 'none' : 'opacity';\n\n const icon = selected ? (selectedIcon || defaultIcon) : defaultIcon;\n const iconElement = icon ? cloneElement(icon, { fill: color }) : null;\n\n return (\n <TabBase\n pressEffect={pressEffect}\n style={tabBaseStyle}\n vertical={vertical}\n {...otherProps}\n >\n <Badge\n children={iconElement}\n invisible={!badgeVisible}\n />\n\n <Text\n children={children}\n style={css(fontStyle)}\n />\n\n {(enableIndicator && selected) ? <TabIndicator/> : null}\n </TabBase>\n );\n};\n"],"mappings":";;AAAA,OAAOA,KAAP,IAAgBC,YAAhB,QAAoC,OAApC;AACA,SAASC,QAAT,EAAmBC,IAAnB,QAA+B,cAA/B;AACA,OAAOC,KAAP,MAAkB,UAAlB;AACA,OAAOC,OAAP,MAAoB,YAApB;AAEA,SAASC,eAAT,EAA0BC,GAA1B,EAA+BC,UAA/B,EAA2CC,QAA3C,QAA2D,WAA3D;AACA,OAAOC,YAAP,MAAyB,gBAAzB;AAEA,MAAMC,MAAM,GAAGH,UAAU,CAACI,MAAX,CAAkB;EAC7BC,IAAI,EAAE,EACF;IACA,IAAIX,QAAQ,CAACY,EAAT,KAAgB,KAAhB,GAAwB;MAAEC,QAAQ,EAAE;IAAZ,CAAxB,GAA+C,EAAnD;EAFE,CADuB;EAK7BC,OAAO,EAAE;IACLC,SAAS,EAAE;EADN,CALoB;EAQ7BC,SAAS,EAAE;IACPD,SAAS,EAAE;EADJ,CARkB;EAW7BE,gBAAgB,EAAE;IACdF,SAAS,EAAE;EADG;AAXW,CAAlB,CAAf;AAgBA,eAAe,SAASG,GAAT,CAAaC,KAAb,EAA8B;EACzC,MAAM;IACFC,YAAY,GAAG,KADb;IAEFC,QAFE;IAGFC,eAAe,GAAG,KAHhB;IAIFC,IAAI,EAAEC,WAJJ;IAKFC,QAAQ,GAAG,KALT;IAMFC,YANE;IAOFC,OAAO,GAAG,SAPR;IAQFC,KARE;IASF,GAAGC;EATD,IAUFV,KAVJ;EAYA,MAAMW,KAAK,GAAGvB,QAAQ,EAAtB;EAEA,MAAMwB,QAAQ,GAAGJ,OAAO,KAAK,mBAA7B;EAEA,MAAMK,KAAK,GAAGP,QAAQ,GAAGK,KAAK,CAACG,OAAN,CAAcC,IAAd,CAAmBpB,OAAtB,GAAgCgB,KAAK,CAACG,OAAN,CAAcC,IAAd,CAAmBC,IAAzE;EAEA,MAAMC,YAAY,GAAG/B,GAAG,CAAC,CACrBI,MAAM,CAACE,IADc,EAErBgB,OAAO,KAAK,SAAZ,GACMlB,MAAM,CAACK,OADb,GAEOa,OAAO,KAAK,WAAZ,GAA0BlB,MAAM,CAACO,SAAjC,GAA6CP,MAAM,CAACQ,gBAJtC,EAKrBW,KALqB,CAAD,CAAxB;EAQA,MAAMS,SAAS,GAAGjC,eAAe,CAAC0B,KAAD,EAAQ;IACrCQ,QAAQ,EAAGC,IAAD,IAAUZ,OAAO,KAAK,SAAZ,GACdY,IAAI,CAACC,EADS,GAEbb,OAAO,KAAK,WAAZ,GAA0BY,IAAI,CAACE,OAA/B,GAAyCF,IAAI,CAACG,IAHhB;IAIrCV;EAJqC,CAAR,CAAjC;EAOA,MAAMW,WAAW,GAAGlB,QAAQ,GAAG,MAAH,GAAY,SAAxC;EAEA,MAAMF,IAAI,GAAGE,QAAQ,GAAIC,YAAY,IAAIF,WAApB,GAAmCA,WAAxD;EACA,MAAMoB,WAAW,GAAGrB,IAAI,gBAAGxB,YAAY,CAACwB,IAAD,EAAO;IAAEsB,IAAI,EAAEb;EAAR,CAAP,CAAf,GAAyC,IAAjE;EAEA,oBACI,oBAAC,OAAD;IACI,WAAW,EAAEW,WADjB;IAEI,KAAK,EAAEP,YAFX;IAGI,QAAQ,EAAEL;EAHd,GAIQF,UAJR,gBAMI,oBAAC,KAAD;IACI,QAAQ,EAAEe,WADd;IAEI,SAAS,EAAE,CAACxB;EAFhB,EANJ,eAWI,oBAAC,IAAD;IACI,QAAQ,EAAEC,QADd;IAEI,KAAK,EAAEhB,GAAG,CAACgC,SAAD;EAFd,EAXJ,EAgBMf,eAAe,IAAIG,QAApB,gBAAgC,oBAAC,YAAD,OAAhC,GAAkD,IAhBvD,CADJ;AAoBH;AAAA"}
@@ -0,0 +1,18 @@
1
+ import { cloneElement, useState } from 'react';
2
+ import { runOnJS, useAnimatedReaction } from 'react-native-reanimated';
3
+ export default function IndexAwareTab(props) {
4
+ const {
5
+ children,
6
+ index,
7
+ sharedIndex
8
+ } = props;
9
+ const [selected, setSelected] = useState(index === sharedIndex.value);
10
+ useAnimatedReaction(() => index === sharedIndex.value, result => {
11
+ runOnJS(setSelected)(result);
12
+ }, [index]);
13
+ return /*#__PURE__*/cloneElement(children, {
14
+ selected
15
+ });
16
+ }
17
+ ;
18
+ //# sourceMappingURL=IndexAwareTab.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["cloneElement","useState","runOnJS","useAnimatedReaction","IndexAwareTab","props","children","index","sharedIndex","selected","setSelected","value","result"],"sources":["IndexAwareTab.tsx"],"sourcesContent":["import type { ReactElement } from 'react';\nimport React, { cloneElement, useState } from 'react';\nimport type { SharedValue } from 'react-native-reanimated';\nimport { runOnJS, useAnimatedReaction } from 'react-native-reanimated';\n\nexport interface IndexAwareTabProps {\n children: ReactElement;\n index: number;\n sharedIndex: SharedValue<number>;\n}\n\nexport default function IndexAwareTab(props: IndexAwareTabProps) {\n const {\n children,\n index,\n sharedIndex,\n } = props;\n\n const [selected, setSelected] = useState(index === sharedIndex.value);\n\n useAnimatedReaction(\n () => index === sharedIndex.value,\n (result) => {\n runOnJS(setSelected)(result);\n },\n [index],\n );\n\n return cloneElement(children, { selected });\n};\n"],"mappings":"AACA,SAAgBA,YAAhB,EAA8BC,QAA9B,QAA8C,OAA9C;AAEA,SAASC,OAAT,EAAkBC,mBAAlB,QAA6C,yBAA7C;AAQA,eAAe,SAASC,aAAT,CAAuBC,KAAvB,EAAkD;EAC7D,MAAM;IACFC,QADE;IAEFC,KAFE;IAGFC;EAHE,IAIFH,KAJJ;EAMA,MAAM,CAACI,QAAD,EAAWC,WAAX,IAA0BT,QAAQ,CAACM,KAAK,KAAKC,WAAW,CAACG,KAAvB,CAAxC;EAEAR,mBAAmB,CACf,MAAMI,KAAK,KAAKC,WAAW,CAACG,KADb,EAEdC,MAAD,IAAY;IACRV,OAAO,CAACQ,WAAD,CAAP,CAAqBE,MAArB;EACH,CAJc,EAKf,CAACL,KAAD,CALe,CAAnB;EAQA,oBAAOP,YAAY,CAACM,QAAD,EAAW;IAAEG;EAAF,CAAX,CAAnB;AACH;AAAA"}
@@ -1,17 +1,22 @@
1
1
  function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
2
2
 
3
3
  import React from 'react';
4
- import Animated, { useAnimatedStyle } from 'react-native-reanimated';
4
+ import Animated, { Easing, useAnimatedStyle, withTiming } from 'react-native-reanimated';
5
5
  import { useTheme } from '../styles';
6
6
  import { defaultCoordinate } from './TabCoordinate';
7
+ const INDICATOR_WIDTH = 10;
8
+ const INDICATOR_HEIGHT = 4;
9
+ const SCROLLABLE_TABS_INSET = 12 * 2;
7
10
 
8
11
  const useStyles = function () {
9
12
  const theme = useTheme();
10
13
  return {
11
14
  root: {
12
15
  backgroundColor: theme.palette.secondary.main,
16
+ left: 0,
13
17
  bottom: 0,
14
- height: 4,
18
+ width: INDICATOR_WIDTH,
19
+ height: INDICATOR_HEIGHT,
15
20
  position: 'absolute'
16
21
  },
17
22
  disabled: {
@@ -20,29 +25,36 @@ const useStyles = function () {
20
25
  };
21
26
  };
22
27
 
28
+ const ANIMATION_CONFIG = {
29
+ duration: 300,
30
+ easing: Easing.out(Easing.exp)
31
+ };
23
32
  export default function TabIndicator(props) {
24
33
  const {
25
34
  coordinates,
26
35
  disabled,
27
36
  scrollable,
28
- scrollValue,
37
+ sharedIndex,
29
38
  style,
30
39
  ...otherProps
31
40
  } = props;
32
41
  const styles = useStyles();
33
42
  const animatedStyle = useAnimatedStyle(() => {
34
- const rawScrollValue = scrollValue.value;
35
- const index = Math.floor(rawScrollValue);
36
- const offset = rawScrollValue % 1;
37
- const coordinate = coordinates[index] ?? defaultCoordinate;
38
- const nextCoordinate = coordinates[index + 1] ?? defaultCoordinate;
39
- const x1 = offset * nextCoordinate.x1 + (1 - offset) * coordinate.x1;
40
- const x2 = offset * nextCoordinate.x2 + (1 - offset) * coordinate.x2;
41
- const leftInset = scrollable ? 12 : 0;
42
- const rightInset = scrollable ? 24 : 0;
43
+ const index = sharedIndex.value;
44
+ const {
45
+ x1,
46
+ x2
47
+ } = coordinates[index] ?? defaultCoordinate;
48
+ const tabWidth = x2 - x1;
49
+ const translateX = x1 + (tabWidth - INDICATOR_WIDTH) / 2;
50
+ const inset = scrollable ? SCROLLABLE_TABS_INSET : 0;
51
+ const scaleX = (tabWidth - inset) / INDICATOR_WIDTH;
43
52
  return {
44
- left: x1 + leftInset,
45
- width: Math.max(x2 - x1 - rightInset, 0)
53
+ transform: [{
54
+ translateX: withTiming(translateX, ANIMATION_CONFIG)
55
+ }, {
56
+ scaleX: withTiming(scaleX, ANIMATION_CONFIG)
57
+ }]
46
58
  };
47
59
  }, [coordinates, scrollable]);
48
60
  return /*#__PURE__*/React.createElement(Animated.View, _extends({
@@ -1 +1 @@
1
- {"version":3,"names":["React","Animated","useAnimatedStyle","useTheme","defaultCoordinate","useStyles","theme","root","backgroundColor","palette","secondary","main","bottom","height","position","disabled","TabIndicator","props","coordinates","scrollable","scrollValue","style","otherProps","styles","animatedStyle","rawScrollValue","value","index","Math","floor","offset","coordinate","nextCoordinate","x1","x2","leftInset","rightInset","left","width","max","undefined"],"sources":["TabIndicator.tsx"],"sourcesContent":["import React from 'react';\nimport Animated, { useAnimatedStyle } from 'react-native-reanimated';\nimport { NamedStylesStringUnion, UseStyles } from '@fountain-ui/styles';\nimport { useTheme } from '../styles';\nimport type TabIndicatorProps from './TabIndicatorProps';\nimport { defaultCoordinate } from './TabCoordinate';\n\ntype TabIndicatorStyles = NamedStylesStringUnion<'root' | 'disabled'>;\n\nconst useStyles: UseStyles<TabIndicatorStyles> = function (): TabIndicatorStyles {\n const theme = useTheme();\n\n return {\n root: {\n backgroundColor: theme.palette.secondary.main,\n bottom: 0,\n height: 4,\n position: 'absolute',\n },\n disabled: {\n height: 0,\n },\n };\n};\n\nexport default function TabIndicator(props: TabIndicatorProps) {\n const {\n coordinates,\n disabled,\n scrollable,\n scrollValue,\n style,\n ...otherProps\n } = props;\n\n const styles = useStyles();\n\n const animatedStyle = useAnimatedStyle(() => {\n const rawScrollValue = scrollValue.value;\n\n const index = Math.floor(rawScrollValue);\n const offset = rawScrollValue % 1;\n\n const coordinate = coordinates[index] ?? defaultCoordinate;\n const nextCoordinate = coordinates[index + 1] ?? defaultCoordinate;\n\n const x1 = (offset * nextCoordinate.x1 + (1 - offset) * coordinate.x1);\n const x2 = (offset * nextCoordinate.x2 + (1 - offset) * coordinate.x2);\n\n const leftInset = scrollable ? 12 : 0;\n const rightInset = scrollable ? 24 : 0;\n\n return {\n left: x1 + leftInset,\n width: Math.max(x2 - x1 - rightInset, 0),\n };\n }, [coordinates, scrollable]);\n\n return (\n <Animated.View\n style={[\n styles.root,\n disabled ? styles.disabled : undefined,\n animatedStyle,\n style,\n ]}\n {...otherProps}\n />\n );\n};\n"],"mappings":";;AAAA,OAAOA,KAAP,MAAkB,OAAlB;AACA,OAAOC,QAAP,IAAmBC,gBAAnB,QAA2C,yBAA3C;AAEA,SAASC,QAAT,QAAyB,WAAzB;AAEA,SAASC,iBAAT,QAAkC,iBAAlC;;AAIA,MAAMC,SAAwC,GAAG,YAAgC;EAC7E,MAAMC,KAAK,GAAGH,QAAQ,EAAtB;EAEA,OAAO;IACHI,IAAI,EAAE;MACFC,eAAe,EAAEF,KAAK,CAACG,OAAN,CAAcC,SAAd,CAAwBC,IADvC;MAEFC,MAAM,EAAE,CAFN;MAGFC,MAAM,EAAE,CAHN;MAIFC,QAAQ,EAAE;IAJR,CADH;IAOHC,QAAQ,EAAE;MACNF,MAAM,EAAE;IADF;EAPP,CAAP;AAWH,CAdD;;AAgBA,eAAe,SAASG,YAAT,CAAsBC,KAAtB,EAAgD;EAC3D,MAAM;IACFC,WADE;IAEFH,QAFE;IAGFI,UAHE;IAIFC,WAJE;IAKFC,KALE;IAMF,GAAGC;EAND,IAOFL,KAPJ;EASA,MAAMM,MAAM,GAAGlB,SAAS,EAAxB;EAEA,MAAMmB,aAAa,GAAGtB,gBAAgB,CAAC,MAAM;IACzC,MAAMuB,cAAc,GAAGL,WAAW,CAACM,KAAnC;IAEA,MAAMC,KAAK,GAAGC,IAAI,CAACC,KAAL,CAAWJ,cAAX,CAAd;IACA,MAAMK,MAAM,GAAGL,cAAc,GAAG,CAAhC;IAEA,MAAMM,UAAU,GAAGb,WAAW,CAACS,KAAD,CAAX,IAAsBvB,iBAAzC;IACA,MAAM4B,cAAc,GAAGd,WAAW,CAACS,KAAK,GAAG,CAAT,CAAX,IAA0BvB,iBAAjD;IAEA,MAAM6B,EAAE,GAAIH,MAAM,GAAGE,cAAc,CAACC,EAAxB,GAA6B,CAAC,IAAIH,MAAL,IAAeC,UAAU,CAACE,EAAnE;IACA,MAAMC,EAAE,GAAIJ,MAAM,GAAGE,cAAc,CAACE,EAAxB,GAA6B,CAAC,IAAIJ,MAAL,IAAeC,UAAU,CAACG,EAAnE;IAEA,MAAMC,SAAS,GAAGhB,UAAU,GAAG,EAAH,GAAQ,CAApC;IACA,MAAMiB,UAAU,GAAGjB,UAAU,GAAG,EAAH,GAAQ,CAArC;IAEA,OAAO;MACHkB,IAAI,EAAEJ,EAAE,GAAGE,SADR;MAEHG,KAAK,EAAEV,IAAI,CAACW,GAAL,CAASL,EAAE,GAAGD,EAAL,GAAUG,UAAnB,EAA+B,CAA/B;IAFJ,CAAP;EAIH,CAnBqC,EAmBnC,CAAClB,WAAD,EAAcC,UAAd,CAnBmC,CAAtC;EAqBA,oBACI,oBAAC,QAAD,CAAU,IAAV;IACI,KAAK,EAAE,CACHI,MAAM,CAAChB,IADJ,EAEHQ,QAAQ,GAAGQ,MAAM,CAACR,QAAV,GAAqByB,SAF1B,EAGHhB,aAHG,EAIHH,KAJG;EADX,GAOQC,UAPR,EADJ;AAWH;AAAA"}
1
+ {"version":3,"names":["React","Animated","Easing","useAnimatedStyle","withTiming","useTheme","defaultCoordinate","INDICATOR_WIDTH","INDICATOR_HEIGHT","SCROLLABLE_TABS_INSET","useStyles","theme","root","backgroundColor","palette","secondary","main","left","bottom","width","height","position","disabled","ANIMATION_CONFIG","duration","easing","out","exp","TabIndicator","props","coordinates","scrollable","sharedIndex","style","otherProps","styles","animatedStyle","index","value","x1","x2","tabWidth","translateX","inset","scaleX","transform","undefined"],"sources":["TabIndicator.tsx"],"sourcesContent":["import React from 'react';\nimport type { WithTimingConfig } from 'react-native-reanimated';\nimport Animated, { Easing, useAnimatedStyle, withTiming } from 'react-native-reanimated';\nimport { NamedStylesStringUnion, UseStyles } from '@fountain-ui/styles';\nimport { useTheme } from '../styles';\nimport type TabIndicatorProps from './TabIndicatorProps';\nimport { defaultCoordinate } from './TabCoordinate';\n\ntype TabIndicatorStyles = NamedStylesStringUnion<'root' | 'disabled'>;\n\nconst INDICATOR_WIDTH = 10;\nconst INDICATOR_HEIGHT = 4;\n\nconst SCROLLABLE_TABS_INSET = 12 * 2;\n\nconst useStyles: UseStyles<TabIndicatorStyles> = function (): TabIndicatorStyles {\n const theme = useTheme();\n\n return {\n root: {\n backgroundColor: theme.palette.secondary.main,\n left: 0,\n bottom: 0,\n width: INDICATOR_WIDTH,\n height: INDICATOR_HEIGHT,\n position: 'absolute',\n },\n disabled: {\n height: 0,\n },\n };\n};\n\nconst ANIMATION_CONFIG: Readonly<WithTimingConfig> = {\n duration: 300,\n easing: Easing.out(Easing.exp),\n};\n\nexport default function TabIndicator(props: TabIndicatorProps) {\n const {\n coordinates,\n disabled,\n scrollable,\n sharedIndex,\n style,\n ...otherProps\n } = props;\n\n const styles = useStyles();\n\n const animatedStyle = useAnimatedStyle(() => {\n const index = sharedIndex.value;\n\n const { x1, x2 } = coordinates[index] ?? defaultCoordinate;\n\n const tabWidth = x2 - x1;\n\n const translateX = x1 + (tabWidth - INDICATOR_WIDTH) / 2;\n\n const inset = scrollable ? SCROLLABLE_TABS_INSET : 0;\n const scaleX = (tabWidth - inset) / INDICATOR_WIDTH;\n\n return {\n transform: [\n { translateX: withTiming(translateX, ANIMATION_CONFIG) },\n { scaleX: withTiming(scaleX, ANIMATION_CONFIG) },\n ],\n };\n }, [coordinates, scrollable]);\n\n return (\n <Animated.View\n style={[\n styles.root,\n disabled ? styles.disabled : undefined,\n animatedStyle,\n style,\n ]}\n {...otherProps}\n />\n );\n};\n"],"mappings":";;AAAA,OAAOA,KAAP,MAAkB,OAAlB;AAEA,OAAOC,QAAP,IAAmBC,MAAnB,EAA2BC,gBAA3B,EAA6CC,UAA7C,QAA+D,yBAA/D;AAEA,SAASC,QAAT,QAAyB,WAAzB;AAEA,SAASC,iBAAT,QAAkC,iBAAlC;AAIA,MAAMC,eAAe,GAAG,EAAxB;AACA,MAAMC,gBAAgB,GAAG,CAAzB;AAEA,MAAMC,qBAAqB,GAAG,KAAK,CAAnC;;AAEA,MAAMC,SAAwC,GAAG,YAAgC;EAC7E,MAAMC,KAAK,GAAGN,QAAQ,EAAtB;EAEA,OAAO;IACHO,IAAI,EAAE;MACFC,eAAe,EAAEF,KAAK,CAACG,OAAN,CAAcC,SAAd,CAAwBC,IADvC;MAEFC,IAAI,EAAE,CAFJ;MAGFC,MAAM,EAAE,CAHN;MAIFC,KAAK,EAAEZ,eAJL;MAKFa,MAAM,EAAEZ,gBALN;MAMFa,QAAQ,EAAE;IANR,CADH;IASHC,QAAQ,EAAE;MACNF,MAAM,EAAE;IADF;EATP,CAAP;AAaH,CAhBD;;AAkBA,MAAMG,gBAA4C,GAAG;EACjDC,QAAQ,EAAE,GADuC;EAEjDC,MAAM,EAAEvB,MAAM,CAACwB,GAAP,CAAWxB,MAAM,CAACyB,GAAlB;AAFyC,CAArD;AAKA,eAAe,SAASC,YAAT,CAAsBC,KAAtB,EAAgD;EAC3D,MAAM;IACFC,WADE;IAEFR,QAFE;IAGFS,UAHE;IAIFC,WAJE;IAKFC,KALE;IAMF,GAAGC;EAND,IAOFL,KAPJ;EASA,MAAMM,MAAM,GAAGzB,SAAS,EAAxB;EAEA,MAAM0B,aAAa,GAAGjC,gBAAgB,CAAC,MAAM;IACzC,MAAMkC,KAAK,GAAGL,WAAW,CAACM,KAA1B;IAEA,MAAM;MAAEC,EAAF;MAAMC;IAAN,IAAaV,WAAW,CAACO,KAAD,CAAX,IAAsB/B,iBAAzC;IAEA,MAAMmC,QAAQ,GAAGD,EAAE,GAAGD,EAAtB;IAEA,MAAMG,UAAU,GAAGH,EAAE,GAAG,CAACE,QAAQ,GAAGlC,eAAZ,IAA+B,CAAvD;IAEA,MAAMoC,KAAK,GAAGZ,UAAU,GAAGtB,qBAAH,GAA2B,CAAnD;IACA,MAAMmC,MAAM,GAAG,CAACH,QAAQ,GAAGE,KAAZ,IAAqBpC,eAApC;IAEA,OAAO;MACHsC,SAAS,EAAE,CACP;QAAEH,UAAU,EAAEtC,UAAU,CAACsC,UAAD,EAAanB,gBAAb;MAAxB,CADO,EAEP;QAAEqB,MAAM,EAAExC,UAAU,CAACwC,MAAD,EAASrB,gBAAT;MAApB,CAFO;IADR,CAAP;EAMH,CAlBqC,EAkBnC,CAACO,WAAD,EAAcC,UAAd,CAlBmC,CAAtC;EAoBA,oBACI,oBAAC,QAAD,CAAU,IAAV;IACI,KAAK,EAAE,CACHI,MAAM,CAACvB,IADJ,EAEHU,QAAQ,GAAGa,MAAM,CAACb,QAAV,GAAqBwB,SAF1B,EAGHV,aAHG,EAIHH,KAJG;EADX,GAOQC,UAPR,EADJ;AAWH;AAAA"}
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["TabIndicatorProps.ts"],"sourcesContent":["import type { ViewProps } from 'react-native';\nimport type { SharedValue } from 'react-native-reanimated';\nimport type { OverridableComponentProps } from '../types';\nimport type TabCoordinate from './TabCoordinate';\n\nexport default interface TabIndicatorProps extends OverridableComponentProps<ViewProps, {\n /**\n * Tab item coordinates.\n */\n coordinates: TabCoordinate[];\n\n /**\n * If `true`, the indicator is disabled.\n */\n disabled: boolean;\n\n /**\n * If `true`, the tab will be able to scroll.\n */\n scrollable: boolean;\n\n /**\n * Scrollable value for using animated interpolation.\n */\n scrollValue: SharedValue<number>;\n}> {}\n"],"mappings":""}
1
+ {"version":3,"names":[],"sources":["TabIndicatorProps.ts"],"sourcesContent":["import type { ViewProps } from 'react-native';\nimport type { SharedValue } from 'react-native-reanimated';\nimport type { OverridableComponentProps } from '../types';\nimport type TabCoordinate from './TabCoordinate';\n\nexport default interface TabIndicatorProps extends OverridableComponentProps<ViewProps, {\n /**\n * Tab item coordinates.\n */\n coordinates: TabCoordinate[];\n\n /**\n * If `true`, the indicator is disabled.\n */\n disabled: boolean;\n\n /**\n * If `true`, the tab will be able to scroll.\n */\n scrollable: boolean;\n\n /**\n * Shared index value for using animated interpolation.\n */\n sharedIndex: SharedValue<number>;\n}> {}\n"],"mappings":""}
@@ -1,12 +1,11 @@
1
- function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
2
-
3
- import React, { cloneElement, useEffect, useMemo, useRef } from 'react';
1
+ import React, { cloneElement, forwardRef, useImperativeHandle } from 'react';
4
2
  import { ScrollView, View } from 'react-native';
5
- import { Easing, useSharedValue, withTiming } from 'react-native-reanimated';
3
+ import { useSharedValue } from 'react-native-reanimated';
6
4
  import { css, useTheme } from '../styles';
7
5
  import TabIndicator from './TabIndicator';
8
- import useTabsWidth from './useTabsWidth';
6
+ import IndexAwareTab from './IndexAwareTab';
9
7
  import useTabCoordinates from './useTabCoordinates';
8
+ import useScrollViewReaction from './useScrollViewReaction';
10
9
 
11
10
  const useStyles = function () {
12
11
  const theme = useTheme();
@@ -24,62 +23,42 @@ const useStyles = function () {
24
23
  };
25
24
  };
26
25
 
27
- const ANIMATION_CONFIG = {
28
- duration: 200,
29
- easing: Easing.out(Easing.exp)
30
- };
31
- export default function Tabs(props) {
26
+ const Tabs = /*#__PURE__*/forwardRef(function Tabs(props, ref) {
32
27
  const {
33
28
  children,
34
- index: indexProp,
29
+ initialIndex = 0,
35
30
  disableIndicator = false,
36
31
  keyboardDismissMode = 'none',
37
32
  keyboardShouldPersistTaps = 'never',
38
33
  onChange,
39
34
  scrollable = false,
40
- scrollValue: scrollValueProp,
41
35
  style,
42
36
  variant = 'primary',
43
- ...otherProps
37
+ UNSTABLE_sharedIndex
44
38
  } = props;
39
+ const fallbackSharedIndex = useSharedValue(initialIndex);
40
+ const sharedIndex = UNSTABLE_sharedIndex ?? fallbackSharedIndex;
41
+
42
+ const getCurrentIndex = () => sharedIndex.value;
43
+
44
+ const setTab = newIndex => {
45
+ sharedIndex.value = newIndex;
46
+ };
47
+
48
+ useImperativeHandle(ref, () => ({
49
+ getCurrentIndex,
50
+ setTab
51
+ }), [sharedIndex]);
45
52
  const styles = useStyles();
46
- const [containerWidth, handleLayout] = useTabsWidth();
47
- const scrollViewRef = useRef(null);
48
53
  const {
49
54
  coordinates,
50
55
  updateCoordinate
51
56
  } = useTabCoordinates(children);
52
- const internalScrollValue = useSharedValue(0);
53
- const scrollValue = scrollValueProp ?? internalScrollValue;
57
+ const {
58
+ scrollViewRef,
59
+ onLayout
60
+ } = useScrollViewReaction(sharedIndex, coordinates);
54
61
  const isReadyToRenderIndicator = coordinates.length > 0;
55
- useEffect(() => {
56
- const animateTab = index => {
57
- scrollValue.value = withTiming(index, ANIMATION_CONFIG);
58
- };
59
-
60
- animateTab(indexProp);
61
- }, [indexProp, scrollValue]);
62
- const scrollPosition = useMemo(() => {
63
- const coordinate = coordinates[indexProp - 1];
64
-
65
- if (coordinate) {
66
- const tabWidth = coordinate.x2 - coordinate.x1;
67
- return Math.floor(coordinate.x1 + tabWidth / 2);
68
- }
69
-
70
- return 0;
71
- }, [indexProp, coordinates]);
72
- useEffect(() => {
73
- const scrollView = scrollViewRef.current;
74
-
75
- if (scrollView) {
76
- scrollView.scrollTo({
77
- x: scrollPosition,
78
- y: 0,
79
- animated: true
80
- });
81
- }
82
- }, [scrollPosition, containerWidth]);
83
62
  const tabElements = React.Children.map(children, (child, index) => {
84
63
  const onLayout = event => {
85
64
  const {
@@ -98,34 +77,37 @@ export default function Tabs(props) {
98
77
  const onPress = () => {
99
78
  var _child$props$onPress, _child$props;
100
79
 
80
+ setTab(index);
101
81
  onChange === null || onChange === void 0 ? void 0 : onChange(index); // @ts-ignore
102
82
 
103
83
  (_child$props$onPress = (_child$props = child.props).onPress) === null || _child$props$onPress === void 0 ? void 0 : _child$props$onPress.call(_child$props);
104
- };
84
+ }; // @ts-ignore
105
85
 
106
- const selected = index === indexProp;
107
- const enableIndicatorPlaceholder = disableIndicator ? false : isReadyToRenderIndicator ? false : selected; //@ts-ignore
108
86
 
109
- return /*#__PURE__*/cloneElement(child, {
110
- enableIndicator: enableIndicatorPlaceholder,
87
+ const tabElement = /*#__PURE__*/cloneElement(child, {
88
+ enableIndicator: !disableIndicator && !isReadyToRenderIndicator,
111
89
  onLayout,
112
90
  onPress,
113
91
  onMouseDown,
114
92
  variant,
115
- selected,
116
93
  style: scrollable ? undefined : styles.fixedTab
117
94
  });
95
+ return /*#__PURE__*/React.createElement(IndexAwareTab, {
96
+ children: tabElement,
97
+ index: index,
98
+ sharedIndex: sharedIndex
99
+ });
118
100
  });
119
- const indicator = /*#__PURE__*/React.createElement(TabIndicator, {
101
+ const tabIndicator = isReadyToRenderIndicator ? /*#__PURE__*/React.createElement(TabIndicator, {
120
102
  coordinates: coordinates,
121
103
  disabled: disableIndicator,
122
104
  scrollable: scrollable,
123
- scrollValue: scrollValue
124
- });
125
- return /*#__PURE__*/React.createElement(View, _extends({
126
- onLayout: handleLayout,
105
+ sharedIndex: sharedIndex
106
+ }) : null;
107
+ return /*#__PURE__*/React.createElement(View, {
108
+ onLayout: onLayout,
127
109
  style: css([styles.root, scrollable ? undefined : styles.fixedRoot, style])
128
- }, otherProps), scrollable ? /*#__PURE__*/React.createElement(ScrollView, {
110
+ }, scrollable ? /*#__PURE__*/React.createElement(ScrollView, {
129
111
  automaticallyAdjustContentInsets: false,
130
112
  bounces: false,
131
113
  contentContainerStyle: styles.scrollableContainer,
@@ -137,7 +119,7 @@ export default function Tabs(props) {
137
119
  showsVerticalScrollIndicator: false,
138
120
  keyboardDismissMode: keyboardDismissMode,
139
121
  keyboardShouldPersistTaps: keyboardShouldPersistTaps
140
- }, tabElements, indicator) : /*#__PURE__*/React.createElement(React.Fragment, null, tabElements, indicator));
141
- }
142
- ;
122
+ }, tabElements, tabIndicator) : /*#__PURE__*/React.createElement(React.Fragment, null, tabElements, tabIndicator));
123
+ });
124
+ export default Tabs;
143
125
  //# sourceMappingURL=Tabs.js.map