Skip to content

Drawer

A panel that slides in from the edge of the screen.

Basic Usage

vue
<template>
  <bp-space :size="16">
    <bp-button @click="handleOpen('right')">Popup right</bp-button>
    <bp-button @click="handleOpen('left')">Popup left</bp-button>
  </bp-space>

  <bp-drawer v-model="show" :placement title="Basic drawer">
    <p>This is a basic drawer.</p>
  </bp-drawer>
</template>

<script setup lang="ts">
import { ref } from "vue";

const show = ref(false);
const placement = ref("right");

const handleOpen = (p: string) => {
  placement.value = p;
  show.value = true;
};
</script>

Placement

Control side and size with placement, width, and height.

vue
<template>
  <bp-space :size="16">
    <bp-button @click="handleOpen('right')">Popup right</bp-button>
    <bp-button @click="handleOpen('left')">Popup left</bp-button>
    <bp-button @click="handleOpen('up')">Popup top</bp-button>
    <bp-button @click="handleOpen('down')">Popup bottom</bp-button>
  </bp-space>

  <bp-drawer v-model="show" :placement title="Placement">
    <p>Current placement: {{ placement }}</p>
  </bp-drawer>
</template>

<script setup lang="ts">
import { ref } from "vue";

const show = ref(false);
const placement = ref("right");

const handleOpen = (p: string) => {
  placement.value = p;
  show.value = true;
};
</script>

Custom Slots

Customize header and footer slots.

vue
<template>
  <bp-space :size="16">
    <bp-button @click="showCustom = true">Custom content</bp-button>
    <bp-button @click="showHeader = true">Custom header</bp-button>
    <bp-button @click="showFooter = true">Custom footer</bp-button>
  </bp-space>

  <bp-drawer v-model="showCustom" title="User details">
    <div class="custom-content">
      <p><strong>Name:</strong>Zhang San</p>
      <p><strong>Email:</strong>zhangsan@example.com</p>
      <p><strong>Dept:</strong>Engineering</p>
    </div>
  </bp-drawer>

  <bp-drawer v-model="showHeader" title="Custom header">
    <template #header>
      <div class="custom-header">
        <IconStarFill size="18" style="color: #f7ba2a" />
        <span>Custom title area</span>
      </div>
    </template>
    <p>Header uses a custom slot.</p>
  </bp-drawer>

  <bp-drawer v-model="showFooter" title="Custom footer">
    <p>Footer uses a custom slot.</p>
    <template #footer>
      <bp-button type="secondary" @click="showFooter = false">Close</bp-button>
      <bp-button status="danger" @click="showFooter = false">Delete</bp-button>
    </template>
  </bp-drawer>
</template>

<script setup lang="ts">
import { ref } from "vue";
import { IconStarFill } from "birdpaper-icon";

const showCustom = ref(false);
const showHeader = ref(false);
const showFooter = ref(false);
</script>

<style lang="scss" scoped>
.custom-content {
  p {
    line-height: 2.2;
    border-bottom: 1px solid #f0f0f0;
  }
}

.custom-header {
  display: flex;
  align-items: center;
  gap: 8px;
  font-weight: 600;
}
</style>

Async Confirm

Use on-before-ok and return loading until resolved.

vue
<template>
  <bp-button @click="show = true">Async confirm</bp-button>

  <bp-drawer v-model="show" title="Submit confirm" :on-before-ok="handleBeforeOk">
    <p>After confirm, an async action runs and the confirm button enters loading.</p>
  </bp-drawer>
</template>

<script setup lang="ts">
import { ref } from "vue";

const show = ref(false);

const handleBeforeOk = async () => {
  await new Promise((resolve) => setTimeout(resolve, 2000));
  return true;
};
</script>

Drawer Props

v-modelWhether the drawer is visible
Boolean
--
titleDrawer title
String
Title-
widthDrawer width (for left/right)
String
360px-
heightDrawer height (for up/down)
String
360px-
placementDrawer placement
String
right-
hide-footerWhether to hide the footer
Boolean
--
hide-closeWhether to hide the close button
Boolean
--
borderWhether bordered
Boolean
--
mask-closableWhether clicking the mask closes the drawer
Boolean
true-
ok-textOK button text
String
OK-
cancel-textCancel button text
String
Cancel-
on-before-okAsync callback before confirm; return true to close, false to keep open. Button shows loading automatically
Function
--

Drawer Events

cancelTriggered on cancel or close--
confirmTriggered after confirm--

Drawer Slots

defaultDrawer body content--
headerCustom header--
footerCustom footer actions--