组件

对话框

一个覆盖在主窗口或其他对话框窗口之上的窗口,使其下方的内容变为非交互状态。

import * as React from "react";
import { Dialog } from "radix-ui";
import { Cross2Icon } from "@radix-ui/react-icons";
import "./styles.css";
const DialogDemo = () => (
<Dialog.Root>
<Dialog.Trigger asChild>
<button className="Button violet">Edit profile</button>
</Dialog.Trigger>
<Dialog.Portal>
<Dialog.Overlay className="DialogOverlay" />
<Dialog.Content className="DialogContent">
<Dialog.Title className="DialogTitle">Edit profile</Dialog.Title>
<Dialog.Description className="DialogDescription">
Make changes to your profile here. Click save when you're done.
</Dialog.Description>
<fieldset className="Fieldset">
<label className="Label" htmlFor="name">
Name
</label>
<input className="Input" id="name" defaultValue="Pedro Duarte" />
</fieldset>
<fieldset className="Fieldset">
<label className="Label" htmlFor="username">
Username
</label>
<input className="Input" id="username" defaultValue="@peduarte" />
</fieldset>
<div style={{ display: "flex", marginTop: 25, justifyContent: "flex-end" }} >
<Dialog.Close asChild>
<button className="Button green">Save changes</button>
</Dialog.Close>
</div>
<Dialog.Close asChild>
<button className="IconButton" aria-label="Close">
<Cross2Icon />
</button>
</Dialog.Close>
</Dialog.Content>
</Dialog.Portal>
</Dialog.Root>
);
export default DialogDemo;

特性

    支持模态和非模态模式。

    焦点自动限制在模态框内。

    可以是受控的或非受控的。

    使用 Title 和管理屏幕阅读器公告 Description 组件。

    Esc 键自动关闭组件。

安装

从命令行安装组件。

npm install @radix-ui/react-dialog

解剖结构

导入所有部件并将它们组装在一起。

import { Dialog } from "radix-ui";
export default () => (
<Dialog.Root>
<Dialog.Trigger />
<Dialog.Portal>
<Dialog.Overlay />
<Dialog.Content>
<Dialog.Title />
<Dialog.Description />
<Dialog.Close />
</Dialog.Content>
</Dialog.Portal>
</Dialog.Root>
);

API 参考

Root (根)

包含对话框的所有部件。

Prop (属性)Type (类型)Default (默认值)
defaultOpen
boolean (布尔值)
无默认值
open (打开)
boolean (布尔值)
无默认值
onOpenChange (打开时更改)
function (函数)
无默认值
modal (模态)
boolean (布尔值)
true (真)

Trigger (触发器)

打开对话框的按钮。

Prop (属性)Type (类型)Default (默认值)
asChild
boolean (布尔值)
false (假)
Data attribute (数据属性)Values (值)
[data-state]"open" | (打开 |)"closed" (关闭)

Portal

使用时,将您的 overlay (覆盖层) 和 content (内容) 部件传送到 body 中。

Prop (属性)Type (类型)Default (默认值)
forceMount (强制挂载)
boolean (布尔值)
无默认值
container (容器)
HTMLElement
document.body

Overlay (覆盖层)

当对话框打开时,覆盖视图的非交互部分的图层。

Prop (属性)Type (类型)Default (默认值)
asChild
boolean (布尔值)
false (假)
forceMount (强制挂载)
boolean (布尔值)
无默认值
Data attribute (数据属性)Values (值)
[data-state]"open" | (打开 |)"closed" (关闭)

Content (内容)

包含要在打开的对话框中渲染的内容。

Prop (属性)Type (类型)Default (默认值)
asChild
boolean (布尔值)
false (假)
forceMount (强制挂载)
boolean (布尔值)
无默认值
onOpenAutoFocus (打开时自动聚焦)
function (函数)
无默认值
onCloseAutoFocus (关闭时自动聚焦)
function (函数)
无默认值
onEscapeKeyDown (按下 Esc 键时)
function (函数)
无默认值
onPointerDownOutside (在外部指针按下时)
function (函数)
无默认值
onInteractOutside (在外部交互时)
function (函数)
无默认值
Data attribute (数据属性)Values (值)
[data-state]"open" | (打开 |)"closed" (关闭)

Close (关闭)

关闭对话框的按钮。

Prop (属性)Type (类型)Default (默认值)
asChild
boolean (布尔值)
false (假)

Title (标题)

对话框打开时要宣告的可访问标题。

如果您想隐藏标题,请将其包裹在我们的 Visually Hidden 实用工具中,就像这样 <VisuallyHidden asChild>

Prop (属性)Type (类型)Default (默认值)
asChild
boolean (布尔值)
false (假)

Description (描述)

对话框打开时要宣告的可选可访问描述。

如果您想隐藏描述,请将其包裹在我们的 Visually Hidden 实用工具中,就像这样 <VisuallyHidden asChild>。如果您想完全移除描述,请移除此部分并将 aria-describedby={undefined} 传递给 Dialog.Content

Prop (属性)Type (类型)Default (默认值)
asChild
boolean (布尔值)
false (假)

示例

异步表单提交后关闭

使用受控属性在异步操作完成后以编程方式关闭对话框。

import * as React from "react";
import { Dialog } from "radix-ui";
const wait = () => new Promise((resolve) => setTimeout(resolve, 1000));
export default () => {
const [open, setOpen] = React.useState(false);
return (
<Dialog.Root open={open} onOpenChange={setOpen}>
<Dialog.Trigger>Open</Dialog.Trigger>
<Dialog.Portal>
<Dialog.Overlay />
<Dialog.Content>
<form onSubmit={(event) => { wait().then(() => setOpen(false)); event.preventDefault(); }} >
{/** some inputs */}
<button type="submit">Submit</button>
</form>
</Dialog.Content>
</Dialog.Portal>
</Dialog.Root>
);
};

可滚动覆盖层

将内容移动到覆盖层内部以渲染带有溢出的对话框。

// index.jsx
import { Dialog } from "radix-ui";
import "./styles.css";
export default () => {
return (
<Dialog.Root>
<Dialog.Trigger />
<Dialog.Portal>
<Dialog.Overlay className="DialogOverlay">
<Dialog.Content className="DialogContent">...</Dialog.Content>
</Dialog.Overlay>
</Dialog.Portal>
</Dialog.Root>
);
};
/* styles.css */
.DialogOverlay {
background: rgba(0 0 0 / 0.5);
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
display: grid;
place-items: center;
overflow-y: auto;
}
.DialogContent {
min-width: 300px;
background: white;
padding: 30px;
border-radius: 4px;
}

自定义 portal 容器

自定义您的对话框 portal 进入的元素。

import * as React from "react";
import { Dialog } from "radix-ui";
export default () => {
const [container, setContainer] = React.useState(null);
return (
<div>
<Dialog.Root>
<Dialog.Trigger />
<Dialog.Portal container={container}>
<Dialog.Overlay />
<Dialog.Content>...</Dialog.Content>
</Dialog.Portal>
</Dialog.Root>
<div ref={setContainer} />
</div>
);
};

可访问性

遵循 Dialog WAI-ARIA 设计模式

键盘交互

按键Description (描述)
空格键
打开/关闭对话框。
Enter 键
打开/关闭对话框。
Tab 键
将焦点移动到下一个可聚焦元素。
Shift + Tab 键
将焦点移动到上一个可聚焦元素。
Esc 键
关闭对话框并将焦点移动到 Dialog.Trigger

自定义 API

通过将基本部件抽象到您自己的组件中来创建您自己的 API。

抽象覆盖层和关闭按钮

此示例抽象了 Dialog.OverlayDialog.Close 部件。

用法

import { Dialog, DialogTrigger, DialogContent } from "./your-dialog";
export default () => (
<Dialog>
<DialogTrigger>Dialog trigger</DialogTrigger>
<DialogContent>Dialog Content</DialogContent>
</Dialog>
);

实现

// your-dialog.jsx
import * as React from "react";
import { Dialog as DialogPrimitive } from "radix-ui";
import { Cross1Icon } from "@radix-ui/react-icons";
export const DialogContent = React.forwardRef(
({ children, ...props }, forwardedRef) => (
<DialogPrimitive.Portal>
<DialogPrimitive.Overlay />
<DialogPrimitive.Content {...props} ref={forwardedRef}>
{children}
<DialogPrimitive.Close aria-label="Close">
<Cross1Icon />
</DialogPrimitive.Close>
</DialogPrimitive.Content>
</DialogPrimitive.Portal>
),
);
export const Dialog = DialogPrimitive.Root;
export const DialogTrigger = DialogPrimitive.Trigger;
下一个下拉菜单