| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192 | 
							- /* eslint-disable no-unreachable */
 
- import React from 'react';
 
- import cls from 'classnames';
 
- import PropTypes from 'prop-types';
 
- import ConfigContext, { ContextValue } from '../configProvider/context';
 
- import { cssClasses, numbers, strings } from '@douyinfe/semi-foundation/notification/constants';
 
- import NotificationFoundation, {
 
-     NoticeAdapter,
 
-     NoticeProps,
 
-     NoticeState
 
- } from '@douyinfe/semi-foundation/notification/notificationFoundation';
 
- import Button from '../iconButton';
 
- import BaseComponent from '../_base/baseComponent';
 
- import { isSemiIcon } from '../_utils';
 
- import { noop } from 'lodash';
 
- import { IconAlertCircle, IconAlertTriangle, IconClose, IconInfoCircle, IconTickCircle } from '@douyinfe/semi-icons';
 
- import { getUuidShort } from '@douyinfe/semi-foundation/utils/uuid';
 
- export interface NoticeReactProps extends NoticeProps {
 
-     style?: React.CSSProperties;
 
-     title?: React.ReactNode;
 
-     content?: React.ReactNode;
 
-     icon?: React.ReactNode;
 
-     onClick?: (e: React.MouseEvent) => void;
 
- }
 
- const prefixCls = cssClasses.NOTICE;
 
- const { duration } = numbers;
 
- const { types, themes, directions } = strings;
 
- class Notice extends BaseComponent<NoticeReactProps, NoticeState> {
 
-     static contextType = ConfigContext;
 
-     static propTypes = {
 
-         duration: PropTypes.number,
 
-         id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
 
-         title: PropTypes.node,
 
-         content: PropTypes.node, // strings、numbers、array、element
 
-         type: PropTypes.oneOf(types),
 
-         theme: PropTypes.oneOf(themes),
 
-         icon: PropTypes.node,
 
-         onClick: PropTypes.func,
 
-         onClose: PropTypes.func,
 
-         onCloseClick: PropTypes.func,
 
-         showClose: PropTypes.bool,
 
-         // private props
 
-         close: PropTypes.func,
 
-         direction: PropTypes.oneOf(directions),
 
-     };
 
-     static defaultProps = {
 
-         duration,
 
-         id: '',
 
-         close: noop,
 
-         onClose: noop,
 
-         onClick: noop,
 
-         onCloseClick: noop,
 
-         content: '',
 
-         title: '',
 
-         showClose: true,
 
-         theme: 'normal',
 
-     };
 
-     get adapter(): NoticeAdapter {
 
-         return {
 
-             ...super.adapter,
 
-             notifyWrapperToRemove: (id: string) => {
 
-                 this.props.close(id);
 
-             },
 
-             notifyClose: () => {
 
-                 this.props.onClose();
 
-                 this.props.onHookClose && this.props.onHookClose();
 
-             },
 
-         };
 
-     }
 
-     constructor(props: NoticeReactProps) {
 
-         super(props);
 
-         this.state = {
 
-             visible: true,
 
-         };
 
-         this.foundation = new NotificationFoundation(this.adapter);
 
-     }
 
-     context: ContextValue;
 
-     componentWillUnmount() {
 
-         this.foundation.destroy();
 
-     }
 
-     renderTypeIcon() {
 
-         const { type, icon } = this.props;
 
-         const iconMap = {
 
-             warning: <IconAlertTriangle size="large"/>,
 
-             success: <IconTickCircle size="large"/>,
 
-             info: <IconInfoCircle size="large"/>,
 
-             error: <IconAlertCircle size="large"/>,
 
-         };
 
-         let iconType = iconMap[type];
 
-         const iconCls = cls({
 
-             [`${prefixCls}-icon`]: true,
 
-             [`${prefixCls}-${type}`]: true,
 
-         });
 
-         if (icon) {
 
-             iconType = icon;
 
-         }
 
-         if (iconType) {
 
-             return (
 
-                 <div className={iconCls}>
 
-                     {isSemiIcon(iconType) ? React.cloneElement(iconType, { size: iconType.props.size || 'large' }) : iconType}
 
-                 </div>
 
-             );
 
-         }
 
-         return null;
 
-     }
 
-     clearCloseTimer = () => {
 
-         this.foundation._clearCloseTimer();
 
-     };
 
-     startCloseTimer = () => {
 
-         this.foundation._startCloseTimer();
 
-     };
 
-     close = (e: React.MouseEvent) => {
 
-         this.props.onCloseClick(this.props.id);
 
-         this.foundation.close(e);
 
-     };
 
-     notifyClick = (e: React.MouseEvent) => {
 
-         this.props.onClick(e);
 
-     };
 
-     render() {
 
-         const direction = this.props.direction || this.context.direction;
 
-         const defaultPosition = direction === 'rtl' ? 'topLeft' : 'topRight';
 
-         const {
 
-             content,
 
-             title,
 
-             theme,
 
-             position = defaultPosition,
 
-             type,
 
-             id,
 
-             onCloseClick,
 
-             className,
 
-             showClose,
 
-             style,
 
-             ...attr
 
-         } = this.props;
 
-         const { visible } = this.state;
 
-         const wrapper = cls(prefixCls, className, {
 
-             [`${prefixCls}-close`]: !visible,
 
-             [`${prefixCls}-icon-show`]: types.includes(type),
 
-             [`${prefixCls}-${type}`]: true,
 
-             [`${prefixCls}-${theme}`]: theme === 'light',
 
-             [`${prefixCls}-rtl`]: direction === 'rtl',
 
-         });
 
-         const titleID = getUuidShort({});
 
-         return (
 
-             // eslint-disable-next-line jsx-a11y/no-static-element-interactions
 
-             <div
 
-                 className={wrapper}
 
-                 style={style}
 
-                 onMouseEnter={this.clearCloseTimer}
 
-                 onMouseLeave={this.startCloseTimer}
 
-                 onClick={this.notifyClick}
 
-                 aria-labelledby={titleID}
 
-                 role={'alert'}
 
-             >
 
-                 <div>{this.renderTypeIcon()}</div>
 
-                 <div className={`${prefixCls}-inner`}>
 
-                     <div className={`${prefixCls}-content-wrapper`}>
 
-                         {title ? <div id={titleID} className={`${prefixCls}-title`}>{title}</div> : ''}
 
-                         {content ? <div className={`${prefixCls}-content`}>{content}</div> : ''}
 
-                     </div>
 
-                     {showClose && (
 
-                         <Button
 
-                             className={`${prefixCls}-icon-close`}
 
-                             type="tertiary"
 
-                             icon={<IconClose/>}
 
-                             theme="borderless"
 
-                             size="small"
 
-                             onClick={this.close}
 
-                         />
 
-                     )}
 
-                 </div>
 
-             </div>
 
-         );
 
-     }
 
- }
 
- export default Notice;
 
 
  |