Skip to content

Commit

Permalink
feat: notification 组件插件化使用方式破坏性修改,支持 NotificationPlugin,notification …
Browse files Browse the repository at this point in the history
…的调用,废弃 Notification.info
  • Loading branch information
kenzyyang committed Dec 7, 2021
1 parent 94eeafa commit 98c3d0a
Show file tree
Hide file tree
Showing 7 changed files with 98 additions and 97 deletions.
85 changes: 4 additions & 81 deletions src/notification/Notification.tsx
Original file line number Diff line number Diff line change
@@ -1,37 +1,14 @@
import * as React from 'react';
import { CloseIcon, InfoCircleFilledIcon, CheckCircleFilledIcon } from 'tdesign-icons-react';
import { CheckCircleFilledIcon, CloseIcon, InfoCircleFilledIcon } from 'tdesign-icons-react';
import noop from '../_util/noop';
import useConfig from '../_util/useConfig';

import {
NotificationCloseMethod,
NotificationErrorMethod,
NotificationInfoMethod,
NotificationSuccessMethod,
NotificationWarningMethod,
TdNotificationProps,
NotificationThemeList,
NotificationInfoOptions,
NotificationInstance,
NotificationPlacementList,
NotificationCloseAllMethod,
} from './type';
import { NotificationInstance, TdNotificationProps } from './type';
import { Styles } from '../common';
import { fetchListInstance, listMap } from './NotificationList';

const blockName = 'notification';

// 扩展接口声明的结构,用户使用时可得到 .info 的 ts 提示
interface Notification extends React.FC<TdNotificationProps> {
info: NotificationInfoMethod;
success: NotificationSuccessMethod;
warning: NotificationWarningMethod;
error: NotificationErrorMethod;
closeAll: NotificationCloseAllMethod;
close: NotificationCloseMethod;
}

interface NotificationProps extends TdNotificationProps {
export interface NotificationProps extends TdNotificationProps {
style?: Styles;
}

Expand Down Expand Up @@ -150,58 +127,4 @@ export const NotificationComponent = React.forwardRef<any, NotificationProps>((p
);
});

/**
* @author kenzyyang
* @date 2021-05-30 22:54:39
* @desc 函数调用时的渲染函数
* @param theme 主题类型
* @param options 通知的参数
*/
const renderNotification = (theme: NotificationThemeList, options: NotificationInfoOptions) => {
if (typeof options !== 'object') return;

const placement: NotificationPlacementList = (() => {
if (['top-left', 'top-right', 'bottom-left', 'bottom-right'].indexOf(options.placement) >= 0) {
return options.placement;
}
return 'top-right';
})();

const attach: HTMLElement = (() => {
if (options.attach && typeof options.attach === 'string') {
const element: Element = document.querySelector(options.attach);
if (element instanceof HTMLElement) return element;
}

if (options.attach instanceof HTMLElement) return options.attach;

const containerId = `tdesign-notification-${placement}`;
const container = document.querySelector(`#${containerId}`);
if (container && container instanceof HTMLElement) {
return container;
}

const element: HTMLDivElement = document.createElement('div');
element.setAttribute('id', containerId);
document.body.appendChild(element);
return element;
})();

const zIndex = options.zIndex || 6000;

return fetchListInstance(placement, attach, zIndex).then((listInstance) => listInstance.push(theme, options));
};

// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
const Notification: Notification = NotificationComponent;

['info', 'success', 'warning', 'error'].forEach((theme: NotificationThemeList) => {
Notification[theme] = (options) => renderNotification(theme, options);
});

Notification.close = (promise) => promise.then((instance) => instance.close());

Notification.closeAll = () => listMap.forEach((list) => list.removeAll());

export default Notification;
export default NotificationComponent;
75 changes: 75 additions & 0 deletions src/notification/NotificationPlugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { fetchListInstance, listMap } from 'tdesign-react/notification/NotificationList';
import {
NotificationCloseAllMethod,
NotificationCloseMethod,
NotificationErrorMethod,
NotificationInfoMethod,
NotificationInfoOptions,
NotificationInstance,
NotificationOptions,
NotificationPlacementList,
NotificationSuccessMethod,
NotificationThemeList,
NotificationWarningMethod,
} from 'tdesign-react';

// 扩展接口声明的结构,用户使用时可得到 .info 的 ts 提示
interface Notification {
(theme: NotificationThemeList, options: NotificationOptions): Promise<NotificationInstance>;
info: NotificationInfoMethod;
success: NotificationSuccessMethod;
warning: NotificationWarningMethod;
error: NotificationErrorMethod;
closeAll: NotificationCloseAllMethod;
close: NotificationCloseMethod;
}

/**
* @desc 函数调用时的渲染函数
* @param theme 主题类型
* @param options 通知的参数
*/
const renderNotification = (theme: NotificationThemeList, options: NotificationInfoOptions) => {
if (typeof options !== 'object') return;

const placement: NotificationPlacementList = (() => {
if (['top-left', 'top-right', 'bottom-left', 'bottom-right'].indexOf(options.placement) >= 0) {
return options.placement;
}
return 'top-right';
})();

const attach: HTMLElement = (() => {
if (options.attach && typeof options.attach === 'string') {
const element: Element = document.querySelector(options.attach);
if (element instanceof HTMLElement) return element;
}

if (options.attach instanceof HTMLElement) return options.attach;

const containerId = `tdesign-notification-${placement}`;
const container = document.querySelector(`#${containerId}`);
if (container && container instanceof HTMLElement) {
return container;
}

const element: HTMLDivElement = document.createElement('div');
element.setAttribute('id', containerId);
document.body.appendChild(element);
return element;
})();

const zIndex = options.zIndex || 6000;

return fetchListInstance(placement, attach, zIndex).then((listInstance) => listInstance.push(theme, options));
};

export const NotificationPlugin: Notification = (theme, props) => renderNotification(theme, props);
NotificationPlugin.info = (options) => renderNotification('info', options);
NotificationPlugin.success = (options) => renderNotification('success', options);
NotificationPlugin.warning = (options) => renderNotification('warning', options);
NotificationPlugin.error = (options) => renderNotification('error', options);
NotificationPlugin.close = (promise) => promise.then((instance) => instance.close());
NotificationPlugin.closeAll = () => listMap.forEach((list) => list.removeAll());

export const notification = NotificationPlugin;
12 changes: 6 additions & 6 deletions src/notification/_example/close-all.jsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,31 @@
import React from 'react';
import { Notification, Button } from 'tdesign-react';
import { NotificationPlugin, Button } from 'tdesign-react';

export default function NotificationExample() {
const openMore = React.useCallback(() => {
Notification.info({
NotificationPlugin.info({
title: '标题名称',
content: '这是一条需要手动关闭的消息通知',
duration: 0,
});
Notification.warning({
NotificationPlugin.warning({
title: '标题名称',
content: '这是第二条通知',
duration: 0,
});
Notification.error({
NotificationPlugin.error({
title: '标题名称',
content: '这是第三条通知',
duration: 0,
});
}, []);

const closeAll = React.useCallback(() => {
Notification.closeAll();
NotificationPlugin.closeAll();
}, []);

return (
<div className="tdesign-demo-block-row">
<div className='tdesign-demo-block-row'>
<Button onClick={openMore}>点击打开多个消息</Button>
<Button onClick={closeAll}>点击关闭多个消息</Button>
</div>
Expand Down
4 changes: 2 additions & 2 deletions src/notification/_example/placement.jsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import React, { useState } from 'react';
import { Notification, Button, Input } from 'tdesign-react';
import { NotificationPlugin, Button, Input } from 'tdesign-react';

export default function NotificationExample() {
const [offsetY, setOffsetY] = useState('');
const [offsetX, setOffsetX] = useState('');

const openNotification = React.useCallback(
(placement) => {
Notification.info({
NotificationPlugin.info({
title: '标题名称',
content: '这是一条可以自动关闭的消息通知',
placement,
Expand Down
10 changes: 5 additions & 5 deletions src/notification/_example/plugin.jsx
Original file line number Diff line number Diff line change
@@ -1,33 +1,33 @@
import React from 'react';
import { Notification, Button } from 'tdesign-react';
import { NotificationPlugin, Button } from 'tdesign-react';

export default function NotificationExample() {
const openInfoNotification = React.useCallback(() => {
Notification.info({
NotificationPlugin.info({
title: '信息',
content: '这是一条可以自动关闭的消息通知',
duration: 3000,
});
}, []);

const openSuccessNotification = React.useCallback(() => {
Notification.success({
NotificationPlugin.success({
title: '信息',
content: '这是一条可以自动关闭的消息通知',
duration: 3000,
});
}, []);

const openWarningNotification = React.useCallback(() => {
Notification.warning({
NotificationPlugin.warning({
title: '信息',
content: '这是一条可以自动关闭的消息通知',
duration: 3000,
});
}, []);

const openErrorNotification = React.useCallback(() => {
Notification.error({
NotificationPlugin.error({
title: '信息',
content: '这是一条可以自动关闭的消息通知',
duration: 3000,
Expand Down
6 changes: 3 additions & 3 deletions src/notification/_example/toggle.jsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import React from 'react';
import { Notification, Button } from 'tdesign-react';
import { NotificationPlugin, Button } from 'tdesign-react';

export default function NotificationExample() {
const openNotification = React.useCallback(() => {
const notification = Notification.info({
const notification = NotificationPlugin.info({
title: '信息',
content: '这是一条可以自动关闭的消息通知',
onCloseBtnClick: () => {
notification.then((instance) => instance.close());
Notification.close(notification);
NotificationPlugin.close(notification);
},
});
}, []);
Expand Down
3 changes: 3 additions & 0 deletions src/notification/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,7 @@ import './style/index.js';
export * from './type';

export const Notification = _Notification;

export { NotificationPlugin, notification } from './NotificationPlugin';

export default Notification;

0 comments on commit 98c3d0a

Please sign in to comment.