123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 |
- import React, { useEffect, useRef, useState } from 'react'
- import { createPortal } from 'react-dom'
- import { useTranslation } from 'react-i18next'
- import Button from '../button'
- export type IConfirm = {
- className?: string
- isShow: boolean
- type?: 'info' | 'warning'
- title: string
- content?: React.ReactNode
- confirmText?: string | null
- onConfirm: () => void
- cancelText?: string
- onCancel: () => void
- isLoading?: boolean
- isDisabled?: boolean
- showConfirm?: boolean
- showCancel?: boolean
- maskClosable?: boolean
- }
- function Confirm({
- isShow,
- type = 'warning',
- title,
- content,
- confirmText,
- cancelText,
- onConfirm,
- onCancel,
- showConfirm = true,
- showCancel = true,
- isLoading = false,
- isDisabled = false,
- maskClosable = true,
- }: IConfirm) {
- const { t } = useTranslation()
- const dialogRef = useRef<HTMLDivElement>(null)
- const [isVisible, setIsVisible] = useState(isShow)
- const confirmTxt = confirmText || `${t('common.operation.confirm')}`
- const cancelTxt = cancelText || `${t('common.operation.cancel')}`
- useEffect(() => {
- const handleKeyDown = (event: KeyboardEvent) => {
- if (event.key === 'Escape')
- onCancel()
- }
- document.addEventListener('keydown', handleKeyDown)
- return () => {
- document.removeEventListener('keydown', handleKeyDown)
- }
- }, [onCancel])
- const handleClickOutside = (event: MouseEvent) => {
- if (maskClosable && dialogRef.current && !dialogRef.current.contains(event.target as Node))
- onCancel()
- }
- useEffect(() => {
- document.addEventListener('mousedown', handleClickOutside)
- return () => {
- document.removeEventListener('mousedown', handleClickOutside)
- }
- }, [maskClosable])
- useEffect(() => {
- if (isShow) {
- setIsVisible(true)
- }
- else {
- const timer = setTimeout(() => setIsVisible(false), 200)
- return () => clearTimeout(timer)
- }
- }, [isShow])
- if (!isVisible)
- return null
- return createPortal(
- <div className={'fixed inset-0 flex items-center justify-center z-[10000000] bg-background-overlay'}
- onClick={(e) => {
- e.preventDefault()
- e.stopPropagation()
- }}>
- <div ref={dialogRef} className={'relative w-full max-w-[480px] overflow-hidden'}>
- <div className='flex flex-col items-start max-w-full rounded-2xl border-[0.5px] border-solid border-components-panel-border shadows-shadow-lg bg-components-panel-bg'>
- <div className='flex pt-6 pl-6 pr-6 pb-4 flex-col items-start gap-2 self-stretch'>
- <div className='title-2xl-semi-bold text-text-primary'>{title}</div>
- <div className='system-md-regular text-text-tertiary w-full'>{content}</div>
- </div>
- <div className='flex p-6 gap-2 justify-end items-start self-stretch'>
- {showCancel && <Button onClick={onCancel}>{cancelTxt}</Button>}
- {showConfirm && <Button variant={'primary'} destructive={type !== 'info'} loading={isLoading} disabled={isDisabled} onClick={onConfirm}>{confirmTxt}</Button>}
- </div>
- </div>
- </div>
- </div>, document.body,
- )
- }
- export default React.memo(Confirm)
|