Commit f4c86309 authored by Chunchi Che's avatar Chunchi Che

add modal shared component

parent d724a676
Pipeline #25388 passed with stages
in 15 minutes and 7 seconds
.title {
color: red;
}
.footer {
display: flex;
justify-content: flex-end;
gap: 12px;
}
.modal {
position: fixed;
left: 0;
right: 0;
top: 0 !important;
bottom: 0 !important;
top: -webkit-fill-available;
margin: auto;
height: fit-content;
transition: top 0.3s;
}
.mini {
top: 100% !important;
bottom: 0 !important;
transform: translateY(calc(50% - 66px));
}
.btn-minimize {
position: absolute;
right: 16px;
top: 16px;
}
import { MinusOutlined, UpOutlined } from "@ant-design/icons";
import { Button } from "antd";
import type { ModalFunc } from "antd/es/modal/confirm";
import classNames from "classnames";
import { proxy } from "valtio";
import styles from "./index.module.scss";
type PropsWithOnResult<Props extends {}, Result extends {}> = Props & {
onResult: (result: Result) => void;
};
export type ReactFcWithOnResult<Props extends {}, Result extends {}> = React.FC<
PropsWithOnResult<Props, Result>
>;
export const Title: React.FC<React.PropsWithChildren> = ({ children }) => (
<div className={styles.title}>{children}</div>
);
export const Footer: React.FC<React.PropsWithChildren> = ({ children }) => (
<div className={styles.footer}>{children}</div>
);
/**
* 目的是通过传入不同的 Content 组件和配置选项,生成不同类型的弹窗,并在弹窗的 Content 中处理回调,最终返回一个 Promise 来处理弹窗的结果。
*/
export const genModal = <Props extends {}, Result extends {}>({
api,
Content: _Content,
type = "confirm",
...rest
}: {
api: any;
Content: React.ComponentType<PropsWithOnResult<Props, Result>>;
type?: "confirm" | "info" | "success" | "error";
} & Omit<
Parameters<ModalFunc>[0],
"content" | "onCancel" | "onOk" | "footer" | "title"
>) => {
return (props: Props): Promise<Result> =>
new Promise<Result>((rs) => {
let isMini = proxy({ value: false });
const getClassNames = () =>
classNames(styles.modal, {
[styles.mini]: isMini.value,
});
// const Content = ContentWrap(_Content);
const BtnMini = () => (
<Button
icon={<MinusOutlined />}
onClick={function () {
isMini.value = !isMini.value;
update({ className: getClassNames(), title: BtnMax() });
}}
/>
);
const BtnMax = () => (
<Button
icon={<UpOutlined />}
onClick={function () {
isMini.value = !isMini.value;
update({ className: getClassNames(), title: BtnMini() });
}}
/>
);
const genMinimizeBtn = () => (
<Button
className={styles["btn-minimize"]}
type="text"
// size={16}
icon={isMini.value ? <UpOutlined /> : <MinusOutlined />}
onClick={() => {
isMini.value = !isMini.value;
update({ className: getClassNames(), title: genMinimizeBtn() });
}}
/>
);
const { destroy, update } = api[type]({
content: (
<div>
<_Content
onResult={(result) => {
rs(result);
destroy();
}}
{...props}
/>
</div>
),
icon: null,
title: genMinimizeBtn(),
footer: null,
centered: true,
className: getClassNames(),
onCancel: () => false,
...rest,
});
});
};
// function ContentWrap<P extends {}>(ChildrenComponent: React.ComponentType<P>) {
// return (props: P & { toggleMini: () => void; isMini: boolean }) => {
// return (
// <>
// <Button onClick={props.toggleMini} icon={props.isMini ? "a" : "b"} />
// <ChildrenComponent {...props} />
// </>
// );
// };
// }
......@@ -6,6 +6,7 @@ export * from "./DeckCard";
export * from "./DeckZone";
export * from "./IconFont";
export * from "./Loading";
export * from "./Modal";
export * from "./Scrollbar";
export * from "./Select";
export * from "./SpecialButton";
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment