114 lines
2.9 KiB
TypeScript
114 lines
2.9 KiB
TypeScript
import { Drawer, Button, Space, Tabs } from "antd";
|
|
import { CloseOutlined } from "@ant-design/icons";
|
|
import type { ReactNode } from "react";
|
|
import "./DetailDrawer.css";
|
|
|
|
type DrawerTitle = {
|
|
text: string;
|
|
badge?: ReactNode;
|
|
icon?: ReactNode;
|
|
};
|
|
|
|
type HeaderAction = {
|
|
key: string;
|
|
label: string;
|
|
type?: "default" | "primary" | "dashed" | "link" | "text";
|
|
icon?: ReactNode;
|
|
danger?: boolean;
|
|
disabled?: boolean;
|
|
onClick: () => void;
|
|
};
|
|
|
|
type DrawerTab = {
|
|
key: string;
|
|
label: ReactNode;
|
|
content: ReactNode;
|
|
};
|
|
|
|
interface DetailDrawerProps {
|
|
visible: boolean;
|
|
onClose: () => void;
|
|
title?: DrawerTitle;
|
|
headerActions?: HeaderAction[];
|
|
width?: number;
|
|
children?: ReactNode;
|
|
tabs?: DrawerTab[];
|
|
}
|
|
|
|
function DetailDrawer({
|
|
visible,
|
|
onClose,
|
|
title,
|
|
headerActions = [],
|
|
width = 1080,
|
|
children,
|
|
tabs,
|
|
}: DetailDrawerProps) {
|
|
return (
|
|
<Drawer
|
|
title={null}
|
|
placement="right"
|
|
width={width}
|
|
onClose={onClose}
|
|
open={visible}
|
|
closable={false}
|
|
styles={{ body: { padding: 0 } }}
|
|
>
|
|
<div className="detail-drawer-content">
|
|
<div className="detail-drawer-header">
|
|
<div className="detail-drawer-header-left">
|
|
<Button
|
|
type="text"
|
|
icon={<CloseOutlined />}
|
|
onClick={onClose}
|
|
className="detail-drawer-close-button"
|
|
/>
|
|
<div className="detail-drawer-header-info">
|
|
{title?.icon && <span className="detail-drawer-title-icon">{title.icon}</span>}
|
|
<h2 className="detail-drawer-title">{title?.text}</h2>
|
|
{title?.badge && <span className="detail-drawer-badge">{title.badge}</span>}
|
|
</div>
|
|
</div>
|
|
<div className="detail-drawer-header-right">
|
|
<Space size="middle">
|
|
{headerActions.map((action) => (
|
|
<Button
|
|
key={action.key}
|
|
type={action.type || "default"}
|
|
icon={action.icon}
|
|
danger={action.danger}
|
|
disabled={action.disabled}
|
|
onClick={action.onClick}
|
|
>
|
|
{action.label}
|
|
</Button>
|
|
))}
|
|
</Space>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="detail-drawer-scrollable-content">
|
|
{children}
|
|
|
|
{tabs && tabs.length > 0 && (
|
|
<div className="detail-drawer-tabs">
|
|
<Tabs
|
|
defaultActiveKey={tabs[0].key}
|
|
type="line"
|
|
size="large"
|
|
items={tabs.map((tab) => ({
|
|
key: tab.key,
|
|
label: tab.label,
|
|
children: <div className="detail-drawer-tab-content">{tab.content}</div>,
|
|
}))}
|
|
/>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</Drawer>
|
|
);
|
|
}
|
|
|
|
export default DetailDrawer;
|