/** * 基于Radix的对话框展示封装:保留其开关、焦点管理和可访问语义,补项目统一的遮罩、布局与动画。 * 调用方通过Root的open/onOpenChange控制业务流程;保存中是否允许关闭等规则不由本模块决定。 */ "use client"; import * as React from "react"; import * as DialogPrimitive from "@radix-ui/react-dialog"; import { X } from "lucide-react"; import { cn } from "@/lib/utils"; /** Root提供受控或非受控开关上下文,本层不再复制一份open状态。 */ const Dialog = DialogPrimitive.Root; /** Trigger接入同一Root,负责触发打开;可沿用Radix的asChild组合调用方控件。 */ const DialogTrigger = DialogPrimitive.Trigger; /** Portal把浮层移出页面普通布局,避免受父容器裁切;挂载方式沿用Radix。 */ const DialogPortal = DialogPrimitive.Portal; /** 暴露关闭原语,供业务在底部动作区等位置放额外关闭入口。 */ const DialogClose = DialogPrimitive.Close; /** 转发遮罩ref与属性,铺满视口;开关动画由Radix的data-state驱动,className允许调用方补样式。 */ const DialogOverlay = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )); DialogOverlay.displayName = DialogPrimitive.Overlay.displayName; /** 组合Portal、遮罩与居中内容面板,并在children之后固定附带右上角关闭按钮。 * 面板ref和剩余属性交给Radix Content,保留焦点及外部交互事件;关闭按钮有读屏文字。 * 本封装没有单独隐藏默认关闭按钮的参数,业务若要阻止关闭应在受控开关/事件层处理。 * 剩余 props 只传 Content;当前调用没有把 Overlay 的属性入口一并暴露给 DialogContent。 */ const DialogContent = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, children, ...props }, ref) => ( {children} Close )); DialogContent.displayName = DialogPrimitive.Content.displayName; /** 标题区只组织纵向间距与响应式文字对齐;原生div属性和children原样透传。 */ const DialogHeader = ({ className, ...props }: React.HTMLAttributes) => (
); DialogHeader.displayName = "DialogHeader"; /** 动作区在窄屏使用反向纵排,在sm及以上改为靠右横排;不绑定提交或取消动作。 */ const DialogFooter = ({ className, ...props }: React.HTMLAttributes) => (
); DialogFooter.displayName = "DialogFooter"; /** 转发Radix标题的ref/属性并统一字号;标题仍参与对话框的可访问命名关联。 */ const DialogTitle = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )); DialogTitle.displayName = DialogPrimitive.Title.displayName; /** 转发Radix说明文字的ref/属性并使用弱化文字样式;说明关联由Radix上下文维护。 */ const DialogDescription = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )); DialogDescription.displayName = DialogPrimitive.Description.displayName; export { Dialog, DialogPortal, DialogOverlay, DialogTrigger, DialogClose, DialogContent, DialogHeader, DialogFooter, DialogTitle, DialogDescription, };