import React, { CSSProperties, HTMLAttributes, ReactNode, useEffect, useRef, useState } from 'react'
import classnames from 'classnames'
import { usePrefix } from '../ConfigProvider'
import { concat } from '../utils'
import { CheckCircleFilledIcon, InfoFilledIcon, TipFilledIcon, CloseCircleFilledIcon } from '../icons'
import { WithRef } from '../utils/type'
export { default as ToasterContainer } from './Container'
export type { Props as ToasterContainerProps } from './Container'
export type ToasterType = 'info' | 'error' | 'success' | 'warning'
export type ToasterProps = {
type?: ToasterType
message: ReactNode
className?: string
style?: CSSProperties
/**
* 根元素的 html 属性
*/
rootHtmlProps?: WithRef, HTMLDivElement>
}
export default function Toaster(props: ToasterProps) {
const { className, message, type = 'info', rootHtmlProps, style } = props
const prefix = usePrefix('toaster')
const typePrefix = concat(prefix, type)
const iconPrefix = concat(prefix, 'icon')
const messagePrefix = concat(prefix, 'message')
const innerIcon = getIconByType(type)
const cls = classnames(
className, prefix, typePrefix, rootHtmlProps?.className
)
return (
)
}
function getIconByType(type: ToasterType) {
switch (type) {
case 'info':
default:
return
case 'success':
return
case 'error':
return
case 'warning':
return
}
}
export type AnimatedToasterProps = Pick & {
/** 显示/隐藏 Toaster。消失动画需要先把 visible 设置为 false,等动画完成后再移除元素 */
visible?: boolean
/** 自定义样式名 */
className?: string
/** 自定义样式。注意:不支持自定义高度,height 设置会被忽略 */
style?: CSSProperties
}
export function AnimatedToaster({ visible = true, className, style, ...props }: AnimatedToasterProps) {
const prefix = usePrefix('toaster-animate-container')
const childRef = useRef(null)
const [height, setHeight] = useState(0)
useEffect(() => {
setHeight(visible && childRef.current ? childRef.current.offsetHeight : 0)
}, [visible, props.message])
const targetClass = concat(prefix, height > 0 ? 'show' : 'hide')
return (
)
}