/**
* Modal
* Dependencies:
* - @gorhom/bottom-sheet.
*
* Props:
* - All `BottomSheetModalProps` props.
* - `title` (string | undefined): Optional title for the modal header.
*
* Usage Example:
* import { Modal, useModal } from '@gorhom/bottom-sheet';
*
* function DisplayModal() {
* const { ref, present, dismiss } = useModal();
*
* return (
*
*
* Modal Content
*
*
* );
* }
*
*/
import type {
BottomSheetBackdropProps,
BottomSheetModalProps,
} from '@gorhom/bottom-sheet';
import { BottomSheetModal, useBottomSheet } from '@gorhom/bottom-sheet';
import * as React from 'react';
import { Pressable, View } from 'react-native';
import Animated, { FadeIn, FadeOut } from 'react-native-reanimated';
import { Path, Svg } from 'react-native-svg';
import { Text } from './text';
type ModalProps = BottomSheetModalProps & {
title?: string;
};
type ModalRef = React.ForwardedRef;
type ModalHeaderProps = {
title?: string;
dismiss: () => void;
};
export const useModal = () => {
const ref = React.useRef(null);
const present = React.useCallback((data?: any) => {
ref.current?.present(data);
}, []);
const dismiss = React.useCallback(() => {
ref.current?.dismiss();
}, []);
return { ref, present, dismiss };
};
export const Modal = React.forwardRef(
(
{
snapPoints: _snapPoints = ['60%'],
title,
detached = false,
...props
}: ModalProps,
ref: ModalRef,
) => {
const detachedProps = React.useMemo(
() => getDetachedProps(detached),
[detached],
);
const modal = useModal();
const snapPoints = React.useMemo(() => _snapPoints, [_snapPoints]);
React.useImperativeHandle(
ref,
() => (modal.ref.current as BottomSheetModal) || null,
);
const renderHandleComponent = React.useCallback(
() => (
<>
>
),
[title, modal.dismiss],
);
return (
);
},
);
/**
* Custom Backdrop
*/
const AnimatedPressable = Animated.createAnimatedComponent(Pressable);
const CustomBackdrop = ({ style }: BottomSheetBackdropProps) => {
const { close } = useBottomSheet();
return (
close()}
entering={FadeIn.duration(50)}
exiting={FadeOut.duration(20)}
style={[style, { backgroundColor: 'rgba(0, 0, 0, 0.4)' }]}
/>
);
};
export const renderBackdrop = (props: BottomSheetBackdropProps) => (
);
/**
*
* @param detached
* @returns
*
* @description
* In case the modal is detached, we need to add some extra props to the modal to make it look like a detached modal.
*/
const getDetachedProps = (detached: boolean) => {
if (detached) {
return {
detached: true,
bottomInset: 46,
style: { marginHorizontal: 16, overflow: 'hidden' },
} as Partial;
}
return {} as Partial;
};
/**
* ModalHeader
*/
const ModalHeader = React.memo(({ title, dismiss }: ModalHeaderProps) => {
return (
<>
{title && (
{title}
)}
>
);
});
const CloseButton = ({ close }: { close: () => void }) => {
return (
);
};