侧边面板
概述
从屏幕边缘滑出的面板。它复用 SDialog 的声明式 API 与插槽契约(同一 Aria DialogCompact 基座,相同的模态/焦点/可关闭行为),并新增 side 控制面板进入方向——top/bottom/left/right(默认 right)。
SSheet 组合 Aria dialog 基础组件家族与 sheetVariants 样式配方(继承 dialogVariants,6 种尺寸 × 4 个方向)。
需要带吸附点与滑动关闭的手势面板?那是 Drawer——侧边面板刻意保持"带侧边的 dialog"定位。
用法
特性
- 🧩 复用 dialog 基座 — 构建于
DialogCompact,继承SDialog的插槽、事件、逐部分*Props、pure、isAlert与命令式dialog(...)API - 🧭 4 个方向 —
side="top"/"bottom"/"left"/"right"(默认right);左右方向支持 RTL 镜像滑动 - 🎭 默认模态 —
aria-modal、useHideOthers、外部指针拦截与焦点陷阱,与SDialog相同 - ❌ 可关闭 —
showClose、Escape、外部指针/焦点与关闭按钮均可关闭 - 🎞️ 动画 — 进入/退出过渡(
slide-in-from-*/slide-out-to-*)由打开状态驱动 - 📐 6 种尺寸 — xs–2xl
size;逐槽ui覆盖 - ⛶ 全屏 —
showFullscreen渲染切换按钮;fullscreen/defaultFullscreen驱动v-model:fullscreen状态,使面板撑满视口 - 🔘 取消/确认底部 —
showCancel/showConfirm,cancelText/confirmText本地化 - ♿ 无障碍 —
role="dialog"、焦点陷阱 + 循环、关闭时焦点还原、axe-core零违规
组件家族
SSheet(样式层)— 入口包装组件;sheetVariants配方(size+side)配合动态插槽转发- 其余部分均来自 Aria dialog 家族(见
Dialog):DialogRoot、DialogTrigger、DialogOverlay、DialogPopup、DialogHeader、DialogContent、DialogFooter、DialogTitle、DialogDescription、DialogClose、DialogCancel、DialogConfirm、DialogCompact
演示
基础
API
Aria 层
1Sheet
属性
| 属性名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
side | Side | — | 组件的侧边布局。 |
showFullscreen | boolean | false | 是否在对话框的标题栏中显示全屏切换按钮。 |
class | ClassValue | — | 对话框的 popup 类 |
size | ThemeSize | — | 组件的视觉尺寸。 |
ui | Partial<DialogUi> | — | 该组件的按槽类重写。 |
title | string | — | 对话框的标题。此标题用于辅助功能,若未提供 `title` 槽,则会显示在对话框的标题栏中。 |
description | string | — | 对话框的描述。此描述用于辅助功能,若未提供 `description` 槽,则会在对话框内容中显示。 |
icon | IconValue | — | 对话框的图标。该图标用于辅助功能,若未提供 `icon` 槽,则会显示在对话框的标题栏中。 |
showClose | boolean | true | 是否在对话框的标题栏中显示关闭按钮。 |
pure | boolean | false | 是否使用不包含页眉和页脚的“纯版”对话框。
当您希望完全控制对话框内容且不需要内置页眉和页脚时,此选项非常有用。 |
showCancel | boolean | 'onlyWarning' | 'onlyWarning' | 是否显示“取消”按钮。
当设置为 `onlyWarning` 时,只有当对话框是 `alertType="warning"` 的警告对话框时,才会显示“取消”按钮。
当设置为 `true` 时,将始终显示“取消”按钮。 |
cancelText | string | — | “取消”按钮的文本。此文本用于辅助功能,若未提供 `cancel` 插槽,则会在对话框的页脚中显示。
默认采用来自 `ConfigProvider` 的本地化 `dialog.cancel` 消息。 |
showConfirm | boolean | — | 当对话框为提示对话框时,是否显示确认按钮。
当对话框为提示对话框时,默认值为 `true`。 |
confirmText | string | — | “确认”按钮的文本。此文本用于辅助功能,若未提供 `confirm` 插槽,则会显示在对话框的页脚中。
默认采用来自 `ConfigProvider` 的本地化 `dialog.confirm` 消息。 |
triggerProps | DialogTriggerProps | — | 转发给触发元素的属性。 |
overlayProps | DialogOverlayProps | — | 转发给覆盖元素的属性。 |
portalProps | PortalProps | — | 转发给 portal 元素的属性。 |
popupProps | DialogPopupProps | — | 转发给弹出窗口元素的属性。 |
headerProps | DialogHeaderProps | — | 转发至 header 元素的属性。 |
contentProps | DialogContentProps | — | 转发给内容元素的属性。 |
footerProps | DialogFooterProps | — | 转发至页脚元素的属性。 |
titleProps | DialogTitleProps | — | 传递给 title 元素的属性。 |
descriptionProps | DialogDescriptionProps | — | 已将属性转发至 description 元素。 |
closeProps | DialogCloseProps | — | 转发至 close 元素的属性。 |
fullscreenProps | DialogFullscreenProps | — | 转发给全屏元素的属性。 |
cancelProps | DialogCancelProps | — | 转发给 cancel 元素的属性。 |
confirmProps | DialogConfirmProps | — | 转发给 confirm 元素的属性。 |
modal | ModalityTier | true | 对话框的模态属性。当设置为 `true` 时,将禁用与外部元素的交互,且屏幕阅读器仅能读取对话框
内容。
设置为 `'trap-focus'` 可在捕获焦点的同时仍允许外部指针事件通过(非模态侧边面板,例如
`'trap-focus'` 层级的 `Drawer`)。 |
dir | Direction | — | 对话框的文本方向 |
isAlert | boolean | false | 该对话框是否为警报对话框。警报对话框是一种会中断用户工作流程以传达重要信息并需要用户做出响应的对话框。
当设置为 `true` 时,对话框将具有 `role="alertdialog"` 属性,并需要提供 `DialogTitle`。此设置用于辅助功能支持。 |
alertType | DialogAlertType | — | 对话框的“alert”类型,当对话框为警报对话框时,该类型将决定默认图标和样式。 |
draggable | boolean | false | 是否可以通过拖动对话框的标题来移动该对话框。 |
fullscreen | boolean | undefined | 对话框的可控全屏状态。可通过 `v-model:fullscreen` 进行绑定。 |
defaultFullscreen | boolean | false | 对话框初次渲染时的全屏状态。当您无需控制其全屏状态时使用此选项。 |
open | boolean | undefined | 对话框的受控打开状态。可通过 `v-model:open` 进行绑定。 |
defaultOpen | boolean | false | 对话框在初始渲染时的打开状态。当无需控制其打开状态时使用。 |
事件
| 事件名 | 参数 | 描述 |
|---|---|---|
update:open | boolean | 当对话框的打开状态发生变化时调用的事件处理程序。 |
update:fullscreen | boolean | 当对话框的全屏状态发生变化时调用的事件处理程序。 |
click | PointerEvent | 当对话框触发器被激活时调用的事件处理程序。 |
escapeKeyDown | KeyboardEvent | 当 Esc 键被按下时触发的事件处理程序。可被阻止。 |
pointerDownOutside | PointerDownOutsideEvent | 当 `pointerdown` 事件发生在 `DismissableLayer` 外部时调用的事件处理程序。可被阻止。 |
focusOutside | FocusOutsideEvent | 当焦点移出 `DismissableLayer` 时触发的事件处理程序。可被阻止。 |
interactOutside | PointerDownOutsideEvent | FocusOutsideEvent | 当在 `DismissableLayer` 外部发生交互时触发的事件处理程序。具体而言,当 `pointerdown`
事件在该区域外部发生,或焦点移出该区域时触发。此事件可被阻止。 |
openAutoFocus | Event | 在打开页面时自动聚焦时触发的事件处理程序。可被阻止。 |
closeAutoFocus | Event | 在关闭时自动聚焦时触发的事件处理程序。可被阻止。 |
close | MouseEvent | 当请求关闭对话框时调用的事件处理程序。 |
fullscreen | MouseEvent | 当请求切换对话框的全屏状态时,会调用此事件处理程序。 |
confirm | MouseEvent | 当通过确认操作请求关闭对话框时,将调用此事件处理程序。 |
cancel | MouseEvent | 当请求取消对话框时调用的事件处理程序。 |
插槽
| 插槽名 | 参数 | 描述 |
|---|---|---|
default | props: DialogCompactBaseSlotProps | 默认插槽的自定义内容。 |
trigger | DialogCompactBaseSlotProps | 触发槽的自定义内容。 |
title | DialogCompactBaseSlotProps | 标题槽位的自定义内容。 |
description | DialogCompactBaseSlotProps | 描述字段的自定义内容。 |
close | DialogCompactBaseSlotProps | close 插槽的自定义内容。 |
fullscreen | DialogCompactBaseSlotProps | 全屏插槽的自定义内容。 |
footer | DialogCompactBaseSlotProps | 页脚位置的自定义内容。 |
cancel | DialogCompactBaseSlotProps | “cancel”插槽的自定义内容。 |
confirm | DialogCompactBaseSlotProps | 用于 confirm 插槽的自定义内容。 |
注意事项
架构与对标差异
SSheet 是薄样式包装组件:它把每个 prop/插槽/事件转发给 Aria DialogCompact,仅提供继承 dialogVariants 并按方向定制 popup 类的 sheetVariants 配方。这使得侧边面板与对话框行为一致而仅表现不同——与 shadcn-ui/vaul 式面板相同的 headless/样式分离;而 Ant Design 的 drawer(带 placement/width/closable/mask prop 的单一样式化组件)及 Element Plus/Mantine/Naive UI 为另一模型。
| 能力 | VeanUI | shadcn/ui | Ant Design Drawer | Element Plus Drawer | Mantine Drawer | Naive UI Drawer |
|---|---|---|---|---|---|---|
| 复用 dialog 基座 | ✅ | ✅ | — | — | — | — |
| Aria/样式分离 | ✅ | ✅ | — | — | — | — |
| 4 个方向(side) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| 模态(aria-modal+陷阱) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| 关闭时焦点还原 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| 尺寸(6) | ✅ | — | — | — | — | — |
| 纯净(无头/底部) | ✅ | — | — | — | — | — |
— = 不支持或采用不同交互模型。
运行时注意
- 侧边面板继承 dialog 契约:默认模态,弹层传送至
document.body;Escape/外部交互关闭。 side只改变滑动方向与位置类;可访问role仍为dialog(侧边面板没有独立的 ARIA 角色)。- 左右面板沿逻辑方向滑动,并在 RTL(
dir)下镜像。 - 全屏时面板从所锚定的那条边撑满视口,
side只决定是哪条边;各方向自身的尺寸上限(w-3/4/sm:max-w-sm、以及100dvh - 2rem的高度上限)会被解除。 - 命令式
dialog(...)API 在传入匹配选项时同样能渲染侧边面板——无需独立的 sheet 服务。
从 SDrawer 迁移(v0.50.0)
SDrawer 这一名称现已归属手势驱动的 Drawer。侧边面板以新名称保留完全一致的行为:
| 旧名 | 新名 |
|---|---|
SDrawer(侧边面板) | SSheet |
@vean/ui → SDrawer | @vean/ui → SSheet |
drawerVariants | sheetVariants |
DrawerProps / DrawerEmits / DrawerSlots | SheetProps / SheetEmits / SheetSlots |
<!-- 旧 -->
<SDrawer v-model:open="open" side="left" title="筛选">...</SDrawer>
<!-- 新 -->
<SSheet v-model:open="open" side="left" title="筛选">...</SSheet>FAQ
如何从特定边缘滑出面板?
设置 side 为 top/bottom/left/right:
<SSheet v-model:open="open" side="left" title="筛选">...</SSheet>如何控制打开状态?
用 v-model 绑定 open,或使用 defaultOpen 实现非受控面板:
<SSheet v-model:open="open" title="设置">...</SSheet>如何添加取消/确认操作?
使用 footer 插槽,或依赖带本地化文本的 showCancel/showConfirm:
<SSheet v-model:open="open" show-confirm confirm-text="应用" title="偏好设置">
<template #trigger><SButton>打开</SButton></template>
</SSheet>如何制作自定义面板?
使用 pure 并填充默认插槽:
<SSheet v-model:open="open" pure side="bottom">
<div class="custom">...</div>
</SSheet>如何让面板全屏?
用 show-fullscreen 渲染头部切换按钮,或用 v-model:fullscreen 直接驱动状态。两种方式都会让面板从 side 所在一侧撑满视口:
<SSheet v-model:open="open" v-model:fullscreen="fullscreen" show-fullscreen side="right" title="设置">
<template #trigger><SButton>打开</SButton></template>
</SSheet>