@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.
- package/build/commonjs/ButtonBase/ButtonBase.js +3 -2
- package/build/commonjs/ButtonBase/ButtonBase.js.map +1 -1
- package/build/commonjs/CircularProgress/CircularProgress.js +15 -11
- package/build/commonjs/CircularProgress/CircularProgress.js.map +1 -1
- package/build/commonjs/Tab/Tab.js +9 -5
- package/build/commonjs/Tab/Tab.js.map +1 -1
- package/build/commonjs/Tabs/IndexAwareTab.js +28 -0
- package/build/commonjs/Tabs/IndexAwareTab.js.map +1 -0
- package/build/commonjs/Tabs/TabIndicator.js +27 -13
- package/build/commonjs/Tabs/TabIndicator.js.map +1 -1
- package/build/commonjs/Tabs/TabIndicatorProps.js.map +1 -1
- package/build/commonjs/Tabs/Tabs.js +43 -62
- package/build/commonjs/Tabs/Tabs.js.map +1 -1
- package/build/commonjs/Tabs/TabsProps.js.map +1 -1
- package/build/commonjs/Tabs/index.js.map +1 -1
- package/build/commonjs/Tabs/useScrollViewReaction.js +65 -0
- package/build/commonjs/Tabs/useScrollViewReaction.js.map +1 -0
- package/build/commonjs/hooks/useValidWindowDimensions/index.ios.js +14 -7
- package/build/commonjs/hooks/useValidWindowDimensions/index.ios.js.map +1 -1
- package/build/module/ButtonBase/ButtonBase.js +3 -2
- package/build/module/ButtonBase/ButtonBase.js.map +1 -1
- package/build/module/CircularProgress/CircularProgress.js +15 -11
- package/build/module/CircularProgress/CircularProgress.js.map +1 -1
- package/build/module/Tab/Tab.js +5 -5
- package/build/module/Tab/Tab.js.map +1 -1
- package/build/module/Tabs/IndexAwareTab.js +18 -0
- package/build/module/Tabs/IndexAwareTab.js.map +1 -0
- package/build/module/Tabs/TabIndicator.js +26 -14
- package/build/module/Tabs/TabIndicator.js.map +1 -1
- package/build/module/Tabs/TabIndicatorProps.js.map +1 -1
- package/build/module/Tabs/Tabs.js +42 -60
- package/build/module/Tabs/Tabs.js.map +1 -1
- package/build/module/Tabs/TabsProps.js.map +1 -1
- package/build/module/Tabs/index.js.map +1 -1
- package/build/module/Tabs/useScrollViewReaction.js +54 -0
- package/build/module/Tabs/useScrollViewReaction.js.map +1 -0
- package/build/module/hooks/useValidWindowDimensions/index.ios.js +15 -9
- package/build/module/hooks/useValidWindowDimensions/index.ios.js.map +1 -1
- package/build/typescript/CircularProgress/CircularProgress.d.ts +1 -1
- package/build/typescript/Tabs/IndexAwareTab.d.ts +9 -0
- package/build/typescript/Tabs/TabIndicatorProps.d.ts +2 -2
- package/build/typescript/Tabs/Tabs.d.ts +4 -1
- package/build/typescript/Tabs/TabsProps.d.ts +22 -9
- package/build/typescript/Tabs/index.d.ts +1 -1
- package/build/typescript/Tabs/useScrollViewReaction.d.ts +9 -0
- package/build/typescript/hooks/useValidWindowDimensions/index.ios.d.ts +2 -1
- package/package.json +2 -2
- package/src/ButtonBase/ButtonBase.tsx +6 -2
- package/src/CircularProgress/CircularProgress.tsx +23 -15
- package/src/Tab/Tab.tsx +5 -5
- package/src/Tabs/IndexAwareTab.tsx +30 -0
- package/src/Tabs/TabIndicator.tsx +26 -14
- package/src/Tabs/TabIndicatorProps.ts +2 -2
- package/src/Tabs/Tabs.tsx +50 -62
- package/src/Tabs/TabsProps.ts +25 -9
- package/src/Tabs/index.ts +1 -1
- package/src/Tabs/useScrollViewReaction.ts +63 -0
- package/src/hooks/useValidWindowDimensions/index.ios.ts +16 -10
- package/build/commonjs/Tabs/useTabsWidth.js +0 -26
- package/build/commonjs/Tabs/useTabsWidth.js.map +0 -1
- package/build/module/Tabs/useTabsWidth.js +0 -18
- package/build/module/Tabs/useTabsWidth.js.map +0 -1
- package/build/typescript/Tabs/useTabsWidth.d.ts +0 -2
- package/src/Tabs/useTabsWidth.ts +0 -20
|
@@ -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,
|
|
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
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
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","
|
|
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
|
|
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:
|
|
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","
|
|
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":";;AAAA,OAAOA,KAAP,IAAgBC,WAAhB,EAA6BC,SAA7B,EAAwCC,MAAxC,QAAsD,OAAtD;AACA,SAASC,QAAT,QAAyB,cAAzB;AACA,SAASC,WAAT,QAA4B,UAA5B;AACA,SAASC,iBAAT,QAAkC,aAAlC;AAOA,OAAO,MAAMC,gBAAgB,GAAG,CAAzB;AACP,OAAO,MAAMC,gBAAgB,GAAG,EAAzB;AACP,MAAMC,cAAc,GAAG,GAAvB;AAEA,MAAMC,cAAc,GAAG,CAAvB;AACA,MAAMC,cAAc,GAAG,GAAvB,C,CAEA;AACA;;AACA,MAAMC,2BAA2B,GAAG,GAApC;;AAKA,MAAMC,gCAAgC,GAAG,CACrCC,KADqC,EAErCC,OAFqC,KAGpC;EACDX,QAAQ,CAACY,MAAT,CAAgBF,KAAhB,EAAuB;IACnBC,OADmB;IAEnBE,QAAQ,EAAE,GAFS;IAGnBC,eAAe,EAAE;EAHE,CAAvB,EAIGC,KAJH;AAKH,CATD;;AAWA,eAAe,SAASC,UAAT,CAAoBC,KAApB,EAA4C;EACvD,MAAM;IACFC,QADE;IAEFC,QAAQ,GAAG,KAFT;IAGFC,eAAe,GAAG,KAHhB;IAIFC,OAJE;IAKFC,WAAW,GAAG,SALZ;IAMFC,KAAK,EAAEC,SANL;IAOFC,cAAc,GAAG,GAPf;IAQF,GAAGC;EARD,IASFT,KATJ;EAWA,MAAMU,WAAW,GAAG1B,WAAW,CAAC;IAC5B2B,YAAY,EAAER,eAAe,GAAG,CAAH,GAAOK,cADR;IAE5BI,QAAQ,EAAER;EAFkB,CAAD,CAA/B;EAKA,MAAMS,OAAO,GAAG/B,MAAM,CAAiB,IAAIC,QAAQ,CAAC+B,KAAb,CAAmB5B,gBAAnB,CAAjB,CAAN,CAA6D6B,OAA7E;EACA,MAAMC,KAAK,GAAGlC,MAAM,CAAiB,IAAIC,QAAQ,CAAC+B,KAAb,CAAmBzB,cAAnB,CAAjB,CAAN,CAA2D0B,OAAzE;EAEAlC,SAAS,CAAC,MAAM;IACZgC,OAAO,CAACI,QAAR,CAAiBf,QAAQ,GAAGf,gBAAH,GAAsBD,gBAA/C;EACH,CAFQ,EAEN,CAACgB,QAAD,CAFM,CAAT;EAIA,MAAMgB,mBAAmB,GAAGtC,WAAW,CAAsB,CAACuC,OAAD,EAAUC,OAAV,KAAsB;IAC/E,IAAI,CAACA,OAAL,EAAc;MACV5B,gCAAgC,CAC5BwB,KAD4B,EAE5BG,OAAO,GAAG7B,cAAH,GAAoBD,cAFC,CAAhC;IAIH;EACJ,CAPsC,EAOpC,EAPoC,CAAvC;EASA,MAAMgC,qBAAqB,GAAGzC,WAAW,CAAuBuC,OAAD,IAAa;IACxE,IAAIA,OAAJ,EAAa;MACTN,OAAO,CAACI,QAAR,CAAiB7B,cAAjB;IACH,CAFD,MAEO;MACHI,gCAAgC,CAACqB,OAAD,EAAU3B,gBAAV,CAAhC;IACH;EACJ,CANwC,EAMtC,EANsC,CAAzC;EAQA,MAAMoC,mBAAmB,GAAG1C,WAAW,CAAsB,UAACuC,OAAD,EAA8B;IAAA,IAApBC,OAAoB,uEAAV,KAAU;;IACvF,IAAIf,WAAW,KAAK,OAApB,EAA6B;MACzBa,mBAAmB,CAACC,OAAD,EAAUC,OAAV,CAAnB;IACH,CAFD,MAEO,IAAIf,WAAW,KAAK,SAApB,EAA+B;MAClCgB,qBAAqB,CAACF,OAAD,EAAUC,OAAV,CAArB;IACH;EACJ,CANsC,EAMpC,CAACf,WAAD,CANoC,CAAvC;EAQA,MAAMkB,aAAa,GAAG3C,WAAW,CAAC,MAAM;IACpC0C,mBAAmB,CAAC,IAAD,EAAO,KAAP,CAAnB;EACH,CAFgC,EAE9B,CAACA,mBAAD,CAF8B,CAAjC;EAIA,MAAME,cAAc,GAAG5C,WAAW,CAAC,MAAM;IACrC0C,mBAAmB,CAAC,KAAD,EAAQ,KAAR,CAAnB;EACH,CAFiC,EAE/B,CAACA,mBAAD,CAF+B,CAAlC;EAIA,MAAMG,aAAa,GAAG;IAClBZ,OADkB;IAElBa,SAAS,EAAE,CAAC;MAAEV;IAAF,CAAD;EAFO,CAAtB;EAKA,MAAMW,UAAU,GAAGtB,WAAW,KAAK,OAAhB,GACbd,2BADa,GAEb,CAFN;EAIA,oBACI,oBAAC,iBAAD;IACI,QAAQ,EAAEW,QADd;IAEI,OAAO,EAAEQ,WAFb;IAGI,SAAS,EAAEa,aAHf;IAII,UAAU,EAAEC,cAJhB;IAKI,KAAK,EAAE,CACHC,aADG,EAEHlB,SAFG,CALX;IASI,mBAAmB,EAAEoB;EATzB,GAUQlB,UAVR,GAYK,OAAOR,QAAP,KAAoB,UAApB,GACG,QAAiB;IAAA,IAAhB;MAAE2B;IAAF,CAAgB;;IACb,IAAIA,OAAO,KAAKC,SAAZ,IAAyB,CAAC3B,QAA9B,EAAwC;MACpCoB,mBAAmB,CAACM,OAAD,EAAU,IAAV,CAAnB;IACH;;IAED,OAAO3B,QAAP;EACH,CAPJ,GAQGA,QApBR,CADJ;AAwBH;AAAA"}
|
|
@@ -1,10 +1,6 @@
|
|
|
1
|
-
import React, { useEffect } from 'react';
|
|
2
|
-
import Animated,
|
|
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 =
|
|
26
|
-
const animatedStyle =
|
|
21
|
+
const rotate = useRef(new Animated.Value(MIN_ROTATE_DEGREE)).current;
|
|
22
|
+
const animatedStyle = {
|
|
27
23
|
transform: [{
|
|
28
|
-
rotate:
|
|
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
|
-
|
|
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","
|
|
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"}
|
package/build/module/Tab/Tab.js
CHANGED
|
@@ -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__*/
|
|
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","
|
|
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
|
-
|
|
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
|
-
|
|
37
|
+
sharedIndex,
|
|
29
38
|
style,
|
|
30
39
|
...otherProps
|
|
31
40
|
} = props;
|
|
32
41
|
const styles = useStyles();
|
|
33
42
|
const animatedStyle = useAnimatedStyle(() => {
|
|
34
|
-
const
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
const
|
|
40
|
-
const
|
|
41
|
-
const
|
|
42
|
-
const
|
|
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
|
-
|
|
45
|
-
|
|
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","
|
|
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 *
|
|
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
|
-
|
|
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 {
|
|
3
|
+
import { useSharedValue } from 'react-native-reanimated';
|
|
6
4
|
import { css, useTheme } from '../styles';
|
|
7
5
|
import TabIndicator from './TabIndicator';
|
|
8
|
-
import
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
53
|
-
|
|
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
|
-
|
|
110
|
-
enableIndicator:
|
|
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
|
|
101
|
+
const tabIndicator = isReadyToRenderIndicator ? /*#__PURE__*/React.createElement(TabIndicator, {
|
|
120
102
|
coordinates: coordinates,
|
|
121
103
|
disabled: disableIndicator,
|
|
122
104
|
scrollable: scrollable,
|
|
123
|
-
|
|
124
|
-
});
|
|
125
|
-
return /*#__PURE__*/React.createElement(View,
|
|
126
|
-
onLayout:
|
|
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
|
-
},
|
|
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,
|
|
141
|
-
}
|
|
142
|
-
;
|
|
122
|
+
}, tabElements, tabIndicator) : /*#__PURE__*/React.createElement(React.Fragment, null, tabElements, tabIndicator));
|
|
123
|
+
});
|
|
124
|
+
export default Tabs;
|
|
143
125
|
//# sourceMappingURL=Tabs.js.map
|