Files
simple-react-app-kit/packages/ui/docs/zh-Hans/guide/overlays.mdx
T
2026-09-21 17:27:45 +08:00

114 lines
3.5 KiB
Plaintext

---
title: 浮层与定位
description: 使用 Base UI 的 render 组合 Dialog、Popover 与本地 AnchoredSurface。
order: 12
toc:
- id: dialog
title: Dialog
- id: popover
title: Popover
- id: anchored-surface
title: 连续尾巴
- id: positioning
title: 自定义定位
- id: choosing-an-overlay
title: 选择浮层
---
## Dialog {#dialog}
```tsx
import { Button } from "@workspace/ui/components/button"
import {
Dialog,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "@workspace/ui/components/dialog"
export function ProfileDialog() {
return (
<Dialog>
<DialogTrigger render={<Button variant="outline" />}>
编辑资料
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>编辑资料</DialogTitle>
<DialogDescription>更新公开显示的信息。</DialogDescription>
</DialogHeader>
<div>表单内容</div>
<DialogFooter>
<Button type="submit">保存</Button>
</DialogFooter>
</DialogContent>
</Dialog>
)
}
```
`DialogContent` 已包含 Portal、Overlay 和默认关闭按钮。标题与说明会连接到底层可访问性属性,不要只用无语义的 `div` 替代。
## Popover {#popover}
```tsx
import { Button } from "@workspace/ui/components/button"
import {
Popover,
PopoverContent,
PopoverDescription,
PopoverTitle,
PopoverTrigger,
} from "@workspace/ui/components/popover"
;<Popover>
<PopoverTrigger render={<Button variant="outline" />}>
打开设置
</PopoverTrigger>
<PopoverContent align="end">
<PopoverTitle>显示设置</PopoverTitle>
<PopoverDescription>选择列表密度。</PopoverDescription>
</PopoverContent>
</Popover>
```
本地 API 继续转发 Base UI Popup 与 Positioner 的 props。需要受控状态时给 `Popover` 传入 `open` 和 `onOpenChange`。
## 连续尾巴 {#anchored-surface}
本仓库的 `showArrow` 不是普通三角 SVG。它让 `PopoverContent` 用 `AnchoredSurface` 渲染一个圆角表面与连续曲线尾巴:
```tsx
<PopoverContent
side="bottom"
showArrow={{ cornerRadius: "2xl", tailSize: "sm" }}
className="w-80 p-0"
viewportClassName="max-h-72 p-4"
>
{content}
</PopoverContent>
```
外层表面保持 `overflow: visible`,避免尾巴被裁剪;滚动发生在内部 `data-slot="popover-viewport"`。因此要限制内容高度或设置 padding 时,优先使用 `viewportClassName`。
`AnchoredSurface` 也可以独立使用,但它只负责视觉表面,不负责测量锚点、碰撞检测、焦点或 Portal。
## 自定义定位 {#positioning}
`PopoverContent` 额外暴露 `anchor`、`positionMethod`、`arrowPadding`、`alignOffset` 和 `sideOffset`。虚拟锚点或自定义锚点应通过这些参数传给共享组件,不需要绕过它重新拼装 Base UI primitives。
需要从非 React 代码控制弹层时,可使用 `createPopoverHandle<Payload>()` 创建 handle,再按 Base UI 的 handle 模式传给 Root。
## 选择浮层 {#choosing-an-overlay}
- 必须阻止背景交互:`Dialog` 或 `AlertDialog`。
- 从屏幕边缘进入的任务面板:`Sheet`;强调触摸拖拽的移动面板:`Drawer`。
- 与一个触发点关联的交互内容:`Popover`。
- 只在悬停或聚焦时补充预览:`HoverCard`。
- 简短、非交互说明:`Tooltip`。
基础用法可与 [shadcn Popover 文档](https://ui.shadcn.com/docs/components/base/popover)对照;组合语法必须使用 Base UI 版本的 `render`。