--- 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 ( }> 编辑资料 编辑资料 更新公开显示的信息。
表单内容
) } ``` `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" ; }> 打开设置 显示设置 选择列表密度。 ``` 本地 API 继续转发 Base UI Popup 与 Positioner 的 props。需要受控状态时给 `Popover` 传入 `open` 和 `onOpenChange`。 ## 连续尾巴 {#anchored-surface} 本仓库的 `showArrow` 不是普通三角 SVG。它让 `PopoverContent` 用 `AnchoredSurface` 渲染一个圆角表面与连续曲线尾巴: ```tsx {content} ``` 外层表面保持 `overflow: visible`,避免尾巴被裁剪;滚动发生在内部 `data-slot="popover-viewport"`。因此要限制内容高度或设置 padding 时,优先使用 `viewportClassName`。 `AnchoredSurface` 也可以独立使用,但它只负责视觉表面,不负责测量锚点、碰撞检测、焦点或 Portal。 ## 自定义定位 {#positioning} `PopoverContent` 额外暴露 `anchor`、`positionMethod`、`arrowPadding`、`alignOffset` 和 `sideOffset`。虚拟锚点或自定义锚点应通过这些参数传给共享组件,不需要绕过它重新拼装 Base UI primitives。 需要从非 React 代码控制弹层时,可使用 `createPopoverHandle()` 创建 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`。