import React, { useState, useEffect } from 'react';
import { useTransition } from 'react-spring';
import {
Container,
Notification,
Content,
Life,
ErrorIcon,
Message,
SuccessIcon,
InfoIcon,
Spinner,
MessageContent,
MessageLife,
InfoIconNotification,
SuccessIconNotification,
ErrorIconNotification,
Title,
Desc,
CloseIcon,
} from './style';
export type IConfigObject = { timeout?: number; config?: { tension?: number; friction?: number; precision?: number } };
export type IMessageFn = (msg: string, messageConfig?: IConfigObject) => void;
export type IItem = { msg: string; key: number };
let id = 0;
const getMsgIcon = (type: 'info' | 'error' | 'success' | 'warning' | 'pending') => {
switch (type) {
case 'error':
return ;
case 'info':
return ;
case 'success':
return ;
case 'warning':
return ;
case 'pending':
return ;
}
};
const getNotificationIcon = (type: 'info' | 'error' | 'success' | 'warning') => {
switch (type) {
case 'error':
return ;
case 'info':
return ;
case 'success':
return ;
case 'warning':
return ;
}
};
function MessageHub({ children, type }: any) {
const config = { tension: 125, friction: 20, precision: 0.1, clamp: true };
const [refMap] = useState(() => new WeakMap());
const [cancelMap] = useState(() => new WeakMap());
const [items, setItems]: any[] = useState([]);
const [timeout, setTime] = useState(2000);
const transitions = useTransition(items, (item: any) => item.key, {
from: { opacity: 0, height: 0, life: '100%' },
enter: (item: any) => async (next: any) => await next({ opacity: 1, height: refMap.get(item).offsetHeight }),
leave: (item: any) => async (next: any, cancel: any) => {
cancelMap.set(item, cancel);
await next({ life: '0%' });
await next({ opacity: 0, height: 0, margin: 0, display: 'none' });
//await next({ height: 0 });
},
onRest: (item: any) => setItems((state: IItem[]) => state.filter((i: IItem) => i.key !== item.key)),
config: (item: IItem, springState: string) =>
springState === 'leave' ? [{ duration: timeout }, config, config] : config,
} as any);
useEffect(
() =>
void children((msg: string, { timeout, ...rest }: any) => {
const item = { key: id++, msg, ...rest };
setItems((state: IItem[]) => [...state, item]);
setTime(s => timeout);
return () => {
cancelMap.get(item) && cancelMap.get(item)();
setTimeout(() => {
cancelMap.get(item) && cancelMap.get(item)();
}, 1001);
};
}),
[]
);
return (
{transitions.map(({ key, item, props: { life, ...style } }: any) =>
type === 'notification' ? (
ref && refMap.set(item, ref)}
hasIcon={item.type}
data-alter={item.alternativeStyle}
>
{item.title && {item.title}}
{getNotificationIcon(item.type)}
{item.msg}
{item.showProgress && }
{
e.stopPropagation();
cancelMap.has(item) && cancelMap.get(item)();
}}
/>
) : (
ref && refMap.set(item, ref)}>
{getMsgIcon(item.type)}
{item.msg}
{item.showProgress && }
)
)}
);
}
export default React.forwardRef(function({ type }: any, ref: any) {
return (ref.current = add)} />;
});