You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
135 lines
3.9 KiB
135 lines
3.9 KiB
import { BellOutlined } from '@ant-design/icons';
|
|
import { Badge, Spin, Tabs } from 'antd';
|
|
import useMergeValue from 'use-merge-value';
|
|
import React from 'react';
|
|
import classNames from 'classnames';
|
|
import NoticeList, { NoticeIconTabProps } from './NoticeList';
|
|
|
|
import HeaderDropdown from '../HeaderDropdown';
|
|
import styles from './index.less';
|
|
|
|
const { TabPane } = Tabs;
|
|
|
|
export interface NoticeIconData {
|
|
avatar?: string | React.ReactNode;
|
|
title?: React.ReactNode;
|
|
description?: React.ReactNode;
|
|
datetime?: React.ReactNode;
|
|
extra?: React.ReactNode;
|
|
style?: React.CSSProperties;
|
|
key?: string | number;
|
|
read?: boolean;
|
|
}
|
|
|
|
export interface NoticeIconProps {
|
|
count?: number;
|
|
bell?: React.ReactNode;
|
|
className?: string;
|
|
loading?: boolean;
|
|
onClear?: (tabName: string, tabKey: string) => void;
|
|
onItemClick?: (item: NoticeIconData, tabProps: NoticeIconTabProps) => void;
|
|
onViewMore?: (tabProps: NoticeIconTabProps, e: MouseEvent) => void;
|
|
onTabChange?: (tabTile: string) => void;
|
|
style?: React.CSSProperties;
|
|
onPopupVisibleChange?: (visible: boolean) => void;
|
|
popupVisible?: boolean;
|
|
clearText?: string;
|
|
viewMoreText?: string;
|
|
clearClose?: boolean;
|
|
emptyImage?: string;
|
|
children: React.ReactElement<NoticeIconTabProps>[];
|
|
}
|
|
|
|
const NoticeIcon: React.FC<NoticeIconProps> & {
|
|
Tab: typeof NoticeList;
|
|
} = props => {
|
|
const getNotificationBox = (): React.ReactNode => {
|
|
const {
|
|
children,
|
|
loading,
|
|
onClear,
|
|
onTabChange,
|
|
onItemClick,
|
|
onViewMore,
|
|
clearText,
|
|
viewMoreText,
|
|
} = props;
|
|
if (!children) {
|
|
return null;
|
|
}
|
|
const panes: React.ReactNode[] = [];
|
|
React.Children.forEach(children, (child: React.ReactElement<NoticeIconTabProps>): void => {
|
|
if (!child) {
|
|
return;
|
|
}
|
|
const { list, title, count, tabKey, showClear, showViewMore } = child.props;
|
|
const len = list && list.length ? list.length : 0;
|
|
const msgCount = count || count === 0 ? count : len;
|
|
const tabTitle: string = msgCount > 0 ? `${title} (${msgCount})` : title;
|
|
panes.push(
|
|
<TabPane tab={tabTitle} key={tabKey}>
|
|
<NoticeList
|
|
clearText={clearText}
|
|
viewMoreText={viewMoreText}
|
|
data={list}
|
|
onClear={(): void => onClear && onClear(title, tabKey)}
|
|
onClick={(item): void => onItemClick && onItemClick(item, child.props)}
|
|
onViewMore={(event): void => onViewMore && onViewMore(child.props, event)}
|
|
showClear={showClear}
|
|
showViewMore={showViewMore}
|
|
title={title}
|
|
{...child.props}
|
|
/>
|
|
</TabPane>,
|
|
);
|
|
});
|
|
return (
|
|
<Spin spinning={loading} delay={300}>
|
|
<Tabs className={styles.tabs} onChange={onTabChange}>
|
|
{panes}
|
|
</Tabs>
|
|
</Spin>
|
|
);
|
|
};
|
|
|
|
const { className, count, bell } = props;
|
|
|
|
const [visible, setVisible] = useMergeValue<boolean>(false, {
|
|
value: props.popupVisible,
|
|
onChange: props.onPopupVisibleChange,
|
|
});
|
|
const noticeButtonClass = classNames(className, styles.noticeButton);
|
|
const notificationBox = getNotificationBox();
|
|
const NoticeBellIcon = bell || <BellOutlined className={styles.icon} />;
|
|
const trigger = (
|
|
<span className={classNames(noticeButtonClass, { opened: visible })}>
|
|
<Badge count={count} style={{ boxShadow: 'none' }} className={styles.badge}>
|
|
{NoticeBellIcon}
|
|
</Badge>
|
|
</span>
|
|
);
|
|
if (!notificationBox) {
|
|
return trigger;
|
|
}
|
|
|
|
return (
|
|
<HeaderDropdown
|
|
placement="bottomRight"
|
|
overlay={notificationBox}
|
|
overlayClassName={styles.popover}
|
|
trigger={['click']}
|
|
visible={visible}
|
|
onVisibleChange={setVisible}
|
|
>
|
|
{trigger}
|
|
</HeaderDropdown>
|
|
);
|
|
};
|
|
|
|
NoticeIcon.defaultProps = {
|
|
emptyImage: 'https://gw.alipayobjects.com/zos/rmsportal/wAhyIChODzsoKIOBHcBk.svg',
|
|
};
|
|
|
|
NoticeIcon.Tab = NoticeList;
|
|
|
|
export default NoticeIcon;
|
|
|