@fountain-ui/lab 3.0.0-alpha.19 → 3.0.0-alpha.20
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/BottomSheet/BottomSheetNative.js +3 -1
- package/build/commonjs/BottomSheet/BottomSheetNative.js.map +1 -1
- package/build/commonjs/BottomSheet/BottomSheetWeb.js +11 -6
- package/build/commonjs/BottomSheet/BottomSheetWeb.js.map +1 -1
- package/build/commonjs/BottomSheet/useDynamicSnapPoints.js +1 -7
- package/build/commonjs/BottomSheet/useDynamicSnapPoints.js.map +1 -1
- package/build/module/BottomSheet/BottomSheetNative.js +3 -1
- package/build/module/BottomSheet/BottomSheetNative.js.map +1 -1
- package/build/module/BottomSheet/BottomSheetWeb.js +10 -6
- package/build/module/BottomSheet/BottomSheetWeb.js.map +1 -1
- package/build/module/BottomSheet/useDynamicSnapPoints.js +2 -8
- package/build/module/BottomSheet/useDynamicSnapPoints.js.map +1 -1
- package/package.json +2 -2
- package/src/BottomSheet/BottomSheetNative.tsx +3 -1
- package/src/BottomSheet/BottomSheetWeb.tsx +12 -6
- package/src/BottomSheet/useDynamicSnapPoints.ts +2 -9
|
@@ -33,6 +33,7 @@ const NoHandle = () => null;
|
|
|
33
33
|
|
|
34
34
|
const DEFAULT_PADDING_BOTTOM = 24;
|
|
35
35
|
const DEFAULT_PADDING_TOP = 22;
|
|
36
|
+
const TOP_ELEMENT_HIDDEN_OFFSET = 16;
|
|
36
37
|
|
|
37
38
|
function BottomSheet(props) {
|
|
38
39
|
const {
|
|
@@ -54,7 +55,8 @@ function BottomSheet(props) {
|
|
|
54
55
|
height: windowHeight
|
|
55
56
|
} = (0, _reactNative.useWindowDimensions)();
|
|
56
57
|
const [topElementHeight, setTopElementHeight] = (0, _react.useState)(0);
|
|
57
|
-
const
|
|
58
|
+
const topElementHeightWithoutOffset = Math.max(0, topElementHeight - TOP_ELEMENT_HIDDEN_OFFSET);
|
|
59
|
+
const maxDynamicContentSize = Math.round(windowHeight * maxHeightNormalizedRatio) - topElementHeightWithoutOffset;
|
|
58
60
|
|
|
59
61
|
const handleTopElementLayout = event => {
|
|
60
62
|
const {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["NoHandle","DEFAULT_PADDING_BOTTOM","DEFAULT_PADDING_TOP","BottomSheet","props","backdropOpacity","backgroundStyle","backgroundStyleProp","borderRadius","borderRadiusProp","children","enableDynamicSizing","topElement","index","maxHeightNormalizedRatio","onChange","snapPoints","style","styleProp","indexRef","useRef","bottomSheetRef","height","windowHeight","useWindowDimensions","topElementHeight","setTopElementHeight","useState","maxDynamicContentSize","Math","round","handleTopElementLayout","event","nativeEvent","layout","handleChange","useCallback","newIndex","current","handleDismiss","useEffect","present","dismiss","snapToIndex","theme","useTheme","shape","radius","xxl","css","backgroundColor","palette","surface","base","borderTopLeftRadius","borderTopRightRadius","bottom","bottomSafeInset","useSafeAreaInsets","contentWrapperStyle","flexShrink","maxHeight","minHeight","overflow","paddingBottom","paddingTop","isBackdropTransparent","OpacityAwareBackdrop","topElementOpacity","useAnimatedValue","topElementAnimationStyle","opacity","topElementLocationStyle","position","width","onAnimate","fromIndex","toIndex","isVisible","Animated","timing","toValue","duration","useNativeDriver","isNotAndroid12","start","animatedHandleHeight","animatedSnapPoints","animatedContentHeight","handleContentLayout","useDynamicSnapPoints","TransparentBackdrop","Boolean","undefined"],"sources":["BottomSheetNative.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useRef, useState } from 'react';\nimport { Animated, LayoutChangeEvent, useWindowDimensions, ViewStyle } from 'react-native';\nimport { useSafeAreaInsets } from 'react-native-safe-area-context';\nimport {\n BottomSheetBackdrop,\n BottomSheetBackdropProps,\n BottomSheetModal,\n BottomSheetModalProvider,\n BottomSheetView,\n} from '@gorhom/bottom-sheet';\nimport { Column, css, ExtendedStyle, isNotAndroid12, useAnimatedValue } from '@fountain-ui/core';\nimport { useTheme } from '@fountain-ui/styles';\nimport type BottomSheetProps from './BottomSheetProps';\nimport TransparentBackdrop from './TransparentBackdrop';\nimport useDynamicSnapPoints from './useDynamicSnapPoints.native';\n\nconst NoHandle = () => null;\n\nconst DEFAULT_PADDING_BOTTOM = 24;\nconst DEFAULT_PADDING_TOP = 22;\n\nexport default function BottomSheet(props: BottomSheetProps) {\n const {\n backdropOpacity = 0.5,\n backgroundStyle: backgroundStyleProp,\n borderRadius: borderRadiusProp,\n children,\n enableDynamicSizing = true,\n topElement,\n index,\n maxHeightNormalizedRatio = 0.8,\n onChange,\n snapPoints = [],\n style: styleProp,\n } = props;\n\n const indexRef = useRef<number>(-1);\n const bottomSheetRef = useRef<BottomSheetModal | null>(null);\n\n const { height: windowHeight } = useWindowDimensions();\n const [topElementHeight, setTopElementHeight] = useState(0);\n\n const maxDynamicContentSize = Math.round(windowHeight * maxHeightNormalizedRatio) - topElementHeight;\n\n const handleTopElementLayout = (event: LayoutChangeEvent) => {\n const { height } = event.nativeEvent.layout;\n setTopElementHeight(height);\n };\n\n const handleChange = useCallback((newIndex: number) => {\n indexRef.current = newIndex;\n\n if (onChange) {\n onChange(newIndex);\n }\n }, [onChange]);\n\n const handleDismiss = useCallback(() => {\n handleChange(-1);\n }, [handleChange]);\n\n useEffect(() => {\n if (index === indexRef.current) {\n return;\n }\n\n if (indexRef.current < 0 && index >= 0) {\n bottomSheetRef.current?.present();\n } else if (indexRef.current >= 0 && index < 0) {\n bottomSheetRef.current?.dismiss();\n } else {\n // @ts-ignore\n bottomSheetRef.current?.snapToIndex(index);\n }\n }, [index]);\n\n const theme = useTheme();\n\n const borderRadius = borderRadiusProp ?? theme.shape.radius.xxl;\n const backgroundStyle = css([\n {\n backgroundColor: theme.palette.surface.base,\n borderTopLeftRadius: borderRadius,\n borderTopRightRadius: borderRadius,\n },\n backgroundStyleProp,\n ]);\n\n const { bottom: bottomSafeInset } = useSafeAreaInsets();\n\n const contentWrapperStyle: ViewStyle = css([\n {\n backgroundColor: theme.palette.surface.base,\n borderTopLeftRadius: borderRadius,\n borderTopRightRadius: borderRadius,\n flexShrink: 1,\n maxHeight: maxDynamicContentSize,\n minHeight: 325,\n overflow: 'hidden',\n paddingBottom: DEFAULT_PADDING_BOTTOM + bottomSafeInset,\n paddingTop: DEFAULT_PADDING_TOP,\n },\n styleProp,\n ]);\n\n const isBackdropTransparent = backdropOpacity <= 0;\n\n const OpacityAwareBackdrop = (props: BottomSheetBackdropProps) => (\n <BottomSheetBackdrop\n {...props}\n appearsOnIndex={0}\n disappearsOnIndex={-1}\n opacity={backdropOpacity}\n pressBehavior={onChange ? 'close' : 'none'}\n />\n );\n\n const topElementOpacity = useAnimatedValue(0);\n const topElementAnimationStyle: Animated.WithAnimatedValue<ExtendedStyle> = { opacity: topElementOpacity };\n const topElementLocationStyle: ExtendedStyle = {\n position: 'absolute',\n width: '100%',\n bottom: 0,\n };\n const onAnimate = (fromIndex: number, toIndex: number) => {\n const isVisible = toIndex > -1;\n\n Animated.timing(topElementOpacity, {\n toValue: isVisible ? 1 : 0,\n duration: 0,\n useNativeDriver: isNotAndroid12,\n }).start();\n };\n\n const {\n animatedHandleHeight,\n animatedSnapPoints,\n animatedContentHeight,\n handleContentLayout,\n } = useDynamicSnapPoints(snapPoints);\n\n return (\n <BottomSheetModalProvider>\n <BottomSheetModal\n backdropComponent={isBackdropTransparent ? TransparentBackdrop : OpacityAwareBackdrop}\n // @ts-ignore\n backgroundStyle={backgroundStyle}\n enableOverDrag={false}\n index={index}\n handleComponent={NoHandle}\n onChange={handleChange}\n onDismiss={handleDismiss}\n ref={bottomSheetRef}\n enablePanDownToClose={Boolean(onChange)}\n enableDynamicSizing={enableDynamicSizing}\n maxDynamicContentSize={maxDynamicContentSize}\n detached={Boolean(topElement)}\n onAnimate={topElement ? onAnimate : undefined}\n snapPoints={animatedSnapPoints}\n handleHeight={animatedHandleHeight}\n contentHeight={animatedContentHeight}\n >\n {topElement ? (\n <Animated.View style={topElementAnimationStyle}>\n <Column\n onLayout={handleTopElementLayout}\n style={topElementLocationStyle}\n >\n {topElement}\n </Column>\n </Animated.View>\n ) : null}\n\n <BottomSheetView\n onLayout={handleContentLayout}\n style={contentWrapperStyle}\n >\n {children}\n </BottomSheetView>\n </BottomSheetModal>\n </BottomSheetModalProvider>\n );\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"names":["NoHandle","DEFAULT_PADDING_BOTTOM","DEFAULT_PADDING_TOP","TOP_ELEMENT_HIDDEN_OFFSET","BottomSheet","props","backdropOpacity","backgroundStyle","backgroundStyleProp","borderRadius","borderRadiusProp","children","enableDynamicSizing","topElement","index","maxHeightNormalizedRatio","onChange","snapPoints","style","styleProp","indexRef","useRef","bottomSheetRef","height","windowHeight","useWindowDimensions","topElementHeight","setTopElementHeight","useState","topElementHeightWithoutOffset","Math","max","maxDynamicContentSize","round","handleTopElementLayout","event","nativeEvent","layout","handleChange","useCallback","newIndex","current","handleDismiss","useEffect","present","dismiss","snapToIndex","theme","useTheme","shape","radius","xxl","css","backgroundColor","palette","surface","base","borderTopLeftRadius","borderTopRightRadius","bottom","bottomSafeInset","useSafeAreaInsets","contentWrapperStyle","flexShrink","maxHeight","minHeight","overflow","paddingBottom","paddingTop","isBackdropTransparent","OpacityAwareBackdrop","topElementOpacity","useAnimatedValue","topElementAnimationStyle","opacity","topElementLocationStyle","position","width","onAnimate","fromIndex","toIndex","isVisible","Animated","timing","toValue","duration","useNativeDriver","isNotAndroid12","start","animatedHandleHeight","animatedSnapPoints","animatedContentHeight","handleContentLayout","useDynamicSnapPoints","TransparentBackdrop","Boolean","undefined"],"sources":["BottomSheetNative.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useRef, useState } from 'react';\nimport { Animated, LayoutChangeEvent, useWindowDimensions, ViewStyle } from 'react-native';\nimport { useSafeAreaInsets } from 'react-native-safe-area-context';\nimport {\n BottomSheetBackdrop,\n BottomSheetBackdropProps,\n BottomSheetModal,\n BottomSheetModalProvider,\n BottomSheetView,\n} from '@gorhom/bottom-sheet';\nimport { Column, css, ExtendedStyle, isNotAndroid12, useAnimatedValue } from '@fountain-ui/core';\nimport { useTheme } from '@fountain-ui/styles';\nimport type BottomSheetProps from './BottomSheetProps';\nimport TransparentBackdrop from './TransparentBackdrop';\nimport useDynamicSnapPoints from './useDynamicSnapPoints.native';\n\nconst NoHandle = () => null;\n\nconst DEFAULT_PADDING_BOTTOM = 24;\nconst DEFAULT_PADDING_TOP = 22;\nconst TOP_ELEMENT_HIDDEN_OFFSET = 16;\n\nexport default function BottomSheet(props: BottomSheetProps) {\n const {\n backdropOpacity = 0.5,\n backgroundStyle: backgroundStyleProp,\n borderRadius: borderRadiusProp,\n children,\n enableDynamicSizing = true,\n topElement,\n index,\n maxHeightNormalizedRatio = 0.8,\n onChange,\n snapPoints = [],\n style: styleProp,\n } = props;\n\n const indexRef = useRef<number>(-1);\n const bottomSheetRef = useRef<BottomSheetModal | null>(null);\n\n const { height: windowHeight } = useWindowDimensions();\n const [topElementHeight, setTopElementHeight] = useState(0);\n\n const topElementHeightWithoutOffset = Math.max(0, topElementHeight - TOP_ELEMENT_HIDDEN_OFFSET);\n const maxDynamicContentSize = Math.round(windowHeight * maxHeightNormalizedRatio) - topElementHeightWithoutOffset;\n\n const handleTopElementLayout = (event: LayoutChangeEvent) => {\n const { height } = event.nativeEvent.layout;\n setTopElementHeight(height);\n };\n\n const handleChange = useCallback((newIndex: number) => {\n indexRef.current = newIndex;\n\n if (onChange) {\n onChange(newIndex);\n }\n }, [onChange]);\n\n const handleDismiss = useCallback(() => {\n handleChange(-1);\n }, [handleChange]);\n\n useEffect(() => {\n if (index === indexRef.current) {\n return;\n }\n\n if (indexRef.current < 0 && index >= 0) {\n bottomSheetRef.current?.present();\n } else if (indexRef.current >= 0 && index < 0) {\n bottomSheetRef.current?.dismiss();\n } else {\n // @ts-ignore\n bottomSheetRef.current?.snapToIndex(index);\n }\n }, [index]);\n\n const theme = useTheme();\n\n const borderRadius = borderRadiusProp ?? theme.shape.radius.xxl;\n const backgroundStyle = css([\n {\n backgroundColor: theme.palette.surface.base,\n borderTopLeftRadius: borderRadius,\n borderTopRightRadius: borderRadius,\n },\n backgroundStyleProp,\n ]);\n\n const { bottom: bottomSafeInset } = useSafeAreaInsets();\n\n const contentWrapperStyle: ViewStyle = css([\n {\n backgroundColor: theme.palette.surface.base,\n borderTopLeftRadius: borderRadius,\n borderTopRightRadius: borderRadius,\n flexShrink: 1,\n maxHeight: maxDynamicContentSize,\n minHeight: 325,\n overflow: 'hidden',\n paddingBottom: DEFAULT_PADDING_BOTTOM + bottomSafeInset,\n paddingTop: DEFAULT_PADDING_TOP,\n },\n styleProp,\n ]);\n\n const isBackdropTransparent = backdropOpacity <= 0;\n\n const OpacityAwareBackdrop = (props: BottomSheetBackdropProps) => (\n <BottomSheetBackdrop\n {...props}\n appearsOnIndex={0}\n disappearsOnIndex={-1}\n opacity={backdropOpacity}\n pressBehavior={onChange ? 'close' : 'none'}\n />\n );\n\n const topElementOpacity = useAnimatedValue(0);\n const topElementAnimationStyle: Animated.WithAnimatedValue<ExtendedStyle> = { opacity: topElementOpacity };\n const topElementLocationStyle: ExtendedStyle = {\n position: 'absolute',\n width: '100%',\n bottom: 0,\n };\n const onAnimate = (fromIndex: number, toIndex: number) => {\n const isVisible = toIndex > -1;\n\n Animated.timing(topElementOpacity, {\n toValue: isVisible ? 1 : 0,\n duration: 0,\n useNativeDriver: isNotAndroid12,\n }).start();\n };\n\n const {\n animatedHandleHeight,\n animatedSnapPoints,\n animatedContentHeight,\n handleContentLayout,\n } = useDynamicSnapPoints(snapPoints);\n\n return (\n <BottomSheetModalProvider>\n <BottomSheetModal\n backdropComponent={isBackdropTransparent ? TransparentBackdrop : OpacityAwareBackdrop}\n // @ts-ignore\n backgroundStyle={backgroundStyle}\n enableOverDrag={false}\n index={index}\n handleComponent={NoHandle}\n onChange={handleChange}\n onDismiss={handleDismiss}\n ref={bottomSheetRef}\n enablePanDownToClose={Boolean(onChange)}\n enableDynamicSizing={enableDynamicSizing}\n maxDynamicContentSize={maxDynamicContentSize}\n detached={Boolean(topElement)}\n onAnimate={topElement ? onAnimate : undefined}\n snapPoints={animatedSnapPoints}\n handleHeight={animatedHandleHeight}\n contentHeight={animatedContentHeight}\n >\n {topElement ? (\n <Animated.View style={topElementAnimationStyle}>\n <Column\n onLayout={handleTopElementLayout}\n style={topElementLocationStyle}\n >\n {topElement}\n </Column>\n </Animated.View>\n ) : null}\n\n <BottomSheetView\n onLayout={handleContentLayout}\n style={contentWrapperStyle}\n >\n {children}\n </BottomSheetView>\n </BottomSheetModal>\n </BottomSheetModalProvider>\n );\n};\n"],"mappings":"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"}
|
|
@@ -45,12 +45,13 @@ const useStyles = function () {
|
|
|
45
45
|
},
|
|
46
46
|
topElementLocation: {
|
|
47
47
|
position: 'absolute',
|
|
48
|
-
bottom: 0,
|
|
49
48
|
width: '100%'
|
|
50
49
|
}
|
|
51
50
|
};
|
|
52
51
|
};
|
|
53
52
|
|
|
53
|
+
const TOP_ELEMENT_HIDDEN_OFFSET = 16;
|
|
54
|
+
|
|
54
55
|
function BottomSheet(props) {
|
|
55
56
|
const {
|
|
56
57
|
backdropOpacity,
|
|
@@ -69,7 +70,8 @@ function BottomSheet(props) {
|
|
|
69
70
|
height: windowHeight
|
|
70
71
|
} = (0, _reactNative.useWindowDimensions)();
|
|
71
72
|
const [topElementHeight, setTopElementHeight] = (0, _react.useState)(0);
|
|
72
|
-
const
|
|
73
|
+
const topElementHeightWithoutOffset = Math.max(0, topElementHeight - TOP_ELEMENT_HIDDEN_OFFSET);
|
|
74
|
+
const maxDynamicContentSize = Math.round(windowHeight * maxHeightNormalizedRatio) - topElementHeightWithoutOffset;
|
|
73
75
|
|
|
74
76
|
const handleTopElementLayout = event => {
|
|
75
77
|
const {
|
|
@@ -84,6 +86,7 @@ function BottomSheet(props) {
|
|
|
84
86
|
}
|
|
85
87
|
};
|
|
86
88
|
|
|
89
|
+
const filteredSnapPoints = snapPoints.filter(point => point !== 'CONTENT_HEIGHT');
|
|
87
90
|
const {
|
|
88
91
|
convertedSnapPoints,
|
|
89
92
|
handleLayout,
|
|
@@ -91,14 +94,14 @@ function BottomSheet(props) {
|
|
|
91
94
|
} = (0, _useDynamicSnapPoints.default)({
|
|
92
95
|
enableDynamicSizing,
|
|
93
96
|
maxDynamicContentSize,
|
|
94
|
-
snapPoints
|
|
97
|
+
snapPoints: filteredSnapPoints
|
|
95
98
|
});
|
|
96
|
-
const translateY = highestSnapPoint - (convertedSnapPoints[index] ?? 0);
|
|
99
|
+
const translateY = convertedSnapPoints.length > 0 ? highestSnapPoint - (convertedSnapPoints[index] ?? 0) : 0;
|
|
97
100
|
const contentStyles = (0, _core.css)([styles.paper, { ...(borderRadius ? {
|
|
98
101
|
borderTopLeftRadius: borderRadius,
|
|
99
102
|
borderTopRightRadius: borderRadius
|
|
100
103
|
} : {}),
|
|
101
|
-
...(highestSnapPoint !== maxDynamicContentSize ? {
|
|
104
|
+
...(!enableDynamicSizing && highestSnapPoint !== maxDynamicContentSize ? {
|
|
102
105
|
height: highestSnapPoint
|
|
103
106
|
} : {}),
|
|
104
107
|
maxHeight: maxDynamicContentSize
|
|
@@ -112,7 +115,9 @@ function BottomSheet(props) {
|
|
|
112
115
|
translateY: translateY
|
|
113
116
|
}, topElement ? /*#__PURE__*/_react.default.createElement(_core.Column, {
|
|
114
117
|
onLayout: handleTopElementLayout,
|
|
115
|
-
style: styles.topElementLocation
|
|
118
|
+
style: [styles.topElementLocation, {
|
|
119
|
+
top: -topElementHeight
|
|
120
|
+
}]
|
|
116
121
|
}, topElement) : null, /*#__PURE__*/_react.default.createElement(_reactNative.View, {
|
|
117
122
|
onLayout: handleLayout,
|
|
118
123
|
style: contentStyles
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["useStyles","theme","useTheme","root","justifyContent","zIndex","dialog","animated","alignSelf","maxWidth","width","paper","backgroundColor","palette","surface","base","borderTopLeftRadius","shape","radius","xxl","borderTopRightRadius","flexGrow","minHeight","overflow","paddingBottom","spacing","paddingTop","topElementLocation","position","
|
|
1
|
+
{"version":3,"names":["useStyles","theme","useTheme","root","justifyContent","zIndex","dialog","animated","alignSelf","maxWidth","width","paper","backgroundColor","palette","surface","base","borderTopLeftRadius","shape","radius","xxl","borderTopRightRadius","flexGrow","minHeight","overflow","paddingBottom","spacing","paddingTop","topElementLocation","position","TOP_ELEMENT_HIDDEN_OFFSET","BottomSheet","props","backdropOpacity","borderRadius","children","enableDynamicSizing","topElement","index","maxHeightNormalizedRatio","onChange","snapPoints","style","styleProp","styles","height","windowHeight","useWindowDimensions","topElementHeight","setTopElementHeight","useState","topElementHeightWithoutOffset","Math","max","maxDynamicContentSize","round","handleTopElementLayout","event","nativeEvent","layout","handleClose","filteredSnapPoints","filter","point","convertedSnapPoints","handleLayout","highestSnapPoint","useDynamicSnapPoints","translateY","length","contentStyles","css","maxHeight","StyleSheet","absoluteFill","top"],"sources":["BottomSheetWeb.tsx"],"sourcesContent":["import React, { useState } from 'react';\nimport { LayoutChangeEvent, useWindowDimensions, View } from 'react-native';\nimport { Column, css, Modal, StyleSheet, useTheme } from '@fountain-ui/core';\nimport { NamedStylesStringUnion, UseStyles } from '@fountain-ui/styles';\nimport AnimatedY from '../AnimatedY';\nimport type BottomSheetProps from './BottomSheetProps';\nimport useDynamicSnapPoints from './useDynamicSnapPoints';\n\ntype BottomSheetStyles = NamedStylesStringUnion<'root' | 'animated' | 'paper' | 'topElementLocation'>;\n\nconst useStyles: UseStyles<BottomSheetStyles> = function (): BottomSheetStyles {\n const theme = useTheme();\n\n return {\n root: {\n justifyContent: 'flex-end',\n zIndex: theme.zIndex.dialog,\n },\n animated: {\n alignSelf: 'center',\n maxWidth: 720,\n width: '100%',\n },\n paper: {\n backgroundColor: theme.palette.surface.base,\n borderTopLeftRadius: theme.shape.radius.xxl,\n borderTopRightRadius: theme.shape.radius.xxl,\n flexGrow: 1,\n minHeight: 325,\n overflow: 'hidden',\n paddingBottom: theme.spacing(6),\n paddingTop: theme.spacing(5.5),\n },\n topElementLocation: {\n position: 'absolute',\n width: '100%',\n },\n };\n};\n\nconst TOP_ELEMENT_HIDDEN_OFFSET = 16;\n\nexport default function BottomSheet(props: BottomSheetProps) {\n const {\n backdropOpacity,\n borderRadius,\n children,\n enableDynamicSizing = true,\n topElement,\n index,\n maxHeightNormalizedRatio = 0.8,\n onChange,\n snapPoints = [],\n style: styleProp,\n } = props;\n\n const styles = useStyles();\n\n const { height: windowHeight } = useWindowDimensions();\n\n const [topElementHeight, setTopElementHeight] = useState(0);\n\n const topElementHeightWithoutOffset = Math.max(0, topElementHeight - TOP_ELEMENT_HIDDEN_OFFSET);\n const maxDynamicContentSize = Math.round(windowHeight * maxHeightNormalizedRatio) - topElementHeightWithoutOffset;\n\n const handleTopElementLayout = (event: LayoutChangeEvent) => {\n const { height } = event.nativeEvent.layout;\n setTopElementHeight(height);\n };\n\n const handleClose = () => {\n if (onChange) {\n onChange(-1);\n }\n };\n\n const filteredSnapPoints = snapPoints.filter(point => point !== 'CONTENT_HEIGHT');\n\n const {\n convertedSnapPoints,\n handleLayout,\n highestSnapPoint,\n } = useDynamicSnapPoints({\n enableDynamicSizing,\n maxDynamicContentSize,\n snapPoints: filteredSnapPoints,\n });\n\n const translateY = convertedSnapPoints.length > 0\n ? highestSnapPoint - (convertedSnapPoints[index] ?? 0)\n : 0;\n\n const contentStyles = css([\n styles.paper,\n {\n ...(borderRadius ? { borderTopLeftRadius: borderRadius, borderTopRightRadius: borderRadius } : {}),\n ...(!enableDynamicSizing && highestSnapPoint !== maxDynamicContentSize ? { height: highestSnapPoint } : {}),\n maxHeight: maxDynamicContentSize,\n },\n styleProp,\n ]);\n\n return (\n <Modal\n backdropOpacity={backdropOpacity}\n onClose={handleClose}\n visible={index >= 0}\n style={css([StyleSheet.absoluteFill, styles.root])}\n >\n <AnimatedY translateY={translateY}>\n {topElement ? (\n <Column\n onLayout={handleTopElementLayout}\n style={[styles.topElementLocation, { top: -topElementHeight }]}\n >\n {topElement}\n </Column>\n ) : null}\n\n <View\n onLayout={handleLayout}\n style={contentStyles}\n >\n {children}\n </View>\n </AnimatedY>\n </Modal>\n );\n};\n"],"mappings":"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"}
|
|
@@ -42,7 +42,6 @@ function useDynamicSnapPoints(params) {
|
|
|
42
42
|
height: windowHeight
|
|
43
43
|
} = (0, _reactNative.useWindowDimensions)();
|
|
44
44
|
const [contentHeight, setContentHeight] = (0, _react.useState)(INITIAL_CONTAINER_HEIGHT);
|
|
45
|
-
const hasMeasureRef = (0, _react.useRef)(false);
|
|
46
45
|
const convertedSnapPoints = (0, _react.useMemo)(() => {
|
|
47
46
|
if (contentHeight === INITIAL_CONTAINER_HEIGHT) {
|
|
48
47
|
return [];
|
|
@@ -60,15 +59,10 @@ function useDynamicSnapPoints(params) {
|
|
|
60
59
|
}, [contentHeight, enableDynamicSizing, maxDynamicContentSize, snapPoints, windowHeight]);
|
|
61
60
|
const highestSnapPoint = R.last(convertedSnapPoints) ?? maxDynamicContentSize;
|
|
62
61
|
const handleLayout = (0, _react.useCallback)(event => {
|
|
63
|
-
if (hasMeasureRef.current) {
|
|
64
|
-
return;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
hasMeasureRef.current = true;
|
|
68
62
|
const {
|
|
69
63
|
height
|
|
70
64
|
} = event.nativeEvent.layout;
|
|
71
|
-
setContentHeight(height);
|
|
65
|
+
setContentHeight(prev => Math.abs(prev - height) > 1 ? height : prev);
|
|
72
66
|
}, []);
|
|
73
67
|
return {
|
|
74
68
|
convertedSnapPoints,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["INITIAL_CONTAINER_HEIGHT","convertSnapPoint","snapPoint","windowHeight","maxDynamicContentSize","Math","min","percentageRegex","RegExp","test","percentage","parseFloat","isNaN","round","useDynamicSnapPoints","params","enableDynamicSizing","snapPoints","height","useWindowDimensions","contentHeight","setContentHeight","useState","
|
|
1
|
+
{"version":3,"names":["INITIAL_CONTAINER_HEIGHT","convertSnapPoint","snapPoint","windowHeight","maxDynamicContentSize","Math","min","percentageRegex","RegExp","test","percentage","parseFloat","isNaN","round","useDynamicSnapPoints","params","enableDynamicSizing","snapPoints","height","useWindowDimensions","contentHeight","setContentHeight","useState","convertedSnapPoints","useMemo","map","push","Array","from","Set","sort","a","b","highestSnapPoint","R","last","handleLayout","useCallback","event","nativeEvent","layout","prev","abs"],"sources":["useDynamicSnapPoints.ts"],"sourcesContent":["import { useCallback, useMemo, useState } from 'react';\nimport { LayoutChangeEvent, useWindowDimensions } from 'react-native';\nimport * as R from 'ramda';\n\nconst INITIAL_CONTAINER_HEIGHT = -999;\n\ninterface UseDynamicSnapPointsParams {\n enableDynamicSizing: boolean;\n maxDynamicContentSize: number;\n snapPoints: (number | string)[];\n}\n\ninterface UseDynamicSnapPointsReturns {\n convertedSnapPoints: number[];\n handleLayout: (e: LayoutChangeEvent) => void;\n highestSnapPoint: number;\n}\n\nconst convertSnapPoint = (snapPoint: number | string, windowHeight: number, maxDynamicContentSize: number): number => {\n if (typeof snapPoint === 'number') {\n return Math.min(maxDynamicContentSize, snapPoint);\n }\n\n const percentageRegex = new RegExp(/^[0-9]+%$/);\n if (percentageRegex.test(snapPoint)) {\n const percentage = parseFloat(snapPoint) / 100;\n return isNaN(percentage) ? 0 : Math.min(maxDynamicContentSize, Math.round(windowHeight * percentage));\n }\n\n return 0;\n};\n\nexport default function useDynamicSnapPoints(params: UseDynamicSnapPointsParams): UseDynamicSnapPointsReturns {\n const {\n enableDynamicSizing,\n maxDynamicContentSize,\n snapPoints,\n } = params;\n\n const { height: windowHeight } = useWindowDimensions();\n\n const [contentHeight, setContentHeight] = useState<number>(INITIAL_CONTAINER_HEIGHT);\n\n const convertedSnapPoints = useMemo(() => {\n if (contentHeight === INITIAL_CONTAINER_HEIGHT) {\n return [];\n }\n\n const convertedSnapPoints = snapPoints.map((snapPoint) => {\n return convertSnapPoint(snapPoint, windowHeight, maxDynamicContentSize);\n });\n\n if (enableDynamicSizing && contentHeight !== 0) {\n convertedSnapPoints.push(\n convertSnapPoint(contentHeight, windowHeight, maxDynamicContentSize),\n );\n }\n\n return Array.from(new Set(convertedSnapPoints)).sort((a, b) => a - b);\n }, [\n contentHeight,\n enableDynamicSizing,\n maxDynamicContentSize,\n snapPoints,\n windowHeight,\n ]);\n\n const highestSnapPoint = R.last(convertedSnapPoints) ?? maxDynamicContentSize;\n\n const handleLayout = useCallback((event: LayoutChangeEvent) => {\n const { height } = event.nativeEvent.layout;\n setContentHeight(prev => (Math.abs(prev - height) > 1 ? height : prev));\n }, []);\n\n return {\n convertedSnapPoints,\n handleLayout,\n highestSnapPoint,\n };\n}\n"],"mappings":";;;;;;;AAAA;;AACA;;AACA;;;;;;AAEA,MAAMA,wBAAwB,GAAG,CAAC,GAAlC;;AAcA,MAAMC,gBAAgB,GAAG,CAACC,SAAD,EAA6BC,YAA7B,EAAmDC,qBAAnD,KAA6F;EAClH,IAAI,OAAOF,SAAP,KAAqB,QAAzB,EAAmC;IAC/B,OAAOG,IAAI,CAACC,GAAL,CAASF,qBAAT,EAAgCF,SAAhC,CAAP;EACH;;EAED,MAAMK,eAAe,GAAG,IAAIC,MAAJ,CAAW,WAAX,CAAxB;;EACA,IAAID,eAAe,CAACE,IAAhB,CAAqBP,SAArB,CAAJ,EAAqC;IACjC,MAAMQ,UAAU,GAAGC,UAAU,CAACT,SAAD,CAAV,GAAwB,GAA3C;IACA,OAAOU,KAAK,CAACF,UAAD,CAAL,GAAoB,CAApB,GAAwBL,IAAI,CAACC,GAAL,CAASF,qBAAT,EAAgCC,IAAI,CAACQ,KAAL,CAAWV,YAAY,GAAGO,UAA1B,CAAhC,CAA/B;EACH;;EAED,OAAO,CAAP;AACH,CAZD;;AAce,SAASI,oBAAT,CAA8BC,MAA9B,EAA+F;EAC1G,MAAM;IACFC,mBADE;IAEFZ,qBAFE;IAGFa;EAHE,IAIFF,MAJJ;EAMA,MAAM;IAAEG,MAAM,EAAEf;EAAV,IAA2B,IAAAgB,gCAAA,GAAjC;EAEA,MAAM,CAACC,aAAD,EAAgBC,gBAAhB,IAAoC,IAAAC,eAAA,EAAiBtB,wBAAjB,CAA1C;EAEA,MAAMuB,mBAAmB,GAAG,IAAAC,cAAA,EAAQ,MAAM;IACtC,IAAIJ,aAAa,KAAKpB,wBAAtB,EAAgD;MAC5C,OAAO,EAAP;IACH;;IAED,MAAMuB,mBAAmB,GAAGN,UAAU,CAACQ,GAAX,CAAgBvB,SAAD,IAAe;MACtD,OAAOD,gBAAgB,CAACC,SAAD,EAAYC,YAAZ,EAA0BC,qBAA1B,CAAvB;IACH,CAF2B,CAA5B;;IAIA,IAAIY,mBAAmB,IAAII,aAAa,KAAK,CAA7C,EAAgD;MAC5CG,mBAAmB,CAACG,IAApB,CACIzB,gBAAgB,CAACmB,aAAD,EAAgBjB,YAAhB,EAA8BC,qBAA9B,CADpB;IAGH;;IAED,OAAOuB,KAAK,CAACC,IAAN,CAAW,IAAIC,GAAJ,CAAQN,mBAAR,CAAX,EAAyCO,IAAzC,CAA8C,CAACC,CAAD,EAAIC,CAAJ,KAAUD,CAAC,GAAGC,CAA5D,CAAP;EACH,CAhB2B,EAgBzB,CACCZ,aADD,EAECJ,mBAFD,EAGCZ,qBAHD,EAICa,UAJD,EAKCd,YALD,CAhByB,CAA5B;EAwBA,MAAM8B,gBAAgB,GAAGC,CAAC,CAACC,IAAF,CAAOZ,mBAAP,KAA+BnB,qBAAxD;EAEA,MAAMgC,YAAY,GAAG,IAAAC,kBAAA,EAAaC,KAAD,IAA8B;IAC3D,MAAM;MAAEpB;IAAF,IAAaoB,KAAK,CAACC,WAAN,CAAkBC,MAArC;IACAnB,gBAAgB,CAACoB,IAAI,IAAKpC,IAAI,CAACqC,GAAL,CAASD,IAAI,GAAGvB,MAAhB,IAA0B,CAA1B,GAA8BA,MAA9B,GAAuCuB,IAAjD,CAAhB;EACH,CAHoB,EAGlB,EAHkB,CAArB;EAKA,OAAO;IACHlB,mBADG;IAEHa,YAFG;IAGHH;EAHG,CAAP;AAKH"}
|
|
@@ -13,6 +13,7 @@ const NoHandle = () => null;
|
|
|
13
13
|
|
|
14
14
|
const DEFAULT_PADDING_BOTTOM = 24;
|
|
15
15
|
const DEFAULT_PADDING_TOP = 22;
|
|
16
|
+
const TOP_ELEMENT_HIDDEN_OFFSET = 16;
|
|
16
17
|
export default function BottomSheet(props) {
|
|
17
18
|
const {
|
|
18
19
|
backdropOpacity = 0.5,
|
|
@@ -33,7 +34,8 @@ export default function BottomSheet(props) {
|
|
|
33
34
|
height: windowHeight
|
|
34
35
|
} = useWindowDimensions();
|
|
35
36
|
const [topElementHeight, setTopElementHeight] = useState(0);
|
|
36
|
-
const
|
|
37
|
+
const topElementHeightWithoutOffset = Math.max(0, topElementHeight - TOP_ELEMENT_HIDDEN_OFFSET);
|
|
38
|
+
const maxDynamicContentSize = Math.round(windowHeight * maxHeightNormalizedRatio) - topElementHeightWithoutOffset;
|
|
37
39
|
|
|
38
40
|
const handleTopElementLayout = event => {
|
|
39
41
|
const {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["React","useCallback","useEffect","useRef","useState","Animated","useWindowDimensions","useSafeAreaInsets","BottomSheetBackdrop","BottomSheetModal","BottomSheetModalProvider","BottomSheetView","Column","css","isNotAndroid12","useAnimatedValue","useTheme","TransparentBackdrop","useDynamicSnapPoints","NoHandle","DEFAULT_PADDING_BOTTOM","DEFAULT_PADDING_TOP","BottomSheet","props","backdropOpacity","backgroundStyle","backgroundStyleProp","borderRadius","borderRadiusProp","children","enableDynamicSizing","topElement","index","maxHeightNormalizedRatio","onChange","snapPoints","style","styleProp","indexRef","bottomSheetRef","height","windowHeight","topElementHeight","setTopElementHeight","maxDynamicContentSize","Math","round","handleTopElementLayout","event","nativeEvent","layout","handleChange","newIndex","current","handleDismiss","present","dismiss","snapToIndex","theme","shape","radius","xxl","backgroundColor","palette","surface","base","borderTopLeftRadius","borderTopRightRadius","bottom","bottomSafeInset","contentWrapperStyle","flexShrink","maxHeight","minHeight","overflow","paddingBottom","paddingTop","isBackdropTransparent","OpacityAwareBackdrop","topElementOpacity","topElementAnimationStyle","opacity","topElementLocationStyle","position","width","onAnimate","fromIndex","toIndex","isVisible","timing","toValue","duration","useNativeDriver","start","animatedHandleHeight","animatedSnapPoints","animatedContentHeight","handleContentLayout","Boolean","undefined"],"sources":["BottomSheetNative.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useRef, useState } from 'react';\nimport { Animated, LayoutChangeEvent, useWindowDimensions, ViewStyle } from 'react-native';\nimport { useSafeAreaInsets } from 'react-native-safe-area-context';\nimport {\n BottomSheetBackdrop,\n BottomSheetBackdropProps,\n BottomSheetModal,\n BottomSheetModalProvider,\n BottomSheetView,\n} from '@gorhom/bottom-sheet';\nimport { Column, css, ExtendedStyle, isNotAndroid12, useAnimatedValue } from '@fountain-ui/core';\nimport { useTheme } from '@fountain-ui/styles';\nimport type BottomSheetProps from './BottomSheetProps';\nimport TransparentBackdrop from './TransparentBackdrop';\nimport useDynamicSnapPoints from './useDynamicSnapPoints.native';\n\nconst NoHandle = () => null;\n\nconst DEFAULT_PADDING_BOTTOM = 24;\nconst DEFAULT_PADDING_TOP = 22;\n\nexport default function BottomSheet(props: BottomSheetProps) {\n const {\n backdropOpacity = 0.5,\n backgroundStyle: backgroundStyleProp,\n borderRadius: borderRadiusProp,\n children,\n enableDynamicSizing = true,\n topElement,\n index,\n maxHeightNormalizedRatio = 0.8,\n onChange,\n snapPoints = [],\n style: styleProp,\n } = props;\n\n const indexRef = useRef<number>(-1);\n const bottomSheetRef = useRef<BottomSheetModal | null>(null);\n\n const { height: windowHeight } = useWindowDimensions();\n const [topElementHeight, setTopElementHeight] = useState(0);\n\n const maxDynamicContentSize = Math.round(windowHeight * maxHeightNormalizedRatio) - topElementHeight;\n\n const handleTopElementLayout = (event: LayoutChangeEvent) => {\n const { height } = event.nativeEvent.layout;\n setTopElementHeight(height);\n };\n\n const handleChange = useCallback((newIndex: number) => {\n indexRef.current = newIndex;\n\n if (onChange) {\n onChange(newIndex);\n }\n }, [onChange]);\n\n const handleDismiss = useCallback(() => {\n handleChange(-1);\n }, [handleChange]);\n\n useEffect(() => {\n if (index === indexRef.current) {\n return;\n }\n\n if (indexRef.current < 0 && index >= 0) {\n bottomSheetRef.current?.present();\n } else if (indexRef.current >= 0 && index < 0) {\n bottomSheetRef.current?.dismiss();\n } else {\n // @ts-ignore\n bottomSheetRef.current?.snapToIndex(index);\n }\n }, [index]);\n\n const theme = useTheme();\n\n const borderRadius = borderRadiusProp ?? theme.shape.radius.xxl;\n const backgroundStyle = css([\n {\n backgroundColor: theme.palette.surface.base,\n borderTopLeftRadius: borderRadius,\n borderTopRightRadius: borderRadius,\n },\n backgroundStyleProp,\n ]);\n\n const { bottom: bottomSafeInset } = useSafeAreaInsets();\n\n const contentWrapperStyle: ViewStyle = css([\n {\n backgroundColor: theme.palette.surface.base,\n borderTopLeftRadius: borderRadius,\n borderTopRightRadius: borderRadius,\n flexShrink: 1,\n maxHeight: maxDynamicContentSize,\n minHeight: 325,\n overflow: 'hidden',\n paddingBottom: DEFAULT_PADDING_BOTTOM + bottomSafeInset,\n paddingTop: DEFAULT_PADDING_TOP,\n },\n styleProp,\n ]);\n\n const isBackdropTransparent = backdropOpacity <= 0;\n\n const OpacityAwareBackdrop = (props: BottomSheetBackdropProps) => (\n <BottomSheetBackdrop\n {...props}\n appearsOnIndex={0}\n disappearsOnIndex={-1}\n opacity={backdropOpacity}\n pressBehavior={onChange ? 'close' : 'none'}\n />\n );\n\n const topElementOpacity = useAnimatedValue(0);\n const topElementAnimationStyle: Animated.WithAnimatedValue<ExtendedStyle> = { opacity: topElementOpacity };\n const topElementLocationStyle: ExtendedStyle = {\n position: 'absolute',\n width: '100%',\n bottom: 0,\n };\n const onAnimate = (fromIndex: number, toIndex: number) => {\n const isVisible = toIndex > -1;\n\n Animated.timing(topElementOpacity, {\n toValue: isVisible ? 1 : 0,\n duration: 0,\n useNativeDriver: isNotAndroid12,\n }).start();\n };\n\n const {\n animatedHandleHeight,\n animatedSnapPoints,\n animatedContentHeight,\n handleContentLayout,\n } = useDynamicSnapPoints(snapPoints);\n\n return (\n <BottomSheetModalProvider>\n <BottomSheetModal\n backdropComponent={isBackdropTransparent ? TransparentBackdrop : OpacityAwareBackdrop}\n // @ts-ignore\n backgroundStyle={backgroundStyle}\n enableOverDrag={false}\n index={index}\n handleComponent={NoHandle}\n onChange={handleChange}\n onDismiss={handleDismiss}\n ref={bottomSheetRef}\n enablePanDownToClose={Boolean(onChange)}\n enableDynamicSizing={enableDynamicSizing}\n maxDynamicContentSize={maxDynamicContentSize}\n detached={Boolean(topElement)}\n onAnimate={topElement ? onAnimate : undefined}\n snapPoints={animatedSnapPoints}\n handleHeight={animatedHandleHeight}\n contentHeight={animatedContentHeight}\n >\n {topElement ? (\n <Animated.View style={topElementAnimationStyle}>\n <Column\n onLayout={handleTopElementLayout}\n style={topElementLocationStyle}\n >\n {topElement}\n </Column>\n </Animated.View>\n ) : null}\n\n <BottomSheetView\n onLayout={handleContentLayout}\n style={contentWrapperStyle}\n >\n {children}\n </BottomSheetView>\n </BottomSheetModal>\n </BottomSheetModalProvider>\n );\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"names":["React","useCallback","useEffect","useRef","useState","Animated","useWindowDimensions","useSafeAreaInsets","BottomSheetBackdrop","BottomSheetModal","BottomSheetModalProvider","BottomSheetView","Column","css","isNotAndroid12","useAnimatedValue","useTheme","TransparentBackdrop","useDynamicSnapPoints","NoHandle","DEFAULT_PADDING_BOTTOM","DEFAULT_PADDING_TOP","TOP_ELEMENT_HIDDEN_OFFSET","BottomSheet","props","backdropOpacity","backgroundStyle","backgroundStyleProp","borderRadius","borderRadiusProp","children","enableDynamicSizing","topElement","index","maxHeightNormalizedRatio","onChange","snapPoints","style","styleProp","indexRef","bottomSheetRef","height","windowHeight","topElementHeight","setTopElementHeight","topElementHeightWithoutOffset","Math","max","maxDynamicContentSize","round","handleTopElementLayout","event","nativeEvent","layout","handleChange","newIndex","current","handleDismiss","present","dismiss","snapToIndex","theme","shape","radius","xxl","backgroundColor","palette","surface","base","borderTopLeftRadius","borderTopRightRadius","bottom","bottomSafeInset","contentWrapperStyle","flexShrink","maxHeight","minHeight","overflow","paddingBottom","paddingTop","isBackdropTransparent","OpacityAwareBackdrop","topElementOpacity","topElementAnimationStyle","opacity","topElementLocationStyle","position","width","onAnimate","fromIndex","toIndex","isVisible","timing","toValue","duration","useNativeDriver","start","animatedHandleHeight","animatedSnapPoints","animatedContentHeight","handleContentLayout","Boolean","undefined"],"sources":["BottomSheetNative.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useRef, useState } from 'react';\nimport { Animated, LayoutChangeEvent, useWindowDimensions, ViewStyle } from 'react-native';\nimport { useSafeAreaInsets } from 'react-native-safe-area-context';\nimport {\n BottomSheetBackdrop,\n BottomSheetBackdropProps,\n BottomSheetModal,\n BottomSheetModalProvider,\n BottomSheetView,\n} from '@gorhom/bottom-sheet';\nimport { Column, css, ExtendedStyle, isNotAndroid12, useAnimatedValue } from '@fountain-ui/core';\nimport { useTheme } from '@fountain-ui/styles';\nimport type BottomSheetProps from './BottomSheetProps';\nimport TransparentBackdrop from './TransparentBackdrop';\nimport useDynamicSnapPoints from './useDynamicSnapPoints.native';\n\nconst NoHandle = () => null;\n\nconst DEFAULT_PADDING_BOTTOM = 24;\nconst DEFAULT_PADDING_TOP = 22;\nconst TOP_ELEMENT_HIDDEN_OFFSET = 16;\n\nexport default function BottomSheet(props: BottomSheetProps) {\n const {\n backdropOpacity = 0.5,\n backgroundStyle: backgroundStyleProp,\n borderRadius: borderRadiusProp,\n children,\n enableDynamicSizing = true,\n topElement,\n index,\n maxHeightNormalizedRatio = 0.8,\n onChange,\n snapPoints = [],\n style: styleProp,\n } = props;\n\n const indexRef = useRef<number>(-1);\n const bottomSheetRef = useRef<BottomSheetModal | null>(null);\n\n const { height: windowHeight } = useWindowDimensions();\n const [topElementHeight, setTopElementHeight] = useState(0);\n\n const topElementHeightWithoutOffset = Math.max(0, topElementHeight - TOP_ELEMENT_HIDDEN_OFFSET);\n const maxDynamicContentSize = Math.round(windowHeight * maxHeightNormalizedRatio) - topElementHeightWithoutOffset;\n\n const handleTopElementLayout = (event: LayoutChangeEvent) => {\n const { height } = event.nativeEvent.layout;\n setTopElementHeight(height);\n };\n\n const handleChange = useCallback((newIndex: number) => {\n indexRef.current = newIndex;\n\n if (onChange) {\n onChange(newIndex);\n }\n }, [onChange]);\n\n const handleDismiss = useCallback(() => {\n handleChange(-1);\n }, [handleChange]);\n\n useEffect(() => {\n if (index === indexRef.current) {\n return;\n }\n\n if (indexRef.current < 0 && index >= 0) {\n bottomSheetRef.current?.present();\n } else if (indexRef.current >= 0 && index < 0) {\n bottomSheetRef.current?.dismiss();\n } else {\n // @ts-ignore\n bottomSheetRef.current?.snapToIndex(index);\n }\n }, [index]);\n\n const theme = useTheme();\n\n const borderRadius = borderRadiusProp ?? theme.shape.radius.xxl;\n const backgroundStyle = css([\n {\n backgroundColor: theme.palette.surface.base,\n borderTopLeftRadius: borderRadius,\n borderTopRightRadius: borderRadius,\n },\n backgroundStyleProp,\n ]);\n\n const { bottom: bottomSafeInset } = useSafeAreaInsets();\n\n const contentWrapperStyle: ViewStyle = css([\n {\n backgroundColor: theme.palette.surface.base,\n borderTopLeftRadius: borderRadius,\n borderTopRightRadius: borderRadius,\n flexShrink: 1,\n maxHeight: maxDynamicContentSize,\n minHeight: 325,\n overflow: 'hidden',\n paddingBottom: DEFAULT_PADDING_BOTTOM + bottomSafeInset,\n paddingTop: DEFAULT_PADDING_TOP,\n },\n styleProp,\n ]);\n\n const isBackdropTransparent = backdropOpacity <= 0;\n\n const OpacityAwareBackdrop = (props: BottomSheetBackdropProps) => (\n <BottomSheetBackdrop\n {...props}\n appearsOnIndex={0}\n disappearsOnIndex={-1}\n opacity={backdropOpacity}\n pressBehavior={onChange ? 'close' : 'none'}\n />\n );\n\n const topElementOpacity = useAnimatedValue(0);\n const topElementAnimationStyle: Animated.WithAnimatedValue<ExtendedStyle> = { opacity: topElementOpacity };\n const topElementLocationStyle: ExtendedStyle = {\n position: 'absolute',\n width: '100%',\n bottom: 0,\n };\n const onAnimate = (fromIndex: number, toIndex: number) => {\n const isVisible = toIndex > -1;\n\n Animated.timing(topElementOpacity, {\n toValue: isVisible ? 1 : 0,\n duration: 0,\n useNativeDriver: isNotAndroid12,\n }).start();\n };\n\n const {\n animatedHandleHeight,\n animatedSnapPoints,\n animatedContentHeight,\n handleContentLayout,\n } = useDynamicSnapPoints(snapPoints);\n\n return (\n <BottomSheetModalProvider>\n <BottomSheetModal\n backdropComponent={isBackdropTransparent ? TransparentBackdrop : OpacityAwareBackdrop}\n // @ts-ignore\n backgroundStyle={backgroundStyle}\n enableOverDrag={false}\n index={index}\n handleComponent={NoHandle}\n onChange={handleChange}\n onDismiss={handleDismiss}\n ref={bottomSheetRef}\n enablePanDownToClose={Boolean(onChange)}\n enableDynamicSizing={enableDynamicSizing}\n maxDynamicContentSize={maxDynamicContentSize}\n detached={Boolean(topElement)}\n onAnimate={topElement ? onAnimate : undefined}\n snapPoints={animatedSnapPoints}\n handleHeight={animatedHandleHeight}\n contentHeight={animatedContentHeight}\n >\n {topElement ? (\n <Animated.View style={topElementAnimationStyle}>\n <Column\n onLayout={handleTopElementLayout}\n style={topElementLocationStyle}\n >\n {topElement}\n </Column>\n </Animated.View>\n ) : null}\n\n <BottomSheetView\n onLayout={handleContentLayout}\n style={contentWrapperStyle}\n >\n {children}\n </BottomSheetView>\n </BottomSheetModal>\n </BottomSheetModalProvider>\n );\n};\n"],"mappings":"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"}
|
|
@@ -28,12 +28,12 @@ const useStyles = function () {
|
|
|
28
28
|
},
|
|
29
29
|
topElementLocation: {
|
|
30
30
|
position: 'absolute',
|
|
31
|
-
bottom: 0,
|
|
32
31
|
width: '100%'
|
|
33
32
|
}
|
|
34
33
|
};
|
|
35
34
|
};
|
|
36
35
|
|
|
36
|
+
const TOP_ELEMENT_HIDDEN_OFFSET = 16;
|
|
37
37
|
export default function BottomSheet(props) {
|
|
38
38
|
const {
|
|
39
39
|
backdropOpacity,
|
|
@@ -52,7 +52,8 @@ export default function BottomSheet(props) {
|
|
|
52
52
|
height: windowHeight
|
|
53
53
|
} = useWindowDimensions();
|
|
54
54
|
const [topElementHeight, setTopElementHeight] = useState(0);
|
|
55
|
-
const
|
|
55
|
+
const topElementHeightWithoutOffset = Math.max(0, topElementHeight - TOP_ELEMENT_HIDDEN_OFFSET);
|
|
56
|
+
const maxDynamicContentSize = Math.round(windowHeight * maxHeightNormalizedRatio) - topElementHeightWithoutOffset;
|
|
56
57
|
|
|
57
58
|
const handleTopElementLayout = event => {
|
|
58
59
|
const {
|
|
@@ -67,6 +68,7 @@ export default function BottomSheet(props) {
|
|
|
67
68
|
}
|
|
68
69
|
};
|
|
69
70
|
|
|
71
|
+
const filteredSnapPoints = snapPoints.filter(point => point !== 'CONTENT_HEIGHT');
|
|
70
72
|
const {
|
|
71
73
|
convertedSnapPoints,
|
|
72
74
|
handleLayout,
|
|
@@ -74,14 +76,14 @@ export default function BottomSheet(props) {
|
|
|
74
76
|
} = useDynamicSnapPoints({
|
|
75
77
|
enableDynamicSizing,
|
|
76
78
|
maxDynamicContentSize,
|
|
77
|
-
snapPoints
|
|
79
|
+
snapPoints: filteredSnapPoints
|
|
78
80
|
});
|
|
79
|
-
const translateY = highestSnapPoint - (convertedSnapPoints[index] ?? 0);
|
|
81
|
+
const translateY = convertedSnapPoints.length > 0 ? highestSnapPoint - (convertedSnapPoints[index] ?? 0) : 0;
|
|
80
82
|
const contentStyles = css([styles.paper, { ...(borderRadius ? {
|
|
81
83
|
borderTopLeftRadius: borderRadius,
|
|
82
84
|
borderTopRightRadius: borderRadius
|
|
83
85
|
} : {}),
|
|
84
|
-
...(highestSnapPoint !== maxDynamicContentSize ? {
|
|
86
|
+
...(!enableDynamicSizing && highestSnapPoint !== maxDynamicContentSize ? {
|
|
85
87
|
height: highestSnapPoint
|
|
86
88
|
} : {}),
|
|
87
89
|
maxHeight: maxDynamicContentSize
|
|
@@ -95,7 +97,9 @@ export default function BottomSheet(props) {
|
|
|
95
97
|
translateY: translateY
|
|
96
98
|
}, topElement ? /*#__PURE__*/React.createElement(Column, {
|
|
97
99
|
onLayout: handleTopElementLayout,
|
|
98
|
-
style: styles.topElementLocation
|
|
100
|
+
style: [styles.topElementLocation, {
|
|
101
|
+
top: -topElementHeight
|
|
102
|
+
}]
|
|
99
103
|
}, topElement) : null, /*#__PURE__*/React.createElement(View, {
|
|
100
104
|
onLayout: handleLayout,
|
|
101
105
|
style: contentStyles
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["React","useState","useWindowDimensions","View","Column","css","Modal","StyleSheet","useTheme","AnimatedY","useDynamicSnapPoints","useStyles","theme","root","justifyContent","zIndex","dialog","animated","alignSelf","maxWidth","width","paper","backgroundColor","palette","surface","base","borderTopLeftRadius","shape","radius","xxl","borderTopRightRadius","flexGrow","minHeight","overflow","paddingBottom","spacing","paddingTop","topElementLocation","position","
|
|
1
|
+
{"version":3,"names":["React","useState","useWindowDimensions","View","Column","css","Modal","StyleSheet","useTheme","AnimatedY","useDynamicSnapPoints","useStyles","theme","root","justifyContent","zIndex","dialog","animated","alignSelf","maxWidth","width","paper","backgroundColor","palette","surface","base","borderTopLeftRadius","shape","radius","xxl","borderTopRightRadius","flexGrow","minHeight","overflow","paddingBottom","spacing","paddingTop","topElementLocation","position","TOP_ELEMENT_HIDDEN_OFFSET","BottomSheet","props","backdropOpacity","borderRadius","children","enableDynamicSizing","topElement","index","maxHeightNormalizedRatio","onChange","snapPoints","style","styleProp","styles","height","windowHeight","topElementHeight","setTopElementHeight","topElementHeightWithoutOffset","Math","max","maxDynamicContentSize","round","handleTopElementLayout","event","nativeEvent","layout","handleClose","filteredSnapPoints","filter","point","convertedSnapPoints","handleLayout","highestSnapPoint","translateY","length","contentStyles","maxHeight","absoluteFill","top"],"sources":["BottomSheetWeb.tsx"],"sourcesContent":["import React, { useState } from 'react';\nimport { LayoutChangeEvent, useWindowDimensions, View } from 'react-native';\nimport { Column, css, Modal, StyleSheet, useTheme } from '@fountain-ui/core';\nimport { NamedStylesStringUnion, UseStyles } from '@fountain-ui/styles';\nimport AnimatedY from '../AnimatedY';\nimport type BottomSheetProps from './BottomSheetProps';\nimport useDynamicSnapPoints from './useDynamicSnapPoints';\n\ntype BottomSheetStyles = NamedStylesStringUnion<'root' | 'animated' | 'paper' | 'topElementLocation'>;\n\nconst useStyles: UseStyles<BottomSheetStyles> = function (): BottomSheetStyles {\n const theme = useTheme();\n\n return {\n root: {\n justifyContent: 'flex-end',\n zIndex: theme.zIndex.dialog,\n },\n animated: {\n alignSelf: 'center',\n maxWidth: 720,\n width: '100%',\n },\n paper: {\n backgroundColor: theme.palette.surface.base,\n borderTopLeftRadius: theme.shape.radius.xxl,\n borderTopRightRadius: theme.shape.radius.xxl,\n flexGrow: 1,\n minHeight: 325,\n overflow: 'hidden',\n paddingBottom: theme.spacing(6),\n paddingTop: theme.spacing(5.5),\n },\n topElementLocation: {\n position: 'absolute',\n width: '100%',\n },\n };\n};\n\nconst TOP_ELEMENT_HIDDEN_OFFSET = 16;\n\nexport default function BottomSheet(props: BottomSheetProps) {\n const {\n backdropOpacity,\n borderRadius,\n children,\n enableDynamicSizing = true,\n topElement,\n index,\n maxHeightNormalizedRatio = 0.8,\n onChange,\n snapPoints = [],\n style: styleProp,\n } = props;\n\n const styles = useStyles();\n\n const { height: windowHeight } = useWindowDimensions();\n\n const [topElementHeight, setTopElementHeight] = useState(0);\n\n const topElementHeightWithoutOffset = Math.max(0, topElementHeight - TOP_ELEMENT_HIDDEN_OFFSET);\n const maxDynamicContentSize = Math.round(windowHeight * maxHeightNormalizedRatio) - topElementHeightWithoutOffset;\n\n const handleTopElementLayout = (event: LayoutChangeEvent) => {\n const { height } = event.nativeEvent.layout;\n setTopElementHeight(height);\n };\n\n const handleClose = () => {\n if (onChange) {\n onChange(-1);\n }\n };\n\n const filteredSnapPoints = snapPoints.filter(point => point !== 'CONTENT_HEIGHT');\n\n const {\n convertedSnapPoints,\n handleLayout,\n highestSnapPoint,\n } = useDynamicSnapPoints({\n enableDynamicSizing,\n maxDynamicContentSize,\n snapPoints: filteredSnapPoints,\n });\n\n const translateY = convertedSnapPoints.length > 0\n ? highestSnapPoint - (convertedSnapPoints[index] ?? 0)\n : 0;\n\n const contentStyles = css([\n styles.paper,\n {\n ...(borderRadius ? { borderTopLeftRadius: borderRadius, borderTopRightRadius: borderRadius } : {}),\n ...(!enableDynamicSizing && highestSnapPoint !== maxDynamicContentSize ? { height: highestSnapPoint } : {}),\n maxHeight: maxDynamicContentSize,\n },\n styleProp,\n ]);\n\n return (\n <Modal\n backdropOpacity={backdropOpacity}\n onClose={handleClose}\n visible={index >= 0}\n style={css([StyleSheet.absoluteFill, styles.root])}\n >\n <AnimatedY translateY={translateY}>\n {topElement ? (\n <Column\n onLayout={handleTopElementLayout}\n style={[styles.topElementLocation, { top: -topElementHeight }]}\n >\n {topElement}\n </Column>\n ) : null}\n\n <View\n onLayout={handleLayout}\n style={contentStyles}\n >\n {children}\n </View>\n </AnimatedY>\n </Modal>\n );\n};\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useCallback, useMemo,
|
|
1
|
+
import { useCallback, useMemo, useState } from 'react';
|
|
2
2
|
import { useWindowDimensions } from 'react-native';
|
|
3
3
|
import * as R from 'ramda';
|
|
4
4
|
const INITIAL_CONTAINER_HEIGHT = -999;
|
|
@@ -28,7 +28,6 @@ export default function useDynamicSnapPoints(params) {
|
|
|
28
28
|
height: windowHeight
|
|
29
29
|
} = useWindowDimensions();
|
|
30
30
|
const [contentHeight, setContentHeight] = useState(INITIAL_CONTAINER_HEIGHT);
|
|
31
|
-
const hasMeasureRef = useRef(false);
|
|
32
31
|
const convertedSnapPoints = useMemo(() => {
|
|
33
32
|
if (contentHeight === INITIAL_CONTAINER_HEIGHT) {
|
|
34
33
|
return [];
|
|
@@ -46,15 +45,10 @@ export default function useDynamicSnapPoints(params) {
|
|
|
46
45
|
}, [contentHeight, enableDynamicSizing, maxDynamicContentSize, snapPoints, windowHeight]);
|
|
47
46
|
const highestSnapPoint = R.last(convertedSnapPoints) ?? maxDynamicContentSize;
|
|
48
47
|
const handleLayout = useCallback(event => {
|
|
49
|
-
if (hasMeasureRef.current) {
|
|
50
|
-
return;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
hasMeasureRef.current = true;
|
|
54
48
|
const {
|
|
55
49
|
height
|
|
56
50
|
} = event.nativeEvent.layout;
|
|
57
|
-
setContentHeight(height);
|
|
51
|
+
setContentHeight(prev => Math.abs(prev - height) > 1 ? height : prev);
|
|
58
52
|
}, []);
|
|
59
53
|
return {
|
|
60
54
|
convertedSnapPoints,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["useCallback","useMemo","
|
|
1
|
+
{"version":3,"names":["useCallback","useMemo","useState","useWindowDimensions","R","INITIAL_CONTAINER_HEIGHT","convertSnapPoint","snapPoint","windowHeight","maxDynamicContentSize","Math","min","percentageRegex","RegExp","test","percentage","parseFloat","isNaN","round","useDynamicSnapPoints","params","enableDynamicSizing","snapPoints","height","contentHeight","setContentHeight","convertedSnapPoints","map","push","Array","from","Set","sort","a","b","highestSnapPoint","last","handleLayout","event","nativeEvent","layout","prev","abs"],"sources":["useDynamicSnapPoints.ts"],"sourcesContent":["import { useCallback, useMemo, useState } from 'react';\nimport { LayoutChangeEvent, useWindowDimensions } from 'react-native';\nimport * as R from 'ramda';\n\nconst INITIAL_CONTAINER_HEIGHT = -999;\n\ninterface UseDynamicSnapPointsParams {\n enableDynamicSizing: boolean;\n maxDynamicContentSize: number;\n snapPoints: (number | string)[];\n}\n\ninterface UseDynamicSnapPointsReturns {\n convertedSnapPoints: number[];\n handleLayout: (e: LayoutChangeEvent) => void;\n highestSnapPoint: number;\n}\n\nconst convertSnapPoint = (snapPoint: number | string, windowHeight: number, maxDynamicContentSize: number): number => {\n if (typeof snapPoint === 'number') {\n return Math.min(maxDynamicContentSize, snapPoint);\n }\n\n const percentageRegex = new RegExp(/^[0-9]+%$/);\n if (percentageRegex.test(snapPoint)) {\n const percentage = parseFloat(snapPoint) / 100;\n return isNaN(percentage) ? 0 : Math.min(maxDynamicContentSize, Math.round(windowHeight * percentage));\n }\n\n return 0;\n};\n\nexport default function useDynamicSnapPoints(params: UseDynamicSnapPointsParams): UseDynamicSnapPointsReturns {\n const {\n enableDynamicSizing,\n maxDynamicContentSize,\n snapPoints,\n } = params;\n\n const { height: windowHeight } = useWindowDimensions();\n\n const [contentHeight, setContentHeight] = useState<number>(INITIAL_CONTAINER_HEIGHT);\n\n const convertedSnapPoints = useMemo(() => {\n if (contentHeight === INITIAL_CONTAINER_HEIGHT) {\n return [];\n }\n\n const convertedSnapPoints = snapPoints.map((snapPoint) => {\n return convertSnapPoint(snapPoint, windowHeight, maxDynamicContentSize);\n });\n\n if (enableDynamicSizing && contentHeight !== 0) {\n convertedSnapPoints.push(\n convertSnapPoint(contentHeight, windowHeight, maxDynamicContentSize),\n );\n }\n\n return Array.from(new Set(convertedSnapPoints)).sort((a, b) => a - b);\n }, [\n contentHeight,\n enableDynamicSizing,\n maxDynamicContentSize,\n snapPoints,\n windowHeight,\n ]);\n\n const highestSnapPoint = R.last(convertedSnapPoints) ?? maxDynamicContentSize;\n\n const handleLayout = useCallback((event: LayoutChangeEvent) => {\n const { height } = event.nativeEvent.layout;\n setContentHeight(prev => (Math.abs(prev - height) > 1 ? height : prev));\n }, []);\n\n return {\n convertedSnapPoints,\n handleLayout,\n highestSnapPoint,\n };\n}\n"],"mappings":"AAAA,SAASA,WAAT,EAAsBC,OAAtB,EAA+BC,QAA/B,QAA+C,OAA/C;AACA,SAA4BC,mBAA5B,QAAuD,cAAvD;AACA,OAAO,KAAKC,CAAZ,MAAmB,OAAnB;AAEA,MAAMC,wBAAwB,GAAG,CAAC,GAAlC;;AAcA,MAAMC,gBAAgB,GAAG,CAACC,SAAD,EAA6BC,YAA7B,EAAmDC,qBAAnD,KAA6F;EAClH,IAAI,OAAOF,SAAP,KAAqB,QAAzB,EAAmC;IAC/B,OAAOG,IAAI,CAACC,GAAL,CAASF,qBAAT,EAAgCF,SAAhC,CAAP;EACH;;EAED,MAAMK,eAAe,GAAG,IAAIC,MAAJ,CAAW,WAAX,CAAxB;;EACA,IAAID,eAAe,CAACE,IAAhB,CAAqBP,SAArB,CAAJ,EAAqC;IACjC,MAAMQ,UAAU,GAAGC,UAAU,CAACT,SAAD,CAAV,GAAwB,GAA3C;IACA,OAAOU,KAAK,CAACF,UAAD,CAAL,GAAoB,CAApB,GAAwBL,IAAI,CAACC,GAAL,CAASF,qBAAT,EAAgCC,IAAI,CAACQ,KAAL,CAAWV,YAAY,GAAGO,UAA1B,CAAhC,CAA/B;EACH;;EAED,OAAO,CAAP;AACH,CAZD;;AAcA,eAAe,SAASI,oBAAT,CAA8BC,MAA9B,EAA+F;EAC1G,MAAM;IACFC,mBADE;IAEFZ,qBAFE;IAGFa;EAHE,IAIFF,MAJJ;EAMA,MAAM;IAAEG,MAAM,EAAEf;EAAV,IAA2BL,mBAAmB,EAApD;EAEA,MAAM,CAACqB,aAAD,EAAgBC,gBAAhB,IAAoCvB,QAAQ,CAASG,wBAAT,CAAlD;EAEA,MAAMqB,mBAAmB,GAAGzB,OAAO,CAAC,MAAM;IACtC,IAAIuB,aAAa,KAAKnB,wBAAtB,EAAgD;MAC5C,OAAO,EAAP;IACH;;IAED,MAAMqB,mBAAmB,GAAGJ,UAAU,CAACK,GAAX,CAAgBpB,SAAD,IAAe;MACtD,OAAOD,gBAAgB,CAACC,SAAD,EAAYC,YAAZ,EAA0BC,qBAA1B,CAAvB;IACH,CAF2B,CAA5B;;IAIA,IAAIY,mBAAmB,IAAIG,aAAa,KAAK,CAA7C,EAAgD;MAC5CE,mBAAmB,CAACE,IAApB,CACItB,gBAAgB,CAACkB,aAAD,EAAgBhB,YAAhB,EAA8BC,qBAA9B,CADpB;IAGH;;IAED,OAAOoB,KAAK,CAACC,IAAN,CAAW,IAAIC,GAAJ,CAAQL,mBAAR,CAAX,EAAyCM,IAAzC,CAA8C,CAACC,CAAD,EAAIC,CAAJ,KAAUD,CAAC,GAAGC,CAA5D,CAAP;EACH,CAhBkC,EAgBhC,CACCV,aADD,EAECH,mBAFD,EAGCZ,qBAHD,EAICa,UAJD,EAKCd,YALD,CAhBgC,CAAnC;EAwBA,MAAM2B,gBAAgB,GAAG/B,CAAC,CAACgC,IAAF,CAAOV,mBAAP,KAA+BjB,qBAAxD;EAEA,MAAM4B,YAAY,GAAGrC,WAAW,CAAEsC,KAAD,IAA8B;IAC3D,MAAM;MAAEf;IAAF,IAAae,KAAK,CAACC,WAAN,CAAkBC,MAArC;IACAf,gBAAgB,CAACgB,IAAI,IAAK/B,IAAI,CAACgC,GAAL,CAASD,IAAI,GAAGlB,MAAhB,IAA0B,CAA1B,GAA8BA,MAA9B,GAAuCkB,IAAjD,CAAhB;EACH,CAH+B,EAG7B,EAH6B,CAAhC;EAKA,OAAO;IACHf,mBADG;IAEHW,YAFG;IAGHF;EAHG,CAAP;AAKH"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fountain-ui/lab",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.20",
|
|
4
4
|
"private": false,
|
|
5
5
|
"author": "Fountain-UI Team",
|
|
6
6
|
"description": "Incubator for Fountain-UI React components.",
|
|
@@ -71,5 +71,5 @@
|
|
|
71
71
|
"publishConfig": {
|
|
72
72
|
"access": "public"
|
|
73
73
|
},
|
|
74
|
-
"gitHead": "
|
|
74
|
+
"gitHead": "1791de45a37a8f9c9810cfaaa3b84908ba0bda83"
|
|
75
75
|
}
|
|
@@ -18,6 +18,7 @@ const NoHandle = () => null;
|
|
|
18
18
|
|
|
19
19
|
const DEFAULT_PADDING_BOTTOM = 24;
|
|
20
20
|
const DEFAULT_PADDING_TOP = 22;
|
|
21
|
+
const TOP_ELEMENT_HIDDEN_OFFSET = 16;
|
|
21
22
|
|
|
22
23
|
export default function BottomSheet(props: BottomSheetProps) {
|
|
23
24
|
const {
|
|
@@ -40,7 +41,8 @@ export default function BottomSheet(props: BottomSheetProps) {
|
|
|
40
41
|
const { height: windowHeight } = useWindowDimensions();
|
|
41
42
|
const [topElementHeight, setTopElementHeight] = useState(0);
|
|
42
43
|
|
|
43
|
-
const
|
|
44
|
+
const topElementHeightWithoutOffset = Math.max(0, topElementHeight - TOP_ELEMENT_HIDDEN_OFFSET);
|
|
45
|
+
const maxDynamicContentSize = Math.round(windowHeight * maxHeightNormalizedRatio) - topElementHeightWithoutOffset;
|
|
44
46
|
|
|
45
47
|
const handleTopElementLayout = (event: LayoutChangeEvent) => {
|
|
46
48
|
const { height } = event.nativeEvent.layout;
|
|
@@ -33,12 +33,13 @@ const useStyles: UseStyles<BottomSheetStyles> = function (): BottomSheetStyles {
|
|
|
33
33
|
},
|
|
34
34
|
topElementLocation: {
|
|
35
35
|
position: 'absolute',
|
|
36
|
-
bottom: 0,
|
|
37
36
|
width: '100%',
|
|
38
37
|
},
|
|
39
38
|
};
|
|
40
39
|
};
|
|
41
40
|
|
|
41
|
+
const TOP_ELEMENT_HIDDEN_OFFSET = 16;
|
|
42
|
+
|
|
42
43
|
export default function BottomSheet(props: BottomSheetProps) {
|
|
43
44
|
const {
|
|
44
45
|
backdropOpacity,
|
|
@@ -59,7 +60,8 @@ export default function BottomSheet(props: BottomSheetProps) {
|
|
|
59
60
|
|
|
60
61
|
const [topElementHeight, setTopElementHeight] = useState(0);
|
|
61
62
|
|
|
62
|
-
const
|
|
63
|
+
const topElementHeightWithoutOffset = Math.max(0, topElementHeight - TOP_ELEMENT_HIDDEN_OFFSET);
|
|
64
|
+
const maxDynamicContentSize = Math.round(windowHeight * maxHeightNormalizedRatio) - topElementHeightWithoutOffset;
|
|
63
65
|
|
|
64
66
|
const handleTopElementLayout = (event: LayoutChangeEvent) => {
|
|
65
67
|
const { height } = event.nativeEvent.layout;
|
|
@@ -72,6 +74,8 @@ export default function BottomSheet(props: BottomSheetProps) {
|
|
|
72
74
|
}
|
|
73
75
|
};
|
|
74
76
|
|
|
77
|
+
const filteredSnapPoints = snapPoints.filter(point => point !== 'CONTENT_HEIGHT');
|
|
78
|
+
|
|
75
79
|
const {
|
|
76
80
|
convertedSnapPoints,
|
|
77
81
|
handleLayout,
|
|
@@ -79,16 +83,18 @@ export default function BottomSheet(props: BottomSheetProps) {
|
|
|
79
83
|
} = useDynamicSnapPoints({
|
|
80
84
|
enableDynamicSizing,
|
|
81
85
|
maxDynamicContentSize,
|
|
82
|
-
snapPoints,
|
|
86
|
+
snapPoints: filteredSnapPoints,
|
|
83
87
|
});
|
|
84
88
|
|
|
85
|
-
const translateY =
|
|
89
|
+
const translateY = convertedSnapPoints.length > 0
|
|
90
|
+
? highestSnapPoint - (convertedSnapPoints[index] ?? 0)
|
|
91
|
+
: 0;
|
|
86
92
|
|
|
87
93
|
const contentStyles = css([
|
|
88
94
|
styles.paper,
|
|
89
95
|
{
|
|
90
96
|
...(borderRadius ? { borderTopLeftRadius: borderRadius, borderTopRightRadius: borderRadius } : {}),
|
|
91
|
-
...(highestSnapPoint !== maxDynamicContentSize ? { height: highestSnapPoint } : {}),
|
|
97
|
+
...(!enableDynamicSizing && highestSnapPoint !== maxDynamicContentSize ? { height: highestSnapPoint } : {}),
|
|
92
98
|
maxHeight: maxDynamicContentSize,
|
|
93
99
|
},
|
|
94
100
|
styleProp,
|
|
@@ -105,7 +111,7 @@ export default function BottomSheet(props: BottomSheetProps) {
|
|
|
105
111
|
{topElement ? (
|
|
106
112
|
<Column
|
|
107
113
|
onLayout={handleTopElementLayout}
|
|
108
|
-
style={styles.topElementLocation}
|
|
114
|
+
style={[styles.topElementLocation, { top: -topElementHeight }]}
|
|
109
115
|
>
|
|
110
116
|
{topElement}
|
|
111
117
|
</Column>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useCallback, useMemo,
|
|
1
|
+
import { useCallback, useMemo, useState } from 'react';
|
|
2
2
|
import { LayoutChangeEvent, useWindowDimensions } from 'react-native';
|
|
3
3
|
import * as R from 'ramda';
|
|
4
4
|
|
|
@@ -41,8 +41,6 @@ export default function useDynamicSnapPoints(params: UseDynamicSnapPointsParams)
|
|
|
41
41
|
|
|
42
42
|
const [contentHeight, setContentHeight] = useState<number>(INITIAL_CONTAINER_HEIGHT);
|
|
43
43
|
|
|
44
|
-
const hasMeasureRef = useRef<boolean>(false);
|
|
45
|
-
|
|
46
44
|
const convertedSnapPoints = useMemo(() => {
|
|
47
45
|
if (contentHeight === INITIAL_CONTAINER_HEIGHT) {
|
|
48
46
|
return [];
|
|
@@ -70,13 +68,8 @@ export default function useDynamicSnapPoints(params: UseDynamicSnapPointsParams)
|
|
|
70
68
|
const highestSnapPoint = R.last(convertedSnapPoints) ?? maxDynamicContentSize;
|
|
71
69
|
|
|
72
70
|
const handleLayout = useCallback((event: LayoutChangeEvent) => {
|
|
73
|
-
if (hasMeasureRef.current) {
|
|
74
|
-
return;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
hasMeasureRef.current = true;
|
|
78
71
|
const { height } = event.nativeEvent.layout;
|
|
79
|
-
setContentHeight(height);
|
|
72
|
+
setContentHeight(prev => (Math.abs(prev - height) > 1 ? height : prev));
|
|
80
73
|
}, []);
|
|
81
74
|
|
|
82
75
|
return {
|