92 lines
2.6 KiB
TypeScript
92 lines
2.6 KiB
TypeScript
import type { ReactNode } from "react"
|
|
|
|
import {
|
|
Dialog,
|
|
DialogContent,
|
|
DialogFooter,
|
|
DialogHeader,
|
|
DialogTitle,
|
|
} from "~/components/ui/dialog"
|
|
import { cn } from "~/lib/utils"
|
|
|
|
import { primaryGradientButtonClass } from "./buttonClasses"
|
|
|
|
/** 与系统管理弹窗 footer 一致的次要按钮样式 */
|
|
export const dialogSecondaryButtonClass =
|
|
"h-[37px] gap-[7px] rounded-md border-[#d8e1e9] bg-white px-[15px] text-xs font-[650] text-[#56687c]"
|
|
|
|
/** 与系统管理弹窗 footer 一致的主按钮样式(STYLE_GUIDE §2.2 官方渐变) */
|
|
export const dialogPrimaryButtonClass = primaryGradientButtonClass
|
|
|
|
const EYEBROW_CLASS =
|
|
"text-[9px] font-extrabold tracking-[0.12em] text-[#2d82d4]"
|
|
|
|
const TITLE_CLASS = "mt-1 text-[19px] font-normal text-[#1c2d42]"
|
|
|
|
type AppFormDialogProps = {
|
|
open: boolean
|
|
onOpenChange: (open: boolean) => void
|
|
eyebrow?: string
|
|
title?: ReactNode
|
|
titleId?: string
|
|
children: ReactNode
|
|
footer?: ReactNode
|
|
contentClassName?: string
|
|
bodyClassName?: string
|
|
showCloseButton?: boolean
|
|
size?: "compact" | "panel"
|
|
}
|
|
|
|
function AppFormDialog({
|
|
open,
|
|
onOpenChange,
|
|
eyebrow,
|
|
title,
|
|
titleId,
|
|
children,
|
|
footer,
|
|
contentClassName,
|
|
bodyClassName,
|
|
showCloseButton = true,
|
|
size = "compact",
|
|
}: AppFormDialogProps) {
|
|
const maxWidth =
|
|
size === "panel"
|
|
? "sm:max-w-[min(520px,calc(100vw-40px))]"
|
|
: "sm:max-w-[min(480px,calc(100vw-40px))]"
|
|
|
|
return (
|
|
<Dialog open={open} onOpenChange={onOpenChange}>
|
|
<DialogContent
|
|
showCloseButton={showCloseButton}
|
|
className={cn(
|
|
"flex max-h-[80vh] flex-col gap-0 overflow-hidden rounded-[11px] border-[#dce4eb] bg-white p-0 text-[#1c2d42] shadow-xl ring-0",
|
|
maxWidth,
|
|
contentClassName,
|
|
)}
|
|
>
|
|
{eyebrow || title ? (
|
|
<DialogHeader className="shrink-0 space-y-0 border-b border-line px-[22px] pb-4 pt-5 text-left">
|
|
{eyebrow ? <span className={EYEBROW_CLASS}>{eyebrow}</span> : null}
|
|
{title ? (
|
|
<DialogTitle id={titleId} className={TITLE_CLASS}>
|
|
{title}
|
|
</DialogTitle>
|
|
) : null}
|
|
</DialogHeader>
|
|
) : null}
|
|
<div className={cn("min-h-0 flex-1 overflow-y-auto", bodyClassName)}>
|
|
{children}
|
|
</div>
|
|
{footer ? (
|
|
<DialogFooter className="mt-0 shrink-0 flex-row justify-end gap-2 border-t border-line bg-white px-[22px] py-3.5 sm:justify-end">
|
|
{footer}
|
|
</DialogFooter>
|
|
) : null}
|
|
</DialogContent>
|
|
</Dialog>
|
|
)
|
|
}
|
|
|
|
export { AppFormDialog }
|