@fountain-ui/lab 3.0.0-alpha.2 → 3.0.0-alpha.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/commonjs/AnimatedY/AnimatedY.js +1 -1
- package/build/commonjs/AnimatedY/AnimatedY.js.map +1 -1
- package/build/commonjs/BottomSheet/BottomSheetNative.js +39 -12
- package/build/commonjs/BottomSheet/BottomSheetNative.js.map +1 -1
- package/build/commonjs/BottomSheet/BottomSheetProps.js.map +1 -1
- package/build/commonjs/BottomSheet/BottomSheetWeb.js +15 -9
- package/build/commonjs/BottomSheet/BottomSheetWeb.js.map +1 -1
- package/build/commonjs/BottomSheet/useDynamicSnapPoints.js +1 -7
- package/build/commonjs/BottomSheet/useDynamicSnapPoints.js.map +1 -1
- package/build/commonjs/BottomSheet/useDynamicSnapPoints.native.js +22 -0
- package/build/commonjs/BottomSheet/useDynamicSnapPoints.native.js.map +1 -0
- package/build/commonjs/Carousel/Carousel.js +4 -2
- package/build/commonjs/Carousel/Carousel.js.map +1 -1
- package/build/commonjs/Carousel/CarouselProps.js.map +1 -1
- package/build/commonjs/Carousel/components/InternalContext.js +2 -1
- package/build/commonjs/Carousel/components/InternalContext.js.map +1 -1
- package/build/commonjs/Carousel/components/ItemView.js +3 -1
- package/build/commonjs/Carousel/components/ItemView.js.map +1 -1
- package/build/commonjs/ComicViewer/FastScroll.js +9 -11
- package/build/commonjs/ComicViewer/FastScroll.js.map +1 -1
- package/build/commonjs/FlipCard/FlipCard.js +2 -2
- package/build/commonjs/FlipCard/FlipCard.js.map +1 -1
- package/build/commonjs/StatusBarProvider/StatusBarProvider.js +1 -1
- package/build/commonjs/StatusBarProvider/StatusBarProvider.js.map +1 -1
- package/build/commonjs/hooks/useUnstableCollapsibleAppBar.js +2 -6
- package/build/commonjs/hooks/useUnstableCollapsibleAppBar.js.map +1 -1
- package/build/commonjs/hooks/useUnstableToggleDisplayStyle.js +1 -1
- package/build/commonjs/hooks/useUnstableToggleDisplayStyle.js.map +1 -1
- package/build/module/AnimatedY/AnimatedY.js +1 -1
- package/build/module/AnimatedY/AnimatedY.js.map +1 -1
- package/build/module/BottomSheet/BottomSheetNative.js +37 -13
- package/build/module/BottomSheet/BottomSheetNative.js.map +1 -1
- package/build/module/BottomSheet/BottomSheetProps.js.map +1 -1
- package/build/module/BottomSheet/BottomSheetWeb.js +14 -9
- package/build/module/BottomSheet/BottomSheetWeb.js.map +1 -1
- package/build/module/BottomSheet/useDynamicSnapPoints.js +2 -8
- package/build/module/BottomSheet/useDynamicSnapPoints.js.map +1 -1
- package/build/module/BottomSheet/useDynamicSnapPoints.native.js +14 -0
- package/build/module/BottomSheet/useDynamicSnapPoints.native.js.map +1 -0
- package/build/module/Carousel/Carousel.js +4 -2
- package/build/module/Carousel/Carousel.js.map +1 -1
- package/build/module/Carousel/CarouselProps.js.map +1 -1
- package/build/module/Carousel/components/InternalContext.js +2 -1
- package/build/module/Carousel/components/InternalContext.js.map +1 -1
- package/build/module/Carousel/components/ItemView.js +3 -1
- package/build/module/Carousel/components/ItemView.js.map +1 -1
- package/build/module/ComicViewer/FastScroll.js +6 -9
- package/build/module/ComicViewer/FastScroll.js.map +1 -1
- package/build/module/FlipCard/FlipCard.js +2 -2
- package/build/module/FlipCard/FlipCard.js.map +1 -1
- package/build/module/StatusBarProvider/StatusBarProvider.js +1 -1
- package/build/module/StatusBarProvider/StatusBarProvider.js.map +1 -1
- package/build/module/hooks/useUnstableCollapsibleAppBar.js +2 -6
- package/build/module/hooks/useUnstableCollapsibleAppBar.js.map +1 -1
- package/build/module/hooks/useUnstableToggleDisplayStyle.js +1 -1
- package/build/module/hooks/useUnstableToggleDisplayStyle.js.map +1 -1
- package/build/typescript/BottomSheet/BottomSheetProps.d.ts +9 -1
- package/build/typescript/BottomSheet/useDynamicSnapPoints.native.d.ts +21 -0
- package/build/typescript/Carousel/Carousel.d.ts +1 -1
- package/build/typescript/Carousel/CarouselProps.d.ts +7 -0
- package/build/typescript/Carousel/components/InternalContext.d.ts +1 -0
- package/package.json +5 -4
- package/src/AnimatedY/AnimatedY.tsx +1 -1
- package/src/BottomSheet/BottomSheetNative.tsx +51 -18
- package/src/BottomSheet/BottomSheetProps.ts +11 -1
- package/src/BottomSheet/BottomSheetWeb.tsx +15 -7
- package/src/BottomSheet/useDynamicSnapPoints.native.ts +15 -0
- package/src/BottomSheet/useDynamicSnapPoints.ts +2 -9
- package/src/Carousel/Carousel.tsx +3 -0
- package/src/Carousel/CarouselProps.ts +8 -0
- package/src/Carousel/components/InternalContext.ts +2 -0
- package/src/Carousel/components/ItemView.tsx +2 -0
- package/src/ComicViewer/FastScroll.tsx +7 -13
- package/src/FlipCard/FlipCard.tsx +2 -2
- package/src/StatusBarProvider/StatusBarProvider.tsx +2 -2
- package/src/hooks/useUnstableCollapsibleAppBar.ts +2 -6
- package/src/hooks/useUnstableToggleDisplayStyle.ts +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["useCallback","useRef","Platform","useAnimatedScrollHandler","useAnimatedStyle","useDerivedValue","useSharedValue","withTiming","useSafeAreaInsets","useAppbarStyles","useElevationStyle","useHeight","defaultOptions","shouldTranslateYReset","ANIMATION_DURATION_MILLIS","SUPPORTS_DRAG_DETECTION","OS","useLargerValueOfLastTwoValues","value","refLatestTwoValues","current","shift","push","Math","max","useUnstableCollapsibleAppBar","userOptions","styles","safeAreaInsets","appBarHeight","onAppBarLayout","appBarMaxHeight","collapsibleToolbarHeight","onCollapsibleToolbarLayout","maxTranslateY","translateY","lastTranslateY","lastOffsetY","prevOffsetY","overlapped","vectorY","elevationStyle","animatedStyle","transform","boxShadow","elevation","shadowColor","shadowOffset","shadowRadius","shadowOpacity","indexRef","offsetsRef","onScrollViewChanged","nextIndex","prevIndex","duration","savedOffsetY","scrollHandler","onBeginDrag","onMomentumBegin","onScroll","event","offsetY","contentOffset","y","ty","maxTy","deltaY","dy","min","onEndDrag","onMomentumEnd","threshold","nextTranslateY","hasCollapsible","appBarStyle","paddingTop","top","floating","undefined","scrollContentInsets"],"sources":["useUnstableCollapsibleAppBar.ts"],"sourcesContent":["import { useCallback, useRef } from 'react';\nimport { Falsy, Platform, RegisteredStyle, ScrollViewProps, ViewProps, ViewStyle } from 'react-native';\nimport type { SharedValue } from 'react-native-reanimated';\nimport {\n useAnimatedScrollHandler,\n useAnimatedStyle,\n useDerivedValue,\n useSharedValue,\n withTiming,\n} from 'react-native-reanimated';\nimport { useSafeAreaInsets } from 'react-native-safe-area-context';\nimport useAppbarStyles from './useAppbarStyles';\nimport useElevationStyle from './useElevationStyle';\nimport useHeight from './useHeight';\n\ntype WebOnlyStyle = { boxShadow: any };\n\ntype ViewStyleProp = Array<ViewStyle | RegisteredStyle<ViewStyle> | WebOnlyStyle | Falsy>;\n\ntype OnScroll = ScrollViewProps['onScroll'];\n\ntype OnLayoutCallback = ViewProps['onLayout'];\n\nexport interface ContentInsets {\n top?: number;\n bottom?: number;\n left?: number;\n right?: number;\n}\n\nexport interface Options {\n shouldTranslateYReset?: boolean;\n}\n\nexport interface CollapsibleAppBar {\n appBarStyle: ViewStyleProp;\n vectorY: SharedValue<number>;\n onAppBarLayout: OnLayoutCallback;\n onCollapsibleToolbarLayout: OnLayoutCallback;\n onScroll: OnScroll;\n onScrollViewChanged: (index: number) => void;\n scrollContentInsets: ContentInsets;\n}\n\nconst defaultOptions: Required<Options> = {\n shouldTranslateYReset: false,\n};\n\nconst ANIMATION_DURATION_MILLIS = 100;\n\nconst SUPPORTS_DRAG_DETECTION = Platform.OS !== 'web';\n\nfunction useLargerValueOfLastTwoValues(value: number) {\n const refLatestTwoValues = useRef([0, 0]);\n\n refLatestTwoValues.current.shift();\n refLatestTwoValues.current.push(value);\n\n return Math.max(...refLatestTwoValues.current);\n}\n\nexport default function useUnstableCollapsibleAppBar(userOptions: Options = defaultOptions): CollapsibleAppBar {\n const { shouldTranslateYReset }: Required<Options> = {\n ...defaultOptions,\n ...userOptions,\n };\n\n const styles = useAppbarStyles();\n\n const safeAreaInsets = useSafeAreaInsets();\n\n const [appBarHeight, onAppBarLayout] = useHeight();\n const appBarMaxHeight = useLargerValueOfLastTwoValues(appBarHeight);\n const [collapsibleToolbarHeight, onCollapsibleToolbarLayout] = useHeight();\n\n const maxTranslateY = useDerivedValue(() => -collapsibleToolbarHeight, [collapsibleToolbarHeight]);\n\n const translateY = useSharedValue<number>(0);\n const lastTranslateY = useSharedValue<number>(0);\n const lastOffsetY = useSharedValue<number>(0);\n const prevOffsetY = useSharedValue<number>(0);\n const overlapped = useSharedValue<boolean>(false);\n const vectorY = useSharedValue<number>(0);\n\n const elevationStyle = useElevationStyle(4);\n const animatedStyle = useAnimatedStyle(() => {\n const transform = [{ translateY: translateY.value }];\n\n if (Platform.OS === 'web') {\n return {\n transform,\n boxShadow: overlapped.value ? elevationStyle?.boxShadow : 0,\n };\n }\n if (Platform.OS === 'android') {\n return {\n transform,\n elevation: overlapped.value ? elevationStyle?.elevation : 0,\n };\n }\n if (Platform.OS === 'ios') {\n return {\n transform,\n shadowColor: elevationStyle?.shadowColor,\n shadowOffset: elevationStyle?.shadowOffset,\n shadowRadius: elevationStyle?.shadowRadius,\n shadowOpacity: overlapped.value ? elevationStyle?.shadowOpacity : 0,\n };\n }\n return {};\n }, [\n /**\n * FIXME: Consider add `elevationStyle` to dependencies.\n */\n ]);\n\n const indexRef = useRef<number>(0);\n const offsetsRef = useRef<Array<number>>([]);\n\n const onScrollViewChanged = useCallback((nextIndex: number) => {\n const prevIndex = indexRef.current;\n if (prevIndex === nextIndex) {\n if (shouldTranslateYReset) {\n translateY.value = withTiming(0, {\n duration: ANIMATION_DURATION_MILLIS,\n });\n\n vectorY.value = 0;\n offsetsRef.current = [];\n overlapped.value = false;\n }\n\n return;\n }\n\n offsetsRef.current[prevIndex] = lastOffsetY.value;\n\n const savedOffsetY = offsetsRef.current[nextIndex] ?? 0;\n lastOffsetY.value = savedOffsetY;\n\n indexRef.current = nextIndex;\n\n // Determine whether to overlap every time index is changed.\n overlapped.value = savedOffsetY > 0;\n\n // If next ScrollView's offset is too short, expand app bar.\n if (translateY.value < 0 && savedOffsetY < appBarHeight) {\n translateY.value = withTiming(0, {\n duration: ANIMATION_DURATION_MILLIS,\n });\n\n vectorY.value = 0;\n }\n }, [appBarHeight]);\n\n const scrollHandler = useAnimatedScrollHandler({\n onBeginDrag: () => {\n lastTranslateY.value = translateY.value;\n },\n onMomentumBegin: () => {\n lastTranslateY.value = translateY.value;\n },\n onScroll: (event) => {\n const offsetY = event.contentOffset.y;\n\n const ty = translateY.value;\n const maxTy = maxTranslateY.value;\n\n const deltaY = offsetY - prevOffsetY.value;\n vectorY.value = (vectorY.value * deltaY >= 0 && offsetY > 0) ? vectorY.value + deltaY : deltaY;\n prevOffsetY.value = offsetY;\n\n if (SUPPORTS_DRAG_DETECTION) {\n const dy = offsetY - lastOffsetY.value;\n\n translateY.value = offsetY <= 0 ? 0 : Math.min(Math.max(lastTranslateY.value - dy, maxTy), 0);\n\n overlapped.value = offsetY + translateY.value > 0;\n } else {\n if (offsetY > -maxTy) {\n if (ty === 0) {\n translateY.value = withTiming(Math.min(Math.max(-offsetY, maxTy), 0), {\n duration: ANIMATION_DURATION_MILLIS,\n });\n }\n } else {\n if (ty === maxTy) {\n translateY.value = withTiming(0, {\n duration: ANIMATION_DURATION_MILLIS,\n });\n }\n }\n\n overlapped.value = offsetY > 0;\n\n lastOffsetY.value = offsetY;\n }\n },\n onEndDrag: (event) => {\n lastOffsetY.value = event.contentOffset.y;\n },\n onMomentumEnd: (event) => {\n const offsetY = event.contentOffset.y;\n\n lastOffsetY.value = offsetY;\n\n const ty = translateY.value;\n const maxTy = maxTranslateY.value;\n\n // If toolbar is already positioned on edge, do nothing.\n if (ty <= maxTy || ty >= 0) {\n return;\n }\n\n const threshold = maxTy * 0.5;\n\n const nextTranslateY = (ty > threshold || offsetY < appBarHeight) ? 0 : maxTy;\n\n overlapped.value = offsetY + nextTranslateY > 0;\n\n translateY.value = withTiming(nextTranslateY, {\n duration: ANIMATION_DURATION_MILLIS,\n });\n },\n }, [appBarHeight]);\n\n const hasCollapsible = collapsibleToolbarHeight > 0;\n\n const appBarStyle = [\n animatedStyle,\n { paddingTop: safeAreaInsets.top },\n hasCollapsible ? styles.floating : undefined,\n ];\n\n return {\n appBarStyle,\n vectorY,\n onAppBarLayout,\n onCollapsibleToolbarLayout,\n onScroll: scrollHandler,\n onScrollViewChanged,\n scrollContentInsets: { top: hasCollapsible ? appBarMaxHeight : 0 },\n };\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"names":["useCallback","useRef","Platform","useAnimatedScrollHandler","useAnimatedStyle","useDerivedValue","useSharedValue","withTiming","useSafeAreaInsets","useAppbarStyles","useElevationStyle","useHeight","defaultOptions","shouldTranslateYReset","ANIMATION_DURATION_MILLIS","SUPPORTS_DRAG_DETECTION","OS","useLargerValueOfLastTwoValues","value","refLatestTwoValues","current","shift","push","Math","max","useUnstableCollapsibleAppBar","userOptions","styles","safeAreaInsets","appBarHeight","onAppBarLayout","appBarMaxHeight","collapsibleToolbarHeight","onCollapsibleToolbarLayout","maxTranslateY","translateY","lastTranslateY","lastOffsetY","prevOffsetY","overlapped","vectorY","elevationStyle","animatedStyle","transform","boxShadow","elevation","shadowColor","shadowOffset","shadowRadius","shadowOpacity","indexRef","offsetsRef","onScrollViewChanged","nextIndex","prevIndex","duration","savedOffsetY","scrollHandler","onBeginDrag","onMomentumBegin","onScroll","event","offsetY","contentOffset","y","ty","maxTy","deltaY","dy","min","onEndDrag","onMomentumEnd","threshold","nextTranslateY","hasCollapsible","appBarStyle","paddingTop","top","floating","undefined","scrollContentInsets"],"sources":["useUnstableCollapsibleAppBar.ts"],"sourcesContent":["import { useCallback, useRef } from 'react';\nimport { Falsy, Platform, RegisteredStyle, ScrollViewProps, ViewProps, ViewStyle } from 'react-native';\nimport type { SharedValue } from 'react-native-reanimated';\nimport {\n useAnimatedScrollHandler,\n useAnimatedStyle,\n useDerivedValue,\n useSharedValue,\n withTiming,\n} from 'react-native-reanimated';\nimport { useSafeAreaInsets } from 'react-native-safe-area-context';\nimport useAppbarStyles from './useAppbarStyles';\nimport useElevationStyle from './useElevationStyle';\nimport useHeight from './useHeight';\n\ntype WebOnlyStyle = { boxShadow: any };\n\ntype ViewStyleProp = Array<ViewStyle | RegisteredStyle<ViewStyle> | WebOnlyStyle | Falsy>;\n\ntype OnScroll = ScrollViewProps['onScroll'];\n\ntype OnLayoutCallback = ViewProps['onLayout'];\n\nexport interface ContentInsets {\n top?: number;\n bottom?: number;\n left?: number;\n right?: number;\n}\n\nexport interface Options {\n shouldTranslateYReset?: boolean;\n}\n\nexport interface CollapsibleAppBar {\n appBarStyle: ViewStyleProp;\n vectorY: SharedValue<number>;\n onAppBarLayout: OnLayoutCallback;\n onCollapsibleToolbarLayout: OnLayoutCallback;\n onScroll: OnScroll;\n onScrollViewChanged: (index: number) => void;\n scrollContentInsets: ContentInsets;\n}\n\nconst defaultOptions: Required<Options> = {\n shouldTranslateYReset: false,\n};\n\nconst ANIMATION_DURATION_MILLIS = 100;\n\nconst SUPPORTS_DRAG_DETECTION = Platform.OS !== 'web';\n\nfunction useLargerValueOfLastTwoValues(value: number) {\n const refLatestTwoValues = useRef([0, 0]);\n\n refLatestTwoValues.current.shift();\n refLatestTwoValues.current.push(value);\n\n return Math.max(...refLatestTwoValues.current);\n}\n\nexport default function useUnstableCollapsibleAppBar(userOptions: Options = defaultOptions): CollapsibleAppBar {\n const { shouldTranslateYReset }: Required<Options> = {\n ...defaultOptions,\n ...userOptions,\n };\n\n const styles = useAppbarStyles();\n\n const safeAreaInsets = useSafeAreaInsets();\n\n const [appBarHeight, onAppBarLayout] = useHeight();\n const appBarMaxHeight = useLargerValueOfLastTwoValues(appBarHeight);\n const [collapsibleToolbarHeight, onCollapsibleToolbarLayout] = useHeight();\n\n const maxTranslateY = useDerivedValue(() => -collapsibleToolbarHeight, [collapsibleToolbarHeight]);\n\n const translateY = useSharedValue<number>(0);\n const lastTranslateY = useSharedValue<number>(0);\n const lastOffsetY = useSharedValue<number>(0);\n const prevOffsetY = useSharedValue<number>(0);\n const overlapped = useSharedValue<boolean>(false);\n const vectorY = useSharedValue<number>(0);\n\n const elevationStyle = useElevationStyle(4);\n const animatedStyle = useAnimatedStyle(() => {\n const transform = [{ translateY: translateY.value }];\n\n if (Platform.OS === 'web') {\n return {\n transform,\n boxShadow: overlapped.value ? elevationStyle?.boxShadow : 0,\n };\n }\n if (Platform.OS === 'android') {\n return {\n transform,\n elevation: overlapped.value ? elevationStyle?.elevation : 0,\n };\n }\n if (Platform.OS === 'ios') {\n return {\n transform,\n shadowColor: elevationStyle?.shadowColor,\n shadowOffset: elevationStyle?.shadowOffset,\n shadowRadius: elevationStyle?.shadowRadius,\n shadowOpacity: overlapped.value ? elevationStyle?.shadowOpacity : 0,\n };\n }\n return {};\n }, [translateY, overlapped, elevationStyle]);\n\n const indexRef = useRef<number>(0);\n const offsetsRef = useRef<Array<number>>([]);\n\n const onScrollViewChanged = useCallback((nextIndex: number) => {\n const prevIndex = indexRef.current;\n if (prevIndex === nextIndex) {\n if (shouldTranslateYReset) {\n translateY.value = withTiming(0, {\n duration: ANIMATION_DURATION_MILLIS,\n });\n\n vectorY.value = 0;\n offsetsRef.current = [];\n overlapped.value = false;\n }\n\n return;\n }\n\n offsetsRef.current[prevIndex] = lastOffsetY.value;\n\n const savedOffsetY = offsetsRef.current[nextIndex] ?? 0;\n lastOffsetY.value = savedOffsetY;\n\n indexRef.current = nextIndex;\n\n // Determine whether to overlap every time index is changed.\n overlapped.value = savedOffsetY > 0;\n\n // If next ScrollView's offset is too short, expand app bar.\n if (translateY.value < 0 && savedOffsetY < appBarHeight) {\n translateY.value = withTiming(0, {\n duration: ANIMATION_DURATION_MILLIS,\n });\n\n vectorY.value = 0;\n }\n }, [appBarHeight]);\n\n const scrollHandler = useAnimatedScrollHandler({\n onBeginDrag: () => {\n lastTranslateY.value = translateY.value;\n },\n onMomentumBegin: () => {\n lastTranslateY.value = translateY.value;\n },\n onScroll: (event) => {\n const offsetY = event.contentOffset.y;\n\n const ty = translateY.value;\n const maxTy = maxTranslateY.value;\n\n const deltaY = offsetY - prevOffsetY.value;\n vectorY.value = (vectorY.value * deltaY >= 0 && offsetY > 0) ? vectorY.value + deltaY : deltaY;\n prevOffsetY.value = offsetY;\n\n if (SUPPORTS_DRAG_DETECTION) {\n const dy = offsetY - lastOffsetY.value;\n\n translateY.value = offsetY <= 0 ? 0 : Math.min(Math.max(lastTranslateY.value - dy, maxTy), 0);\n\n overlapped.value = offsetY + translateY.value > 0;\n } else {\n if (offsetY > -maxTy) {\n if (ty === 0) {\n translateY.value = withTiming(Math.min(Math.max(-offsetY, maxTy), 0), {\n duration: ANIMATION_DURATION_MILLIS,\n });\n }\n } else {\n if (ty === maxTy) {\n translateY.value = withTiming(0, {\n duration: ANIMATION_DURATION_MILLIS,\n });\n }\n }\n\n overlapped.value = offsetY > 0;\n\n lastOffsetY.value = offsetY;\n }\n },\n onEndDrag: (event) => {\n lastOffsetY.value = event.contentOffset.y;\n },\n onMomentumEnd: (event) => {\n const offsetY = event.contentOffset.y;\n\n lastOffsetY.value = offsetY;\n\n const ty = translateY.value;\n const maxTy = maxTranslateY.value;\n\n // If toolbar is already positioned on edge, do nothing.\n if (ty <= maxTy || ty >= 0) {\n return;\n }\n\n const threshold = maxTy * 0.5;\n\n const nextTranslateY = (ty > threshold || offsetY < appBarHeight) ? 0 : maxTy;\n\n overlapped.value = offsetY + nextTranslateY > 0;\n\n translateY.value = withTiming(nextTranslateY, {\n duration: ANIMATION_DURATION_MILLIS,\n });\n },\n });\n\n const hasCollapsible = collapsibleToolbarHeight > 0;\n\n const appBarStyle = [\n animatedStyle,\n { paddingTop: safeAreaInsets.top },\n hasCollapsible ? styles.floating : undefined,\n ];\n\n return {\n appBarStyle,\n vectorY,\n onAppBarLayout,\n onCollapsibleToolbarLayout,\n onScroll: scrollHandler,\n onScrollViewChanged,\n scrollContentInsets: { top: hasCollapsible ? appBarMaxHeight : 0 },\n };\n};\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["useAnimatedReaction","useAnimatedStyle","useSharedValue","useAnimatedDisplayStyle","vectorY","threshold","defaultDisplay","display","value","vy"],"sources":["useUnstableToggleDisplayStyle.ts"],"sourcesContent":["import type { SharedValue } from 'react-native-reanimated';\nimport { useAnimatedReaction, useAnimatedStyle, useSharedValue } from 'react-native-reanimated';\n\nexport default function useAnimatedDisplayStyle(\n vectorY: SharedValue<number>,\n threshold: number = 200,\n defaultDisplay: 'flex' | 'none' = 'flex',\n) {\n const display = useSharedValue(defaultDisplay);\n\n useAnimatedReaction(\n () => vectorY.value,\n (vy) => {\n if (vy >= threshold) {\n display.value = 'none';\n } else if (vy < threshold) {\n display.value = 'flex';\n }\n },\n [threshold],\n );\n\n return useAnimatedStyle(() => ({\n display: display.value,\n }), []);\n};\n"],"mappings":"AACA,SAASA,mBAAT,EAA8BC,gBAA9B,EAAgDC,cAAhD,QAAsE,yBAAtE;AAEA,eAAe,SAASC,uBAAT,CACXC,OADW,EAIb;EAAA,IAFEC,SAEF,uEAFsB,GAEtB;EAAA,IADEC,cACF,uEADoC,MACpC;EACE,MAAMC,OAAO,GAAGL,cAAc,CAACI,cAAD,CAA9B;EAEAN,mBAAmB,CACf,MAAMI,OAAO,CAACI,KADC,EAEdC,EAAD,IAAQ;IACJ,IAAIA,EAAE,IAAIJ,SAAV,EAAqB;MACjBE,OAAO,CAACC,KAAR,GAAgB,MAAhB;IACH,CAFD,MAEO,IAAIC,EAAE,GAAGJ,SAAT,EAAoB;MACvBE,OAAO,CAACC,KAAR,GAAgB,MAAhB;IACH;EACJ,CARc,EASf,CAACH,SAAD,CATe,CAAnB;EAYA,OAAOJ,gBAAgB,CAAC,OAAO;IAC3BM,OAAO,EAAEA,OAAO,CAACC;EADU,CAAP,CAAD,EAEnB,
|
|
1
|
+
{"version":3,"names":["useAnimatedReaction","useAnimatedStyle","useSharedValue","useAnimatedDisplayStyle","vectorY","threshold","defaultDisplay","display","value","vy"],"sources":["useUnstableToggleDisplayStyle.ts"],"sourcesContent":["import type { SharedValue } from 'react-native-reanimated';\nimport { useAnimatedReaction, useAnimatedStyle, useSharedValue } from 'react-native-reanimated';\n\nexport default function useAnimatedDisplayStyle(\n vectorY: SharedValue<number>,\n threshold: number = 200,\n defaultDisplay: 'flex' | 'none' = 'flex',\n) {\n const display = useSharedValue(defaultDisplay);\n\n useAnimatedReaction(\n () => vectorY.value,\n (vy) => {\n if (vy >= threshold) {\n display.value = 'none';\n } else if (vy < threshold) {\n display.value = 'flex';\n }\n },\n [threshold],\n );\n\n return useAnimatedStyle(() => ({\n display: display.value,\n }), [display]);\n};\n"],"mappings":"AACA,SAASA,mBAAT,EAA8BC,gBAA9B,EAAgDC,cAAhD,QAAsE,yBAAtE;AAEA,eAAe,SAASC,uBAAT,CACXC,OADW,EAIb;EAAA,IAFEC,SAEF,uEAFsB,GAEtB;EAAA,IADEC,cACF,uEADoC,MACpC;EACE,MAAMC,OAAO,GAAGL,cAAc,CAACI,cAAD,CAA9B;EAEAN,mBAAmB,CACf,MAAMI,OAAO,CAACI,KADC,EAEdC,EAAD,IAAQ;IACJ,IAAIA,EAAE,IAAIJ,SAAV,EAAqB;MACjBE,OAAO,CAACC,KAAR,GAAgB,MAAhB;IACH,CAFD,MAEO,IAAIC,EAAE,GAAGJ,SAAT,EAAoB;MACvBE,OAAO,CAACC,KAAR,GAAgB,MAAhB;IACH;EACJ,CARc,EASf,CAACH,SAAD,CATe,CAAnB;EAYA,OAAOJ,gBAAgB,CAAC,OAAO;IAC3BM,OAAO,EAAEA,OAAO,CAACC;EADU,CAAP,CAAD,EAEnB,CAACD,OAAD,CAFmB,CAAvB;AAGH;AAAA"}
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import type { ComponentProps } from '@fountain-ui/core';
|
|
2
|
+
import type { ComponentProps, ExtendedStyle } from '@fountain-ui/core';
|
|
3
3
|
export default interface BottomSheetProps extends ComponentProps<{
|
|
4
4
|
/**
|
|
5
5
|
* Opacity for BackdropComponent
|
|
6
6
|
* @default 0.5
|
|
7
7
|
*/
|
|
8
8
|
backdropOpacity?: number;
|
|
9
|
+
/**
|
|
10
|
+
* View style to be applied to the background component. (only native)
|
|
11
|
+
*/
|
|
12
|
+
backgroundStyle?: ExtendedStyle | ExtendedStyle[];
|
|
9
13
|
/**
|
|
10
14
|
* Border radius for bottom sheet
|
|
11
15
|
*/
|
|
@@ -45,5 +49,9 @@ export default interface BottomSheetProps extends ComponentProps<{
|
|
|
45
49
|
* @default []
|
|
46
50
|
*/
|
|
47
51
|
snapPoints?: Array<number | string>;
|
|
52
|
+
/**
|
|
53
|
+
* View style to be applied to the content area.
|
|
54
|
+
*/
|
|
55
|
+
style?: ExtendedStyle | ExtendedStyle[];
|
|
48
56
|
}> {
|
|
49
57
|
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/// <reference types="react-native-reanimated" />
|
|
2
|
+
import type BottomSheetProps from './BottomSheetProps';
|
|
3
|
+
export default function useDynamicSnapPoints(snapPoints: BottomSheetProps['snapPoints']): {
|
|
4
|
+
animatedSnapPoints: Readonly<{
|
|
5
|
+
value: (string | number)[];
|
|
6
|
+
}>;
|
|
7
|
+
animatedHandleHeight: import("react-native-reanimated").SharedValue<number>;
|
|
8
|
+
animatedContentHeight: import("react-native-reanimated").SharedValue<number>;
|
|
9
|
+
handleContentLayout: ({ nativeEvent: { layout: { height }, }, }: {
|
|
10
|
+
nativeEvent: {
|
|
11
|
+
layout: {
|
|
12
|
+
height: number;
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
}) => void;
|
|
16
|
+
} | {
|
|
17
|
+
animatedHandleHeight: undefined;
|
|
18
|
+
animatedSnapPoints: (string | number)[] | undefined;
|
|
19
|
+
animatedContentHeight: undefined;
|
|
20
|
+
handleContentLayout: undefined;
|
|
21
|
+
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type CarouselProps from './CarouselProps';
|
|
3
3
|
import type { CarouselInstance } from './types';
|
|
4
|
-
declare const _default: React.MemoExoticComponent<React.ForwardRefExoticComponent<Pick<CarouselProps<any>, "style" | "data" | "autoplay" | "autoplayInterval" | "createItemStyle" | "createScrollAnimation" | "disableSmartAutoplay" | "initialIndex" | "itemHeight" | "itemWidth" | "loop" | "onIndexChange" | "renderItem" | "scrollEnabled" | "windowSize"> & React.RefAttributes<CarouselInstance>>>;
|
|
4
|
+
declare const _default: React.MemoExoticComponent<React.ForwardRefExoticComponent<Pick<CarouselProps<any>, "style" | "data" | "autoplay" | "autoplayInterval" | "createItemStyle" | "createScrollAnimation" | "disableSmartAutoplay" | "initialIndex" | "itemHeight" | "itemWidth" | "loop" | "onIndexChange" | "renderItem" | "scrollEnabled" | "windowSize" | "needsOffscreenAlphaCompositingOnItem"> & React.RefAttributes<CarouselInstance>>>;
|
|
5
5
|
export default _default;
|
|
@@ -71,5 +71,12 @@ export default interface CarouselProps<ItemT = any> extends ComponentProps<{
|
|
|
71
71
|
* @default 5
|
|
72
72
|
*/
|
|
73
73
|
windowSize?: number;
|
|
74
|
+
/**
|
|
75
|
+
* Whether item views need to be rendered offscreen and composited with an alpha
|
|
76
|
+
* in order to preserve 100% correct colors and blending behavior.
|
|
77
|
+
* Use this when items have opacity animations and multiple overlapping elements.
|
|
78
|
+
* @default false
|
|
79
|
+
*/
|
|
80
|
+
needsOffscreenAlphaCompositingOnItem?: boolean;
|
|
74
81
|
}> {
|
|
75
82
|
}
|
|
@@ -9,6 +9,7 @@ export interface InternalContextValue<ItemT> {
|
|
|
9
9
|
itemWidth: number;
|
|
10
10
|
itemVisibilityStore: ItemVisibilityStore;
|
|
11
11
|
loop: boolean;
|
|
12
|
+
needsOffscreenAlphaCompositingOnItem: boolean;
|
|
12
13
|
}
|
|
13
14
|
declare const InternalContext: import("react").Context<InternalContextValue<any>>;
|
|
14
15
|
export default InternalContext;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fountain-ui/lab",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.21",
|
|
4
4
|
"private": false,
|
|
5
5
|
"author": "Fountain-UI Team",
|
|
6
6
|
"description": "Incubator for Fountain-UI React components.",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"dependencies": {
|
|
18
18
|
"@emotion/react": "^11.10.0",
|
|
19
19
|
"@emotion/styled": "^11.10.0",
|
|
20
|
-
"@fountain-ui/icons": "3.0.0-alpha.
|
|
20
|
+
"@fountain-ui/icons": "3.0.0-alpha.12",
|
|
21
21
|
"@fountain-ui/utils": "^3.0.0-alpha.1",
|
|
22
22
|
"react-native-calendars": "1.1267.0"
|
|
23
23
|
},
|
|
@@ -29,7 +29,8 @@
|
|
|
29
29
|
"react-dom": "^16.8.0 || ^17.0.0",
|
|
30
30
|
"react-native": "^0.63.0",
|
|
31
31
|
"react-native-gesture-handler": "^2.0.0",
|
|
32
|
-
"react-native-pager-view": "^4.0.0"
|
|
32
|
+
"react-native-pager-view": "^4.0.0",
|
|
33
|
+
"react-native-safe-area-context": "^4.0.0"
|
|
33
34
|
},
|
|
34
35
|
"peerDependenciesMeta": {
|
|
35
36
|
"@gorhom/bottom-sheet": {
|
|
@@ -70,5 +71,5 @@
|
|
|
70
71
|
"publishConfig": {
|
|
71
72
|
"access": "public"
|
|
72
73
|
},
|
|
73
|
-
"gitHead": "
|
|
74
|
+
"gitHead": "a14becb14e77ed3a206bd22a0e0c1a5026878e6f"
|
|
74
75
|
}
|
|
@@ -18,7 +18,7 @@ export default function AnimatedY(props: AnimatedYProps) {
|
|
|
18
18
|
const animatedY = useSharedValue(translateY);
|
|
19
19
|
const animatedStyle = useAnimatedStyle(() => ({
|
|
20
20
|
transform: [{ translateY: animatedY.value }],
|
|
21
|
-
}), []);
|
|
21
|
+
}), [animatedY]);
|
|
22
22
|
|
|
23
23
|
useEffect(() => {
|
|
24
24
|
if (translateY >= 0) {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
|
2
2
|
import { Animated, LayoutChangeEvent, useWindowDimensions, ViewStyle } from 'react-native';
|
|
3
|
+
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
3
4
|
import {
|
|
4
5
|
BottomSheetBackdrop,
|
|
5
6
|
BottomSheetBackdropProps,
|
|
@@ -7,16 +8,22 @@ import {
|
|
|
7
8
|
BottomSheetModalProvider,
|
|
8
9
|
BottomSheetView,
|
|
9
10
|
} from '@gorhom/bottom-sheet';
|
|
10
|
-
import { Column, ExtendedStyle, isNotAndroid12, useAnimatedValue } from '@fountain-ui/core';
|
|
11
|
+
import { Column, css, ExtendedStyle, isNotAndroid12, useAnimatedValue } from '@fountain-ui/core';
|
|
11
12
|
import { useTheme } from '@fountain-ui/styles';
|
|
12
13
|
import type BottomSheetProps from './BottomSheetProps';
|
|
13
14
|
import TransparentBackdrop from './TransparentBackdrop';
|
|
15
|
+
import useDynamicSnapPoints from './useDynamicSnapPoints.native';
|
|
14
16
|
|
|
15
17
|
const NoHandle = () => null;
|
|
16
18
|
|
|
19
|
+
const DEFAULT_PADDING_BOTTOM = 24;
|
|
20
|
+
const DEFAULT_PADDING_TOP = 22;
|
|
21
|
+
const TOP_ELEMENT_HIDDEN_OFFSET = 16;
|
|
22
|
+
|
|
17
23
|
export default function BottomSheet(props: BottomSheetProps) {
|
|
18
24
|
const {
|
|
19
25
|
backdropOpacity = 0.5,
|
|
26
|
+
backgroundStyle: backgroundStyleProp,
|
|
20
27
|
borderRadius: borderRadiusProp,
|
|
21
28
|
children,
|
|
22
29
|
enableDynamicSizing = true,
|
|
@@ -25,6 +32,7 @@ export default function BottomSheet(props: BottomSheetProps) {
|
|
|
25
32
|
maxHeightNormalizedRatio = 0.8,
|
|
26
33
|
onChange,
|
|
27
34
|
snapPoints = [],
|
|
35
|
+
style: styleProp,
|
|
28
36
|
} = props;
|
|
29
37
|
|
|
30
38
|
const indexRef = useRef<number>(-1);
|
|
@@ -33,7 +41,8 @@ export default function BottomSheet(props: BottomSheetProps) {
|
|
|
33
41
|
const { height: windowHeight } = useWindowDimensions();
|
|
34
42
|
const [topElementHeight, setTopElementHeight] = useState(0);
|
|
35
43
|
|
|
36
|
-
const
|
|
44
|
+
const topElementHeightWithoutOffset = Math.max(0, topElementHeight - TOP_ELEMENT_HIDDEN_OFFSET);
|
|
45
|
+
const maxDynamicContentSize = Math.round(windowHeight * maxHeightNormalizedRatio) - topElementHeightWithoutOffset;
|
|
37
46
|
|
|
38
47
|
const handleTopElementLayout = (event: LayoutChangeEvent) => {
|
|
39
48
|
const { height } = event.nativeEvent.layout;
|
|
@@ -70,20 +79,31 @@ export default function BottomSheet(props: BottomSheetProps) {
|
|
|
70
79
|
const theme = useTheme();
|
|
71
80
|
|
|
72
81
|
const borderRadius = borderRadiusProp ?? theme.shape.radius.xxl;
|
|
73
|
-
const backgroundStyle =
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
82
|
+
const backgroundStyle = css([
|
|
83
|
+
{
|
|
84
|
+
backgroundColor: theme.palette.surface.base,
|
|
85
|
+
borderTopLeftRadius: borderRadius,
|
|
86
|
+
borderTopRightRadius: borderRadius,
|
|
87
|
+
},
|
|
88
|
+
backgroundStyleProp,
|
|
89
|
+
]);
|
|
90
|
+
|
|
91
|
+
const { bottom: bottomSafeInset } = useSafeAreaInsets();
|
|
92
|
+
|
|
93
|
+
const contentWrapperStyle: ViewStyle = css([
|
|
94
|
+
{
|
|
95
|
+
backgroundColor: theme.palette.surface.base,
|
|
96
|
+
borderTopLeftRadius: borderRadius,
|
|
97
|
+
borderTopRightRadius: borderRadius,
|
|
98
|
+
flexShrink: 1,
|
|
99
|
+
maxHeight: maxDynamicContentSize,
|
|
100
|
+
minHeight: 325,
|
|
101
|
+
overflow: 'hidden',
|
|
102
|
+
paddingBottom: DEFAULT_PADDING_BOTTOM + bottomSafeInset,
|
|
103
|
+
paddingTop: DEFAULT_PADDING_TOP,
|
|
104
|
+
},
|
|
105
|
+
styleProp,
|
|
106
|
+
]);
|
|
87
107
|
|
|
88
108
|
const isBackdropTransparent = backdropOpacity <= 0;
|
|
89
109
|
|
|
@@ -114,23 +134,33 @@ export default function BottomSheet(props: BottomSheetProps) {
|
|
|
114
134
|
}).start();
|
|
115
135
|
};
|
|
116
136
|
|
|
137
|
+
const {
|
|
138
|
+
animatedHandleHeight,
|
|
139
|
+
animatedSnapPoints,
|
|
140
|
+
animatedContentHeight,
|
|
141
|
+
handleContentLayout,
|
|
142
|
+
} = useDynamicSnapPoints(snapPoints);
|
|
143
|
+
|
|
117
144
|
return (
|
|
118
145
|
<BottomSheetModalProvider>
|
|
119
146
|
<BottomSheetModal
|
|
120
147
|
backdropComponent={isBackdropTransparent ? TransparentBackdrop : OpacityAwareBackdrop}
|
|
121
148
|
// @ts-ignore
|
|
122
149
|
backgroundStyle={backgroundStyle}
|
|
150
|
+
enableOverDrag={false}
|
|
123
151
|
index={index}
|
|
124
152
|
handleComponent={NoHandle}
|
|
125
153
|
onChange={handleChange}
|
|
126
154
|
onDismiss={handleDismiss}
|
|
127
155
|
ref={bottomSheetRef}
|
|
128
|
-
snapPoints={snapPoints}
|
|
129
156
|
enablePanDownToClose={Boolean(onChange)}
|
|
130
157
|
enableDynamicSizing={enableDynamicSizing}
|
|
131
158
|
maxDynamicContentSize={maxDynamicContentSize}
|
|
132
159
|
detached={Boolean(topElement)}
|
|
133
160
|
onAnimate={topElement ? onAnimate : undefined}
|
|
161
|
+
snapPoints={animatedSnapPoints}
|
|
162
|
+
handleHeight={animatedHandleHeight}
|
|
163
|
+
contentHeight={animatedContentHeight}
|
|
134
164
|
>
|
|
135
165
|
{topElement ? (
|
|
136
166
|
<Animated.View style={topElementAnimationStyle}>
|
|
@@ -143,7 +173,10 @@ export default function BottomSheet(props: BottomSheetProps) {
|
|
|
143
173
|
</Animated.View>
|
|
144
174
|
) : null}
|
|
145
175
|
|
|
146
|
-
<BottomSheetView
|
|
176
|
+
<BottomSheetView
|
|
177
|
+
onLayout={handleContentLayout}
|
|
178
|
+
style={contentWrapperStyle}
|
|
179
|
+
>
|
|
147
180
|
{children}
|
|
148
181
|
</BottomSheetView>
|
|
149
182
|
</BottomSheetModal>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import type { ComponentProps } from '@fountain-ui/core';
|
|
2
|
+
import type { ComponentProps, ExtendedStyle } from '@fountain-ui/core';
|
|
3
3
|
|
|
4
4
|
export default interface BottomSheetProps extends ComponentProps<{
|
|
5
5
|
/**
|
|
@@ -8,6 +8,11 @@ export default interface BottomSheetProps extends ComponentProps<{
|
|
|
8
8
|
*/
|
|
9
9
|
backdropOpacity?: number;
|
|
10
10
|
|
|
11
|
+
/**
|
|
12
|
+
* View style to be applied to the background component. (only native)
|
|
13
|
+
*/
|
|
14
|
+
backgroundStyle?: ExtendedStyle | ExtendedStyle[];
|
|
15
|
+
|
|
11
16
|
/**
|
|
12
17
|
* Border radius for bottom sheet
|
|
13
18
|
*/
|
|
@@ -54,4 +59,9 @@ export default interface BottomSheetProps extends ComponentProps<{
|
|
|
54
59
|
* @default []
|
|
55
60
|
*/
|
|
56
61
|
snapPoints?: Array<number | string>;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* View style to be applied to the content area.
|
|
65
|
+
*/
|
|
66
|
+
style?: ExtendedStyle | ExtendedStyle[];
|
|
57
67
|
}> {}
|
|
@@ -26,19 +26,20 @@ const useStyles: UseStyles<BottomSheetStyles> = function (): BottomSheetStyles {
|
|
|
26
26
|
borderTopLeftRadius: theme.shape.radius.xxl,
|
|
27
27
|
borderTopRightRadius: theme.shape.radius.xxl,
|
|
28
28
|
flexGrow: 1,
|
|
29
|
-
minHeight:
|
|
29
|
+
minHeight: 325,
|
|
30
30
|
overflow: 'hidden',
|
|
31
31
|
paddingBottom: theme.spacing(6),
|
|
32
32
|
paddingTop: theme.spacing(5.5),
|
|
33
33
|
},
|
|
34
34
|
topElementLocation: {
|
|
35
35
|
position: 'absolute',
|
|
36
|
-
bottom: 0,
|
|
37
36
|
width: '100%',
|
|
38
37
|
},
|
|
39
38
|
};
|
|
40
39
|
};
|
|
41
40
|
|
|
41
|
+
const TOP_ELEMENT_HIDDEN_OFFSET = 16;
|
|
42
|
+
|
|
42
43
|
export default function BottomSheet(props: BottomSheetProps) {
|
|
43
44
|
const {
|
|
44
45
|
backdropOpacity,
|
|
@@ -50,6 +51,7 @@ export default function BottomSheet(props: BottomSheetProps) {
|
|
|
50
51
|
maxHeightNormalizedRatio = 0.8,
|
|
51
52
|
onChange,
|
|
52
53
|
snapPoints = [],
|
|
54
|
+
style: styleProp,
|
|
53
55
|
} = props;
|
|
54
56
|
|
|
55
57
|
const styles = useStyles();
|
|
@@ -58,7 +60,8 @@ export default function BottomSheet(props: BottomSheetProps) {
|
|
|
58
60
|
|
|
59
61
|
const [topElementHeight, setTopElementHeight] = useState(0);
|
|
60
62
|
|
|
61
|
-
const
|
|
63
|
+
const topElementHeightWithoutOffset = Math.max(0, topElementHeight - TOP_ELEMENT_HIDDEN_OFFSET);
|
|
64
|
+
const maxDynamicContentSize = Math.round(windowHeight * maxHeightNormalizedRatio) - topElementHeightWithoutOffset;
|
|
62
65
|
|
|
63
66
|
const handleTopElementLayout = (event: LayoutChangeEvent) => {
|
|
64
67
|
const { height } = event.nativeEvent.layout;
|
|
@@ -71,6 +74,8 @@ export default function BottomSheet(props: BottomSheetProps) {
|
|
|
71
74
|
}
|
|
72
75
|
};
|
|
73
76
|
|
|
77
|
+
const filteredSnapPoints = snapPoints.filter(point => point !== 'CONTENT_HEIGHT');
|
|
78
|
+
|
|
74
79
|
const {
|
|
75
80
|
convertedSnapPoints,
|
|
76
81
|
handleLayout,
|
|
@@ -78,18 +83,21 @@ export default function BottomSheet(props: BottomSheetProps) {
|
|
|
78
83
|
} = useDynamicSnapPoints({
|
|
79
84
|
enableDynamicSizing,
|
|
80
85
|
maxDynamicContentSize,
|
|
81
|
-
snapPoints,
|
|
86
|
+
snapPoints: filteredSnapPoints,
|
|
82
87
|
});
|
|
83
88
|
|
|
84
|
-
const translateY =
|
|
89
|
+
const translateY = convertedSnapPoints.length > 0
|
|
90
|
+
? highestSnapPoint - (convertedSnapPoints[index] ?? 0)
|
|
91
|
+
: 0;
|
|
85
92
|
|
|
86
93
|
const contentStyles = css([
|
|
87
94
|
styles.paper,
|
|
88
95
|
{
|
|
89
96
|
...(borderRadius ? { borderTopLeftRadius: borderRadius, borderTopRightRadius: borderRadius } : {}),
|
|
90
|
-
...(highestSnapPoint !== maxDynamicContentSize ? { height: highestSnapPoint } : {}),
|
|
97
|
+
...(!enableDynamicSizing && highestSnapPoint !== maxDynamicContentSize ? { height: highestSnapPoint } : {}),
|
|
91
98
|
maxHeight: maxDynamicContentSize,
|
|
92
99
|
},
|
|
100
|
+
styleProp,
|
|
93
101
|
]);
|
|
94
102
|
|
|
95
103
|
return (
|
|
@@ -103,7 +111,7 @@ export default function BottomSheet(props: BottomSheetProps) {
|
|
|
103
111
|
{topElement ? (
|
|
104
112
|
<Column
|
|
105
113
|
onLayout={handleTopElementLayout}
|
|
106
|
-
style={styles.topElementLocation}
|
|
114
|
+
style={[styles.topElementLocation, { top: -topElementHeight }]}
|
|
107
115
|
>
|
|
108
116
|
{topElement}
|
|
109
117
|
</Column>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { useBottomSheetDynamicSnapPoints } from '@gorhom/bottom-sheet';
|
|
2
|
+
import type BottomSheetProps from './BottomSheetProps';
|
|
3
|
+
|
|
4
|
+
export default function useDynamicSnapPoints(snapPoints: BottomSheetProps['snapPoints']) {
|
|
5
|
+
if (snapPoints?.includes('CONTENT_HEIGHT')) {
|
|
6
|
+
return useBottomSheetDynamicSnapPoints(snapPoints);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
return {
|
|
10
|
+
animatedHandleHeight: undefined,
|
|
11
|
+
animatedSnapPoints: snapPoints,
|
|
12
|
+
animatedContentHeight: undefined,
|
|
13
|
+
handleContentLayout: undefined,
|
|
14
|
+
};
|
|
15
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useCallback, useMemo,
|
|
1
|
+
import { useCallback, useMemo, useState } from 'react';
|
|
2
2
|
import { LayoutChangeEvent, useWindowDimensions } from 'react-native';
|
|
3
3
|
import * as R from 'ramda';
|
|
4
4
|
|
|
@@ -41,8 +41,6 @@ export default function useDynamicSnapPoints(params: UseDynamicSnapPointsParams)
|
|
|
41
41
|
|
|
42
42
|
const [contentHeight, setContentHeight] = useState<number>(INITIAL_CONTAINER_HEIGHT);
|
|
43
43
|
|
|
44
|
-
const hasMeasureRef = useRef<boolean>(false);
|
|
45
|
-
|
|
46
44
|
const convertedSnapPoints = useMemo(() => {
|
|
47
45
|
if (contentHeight === INITIAL_CONTAINER_HEIGHT) {
|
|
48
46
|
return [];
|
|
@@ -70,13 +68,8 @@ export default function useDynamicSnapPoints(params: UseDynamicSnapPointsParams)
|
|
|
70
68
|
const highestSnapPoint = R.last(convertedSnapPoints) ?? maxDynamicContentSize;
|
|
71
69
|
|
|
72
70
|
const handleLayout = useCallback((event: LayoutChangeEvent) => {
|
|
73
|
-
if (hasMeasureRef.current) {
|
|
74
|
-
return;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
hasMeasureRef.current = true;
|
|
78
71
|
const { height } = event.nativeEvent.layout;
|
|
79
|
-
setContentHeight(height);
|
|
72
|
+
setContentHeight(prev => (Math.abs(prev - height) > 1 ? height : prev));
|
|
80
73
|
}, []);
|
|
81
74
|
|
|
82
75
|
return {
|
|
@@ -24,6 +24,7 @@ const Carousel = forwardRef<CarouselInstance, CarouselProps>(function Carousel(p
|
|
|
24
24
|
itemHeight,
|
|
25
25
|
itemWidth,
|
|
26
26
|
loop = false,
|
|
27
|
+
needsOffscreenAlphaCompositingOnItem = false,
|
|
27
28
|
onIndexChange,
|
|
28
29
|
renderItem,
|
|
29
30
|
scrollEnabled = true,
|
|
@@ -89,6 +90,7 @@ const Carousel = forwardRef<CarouselInstance, CarouselProps>(function Carousel(p
|
|
|
89
90
|
itemWidth,
|
|
90
91
|
itemVisibilityStore,
|
|
91
92
|
loop,
|
|
93
|
+
needsOffscreenAlphaCompositingOnItem,
|
|
92
94
|
}), [
|
|
93
95
|
createItemStyle,
|
|
94
96
|
data,
|
|
@@ -97,6 +99,7 @@ const Carousel = forwardRef<CarouselInstance, CarouselProps>(function Carousel(p
|
|
|
97
99
|
itemWidth,
|
|
98
100
|
itemVisibilityStore,
|
|
99
101
|
loop,
|
|
102
|
+
needsOffscreenAlphaCompositingOnItem,
|
|
100
103
|
]);
|
|
101
104
|
|
|
102
105
|
return (
|
|
@@ -93,4 +93,12 @@ export default interface CarouselProps<ItemT = any> extends ComponentProps<{
|
|
|
93
93
|
* @default 5
|
|
94
94
|
*/
|
|
95
95
|
windowSize?: number;
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Whether item views need to be rendered offscreen and composited with an alpha
|
|
99
|
+
* in order to preserve 100% correct colors and blending behavior.
|
|
100
|
+
* Use this when items have opacity animations and multiple overlapping elements.
|
|
101
|
+
* @default false
|
|
102
|
+
*/
|
|
103
|
+
needsOffscreenAlphaCompositingOnItem?: boolean;
|
|
96
104
|
}> {}
|
|
@@ -10,6 +10,7 @@ export interface InternalContextValue<ItemT> {
|
|
|
10
10
|
itemWidth: number;
|
|
11
11
|
itemVisibilityStore: ItemVisibilityStore;
|
|
12
12
|
loop: boolean;
|
|
13
|
+
needsOffscreenAlphaCompositingOnItem: boolean;
|
|
13
14
|
}
|
|
14
15
|
|
|
15
16
|
const mockItemVisibilityStore: ItemVisibilityStore = {
|
|
@@ -26,6 +27,7 @@ const initialValue: Readonly<InternalContextValue<any>> = {
|
|
|
26
27
|
itemWidth: 0,
|
|
27
28
|
itemVisibilityStore: mockItemVisibilityStore,
|
|
28
29
|
loop: false,
|
|
30
|
+
needsOffscreenAlphaCompositingOnItem: false,
|
|
29
31
|
};
|
|
30
32
|
|
|
31
33
|
const InternalContext = createContext<InternalContextValue<any>>(initialValue);
|
|
@@ -24,6 +24,7 @@ export default function ItemView(props: ItemViewProps) {
|
|
|
24
24
|
itemHeight,
|
|
25
25
|
itemWidth,
|
|
26
26
|
itemVisibilityStore,
|
|
27
|
+
needsOffscreenAlphaCompositingOnItem,
|
|
27
28
|
} = useContext(InternalContext);
|
|
28
29
|
|
|
29
30
|
const [visible, setVisible] = useState(false);
|
|
@@ -44,6 +45,7 @@ export default function ItemView(props: ItemViewProps) {
|
|
|
44
45
|
|
|
45
46
|
return (
|
|
46
47
|
<Animated.View
|
|
48
|
+
needsOffscreenAlphaCompositing={needsOffscreenAlphaCompositingOnItem}
|
|
47
49
|
children={visible ? children(interpolation) : null}
|
|
48
50
|
onLayout={onLayout}
|
|
49
51
|
style={[
|
|
@@ -3,8 +3,9 @@ import * as R from 'ramda';
|
|
|
3
3
|
import { NativeScrollEvent, NativeSyntheticEvent, View } from 'react-native';
|
|
4
4
|
import { Gesture, GestureDetector } from 'react-native-gesture-handler';
|
|
5
5
|
import Animated, { runOnJS, useAnimatedStyle, useSharedValue, withDelay, withTiming } from 'react-native-reanimated';
|
|
6
|
-
import { ChevronDown, ChevronUp } from '@fountain-ui/icons';
|
|
6
|
+
import { ChevronDown, ChevronUp } from '@fountain-ui/icons/src/v2Icons';
|
|
7
7
|
import { StyleSheet } from '@fountain-ui/core';
|
|
8
|
+
import { baseColors, commonColors } from '@fountain-ui/styles';
|
|
8
9
|
import FastScrollProps from './FastScrollProps';
|
|
9
10
|
import { offsetToPercentage, percentageToOffset } from './util';
|
|
10
11
|
|
|
@@ -14,7 +15,7 @@ const styles = StyleSheet.create({
|
|
|
14
15
|
indicator: {
|
|
15
16
|
width: INDICATOR_WIDTH,
|
|
16
17
|
height: 48,
|
|
17
|
-
backgroundColor: '
|
|
18
|
+
backgroundColor: baseColors.gray['650'],
|
|
18
19
|
flexDirection: 'column',
|
|
19
20
|
alignItems: 'center',
|
|
20
21
|
justifyContent: 'center',
|
|
@@ -54,7 +55,7 @@ const FastScroll = React.forwardRef((props: FastScrollProps, ref) => {
|
|
|
54
55
|
const animatedStyle = useAnimatedStyle(() => ({
|
|
55
56
|
transform: [{ translateY: indicatorOffset.value }],
|
|
56
57
|
opacity: indicatorOpacity.value,
|
|
57
|
-
}));
|
|
58
|
+
}), [indicatorOffset, indicatorOpacity]);
|
|
58
59
|
|
|
59
60
|
const position = {
|
|
60
61
|
...absolutePosition,
|
|
@@ -157,16 +158,9 @@ const FastScroll = React.forwardRef((props: FastScrollProps, ref) => {
|
|
|
157
158
|
animatedStyle,
|
|
158
159
|
styles.indicator,
|
|
159
160
|
]}>
|
|
160
|
-
<ChevronUp
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
width={20}
|
|
164
|
-
/>
|
|
165
|
-
<ChevronDown
|
|
166
|
-
fill={'#ededed'}
|
|
167
|
-
height={20}
|
|
168
|
-
width={20}
|
|
169
|
-
/>
|
|
161
|
+
<ChevronUp fill={commonColors.static.strongInverse}/>
|
|
162
|
+
|
|
163
|
+
<ChevronDown fill={commonColors.static.strongInverse}/>
|
|
170
164
|
</Animated.View>
|
|
171
165
|
</GestureDetector>
|
|
172
166
|
</View>
|