|
|
@ -1,15 +1,43 @@ |
|
|
|
import React from 'react'; |
|
|
|
import Notification from 'rc-notification'; |
|
|
|
import Icon from '../icon'; |
|
|
|
|
|
|
|
export type NotificationPlacement = 'topLeft' | 'topRight' | 'bottomLeft' | 'bottomRight'; |
|
|
|
|
|
|
|
const notificationInstance = {}; |
|
|
|
let defaultDuration = 4.5; |
|
|
|
let defaultTop = 24; |
|
|
|
let defaultBottom = 24; |
|
|
|
let defaultPlacement = 'topRight'; |
|
|
|
let defaultPlacement: NotificationPlacement = 'topRight'; |
|
|
|
let defaultGetContainer; |
|
|
|
export type notificationPlacement = 'topLeft' | 'topRight' | 'bottomLeft' | 'bottomRight'; |
|
|
|
|
|
|
|
function getPlacementStyle(placement) { |
|
|
|
export interface ConfigProps { |
|
|
|
top?: number; |
|
|
|
bottom?: number; |
|
|
|
duration?: number; |
|
|
|
placement?: NotificationPlacement; |
|
|
|
getContainer?: () => HTMLElement; |
|
|
|
} |
|
|
|
function setNotificationConfig(options: ConfigProps) { |
|
|
|
const { duration, placement, bottom, top, getContainer } = options; |
|
|
|
if (duration !== undefined) { |
|
|
|
defaultDuration = duration; |
|
|
|
} |
|
|
|
if (placement !== undefined) { |
|
|
|
defaultPlacement = placement; |
|
|
|
} |
|
|
|
if (bottom !== undefined) { |
|
|
|
defaultBottom = bottom; |
|
|
|
} |
|
|
|
if (top !== undefined) { |
|
|
|
defaultTop = top; |
|
|
|
} |
|
|
|
if (getContainer !== undefined) { |
|
|
|
defaultGetContainer = getContainer; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
function getPlacementStyle(placement: NotificationPlacement) { |
|
|
|
let style; |
|
|
|
switch (placement) { |
|
|
|
case 'topLeft': |
|
|
@ -19,6 +47,13 @@ function getPlacementStyle(placement) { |
|
|
|
bottom: 'auto', |
|
|
|
}; |
|
|
|
break; |
|
|
|
case 'topRight': |
|
|
|
style = { |
|
|
|
right: 0, |
|
|
|
top: defaultTop, |
|
|
|
bottom: 'auto', |
|
|
|
}; |
|
|
|
break; |
|
|
|
case 'bottomLeft': |
|
|
|
style = { |
|
|
|
left: 0, |
|
|
@ -26,23 +61,37 @@ function getPlacementStyle(placement) { |
|
|
|
bottom: defaultBottom, |
|
|
|
}; |
|
|
|
break; |
|
|
|
case 'bottomRight': |
|
|
|
default: |
|
|
|
style = { |
|
|
|
right: 0, |
|
|
|
top: 'auto', |
|
|
|
bottom: defaultBottom, |
|
|
|
}; |
|
|
|
break; |
|
|
|
default: |
|
|
|
style = { |
|
|
|
right: 0, |
|
|
|
top: defaultTop, |
|
|
|
bottom: 'auto', |
|
|
|
}; |
|
|
|
} |
|
|
|
return style; |
|
|
|
} |
|
|
|
|
|
|
|
function getNotificationInstance(prefixCls, placement) { |
|
|
|
const cacheKey = `${prefixCls}-${placement}`; |
|
|
|
if (!notificationInstance[cacheKey]) { |
|
|
|
notificationInstance[cacheKey] = (Notification as any).newInstance({ |
|
|
|
prefixCls, |
|
|
|
className: `${prefixCls}-${placement}`, |
|
|
|
style: getPlacementStyle(placement), |
|
|
|
getContainer: defaultGetContainer, |
|
|
|
}); |
|
|
|
} |
|
|
|
return notificationInstance[cacheKey]; |
|
|
|
} |
|
|
|
|
|
|
|
const typeToIcon = { |
|
|
|
success: 'check-circle-o', |
|
|
|
info: 'info-circle-o', |
|
|
|
error: 'cross-circle-o', |
|
|
|
warning: 'exclamation-circle-o', |
|
|
|
}; |
|
|
|
|
|
|
|
export interface ArgsProps { |
|
|
|
message: React.ReactNode; |
|
|
|
description: React.ReactNode; |
|
|
@ -51,67 +100,18 @@ export interface ArgsProps { |
|
|
|
onClose?: () => void; |
|
|
|
duration?: number; |
|
|
|
icon?: React.ReactNode; |
|
|
|
placement?: notificationPlacement; |
|
|
|
placement?: NotificationPlacement; |
|
|
|
style?: string; |
|
|
|
prefixCls?: string; |
|
|
|
className?: string; |
|
|
|
readonly type?: string; |
|
|
|
} |
|
|
|
|
|
|
|
export interface ConfigProps { |
|
|
|
top?: number; |
|
|
|
bottom?: number; |
|
|
|
duration?: number; |
|
|
|
placement?: notificationPlacement; |
|
|
|
getContainer?: () => HTMLElement; |
|
|
|
} |
|
|
|
|
|
|
|
function getNotificationInstance(prefixCls) { |
|
|
|
if (notificationInstance[defaultPlacement]) { |
|
|
|
return notificationInstance[defaultPlacement]; |
|
|
|
} |
|
|
|
notificationInstance[defaultPlacement] = (Notification as any).newInstance({ |
|
|
|
prefixCls: prefixCls, |
|
|
|
className: `${prefixCls}-${defaultPlacement}`, |
|
|
|
style: getPlacementStyle(defaultPlacement), |
|
|
|
getContainer: defaultGetContainer, |
|
|
|
}); |
|
|
|
return notificationInstance[defaultPlacement]; |
|
|
|
} |
|
|
|
|
|
|
|
function notice(args) { |
|
|
|
function notice(args: ArgsProps) { |
|
|
|
const outerPrefixCls = args.prefixCls || 'ant-notification'; |
|
|
|
const prefixCls = `${outerPrefixCls}-notice`; |
|
|
|
const duration = args.duration === undefined ? defaultDuration : args.duration; |
|
|
|
|
|
|
|
if (args.placement !== undefined) { |
|
|
|
defaultPlacement = args.placement; |
|
|
|
} |
|
|
|
|
|
|
|
let duration; |
|
|
|
if (args.duration === undefined) { |
|
|
|
duration = defaultDuration; |
|
|
|
} else { |
|
|
|
duration = args.duration; |
|
|
|
} |
|
|
|
|
|
|
|
let iconType = ''; |
|
|
|
switch (args.type) { |
|
|
|
case 'success': |
|
|
|
iconType = 'check-circle-o'; |
|
|
|
break; |
|
|
|
case 'info': |
|
|
|
iconType = 'info-circle-o'; |
|
|
|
break; |
|
|
|
case 'error': |
|
|
|
iconType = 'cross-circle-o'; |
|
|
|
break; |
|
|
|
case 'warning': |
|
|
|
iconType = 'exclamation-circle-o'; |
|
|
|
break; |
|
|
|
default: |
|
|
|
iconType = 'info-circle'; |
|
|
|
} |
|
|
|
|
|
|
|
let iconNode; |
|
|
|
let iconNode: React.ReactNode = null; |
|
|
|
if (args.icon) { |
|
|
|
iconNode = ( |
|
|
|
<span className={`${prefixCls}-icon`}> |
|
|
@ -119,15 +119,20 @@ function notice(args) { |
|
|
|
</span> |
|
|
|
); |
|
|
|
} else if (args.type) { |
|
|
|
iconNode = <Icon className={`${prefixCls}-icon ${prefixCls}-icon-${args.type}`} type={iconType} />; |
|
|
|
const iconType = typeToIcon[args.type]; |
|
|
|
iconNode = ( |
|
|
|
<Icon |
|
|
|
className={`${prefixCls}-icon ${prefixCls}-icon-${args.type}`} |
|
|
|
type={iconType} |
|
|
|
/> |
|
|
|
); |
|
|
|
} |
|
|
|
|
|
|
|
const autoMarginTag = (!args.description && iconNode) |
|
|
|
? <span className={`${prefixCls}-message-single-line-auto-margin`} /> |
|
|
|
: null; |
|
|
|
|
|
|
|
const { style, className } = args; |
|
|
|
getNotificationInstance(outerPrefixCls).notice({ |
|
|
|
getNotificationInstance(outerPrefixCls, args.placement || defaultPlacement).notice({ |
|
|
|
content: ( |
|
|
|
<div className={iconNode ? `${prefixCls}-with-icon` : ''}> |
|
|
|
{iconNode} |
|
|
@ -143,62 +148,22 @@ function notice(args) { |
|
|
|
closable: true, |
|
|
|
onClose: args.onClose, |
|
|
|
key: args.key, |
|
|
|
style: { ...style }, |
|
|
|
className, |
|
|
|
style: args.style || {}, |
|
|
|
className: args.className, |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
export interface NotificationApi { |
|
|
|
success(args: ArgsProps): void; |
|
|
|
error(args: ArgsProps): void; |
|
|
|
info(args: ArgsProps): void; |
|
|
|
warn(args: ArgsProps): void; |
|
|
|
warning(args: ArgsProps): void; |
|
|
|
open(args: ArgsProps): void; |
|
|
|
close(key: string): void; |
|
|
|
config(options: ConfigProps): void; |
|
|
|
destroy(): void; |
|
|
|
} |
|
|
|
|
|
|
|
const api = { |
|
|
|
open(args: ArgsProps) { |
|
|
|
notice(args); |
|
|
|
}, |
|
|
|
const api: any = { |
|
|
|
open: notice, |
|
|
|
close(key) { |
|
|
|
if (notificationInstance[defaultPlacement]) { |
|
|
|
notificationInstance[defaultPlacement].removeNotice(key); |
|
|
|
} |
|
|
|
}, |
|
|
|
config(options: ConfigProps) { |
|
|
|
const { duration, placement, bottom, top, getContainer } = options; |
|
|
|
if (placement !== undefined) { |
|
|
|
defaultPlacement = placement; |
|
|
|
} |
|
|
|
if (bottom !== undefined) { |
|
|
|
defaultBottom = bottom; |
|
|
|
} |
|
|
|
if (top !== undefined) { |
|
|
|
defaultTop = top; |
|
|
|
} |
|
|
|
if (getContainer !== undefined) { |
|
|
|
defaultGetContainer = getContainer; |
|
|
|
} |
|
|
|
// delete notificationInstance
|
|
|
|
if (placement !== undefined || bottom !== undefined || top !== undefined) { |
|
|
|
const notify = notificationInstance[defaultPlacement]; |
|
|
|
if (notify) { |
|
|
|
notify.destroy(); |
|
|
|
} |
|
|
|
delete notificationInstance[defaultPlacement]; |
|
|
|
} |
|
|
|
if (duration !== undefined) { |
|
|
|
defaultDuration = duration; |
|
|
|
} |
|
|
|
Object.keys(notificationInstance) |
|
|
|
.forEach(cacheKey => notificationInstance[cacheKey].removeNotice(key)); |
|
|
|
}, |
|
|
|
config: setNotificationConfig, |
|
|
|
destroy() { |
|
|
|
Object.keys(notificationInstance).forEach(key => { |
|
|
|
notificationInstance[key].destroy(); |
|
|
|
delete notificationInstance[key]; |
|
|
|
Object.keys(notificationInstance).forEach(cacheKey => { |
|
|
|
notificationInstance[cacheKey].destroy(); |
|
|
|
delete notificationInstance[cacheKey]; |
|
|
|
}); |
|
|
|
}, |
|
|
|
}; |
|
|
@ -210,6 +175,17 @@ const api = { |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
(api as any).warn = (api as any).warning; |
|
|
|
api.warn = api.warning; |
|
|
|
|
|
|
|
export interface NotificationApi { |
|
|
|
success(args: ArgsProps): void; |
|
|
|
error(args: ArgsProps): void; |
|
|
|
info(args: ArgsProps): void; |
|
|
|
warn(args: ArgsProps): void; |
|
|
|
warning(args: ArgsProps): void; |
|
|
|
open(args: ArgsProps): void; |
|
|
|
close(key: string): void; |
|
|
|
config(options: ConfigProps): void; |
|
|
|
destroy(): void; |
|
|
|
} |
|
|
|
export default api as NotificationApi; |
|
|
|