import {message as antdMessage} from 'antd';
import PubSub from 'pubsub-js';
import {useEffect} from 'react'
export type NoticeType = 'info'|'success'|'error'|'warning'|'loading';
export interface ConfigOptions {
top?:number;
duration?: number;
prefixCls?: string;
transitionName?:string;
maxCount?: number;
maxCount?:number;
rtl?:boolean;
getContainer?:()=> HTMLElement;
}
export interface ArgsProps {
content: React.ReactNode;
duration?: number;
type?:NoticeType;
icon?: React.ReactNode;
key?:string|number;
style?:React.CSSProperties;
className?:string;
onClick?:(e: React.MouseEvent<HTMLDivElement>=>void;
onClose?:()=>void;
}
export type JointContent = React.ReactNode | ArgsProps;
export interface MessageType extends PromiseLike<boolean> {
():void;
}
export type TypeOpen = (
content: JointContent,
duration?:number| VoidFunction,
onClose?:VoidFunction,
)=>void;
interface MessageMethods {
info: TypeOpen;
success: TypeOpen;
error:TypeOpen;
warning: TypeOpen;
loading: TypeOpen;
}
interface AntdMessageEventConfig {
messageType: NoticeType;
content: JointContent;
duration?: number | VoidFunction;
onClose?: VoidFunction;
}
const isLegacyChrome = ()=>{
const ua = navigator.userAgent;
if(ua.indexOf('Chrome')===-1){
return false;
}
const version = parseInt(ua.split('Chrome/')[1],10);
return version < 89;
}
const ANTD_MESSAGE_EVENT = 'ANTD_MESSAGE_EVENT';
const messageAdapter = ()=> {
const message: Partial<MessageMethods> = {};
const typeList: NoticeType[] = ['info','success','error','warning','loading'];
typeList.forEach((messageType)=>{
message[messageType]=(
content: JointContent,
duratin?: number| VoidFunction,
onClose?: VoidFunction
)=>{
try{
PubSub.publish(ANTD_MESSAGE_EVENT, {messageType,content,duratin,onClose})
}catch(e){
console.error(e)
}
}
});
return message as MessageMethods;
}
const useMessageAdapter = ()=>{
const [messageApi, contextHolder] = antdMessage.useMessage();
useEffect(()=>{
if(!isLegacyChrome()) return;
const token = PubSub.subscribe(ANTD_MESSAGE_EVENT,(eventName, config:AntdMessageEventConfig)=>{
const {messageType,content,duratin,onClose} = config;
messageApi[messageType](content, duratin, onClose)
}
)
return ()=>{
PubSub.unsubscribe(token)
}
},[])
if(!isLegacyChrome()){
return [null];
}
return [contextHolder]
}
export { message, useMessageAdapter };
const message = isLegacyChrome() ? messageAdapter() : antdMessage;
export { message, useMessageAdapter };
使用
在应用入口,使用;
const Index = (){
const [globalContextHolder] = useMessageAdapter();
return <>
{globalContextHolder}
<App>
</>
}