diff --git a/src/view/com/Dialog/index.tsx b/src/view/com/Dialog/index.tsx index 2cf78022d2..229cd7b867 100644 --- a/src/view/com/Dialog/index.tsx +++ b/src/view/com/Dialog/index.tsx @@ -1,17 +1,123 @@ -import React from 'react' +import React, {useImperativeHandle} from 'react' +import {View, Dimensions} from 'react-native' +import BottomSheet, {BottomSheetBackdrop} from '@gorhom/bottom-sheet' -import {DialogProps} from '#/view/com/Dialog/types' +import {useTheme, atoms as a} from '#/alf' +import {Portal} from '#/view/com/Portal' -export function Outer(props: React.PropsWithChildren) { - return null +import {DialogProps, DialogControl} from '#/view/com/Dialog/types' + +const Context = React.createContext<{ + close: () => void +}>({ + close: () => {}, +}) + +export function useDialogControl() { + const control = React.useRef({ + open: () => {}, + close: () => {}, + }) + + return control +} + +export function useDialog() { + return React.useContext(Context) +} + +export function Outer({ + control, + onClose, + children, +}: React.PropsWithChildren) { + const t = useTheme() + const sheet = React.useRef(null) + + const open = React.useCallback((i = 0) => { + sheet.current?.snapToIndex(i) + }, []) + + const close = React.useCallback(() => { + sheet.current?.close() + onClose?.() + }, [onClose]) + + useImperativeHandle( + control, + () => ({ + open, + close, + }), + [open, close], + ) + + return ( + + ( + + )} + handleIndicatorStyle={{backgroundColor: t.palette.primary}} + handleStyle={{display: 'none'}} + onChange={() => {}} + onClose={onClose}> + {children} + + + ) } export function Inner(props: React.PropsWithChildren<{}>) { - return null + const t = useTheme() + return ( + + {props.children} + + ) } -export function Header(props: React.PropsWithChildren<{ title: string }>) { - return null +export function Handle() { + const t = useTheme() + return ( + + ) } export function Close() { diff --git a/src/view/com/Dialog/index.web.tsx b/src/view/com/Dialog/index.web.tsx index a972a8f0d7..b27c757029 100644 --- a/src/view/com/Dialog/index.web.tsx +++ b/src/view/com/Dialog/index.web.tsx @@ -1,48 +1,73 @@ -import React from 'react' +import React, {useImperativeHandle} from 'react' import {View, TouchableWithoutFeedback, DimensionValue} from 'react-native' import {FocusScope} from '@tamagui/focus-scope' import Animated, {FadeInDown, FadeIn, FadeOut} from 'react-native-reanimated' import {useTheme, atoms as a, useBreakpoints} from '#/alf' import {EventStopper} from '#/view/com/util/EventStopper' -import {H3, Text} from '#/view/com/Typography' +import {Text} from '#/view/com/Typography' import {Portal} from '#/view/com/Portal' -import {DialogProps} from '#/view/com/Dialog/types' import {Button} from '#/view/com/Button' +import {DialogProps, DialogControl} from '#/view/com/Dialog/types' + const Context = React.createContext<{ - dismiss: () => void + close: () => void }>({ - dismiss: () => {}, + close: () => {}, }) +export function useDialogControl() { + const control = React.useRef({ + open: () => {}, + close: () => {}, + }) + + return control +} + export function useDialog() { return React.useContext(Context) } export function Outer({ - isOpen, - onDismiss, + control, + onClose, children, }: React.PropsWithChildren) { const t = useTheme() const {gtMobile} = useBreakpoints() + const [isOpen, setIsOpen] = React.useState(false) - const dismiss = React.useCallback(() => { - onDismiss() - }, [onDismiss]) + const open = React.useCallback(() => { + setIsOpen(true) + }, [setIsOpen]) + + const close = React.useCallback(() => { + setIsOpen(false) + onClose?.() + }, [onClose, setIsOpen]) + + useImperativeHandle( + control, + () => ({ + open, + close, + }), + [open, close], + ) React.useEffect(() => { function handler(e: KeyboardEvent) { - if (e.key === 'Escape') dismiss() + if (e.key === 'Escape') close() } document.addEventListener('keydown', handler) return () => document.removeEventListener('keydown', handler) - }, [dismiss]) + }, [close]) - const context = React.useMemo(() => ({dismiss}), [dismiss]) + const context = React.useMemo(() => ({close}), [close]) return ( <> @@ -51,7 +76,7 @@ export function Outer({ + onPress={close}> - - {children} - + aria-role="dialog"> + {children} @@ -104,52 +126,46 @@ export function Outer({ export function Inner(props: React.PropsWithChildren<{}>) { const t = useTheme() return ( - + {props.children} ) } -export function Header({ children, title }: React.PropsWithChildren<{ title: string }>) { - const t = useTheme() - return ( - -

{title}

- {children} -
- ) +export function Handle() { + return null } export function Close() { const t = useTheme() - const {dismiss} = useDialog() + const {close} = useDialog() return ( - - - setIsOpen(false)}> - - - - -