组件

Popover

在门户中显示丰富的內容,由按钮触发。

import React from 'react';
import * as Popover from '@radix-ui/react-popover';
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 * as Popover from '@radix-ui/react-popover';
export default () => (
<Popover.Root>
<Popover.Trigger />
<Popover.Anchor />
<Popover.Portal>
<Popover.Content>
<Popover.Close />
<Popover.Arrow />
</Popover.Content>
</Popover.Portal>
</Popover.Root>
);

API 参考

包含 Popover 的所有部分。

道具类型默认值
defaultOpen
boolean
无默认值
open
boolean
无默认值
onOpenChange
function
无默认值
modal
boolean
false

触发器

切换 Popover 的按钮。默认情况下,Popover.Content 将定位到触发器。

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

可选元素,用于将 Popover.Content 定位到。如果未使用此部分,内容将与 Popover.Trigger 定位在一起。

道具类型默认值
asChild
boolean
false

门户

使用时,将内容部分门户到 body 中。

道具类型默认值
forceMount
boolean
无默认值
容器
HTMLElement
document.body

内容

Popover 打开时弹出的组件。

道具类型默认值
asChild
boolean
false
onOpenAutoFocus
function
无默认值
onCloseAutoFocus
function
无默认值
onEscapeKeyDown
function
无默认值
onPointerDownOutside
function
无默认值
onFocusOutside
function
无默认值
onInteractOutside
function
无默认值
forceMount
boolean
无默认值
侧面
enum
"bottom"
sideOffset
number
0
对齐
enum
"center"
alignOffset
number
0
avoidCollisions
boolean
true
collisionBoundary
边界
[]
collisionPadding
number | Padding
0
arrowPadding
number
0
sticky
enum
"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 一起渲染。这可以用于帮助将锚点与 Popover.Content 视觉上关联起来。必须在 Popover.Content 内部渲染。

道具类型默认值
asChild
boolean
false
宽度
number
10
高度
number
5

关闭

关闭打开的弹出窗口的按钮。

道具类型默认值
asChild
boolean
false

示例

约束内容大小

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

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

// index.jsx
import * as Popover from '@radix-ui/react-popover';
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 * as Popover from '@radix-ui/react-popover';
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 * as Popover from '@radix-ui/react-popover';
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 * as Popover from '@radix-ui/react-popover';
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;
}

可访问性

符合 对话框 WAI-ARIA 设计模式

键盘交互

描述
空格
打开/关闭弹出窗口。
回车
打开/关闭弹出窗口。
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 React from 'react';
import * as PopoverPrimitive from '@radix-ui/react-popover';
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>
)
);
上一个导航菜单
下一个进度