@fountain-ui/lab 2.0.0-beta.82 → 2.0.0-beta.84
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 +71 -17
- package/build/commonjs/BottomSheet/BottomSheetNative.js.map +1 -1
- package/build/commonjs/BottomSheet/BottomSheetProps.js.map +1 -1
- package/build/commonjs/BottomSheet/BottomSheetWeb.js +81 -12
- package/build/commonjs/BottomSheet/BottomSheetWeb.js.map +1 -1
- package/build/module/BottomSheet/BottomSheetNative.js +67 -17
- package/build/module/BottomSheet/BottomSheetNative.js.map +1 -1
- package/build/module/BottomSheet/BottomSheetProps.js.map +1 -1
- package/build/module/BottomSheet/BottomSheetWeb.js +79 -14
- package/build/module/BottomSheet/BottomSheetWeb.js.map +1 -1
- package/build/typescript/BottomSheet/BottomSheetProps.d.ts +13 -10
- package/package.json +2 -2
- package/src/BottomSheet/BottomSheetNative.tsx +82 -20
- package/src/BottomSheet/BottomSheetProps.ts +16 -12
- package/src/BottomSheet/BottomSheetWeb.tsx +95 -14
|
@@ -9,12 +9,12 @@ var _react = _interopRequireDefault(require("react"));
|
|
|
9
9
|
|
|
10
10
|
var _reactNative = require("react-native");
|
|
11
11
|
|
|
12
|
+
var _bottomSheet = require("@gorhom/bottom-sheet");
|
|
13
|
+
|
|
12
14
|
var _core = require("@fountain-ui/core");
|
|
13
15
|
|
|
14
16
|
var _styles = require("@fountain-ui/styles");
|
|
15
17
|
|
|
16
|
-
var _bottomSheet = require("@gorhom/bottom-sheet");
|
|
17
|
-
|
|
18
18
|
var _TransparentBackdrop = _interopRequireDefault(require("./TransparentBackdrop"));
|
|
19
19
|
|
|
20
20
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
@@ -23,19 +23,29 @@ function _extends() { _extends = Object.assign ? Object.assign.bind() : function
|
|
|
23
23
|
|
|
24
24
|
const NoHandle = () => null;
|
|
25
25
|
|
|
26
|
+
const createHeightLayoutHandler = setHeight => {
|
|
27
|
+
return event => {
|
|
28
|
+
const {
|
|
29
|
+
height
|
|
30
|
+
} = event.nativeEvent.layout;
|
|
31
|
+
setHeight(height);
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
|
|
26
35
|
function BottomSheet(props) {
|
|
27
36
|
const {
|
|
28
37
|
backdropOpacity = 0.5,
|
|
38
|
+
borderRadius: borderRadiusProp,
|
|
29
39
|
children,
|
|
30
40
|
enableDynamicSizing = true,
|
|
31
41
|
header,
|
|
42
|
+
stickyBottomElement,
|
|
32
43
|
topElement,
|
|
33
44
|
index,
|
|
34
45
|
maxHeightNormalizedRatio = 0.9,
|
|
35
46
|
onChange,
|
|
36
47
|
snapPoints = [],
|
|
37
|
-
|
|
38
|
-
disableDefaultShadow = false
|
|
48
|
+
enableScrollableHeaderBorder = false
|
|
39
49
|
} = props;
|
|
40
50
|
|
|
41
51
|
const indexRef = _react.default.useRef(-1);
|
|
@@ -45,7 +55,16 @@ function BottomSheet(props) {
|
|
|
45
55
|
const {
|
|
46
56
|
height: windowHeight
|
|
47
57
|
} = (0, _reactNative.useWindowDimensions)();
|
|
48
|
-
|
|
58
|
+
|
|
59
|
+
const [isScrollable, setIsScrollable] = _react.default.useState(false);
|
|
60
|
+
|
|
61
|
+
const [topElementHeight, setTopElementHeight] = _react.default.useState(0);
|
|
62
|
+
|
|
63
|
+
const [stickyBottomElementHeight, setStickyBottomElementHeight] = _react.default.useState(0);
|
|
64
|
+
|
|
65
|
+
const maxDynamicContentSize = Math.round(windowHeight * maxHeightNormalizedRatio) - topElementHeight;
|
|
66
|
+
const handleTopElementLayout = createHeightLayoutHandler(setTopElementHeight);
|
|
67
|
+
const handleStickyBottomElementLayout = createHeightLayoutHandler(setStickyBottomElementHeight);
|
|
49
68
|
|
|
50
69
|
const handleChange = _react.default.useCallback(newIndex => {
|
|
51
70
|
indexRef.current = newIndex;
|
|
@@ -82,25 +101,27 @@ function BottomSheet(props) {
|
|
|
82
101
|
|
|
83
102
|
const theme = (0, _styles.useTheme)();
|
|
84
103
|
const shadow = theme.shadow[12];
|
|
104
|
+
const borderRadius = borderRadiusProp ?? theme.shape.roundnessExtra;
|
|
85
105
|
const modalStyle = {
|
|
86
106
|
backgroundColor: '#ffffff00',
|
|
87
|
-
borderTopLeftRadius:
|
|
88
|
-
borderTopRightRadius:
|
|
89
|
-
...
|
|
107
|
+
borderTopLeftRadius: borderRadius,
|
|
108
|
+
borderTopRightRadius: borderRadius,
|
|
109
|
+
..._reactNative.Platform.select({
|
|
90
110
|
android: shadow === null || shadow === void 0 ? void 0 : shadow.elevation,
|
|
91
111
|
ios: shadow === null || shadow === void 0 ? void 0 : shadow.shadow,
|
|
92
112
|
web: shadow === null || shadow === void 0 ? void 0 : shadow.boxShadow
|
|
93
|
-
})
|
|
113
|
+
})
|
|
94
114
|
};
|
|
115
|
+
const backgroundColor = theme.palette.paper.default;
|
|
95
116
|
const backgroundStyle = {
|
|
96
|
-
backgroundColor
|
|
97
|
-
borderTopLeftRadius:
|
|
98
|
-
borderTopRightRadius:
|
|
117
|
+
backgroundColor,
|
|
118
|
+
borderTopLeftRadius: borderRadius,
|
|
119
|
+
borderTopRightRadius: borderRadius
|
|
99
120
|
};
|
|
100
121
|
const contentWrapperStyle = {
|
|
101
122
|
flex: 1,
|
|
102
|
-
borderTopLeftRadius:
|
|
103
|
-
borderTopRightRadius:
|
|
123
|
+
borderTopLeftRadius: borderRadius,
|
|
124
|
+
borderTopRightRadius: borderRadius,
|
|
104
125
|
overflow: 'hidden'
|
|
105
126
|
};
|
|
106
127
|
const isBackdropTransparent = backdropOpacity <= 0;
|
|
@@ -132,6 +153,32 @@ function BottomSheet(props) {
|
|
|
132
153
|
}).start();
|
|
133
154
|
};
|
|
134
155
|
|
|
156
|
+
const handleContentSizeChange = (_, contentHeight) => {
|
|
157
|
+
setIsScrollable(contentHeight > maxDynamicContentSize);
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
const headerStyle = {
|
|
161
|
+
backgroundColor,
|
|
162
|
+
...(isScrollable && enableScrollableHeaderBorder ? {
|
|
163
|
+
borderBottomWidth: 0.5,
|
|
164
|
+
borderBottomColor: theme.palette.divider
|
|
165
|
+
} : {})
|
|
166
|
+
};
|
|
167
|
+
const childrenStyle = {
|
|
168
|
+
backgroundColor,
|
|
169
|
+
paddingBottom: stickyBottomElementHeight
|
|
170
|
+
};
|
|
171
|
+
const stickyBottomElementShadow = (0, _core.useElevationStyle)(8);
|
|
172
|
+
const stickyBottomElementStyle = {
|
|
173
|
+
backgroundColor: theme.palette.paper.default,
|
|
174
|
+
...(isScrollable ? stickyBottomElementShadow : {})
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
const renderFooter = props => /*#__PURE__*/_react.default.createElement(_bottomSheet.BottomSheetFooter, props, /*#__PURE__*/_react.default.createElement(_reactNative.View, {
|
|
178
|
+
onLayout: handleStickyBottomElementLayout,
|
|
179
|
+
style: stickyBottomElementStyle
|
|
180
|
+
}, stickyBottomElement));
|
|
181
|
+
|
|
135
182
|
return /*#__PURE__*/_react.default.createElement(_bottomSheet.BottomSheetModalProvider, null, /*#__PURE__*/_react.default.createElement(_bottomSheet.BottomSheetModal, {
|
|
136
183
|
backdropComponent: isBackdropTransparent ? _TransparentBackdrop.default : OpacityAwareBackdrop // @ts-ignore
|
|
137
184
|
,
|
|
@@ -147,17 +194,24 @@ function BottomSheet(props) {
|
|
|
147
194
|
enableDynamicSizing: enableDynamicSizing,
|
|
148
195
|
maxDynamicContentSize: maxDynamicContentSize,
|
|
149
196
|
detached: Boolean(topElement),
|
|
150
|
-
onAnimate: topElement ? onAnimate : undefined
|
|
197
|
+
onAnimate: topElement ? onAnimate : undefined,
|
|
198
|
+
footerComponent: stickyBottomElement ? renderFooter : undefined
|
|
151
199
|
}, topElement ? /*#__PURE__*/_react.default.createElement(_reactNative.Animated.View, {
|
|
152
200
|
style: topElementAnimationStyle
|
|
153
201
|
}, /*#__PURE__*/_react.default.createElement(_core.Column, {
|
|
202
|
+
onLayout: handleTopElementLayout,
|
|
154
203
|
style: topElementLocationStyle
|
|
155
204
|
}, topElement)) : null, /*#__PURE__*/_react.default.createElement(_reactNative.View, {
|
|
156
205
|
style: contentWrapperStyle
|
|
157
206
|
}, /*#__PURE__*/_react.default.createElement(_bottomSheet.BottomSheetScrollView, {
|
|
158
207
|
bounces: false,
|
|
159
|
-
stickyHeaderIndices: header ? [0] : undefined
|
|
160
|
-
|
|
208
|
+
stickyHeaderIndices: header ? [0] : undefined,
|
|
209
|
+
onContentSizeChange: handleContentSizeChange
|
|
210
|
+
}, /*#__PURE__*/_react.default.createElement(_reactNative.View, {
|
|
211
|
+
style: headerStyle
|
|
212
|
+
}, header), /*#__PURE__*/_react.default.createElement(_reactNative.View, {
|
|
213
|
+
style: childrenStyle
|
|
214
|
+
}, children)))));
|
|
161
215
|
}
|
|
162
216
|
|
|
163
217
|
;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["NoHandle","BottomSheet","props","backdropOpacity","children","enableDynamicSizing","header","topElement","index","maxHeightNormalizedRatio","onChange","snapPoints","disableDefaultBackgroundColor","disableDefaultShadow","indexRef","React","useRef","bottomSheetRef","height","windowHeight","useWindowDimensions","maxDynamicContentSize","Math","round","handleChange","useCallback","newIndex","current","handleDismiss","useEffect","present","dismiss","snapToIndex","theme","useTheme","shadow","modalStyle","backgroundColor","borderTopLeftRadius","shape","roundnessExtra","borderTopRightRadius","Platform","select","android","elevation","ios","web","boxShadow","backgroundStyle","palette","paper","default","contentWrapperStyle","flex","overflow","isBackdropTransparent","OpacityAwareBackdrop","topElementOpacity","useAnimatedValue","topElementAnimationStyle","opacity","topElementLocationStyle","position","width","bottom","onAnimate","fromIndex","toIndex","isVisible","Animated","timing","toValue","duration","useNativeDriver","isNotAndroid12","start","TransparentBackdrop","Boolean","undefined"],"sources":["BottomSheetNative.tsx"],"sourcesContent":["import React from 'react';\nimport { Animated, Platform, useWindowDimensions, View } from 'react-native';\nimport { Column, useAnimatedValue, ExtendedStyle, isNotAndroid12 } from '@fountain-ui/core';\nimport { useTheme } from '@fountain-ui/styles';\nimport {\n BottomSheetBackdrop,\n BottomSheetBackdropProps,\n BottomSheetModal,\n BottomSheetModalProvider,\n BottomSheetScrollView,\n} from '@gorhom/bottom-sheet';\nimport type BottomSheetProps from './BottomSheetProps';\nimport TransparentBackdrop from './TransparentBackdrop';\n\nconst NoHandle = () => null;\n\nexport default function BottomSheet(props: BottomSheetProps) {\n const {\n backdropOpacity = 0.5,\n children,\n enableDynamicSizing = true,\n header,\n topElement,\n index,\n maxHeightNormalizedRatio = 0.9,\n onChange,\n snapPoints = [],\n disableDefaultBackgroundColor = false,\n disableDefaultShadow = false,\n } = props;\n\n const indexRef = React.useRef<number>(-1);\n const bottomSheetRef = React.useRef<BottomSheetModal | null>(null);\n\n const { height: windowHeight } = useWindowDimensions();\n const maxDynamicContentSize = Math.round(windowHeight * maxHeightNormalizedRatio);\n\n const handleChange = React.useCallback((newIndex: number) => {\n indexRef.current = newIndex;\n\n if (onChange) {\n onChange(newIndex);\n }\n }, [onChange]);\n\n const handleDismiss = React.useCallback(() => {\n handleChange(-1);\n }, [handleChange]);\n\n React.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 const shadow = theme.shadow[12];\n const modalStyle = {\n backgroundColor: '#ffffff00',\n borderTopLeftRadius: theme.shape.roundnessExtra,\n borderTopRightRadius: theme.shape.roundnessExtra,\n ...(disableDefaultShadow ? {} : Platform.select<object>({\n android: shadow?.elevation,\n ios: shadow?.shadow,\n web: shadow?.boxShadow,\n })),\n };\n const backgroundStyle = {\n backgroundColor: disableDefaultBackgroundColor ? '#ffffff00' : theme.palette.paper.default,\n borderTopLeftRadius: theme.shape.roundnessExtra,\n borderTopRightRadius: theme.shape.roundnessExtra,\n };\n const contentWrapperStyle = {\n flex: 1,\n borderTopLeftRadius: theme.shape.roundnessExtra,\n borderTopRightRadius: theme.shape.roundnessExtra,\n overflow: 'hidden',\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 return (\n <BottomSheetModalProvider>\n <BottomSheetModal\n backdropComponent={isBackdropTransparent ? TransparentBackdrop : OpacityAwareBackdrop}\n // @ts-ignore\n backgroundStyle={backgroundStyle}\n index={index}\n handleComponent={NoHandle}\n onChange={handleChange}\n onDismiss={handleDismiss}\n ref={bottomSheetRef}\n snapPoints={snapPoints}\n style={modalStyle}\n enablePanDownToClose={Boolean(onChange)}\n enableDynamicSizing={enableDynamicSizing}\n maxDynamicContentSize={maxDynamicContentSize}\n detached={Boolean(topElement)}\n onAnimate={topElement ? onAnimate : undefined}\n >\n {topElement ? (\n <Animated.View style={topElementAnimationStyle}>\n <Column style={topElementLocationStyle}>\n {topElement}\n </Column>\n </Animated.View>\n ) : null}\n\n {/* @ts-ignore */}\n <View style={contentWrapperStyle}>\n <BottomSheetScrollView\n bounces={false}\n stickyHeaderIndices={header ? [0] : undefined}\n >\n {header}\n\n {children}\n </BottomSheetScrollView>\n </View>\n </BottomSheetModal>\n </BottomSheetModalProvider>\n );\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"names":["NoHandle","createHeightLayoutHandler","setHeight","event","height","nativeEvent","layout","BottomSheet","props","backdropOpacity","borderRadius","borderRadiusProp","children","enableDynamicSizing","header","stickyBottomElement","topElement","index","maxHeightNormalizedRatio","onChange","snapPoints","enableScrollableHeaderBorder","indexRef","React","useRef","bottomSheetRef","windowHeight","useWindowDimensions","isScrollable","setIsScrollable","useState","topElementHeight","setTopElementHeight","stickyBottomElementHeight","setStickyBottomElementHeight","maxDynamicContentSize","Math","round","handleTopElementLayout","handleStickyBottomElementLayout","handleChange","useCallback","newIndex","current","handleDismiss","useEffect","present","dismiss","snapToIndex","theme","useTheme","shadow","shape","roundnessExtra","modalStyle","backgroundColor","borderTopLeftRadius","borderTopRightRadius","Platform","select","android","elevation","ios","web","boxShadow","palette","paper","default","backgroundStyle","contentWrapperStyle","flex","overflow","isBackdropTransparent","OpacityAwareBackdrop","topElementOpacity","useAnimatedValue","topElementAnimationStyle","opacity","topElementLocationStyle","position","width","bottom","onAnimate","fromIndex","toIndex","isVisible","Animated","timing","toValue","duration","useNativeDriver","isNotAndroid12","start","handleContentSizeChange","_","contentHeight","headerStyle","borderBottomWidth","borderBottomColor","divider","childrenStyle","paddingBottom","stickyBottomElementShadow","useElevationStyle","stickyBottomElementStyle","renderFooter","TransparentBackdrop","Boolean","undefined"],"sources":["BottomSheetNative.tsx"],"sourcesContent":["import React from 'react';\nimport { Animated, LayoutChangeEvent, Platform, useWindowDimensions, View, ViewStyle } from 'react-native';\nimport {\n BottomSheetBackdrop,\n BottomSheetBackdropProps,\n BottomSheetFooter,\n BottomSheetFooterProps,\n BottomSheetModal,\n BottomSheetModalProvider,\n BottomSheetScrollView,\n} from '@gorhom/bottom-sheet';\nimport { Column, ExtendedStyle, isNotAndroid12, useAnimatedValue, useElevationStyle } from '@fountain-ui/core';\nimport { useTheme } from '@fountain-ui/styles';\nimport type BottomSheetProps from './BottomSheetProps';\nimport TransparentBackdrop from './TransparentBackdrop';\n\nconst NoHandle = () => null;\n\nconst createHeightLayoutHandler = (setHeight: React.Dispatch<React.SetStateAction<number>>) => {\n return (event: LayoutChangeEvent) => {\n const { height } = event.nativeEvent.layout;\n setHeight(height);\n };\n}\n\nexport default function BottomSheet(props: BottomSheetProps) {\n const {\n backdropOpacity = 0.5,\n borderRadius: borderRadiusProp,\n children,\n enableDynamicSizing = true,\n header,\n stickyBottomElement,\n topElement,\n index,\n maxHeightNormalizedRatio = 0.9,\n onChange,\n snapPoints = [],\n enableScrollableHeaderBorder = false,\n } = props;\n\n const indexRef = React.useRef<number>(-1);\n const bottomSheetRef = React.useRef<BottomSheetModal | null>(null);\n\n const { height: windowHeight } = useWindowDimensions();\n const [isScrollable, setIsScrollable] = React.useState(false);\n const [topElementHeight, setTopElementHeight] = React.useState(0);\n const [stickyBottomElementHeight, setStickyBottomElementHeight] = React.useState(0);\n\n const maxDynamicContentSize = Math.round(windowHeight * maxHeightNormalizedRatio) - topElementHeight;\n\n const handleTopElementLayout = createHeightLayoutHandler(setTopElementHeight);\n const handleStickyBottomElementLayout = createHeightLayoutHandler(setStickyBottomElementHeight);\n\n const handleChange = React.useCallback((newIndex: number) => {\n indexRef.current = newIndex;\n\n if (onChange) {\n onChange(newIndex);\n }\n }, [onChange]);\n\n const handleDismiss = React.useCallback(() => {\n handleChange(-1);\n }, [handleChange]);\n\n React.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 const shadow = theme.shadow[12];\n const borderRadius = borderRadiusProp ?? theme.shape.roundnessExtra;\n const modalStyle = {\n backgroundColor: '#ffffff00',\n borderTopLeftRadius: borderRadius,\n borderTopRightRadius: borderRadius,\n ...Platform.select<object>({\n android: shadow?.elevation,\n ios: shadow?.shadow,\n web: shadow?.boxShadow,\n }),\n };\n const backgroundColor = theme.palette.paper.default;\n const backgroundStyle = {\n backgroundColor,\n borderTopLeftRadius: borderRadius,\n borderTopRightRadius: borderRadius,\n };\n const contentWrapperStyle: ViewStyle = {\n flex: 1,\n borderTopLeftRadius: borderRadius,\n borderTopRightRadius: borderRadius,\n overflow: 'hidden',\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 handleContentSizeChange = (_: number, contentHeight: number) => {\n setIsScrollable(contentHeight > maxDynamicContentSize);\n };\n\n const headerStyle = {\n backgroundColor,\n ...(isScrollable && enableScrollableHeaderBorder ? {\n borderBottomWidth: 0.5,\n borderBottomColor: theme.palette.divider,\n }: {})\n }\n\n const childrenStyle = {\n backgroundColor,\n paddingBottom: stickyBottomElementHeight,\n }\n\n const stickyBottomElementShadow = useElevationStyle(8);\n\n const stickyBottomElementStyle = {\n backgroundColor: theme.palette.paper.default,\n ...(isScrollable ? stickyBottomElementShadow : {}),\n }\n\n const renderFooter = (props: BottomSheetFooterProps) => (\n <BottomSheetFooter {...props}>\n <View\n onLayout={handleStickyBottomElementLayout}\n style={stickyBottomElementStyle}\n >\n {stickyBottomElement}\n </View>\n </BottomSheetFooter>\n );\n\n return (\n <BottomSheetModalProvider>\n <BottomSheetModal\n backdropComponent={isBackdropTransparent ? TransparentBackdrop : OpacityAwareBackdrop}\n // @ts-ignore\n backgroundStyle={backgroundStyle}\n index={index}\n handleComponent={NoHandle}\n onChange={handleChange}\n onDismiss={handleDismiss}\n ref={bottomSheetRef}\n snapPoints={snapPoints}\n style={modalStyle}\n enablePanDownToClose={Boolean(onChange)}\n enableDynamicSizing={enableDynamicSizing}\n maxDynamicContentSize={maxDynamicContentSize}\n detached={Boolean(topElement)}\n onAnimate={topElement ? onAnimate : undefined}\n footerComponent={stickyBottomElement ? renderFooter : undefined}\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 <View style={contentWrapperStyle}>\n <BottomSheetScrollView\n bounces={false}\n stickyHeaderIndices={header ? [0] : undefined}\n onContentSizeChange={handleContentSizeChange}\n >\n <View style={headerStyle}>\n {header}\n </View>\n\n <View style={childrenStyle}>\n {children}\n </View>\n </BottomSheetScrollView>\n </View>\n </BottomSheetModal>\n </BottomSheetModalProvider>\n );\n};\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":[],"sources":["BottomSheetProps.ts"],"sourcesContent":["import React from 'react';\nimport type { ComponentProps } from '@fountain-ui/core';\n\nexport default interface BottomSheetProps extends ComponentProps<{\n /**\n * Opacity for BackdropComponent\n * @default 0.5\n */\n backdropOpacity?: number;\n\n /**\n * BottomSheet children, usually the included sub-components.\n */\n children?: React.ReactNode;\n\n /**\n * Enable dynamic sizing for content size.\n * @default true\n */\n enableDynamicSizing?: boolean;\n\n /**\n * Area to be fixed on the top of the bottom sheet.\n */\n header?: React.ReactNode;\n\n /**\n * Top element for displaying additional information on the bottom sheet.\n */\n topElement?: React.ReactNode;\n\n /**\n * Snap index. You could also provide -1 to bottom sheet in closed state.\n */\n index: number;\n\n /**\n * Maximum height(normalized value) of dialog\n * ex. 30% => 0.3 / 90% => 0.9\n * @default 0.9\n */\n maxHeightNormalizedRatio?: number;\n\n /**\n * Callback fired when the index is changed.\n * Important! Use memoized value.\n */\n onChange?: (newIndex: number) => void;\n\n /**\n * Points for the bottom sheet to snap to, points should be sorted from bottom to top.\n * Important! Use memoized value.\n * Only number type or string type(~% format) can be used.\n * @default []\n */\n snapPoints?: Array<number | string>;\n
|
|
1
|
+
{"version":3,"names":[],"sources":["BottomSheetProps.ts"],"sourcesContent":["import React from 'react';\nimport type { ComponentProps } from '@fountain-ui/core';\n\nexport default interface BottomSheetProps extends ComponentProps<{\n /**\n * Opacity for BackdropComponent\n * @default 0.5\n */\n backdropOpacity?: number;\n\n /**\n * Border radius for bottom sheet\n */\n borderRadius?: number;\n\n /**\n * BottomSheet children, usually the included sub-components.\n */\n children?: React.ReactNode;\n\n /**\n * Enable dynamic sizing for content size.\n * @default true\n */\n enableDynamicSizing?: boolean;\n\n /**\n * Area to be fixed on the top of the bottom sheet.\n */\n header?: React.ReactNode;\n\n /**\n * If set to true, a border will be applied to the header area when the bottom sheet content is scrollable.\n * This visually separates the header from the scrollable content.\n */\n enableScrollableHeaderBorder?: boolean;\n\n /**\n * Area to be fixed on the bottom of the bottom sheet.\n */\n stickyBottomElement?: React.ReactNode;\n\n /**\n * Top element for displaying additional information on the bottom sheet.\n */\n topElement?: React.ReactNode;\n\n /**\n * Snap index. You could also provide -1 to bottom sheet in closed state.\n */\n index: number;\n\n /**\n * Maximum height(normalized value) of dialog\n * ex. 30% => 0.3 / 90% => 0.9\n * @default 0.9\n */\n maxHeightNormalizedRatio?: number;\n\n /**\n * Callback fired when the index is changed.\n * Important! Use memoized value.\n */\n onChange?: (newIndex: number) => void;\n\n /**\n * Points for the bottom sheet to snap to, points should be sorted from bottom to top.\n * Important! Use memoized value.\n * Only number type or string type(~% format) can be used.\n * @default []\n */\n snapPoints?: Array<number | string>;\n}> {}\n"],"mappings":""}
|
|
@@ -5,7 +5,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = BottomSheet;
|
|
7
7
|
|
|
8
|
-
var _react =
|
|
8
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
9
9
|
|
|
10
10
|
var _reactNative = require("react-native");
|
|
11
11
|
|
|
@@ -17,8 +17,22 @@ var _useDynamicSnapPoints = _interopRequireDefault(require("./useDynamicSnapPoin
|
|
|
17
17
|
|
|
18
18
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
19
19
|
|
|
20
|
+
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
21
|
+
|
|
22
|
+
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
23
|
+
|
|
24
|
+
const createHeightLayoutHandler = setHeight => {
|
|
25
|
+
return event => {
|
|
26
|
+
const {
|
|
27
|
+
height
|
|
28
|
+
} = event.nativeEvent.layout;
|
|
29
|
+
setHeight(height);
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
|
|
20
33
|
const useStyles = function () {
|
|
21
34
|
const theme = (0, _core.useTheme)();
|
|
35
|
+
const stickyBottomElementShadow = (0, _core.useElevationStyle)(8);
|
|
22
36
|
return {
|
|
23
37
|
root: {
|
|
24
38
|
justifyContent: 'flex-end',
|
|
@@ -41,25 +55,51 @@ const useStyles = function () {
|
|
|
41
55
|
position: 'absolute',
|
|
42
56
|
bottom: 0,
|
|
43
57
|
width: '100%'
|
|
44
|
-
}
|
|
58
|
+
},
|
|
59
|
+
headerContainer: {
|
|
60
|
+
backgroundColor: theme.palette.paper.default
|
|
61
|
+
},
|
|
62
|
+
headerBorder: {
|
|
63
|
+
borderBottomWidth: 0.5,
|
|
64
|
+
borderBottomColor: theme.palette.divider
|
|
65
|
+
},
|
|
66
|
+
stickyBottomElement: {
|
|
67
|
+
position: 'absolute',
|
|
68
|
+
bottom: 0,
|
|
69
|
+
left: 0,
|
|
70
|
+
right: 0,
|
|
71
|
+
backgroundColor: theme.palette.paper.default
|
|
72
|
+
},
|
|
73
|
+
stickyBottomElementShadow
|
|
45
74
|
};
|
|
46
75
|
};
|
|
47
76
|
|
|
48
77
|
function BottomSheet(props) {
|
|
49
78
|
const {
|
|
50
79
|
backdropOpacity,
|
|
80
|
+
borderRadius,
|
|
51
81
|
children,
|
|
52
82
|
enableDynamicSizing = true,
|
|
53
83
|
header,
|
|
84
|
+
stickyBottomElement,
|
|
54
85
|
topElement,
|
|
55
86
|
index,
|
|
56
87
|
maxHeightNormalizedRatio = 0.9,
|
|
57
88
|
onChange,
|
|
58
89
|
snapPoints = [],
|
|
59
|
-
|
|
60
|
-
disableDefaultShadow = false
|
|
90
|
+
enableScrollableHeaderBorder = false
|
|
61
91
|
} = props;
|
|
62
92
|
const styles = useStyles();
|
|
93
|
+
const {
|
|
94
|
+
height: windowHeight
|
|
95
|
+
} = (0, _reactNative.useWindowDimensions)();
|
|
96
|
+
const [topElementHeight, setTopElementHeight] = (0, _react.useState)(0);
|
|
97
|
+
const [stickyBottomElementHeight, setStickyBottomElementHeight] = (0, _react.useState)(0);
|
|
98
|
+
const [contentHeight, setContentHeight] = (0, _react.useState)(0);
|
|
99
|
+
const [isScrollable, setIsScrollable] = (0, _react.useState)(false);
|
|
100
|
+
const maxDynamicContentSize = Math.round(windowHeight * maxHeightNormalizedRatio) - topElementHeight;
|
|
101
|
+
const handleTopElementLayout = createHeightLayoutHandler(setTopElementHeight);
|
|
102
|
+
const handleStickyBottomElementLayout = createHeightLayoutHandler(setStickyBottomElementHeight);
|
|
63
103
|
|
|
64
104
|
const handleClose = () => {
|
|
65
105
|
if (onChange) {
|
|
@@ -77,9 +117,27 @@ function BottomSheet(props) {
|
|
|
77
117
|
snapPoints
|
|
78
118
|
});
|
|
79
119
|
const translateY = highestSnapPoint - (convertedSnapPoints[index] ?? 0);
|
|
80
|
-
const
|
|
81
|
-
|
|
120
|
+
const adjustedContentHeight = (0, _react.useMemo)(() => {
|
|
121
|
+
const adjustedHighestSnapPoint = highestSnapPoint + stickyBottomElementHeight;
|
|
122
|
+
return Math.min(maxDynamicContentSize, adjustedHighestSnapPoint);
|
|
123
|
+
}, [highestSnapPoint, stickyBottomElementHeight]);
|
|
124
|
+
const contentStyles = [styles.paper, borderRadius ? {
|
|
125
|
+
borderTopLeftRadius: borderRadius,
|
|
126
|
+
borderTopRightRadius: borderRadius
|
|
127
|
+
} : {}, {
|
|
128
|
+
height: adjustedContentHeight,
|
|
129
|
+
maxHeight: maxDynamicContentSize
|
|
82
130
|
}];
|
|
131
|
+
const headerStyles = [styles.headerContainer, isScrollable && enableScrollableHeaderBorder ? styles.headerBorder : {}];
|
|
132
|
+
const stickyBottomElementStyles = [styles.stickyBottomElement, isScrollable ? styles.stickyBottomElementShadow : {}];
|
|
133
|
+
(0, _react.useLayoutEffect)(() => {
|
|
134
|
+
if (contentHeight === 0 || highestSnapPoint === 0) {
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const adjustedHighestSnapPoint = highestSnapPoint + stickyBottomElementHeight;
|
|
139
|
+
setIsScrollable(adjustedHighestSnapPoint > maxDynamicContentSize);
|
|
140
|
+
}, [contentHeight, highestSnapPoint, stickyBottomElementHeight, maxDynamicContentSize]);
|
|
83
141
|
return /*#__PURE__*/_react.default.createElement(_core.Modal, {
|
|
84
142
|
backdropOpacity: backdropOpacity,
|
|
85
143
|
onClose: handleClose,
|
|
@@ -89,15 +147,26 @@ function BottomSheet(props) {
|
|
|
89
147
|
style: styles.animated,
|
|
90
148
|
translateY: translateY
|
|
91
149
|
}, topElement ? /*#__PURE__*/_react.default.createElement(_core.Column, null, /*#__PURE__*/_react.default.createElement(_core.Column, {
|
|
150
|
+
onLayout: handleTopElementLayout,
|
|
92
151
|
style: styles.topElementLocation
|
|
93
152
|
}, topElement)) : null, /*#__PURE__*/_react.default.createElement(_core.Paper, {
|
|
94
|
-
elevation:
|
|
95
|
-
style:
|
|
96
|
-
colorValue: disableDefaultBackgroundColor ? '#ffffff00' : undefined
|
|
153
|
+
elevation: 12,
|
|
154
|
+
style: contentStyles
|
|
97
155
|
}, /*#__PURE__*/_react.default.createElement(_reactNative.ScrollView, {
|
|
98
|
-
onContentSizeChange:
|
|
99
|
-
|
|
100
|
-
|
|
156
|
+
onContentSizeChange: (contentWidth, contentHeight) => {
|
|
157
|
+
setContentHeight(contentHeight);
|
|
158
|
+
handleContentSizeChange(contentWidth, contentHeight);
|
|
159
|
+
},
|
|
160
|
+
stickyHeaderIndices: header ? [0] : undefined,
|
|
161
|
+
style: {
|
|
162
|
+
paddingBottom: stickyBottomElementHeight
|
|
163
|
+
}
|
|
164
|
+
}, header ? /*#__PURE__*/_react.default.createElement(_reactNative.View, {
|
|
165
|
+
style: headerStyles
|
|
166
|
+
}, header) : null, children), stickyBottomElement ? /*#__PURE__*/_react.default.createElement(_core.Column, {
|
|
167
|
+
style: stickyBottomElementStyles,
|
|
168
|
+
onLayout: handleStickyBottomElementLayout
|
|
169
|
+
}, stickyBottomElement) : null)));
|
|
101
170
|
}
|
|
102
171
|
|
|
103
172
|
;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["useStyles","theme","useTheme","root","justifyContent","zIndex","dialog","animated","alignSelf","maxWidth","width","paper","borderTopLeftRadius","shape","roundnessExtra","borderTopRightRadius","borderBottomLeftRadius","borderBottomRightRadius","flexGrow","overflow","topElementLocation","position","bottom","BottomSheet","props","backdropOpacity","children","enableDynamicSizing","header","topElement","index","maxHeightNormalizedRatio","onChange","snapPoints","disableDefaultBackgroundColor","disableDefaultShadow","styles","handleClose","convertedSnapPoints","handleContentSizeChange","highestSnapPoint","useDynamicSnapPoints","translateY","paperStyles","height","css","StyleSheet","absoluteFill","undefined"],"sources":["BottomSheetWeb.tsx"],"sourcesContent":["import React from 'react';\nimport { ScrollView } from 'react-native';\nimport { Column, Modal, Paper, StyleSheet, css, 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 borderTopLeftRadius: theme.shape.roundnessExtra,\n borderTopRightRadius: theme.shape.roundnessExtra,\n borderBottomLeftRadius: 0,\n borderBottomRightRadius: 0,\n flexGrow: 1,\n overflow: 'hidden',\n },\n topElementLocation: {\n position: 'absolute',\n bottom: 0,\n width: '100%',\n },\n };\n};\n\nexport default function BottomSheet(props: BottomSheetProps) {\n const {\n backdropOpacity,\n children,\n enableDynamicSizing = true,\n header,\n topElement,\n index,\n maxHeightNormalizedRatio = 0.9,\n onChange,\n snapPoints = [],\n disableDefaultBackgroundColor = false,\n disableDefaultShadow = false,\n } = props;\n\n const styles = useStyles();\n\n const handleClose = () => {\n if (onChange) {\n onChange(-1);\n }\n };\n\n const {\n convertedSnapPoints,\n handleContentSizeChange,\n highestSnapPoint,\n } = useDynamicSnapPoints({\n enableDynamicSizing,\n maxHeightNormalizedRatio,\n snapPoints,\n });\n\n const translateY = highestSnapPoint - (convertedSnapPoints[index] ?? 0);\n\n const paperStyles = [\n styles.paper,\n { height: highestSnapPoint },\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\n style={styles.animated}\n translateY={translateY}\n >\n {topElement ? (\n <Column>\n <Column style={styles.topElementLocation}>\n {topElement}\n </Column>\n </Column>\n ) : null}\n\n <Paper\n elevation={disableDefaultShadow ? 0 : 12}\n style={paperStyles}\n colorValue={disableDefaultBackgroundColor ? '#ffffff00' : undefined}\n >\n <ScrollView\n onContentSizeChange={handleContentSizeChange}\n stickyHeaderIndices={header ? [0] : undefined}\n >\n {header}\n\n {children}\n </ScrollView>\n </Paper>\n </AnimatedY>\n </Modal>\n );\n};\n"],"mappings":";;;;;;;AAAA;;AACA;;AACA;;AAEA;;AAEA;;;;AAIA,MAAMA,SAAuC,GAAG,YAA+B;EAC3E,MAAMC,KAAK,GAAG,IAAAC,cAAA,GAAd;EAEA,OAAO;IACHC,IAAI,EAAE;MACFC,cAAc,EAAE,UADd;MAEFC,MAAM,EAAEJ,KAAK,CAACI,MAAN,CAAaC;IAFnB,CADH;IAKHC,QAAQ,EAAE;MACNC,SAAS,EAAE,QADL;MAENC,QAAQ,EAAE,GAFJ;MAGNC,KAAK,EAAE;IAHD,CALP;IAUHC,KAAK,EAAE;MACHC,mBAAmB,EAAEX,KAAK,CAACY,KAAN,CAAYC,cAD9B;MAEHC,oBAAoB,EAAEd,KAAK,CAACY,KAAN,CAAYC,cAF/B;MAGHE,sBAAsB,EAAE,CAHrB;MAIHC,uBAAuB,EAAE,CAJtB;MAKHC,QAAQ,EAAE,CALP;MAMHC,QAAQ,EAAE;IANP,CAVJ;IAkBHC,kBAAkB,EAAE;MAChBC,QAAQ,EAAE,UADM;MAEhBC,MAAM,EAAE,CAFQ;MAGhBZ,KAAK,EAAE;IAHS;EAlBjB,CAAP;AAwBH,CA3BD;;AA6Be,SAASa,WAAT,CAAqBC,KAArB,EAA8C;EACzD,MAAM;IACFC,eADE;IAEFC,QAFE;IAGFC,mBAAmB,GAAG,IAHpB;IAIFC,MAJE;IAKFC,UALE;IAMFC,KANE;IAOFC,wBAAwB,GAAG,GAPzB;IAQFC,QARE;IASFC,UAAU,GAAG,EATX;IAUFC,6BAA6B,GAAG,KAV9B;IAWFC,oBAAoB,GAAG;EAXrB,IAYFX,KAZJ;EAcA,MAAMY,MAAM,GAAGpC,SAAS,EAAxB;;EAEA,MAAMqC,WAAW,GAAG,MAAM;IACtB,IAAIL,QAAJ,EAAc;MACVA,QAAQ,CAAC,CAAC,CAAF,CAAR;IACH;EACJ,CAJD;;EAMA,MAAM;IACFM,mBADE;IAEFC,uBAFE;IAGFC;EAHE,IAIF,IAAAC,6BAAA,EAAqB;IACrBd,mBADqB;IAErBI,wBAFqB;IAGrBE;EAHqB,CAArB,CAJJ;EAUA,MAAMS,UAAU,GAAGF,gBAAgB,IAAIF,mBAAmB,CAACR,KAAD,CAAnB,IAA8B,CAAlC,CAAnC;EAEA,MAAMa,WAAW,GAAG,CAChBP,MAAM,CAACzB,KADS,EAEhB;IAAEiC,MAAM,EAAEJ;EAAV,CAFgB,CAApB;EAKA,oBACI,6BAAC,WAAD;IACI,eAAe,EAAEf,eADrB;IAEI,OAAO,EAAEY,WAFb;IAGI,OAAO,EAAEP,KAAK,IAAI,CAHtB;IAII,KAAK,EAAE,IAAAe,SAAA,EAAI,CAACC,gBAAA,CAAWC,YAAZ,EAA0BX,MAAM,CAACjC,IAAjC,CAAJ;EAJX,gBAMI,6BAAC,kBAAD;IACI,KAAK,EAAEiC,MAAM,CAAC7B,QADlB;IAEI,UAAU,EAAEmC;EAFhB,GAIKb,UAAU,gBACP,6BAAC,YAAD,qBACI,6BAAC,YAAD;IAAQ,KAAK,EAAEO,MAAM,CAAChB;EAAtB,GACKS,UADL,CADJ,CADO,GAMP,IAVR,eAYI,6BAAC,WAAD;IACI,SAAS,EAAEM,oBAAoB,GAAG,CAAH,GAAO,EAD1C;IAEI,KAAK,EAAEQ,WAFX;IAGI,UAAU,EAAET,6BAA6B,GAAG,WAAH,GAAiBc;EAH9D,gBAKI,6BAAC,uBAAD;IACI,mBAAmB,EAAET,uBADzB;IAEI,mBAAmB,EAAEX,MAAM,GAAG,CAAC,CAAD,CAAH,GAASoB;EAFxC,GAIKpB,MAJL,EAMKF,QANL,CALJ,CAZJ,CANJ,CADJ;AAoCH;;AAAA"}
|
|
1
|
+
{"version":3,"names":["createHeightLayoutHandler","setHeight","event","height","nativeEvent","layout","useStyles","theme","useTheme","stickyBottomElementShadow","useElevationStyle","root","justifyContent","zIndex","dialog","animated","alignSelf","maxWidth","width","paper","borderTopLeftRadius","shape","roundnessExtra","borderTopRightRadius","borderBottomLeftRadius","borderBottomRightRadius","flexGrow","overflow","topElementLocation","position","bottom","headerContainer","backgroundColor","palette","default","headerBorder","borderBottomWidth","borderBottomColor","divider","stickyBottomElement","left","right","BottomSheet","props","backdropOpacity","borderRadius","children","enableDynamicSizing","header","topElement","index","maxHeightNormalizedRatio","onChange","snapPoints","enableScrollableHeaderBorder","styles","windowHeight","useWindowDimensions","topElementHeight","setTopElementHeight","useState","stickyBottomElementHeight","setStickyBottomElementHeight","contentHeight","setContentHeight","isScrollable","setIsScrollable","maxDynamicContentSize","Math","round","handleTopElementLayout","handleStickyBottomElementLayout","handleClose","convertedSnapPoints","handleContentSizeChange","highestSnapPoint","useDynamicSnapPoints","translateY","adjustedContentHeight","useMemo","adjustedHighestSnapPoint","min","contentStyles","maxHeight","headerStyles","stickyBottomElementStyles","useLayoutEffect","css","StyleSheet","absoluteFill","contentWidth","undefined","paddingBottom"],"sources":["BottomSheetWeb.tsx"],"sourcesContent":["import React, { useLayoutEffect, useMemo, useState } from 'react';\nimport { LayoutChangeEvent, ScrollView, useWindowDimensions, View } from 'react-native';\nimport { Column, css, Modal, Paper, StyleSheet, useElevationStyle, 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\nconst createHeightLayoutHandler = (setHeight: React.Dispatch<React.SetStateAction<number>>) => {\n return (event: LayoutChangeEvent) => {\n const { height } = event.nativeEvent.layout;\n setHeight(height);\n };\n}\n\ntype BottomSheetStyles = NamedStylesStringUnion<'root' | 'animated' | 'paper' | 'topElementLocation' | 'headerContainer' | 'headerBorder' | 'stickyBottomElement' | 'stickyBottomElementShadow'>;\n\nconst useStyles: UseStyles<BottomSheetStyles> = function (): BottomSheetStyles {\n const theme = useTheme();\n const stickyBottomElementShadow = useElevationStyle(8);\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 borderTopLeftRadius: theme.shape.roundnessExtra,\n borderTopRightRadius: theme.shape.roundnessExtra,\n borderBottomLeftRadius: 0,\n borderBottomRightRadius: 0,\n flexGrow: 1,\n overflow: 'hidden',\n },\n topElementLocation: {\n position: 'absolute',\n bottom: 0,\n width: '100%',\n },\n headerContainer: {\n backgroundColor: theme.palette.paper.default,\n },\n headerBorder: {\n borderBottomWidth: 0.5,\n borderBottomColor: theme.palette.divider,\n },\n stickyBottomElement: {\n position: 'absolute',\n bottom: 0,\n left: 0,\n right: 0,\n backgroundColor: theme.palette.paper.default,\n },\n stickyBottomElementShadow,\n };\n};\n\nexport default function BottomSheet(props: BottomSheetProps) {\n const {\n backdropOpacity,\n borderRadius,\n children,\n enableDynamicSizing = true,\n header,\n stickyBottomElement,\n topElement,\n index,\n maxHeightNormalizedRatio = 0.9,\n onChange,\n snapPoints = [],\n enableScrollableHeaderBorder = false,\n } = props;\n\n const styles = useStyles();\n\n const { height: windowHeight } = useWindowDimensions();\n\n const [topElementHeight, setTopElementHeight] = useState(0);\n const [stickyBottomElementHeight, setStickyBottomElementHeight] = useState(0);\n const [contentHeight, setContentHeight] = useState(0);\n const [isScrollable, setIsScrollable] = useState(false);\n\n const maxDynamicContentSize = Math.round(windowHeight * maxHeightNormalizedRatio) - topElementHeight;\n\n const handleTopElementLayout = createHeightLayoutHandler(setTopElementHeight);\n const handleStickyBottomElementLayout = createHeightLayoutHandler(setStickyBottomElementHeight);\n\n const handleClose = () => {\n if (onChange) {\n onChange(-1);\n }\n };\n\n const {\n convertedSnapPoints,\n handleContentSizeChange,\n highestSnapPoint,\n } = useDynamicSnapPoints({\n enableDynamicSizing,\n maxHeightNormalizedRatio,\n snapPoints,\n });\n\n const translateY = highestSnapPoint - (convertedSnapPoints[index] ?? 0);\n\n const adjustedContentHeight = useMemo(() => {\n const adjustedHighestSnapPoint = highestSnapPoint + stickyBottomElementHeight;\n\n return Math.min(maxDynamicContentSize, adjustedHighestSnapPoint);\n }, [highestSnapPoint, stickyBottomElementHeight]);\n\n const contentStyles = [\n styles.paper,\n borderRadius ? { borderTopLeftRadius: borderRadius, borderTopRightRadius: borderRadius } : {},\n { height: adjustedContentHeight, maxHeight: maxDynamicContentSize },\n ];\n\n const headerStyles = [\n styles.headerContainer,\n isScrollable && enableScrollableHeaderBorder ? styles.headerBorder : {},\n ];\n\n const stickyBottomElementStyles = [\n styles.stickyBottomElement,\n isScrollable ? styles.stickyBottomElementShadow : {},\n ];\n\n useLayoutEffect(() => {\n if (contentHeight === 0 || highestSnapPoint === 0) {\n return;\n }\n\n const adjustedHighestSnapPoint = highestSnapPoint + stickyBottomElementHeight;\n setIsScrollable(adjustedHighestSnapPoint > maxDynamicContentSize);\n }, [contentHeight, highestSnapPoint, stickyBottomElementHeight, maxDynamicContentSize]);\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\n style={styles.animated}\n translateY={translateY}\n >\n {topElement ? (\n <Column>\n <Column\n onLayout={handleTopElementLayout}\n style={styles.topElementLocation}\n >\n {topElement}\n </Column>\n </Column>\n ) : null}\n\n <Paper\n elevation={12}\n style={contentStyles}\n >\n <ScrollView\n onContentSizeChange={(contentWidth: number, contentHeight: number) => {\n setContentHeight(contentHeight);\n handleContentSizeChange(contentWidth, contentHeight);\n }}\n stickyHeaderIndices={header ? [0] : undefined}\n style={{ paddingBottom: stickyBottomElementHeight }}\n >\n {header ? (\n <View style={headerStyles}>\n {header}\n </View>\n ): null}\n\n {children}\n </ScrollView>\n\n {stickyBottomElement ? (\n <Column\n style={stickyBottomElementStyles}\n onLayout={handleStickyBottomElementLayout}\n >\n {stickyBottomElement}\n </Column>\n ): null}\n </Paper>\n </AnimatedY>\n </Modal>\n );\n};\n"],"mappings":"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"}
|
|
@@ -2,33 +2,48 @@ function _extends() { _extends = Object.assign ? Object.assign.bind() : function
|
|
|
2
2
|
|
|
3
3
|
import React from 'react';
|
|
4
4
|
import { Animated, Platform, useWindowDimensions, View } from 'react-native';
|
|
5
|
-
import {
|
|
5
|
+
import { BottomSheetBackdrop, BottomSheetFooter, BottomSheetModal, BottomSheetModalProvider, BottomSheetScrollView } from '@gorhom/bottom-sheet';
|
|
6
|
+
import { Column, isNotAndroid12, useAnimatedValue, useElevationStyle } from '@fountain-ui/core';
|
|
6
7
|
import { useTheme } from '@fountain-ui/styles';
|
|
7
|
-
import { BottomSheetBackdrop, BottomSheetModal, BottomSheetModalProvider, BottomSheetScrollView } from '@gorhom/bottom-sheet';
|
|
8
8
|
import TransparentBackdrop from './TransparentBackdrop';
|
|
9
9
|
|
|
10
10
|
const NoHandle = () => null;
|
|
11
11
|
|
|
12
|
+
const createHeightLayoutHandler = setHeight => {
|
|
13
|
+
return event => {
|
|
14
|
+
const {
|
|
15
|
+
height
|
|
16
|
+
} = event.nativeEvent.layout;
|
|
17
|
+
setHeight(height);
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
|
|
12
21
|
export default function BottomSheet(props) {
|
|
13
22
|
const {
|
|
14
23
|
backdropOpacity = 0.5,
|
|
24
|
+
borderRadius: borderRadiusProp,
|
|
15
25
|
children,
|
|
16
26
|
enableDynamicSizing = true,
|
|
17
27
|
header,
|
|
28
|
+
stickyBottomElement,
|
|
18
29
|
topElement,
|
|
19
30
|
index,
|
|
20
31
|
maxHeightNormalizedRatio = 0.9,
|
|
21
32
|
onChange,
|
|
22
33
|
snapPoints = [],
|
|
23
|
-
|
|
24
|
-
disableDefaultShadow = false
|
|
34
|
+
enableScrollableHeaderBorder = false
|
|
25
35
|
} = props;
|
|
26
36
|
const indexRef = React.useRef(-1);
|
|
27
37
|
const bottomSheetRef = React.useRef(null);
|
|
28
38
|
const {
|
|
29
39
|
height: windowHeight
|
|
30
40
|
} = useWindowDimensions();
|
|
31
|
-
const
|
|
41
|
+
const [isScrollable, setIsScrollable] = React.useState(false);
|
|
42
|
+
const [topElementHeight, setTopElementHeight] = React.useState(0);
|
|
43
|
+
const [stickyBottomElementHeight, setStickyBottomElementHeight] = React.useState(0);
|
|
44
|
+
const maxDynamicContentSize = Math.round(windowHeight * maxHeightNormalizedRatio) - topElementHeight;
|
|
45
|
+
const handleTopElementLayout = createHeightLayoutHandler(setTopElementHeight);
|
|
46
|
+
const handleStickyBottomElementLayout = createHeightLayoutHandler(setStickyBottomElementHeight);
|
|
32
47
|
const handleChange = React.useCallback(newIndex => {
|
|
33
48
|
indexRef.current = newIndex;
|
|
34
49
|
|
|
@@ -61,25 +76,27 @@ export default function BottomSheet(props) {
|
|
|
61
76
|
}, [index]);
|
|
62
77
|
const theme = useTheme();
|
|
63
78
|
const shadow = theme.shadow[12];
|
|
79
|
+
const borderRadius = borderRadiusProp ?? theme.shape.roundnessExtra;
|
|
64
80
|
const modalStyle = {
|
|
65
81
|
backgroundColor: '#ffffff00',
|
|
66
|
-
borderTopLeftRadius:
|
|
67
|
-
borderTopRightRadius:
|
|
68
|
-
...
|
|
82
|
+
borderTopLeftRadius: borderRadius,
|
|
83
|
+
borderTopRightRadius: borderRadius,
|
|
84
|
+
...Platform.select({
|
|
69
85
|
android: shadow === null || shadow === void 0 ? void 0 : shadow.elevation,
|
|
70
86
|
ios: shadow === null || shadow === void 0 ? void 0 : shadow.shadow,
|
|
71
87
|
web: shadow === null || shadow === void 0 ? void 0 : shadow.boxShadow
|
|
72
|
-
})
|
|
88
|
+
})
|
|
73
89
|
};
|
|
90
|
+
const backgroundColor = theme.palette.paper.default;
|
|
74
91
|
const backgroundStyle = {
|
|
75
|
-
backgroundColor
|
|
76
|
-
borderTopLeftRadius:
|
|
77
|
-
borderTopRightRadius:
|
|
92
|
+
backgroundColor,
|
|
93
|
+
borderTopLeftRadius: borderRadius,
|
|
94
|
+
borderTopRightRadius: borderRadius
|
|
78
95
|
};
|
|
79
96
|
const contentWrapperStyle = {
|
|
80
97
|
flex: 1,
|
|
81
|
-
borderTopLeftRadius:
|
|
82
|
-
borderTopRightRadius:
|
|
98
|
+
borderTopLeftRadius: borderRadius,
|
|
99
|
+
borderTopRightRadius: borderRadius,
|
|
83
100
|
overflow: 'hidden'
|
|
84
101
|
};
|
|
85
102
|
const isBackdropTransparent = backdropOpacity <= 0;
|
|
@@ -110,6 +127,32 @@ export default function BottomSheet(props) {
|
|
|
110
127
|
}).start();
|
|
111
128
|
};
|
|
112
129
|
|
|
130
|
+
const handleContentSizeChange = (_, contentHeight) => {
|
|
131
|
+
setIsScrollable(contentHeight > maxDynamicContentSize);
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
const headerStyle = {
|
|
135
|
+
backgroundColor,
|
|
136
|
+
...(isScrollable && enableScrollableHeaderBorder ? {
|
|
137
|
+
borderBottomWidth: 0.5,
|
|
138
|
+
borderBottomColor: theme.palette.divider
|
|
139
|
+
} : {})
|
|
140
|
+
};
|
|
141
|
+
const childrenStyle = {
|
|
142
|
+
backgroundColor,
|
|
143
|
+
paddingBottom: stickyBottomElementHeight
|
|
144
|
+
};
|
|
145
|
+
const stickyBottomElementShadow = useElevationStyle(8);
|
|
146
|
+
const stickyBottomElementStyle = {
|
|
147
|
+
backgroundColor: theme.palette.paper.default,
|
|
148
|
+
...(isScrollable ? stickyBottomElementShadow : {})
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
const renderFooter = props => /*#__PURE__*/React.createElement(BottomSheetFooter, props, /*#__PURE__*/React.createElement(View, {
|
|
152
|
+
onLayout: handleStickyBottomElementLayout,
|
|
153
|
+
style: stickyBottomElementStyle
|
|
154
|
+
}, stickyBottomElement));
|
|
155
|
+
|
|
113
156
|
return /*#__PURE__*/React.createElement(BottomSheetModalProvider, null, /*#__PURE__*/React.createElement(BottomSheetModal, {
|
|
114
157
|
backdropComponent: isBackdropTransparent ? TransparentBackdrop : OpacityAwareBackdrop // @ts-ignore
|
|
115
158
|
,
|
|
@@ -125,17 +168,24 @@ export default function BottomSheet(props) {
|
|
|
125
168
|
enableDynamicSizing: enableDynamicSizing,
|
|
126
169
|
maxDynamicContentSize: maxDynamicContentSize,
|
|
127
170
|
detached: Boolean(topElement),
|
|
128
|
-
onAnimate: topElement ? onAnimate : undefined
|
|
171
|
+
onAnimate: topElement ? onAnimate : undefined,
|
|
172
|
+
footerComponent: stickyBottomElement ? renderFooter : undefined
|
|
129
173
|
}, topElement ? /*#__PURE__*/React.createElement(Animated.View, {
|
|
130
174
|
style: topElementAnimationStyle
|
|
131
175
|
}, /*#__PURE__*/React.createElement(Column, {
|
|
176
|
+
onLayout: handleTopElementLayout,
|
|
132
177
|
style: topElementLocationStyle
|
|
133
178
|
}, topElement)) : null, /*#__PURE__*/React.createElement(View, {
|
|
134
179
|
style: contentWrapperStyle
|
|
135
180
|
}, /*#__PURE__*/React.createElement(BottomSheetScrollView, {
|
|
136
181
|
bounces: false,
|
|
137
|
-
stickyHeaderIndices: header ? [0] : undefined
|
|
138
|
-
|
|
182
|
+
stickyHeaderIndices: header ? [0] : undefined,
|
|
183
|
+
onContentSizeChange: handleContentSizeChange
|
|
184
|
+
}, /*#__PURE__*/React.createElement(View, {
|
|
185
|
+
style: headerStyle
|
|
186
|
+
}, header), /*#__PURE__*/React.createElement(View, {
|
|
187
|
+
style: childrenStyle
|
|
188
|
+
}, children)))));
|
|
139
189
|
}
|
|
140
190
|
;
|
|
141
191
|
//# sourceMappingURL=BottomSheetNative.js.map
|