Dialog
对话框:模态浮层,弹簧动画进出场,自动圈定焦点、锁定滚动,点击遮罩或按 Escape 关闭并把焦点还给触发元素。
安装
添加组件
pnpm dlx @elyri/cli@latest add dialog示例
基础用法
Dialog.Header / Body / Footer 组织结构,右上角自带关闭按钮;配合 asChild 直接使用 Button。
import { Button } from './components/elyri/Button';
import { Dialog } from './components/elyri/Dialog';
export function Example() {
return (
<Dialog>
<Dialog.Trigger asChild>
<Button variant="danger">Delete project</Button>
</Dialog.Trigger>
<Dialog.Content>
<Dialog.Header>
<Dialog.Title>Delete project</Dialog.Title>
<Dialog.Description>
This permanently removes the project and everything in it. This cannot be undone.
</Dialog.Description>
</Dialog.Header>
<Dialog.Footer>
<Dialog.Close asChild>
<Button variant="secondary">Cancel</Button>
</Dialog.Close>
<Dialog.Close asChild>
<Button variant="danger">Delete</Button>
</Dialog.Close>
</Dialog.Footer>
</Dialog.Content>
</Dialog>
);
}长内容滚动
只有 Body 滚动,Header 与 Footer 保持固定,溢出时自动出现分割线。
import { Button } from './components/elyri/Button';
import { Dialog } from './components/elyri/Dialog';
export function Example({ paragraphs }: { paragraphs: string[] }) {
return (
<Dialog>
<Dialog.Trigger asChild>
<Button variant="secondary">Read terms</Button>
</Dialog.Trigger>
<Dialog.Content>
<Dialog.Header>
<Dialog.Title>Terms of service</Dialog.Title>
<Dialog.Description>Please read carefully before continuing.</Dialog.Description>
</Dialog.Header>
<Dialog.Body>
{paragraphs.map((text) => (
<p key={text}>{text}</p>
))}
</Dialog.Body>
<Dialog.Footer>
<Dialog.Close asChild>
<Button variant="secondary">Decline</Button>
</Dialog.Close>
<Dialog.Close asChild>
<Button>Accept</Button>
</Dialog.Close>
</Dialog.Footer>
</Dialog.Content>
</Dialog>
);
}阻止关闭
关闭遮罩与 Escape 关闭后,误触时面板会轻弹提示,只能通过按钮关闭。
import { Button } from './components/elyri/Button';
import { Dialog } from './components/elyri/Dialog';
export function Example() {
return (
<Dialog>
<Dialog.Trigger asChild>
<Button variant="secondary">Start upload</Button>
</Dialog.Trigger>
<Dialog.Content closeOnOverlayClick={false} closeOnEscape={false} showCloseButton={false}>
<Dialog.Header>
<Dialog.Title>Upload in progress</Dialog.Title>
<Dialog.Description>Try clicking outside or pressing Escape — use the button to finish.</Dialog.Description>
</Dialog.Header>
<Dialog.Footer>
<Dialog.Close asChild>
<Button>Done</Button>
</Dialog.Close>
</Dialog.Footer>
</Dialog.Content>
</Dialog>
);
}属性
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
open | boolean | — | 受控开关 |
defaultOpen | boolean | false | 非受控初始开关 |
onOpenChange | (open: boolean) => void | — | 开关变化回调 |
modal | boolean | true | 模态:锁定滚动并圈定焦点,默认 true |
Dialog.Trigger | ButtonHTMLAttributes | — | 触发按钮,自动带上 aria-haspopup / aria-expanded |
asChild | boolean | false | Trigger / Close 上使用:把行为合并到唯一子元素,如 <Button> |
Dialog.Content | HTMLAttributes | — | 内容区,挂到 body 的浮层里 |
closeOnOverlayClick | boolean | true | 点击遮罩关闭,默认 true;为 false 时面板轻弹提示 |
closeOnEscape | boolean | true | 按 Escape 关闭,默认 true;为 false 时面板轻弹提示 |
showCloseButton | boolean | true | 显示右上角关闭按钮,默认 true |
closeLabel | string | 'Close' | 右上角关闭按钮的无障碍名称 |
Dialog.Header | HTMLAttributes | — | 头部,放 Title 与 Description |
Dialog.Body | HTMLAttributes | — | 可滚动主体,溢出时显示分割线 |
Dialog.Footer | HTMLAttributes | — | 底部操作区,按钮右对齐,窄屏纵向铺满 |
Dialog.Title | HTMLAttributes | — | 标题,作为对话框的无障碍名称 |
Dialog.Description | HTMLAttributes | — | 描述,关联到 aria-describedby |
Dialog.Close | ButtonHTMLAttributes | — | 点击即关闭的按钮 |