Skip to content

Commit

Permalink
fix: [message] 修复ts类型报错 fix #971
Browse files Browse the repository at this point in the history
  • Loading branch information
haohao_peng authored and albyben committed Dec 6, 2024
1 parent 6be1448 commit e8af301
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 53 deletions.
1 change: 1 addition & 0 deletions components/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ export { default as Modal } from './modal'
export { default as Menu } from './menu'

export { default as Message } from './message'
export type { ArgsProps as IMessageProps } from './message'

export { default as Notification } from './notification'

Expand Down
71 changes: 44 additions & 27 deletions components/message/demo/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,51 +9,68 @@ order: 1
import React from 'react'
import ReactDOM from 'react-dom'
import { Button, Message, Icon } from '@kdcloudjs/kdesign'
import type { IMessageProps } from '@kdcloudjs/kdesign'

const Demo: React.FC = () => {
const openConfig: IMessageProps = {
content: 'this is a base',
closable: true,
duration: 0
}
const successConfig: IMessageProps = {
content: <div>this is a jsx success</div>,
closable: true,
icon: <Icon type="user-info" />,
duration: 0
}
const warningConfig: IMessageProps = {
content: 'this is a warning',
icon: ''
}
const errorConfig: IMessageProps = {
content: 'this is a error',
closable: true
}
const base = () => {
Message.open({
content: 'this is a base',
closable: true,
duration: 0,
})
Message.open(openConfig)
}

const success = () => {
Message.success({
content: <div>this is a jsx success</div>,
closable: true,
icon: <Icon type="user-info" />,
duration: 0,
})
Message.success(successConfig)
}

const warning = () => {
Message.warning({
content: 'this is a warning',
icon: true,
})
Message.warning(warningConfig)
}

const error = () => {
Message.error({
content: 'this is a error',
closable: true,
})
Message.error(errorConfig)
}

return (
<div>
<Button style={{ marginRight: '12px' }} onClick={base}>
<Button
style={{
marginRight: '12px'
}}
onClick={base}>
base
</Button>
<Button style={{ marginRight: '12px' }} onClick={success}>
<Button
style={{
marginRight: '12px'
}}
onClick={success}>
success
</Button>
<Button style={{ marginRight: '12px' }} onClick={warning}>
<Button
style={{
marginRight: '12px'
}}
onClick={warning}>
warning
</Button>
<Button style={{ marginRight: '12px' }} onClick={error}>
<Button
style={{
marginRight: '12px'
}}
onClick={error}>
error
</Button>
</div>
Expand Down
43 changes: 22 additions & 21 deletions components/message/index.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import React from 'react'

import { NotificationProps } from '../notification-base/notification'
import NotificationApi from '../notification-base'
import Content from './content'
import { NotificationType } from '../notification-base/notice'

export type ConfigContent = React.ReactNode | string

export type JointContent = ConfigContent | ArgsProps

export interface ContentProps {
Expand All @@ -31,16 +29,16 @@ const defaultClosable = false
const defaultOffset = '40px'
const defaultSuffixCls = 'message'
const defaultPlacement = 'message'
const defaultType = 'info'
const defaultType: NotificationType = 'info'

let messageKey = 1
const messageElement: HTMLElement | null = null

function isArgsProps(content: any): content is ArgsProps {
function isArgsProps(content: unknown): content is ArgsProps {
return Object.prototype.toString.call(content) === '[object Object]' && !!(content as ArgsProps).content
}

const getNotificationProps = (args: ArgsProps) => {
const getNotificationProps = (args: ArgsProps): Partial<NotificationProps> => {
const {
duration = defaultDuration,
key,
Expand All @@ -54,16 +52,20 @@ const getNotificationProps = (args: ArgsProps) => {
closeNode,
} = args

// const placeStyle = getPlacementStyle(placement)

// const element = renderView(args)

const contentClose = () => {
onClose && onClose(key)
if (onClose) onClose(key)
NotificationApi.destroy(key)
}

const contentProps = { type, icon, closeNode, content, closable, suffixCls: defaultSuffixCls, contentClose }
const contentProps: ContentProps = {
type,
icon,
closeNode,
content,
closable,
suffixCls: defaultSuffixCls,
contentClose,
}

return {
duration,
Expand All @@ -79,34 +81,33 @@ const getNotificationProps = (args: ArgsProps) => {
}
}

const getNotificationHTMLElement = () => {
const getNotificationHTMLElement = (): HTMLElement => {
const prefixCls = 'kd'
const suffix = `${prefixCls}-message`
let htmlElement: HTMLElement = document.querySelector(`#${suffix}`) as HTMLElement
let htmlElement = document.querySelector(`#${suffix}`) as HTMLElement
if (!htmlElement) {
htmlElement = document.createElement('div')
htmlElement.id = suffix
htmlElement.className = `${suffix}-box`
htmlElement.style.top = defaultOffset
document.body.appendChild(htmlElement)
}

return htmlElement
}

const notice = (args: ArgsProps) => {
const key = args.key || messageKey++
const props = getNotificationProps({ ...args, key })
let el: HTMLElement
if (messageElement) {
el = messageElement
} else {
el = getNotificationHTMLElement()
}
const el = messageElement || getNotificationHTMLElement()
NotificationApi.add(props, el)
}

const Message: any = {
type MessageTypeFn = (content: JointContent, duration?: number, onClose?: () => void) => void

const Message: Record<string, MessageTypeFn> & {
open: (args: ArgsProps) => void
destroy: (key?: React.Key) => void
} = {
open: notice,
destroy: (key?: React.Key) => {
NotificationApi.destroy(key)
Expand Down
6 changes: 3 additions & 3 deletions components/notification-base/notice.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export interface NoticeProps {
content: React.ReactNode
closable: boolean
duration: number
onClose?: (key?: any) => void
onClose?: (key?: React.Key) => void
type?: NotificationType
suffixCls: string
key: React.Key
Expand All @@ -35,9 +35,9 @@ const Notice: FC<NoticeProps> = (props) => {
key,
} = noticeProps
const noticePrefixCls = getPrefixCls!(prefixCls, suffixCls, customPrefixcls)
let timer: any = null
let timer: ReturnType<typeof setTimeout> | null = null
let isTransition = false
const noticeRef = useRef<any>()
const noticeRef = useRef<HTMLDivElement>(null)

const noticeClasses = classNames(noticePrefixCls, className, {
[`${noticePrefixCls}-${type}`]: type,
Expand Down
11 changes: 9 additions & 2 deletions components/notification-base/notification.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ export interface NotificationProps extends NoticeProps {
placement: string
}

export interface INotificationRef {
add: (props: NotificationProps) => void
remove: (key?: React.Key) => void
placement: string
notices: NotificationProps[]
}

let seed = 0
const now = Date.now()

Expand All @@ -14,7 +21,7 @@ function getUuid() {
return `msg_${now}_${id}`
}

const Notification = React.forwardRef<unknown, NotificationProps>((props, ref) => {
const Notification = React.forwardRef<INotificationRef, NotificationProps>((props, ref) => {
const { placement } = props
const [notices, setNotices] = useState<NotificationProps[]>([])

Expand Down Expand Up @@ -47,7 +54,7 @@ const Notification = React.forwardRef<unknown, NotificationProps>((props, ref) =
}

const remove = (key: React.Key) => {
setNotices((preNotices) => preNotices.filter((notice: any) => notice.key !== key))
setNotices((preNotices) => preNotices.filter((notice: NotificationProps) => notice.key !== key))
}

const onClose = (notice: NotificationProps) => {
Expand Down

0 comments on commit e8af301

Please sign in to comment.