Skyroc UI
弹层覆盖

BottomSheet

从屏幕底部滑出的移动端面板组件

底部抽屉(BottomSheet)用于在当前页面上方展示临时内容,常见于移动端操作面板、筛选器、表单确认和上下文操作。

import {
  BottomSheet,
  BottomSheetClose,
  BottomSheetContent,
  BottomSheetContentBody,
  BottomSheetDescription,
  BottomSheetFooter,
  BottomSheetHeader,
  BottomSheetKnob,
  BottomSheetOverlay,
  BottomSheetRoot,
  BottomSheetTitle,
  BottomSheetTrigger
} from '@skyroc/web-ui';

架构说明

BottomSheet 基于 Vaul 的 RootContentOverlayClose 等能力,并复用项目 Dialog 的标题、描述、页脚、触发器和关闭按钮样式。

  • BottomSheetRoot:Vaul Root,负责打开状态、拖拽、snap point、背景缩放等行为。
  • BottomSheetContent:底部面板内容,内部自动挂载 Portal、Overlay、ContentBody 和 Knob。
  • BottomSheetKnob:面板顶部的拖拽指示条。
  • BottomSheet:组合式主组件,内置 Trigger、Content、Header、Title、Description、Close 和 Footer。

何时使用

  • 移动端需要从屏幕底部展示补充内容或操作面板时。
  • 页面上下文不应完全跳转,但需要临时聚焦一个任务时。
  • 内容适合纵向阅读、拖拽关闭或配合底部操作按钮时。
  • 桌面端复杂表单或长内容弹窗优先考虑 Dialog 或 Drawer。

基础用法

通过 trigger 设置打开触发器,通过 titledescriptionchildrenfooter 组织内容。

Preview
Code
Loading...

页脚与关闭

设置 footer 可在底部放置操作按钮。需要点击按钮关闭面板时,可使用 BottomSheetClose asChild 包裹自定义按钮。

设置 showClose 后,头部会显示默认关闭按钮;通过 closeProps 可以调整关闭按钮属性。

拖拽与打开状态

BottomSheet 继承 Vaul Root 的行为属性,可通过 open / onOpenChange 控制打开状态,通过 snapPointsactiveSnapPointsetActiveSnapPoint 配置吸附点,通过 dismissiblehandleOnlycloseThreshold 控制关闭交互。

自定义样式

通过 classNames 控制 overlaycontentcontentBodyknobheadertitledescriptionfooterclose 等 slot。

通过 size 可以统一控制 BottomSheet 的内容容器、正文间距、拖拽指示条、标题、描述、关闭按钮和页脚等结构尺寸。需要局部覆盖时,可继续通过 contentProps、各 slot props 或 classNames 精细调整。

API

BottomSheet

通用属性参考:基于 Vaul Root,并额外提供项目化的 header、content、footer、trigger 和 slot 样式配置。

属性说明类型默认值
trigger触发 BottomSheet 打开的元素ReactNode-
title面板标题ReactNode-
description面板描述文本ReactNode-
children面板主体内容ReactNode-
footer页脚内容,通常放置操作按钮ReactNode-
showClose是否显示默认关闭按钮booleanfalse
size尺寸,影响内容容器、正文间距、拖拽指示条、标题、描述、关闭按钮和页脚等样式'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl'-
classNames各 slot 的自定义 classBottomSheetClassNames-
contentProps传递给 BottomSheetContent 的额外 propsBottomSheetContentProps-
closeProps传递给 BottomSheetClose 的额外 propsBottomSheetCloseProps-
headerProps传递给 BottomSheetHeader 的额外 propsBottomSheetHeaderProps-
titleProps传递给 BottomSheetTitle 的额外 propsBottomSheetTitleProps-
descriptionProps传递给 BottomSheetDescription 的额外 propsBottomSheetDescriptionProps-
footerProps传递给 BottomSheetFooter 的额外 propsBottomSheetFooterProps-
open受控模式下的打开状态boolean-
defaultOpen非受控模式下的默认打开状态boolean-
onOpenChange打开状态变化时触发(open: boolean) => void-
shouldScaleBackground打开时是否缩放背景booleantrue
modal是否使用模态交互;为 false 时允许与外部元素交互boolean-
dismissible是否允许拖拽、点击外部、Esc 等方式关闭boolean-
direction抽屉方向'top' | 'bottom' | 'left' | 'right''bottom'
snapPoints吸附点列表,可使用比例或 px 字符串(number | string)[]-
activeSnapPoint当前激活的吸附点number | string | null-
setActiveSnapPoint更新当前吸附点(snapPoint: number | string | null) => void-
fadeFromIndex从哪个吸附点开始应用遮罩淡入number-
closeThreshold拖拽关闭阈值,0 到 1 之间number-
handleOnly是否只允许通过 handle/knob 拖拽boolean-
fixed键盘打开时是否只改变高度而不整体上移boolean-
nested是否作为嵌套抽屉使用boolean-
containerPortal 挂载容器HTMLElement | null-
onDrag拖拽过程中触发(event: PointerEvent<HTMLDivElement>, percentageDragged: number) => void-
onRelease拖拽释放时触发(event: PointerEvent<HTMLDivElement>, open: boolean) => void-
onClose关闭时触发() => void-
onAnimationEnd打开或关闭动画结束后触发(open: boolean) => void-

子组件

属性说明类型默认值
BottomSheetRootVaul Root,负责抽屉状态和交互行为DialogProps-
BottomSheetTrigger打开触发器,复用 DialogTriggerDialogTriggerProps-
BottomSheetContent面板内容容器,自动包含 Portal、Overlay、ContentBody 和 KnobBottomSheetContentProps-
BottomSheetContentBody内容内部包裹容器BottomSheetContentBodyProps-
BottomSheetKnob顶部拖拽指示条BottomSheetKnobProps-
BottomSheetOverlay遮罩层BottomSheetOverlayProps-
BottomSheetHeader头部容器,复用 DialogHeaderBottomSheetHeaderProps-
BottomSheetTitle标题组件BottomSheetTitleProps-
BottomSheetDescription描述组件BottomSheetDescriptionProps-
BottomSheetFooter页脚容器,复用 DialogFooterBottomSheetFooterProps-
BottomSheetClose关闭触发器,内部使用 Vaul CloseBottomSheetCloseProps-

类型

BottomSheetProps

主组件属性。继承 Vaul DialogProps,并额外提供项目化内容、标题、描述、页脚和 slot 样式配置。

字段类型说明
activeSnapPointnumber | string | null当前激活吸附点。来自 Vaul DialogProps。
childrenReact.ReactNode面板主体内容。
classNamesBottomSheetClassNames各 slot 的自定义 class。
closePropsBottomSheetCloseProps传递给关闭按钮的属性。
closeThresholdnumber拖拽关闭阈值。来自 Vaul DialogProps。
containerHTMLElement | nullPortal 挂载容器。来自 Vaul DialogProps。
contentPropsBottomSheetContentProps传递给内容容器的属性。
defaultOpenboolean默认打开状态。来自 Vaul DialogProps。
descriptionReact.ReactNode描述内容。
descriptionPropsBottomSheetDescriptionProps传递给描述组件的属性。
direction'top' | 'bottom' | 'left' | 'right'抽屉方向。来自 Vaul DialogProps。
dismissibleboolean是否允许用户关闭。来自 Vaul DialogProps。
fadeFromIndexnumber遮罩淡入起始吸附点索引。仅在 snapPoints 存在时使用。
fixedboolean键盘打开时是否固定位置。来自 Vaul DialogProps。
footerReact.ReactNode页脚内容。
footerPropsBottomSheetFooterProps传递给页脚容器的属性。
handleOnlyboolean是否只允许通过 handle 拖拽。来自 Vaul DialogProps。
headerPropsBottomSheetHeaderProps传递给头部容器的属性。
modalboolean是否模态。来自 Vaul DialogProps。
nestedboolean是否嵌套抽屉。来自 Vaul DialogProps。
onAnimationEnd(open: boolean) => void动画结束后触发。来自 Vaul DialogProps。
onClose() => void关闭时触发。来自 Vaul DialogProps。
onDrag(event: React.PointerEvent<HTMLDivElement>, percentageDragged: number) => void拖拽中触发。来自 Vaul DialogProps。
onOpenChange(open: boolean) => void打开状态变化时触发。来自 Vaul DialogProps。
onRelease(event: React.PointerEvent<HTMLDivElement>, open: boolean) => void拖拽释放时触发。来自 Vaul DialogProps。
openboolean受控打开状态。来自 Vaul DialogProps。
setActiveSnapPoint(snapPoint: number | string | null) => void更新当前吸附点。来自 Vaul DialogProps。
shouldScaleBackgroundboolean是否缩放背景。默认 true。
showCloseboolean是否展示关闭按钮。
size'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl'统一控制 BottomSheet 结构尺寸。
snapPoints(number | string)[]吸附点列表。来自 Vaul DialogProps。
titleReact.ReactNode标题内容。
titlePropsBottomSheetTitleProps传递给标题组件的属性。
triggerReact.ReactNode触发打开的元素。

BottomSheetClassNames

BottomSheet 可定制 slot 的 class 集合。

字段类型说明
closeClassValue关闭按钮 class,来自 DialogSlots。
closeIconClassValue关闭图标 class,来自 BottomSheetSlots。
contentClassValue面板内容容器 class。
contentBodyClassValue面板内部内容包裹区 class。
descriptionClassValue描述区域 class。
footerClassValue页脚区域 class。
headerClassValue头部区域 class。
knobClassValue拖拽指示条 class。
overlayClassValue遮罩层 class。
titleClassValue标题区域 class。

BottomSheetContentProps

内容容器属性。继承 Vaul ContentProps,并通过 StyledComponentProps 增加 className 和 size。

字段类型说明
childrenReact.ReactNode内容子节点。
classNameClassValue内容容器 class。
classNamesPick<BottomSheetClassNames, 'content' | 'contentBody' | 'knob' | 'overlay'>内容区域相关 slot class。
forceMounttrue强制挂载内容。来自 Radix Dialog Content props。
onCloseAutoFocus(event: Event) => void关闭后自动聚焦前触发。来自 ContentProps。
onEscapeKeyDown(event: KeyboardEvent) => void按 Escape 时触发。来自 ContentProps。
onOpenAutoFocus(event: Event) => void打开后自动聚焦前触发。来自 ContentProps。
size'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl'内容容器尺寸。

BottomSheetContentBodyProps

内容内部包裹容器属性,等价于 HTMLComponentProps<"div">。

字段类型说明
childrenReact.ReactNode子节点。
classNameClassValue内容包裹区 class。
idstringDOM id。
size'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl'尺寸属性。

BottomSheetKnobProps

拖拽指示条属性,等价于 HTMLComponentProps<"div">。

字段类型说明
classNameClassValue拖拽指示条 class。
idstringDOM id。
size'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl'尺寸属性。

BottomSheetOverlayProps

遮罩层属性,等价于 Omit<DialogOverlayProps, "component">。

字段类型说明
classNameClassValue遮罩层 class。
forceMounttrue强制挂载遮罩层。
size'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl'尺寸属性。

BottomSheetHeaderProps

头部容器属性,等价于 DialogHeaderProps。

字段类型说明
childrenReact.ReactNode头部内容。
classNameClassValue头部 class。
size'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl'尺寸属性。

BottomSheetDescriptionProps

描述组件属性,等价于 Omit<DialogDescriptionProps, "component">。

字段类型说明
childrenReact.ReactNode描述内容。
classNameClassValue描述 class。
size'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl'尺寸属性。

BottomSheetTitleProps

标题组件属性,等价于 Omit<DialogTitleProps, "component">。

字段类型说明
childrenReact.ReactNode标题内容。
classNameClassValue标题 class。
size'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl'尺寸属性。

BottomSheetCloseProps

关闭按钮属性,等价于 Omit<DialogCloseProps, "component">。

字段类型说明
asChildboolean将关闭行为绑定到子元素。
childrenReact.ReactNode自定义关闭按钮内容。
classNameClassValue关闭按钮 class。
size'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl'尺寸属性。

页脚容器属性,等价于 HTMLComponentProps<"div">。

字段类型说明
childrenReact.ReactNode页脚内容。
classNameClassValue页脚 class。
size'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl'尺寸属性。

BottomSheetSlots

BottomSheet 自身的 slot

'closeIcon' | 'content' | 'contentBody' | 'description' | 'footer' | 'header' | 'knob' | 'overlay' | 'title'

DialogSlots

复用 Dialog 的 slot

'close' | 'content' | 'description' | 'footer' | 'header' | 'overlay' | 'title'

ClassValue

CSS 类名类型

string | null | undefined | Record<string, boolean> | ClassValue[]

On this page