@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.
@@ -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
- disableDefaultBackgroundColor = false,
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
- const maxDynamicContentSize = Math.round(windowHeight * maxHeightNormalizedRatio);
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: theme.shape.roundnessExtra,
88
- borderTopRightRadius: theme.shape.roundnessExtra,
89
- ...(disableDefaultShadow ? {} : _reactNative.Platform.select({
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: disableDefaultBackgroundColor ? '#ffffff00' : theme.palette.paper.default,
97
- borderTopLeftRadius: theme.shape.roundnessExtra,
98
- borderTopRightRadius: theme.shape.roundnessExtra
117
+ backgroundColor,
118
+ borderTopLeftRadius: borderRadius,
119
+ borderTopRightRadius: borderRadius
99
120
  };
100
121
  const contentWrapperStyle = {
101
122
  flex: 1,
102
- borderTopLeftRadius: theme.shape.roundnessExtra,
103
- borderTopRightRadius: theme.shape.roundnessExtra,
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
- }, header, children))));
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\n /**\n * Disable default backgroundColor.\n * @default false\n */\n disableDefaultBackgroundColor?: boolean;\n\n /**\n * Disable default shadow.\n * @default false\n */\n disableDefaultShadow?: boolean;\n}> {}\n"],"mappings":""}
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 = _interopRequireDefault(require("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
- disableDefaultBackgroundColor = false,
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 paperStyles = [styles.paper, {
81
- height: highestSnapPoint
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: disableDefaultShadow ? 0 : 12,
95
- style: paperStyles,
96
- colorValue: disableDefaultBackgroundColor ? '#ffffff00' : undefined
153
+ elevation: 12,
154
+ style: contentStyles
97
155
  }, /*#__PURE__*/_react.default.createElement(_reactNative.ScrollView, {
98
- onContentSizeChange: handleContentSizeChange,
99
- stickyHeaderIndices: header ? [0] : undefined
100
- }, header, children))));
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 { Column, useAnimatedValue, isNotAndroid12 } from '@fountain-ui/core';
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
- disableDefaultBackgroundColor = false,
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 maxDynamicContentSize = Math.round(windowHeight * maxHeightNormalizedRatio);
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: theme.shape.roundnessExtra,
67
- borderTopRightRadius: theme.shape.roundnessExtra,
68
- ...(disableDefaultShadow ? {} : Platform.select({
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: disableDefaultBackgroundColor ? '#ffffff00' : theme.palette.paper.default,
76
- borderTopLeftRadius: theme.shape.roundnessExtra,
77
- borderTopRightRadius: theme.shape.roundnessExtra
92
+ backgroundColor,
93
+ borderTopLeftRadius: borderRadius,
94
+ borderTopRightRadius: borderRadius
78
95
  };
79
96
  const contentWrapperStyle = {
80
97
  flex: 1,
81
- borderTopLeftRadius: theme.shape.roundnessExtra,
82
- borderTopRightRadius: theme.shape.roundnessExtra,
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
- }, header, children))));
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