@attio/react-native-bottom-sheet-toolbox
Version:
143 lines (139 loc) • 5 kB
JavaScript
;
import * as React from "react";
import { Keyboard, Pressable, StyleSheet, View } from "react-native";
import Animated, { Extrapolate, interpolate, useAnimatedReaction, useAnimatedStyle, useSharedValue, withSpring } from "react-native-reanimated";
import { useBottomSheetToolboxInternalContext } from "../context";
import { useBottomSheetActions } from "../hooks";
import { CLOSED_SNAP_POINT, normalizeSheetPosition } from "../utils";
/**
* We want the bottom sheet's opacity to persist across new mounts.
* However, we want to avoid polluting the internal context.
*/
import { jsx as _jsx } from "react/jsx-runtime";
const BottomSheetToolboxBackdropContext = /*#__PURE__*/React.createContext(undefined);
export function NewBottomSheetToolboxBackdropProvider({
children,
hide = false
}) {
const opacitySharedValue = useSharedValue(0);
const contextValue = React.useMemo(() => ({
opacitySharedValue,
hide
}), [hide]);
return /*#__PURE__*/_jsx(BottomSheetToolboxBackdropContext.Provider, {
value: contextValue,
children: children
});
}
export function OldBottomSheetToolboxBackdropProvider({
children,
inheritHide,
hide = false
}) {
const backdropContext = React.useContext(BottomSheetToolboxBackdropContext);
if (!backdropContext) throw new Error("BottomSheetToolboxBackdropProvider not found.");
const {
opacitySharedValue,
hide: ancestorHide
} = backdropContext;
const contextValue = React.useMemo(() => ({
opacitySharedValue,
hide: hide || ancestorHide && inheritHide
}), [ancestorHide, hide, inheritHide, opacitySharedValue]);
return /*#__PURE__*/_jsx(BottomSheetToolboxBackdropContext.Provider, {
value: contextValue,
children: children
});
}
export function BottomSheetToolboxBackdropProvider({
children,
reset = false,
hide = false,
inheritHide = false
}) {
const inheritedContext = React.useContext(BottomSheetToolboxBackdropContext);
return inheritedContext !== undefined && !reset ? /*#__PURE__*/_jsx(OldBottomSheetToolboxBackdropProvider, {
hide: hide,
inheritHide: inheritHide,
children: children
}) : /*#__PURE__*/_jsx(NewBottomSheetToolboxBackdropProvider, {
hide: hide,
children: children
});
}
/**
* Retrieve the bottom sheet internal context, and throw if unavailable.
*/
export function useBottomSheetToolboxBackdropContext() {
const context = React.useContext(BottomSheetToolboxBackdropContext);
if (!context) {
throw new Error("BottomSheetToolboxBackdropProvider not found.");
}
return context;
}
export function BottomSheetToolboxDefaultBackdrop({
maxOpacity = 0.7,
color = "#000000",
children,
maxOpacityPoint,
maxOpacitySnapIndex
}) {
const {
close
} = useBottomSheetActions("BottomSheetToolboxDefaultBackdrop");
const {
currentPositionSharedValue,
normalizedSnapPointsSharedValue,
childrenHeightSharedValue,
wrapperHeightSharedValue,
footerHeightSharedValue
} = useBottomSheetToolboxInternalContext();
const {
opacitySharedValue,
hide
} = useBottomSheetToolboxBackdropContext();
useAnimatedReaction(() => ({
currentPosition: currentPositionSharedValue.get(),
snapPoints: normalizedSnapPointsSharedValue.get()
}), ({
snapPoints,
currentPosition
}) => {
if (hide) return;
const maxOpacityPosition = maxOpacityPoint ? normalizeSheetPosition({
sheetPosition: maxOpacityPoint,
childrenHeightSharedValue,
wrapperHeightSharedValue,
footerHeightSharedValue
}) : null;
const maxOpacitySnapIndexPosition = maxOpacitySnapIndex && snapPoints && maxOpacitySnapIndex in snapPoints ? snapPoints[maxOpacitySnapIndex] : null;
const maxPosition = (maxOpacityPosition || maxOpacitySnapIndexPosition || snapPoints?.find(point => point !== CLOSED_SNAP_POINT)) ?? CLOSED_SNAP_POINT;
const openRatio = maxPosition === 0 ? 0 : currentPosition / maxPosition;
const opacity = interpolate(openRatio, [0, 1], [0, maxOpacity], Extrapolate.CLAMP);
// The snap-points, position, and maxOpacity can make notable instant
// changes. We don't want the backdrop to appear glitchy when this happens.
opacitySharedValue.set(withSpring(opacity, {
stiffness: 200,
mass: 0.2
}));
}, [currentPositionSharedValue, normalizedSnapPointsSharedValue]);
const animatedBackdropStyle = useAnimatedStyle(() => ({
opacity: opacitySharedValue.get(),
backgroundColor: color
}), [color, opacitySharedValue]);
const handleClose = React.useCallback(() => {
Keyboard.isVisible() && Keyboard.dismiss();
close();
}, [close]);
return hide ? null : /*#__PURE__*/_jsx(Pressable, {
onPress: handleClose,
style: StyleSheet.absoluteFill,
children: /*#__PURE__*/_jsx(Animated.View, {
style: [StyleSheet.absoluteFill, animatedBackdropStyle],
children: /*#__PURE__*/_jsx(View, {
children: children
})
})
});
}
//# sourceMappingURL=bottom-sheet-toolbox-default-backdrop.js.map