Drawer 手势抽屉

从屏幕边缘滑出的面板,用于显示侧边内容或表单。基于 BrConfigProvider 实现全局主题配置。

组件特性

  • 👆 手势驱动:支持滑动手势关闭,带来原生应用般流畅的交互体验。
  • 📏 自适应尺寸:支持内容自适应高度或指定固定尺寸,适配各种内容量。
  • 🧭 多方向支持:支持从屏幕上、下、左、右四个方向滑出。
  • 🎨 主题定制:基于 BrConfigProvider 支持全局主题定制。

基础用法

<script setup lang="ts">
import { ref } from 'vue'
import { 
  BrDrawer, 
  BrDrawerTrigger, 
  BrDrawerContent, 
  BrDrawerHeader, 
  BrDrawerFooter, 
  BrDrawerTitle, 
  BrDrawerDescription,
  BrDrawerClose,
  BrButton 
} from '@breezeui/vue'

const isOpen = ref(false)
</script>

<template>
  <div class="flex flex-col items-center gap-4">
    <BrDrawer v-model:open="isOpen">
      <BrDrawerTrigger as-child>
        <BrButton>Open Drawer</BrButton>
      </BrDrawerTrigger>
      <BrDrawerContent>
        <BrDrawerHeader>
          <BrDrawerTitle>Edit Profile</BrDrawerTitle>
          <BrDrawerDescription>
            Edit your profile here. Click save when you're done.
          </BrDrawerDescription>
        </BrDrawerHeader>
        
        <div class="p-6 space-y-4">
          <div class="h-32 bg-muted rounded-md flex items-center justify-center text-muted-foreground">
            Content Area
          </div>
        </div>

        <BrDrawerFooter>
          <BrButton>Save Changes</BrButton>
          <BrDrawerClose as-child>
            <BrButton variant="outline">Cancel</BrButton>
          </BrDrawerClose>
        </BrDrawerFooter>
      </BrDrawerContent>
    </BrDrawer>
    
    <p class="text-sm text-muted-foreground">
      Status: {{ isOpen ? 'Open' : 'Closed' }}
    </p>
  </div>
</template>

方向

<script setup lang="ts">
import { ref } from 'vue'
import { 
  BrDrawer, 
  BrDrawerTrigger, 
  BrDrawerContent, 
  BrDrawerHeader, 
  BrDrawerFooter, 
  BrDrawerTitle, 
  BrDrawerDescription,
  BrDrawerClose,
  BrButton 
} from '@breezeui/vue'

const directions = ['top', 'bottom', 'left', 'right'] as const
</script>

<template>
  <div class="flex flex-wrap gap-4 justify-center">
    <div v-for="dir in directions" :key="dir">
      <BrDrawer :direction="dir">
        <BrDrawerTrigger as-child>
          <BrButton variant="outline">{{ dir.toUpperCase() }}</BrButton>
        </BrDrawerTrigger>
        <BrDrawerContent>
          <BrDrawerHeader>
            <BrDrawerTitle>Drawer Title - {{ dir.toUpperCase() }}</BrDrawerTitle>
            <BrDrawerDescription>
              Current drawer slide direction: {{ dir }}
            </BrDrawerDescription>
          </BrDrawerHeader>
          
          <div class="p-6 space-y-4">
            <div class="h-32 bg-muted rounded-md flex items-center justify-center text-muted-foreground">
              Content Area ({{ dir }})
            </div>
          </div>

          <BrDrawerFooter>
            <BrDrawerClose as-child>
              <BrButton>Close</BrButton>
            </BrDrawerClose>
          </BrDrawerFooter>
        </BrDrawerContent>
      </BrDrawer>
    </div>
  </div>
</template>

尺寸

<script setup lang="ts">
import { ref } from 'vue'
import { 
  BrDrawer, 
  BrDrawerTrigger, 
  BrDrawerContent, 
  BrDrawerHeader, 
  BrDrawerFooter, 
  BrDrawerTitle, 
  BrDrawerDescription,
  BrDrawerClose,
  BrButton 
} from '@breezeui/vue'

const isOpen = ref(false)
</script>

<template>
  <div class="flex flex-col items-center gap-4">
    <BrDrawer v-model:open="isOpen">
      <BrDrawerTrigger as-child>
        <BrButton variant="outline">Custom Size (via class)</BrButton>
      </BrDrawerTrigger>
      <BrDrawerContent class="max-h-[50vh]">
        <BrDrawerHeader>
          <BrDrawerTitle>Custom Height</BrDrawerTitle>
          <BrDrawerDescription>
            This drawer has a max-height set via `class="max-h-[50vh]"`.
          </BrDrawerDescription>
        </BrDrawerHeader>
        
        <div class="p-6 space-y-4">
          <div class="h-20 bg-muted rounded-md flex items-center justify-center text-muted-foreground">
            Content Area (50% Height)
          </div>
        </div>

        <BrDrawerFooter>
          <BrDrawerClose as-child>
            <BrButton>Close</BrButton>
          </BrDrawerClose>
        </BrDrawerFooter>
      </BrDrawerContent>
    </BrDrawer>
  </div>
</template>

关闭按钮

<script setup lang="ts">
import {
  BrDrawer,
  BrDrawerTrigger,
  BrDrawerContent,
  BrDrawerHeader,
  BrDrawerTitle,
  BrDrawerDescription,
  BrDrawerFooter,
  BrDrawerClose,
  BrButton,
} from '@breezeui/vue'
</script>

<template>
  <BrDrawer>
    <BrDrawerTrigger as-child>
      <BrButton variant="outline">With Close Button</BrButton>
    </BrDrawerTrigger>
    <BrDrawerContent show-close>
      <BrDrawerHeader>
        <BrDrawerTitle>Closable Drawer</BrDrawerTitle>
        <BrDrawerDescription>Click the close icon in the top right corner to close the drawer.</BrDrawerDescription>
      </BrDrawerHeader>
      <div class="p-4 pb-0">
        <div class="flex items-center justify-center space-x-2">
          <span class="text-2xl font-bold">Content Area</span>
        </div>
        <div class="mt-3 h-[120px] w-full rounded-md bg-muted/50 flex items-center justify-center text-muted-foreground">
          Here is some content...
        </div>
      </div>
      <BrDrawerFooter>
        <BrButton>Submit</BrButton>
        <BrDrawerClose as-child>
          <BrButton variant="outline">Cancel</BrButton>
        </BrDrawerClose>
      </BrDrawerFooter>
    </BrDrawerContent>
  </BrDrawer>
</template>

API

Props

属性名类型默认值说明
openbooleanfalse是否打开
defaultOpenbooleanfalse默认是否打开
directionstring'bottom'方向:top, bottom, left, right
dismissiblebooleantrue是否可关闭
modalbooleantrue是否为模态

DrawerContent Props

属性名类型默认值说明
showHandlebooleanfalse是否显示把手
showClosebooleanfalse是否显示关闭按钮
classstring-自定义类名
shouldScaleBackgroundbooleanfalse是否锁定滚动
activeSnapPointstring | number-嵌套级别

Slots

插槽名说明
default触发器内容
content抽屉内容
header头部内容
footer底部内容

Emits

事件名说明参数
update:open打开状态变化时触发(value: boolean)
close关闭时触发-

使用示例

<template>
  <BrDrawer v-model:open="isOpen">
    <BrDrawerTrigger>
      <BrButton>打开抽屉</BrButton>
    </BrDrawerTrigger>
    <BrDrawerContent>
      <BrDrawerHeader>
        <BrDrawerTitle>标题</BrDrawerTitle>
      </BrDrawerHeader>
      <div>内容...</div>
    </BrDrawerContent>
  </BrDrawer>
</template>