Integrate new dialogs into old back handling (#3023)
This commit is contained in:
parent
7fd13cacfe
commit
2440975bd2
6 changed files with 64 additions and 20 deletions
|
@ -3,7 +3,7 @@ import React from 'react'
|
|||
import {useDialogStateContext} from '#/state/dialogs'
|
||||
import {
|
||||
DialogContextProps,
|
||||
DialogControlProps,
|
||||
DialogControlRefProps,
|
||||
DialogOuterProps,
|
||||
} from '#/components/Dialog/types'
|
||||
|
||||
|
@ -17,7 +17,7 @@ export function useDialogContext() {
|
|||
|
||||
export function useDialogControl(): DialogOuterProps['control'] {
|
||||
const id = React.useId()
|
||||
const control = React.useRef<DialogControlProps>({
|
||||
const control = React.useRef<DialogControlRefProps>({
|
||||
open: () => {},
|
||||
close: () => {},
|
||||
})
|
||||
|
@ -32,8 +32,13 @@ export function useDialogControl(): DialogOuterProps['control'] {
|
|||
}, [id, activeDialogs])
|
||||
|
||||
return {
|
||||
id,
|
||||
ref: control,
|
||||
open: () => control.current.open(),
|
||||
close: cb => control.current.close(cb),
|
||||
open: () => {
|
||||
control.current.open()
|
||||
},
|
||||
close: cb => {
|
||||
control.current.close(cb)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import {useTheme, atoms as a, flatten} from '#/alf'
|
|||
import {Portal} from '#/components/Portal'
|
||||
import {createInput} from '#/components/forms/TextField'
|
||||
import {logger} from '#/logger'
|
||||
import {useDialogStateContext} from '#/state/dialogs'
|
||||
|
||||
import {
|
||||
DialogOuterProps,
|
||||
|
@ -37,6 +38,7 @@ export function Outer({
|
|||
const hasSnapPoints = !!sheetOptions.snapPoints
|
||||
const insets = useSafeAreaInsets()
|
||||
const closeCallback = React.useRef<() => void>()
|
||||
const {openDialogs} = useDialogStateContext()
|
||||
|
||||
/*
|
||||
* Used to manage open/closed, but index is otherwise handled internally by `BottomSheet`
|
||||
|
@ -50,10 +52,11 @@ export function Outer({
|
|||
|
||||
const open = React.useCallback<DialogControlProps['open']>(
|
||||
({index} = {}) => {
|
||||
openDialogs.current.add(control.id)
|
||||
// can be set to any index of `snapPoints`, but `0` is the first i.e. "open"
|
||||
setOpenIndex(index || 0)
|
||||
},
|
||||
[setOpenIndex],
|
||||
[setOpenIndex, openDialogs, control.id],
|
||||
)
|
||||
|
||||
const close = React.useCallback<DialogControlProps['close']>(cb => {
|
||||
|
@ -85,11 +88,12 @@ export function Outer({
|
|||
closeCallback.current = undefined
|
||||
}
|
||||
|
||||
openDialogs.current.delete(control.id)
|
||||
onClose?.()
|
||||
setOpenIndex(-1)
|
||||
}
|
||||
},
|
||||
[onClose, setOpenIndex],
|
||||
[onClose, setOpenIndex, openDialogs, control.id],
|
||||
)
|
||||
|
||||
const context = React.useMemo(() => ({close}), [close])
|
||||
|
|
|
@ -12,6 +12,7 @@ import {DialogOuterProps, DialogInnerProps} from '#/components/Dialog/types'
|
|||
import {Context} from '#/components/Dialog/context'
|
||||
import {Button, ButtonIcon} from '#/components/Button'
|
||||
import {TimesLarge_Stroke2_Corner0_Rounded as X} from '#/components/icons/Times'
|
||||
import {useDialogStateContext} from '#/state/dialogs'
|
||||
|
||||
export {useDialogControl, useDialogContext} from '#/components/Dialog/context'
|
||||
export * from '#/components/Dialog/types'
|
||||
|
@ -29,18 +30,21 @@ export function Outer({
|
|||
const {gtMobile} = useBreakpoints()
|
||||
const [isOpen, setIsOpen] = React.useState(false)
|
||||
const [isVisible, setIsVisible] = React.useState(true)
|
||||
const {openDialogs} = useDialogStateContext()
|
||||
|
||||
const open = React.useCallback(() => {
|
||||
setIsOpen(true)
|
||||
}, [setIsOpen])
|
||||
openDialogs.current.add(control.id)
|
||||
}, [setIsOpen, openDialogs, control.id])
|
||||
|
||||
const close = React.useCallback(async () => {
|
||||
setIsVisible(false)
|
||||
await new Promise(resolve => setTimeout(resolve, 150))
|
||||
setIsOpen(false)
|
||||
setIsVisible(true)
|
||||
openDialogs.current.delete(control.id)
|
||||
onClose?.()
|
||||
}, [onClose, setIsOpen])
|
||||
}, [onClose, setIsOpen, openDialogs, control.id])
|
||||
|
||||
useImperativeHandle(
|
||||
control.ref,
|
||||
|
|
|
@ -6,11 +6,24 @@ import {ViewStyleProp} from '#/alf'
|
|||
|
||||
type A11yProps = Required<AccessibilityProps>
|
||||
|
||||
export type DialogControlProps = {
|
||||
/**
|
||||
* Mutated by useImperativeHandle to provide a public API for controlling the
|
||||
* dialog. The methods here will actually become the handlers defined within
|
||||
* the `Dialog.Outer` component.
|
||||
*/
|
||||
export type DialogControlRefProps = {
|
||||
open: (options?: DialogControlOpenOptions) => void
|
||||
close: (callback?: () => void) => void
|
||||
}
|
||||
|
||||
/**
|
||||
* The return type of the useDialogControl hook.
|
||||
*/
|
||||
export type DialogControlProps = DialogControlRefProps & {
|
||||
id: string
|
||||
ref: React.RefObject<DialogControlRefProps>
|
||||
}
|
||||
|
||||
export type DialogContextProps = {
|
||||
close: DialogControlProps['close']
|
||||
}
|
||||
|
@ -26,9 +39,7 @@ export type DialogControlOpenOptions = {
|
|||
}
|
||||
|
||||
export type DialogOuterProps = {
|
||||
control: {
|
||||
ref: React.RefObject<DialogControlProps>
|
||||
} & DialogControlProps
|
||||
control: DialogControlProps
|
||||
onClose?: () => void
|
||||
nativeOptions?: {
|
||||
sheet?: Omit<BottomSheetProps, 'children'>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue