@fountain-ui/core 2.0.0-beta.10 → 2.0.0-beta.13
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/Accordion/Accordion.js +3 -3
- package/build/commonjs/Accordion/Accordion.js.map +1 -1
- package/build/commonjs/ButtonBase/ButtonBase.js +56 -52
- package/build/commonjs/ButtonBase/ButtonBase.js.map +1 -1
- package/build/commonjs/CircularProgress/CircularProgress.js +19 -24
- package/build/commonjs/CircularProgress/CircularProgress.js.map +1 -1
- package/build/commonjs/ImageCore/ImageCoreNative.js +24 -26
- package/build/commonjs/ImageCore/ImageCoreNative.js.map +1 -1
- package/build/commonjs/Slide/Slide.js +12 -13
- package/build/commonjs/Slide/Slide.js.map +1 -1
- package/build/commonjs/Tabs/TabIndicator.js +2 -6
- package/build/commonjs/Tabs/TabIndicator.js.map +1 -1
- package/build/commonjs/Tabs/Tabs.js +46 -48
- package/build/commonjs/Tabs/Tabs.js.map +1 -1
- package/build/commonjs/Tabs/useTabCoordinates.js +44 -0
- package/build/commonjs/Tabs/useTabCoordinates.js.map +1 -0
- package/build/commonjs/Tabs/useTabsWidth.js +26 -0
- package/build/commonjs/Tabs/useTabsWidth.js.map +1 -0
- package/build/commonjs/Tooltip/Tooltip.js +18 -22
- package/build/commonjs/Tooltip/Tooltip.js.map +1 -1
- package/build/commonjs/animated/AnimatedPressable.js +2 -3
- package/build/commonjs/animated/AnimatedPressable.js.map +1 -1
- package/build/commonjs/hooks/useCollapsibleAppBar.js +46 -36
- package/build/commonjs/hooks/useCollapsibleAppBar.js.map +1 -1
- package/build/commonjs/hooks/useFadeInAppBar.js +35 -18
- package/build/commonjs/hooks/useFadeInAppBar.js.map +1 -1
- package/build/commonjs/hooks/useThrottle.js +3 -7
- package/build/commonjs/hooks/useThrottle.js.map +1 -1
- package/build/commonjs/internal/hooks/index.js +0 -8
- package/build/commonjs/internal/hooks/index.js.map +1 -1
- package/build/commonjs/internal/hooks/useHeight.js +2 -6
- package/build/commonjs/internal/hooks/useHeight.js.map +1 -1
- package/build/module/Accordion/Accordion.js +3 -3
- package/build/module/Accordion/Accordion.js.map +1 -1
- package/build/module/ButtonBase/ButtonBase.js +54 -48
- package/build/module/ButtonBase/ButtonBase.js.map +1 -1
- package/build/module/CircularProgress/CircularProgress.js +20 -21
- package/build/module/CircularProgress/CircularProgress.js.map +1 -1
- package/build/module/ImageCore/ImageCoreNative.js +20 -23
- package/build/module/ImageCore/ImageCoreNative.js.map +1 -1
- package/build/module/Slide/Slide.js +14 -10
- package/build/module/Slide/Slide.js.map +1 -1
- package/build/module/Tabs/TabIndicator.js +3 -7
- package/build/module/Tabs/TabIndicator.js.map +1 -1
- package/build/module/Tabs/Tabs.js +39 -39
- package/build/module/Tabs/Tabs.js.map +1 -1
- package/build/module/Tabs/useTabCoordinates.js +30 -0
- package/build/module/Tabs/useTabCoordinates.js.map +1 -0
- package/build/module/Tabs/useTabsWidth.js +18 -0
- package/build/module/Tabs/useTabsWidth.js.map +1 -0
- package/build/module/Tooltip/Tooltip.js +15 -15
- package/build/module/Tooltip/Tooltip.js.map +1 -1
- package/build/module/animated/AnimatedPressable.js +2 -3
- package/build/module/animated/AnimatedPressable.js.map +1 -1
- package/build/module/hooks/useCollapsibleAppBar.js +46 -34
- package/build/module/hooks/useCollapsibleAppBar.js.map +1 -1
- package/build/module/hooks/useFadeInAppBar.js +35 -14
- package/build/module/hooks/useFadeInAppBar.js.map +1 -1
- package/build/module/hooks/useThrottle.js +3 -3
- package/build/module/hooks/useThrottle.js.map +1 -1
- package/build/module/internal/hooks/index.js +0 -1
- package/build/module/internal/hooks/index.js.map +1 -1
- package/build/module/internal/hooks/useHeight.js +2 -2
- package/build/module/internal/hooks/useHeight.js.map +1 -1
- package/build/typescript/Tabs/useTabCoordinates.d.ts +7 -0
- package/build/typescript/Tabs/useTabsWidth.d.ts +2 -0
- package/build/typescript/animated/AnimatedPressable.d.ts +2 -2
- package/build/typescript/internal/hooks/index.d.ts +0 -1
- package/package.json +2 -2
- package/src/Accordion/Accordion.tsx +5 -3
- package/src/ButtonBase/ButtonBase.tsx +65 -43
- package/src/CircularProgress/CircularProgress.tsx +24 -30
- package/src/ImageCore/ImageCoreNative.tsx +17 -19
- package/src/Slide/Slide.tsx +17 -15
- package/src/Tabs/TabIndicator.tsx +4 -8
- package/src/Tabs/Tabs.tsx +37 -39
- package/src/Tabs/useTabCoordinates.ts +36 -0
- package/src/Tabs/useTabsWidth.ts +20 -0
- package/src/Tooltip/Tooltip.tsx +16 -16
- package/src/animated/AnimatedPressable.tsx +1 -2
- package/src/hooks/useCollapsibleAppBar.ts +41 -31
- package/src/hooks/useFadeInAppBar.ts +31 -15
- package/src/hooks/useThrottle.ts +3 -3
- package/src/internal/hooks/index.ts +0 -1
- package/src/internal/hooks/useHeight.ts +2 -2
- package/build/commonjs/ButtonBase/ButtonBase.ios.js +0 -101
- package/build/commonjs/ButtonBase/ButtonBase.ios.js.map +0 -1
- package/build/commonjs/ButtonBase/useDisabledReaction/index.js +0 -21
- package/build/commonjs/ButtonBase/useDisabledReaction/index.js.map +0 -1
- package/build/commonjs/ButtonBase/useDisabledReaction/index.native.js +0 -9
- package/build/commonjs/ButtonBase/useDisabledReaction/index.native.js.map +0 -1
- package/build/commonjs/ImageCore/ImageCoreNative.ios.js +0 -60
- package/build/commonjs/ImageCore/ImageCoreNative.ios.js.map +0 -1
- package/build/commonjs/internal/hooks/useWidth.js +0 -29
- package/build/commonjs/internal/hooks/useWidth.js.map +0 -1
- package/build/module/ButtonBase/ButtonBase.ios.js +0 -82
- package/build/module/ButtonBase/ButtonBase.ios.js.map +0 -1
- package/build/module/ButtonBase/useDisabledReaction/index.js +0 -12
- package/build/module/ButtonBase/useDisabledReaction/index.js.map +0 -1
- package/build/module/ButtonBase/useDisabledReaction/index.native.js +0 -2
- package/build/module/ButtonBase/useDisabledReaction/index.native.js.map +0 -1
- package/build/module/ImageCore/ImageCoreNative.ios.js +0 -45
- package/build/module/ImageCore/ImageCoreNative.ios.js.map +0 -1
- package/build/module/internal/hooks/useWidth.js +0 -15
- package/build/module/internal/hooks/useWidth.js.map +0 -1
- package/build/typescript/ButtonBase/ButtonBase.ios.d.ts +0 -2
- package/build/typescript/ButtonBase/useDisabledReaction/index.d.ts +0 -2
- package/build/typescript/ButtonBase/useDisabledReaction/index.native.d.ts +0 -2
- package/build/typescript/ImageCore/ImageCoreNative.ios.d.ts +0 -2
- package/build/typescript/internal/hooks/useWidth.d.ts +0 -2
- package/src/ButtonBase/ButtonBase.ios.tsx +0 -95
- package/src/ButtonBase/useDisabledReaction/index.native.ts +0 -4
- package/src/ButtonBase/useDisabledReaction/index.ts +0 -16
- package/src/ImageCore/ImageCoreNative.ios.tsx +0 -46
- package/src/internal/hooks/useWidth.ts +0 -17
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import
|
|
1
|
+
import React, { useCallback, useRef } from 'react';
|
|
2
|
+
import { Animated } from 'react-native';
|
|
3
3
|
import FastImage from 'react-native-fast-image';
|
|
4
4
|
// @ts-ignore
|
|
5
5
|
const AnimatedFastImage = Animated.createAnimatedComponent(FastImage);
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
const INITIAL_OPACITY = 0;
|
|
7
|
+
const LOADED_OPACITY = 1;
|
|
8
|
+
const ANIMATION_DURATION = 200;
|
|
9
9
|
export default function ImageCore(props) {
|
|
10
10
|
const {
|
|
11
11
|
height,
|
|
@@ -15,23 +15,15 @@ export default function ImageCore(props) {
|
|
|
15
15
|
source,
|
|
16
16
|
width
|
|
17
17
|
} = props;
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
const handleLoad = () => {
|
|
28
|
-
opacity.value = withTiming(1, animationConfig);
|
|
29
|
-
|
|
30
|
-
if (onLoad) {
|
|
31
|
-
onLoad();
|
|
32
|
-
}
|
|
33
|
-
};
|
|
34
|
-
|
|
18
|
+
const opacity = useRef(new Animated.Value(INITIAL_OPACITY)).current;
|
|
19
|
+
const handleLoad = useCallback(() => {
|
|
20
|
+
Animated.timing(opacity, {
|
|
21
|
+
toValue: LOADED_OPACITY,
|
|
22
|
+
duration: ANIMATION_DURATION,
|
|
23
|
+
useNativeDriver: true
|
|
24
|
+
}).start();
|
|
25
|
+
onLoad === null || onLoad === void 0 ? void 0 : onLoad();
|
|
26
|
+
}, [onLoad]);
|
|
35
27
|
return /*#__PURE__*/React.createElement(AnimatedFastImage, {
|
|
36
28
|
onError: onError,
|
|
37
29
|
onLoad: handleLoad,
|
|
@@ -39,7 +31,12 @@ export default function ImageCore(props) {
|
|
|
39
31
|
source: {
|
|
40
32
|
uri: source.uri
|
|
41
33
|
},
|
|
42
|
-
style: [
|
|
34
|
+
style: [{
|
|
35
|
+
opacity
|
|
36
|
+
}, {
|
|
37
|
+
width,
|
|
38
|
+
height
|
|
39
|
+
}]
|
|
43
40
|
});
|
|
44
41
|
}
|
|
45
42
|
;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["React","
|
|
1
|
+
{"version":3,"names":["React","useCallback","useRef","Animated","FastImage","AnimatedFastImage","createAnimatedComponent","INITIAL_OPACITY","LOADED_OPACITY","ANIMATION_DURATION","ImageCore","props","height","onError","onLoad","resizeMode","source","width","opacity","Value","current","handleLoad","timing","toValue","duration","useNativeDriver","start","uri"],"sources":["ImageCoreNative.tsx"],"sourcesContent":["import React, { useCallback, useRef } from 'react';\nimport { Animated } from 'react-native';\nimport FastImage from 'react-native-fast-image';\nimport type ImageCoreProps from './ImageCoreProps';\n\n// @ts-ignore\nconst AnimatedFastImage = Animated.createAnimatedComponent(FastImage);\n\nconst INITIAL_OPACITY = 0;\nconst LOADED_OPACITY = 1;\n\nconst ANIMATION_DURATION = 200;\n\nexport default function ImageCore(props: ImageCoreProps) {\n const {\n height,\n onError,\n onLoad,\n resizeMode,\n source,\n width,\n } = props;\n\n const opacity = useRef<Animated.Value>(new Animated.Value(INITIAL_OPACITY)).current;\n\n const handleLoad = useCallback(() => {\n Animated.timing(opacity, {\n toValue: LOADED_OPACITY,\n duration: ANIMATION_DURATION,\n useNativeDriver: true,\n }).start();\n\n onLoad?.();\n }, [onLoad]);\n\n return (\n <AnimatedFastImage\n onError={onError}\n onLoad={handleLoad}\n resizeMode={resizeMode}\n source={{ uri: source.uri }}\n style={[\n { opacity },\n { width, height },\n ]}\n />\n );\n};\n"],"mappings":"AAAA,OAAOA,KAAP,IAAgBC,WAAhB,EAA6BC,MAA7B,QAA2C,OAA3C;AACA,SAASC,QAAT,QAAyB,cAAzB;AACA,OAAOC,SAAP,MAAsB,yBAAtB;AAGA;AACA,MAAMC,iBAAiB,GAAGF,QAAQ,CAACG,uBAAT,CAAiCF,SAAjC,CAA1B;AAEA,MAAMG,eAAe,GAAG,CAAxB;AACA,MAAMC,cAAc,GAAG,CAAvB;AAEA,MAAMC,kBAAkB,GAAG,GAA3B;AAEA,eAAe,SAASC,SAAT,CAAmBC,KAAnB,EAA0C;EACrD,MAAM;IACFC,MADE;IAEFC,OAFE;IAGFC,MAHE;IAIFC,UAJE;IAKFC,MALE;IAMFC;EANE,IAOFN,KAPJ;EASA,MAAMO,OAAO,GAAGhB,MAAM,CAAiB,IAAIC,QAAQ,CAACgB,KAAb,CAAmBZ,eAAnB,CAAjB,CAAN,CAA4Da,OAA5E;EAEA,MAAMC,UAAU,GAAGpB,WAAW,CAAC,MAAM;IACjCE,QAAQ,CAACmB,MAAT,CAAgBJ,OAAhB,EAAyB;MACrBK,OAAO,EAAEf,cADY;MAErBgB,QAAQ,EAAEf,kBAFW;MAGrBgB,eAAe,EAAE;IAHI,CAAzB,EAIGC,KAJH;IAMAZ,MAAM,SAAN,IAAAA,MAAM,WAAN,YAAAA,MAAM;EACT,CAR6B,EAQ3B,CAACA,MAAD,CAR2B,CAA9B;EAUA,oBACI,oBAAC,iBAAD;IACI,OAAO,EAAED,OADb;IAEI,MAAM,EAAEQ,UAFZ;IAGI,UAAU,EAAEN,UAHhB;IAII,MAAM,EAAE;MAAEY,GAAG,EAAEX,MAAM,CAACW;IAAd,CAJZ;IAKI,KAAK,EAAE,CACH;MAAET;IAAF,CADG,EAEH;MAAED,KAAF;MAASL;IAAT,CAFG;EALX,EADJ;AAYH;AAAA"}
|
|
@@ -1,10 +1,13 @@
|
|
|
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';
|
|
4
|
-
import {
|
|
3
|
+
import React, { useEffect } from 'react';
|
|
4
|
+
import { Dimensions } from 'react-native';
|
|
5
5
|
import Animated, { Easing, runOnJS, useAnimatedStyle, useSharedValue, withTiming } from 'react-native-reanimated';
|
|
6
6
|
const defaultEnterDuration = 300;
|
|
7
7
|
const defaultExitDuration = 300;
|
|
8
|
+
|
|
9
|
+
const getDisappearingOffsetY = () => Dimensions.get('window').height;
|
|
10
|
+
|
|
8
11
|
export default function Slide(props) {
|
|
9
12
|
const {
|
|
10
13
|
animatedY: animatedYProp,
|
|
@@ -18,33 +21,34 @@ export default function Slide(props) {
|
|
|
18
21
|
style,
|
|
19
22
|
...otherProps
|
|
20
23
|
} = props;
|
|
21
|
-
const
|
|
22
|
-
const y = useSharedValue(window.height);
|
|
24
|
+
const y = useSharedValue(getDisappearingOffsetY());
|
|
23
25
|
const animatedY = animatedYProp || y;
|
|
24
26
|
const animatedStyle = useAnimatedStyle(() => ({
|
|
25
27
|
transform: [{
|
|
26
28
|
translateY: animatedY.value
|
|
27
29
|
}]
|
|
28
|
-
}));
|
|
29
|
-
|
|
30
|
+
}), []);
|
|
31
|
+
useEffect(() => {
|
|
30
32
|
if (appear) {
|
|
33
|
+
onEnter === null || onEnter === void 0 ? void 0 : onEnter();
|
|
34
|
+
const toValue = 0;
|
|
31
35
|
const enterConfig = {
|
|
32
36
|
duration: enterDuration,
|
|
33
37
|
easing: Easing.out(Easing.exp)
|
|
34
38
|
};
|
|
35
|
-
|
|
36
|
-
animatedY.value = withTiming(0, enterConfig, isFinished => {
|
|
39
|
+
animatedY.value = withTiming(toValue, enterConfig, isFinished => {
|
|
37
40
|
if (isFinished && onEntered) {
|
|
38
41
|
runOnJS(onEntered)();
|
|
39
42
|
}
|
|
40
43
|
});
|
|
41
44
|
} else {
|
|
45
|
+
onExit === null || onExit === void 0 ? void 0 : onExit();
|
|
46
|
+
const toValue = getDisappearingOffsetY();
|
|
42
47
|
const exitConfig = {
|
|
43
48
|
duration: exitDuration,
|
|
44
49
|
easing: Easing.in(Easing.ease)
|
|
45
50
|
};
|
|
46
|
-
|
|
47
|
-
animatedY.value = withTiming(window.height, exitConfig, isFinished => {
|
|
51
|
+
animatedY.value = withTiming(toValue, exitConfig, isFinished => {
|
|
48
52
|
if (isFinished && onExited) {
|
|
49
53
|
runOnJS(onExited)();
|
|
50
54
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["React","
|
|
1
|
+
{"version":3,"names":["React","useEffect","Dimensions","Animated","Easing","runOnJS","useAnimatedStyle","useSharedValue","withTiming","defaultEnterDuration","defaultExitDuration","getDisappearingOffsetY","get","height","Slide","props","animatedY","animatedYProp","appear","enterDuration","exitDuration","onEnter","onEntered","onExit","onExited","style","otherProps","y","animatedStyle","transform","translateY","value","toValue","enterConfig","duration","easing","out","exp","isFinished","exitConfig","in","ease"],"sources":["Slide.tsx"],"sourcesContent":["import React, { useEffect } from 'react';\nimport { Dimensions } from 'react-native';\nimport type { WithTimingConfig } from 'react-native-reanimated';\nimport Animated, { Easing, runOnJS, useAnimatedStyle, useSharedValue, withTiming } from 'react-native-reanimated';\nimport type SlideProps from './SlideProps';\n\nconst defaultEnterDuration = 300;\nconst defaultExitDuration = 300;\n\nconst getDisappearingOffsetY = (): number => Dimensions.get('window').height;\n\nexport default function Slide(props: SlideProps) {\n const {\n animatedY: animatedYProp,\n appear,\n enterDuration = defaultEnterDuration,\n exitDuration = defaultExitDuration,\n onEnter,\n onEntered,\n onExit,\n onExited,\n style,\n ...otherProps\n } = props;\n\n const y = useSharedValue(getDisappearingOffsetY());\n const animatedY = animatedYProp || y;\n\n const animatedStyle = useAnimatedStyle(() => ({\n transform: [{ translateY: animatedY.value }],\n }), []);\n\n useEffect(() => {\n if (appear) {\n onEnter?.();\n\n const toValue = 0;\n const enterConfig: Readonly<WithTimingConfig> = {\n duration: enterDuration,\n easing: Easing.out(Easing.exp),\n };\n\n animatedY.value = withTiming(toValue, enterConfig, isFinished => {\n if (isFinished && onEntered) {\n runOnJS(onEntered)();\n }\n });\n } else {\n onExit?.();\n\n const toValue = getDisappearingOffsetY();\n const exitConfig: Readonly<WithTimingConfig> = {\n duration: exitDuration,\n easing: Easing.in(Easing.ease),\n };\n\n animatedY.value = withTiming(toValue, exitConfig, isFinished => {\n if (isFinished && onExited) {\n runOnJS(onExited)();\n }\n });\n }\n }, [appear, onEnter, onEntered, onExit, onExited]);\n\n return (\n <Animated.View\n style={[\n animatedStyle,\n style,\n ]}\n {...otherProps}\n />\n );\n};\n"],"mappings":";;AAAA,OAAOA,KAAP,IAAgBC,SAAhB,QAAiC,OAAjC;AACA,SAASC,UAAT,QAA2B,cAA3B;AAEA,OAAOC,QAAP,IAAmBC,MAAnB,EAA2BC,OAA3B,EAAoCC,gBAApC,EAAsDC,cAAtD,EAAsEC,UAAtE,QAAwF,yBAAxF;AAGA,MAAMC,oBAAoB,GAAG,GAA7B;AACA,MAAMC,mBAAmB,GAAG,GAA5B;;AAEA,MAAMC,sBAAsB,GAAG,MAAcT,UAAU,CAACU,GAAX,CAAe,QAAf,EAAyBC,MAAtE;;AAEA,eAAe,SAASC,KAAT,CAAeC,KAAf,EAAkC;EAC7C,MAAM;IACFC,SAAS,EAAEC,aADT;IAEFC,MAFE;IAGFC,aAAa,GAAGV,oBAHd;IAIFW,YAAY,GAAGV,mBAJb;IAKFW,OALE;IAMFC,SANE;IAOFC,MAPE;IAQFC,QARE;IASFC,KATE;IAUF,GAAGC;EAVD,IAWFX,KAXJ;EAaA,MAAMY,CAAC,GAAGpB,cAAc,CAACI,sBAAsB,EAAvB,CAAxB;EACA,MAAMK,SAAS,GAAGC,aAAa,IAAIU,CAAnC;EAEA,MAAMC,aAAa,GAAGtB,gBAAgB,CAAC,OAAO;IAC1CuB,SAAS,EAAE,CAAC;MAAEC,UAAU,EAAEd,SAAS,CAACe;IAAxB,CAAD;EAD+B,CAAP,CAAD,EAElC,EAFkC,CAAtC;EAIA9B,SAAS,CAAC,MAAM;IACZ,IAAIiB,MAAJ,EAAY;MACRG,OAAO,SAAP,IAAAA,OAAO,WAAP,YAAAA,OAAO;MAEP,MAAMW,OAAO,GAAG,CAAhB;MACA,MAAMC,WAAuC,GAAG;QAC5CC,QAAQ,EAAEf,aADkC;QAE5CgB,MAAM,EAAE/B,MAAM,CAACgC,GAAP,CAAWhC,MAAM,CAACiC,GAAlB;MAFoC,CAAhD;MAKArB,SAAS,CAACe,KAAV,GAAkBvB,UAAU,CAACwB,OAAD,EAAUC,WAAV,EAAuBK,UAAU,IAAI;QAC7D,IAAIA,UAAU,IAAIhB,SAAlB,EAA6B;UACzBjB,OAAO,CAACiB,SAAD,CAAP;QACH;MACJ,CAJ2B,CAA5B;IAKH,CAdD,MAcO;MACHC,MAAM,SAAN,IAAAA,MAAM,WAAN,YAAAA,MAAM;MAEN,MAAMS,OAAO,GAAGrB,sBAAsB,EAAtC;MACA,MAAM4B,UAAsC,GAAG;QAC3CL,QAAQ,EAAEd,YADiC;QAE3Ce,MAAM,EAAE/B,MAAM,CAACoC,EAAP,CAAUpC,MAAM,CAACqC,IAAjB;MAFmC,CAA/C;MAKAzB,SAAS,CAACe,KAAV,GAAkBvB,UAAU,CAACwB,OAAD,EAAUO,UAAV,EAAsBD,UAAU,IAAI;QAC5D,IAAIA,UAAU,IAAId,QAAlB,EAA4B;UACxBnB,OAAO,CAACmB,QAAD,CAAP;QACH;MACJ,CAJ2B,CAA5B;IAKH;EACJ,CA9BQ,EA8BN,CAACN,MAAD,EAASG,OAAT,EAAkBC,SAAlB,EAA6BC,MAA7B,EAAqCC,QAArC,CA9BM,CAAT;EAgCA,oBACI,oBAAC,QAAD,CAAU,IAAV;IACI,KAAK,EAAE,CACHI,aADG,EAEHH,KAFG;EADX,GAKQC,UALR,EADJ;AASH;AAAA"}
|
|
@@ -1,7 +1,7 @@
|
|
|
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
|
|
4
|
+
import Animated, { useAnimatedStyle } from 'react-native-reanimated';
|
|
5
5
|
import { useTheme } from '../styles';
|
|
6
6
|
import { defaultCoordinate } from './TabCoordinate';
|
|
7
7
|
|
|
@@ -30,7 +30,7 @@ export default function TabIndicator(props) {
|
|
|
30
30
|
...otherProps
|
|
31
31
|
} = props;
|
|
32
32
|
const styles = useStyles();
|
|
33
|
-
const
|
|
33
|
+
const animatedStyle = useAnimatedStyle(() => {
|
|
34
34
|
const rawScrollValue = scrollValue.value;
|
|
35
35
|
const index = Math.floor(rawScrollValue);
|
|
36
36
|
const offset = rawScrollValue % 1;
|
|
@@ -44,11 +44,7 @@ export default function TabIndicator(props) {
|
|
|
44
44
|
left: x1 + leftInset,
|
|
45
45
|
width: Math.max(x2 - x1 - rightInset, 0)
|
|
46
46
|
};
|
|
47
|
-
});
|
|
48
|
-
const animatedStyle = useAnimatedStyle(() => ({
|
|
49
|
-
left: layout.value.left,
|
|
50
|
-
width: layout.value.width
|
|
51
|
-
}));
|
|
47
|
+
}, [coordinates, scrollable]);
|
|
52
48
|
return /*#__PURE__*/React.createElement(Animated.View, _extends({
|
|
53
49
|
style: [styles.root, disabled ? styles.disabled : undefined, animatedStyle, style]
|
|
54
50
|
}, otherProps));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["React","Animated","useAnimatedStyle","
|
|
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,13 +1,12 @@
|
|
|
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, useEffect, useMemo, useRef } from 'react';
|
|
4
4
|
import { ScrollView, View } from 'react-native';
|
|
5
5
|
import { Easing, useSharedValue, withTiming } from 'react-native-reanimated';
|
|
6
|
-
import { isEveryDefined } from '@fountain-ui/utils';
|
|
7
6
|
import { css, useTheme } from '../styles';
|
|
8
|
-
import { useWidth } from '../internal/hooks';
|
|
9
|
-
import { defaultCoordinate } from './TabCoordinate';
|
|
10
7
|
import TabIndicator from './TabIndicator';
|
|
8
|
+
import useTabsWidth from './useTabsWidth';
|
|
9
|
+
import useTabCoordinates from './useTabCoordinates';
|
|
11
10
|
|
|
12
11
|
const useStyles = function () {
|
|
13
12
|
const theme = useTheme();
|
|
@@ -25,6 +24,10 @@ const useStyles = function () {
|
|
|
25
24
|
};
|
|
26
25
|
};
|
|
27
26
|
|
|
27
|
+
const ANIMATION_CONFIG = {
|
|
28
|
+
duration: 200,
|
|
29
|
+
easing: Easing.out(Easing.exp)
|
|
30
|
+
};
|
|
28
31
|
export default function Tabs(props) {
|
|
29
32
|
const {
|
|
30
33
|
children,
|
|
@@ -40,53 +43,50 @@ export default function Tabs(props) {
|
|
|
40
43
|
...otherProps
|
|
41
44
|
} = props;
|
|
42
45
|
const styles = useStyles();
|
|
43
|
-
const [containerWidth, handleLayout] =
|
|
44
|
-
const scrollViewRef =
|
|
45
|
-
const
|
|
46
|
-
|
|
46
|
+
const [containerWidth, handleLayout] = useTabsWidth();
|
|
47
|
+
const scrollViewRef = useRef(null);
|
|
48
|
+
const {
|
|
49
|
+
coordinates,
|
|
50
|
+
updateCoordinate
|
|
51
|
+
} = useTabCoordinates(children);
|
|
47
52
|
const internalScrollValue = useSharedValue(0);
|
|
48
|
-
const scrollValue = scrollValueProp
|
|
49
|
-
const isReadyToRenderIndicator =
|
|
50
|
-
|
|
53
|
+
const scrollValue = scrollValueProp ?? internalScrollValue;
|
|
54
|
+
const isReadyToRenderIndicator = coordinates.length > 0;
|
|
55
|
+
useEffect(() => {
|
|
51
56
|
const animateTab = index => {
|
|
52
|
-
|
|
53
|
-
duration: 200,
|
|
54
|
-
easing: Easing.out(Easing.exp)
|
|
55
|
-
});
|
|
57
|
+
scrollValue.value = withTiming(index, ANIMATION_CONFIG);
|
|
56
58
|
};
|
|
57
59
|
|
|
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);
|
|
60
68
|
}
|
|
61
|
-
}, [indexProp, scrollValueProp, internalScrollValue]);
|
|
62
|
-
React.useEffect(() => {
|
|
63
|
-
const snapTab = index => {
|
|
64
|
-
const scrollView = scrollViewRef.current;
|
|
65
|
-
const coordinate = coordinates[index - 1] || defaultCoordinate;
|
|
66
69
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
x,
|
|
72
|
-
y: 0,
|
|
73
|
-
animated: true
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
};
|
|
70
|
+
return 0;
|
|
71
|
+
}, [indexProp, coordinates]);
|
|
72
|
+
useEffect(() => {
|
|
73
|
+
const scrollView = scrollViewRef.current;
|
|
77
74
|
|
|
78
|
-
|
|
79
|
-
|
|
75
|
+
if (scrollView) {
|
|
76
|
+
scrollView.scrollTo({
|
|
77
|
+
x: scrollPosition,
|
|
78
|
+
y: 0,
|
|
79
|
+
animated: true
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
}, [scrollPosition, containerWidth]);
|
|
80
83
|
const tabElements = React.Children.map(children, (child, index) => {
|
|
81
84
|
const onLayout = event => {
|
|
82
85
|
const {
|
|
83
86
|
x,
|
|
84
87
|
width
|
|
85
88
|
} = event.nativeEvent.layout;
|
|
86
|
-
|
|
87
|
-
x1: x,
|
|
88
|
-
x2: x + width
|
|
89
|
-
}, ...prev.slice(index + 1)]);
|
|
89
|
+
updateCoordinate(index, x, width);
|
|
90
90
|
};
|
|
91
91
|
|
|
92
92
|
const onMouseDown = e => {
|
|
@@ -106,7 +106,7 @@ export default function Tabs(props) {
|
|
|
106
106
|
const selected = index === indexProp;
|
|
107
107
|
const enableIndicatorPlaceholder = disableIndicator ? false : isReadyToRenderIndicator ? false : selected; //@ts-ignore
|
|
108
108
|
|
|
109
|
-
return /*#__PURE__*/
|
|
109
|
+
return /*#__PURE__*/cloneElement(child, {
|
|
110
110
|
enableIndicator: enableIndicatorPlaceholder,
|
|
111
111
|
onLayout,
|
|
112
112
|
onPress,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["React","ScrollView","View","Easing","useSharedValue","withTiming","isEveryDefined","css","useTheme","useWidth","defaultCoordinate","TabIndicator","useStyles","theme","root","fixedRoot","flexDirection","fixedTab","flex","scrollableContainer","paddingHorizontal","spacing","Tabs","props","children","index","indexProp","disableIndicator","keyboardDismissMode","keyboardShouldPersistTaps","onChange","scrollable","scrollValue","scrollValueProp","style","variant","otherProps","styles","containerWidth","handleLayout","scrollViewRef","useRef","tabCount","Children","count","coordinates","setCoordinates","useState","Array","internalScrollValue","isReadyToRenderIndicator","useEffect","animateTab","value","duration","easing","out","exp","undefined","snapTab","scrollView","current","coordinate","tabWidth","x2","x1","x","scrollTo","y","animated","tabElements","map","child","onLayout","event","width","nativeEvent","layout","prev","slice","onMouseDown","e","preventDefault","onPress","selected","enableIndicatorPlaceholder","cloneElement","enableIndicator","indicator"],"sources":["Tabs.tsx"],"sourcesContent":["import React from 'react';\nimport { GestureResponderEvent, LayoutChangeEvent, ScrollView, View } from 'react-native';\nimport { Easing, useSharedValue, withTiming } from 'react-native-reanimated';\nimport { NamedStylesStringUnion, UseStyles } from '@fountain-ui/styles';\nimport { isEveryDefined } from '@fountain-ui/utils';\nimport { css, useTheme } from '../styles';\nimport { useWidth } from '../internal/hooks';\nimport type TabsProps from './TabsProps';\nimport TabCoordinate, { defaultCoordinate } from './TabCoordinate';\nimport TabIndicator from './TabIndicator';\n\ntype TabsStyleKeys =\n | 'root'\n | 'fixedRoot'\n | 'fixedTab'\n | 'scrollableContainer';\n\ntype TabsStyles = NamedStylesStringUnion<TabsStyleKeys>;\n\nconst useStyles: UseStyles<TabsStyles> = function (): TabsStyles {\n const theme = useTheme();\n\n return {\n root: {},\n fixedRoot: {\n flexDirection: 'row',\n },\n fixedTab: {\n flex: 1,\n },\n scrollableContainer: {\n paddingHorizontal: theme.spacing(1),\n },\n };\n};\n\nexport default function Tabs(props: TabsProps) {\n const {\n children,\n index: indexProp,\n disableIndicator = false,\n keyboardDismissMode = 'none',\n keyboardShouldPersistTaps = 'never',\n onChange,\n scrollable = false,\n scrollValue: scrollValueProp,\n style,\n variant = 'primary',\n ...otherProps\n } = props;\n\n const styles = useStyles();\n\n const [containerWidth, handleLayout] = useWidth();\n\n const scrollViewRef = React.useRef<ScrollView | null>(null);\n\n const tabCount = React.Children.count(children);\n const [coordinates, setCoordinates] = React.useState<TabCoordinate[]>(() => new Array(tabCount));\n\n const internalScrollValue = useSharedValue(0);\n const scrollValue = scrollValueProp || internalScrollValue;\n\n const isReadyToRenderIndicator = isEveryDefined(coordinates);\n\n React.useEffect(() => {\n const animateTab = (index: number) => {\n internalScrollValue.value = withTiming(index, {\n duration: 200,\n easing: Easing.out(Easing.exp),\n });\n };\n\n if (scrollValueProp === undefined) {\n animateTab(indexProp);\n }\n }, [indexProp, scrollValueProp, internalScrollValue]);\n\n React.useEffect(() => {\n const snapTab = (index: number) => {\n const scrollView = scrollViewRef.current;\n const coordinate: TabCoordinate = coordinates[index - 1] || defaultCoordinate;\n\n if (scrollView) {\n const tabWidth = coordinate.x2 - coordinate.x1;\n const x = coordinate.x1 + tabWidth / 2;\n\n scrollView.scrollTo({ x, y: 0, animated: true });\n }\n };\n\n snapTab(indexProp);\n }, [indexProp, containerWidth, coordinates]);\n\n const tabElements = React.Children.map(children, (child, index) => {\n const onLayout = (event: LayoutChangeEvent) => {\n const { x, width } = event.nativeEvent.layout;\n\n setCoordinates(prev => ([\n ...prev.slice(0, index),\n { x1: x, x2: x + width },\n ...prev.slice(index + 1),\n ]));\n };\n\n const onMouseDown = (e: GestureResponderEvent) => {\n if (keyboardShouldPersistTaps === 'always') {\n e.preventDefault();\n }\n };\n\n const onPress = () => {\n onChange?.(index);\n // @ts-ignore\n child.props.onPress?.();\n };\n\n const selected = index === indexProp;\n const enableIndicatorPlaceholder = disableIndicator\n ? false\n : (isReadyToRenderIndicator ? false : selected);\n\n //@ts-ignore\n return React.cloneElement(child, {\n enableIndicator: enableIndicatorPlaceholder,\n onLayout,\n onPress,\n onMouseDown,\n variant,\n selected,\n style: scrollable ? undefined : styles.fixedTab,\n });\n });\n\n const indicator = (\n <TabIndicator\n coordinates={coordinates}\n disabled={disableIndicator}\n scrollable={scrollable}\n scrollValue={scrollValue}\n />\n );\n\n return (\n <View\n onLayout={handleLayout}\n style={css([\n styles.root,\n scrollable ? undefined : styles.fixedRoot,\n style,\n ])}\n {...otherProps}\n >\n {scrollable ? (\n <ScrollView\n automaticallyAdjustContentInsets={false}\n bounces={false}\n contentContainerStyle={styles.scrollableContainer}\n directionalLockEnabled={true}\n horizontal={true}\n ref={scrollViewRef}\n scrollsToTop={false}\n showsHorizontalScrollIndicator={false}\n showsVerticalScrollIndicator={false}\n keyboardDismissMode={keyboardDismissMode}\n keyboardShouldPersistTaps={keyboardShouldPersistTaps}\n >\n {tabElements}\n {indicator}\n </ScrollView>\n ) : (\n <>\n {tabElements}\n {indicator}\n </>\n )}\n </View>\n );\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"names":["React","cloneElement","useEffect","useMemo","useRef","ScrollView","View","Easing","useSharedValue","withTiming","css","useTheme","TabIndicator","useTabsWidth","useTabCoordinates","useStyles","theme","root","fixedRoot","flexDirection","fixedTab","flex","scrollableContainer","paddingHorizontal","spacing","ANIMATION_CONFIG","duration","easing","out","exp","Tabs","props","children","index","indexProp","disableIndicator","keyboardDismissMode","keyboardShouldPersistTaps","onChange","scrollable","scrollValue","scrollValueProp","style","variant","otherProps","styles","containerWidth","handleLayout","scrollViewRef","coordinates","updateCoordinate","internalScrollValue","isReadyToRenderIndicator","length","animateTab","value","scrollPosition","coordinate","tabWidth","x2","x1","Math","floor","scrollView","current","scrollTo","x","y","animated","tabElements","Children","map","child","onLayout","event","width","nativeEvent","layout","onMouseDown","e","preventDefault","onPress","selected","enableIndicatorPlaceholder","enableIndicator","undefined","indicator"],"sources":["Tabs.tsx"],"sourcesContent":["import React, { cloneElement, useEffect, useMemo, useRef } from 'react';\nimport { GestureResponderEvent, LayoutChangeEvent, ScrollView, View } from 'react-native';\nimport type { WithTimingConfig } from 'react-native-reanimated';\nimport { Easing, useSharedValue, withTiming } from 'react-native-reanimated';\nimport { NamedStylesStringUnion, UseStyles } from '@fountain-ui/styles';\nimport { css, useTheme } from '../styles';\nimport type TabsProps from './TabsProps';\nimport TabIndicator from './TabIndicator';\nimport useTabsWidth from './useTabsWidth';\nimport useTabCoordinates from './useTabCoordinates';\n\ntype TabsStyleKeys =\n | 'root'\n | 'fixedRoot'\n | 'fixedTab'\n | 'scrollableContainer';\n\ntype TabsStyles = NamedStylesStringUnion<TabsStyleKeys>;\n\nconst useStyles: UseStyles<TabsStyles> = function (): TabsStyles {\n const theme = useTheme();\n\n return {\n root: {},\n fixedRoot: {\n flexDirection: 'row',\n },\n fixedTab: {\n flex: 1,\n },\n scrollableContainer: {\n paddingHorizontal: theme.spacing(1),\n },\n };\n};\n\nconst ANIMATION_CONFIG: Readonly<WithTimingConfig> = {\n duration: 200,\n easing: Easing.out(Easing.exp),\n};\n\nexport default function Tabs(props: TabsProps) {\n const {\n children,\n index: indexProp,\n disableIndicator = false,\n keyboardDismissMode = 'none',\n keyboardShouldPersistTaps = 'never',\n onChange,\n scrollable = false,\n scrollValue: scrollValueProp,\n style,\n variant = 'primary',\n ...otherProps\n } = props;\n\n const styles = useStyles();\n\n const [containerWidth, handleLayout] = useTabsWidth();\n\n const scrollViewRef = useRef<ScrollView | null>(null);\n\n const { coordinates, updateCoordinate } = useTabCoordinates(children);\n\n const internalScrollValue = useSharedValue(0);\n const scrollValue = scrollValueProp ?? internalScrollValue;\n\n const isReadyToRenderIndicator = coordinates.length > 0;\n\n useEffect(() => {\n const animateTab = (index: number) => {\n scrollValue.value = withTiming(index, ANIMATION_CONFIG);\n };\n\n animateTab(indexProp);\n }, [indexProp, scrollValue]);\n\n const scrollPosition = useMemo<number>(() => {\n const coordinate = coordinates[indexProp - 1];\n\n if (coordinate) {\n const tabWidth = coordinate.x2 - coordinate.x1;\n return Math.floor(coordinate.x1 + tabWidth / 2);\n }\n\n return 0;\n }, [indexProp, coordinates]);\n\n useEffect(() => {\n const scrollView = scrollViewRef.current;\n\n if (scrollView) {\n scrollView.scrollTo({ x: scrollPosition, y: 0, animated: true });\n }\n }, [scrollPosition, containerWidth]);\n\n const tabElements = React.Children.map(children, (child, index) => {\n const onLayout = (event: LayoutChangeEvent) => {\n const { x, width } = event.nativeEvent.layout;\n\n updateCoordinate(index, x, width);\n };\n\n const onMouseDown = (e: GestureResponderEvent) => {\n if (keyboardShouldPersistTaps === 'always') {\n e.preventDefault();\n }\n };\n\n const onPress = () => {\n onChange?.(index);\n // @ts-ignore\n child.props.onPress?.();\n };\n\n const selected = index === indexProp;\n const enableIndicatorPlaceholder = disableIndicator\n ? false\n : (isReadyToRenderIndicator ? false : selected);\n\n //@ts-ignore\n return cloneElement(child, {\n enableIndicator: enableIndicatorPlaceholder,\n onLayout,\n onPress,\n onMouseDown,\n variant,\n selected,\n style: scrollable ? undefined : styles.fixedTab,\n });\n });\n\n const indicator = (\n <TabIndicator\n coordinates={coordinates}\n disabled={disableIndicator}\n scrollable={scrollable}\n scrollValue={scrollValue}\n />\n );\n\n return (\n <View\n onLayout={handleLayout}\n style={css([\n styles.root,\n scrollable ? undefined : styles.fixedRoot,\n style,\n ])}\n {...otherProps}\n >\n {scrollable ? (\n <ScrollView\n automaticallyAdjustContentInsets={false}\n bounces={false}\n contentContainerStyle={styles.scrollableContainer}\n directionalLockEnabled={true}\n horizontal={true}\n ref={scrollViewRef}\n scrollsToTop={false}\n showsHorizontalScrollIndicator={false}\n showsVerticalScrollIndicator={false}\n keyboardDismissMode={keyboardDismissMode}\n keyboardShouldPersistTaps={keyboardShouldPersistTaps}\n >\n {tabElements}\n {indicator}\n </ScrollView>\n ) : (\n <React.Fragment>\n {tabElements}\n {indicator}\n </React.Fragment>\n )}\n </View>\n );\n};\n"],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import React, { useRef, useState } from 'react';
|
|
2
|
+
import { isEveryDefined } from '@fountain-ui/utils';
|
|
3
|
+
export default function useTabCoordinates(tabElements) {
|
|
4
|
+
const incompleteCoordinatesRef = useRef([]);
|
|
5
|
+
const [completeCoordinates, setCompleteCoordinates] = useState([]);
|
|
6
|
+
|
|
7
|
+
const isAllCoordinatesDefined = coordinates => {
|
|
8
|
+
const numberOfTab = React.Children.count(tabElements);
|
|
9
|
+
const numberOfCoordinates = coordinates.length;
|
|
10
|
+
const everyCoordinatesDefined = isEveryDefined(coordinates);
|
|
11
|
+
return numberOfTab === numberOfCoordinates && everyCoordinatesDefined;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const updateCoordinate = (index, x, width) => {
|
|
15
|
+
incompleteCoordinatesRef.current[index] = {
|
|
16
|
+
x1: x,
|
|
17
|
+
x2: x + width
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
if (isAllCoordinatesDefined(incompleteCoordinatesRef.current)) {
|
|
21
|
+
setCompleteCoordinates(incompleteCoordinatesRef.current);
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
return {
|
|
26
|
+
coordinates: completeCoordinates,
|
|
27
|
+
updateCoordinate
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=useTabCoordinates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["React","useRef","useState","isEveryDefined","useTabCoordinates","tabElements","incompleteCoordinatesRef","completeCoordinates","setCompleteCoordinates","isAllCoordinatesDefined","coordinates","numberOfTab","Children","count","numberOfCoordinates","length","everyCoordinatesDefined","updateCoordinate","index","x","width","current","x1","x2"],"sources":["useTabCoordinates.ts"],"sourcesContent":["import React, { useRef, useState } from 'react';\nimport { isEveryDefined } from '@fountain-ui/utils';\nimport TabCoordinate from './TabCoordinate';\n\nexport interface UseTabCoordinates {\n coordinates: TabCoordinate[];\n updateCoordinate: (index: number, x: number, width: number) => void;\n}\n\nexport default function useTabCoordinates(tabElements: React.ReactNode): UseTabCoordinates {\n const incompleteCoordinatesRef = useRef<TabCoordinate[]>([]);\n\n const [completeCoordinates, setCompleteCoordinates] = useState<TabCoordinate[]>([]);\n\n const isAllCoordinatesDefined = (coordinates: TabCoordinate[]): boolean => {\n const numberOfTab = React.Children.count(tabElements);\n const numberOfCoordinates = coordinates.length;\n\n const everyCoordinatesDefined = isEveryDefined(coordinates);\n\n return numberOfTab === numberOfCoordinates && everyCoordinatesDefined;\n };\n\n const updateCoordinate = (index: number, x: number, width: number) => {\n incompleteCoordinatesRef.current[index] = { x1: x, x2: x + width };\n\n if (isAllCoordinatesDefined(incompleteCoordinatesRef.current)) {\n setCompleteCoordinates(incompleteCoordinatesRef.current);\n }\n };\n\n return {\n coordinates: completeCoordinates,\n updateCoordinate,\n };\n}\n"],"mappings":"AAAA,OAAOA,KAAP,IAAgBC,MAAhB,EAAwBC,QAAxB,QAAwC,OAAxC;AACA,SAASC,cAAT,QAA+B,oBAA/B;AAQA,eAAe,SAASC,iBAAT,CAA2BC,WAA3B,EAA4E;EACvF,MAAMC,wBAAwB,GAAGL,MAAM,CAAkB,EAAlB,CAAvC;EAEA,MAAM,CAACM,mBAAD,EAAsBC,sBAAtB,IAAgDN,QAAQ,CAAkB,EAAlB,CAA9D;;EAEA,MAAMO,uBAAuB,GAAIC,WAAD,IAA2C;IACvE,MAAMC,WAAW,GAAGX,KAAK,CAACY,QAAN,CAAeC,KAAf,CAAqBR,WAArB,CAApB;IACA,MAAMS,mBAAmB,GAAGJ,WAAW,CAACK,MAAxC;IAEA,MAAMC,uBAAuB,GAAGb,cAAc,CAACO,WAAD,CAA9C;IAEA,OAAOC,WAAW,KAAKG,mBAAhB,IAAuCE,uBAA9C;EACH,CAPD;;EASA,MAAMC,gBAAgB,GAAG,CAACC,KAAD,EAAgBC,CAAhB,EAA2BC,KAA3B,KAA6C;IAClEd,wBAAwB,CAACe,OAAzB,CAAiCH,KAAjC,IAA0C;MAAEI,EAAE,EAAEH,CAAN;MAASI,EAAE,EAAEJ,CAAC,GAAGC;IAAjB,CAA1C;;IAEA,IAAIX,uBAAuB,CAACH,wBAAwB,CAACe,OAA1B,CAA3B,EAA+D;MAC3Db,sBAAsB,CAACF,wBAAwB,CAACe,OAA1B,CAAtB;IACH;EACJ,CAND;;EAQA,OAAO;IACHX,WAAW,EAAEH,mBADV;IAEHU;EAFG,CAAP;AAIH"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { useCallback, useState } from 'react';
|
|
2
|
+
import { Dimensions } from 'react-native';
|
|
3
|
+
|
|
4
|
+
const assumeInitialWidth = () => Dimensions.get('window').width;
|
|
5
|
+
|
|
6
|
+
const isIntegerPartEquals = (a, b) => Math.round(a) === Math.round(b);
|
|
7
|
+
|
|
8
|
+
const isIntegerPartDifferent = (a, b) => !isIntegerPartEquals(a, b);
|
|
9
|
+
|
|
10
|
+
export default function useTabsWidth() {
|
|
11
|
+
const [width, setWidth] = useState(assumeInitialWidth);
|
|
12
|
+
const onLayout = useCallback(e => {
|
|
13
|
+
const newWidth = e.nativeEvent.layout.width;
|
|
14
|
+
setWidth(prevWidth => isIntegerPartDifferent(prevWidth, newWidth) ? newWidth : prevWidth);
|
|
15
|
+
}, []);
|
|
16
|
+
return [width, onLayout];
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=useTabsWidth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["useCallback","useState","Dimensions","assumeInitialWidth","get","width","isIntegerPartEquals","a","b","Math","round","isIntegerPartDifferent","useTabsWidth","setWidth","onLayout","e","newWidth","nativeEvent","layout","prevWidth"],"sources":["useTabsWidth.ts"],"sourcesContent":["import { useCallback, useState } from 'react';\nimport { Dimensions, LayoutChangeEvent, ViewProps } from 'react-native';\n\nconst assumeInitialWidth = (): number => Dimensions.get('window').width;\n\nconst isIntegerPartEquals = (a: number, b: number) => Math.round(a) === Math.round(b);\n\nconst isIntegerPartDifferent = (a: number, b: number) => !isIntegerPartEquals(a, b);\n\nexport default function useTabsWidth(): [number, ViewProps['onLayout']] {\n const [width, setWidth] = useState(assumeInitialWidth);\n\n const onLayout = useCallback((e: LayoutChangeEvent) => {\n const newWidth = e.nativeEvent.layout.width;\n\n setWidth((prevWidth) => isIntegerPartDifferent(prevWidth, newWidth) ? newWidth : prevWidth);\n }, []);\n\n return [width, onLayout];\n}\n"],"mappings":"AAAA,SAASA,WAAT,EAAsBC,QAAtB,QAAsC,OAAtC;AACA,SAASC,UAAT,QAAyD,cAAzD;;AAEA,MAAMC,kBAAkB,GAAG,MAAcD,UAAU,CAACE,GAAX,CAAe,QAAf,EAAyBC,KAAlE;;AAEA,MAAMC,mBAAmB,GAAG,CAACC,CAAD,EAAYC,CAAZ,KAA0BC,IAAI,CAACC,KAAL,CAAWH,CAAX,MAAkBE,IAAI,CAACC,KAAL,CAAWF,CAAX,CAAxE;;AAEA,MAAMG,sBAAsB,GAAG,CAACJ,CAAD,EAAYC,CAAZ,KAA0B,CAACF,mBAAmB,CAACC,CAAD,EAAIC,CAAJ,CAA7E;;AAEA,eAAe,SAASI,YAAT,GAAyD;EACpE,MAAM,CAACP,KAAD,EAAQQ,QAAR,IAAoBZ,QAAQ,CAACE,kBAAD,CAAlC;EAEA,MAAMW,QAAQ,GAAGd,WAAW,CAAEe,CAAD,IAA0B;IACnD,MAAMC,QAAQ,GAAGD,CAAC,CAACE,WAAF,CAAcC,MAAd,CAAqBb,KAAtC;IAEAQ,QAAQ,CAAEM,SAAD,IAAeR,sBAAsB,CAACQ,SAAD,EAAYH,QAAZ,CAAtB,GAA8CA,QAA9C,GAAyDG,SAAzE,CAAR;EACH,CAJ2B,EAIzB,EAJyB,CAA5B;EAMA,OAAO,CAACd,KAAD,EAAQS,QAAR,CAAP;AACH"}
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { useEffect, useState } from 'react';
|
|
2
2
|
import { Text, View } from 'react-native';
|
|
3
|
-
import { TouchableWithoutFeedback } from 'react-native-gesture-handler';
|
|
4
3
|
import Animated, { useAnimatedStyle, useSharedValue, withTiming } from 'react-native-reanimated';
|
|
5
4
|
import { rgb } from '@fountain-ui/utils';
|
|
5
|
+
import ButtonBase from '../ButtonBase';
|
|
6
6
|
import { createFontStyle, css, useTheme } from '../styles';
|
|
7
7
|
import { Close as CloseIcon } from '../internal/icons';
|
|
8
8
|
import UpArrow from './UpArrow';
|
|
9
|
-
const
|
|
9
|
+
const DEFAULT_OPACITY = 0.8;
|
|
10
10
|
const initialLayout = {
|
|
11
11
|
width: 0,
|
|
12
12
|
height: 0,
|
|
13
13
|
x: 0,
|
|
14
14
|
y: 0
|
|
15
15
|
};
|
|
16
|
-
const
|
|
16
|
+
const ANIMATION_CONFIG = {
|
|
17
17
|
duration: 150
|
|
18
18
|
};
|
|
19
19
|
export default function Tooltip(props) {
|
|
@@ -30,13 +30,13 @@ export default function Tooltip(props) {
|
|
|
30
30
|
visible = false
|
|
31
31
|
} = props;
|
|
32
32
|
const theme = useTheme();
|
|
33
|
-
const [layout, setLayout] =
|
|
33
|
+
const [layout, setLayout] = useState(initialLayout);
|
|
34
34
|
const scale = useSharedValue(0);
|
|
35
|
-
const
|
|
35
|
+
const animatedStyle = useAnimatedStyle(() => ({
|
|
36
36
|
transform: [{
|
|
37
37
|
scale: scale.value
|
|
38
38
|
}]
|
|
39
|
-
}));
|
|
39
|
+
}), []);
|
|
40
40
|
const [r, g, b] = rgb(theme.palette.primary.main);
|
|
41
41
|
const totalVerticalOffset = -(layout.height + verticalOffset);
|
|
42
42
|
const tooltipLayoutStyle = {
|
|
@@ -50,13 +50,13 @@ export default function Tooltip(props) {
|
|
|
50
50
|
height: visible ? undefined : 0,
|
|
51
51
|
overflow: visible ? undefined : 'hidden'
|
|
52
52
|
};
|
|
53
|
-
|
|
54
|
-
const
|
|
55
|
-
scale.value = withTiming(
|
|
53
|
+
useEffect(() => {
|
|
54
|
+
const nextScaleValue = visible ? 1 : 0;
|
|
55
|
+
scale.value = withTiming(nextScaleValue, ANIMATION_CONFIG);
|
|
56
56
|
}, [visible]);
|
|
57
57
|
const touchableStyle = {
|
|
58
58
|
alignItems: 'center',
|
|
59
|
-
backgroundColor: `rgba(${r}, ${g}, ${b}, ${
|
|
59
|
+
backgroundColor: `rgba(${r}, ${g}, ${b}, ${DEFAULT_OPACITY})`,
|
|
60
60
|
borderRadius: theme.shape.roundness,
|
|
61
61
|
flexDirection: 'row',
|
|
62
62
|
padding: theme.spacing(2)
|
|
@@ -68,8 +68,8 @@ export default function Tooltip(props) {
|
|
|
68
68
|
const textStyle = css([fontStyle, {
|
|
69
69
|
marginRight: theme.spacing(2)
|
|
70
70
|
}]);
|
|
71
|
-
const buttonElem = /*#__PURE__*/React.createElement(
|
|
72
|
-
|
|
71
|
+
const buttonElem = /*#__PURE__*/React.createElement(ButtonBase, {
|
|
72
|
+
pressEffect: 'none',
|
|
73
73
|
onPress: onClose
|
|
74
74
|
}, /*#__PURE__*/React.createElement(View, {
|
|
75
75
|
style: css(touchableStyle)
|
|
@@ -86,13 +86,13 @@ export default function Tooltip(props) {
|
|
|
86
86
|
const arrowElem = /*#__PURE__*/React.createElement(UpArrow, {
|
|
87
87
|
upsideDown: placement === 'top',
|
|
88
88
|
fill: theme.palette.primary.main,
|
|
89
|
-
opacity:
|
|
89
|
+
opacity: DEFAULT_OPACITY
|
|
90
90
|
});
|
|
91
91
|
return /*#__PURE__*/React.createElement(View, {
|
|
92
92
|
style: style
|
|
93
93
|
}, children, /*#__PURE__*/React.createElement(Animated.View, {
|
|
94
94
|
onLayout: event => setLayout(event.nativeEvent.layout),
|
|
95
|
-
style: [
|
|
95
|
+
style: [animatedStyle, tooltipLayoutStyle, tooltipStyle]
|
|
96
96
|
}, placement === 'top' ? /*#__PURE__*/React.createElement(React.Fragment, null, buttonElem, arrowElem) : /*#__PURE__*/React.createElement(React.Fragment, null, arrowElem, buttonElem)));
|
|
97
97
|
}
|
|
98
98
|
;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["React","
|
|
1
|
+
{"version":3,"names":["React","useEffect","useState","Text","View","Animated","useAnimatedStyle","useSharedValue","withTiming","rgb","ButtonBase","createFontStyle","css","useTheme","Close","CloseIcon","UpArrow","DEFAULT_OPACITY","initialLayout","width","height","x","y","ANIMATION_CONFIG","duration","Tooltip","props","children","left","onClose","placement","right","style","title","tooltipStyle","verticalOffset","visible","theme","layout","setLayout","scale","animatedStyle","transform","value","r","g","b","palette","primary","main","totalVerticalOffset","tooltipLayoutStyle","alignItems","bottom","undefined","position","top","zIndex","tooltip","overflow","nextScaleValue","touchableStyle","backgroundColor","borderRadius","shape","roundness","flexDirection","padding","spacing","fontStyle","selector","typo","caption2","color","contrastTextColor","textStyle","marginRight","buttonElem","arrowElem","event","nativeEvent"],"sources":["Tooltip.tsx"],"sourcesContent":["import React, { useEffect, useState } from 'react';\nimport { Text, View, ViewProps } from 'react-native';\nimport type { WithTimingConfig } from 'react-native-reanimated';\nimport Animated, { useAnimatedStyle, useSharedValue, withTiming } from 'react-native-reanimated';\nimport { rgb } from '@fountain-ui/utils';\nimport ButtonBase from '../ButtonBase';\nimport { createFontStyle, css, useTheme } from '../styles';\nimport { Close as CloseIcon } from '../internal/icons';\nimport type TooltipProps from './TooltipProps';\nimport UpArrow from './UpArrow';\n\nconst DEFAULT_OPACITY = 0.8;\nconst initialLayout = { width: 0, height: 0, x: 0, y: 0 };\n\nconst ANIMATION_CONFIG: Readonly<WithTimingConfig> = { duration: 150 };\n\nexport default function Tooltip(props: TooltipProps) {\n const {\n children,\n left,\n onClose,\n placement = 'top',\n right,\n style,\n title,\n tooltipStyle,\n verticalOffset = 4,\n visible = false,\n } = props;\n\n const theme = useTheme();\n\n const [layout, setLayout] = useState(initialLayout);\n\n const scale = useSharedValue(0);\n\n const animatedStyle = useAnimatedStyle(() => ({\n transform: [{ scale: scale.value }],\n }), []);\n\n const [r, g, b] = rgb(theme.palette.primary.main);\n\n const totalVerticalOffset = -(layout.height + verticalOffset);\n const tooltipLayoutStyle: ViewProps['style'] = {\n alignItems: 'center',\n bottom: placement === 'bottom' ? totalVerticalOffset : undefined,\n left,\n position: 'absolute',\n right,\n top: placement === 'top' ? totalVerticalOffset : undefined,\n zIndex: theme.zIndex.tooltip,\n height: visible ? undefined : 0,\n overflow: visible ? undefined : 'hidden',\n };\n\n useEffect(() => {\n const nextScaleValue = visible ? 1 : 0;\n\n scale.value = withTiming(nextScaleValue, ANIMATION_CONFIG);\n }, [visible]);\n\n const touchableStyle: ViewProps['style'] = {\n alignItems: 'center',\n backgroundColor: `rgba(${r}, ${g}, ${b}, ${DEFAULT_OPACITY})`,\n borderRadius: theme.shape.roundness,\n flexDirection: 'row',\n padding: theme.spacing(2),\n };\n\n const fontStyle = createFontStyle(theme, {\n selector: (typo) => typo.caption2,\n color: theme.palette.primary.contrastTextColor,\n });\n\n const textStyle = css([\n fontStyle,\n { marginRight: theme.spacing(2) },\n ]);\n\n const buttonElem = (\n <ButtonBase\n pressEffect={'none'}\n onPress={onClose}\n >\n <View style={css(touchableStyle)}>\n <Text\n children={title}\n // TODO: Should we provide text prop customization?\n numberOfLines={1}\n style={textStyle}\n />\n <CloseIcon\n fill={theme.palette.primary.contrastTextColor}\n width={20}\n height={20}\n />\n </View>\n </ButtonBase>\n );\n\n const arrowElem = (\n <UpArrow\n upsideDown={placement === 'top'}\n fill={theme.palette.primary.main}\n opacity={DEFAULT_OPACITY}\n />\n );\n\n return (\n <View style={style}>\n {children}\n\n <Animated.View\n onLayout={(event) => setLayout(event.nativeEvent.layout)}\n style={[\n animatedStyle,\n tooltipLayoutStyle,\n tooltipStyle,\n ]}\n >\n {placement === 'top' ? (\n <React.Fragment>\n {buttonElem}\n {arrowElem}\n </React.Fragment>\n ) : (\n <React.Fragment>\n {arrowElem}\n {buttonElem}\n </React.Fragment>\n )}\n </Animated.View>\n </View>\n );\n};\n"],"mappings":"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"}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import Animated from 'react-native
|
|
2
|
-
import Pressable from '../Pressable';
|
|
3
|
-
|
|
1
|
+
import { Animated } from 'react-native';
|
|
2
|
+
import Pressable from '../Pressable';
|
|
4
3
|
export default Animated.createAnimatedComponent(Pressable);
|
|
5
4
|
//# sourceMappingURL=AnimatedPressable.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["Animated","Pressable","createAnimatedComponent"],"sources":["AnimatedPressable.tsx"],"sourcesContent":["import React from 'react';\nimport Animated from 'react-native
|
|
1
|
+
{"version":3,"names":["Animated","Pressable","createAnimatedComponent"],"sources":["AnimatedPressable.tsx"],"sourcesContent":["import React from 'react';\nimport { Animated } from 'react-native';\nimport Pressable from '../Pressable';\n\nexport default Animated.createAnimatedComponent(Pressable);\n"],"mappings":"AACA,SAASA,QAAT,QAAyB,cAAzB;AACA,OAAOC,SAAP,MAAsB,cAAtB;AAEA,eAAeD,QAAQ,CAACE,uBAAT,CAAiCD,SAAjC,CAAf"}
|