feat: rewrite message component

This commit is contained in:
qishaoxuan
2022-07-28 23:42:05 +08:00
parent d5f6ab0bb5
commit 0cce817813
10 changed files with 224 additions and 88 deletions

View File

@@ -0,0 +1,83 @@
import {
NotificationInstance,
type NotificationController,
type NotificationInstanceProps,
type NotificationContent,
type NotificationOption,
type NotificationKey,
} from '../notification';
import {
SuccessMessage,
ErrorMessage,
InfoMessage,
WarningMessage,
} from './MessageContent';
type MessageMethod = (
message: NotificationContent,
option?: Omit<NotificationOption, 'content'>
) => Promise<NotificationKey>;
export class Message {
private _notificationController: NotificationController = null;
private _notificationProps: NotificationInstanceProps = {};
constructor(props: NotificationInstanceProps) {
this._notificationProps = props;
}
private _ensureController() {
if (!this._notificationController) {
NotificationInstance(
this._notificationProps,
notificationController => {
this._notificationController = notificationController;
}
);
}
}
public success: MessageMethod = async (message, option) => {
await this._ensureController();
return this._notificationController.add(message, {
content: (key, message) => (
<SuccessMessage id={key} message={message} />
),
...option,
});
};
public error: MessageMethod = async (message, option) => {
await this._ensureController();
return this._notificationController.add(message, {
content: (key, message) => (
<ErrorMessage id={key} message={message} />
),
...option,
});
};
public warning: MessageMethod = async (message, option) => {
await this._ensureController();
return this._notificationController.add(message, {
content: (key, message) => (
<WarningMessage id={key} message={message} />
),
...option,
});
};
public info: MessageMethod = async (message, option) => {
await this._ensureController();
return this._notificationController.add(message, {
content: (key, message) => (
<InfoMessage id={key} message={message} />
),
...option,
});
};
}

View File

@@ -0,0 +1,69 @@
import { forwardRef } from 'react';
import { NotificationContentProps } from '../notification';
/* eslint-disable no-restricted-imports */
import Alert from '@mui/material/Alert';
// TODO: Variants types of message content await designers
const commonStyle = { background: '#fff' };
export const SuccessMessage = forwardRef<
HTMLDivElement,
NotificationContentProps
>(({ message, id }, ref) => {
return (
<Alert
variant="outlined"
severity="success"
ref={ref}
style={commonStyle}
>
{message}
</Alert>
);
});
export const ErrorMessage = forwardRef<
HTMLDivElement,
NotificationContentProps
>(({ message, id }, ref) => {
return (
<Alert
variant="outlined"
severity="error"
ref={ref}
style={commonStyle}
>
{message}
</Alert>
);
});
export const WarningMessage = forwardRef<
HTMLDivElement,
NotificationContentProps
>(({ message, id }, ref) => {
return (
<Alert
variant="outlined"
severity="warning"
ref={ref}
style={commonStyle}
>
{message}
</Alert>
);
});
export const InfoMessage = forwardRef<HTMLDivElement, NotificationContentProps>(
({ message, id }, ref) => {
return (
<Alert
variant="outlined"
severity="info"
ref={ref}
style={commonStyle}
>
{message}
</Alert>
);
}
);

View File

@@ -1,48 +0,0 @@
import type { FC, ReactNode } from 'react';
import { createRoot } from 'react-dom/client';
import { styled } from '../styled';
import type { ContainerProps } from './types';
interface ShowProps {
Container: FC<ContainerProps>;
/**
* 自动关闭延时,单位毫秒。设为 0 时,不自动关闭。默认 2000
*/
duration?: number;
content: ReactNode;
}
export const show = ({ Container, duration = 2000, content }: ShowProps) => {
const root_element = document.createElement('div');
document.body.appendChild(root_element);
function close() {
document.body.removeChild(root_element);
}
const react_root = createRoot(root_element);
react_root.render(
<PortalContainer>
<Container content={content} duration={duration} close={close} />
</PortalContainer>
);
if (duration > 0) {
setTimeout(() => {
close();
}, duration);
}
return close;
};
const PortalContainer = styled('div')({
position: 'fixed',
top: '100px',
left: '50%',
transform: 'translateX(-50%)',
backgroundColor: '#fff',
zIndex: 100,
});

View File

@@ -1,18 +1,9 @@
import type { ReactNode } from 'react';
import { Message } from './Message';
import { show } from './base';
import { Success } from './success';
interface SuccessProps {
/**
* 自动关闭延时单位毫秒。默认2000
*/
duration?: number;
content: ReactNode;
}
export const message = {
success({ duration, content }: SuccessProps) {
return show({ Container: Success, duration, content });
export const message = new Message({
anchorOrigin: {
vertical: 'top',
horizontal: 'center',
},
};
autoHideDuration: 2000,
});

View File

@@ -1,14 +0,0 @@
import type { FC } from 'react';
import { styled } from '../styled';
import type { ContainerProps } from './types';
export const Success: FC<ContainerProps> = ({ content }) => {
return <Container>{content}</Container>;
};
const Container = styled('div')({
maxWidth: '200px',
backgroundColor: 'rgba(64, 223, 155)',
borderRadius: '4px',
padding: '8px',
});

View File

@@ -1,7 +0,0 @@
import type { ReactNode } from 'react';
export interface ContainerProps {
content: ReactNode;
duration: number;
close: () => void;
}