Files
supabase/apps/studio/hooks/ui/useConfirmOnClose.tsx
CharisandAlaister Young 8828c4e734 refactor(close confirmation modal): abstract out useConfirmOnClose hook (#40310)
Abstract out a hook, useConfirmOnClose, for the pattern where we show a
confirmation modal on close, conditional on whether the user has made
edits.

---------

Co-authored-by: Alaister Young <a@alaisteryoung.com>
2025-11-11 13:34:50 -05:00

57 lines
1.2 KiB
TypeScript

import { useCallback, useMemo, useState } from 'react'
import useLatest from '../misc/useLatest'
export interface ConfirmOnCloseModalProps {
visible: boolean
onClose: () => void
onCancel: () => void
}
interface UseConfirmOnCloseProps {
checkIsDirty: () => boolean
onClose: () => void
}
export const useConfirmOnClose = ({ checkIsDirty, onClose }: UseConfirmOnCloseProps) => {
const [visible, setVisible] = useState(false)
const checkIsDirtyRef = useLatest(checkIsDirty)
const onCloseRef = useLatest(onClose)
const confirmOnClose = useCallback(() => {
if (checkIsDirtyRef.current()) {
setVisible(true)
} else {
onCloseRef.current()
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
const onConfirm = useCallback(() => {
setVisible(false)
onCloseRef.current()
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
const onCancel = useCallback(() => {
setVisible(false)
}, [])
const modalProps: ConfirmOnCloseModalProps = useMemo(
() => ({
visible,
onClose: onConfirm,
onCancel,
}),
[visible, onConfirm, onCancel]
)
return useMemo(
() => ({
confirmOnClose,
modalProps,
}),
[confirmOnClose, modalProps]
)
}