@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.
@@ -1 +1 @@
1
- {"version":3,"names":["React","Animated","Platform","useWindowDimensions","View","Column","useAnimatedValue","isNotAndroid12","useTheme","BottomSheetBackdrop","BottomSheetModal","BottomSheetModalProvider","BottomSheetScrollView","TransparentBackdrop","NoHandle","BottomSheet","props","backdropOpacity","children","enableDynamicSizing","header","topElement","index","maxHeightNormalizedRatio","onChange","snapPoints","disableDefaultBackgroundColor","disableDefaultShadow","indexRef","useRef","bottomSheetRef","height","windowHeight","maxDynamicContentSize","Math","round","handleChange","useCallback","newIndex","current","handleDismiss","useEffect","present","dismiss","snapToIndex","theme","shadow","modalStyle","backgroundColor","borderTopLeftRadius","shape","roundnessExtra","borderTopRightRadius","select","android","elevation","ios","web","boxShadow","backgroundStyle","palette","paper","default","contentWrapperStyle","flex","overflow","isBackdropTransparent","OpacityAwareBackdrop","topElementOpacity","topElementAnimationStyle","opacity","topElementLocationStyle","position","width","bottom","onAnimate","fromIndex","toIndex","isVisible","timing","toValue","duration","useNativeDriver","start","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":";;AAAA,OAAOA,KAAP,MAAkB,OAAlB;AACA,SAASC,QAAT,EAAmBC,QAAnB,EAA6BC,mBAA7B,EAAkDC,IAAlD,QAA8D,cAA9D;AACA,SAASC,MAAT,EAAiBC,gBAAjB,EAAkDC,cAAlD,QAAwE,mBAAxE;AACA,SAASC,QAAT,QAAyB,qBAAzB;AACA,SACIC,mBADJ,EAGIC,gBAHJ,EAIIC,wBAJJ,EAKIC,qBALJ,QAMO,sBANP;AAQA,OAAOC,mBAAP,MAAgC,uBAAhC;;AAEA,MAAMC,QAAQ,GAAG,MAAM,IAAvB;;AAEA,eAAe,SAASC,WAAT,CAAqBC,KAArB,EAA8C;EACzD,MAAM;IACFC,eAAe,GAAG,GADhB;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,QAAQ,GAAG5B,KAAK,CAAC6B,MAAN,CAAqB,CAAC,CAAtB,CAAjB;EACA,MAAMC,cAAc,GAAG9B,KAAK,CAAC6B,MAAN,CAAsC,IAAtC,CAAvB;EAEA,MAAM;IAAEE,MAAM,EAAEC;EAAV,IAA2B7B,mBAAmB,EAApD;EACA,MAAM8B,qBAAqB,GAAGC,IAAI,CAACC,KAAL,CAAWH,YAAY,GAAGT,wBAA1B,CAA9B;EAEA,MAAMa,YAAY,GAAGpC,KAAK,CAACqC,WAAN,CAAmBC,QAAD,IAAsB;IACzDV,QAAQ,CAACW,OAAT,GAAmBD,QAAnB;;IAEA,IAAId,QAAJ,EAAc;MACVA,QAAQ,CAACc,QAAD,CAAR;IACH;EACJ,CANoB,EAMlB,CAACd,QAAD,CANkB,CAArB;EAQA,MAAMgB,aAAa,GAAGxC,KAAK,CAACqC,WAAN,CAAkB,MAAM;IAC1CD,YAAY,CAAC,CAAC,CAAF,CAAZ;EACH,CAFqB,EAEnB,CAACA,YAAD,CAFmB,CAAtB;EAIApC,KAAK,CAACyC,SAAN,CAAgB,MAAM;IAClB,IAAInB,KAAK,KAAKM,QAAQ,CAACW,OAAvB,EAAgC;MAC5B;IACH;;IAED,IAAIX,QAAQ,CAACW,OAAT,GAAmB,CAAnB,IAAwBjB,KAAK,IAAI,CAArC,EAAwC;MAAA;;MACpC,yBAAAQ,cAAc,CAACS,OAAf,gFAAwBG,OAAxB;IACH,CAFD,MAEO,IAAId,QAAQ,CAACW,OAAT,IAAoB,CAApB,IAAyBjB,KAAK,GAAG,CAArC,EAAwC;MAAA;;MAC3C,0BAAAQ,cAAc,CAACS,OAAf,kFAAwBI,OAAxB;IACH,CAFM,MAEA;MAAA;;MACH;MACA,0BAAAb,cAAc,CAACS,OAAf,kFAAwBK,WAAxB,CAAoCtB,KAApC;IACH;EACJ,CAbD,EAaG,CAACA,KAAD,CAbH;EAeA,MAAMuB,KAAK,GAAGrC,QAAQ,EAAtB;EACA,MAAMsC,MAAM,GAAGD,KAAK,CAACC,MAAN,CAAa,EAAb,CAAf;EACA,MAAMC,UAAU,GAAG;IACfC,eAAe,EAAE,WADF;IAEfC,mBAAmB,EAAEJ,KAAK,CAACK,KAAN,CAAYC,cAFlB;IAGfC,oBAAoB,EAAEP,KAAK,CAACK,KAAN,CAAYC,cAHnB;IAIf,IAAIxB,oBAAoB,GAAG,EAAH,GAAQzB,QAAQ,CAACmD,MAAT,CAAwB;MACpDC,OAAO,EAAER,MAAF,aAAEA,MAAF,uBAAEA,MAAM,CAAES,SADmC;MAEpDC,GAAG,EAAEV,MAAF,aAAEA,MAAF,uBAAEA,MAAM,CAAEA,MAFuC;MAGpDW,GAAG,EAAEX,MAAF,aAAEA,MAAF,uBAAEA,MAAM,CAAEY;IAHuC,CAAxB,CAAhC;EAJe,CAAnB;EAUA,MAAMC,eAAe,GAAG;IACpBX,eAAe,EAAEtB,6BAA6B,GAAG,WAAH,GAAiBmB,KAAK,CAACe,OAAN,CAAcC,KAAd,CAAoBC,OAD/D;IAEpBb,mBAAmB,EAAEJ,KAAK,CAACK,KAAN,CAAYC,cAFb;IAGpBC,oBAAoB,EAAEP,KAAK,CAACK,KAAN,CAAYC;EAHd,CAAxB;EAKA,MAAMY,mBAAmB,GAAG;IACxBC,IAAI,EAAE,CADkB;IAExBf,mBAAmB,EAAEJ,KAAK,CAACK,KAAN,CAAYC,cAFT;IAGxBC,oBAAoB,EAAEP,KAAK,CAACK,KAAN,CAAYC,cAHV;IAIxBc,QAAQ,EAAE;EAJc,CAA5B;EAOA,MAAMC,qBAAqB,GAAGjD,eAAe,IAAI,CAAjD;;EAEA,MAAMkD,oBAAoB,GAAInD,KAAD,iBACzB,oBAAC,mBAAD,eACQA,KADR;IAEI,cAAc,EAAE,CAFpB;IAGI,iBAAiB,EAAE,CAAC,CAHxB;IAII,OAAO,EAAEC,eAJb;IAKI,aAAa,EAAEO,QAAQ,GAAG,OAAH,GAAa;EALxC,GADJ;;EAUA,MAAM4C,iBAAiB,GAAG9D,gBAAgB,CAAC,CAAD,CAA1C;EACA,MAAM+D,wBAAmE,GAAG;IAAEC,OAAO,EAAEF;EAAX,CAA5E;EACA,MAAMG,uBAAsC,GAAG;IAC3CC,QAAQ,EAAE,UADiC;IAE3CC,KAAK,EAAE,MAFoC;IAG3CC,MAAM,EAAE;EAHmC,CAA/C;;EAKA,MAAMC,SAAS,GAAG,CAACC,SAAD,EAAoBC,OAApB,KAAwC;IACtD,MAAMC,SAAS,GAAGD,OAAO,GAAG,CAAC,CAA7B;IAEA5E,QAAQ,CAAC8E,MAAT,CAAgBX,iBAAhB,EAAmC;MAC/BY,OAAO,EAAEF,SAAS,GAAG,CAAH,GAAO,CADM;MAE/BG,QAAQ,EAAE,CAFqB;MAG/BC,eAAe,EAAE3E;IAHc,CAAnC,EAIG4E,KAJH;EAKH,CARD;;EAUA,oBACI,oBAAC,wBAAD,qBACI,oBAAC,gBAAD;IACI,iBAAiB,EAAEjB,qBAAqB,GAAGrD,mBAAH,GAAyBsD,oBADrE,CAEI;IAFJ;IAGI,eAAe,EAAER,eAHrB;IAII,KAAK,EAAErC,KAJX;IAKI,eAAe,EAAER,QALrB;IAMI,QAAQ,EAAEsB,YANd;IAOI,SAAS,EAAEI,aAPf;IAQI,GAAG,EAAEV,cART;IASI,UAAU,EAAEL,UAThB;IAUI,KAAK,EAAEsB,UAVX;IAWI,oBAAoB,EAAEqC,OAAO,CAAC5D,QAAD,CAXjC;IAYI,mBAAmB,EAAEL,mBAZzB;IAaI,qBAAqB,EAAEc,qBAb3B;IAcI,QAAQ,EAAEmD,OAAO,CAAC/D,UAAD,CAdrB;IAeI,SAAS,EAAEA,UAAU,GAAGsD,SAAH,GAAeU;EAfxC,GAiBKhE,UAAU,gBACP,oBAAC,QAAD,CAAU,IAAV;IAAe,KAAK,EAAEgD;EAAtB,gBACI,oBAAC,MAAD;IAAQ,KAAK,EAAEE;EAAf,GACKlD,UADL,CADJ,CADO,GAMP,IAvBR,eA0BI,oBAAC,IAAD;IAAM,KAAK,EAAE0C;EAAb,gBACI,oBAAC,qBAAD;IACI,OAAO,EAAE,KADb;IAEI,mBAAmB,EAAE3C,MAAM,GAAG,CAAC,CAAD,CAAH,GAASiE;EAFxC,GAIKjE,MAJL,EAMKF,QANL,CADJ,CA1BJ,CADJ,CADJ;AAyCH;AAAA"}
1
+ {"version":3,"names":["React","Animated","Platform","useWindowDimensions","View","BottomSheetBackdrop","BottomSheetFooter","BottomSheetModal","BottomSheetModalProvider","BottomSheetScrollView","Column","isNotAndroid12","useAnimatedValue","useElevationStyle","useTheme","TransparentBackdrop","NoHandle","createHeightLayoutHandler","setHeight","event","height","nativeEvent","layout","BottomSheet","props","backdropOpacity","borderRadius","borderRadiusProp","children","enableDynamicSizing","header","stickyBottomElement","topElement","index","maxHeightNormalizedRatio","onChange","snapPoints","enableScrollableHeaderBorder","indexRef","useRef","bottomSheetRef","windowHeight","isScrollable","setIsScrollable","useState","topElementHeight","setTopElementHeight","stickyBottomElementHeight","setStickyBottomElementHeight","maxDynamicContentSize","Math","round","handleTopElementLayout","handleStickyBottomElementLayout","handleChange","useCallback","newIndex","current","handleDismiss","useEffect","present","dismiss","snapToIndex","theme","shadow","shape","roundnessExtra","modalStyle","backgroundColor","borderTopLeftRadius","borderTopRightRadius","select","android","elevation","ios","web","boxShadow","palette","paper","default","backgroundStyle","contentWrapperStyle","flex","overflow","isBackdropTransparent","OpacityAwareBackdrop","topElementOpacity","topElementAnimationStyle","opacity","topElementLocationStyle","position","width","bottom","onAnimate","fromIndex","toIndex","isVisible","timing","toValue","duration","useNativeDriver","start","handleContentSizeChange","_","contentHeight","headerStyle","borderBottomWidth","borderBottomColor","divider","childrenStyle","paddingBottom","stickyBottomElementShadow","stickyBottomElementStyle","renderFooter","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":""}
@@ -1,11 +1,21 @@
1
- import React from 'react';
2
- import { ScrollView } from 'react-native';
3
- import { Column, Modal, Paper, StyleSheet, css, useTheme } from '@fountain-ui/core';
1
+ import React, { useLayoutEffect, useMemo, useState } from 'react';
2
+ import { ScrollView, useWindowDimensions, View } from 'react-native';
3
+ import { Column, css, Modal, Paper, StyleSheet, useElevationStyle, useTheme } from '@fountain-ui/core';
4
4
  import AnimatedY from '../AnimatedY';
5
5
  import useDynamicSnapPoints from './useDynamicSnapPoints';
6
6
 
7
+ const createHeightLayoutHandler = setHeight => {
8
+ return event => {
9
+ const {
10
+ height
11
+ } = event.nativeEvent.layout;
12
+ setHeight(height);
13
+ };
14
+ };
15
+
7
16
  const useStyles = function () {
8
17
  const theme = useTheme();
18
+ const stickyBottomElementShadow = useElevationStyle(8);
9
19
  return {
10
20
  root: {
11
21
  justifyContent: 'flex-end',
@@ -28,25 +38,51 @@ const useStyles = function () {
28
38
  position: 'absolute',
29
39
  bottom: 0,
30
40
  width: '100%'
31
- }
41
+ },
42
+ headerContainer: {
43
+ backgroundColor: theme.palette.paper.default
44
+ },
45
+ headerBorder: {
46
+ borderBottomWidth: 0.5,
47
+ borderBottomColor: theme.palette.divider
48
+ },
49
+ stickyBottomElement: {
50
+ position: 'absolute',
51
+ bottom: 0,
52
+ left: 0,
53
+ right: 0,
54
+ backgroundColor: theme.palette.paper.default
55
+ },
56
+ stickyBottomElementShadow
32
57
  };
33
58
  };
34
59
 
35
60
  export default function BottomSheet(props) {
36
61
  const {
37
62
  backdropOpacity,
63
+ borderRadius,
38
64
  children,
39
65
  enableDynamicSizing = true,
40
66
  header,
67
+ stickyBottomElement,
41
68
  topElement,
42
69
  index,
43
70
  maxHeightNormalizedRatio = 0.9,
44
71
  onChange,
45
72
  snapPoints = [],
46
- disableDefaultBackgroundColor = false,
47
- disableDefaultShadow = false
73
+ enableScrollableHeaderBorder = false
48
74
  } = props;
49
75
  const styles = useStyles();
76
+ const {
77
+ height: windowHeight
78
+ } = useWindowDimensions();
79
+ const [topElementHeight, setTopElementHeight] = useState(0);
80
+ const [stickyBottomElementHeight, setStickyBottomElementHeight] = useState(0);
81
+ const [contentHeight, setContentHeight] = useState(0);
82
+ const [isScrollable, setIsScrollable] = useState(false);
83
+ const maxDynamicContentSize = Math.round(windowHeight * maxHeightNormalizedRatio) - topElementHeight;
84
+ const handleTopElementLayout = createHeightLayoutHandler(setTopElementHeight);
85
+ const handleStickyBottomElementLayout = createHeightLayoutHandler(setStickyBottomElementHeight);
50
86
 
51
87
  const handleClose = () => {
52
88
  if (onChange) {
@@ -64,9 +100,27 @@ export default function BottomSheet(props) {
64
100
  snapPoints
65
101
  });
66
102
  const translateY = highestSnapPoint - (convertedSnapPoints[index] ?? 0);
67
- const paperStyles = [styles.paper, {
68
- height: highestSnapPoint
103
+ const adjustedContentHeight = useMemo(() => {
104
+ const adjustedHighestSnapPoint = highestSnapPoint + stickyBottomElementHeight;
105
+ return Math.min(maxDynamicContentSize, adjustedHighestSnapPoint);
106
+ }, [highestSnapPoint, stickyBottomElementHeight]);
107
+ const contentStyles = [styles.paper, borderRadius ? {
108
+ borderTopLeftRadius: borderRadius,
109
+ borderTopRightRadius: borderRadius
110
+ } : {}, {
111
+ height: adjustedContentHeight,
112
+ maxHeight: maxDynamicContentSize
69
113
  }];
114
+ const headerStyles = [styles.headerContainer, isScrollable && enableScrollableHeaderBorder ? styles.headerBorder : {}];
115
+ const stickyBottomElementStyles = [styles.stickyBottomElement, isScrollable ? styles.stickyBottomElementShadow : {}];
116
+ useLayoutEffect(() => {
117
+ if (contentHeight === 0 || highestSnapPoint === 0) {
118
+ return;
119
+ }
120
+
121
+ const adjustedHighestSnapPoint = highestSnapPoint + stickyBottomElementHeight;
122
+ setIsScrollable(adjustedHighestSnapPoint > maxDynamicContentSize);
123
+ }, [contentHeight, highestSnapPoint, stickyBottomElementHeight, maxDynamicContentSize]);
70
124
  return /*#__PURE__*/React.createElement(Modal, {
71
125
  backdropOpacity: backdropOpacity,
72
126
  onClose: handleClose,
@@ -76,15 +130,26 @@ export default function BottomSheet(props) {
76
130
  style: styles.animated,
77
131
  translateY: translateY
78
132
  }, topElement ? /*#__PURE__*/React.createElement(Column, null, /*#__PURE__*/React.createElement(Column, {
133
+ onLayout: handleTopElementLayout,
79
134
  style: styles.topElementLocation
80
135
  }, topElement)) : null, /*#__PURE__*/React.createElement(Paper, {
81
- elevation: disableDefaultShadow ? 0 : 12,
82
- style: paperStyles,
83
- colorValue: disableDefaultBackgroundColor ? '#ffffff00' : undefined
136
+ elevation: 12,
137
+ style: contentStyles
84
138
  }, /*#__PURE__*/React.createElement(ScrollView, {
85
- onContentSizeChange: handleContentSizeChange,
86
- stickyHeaderIndices: header ? [0] : undefined
87
- }, header, children))));
139
+ onContentSizeChange: (contentWidth, contentHeight) => {
140
+ setContentHeight(contentHeight);
141
+ handleContentSizeChange(contentWidth, contentHeight);
142
+ },
143
+ stickyHeaderIndices: header ? [0] : undefined,
144
+ style: {
145
+ paddingBottom: stickyBottomElementHeight
146
+ }
147
+ }, header ? /*#__PURE__*/React.createElement(View, {
148
+ style: headerStyles
149
+ }, header) : null, children), stickyBottomElement ? /*#__PURE__*/React.createElement(Column, {
150
+ style: stickyBottomElementStyles,
151
+ onLayout: handleStickyBottomElementLayout
152
+ }, stickyBottomElement) : null)));
88
153
  }
89
154
  ;
90
155
  //# sourceMappingURL=BottomSheetWeb.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["React","ScrollView","Column","Modal","Paper","StyleSheet","css","useTheme","AnimatedY","useDynamicSnapPoints","useStyles","theme","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","translateY","paperStyles","height","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":"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"}
1
+ {"version":3,"names":["React","useLayoutEffect","useMemo","useState","ScrollView","useWindowDimensions","View","Column","css","Modal","Paper","StyleSheet","useElevationStyle","useTheme","AnimatedY","useDynamicSnapPoints","createHeightLayoutHandler","setHeight","event","height","nativeEvent","layout","useStyles","theme","stickyBottomElementShadow","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","topElementHeight","setTopElementHeight","stickyBottomElementHeight","setStickyBottomElementHeight","contentHeight","setContentHeight","isScrollable","setIsScrollable","maxDynamicContentSize","Math","round","handleTopElementLayout","handleStickyBottomElementLayout","handleClose","convertedSnapPoints","handleContentSizeChange","highestSnapPoint","translateY","adjustedContentHeight","adjustedHighestSnapPoint","min","contentStyles","maxHeight","headerStyles","stickyBottomElementStyles","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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"}
@@ -6,6 +6,10 @@ export default interface BottomSheetProps extends ComponentProps<{
6
6
  * @default 0.5
7
7
  */
8
8
  backdropOpacity?: number;
9
+ /**
10
+ * Border radius for bottom sheet
11
+ */
12
+ borderRadius?: number;
9
13
  /**
10
14
  * BottomSheet children, usually the included sub-components.
11
15
  */
@@ -19,6 +23,15 @@ export default interface BottomSheetProps extends ComponentProps<{
19
23
  * Area to be fixed on the top of the bottom sheet.
20
24
  */
21
25
  header?: React.ReactNode;
26
+ /**
27
+ * If set to true, a border will be applied to the header area when the bottom sheet content is scrollable.
28
+ * This visually separates the header from the scrollable content.
29
+ */
30
+ enableScrollableHeaderBorder?: boolean;
31
+ /**
32
+ * Area to be fixed on the bottom of the bottom sheet.
33
+ */
34
+ stickyBottomElement?: React.ReactNode;
22
35
  /**
23
36
  * Top element for displaying additional information on the bottom sheet.
24
37
  */
@@ -45,15 +58,5 @@ export default interface BottomSheetProps extends ComponentProps<{
45
58
  * @default []
46
59
  */
47
60
  snapPoints?: Array<number | string>;
48
- /**
49
- * Disable default backgroundColor.
50
- * @default false
51
- */
52
- disableDefaultBackgroundColor?: boolean;
53
- /**
54
- * Disable default shadow.
55
- * @default false
56
- */
57
- disableDefaultShadow?: boolean;
58
61
  }> {
59
62
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fountain-ui/lab",
3
- "version": "2.0.0-beta.82",
3
+ "version": "2.0.0-beta.84",
4
4
  "private": false,
5
5
  "author": "Fountain-UI Team",
6
6
  "description": "Incubator for Fountain-UI React components.",
@@ -70,5 +70,5 @@
70
70
  "publishConfig": {
71
71
  "access": "public"
72
72
  },
73
- "gitHead": "43b797c06d530dd485c786adcfcef99dc042de26"
73
+ "gitHead": "c217ad3db355cdbbf38cab98f8befcb584917a3b"
74
74
  }
@@ -1,39 +1,56 @@
1
1
  import React from 'react';
2
- import { Animated, Platform, useWindowDimensions, View } from 'react-native';
3
- import { Column, useAnimatedValue, ExtendedStyle, isNotAndroid12 } from '@fountain-ui/core';
4
- import { useTheme } from '@fountain-ui/styles';
2
+ import { Animated, LayoutChangeEvent, Platform, useWindowDimensions, View, ViewStyle } from 'react-native';
5
3
  import {
6
4
  BottomSheetBackdrop,
7
5
  BottomSheetBackdropProps,
6
+ BottomSheetFooter,
7
+ BottomSheetFooterProps,
8
8
  BottomSheetModal,
9
9
  BottomSheetModalProvider,
10
10
  BottomSheetScrollView,
11
11
  } from '@gorhom/bottom-sheet';
12
+ import { Column, ExtendedStyle, isNotAndroid12, useAnimatedValue, useElevationStyle } from '@fountain-ui/core';
13
+ import { useTheme } from '@fountain-ui/styles';
12
14
  import type BottomSheetProps from './BottomSheetProps';
13
15
  import TransparentBackdrop from './TransparentBackdrop';
14
16
 
15
17
  const NoHandle = () => null;
16
18
 
19
+ const createHeightLayoutHandler = (setHeight: React.Dispatch<React.SetStateAction<number>>) => {
20
+ return (event: LayoutChangeEvent) => {
21
+ const { height } = event.nativeEvent.layout;
22
+ setHeight(height);
23
+ };
24
+ }
25
+
17
26
  export default function BottomSheet(props: BottomSheetProps) {
18
27
  const {
19
28
  backdropOpacity = 0.5,
29
+ borderRadius: borderRadiusProp,
20
30
  children,
21
31
  enableDynamicSizing = true,
22
32
  header,
33
+ stickyBottomElement,
23
34
  topElement,
24
35
  index,
25
36
  maxHeightNormalizedRatio = 0.9,
26
37
  onChange,
27
38
  snapPoints = [],
28
- disableDefaultBackgroundColor = false,
29
- disableDefaultShadow = false,
39
+ enableScrollableHeaderBorder = false,
30
40
  } = props;
31
41
 
32
42
  const indexRef = React.useRef<number>(-1);
33
43
  const bottomSheetRef = React.useRef<BottomSheetModal | null>(null);
34
44
 
35
45
  const { height: windowHeight } = useWindowDimensions();
36
- const maxDynamicContentSize = Math.round(windowHeight * maxHeightNormalizedRatio);
46
+ const [isScrollable, setIsScrollable] = React.useState(false);
47
+ const [topElementHeight, setTopElementHeight] = React.useState(0);
48
+ const [stickyBottomElementHeight, setStickyBottomElementHeight] = React.useState(0);
49
+
50
+ const maxDynamicContentSize = Math.round(windowHeight * maxHeightNormalizedRatio) - topElementHeight;
51
+
52
+ const handleTopElementLayout = createHeightLayoutHandler(setTopElementHeight);
53
+ const handleStickyBottomElementLayout = createHeightLayoutHandler(setStickyBottomElementHeight);
37
54
 
38
55
  const handleChange = React.useCallback((newIndex: number) => {
39
56
  indexRef.current = newIndex;
@@ -64,25 +81,27 @@ export default function BottomSheet(props: BottomSheetProps) {
64
81
 
65
82
  const theme = useTheme();
66
83
  const shadow = theme.shadow[12];
84
+ const borderRadius = borderRadiusProp ?? theme.shape.roundnessExtra;
67
85
  const modalStyle = {
68
86
  backgroundColor: '#ffffff00',
69
- borderTopLeftRadius: theme.shape.roundnessExtra,
70
- borderTopRightRadius: theme.shape.roundnessExtra,
71
- ...(disableDefaultShadow ? {} : Platform.select<object>({
87
+ borderTopLeftRadius: borderRadius,
88
+ borderTopRightRadius: borderRadius,
89
+ ...Platform.select<object>({
72
90
  android: shadow?.elevation,
73
91
  ios: shadow?.shadow,
74
92
  web: shadow?.boxShadow,
75
- })),
93
+ }),
76
94
  };
95
+ const backgroundColor = theme.palette.paper.default;
77
96
  const backgroundStyle = {
78
- backgroundColor: disableDefaultBackgroundColor ? '#ffffff00' : theme.palette.paper.default,
79
- borderTopLeftRadius: theme.shape.roundnessExtra,
80
- borderTopRightRadius: theme.shape.roundnessExtra,
97
+ backgroundColor,
98
+ borderTopLeftRadius: borderRadius,
99
+ borderTopRightRadius: borderRadius,
81
100
  };
82
- const contentWrapperStyle = {
101
+ const contentWrapperStyle: ViewStyle = {
83
102
  flex: 1,
84
- borderTopLeftRadius: theme.shape.roundnessExtra,
85
- borderTopRightRadius: theme.shape.roundnessExtra,
103
+ borderTopLeftRadius: borderRadius,
104
+ borderTopRightRadius: borderRadius,
86
105
  overflow: 'hidden',
87
106
  };
88
107
 
@@ -115,6 +134,41 @@ export default function BottomSheet(props: BottomSheetProps) {
115
134
  }).start();
116
135
  };
117
136
 
137
+ const handleContentSizeChange = (_: number, contentHeight: number) => {
138
+ setIsScrollable(contentHeight > maxDynamicContentSize);
139
+ };
140
+
141
+ const headerStyle = {
142
+ backgroundColor,
143
+ ...(isScrollable && enableScrollableHeaderBorder ? {
144
+ borderBottomWidth: 0.5,
145
+ borderBottomColor: theme.palette.divider,
146
+ }: {})
147
+ }
148
+
149
+ const childrenStyle = {
150
+ backgroundColor,
151
+ paddingBottom: stickyBottomElementHeight,
152
+ }
153
+
154
+ const stickyBottomElementShadow = useElevationStyle(8);
155
+
156
+ const stickyBottomElementStyle = {
157
+ backgroundColor: theme.palette.paper.default,
158
+ ...(isScrollable ? stickyBottomElementShadow : {}),
159
+ }
160
+
161
+ const renderFooter = (props: BottomSheetFooterProps) => (
162
+ <BottomSheetFooter {...props}>
163
+ <View
164
+ onLayout={handleStickyBottomElementLayout}
165
+ style={stickyBottomElementStyle}
166
+ >
167
+ {stickyBottomElement}
168
+ </View>
169
+ </BottomSheetFooter>
170
+ );
171
+
118
172
  return (
119
173
  <BottomSheetModalProvider>
120
174
  <BottomSheetModal
@@ -133,24 +187,32 @@ export default function BottomSheet(props: BottomSheetProps) {
133
187
  maxDynamicContentSize={maxDynamicContentSize}
134
188
  detached={Boolean(topElement)}
135
189
  onAnimate={topElement ? onAnimate : undefined}
190
+ footerComponent={stickyBottomElement ? renderFooter : undefined}
136
191
  >
137
192
  {topElement ? (
138
193
  <Animated.View style={topElementAnimationStyle}>
139
- <Column style={topElementLocationStyle}>
194
+ <Column
195
+ onLayout={handleTopElementLayout}
196
+ style={topElementLocationStyle}
197
+ >
140
198
  {topElement}
141
199
  </Column>
142
200
  </Animated.View>
143
201
  ) : null}
144
202
 
145
- {/* @ts-ignore */}
146
203
  <View style={contentWrapperStyle}>
147
204
  <BottomSheetScrollView
148
205
  bounces={false}
149
206
  stickyHeaderIndices={header ? [0] : undefined}
207
+ onContentSizeChange={handleContentSizeChange}
150
208
  >
151
- {header}
209
+ <View style={headerStyle}>
210
+ {header}
211
+ </View>
152
212
 
153
- {children}
213
+ <View style={childrenStyle}>
214
+ {children}
215
+ </View>
154
216
  </BottomSheetScrollView>
155
217
  </View>
156
218
  </BottomSheetModal>
@@ -8,6 +8,11 @@ export default interface BottomSheetProps extends ComponentProps<{
8
8
  */
9
9
  backdropOpacity?: number;
10
10
 
11
+ /**
12
+ * Border radius for bottom sheet
13
+ */
14
+ borderRadius?: number;
15
+
11
16
  /**
12
17
  * BottomSheet children, usually the included sub-components.
13
18
  */
@@ -24,6 +29,17 @@ export default interface BottomSheetProps extends ComponentProps<{
24
29
  */
25
30
  header?: React.ReactNode;
26
31
 
32
+ /**
33
+ * If set to true, a border will be applied to the header area when the bottom sheet content is scrollable.
34
+ * This visually separates the header from the scrollable content.
35
+ */
36
+ enableScrollableHeaderBorder?: boolean;
37
+
38
+ /**
39
+ * Area to be fixed on the bottom of the bottom sheet.
40
+ */
41
+ stickyBottomElement?: React.ReactNode;
42
+
27
43
  /**
28
44
  * Top element for displaying additional information on the bottom sheet.
29
45
  */
@@ -54,16 +70,4 @@ export default interface BottomSheetProps extends ComponentProps<{
54
70
  * @default []
55
71
  */
56
72
  snapPoints?: Array<number | string>;
57
-
58
- /**
59
- * Disable default backgroundColor.
60
- * @default false
61
- */
62
- disableDefaultBackgroundColor?: boolean;
63
-
64
- /**
65
- * Disable default shadow.
66
- * @default false
67
- */
68
- disableDefaultShadow?: boolean;
69
73
  }> {}