73 lines
1.8 KiB
TypeScript
73 lines
1.8 KiB
TypeScript
import { FC, ReactNode } from 'react'
|
|
import { proxy, useSnapshot } from 'valtio'
|
|
import Button from '../Button'
|
|
import Flex from '../Flex'
|
|
import {
|
|
AlertDialog,
|
|
AlertDialogAction,
|
|
AlertDialogCancel,
|
|
AlertDialogContent,
|
|
AlertDialogDescription,
|
|
AlertDialogTitle
|
|
} from './primitive'
|
|
|
|
export interface AlertState {
|
|
isOpen: boolean
|
|
title?: string
|
|
body?: ReactNode
|
|
cancelText?: string
|
|
confirmText?: string
|
|
confirmPrefix?: ReactNode
|
|
onConfirm?: () => any
|
|
onCancel?: () => any
|
|
}
|
|
|
|
export const alertState = proxy<AlertState>({
|
|
isOpen: false
|
|
})
|
|
|
|
const Alert: FC = () => {
|
|
const {
|
|
title = 'Are you sure?',
|
|
isOpen,
|
|
body,
|
|
cancelText,
|
|
confirmText = 'Ok',
|
|
confirmPrefix,
|
|
onCancel,
|
|
onConfirm
|
|
} = useSnapshot(alertState)
|
|
return (
|
|
<AlertDialog open={isOpen} onOpenChange={value => (alertState.isOpen = value)}>
|
|
<AlertDialogContent>
|
|
<AlertDialogTitle>{title}</AlertDialogTitle>
|
|
<AlertDialogDescription>{body}</AlertDialogDescription>
|
|
<Flex css={{ justifyContent: 'flex-end', gap: '$3' }}>
|
|
{(cancelText || onCancel) && (
|
|
<AlertDialogCancel asChild>
|
|
<Button css={{ minWidth: '$16' }} outline onClick={onCancel}>
|
|
{cancelText || 'Cancel'}
|
|
</Button>
|
|
</AlertDialogCancel>
|
|
)}
|
|
<AlertDialogAction asChild>
|
|
<Button
|
|
css={{ minWidth: '$16' }}
|
|
variant="primary"
|
|
onClick={async () => {
|
|
await onConfirm?.()
|
|
alertState.isOpen = false
|
|
}}
|
|
>
|
|
{confirmPrefix}
|
|
{confirmText}
|
|
</Button>
|
|
</AlertDialogAction>
|
|
</Flex>
|
|
</AlertDialogContent>
|
|
</AlertDialog>
|
|
)
|
|
}
|
|
|
|
export default Alert
|