组件

弹出框

在门户中显示富内容,由按钮触发。

import * as React from "react";
import { Popover } from "radix-ui";
import { MixerHorizontalIcon, Cross2Icon } from "@radix-ui/react-icons";
import "./styles.css";
const PopoverDemo = () => (
<Popover.Root>
<Popover.Trigger asChild>
<button className="IconButton" aria-label="Update dimensions">
<MixerHorizontalIcon />
</button>
</Popover.Trigger>
<Popover.Portal>
<Popover.Content className="PopoverContent" sideOffset={5}>
<div style={{ display: "flex", flexDirection: "column", gap: 10 }}>
<p className="Text" style={{ marginBottom: 10 }}>
Dimensions
</p>
<fieldset className="Fieldset">
<label className="Label" htmlFor="width">
Width
</label>
<input className="Input" id="width" defaultValue="100%" />
</fieldset>
<fieldset className="Fieldset">
<label className="Label" htmlFor="maxWidth">
Max. width
</label>
<input className="Input" id="maxWidth" defaultValue="300px" />
</fieldset>
<fieldset className="Fieldset">
<label className="Label" htmlFor="height">
Height
</label>
<input className="Input" id="height" defaultValue="25px" />
</fieldset>
<fieldset className="Fieldset">
<label className="Label" htmlFor="maxHeight">
Max. height
</label>
<input className="Input" id="maxHeight" defaultValue="none" />
</fieldset>
</div>
<Popover.Close className="PopoverClose" aria-label="Close">
<Cross2Icon />
</Popover.Close>
<Popover.Arrow className="PopoverArrow" />
</Popover.Content>
</Popover.Portal>
</Popover.Root>
);
export default PopoverDemo;

特性

    可以受控或不受控。

    自定义侧边、对齐方式、偏移量、碰撞处理。

    可选渲染指向箭头。

    焦点完全可管理和自定义。

    支持模态和非模态模式。

    关闭和分层行为是高度可定制的。

安装

从命令行安装组件。

npm install @radix-ui/react-popover

解剖结构

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

import { Popover } from "radix-ui";
export default () => (
<Popover.Root>
<Popover.Trigger />
<Popover.Anchor />
<Popover.Portal>
<Popover.Content>
<Popover.Close />
<Popover.Arrow />
</Popover.Content>
</Popover.Portal>
</Popover.Root>
);

API 参考

包含弹出框的所有部件。

属性类型默认值
defaultOpen
boolean
无默认值
open
boolean
无默认值
onOpenChange
function
无默认值
modal
boolean
false

触发器

用于切换弹出框的按钮。默认情况下,Popover.Content 将会相对于触发器定位。

属性类型默认值
asChild
boolean
false
数据属性
[data-state]"open" |"closed"

锚点

一个可选元素,用于定位 Popover.Content。如果未使用此部件,内容将沿 Popover.Trigger 定位。

属性类型默认值
asChild
boolean
false

Portal

使用时,将内容部件传送到 body 中。

属性类型默认值
forceMount
boolean
无默认值
container
HTMLElement
document.body

内容

弹出框打开时弹出的组件。

属性类型默认值
asChild
boolean
false
onOpenAutoFocus
function
无默认值
onCloseAutoFocus
function
无默认值
onEscapeKeyDown
function
无默认值
onPointerDownOutside
function
无默认值
onFocusOutside
function
无默认值
onInteractOutside
function
无默认值
forceMount
boolean
无默认值
side
枚举
"bottom"
sideOffset
number
0
align
枚举
"center"
alignOffset
number
0
avoidCollisions
boolean
true
collisionBoundary
Boundary
[]
collisionPadding
number | Padding
0
arrowPadding
number
0
sticky
枚举
"partial"
hideWhenDetached
boolean
false
数据属性
[data-state]"open" |"closed"
[data-side]"left" |"right" |"bottom" |"top"
[data-align]"start" |"end" |"center"
CSS 变量描述
--radix-popover-content-transform-origin从内容和箭头位置/偏移量计算得出的 transform-origin
--radix-popover-content-available-width触发器和边界边缘之间的剩余宽度
--radix-popover-content-available-height触发器和边界边缘之间的剩余高度
--radix-popover-trigger-width触发器的宽度
--radix-popover-trigger-height触发器的高度

箭头

一个可选的箭头元素,用于在弹出框旁边渲染。这可以用于帮助在视觉上将锚点与 Popover.Content 链接起来。必须在 Popover.Content 内部渲染。

属性类型默认值
asChild
boolean
false
width
number
10
height
number
5

关闭

用于关闭已打开的弹出框的按钮。

属性类型默认值
asChild
boolean
false

示例

约束内容大小

您可能希望约束内容的宽度,使其与触发器宽度匹配。您可能还希望约束其高度,使其不超过视口。

我们公开了几个 CSS 自定义属性,例如 --radix-popover-trigger-width--radix-popover-content-available-height 来支持这一点。使用它们来约束内容尺寸。

// index.jsx
import { Popover } from "radix-ui";
import "./styles.css";
export default () => (
<Popover.Root>
<Popover.Trigger></Popover.Trigger>
<Popover.Portal>
<Popover.Content className="PopoverContent" sideOffset={5}>
</Popover.Content>
</Popover.Portal>
</Popover.Root>
);
/* styles.css */
.PopoverContent {
width: var(--radix-popover-trigger-width);
max-height: var(--radix-popover-content-available-height);
}

原点感知动画

我们公开了一个 CSS 自定义属性 --radix-popover-content-transform-origin。使用它来从其计算出的原点动画内容,基于 sidesideOffsetalignalignOffset 和任何碰撞。

// index.jsx
import { Popover } from "radix-ui";
import "./styles.css";
export default () => (
<Popover.Root>
<Popover.Trigger></Popover.Trigger>
<Popover.Portal>
<Popover.Content className="PopoverContent"></Popover.Content>
</Popover.Portal>
</Popover.Root>
);
/* styles.css */
.PopoverContent {
transform-origin: var(--radix-popover-content-transform-origin);
animation: scaleIn 0.5s ease-out;
}
@keyframes scaleIn {
from {
opacity: 0;
transform: scale(0);
}
to {
opacity: 1;
transform: scale(1);
}
}

碰撞感知动画

我们公开了 data-sidedata-align 属性。它们的值将在运行时更改以反映碰撞。使用它们来创建碰撞和方向感知动画。

// index.jsx
import { Popover } from "radix-ui";
import "./styles.css";
export default () => (
<Popover.Root>
<Popover.Trigger></Popover.Trigger>
<Popover.Portal>
<Popover.Content className="PopoverContent"></Popover.Content>
</Popover.Portal>
</Popover.Root>
);
/* styles.css */
.PopoverContent {
animation-duration: 0.6s;
animation-timing-function: cubic-bezier(0.16, 1, 0.3, 1);
}
.PopoverContent[data-side="top"] {
animation-name: slideUp;
}
.PopoverContent[data-side="bottom"] {
animation-name: slideDown;
}
@keyframes slideDown {
from {
opacity: 0;
transform: translateY(-10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes slideUp {
from {
opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}

使用自定义锚点

如果您不想使用触发器作为锚点,您可以将内容锚定到另一个元素。

// index.jsx
import { Popover } from "radix-ui";
import "./styles.css";
export default () => (
<Popover.Root>
<Popover.Anchor asChild>
<div className="Row">
Row as anchor <Popover.Trigger>Trigger</Popover.Trigger>
</div>
</Popover.Anchor>
<Popover.Portal>
<Popover.Content></Popover.Content>
</Popover.Portal>
</Popover.Root>
);
/* styles.css */
.Row {
background-color: gainsboro;
padding: 20px;
}

可访问性

遵循 Dialog WAI-ARIA 设计模式

键盘交互

按键描述
空格键
打开/关闭弹出框。
Enter 键
打开/关闭弹出框。
Tab 键
将焦点移动到下一个可聚焦元素
Shift + Tab 键
将焦点移动到上一个可聚焦元素
Esc 键
关闭弹出框并将焦点移动到 Popover.Trigger

自定义 API

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

抽象箭头并设置默认配置

此示例抽象了 Popover.Arrow 部件并设置了默认的 sideOffset 配置。

用法

import { Popover, PopoverTrigger, PopoverContent } from "./your-popover";
export default () => (
<Popover>
<PopoverTrigger>Popover trigger</PopoverTrigger>
<PopoverContent>Popover content</PopoverContent>
</Popover>
);

实现

// your-popover.jsx
import * as React from "react";
import { Popover as PopoverPrimitive } from "radix-ui";
export const Popover = PopoverPrimitive.Root;
export const PopoverTrigger = PopoverPrimitive.Trigger;
export const PopoverContent = React.forwardRef(
({ children, ...props }, forwardedRef) => (
<PopoverPrimitive.Portal>
<PopoverPrimitive.Content sideOffset={5} {...props} ref={forwardedRef}>
{children}
<PopoverPrimitive.Arrow />
</PopoverPrimitive.Content>
</PopoverPrimitive.Portal>
),
);
上一个导航菜单
下一个进度条