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
 |