Skip to content

Modal

A modal dialog for confirmations and focused content.

Basic Usage

vue
<template>
  <bp-button @click="handleClick">open modal</bp-button>
</template>

<script lang="ts" setup>
import { Modal } from "@birdpaper-ui/components";

const handleClick = ()=>{
  Modal.info({
    title: "title",
    content: "content",
  });
}
</script>

Supports info, success, warning, error, and confirm.

vue
<template>
  <bp-space :size="16">
    <bp-button @click="openModal('info')">Info</bp-button>
    <bp-button @click="openModal('success')">Success</bp-button>
    <bp-button @click="openModal('warning')">Warning</bp-button>
    <bp-button @click="openModal('error')">Error</bp-button>
    <bp-button @click="openModal('confirm')">Confirm</bp-button>
  </bp-space>
</template>

<script lang="ts" setup>
import { Modal } from "@birdpaper-ui/components";

const openModal = (type: string) => {
  (Modal as any)[type]({
    title: `${type} dialog`,
    content: `This is a ${type} dialog`,
  });
};
</script>

Customize actions with the footer slot.

vue
<template>
  <bp-button @click="handleOpen">Custom footer</bp-button>

  <bp-modal v-model="show" title="Title">
    <p>Dialog content.</p>

    <template #footer>
      <bp-button type="secondary" @click="show = false">Cancel</bp-button>
      <bp-button type="secondary" status="danger" @click="show = false">Confirm delete</bp-button>
    </template>
  </bp-modal>
</template>

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

const show = ref(false);

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

Async Confirm

Use on-before-ok and keep loading until the promise resolves.

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

  <bp-modal 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-modal>
</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>

Fullscreen

Open a fullscreen dialog with fullscreen.

vue
<template>
  <bp-button @click="show = true">Fullscreen Modal</bp-button>

  <bp-modal v-model="show" title="Fullscreen dialog" fullscreen>
    <p>This is a fullscreen dialog for large content.</p>
  </bp-modal>
</template>

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

const show = ref(false);
</script>

Custom Slots

Customize the dialog chrome with the header slot.

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

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

  <bp-modal v-model="showContent" title="Custom content">
    <div class="custom-content">
      <p>Place any custom content here:</p>
      <ul>
        <li>Form</li>
        <li>Table</li>
        <li>Image</li>
      </ul>
    </div>
  </bp-modal>
</template>

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

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

<style lang="scss" scoped>
.custom-header {
  display: flex;
  align-items: center;
  gap: 8px;
  font-weight: 600;
}

.custom-content {
  ul {
    padding-left: 20px;
    line-height: 2;
  }
}
</style>
v-modelWhether the modal is visible
Boolean
--
is-methodWhether opened via imperative API (internal)
Boolean
--
typeModal type; affects title icon style
String
--
titleModal title
String
--
contentModal content text
String
--
widthModal width
StringNumber
50%-
body-classCustom class for the body area
String
--
border-radiusModal border radius
String
8px-
centerWhether vertically centered
Boolean
--
show-borderWhether bordered
Boolean
true-
topOffset from the top
String
0-
bottomOffset from the bottom
String
0-
mask-closableWhether clicking the mask closes the modal
Boolean
true-
hide-headerWhether to hide the header
Boolean
--
hide-footerWhether to hide the footer
Boolean
--
hide-closeWhether to hide the close button
Boolean
--
fullscreenWhether fullscreen
Boolean
--
ok-textOK button text
String
OK-
ok-btn-propsOK button props, passed through to Button
Object
--
cancel-textCancel button text
String
Cancel-
cancel-btn-propsCancel button props, passed through to Button
Object
--
hide-cancelWhether to hide the cancel button
Boolean
--
hide-title-iconWhether to hide title icon
Boolean
--
on-before-okAsync callback before confirm; return true to close, false to keep open. Button shows loading automatically
Function
--
cancelTriggered on cancel or close--
confirmTriggered after confirm--
defaultModal body content--
headerCustom header--
footerCustom footer actions--