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>Modal Type
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>Custom Footer
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>Modal Props
| v-model | Whether the modal is visible | Boolean | - | - |
| is-method | Whether opened via imperative API (internal) | Boolean | - | - |
| type | Modal type; affects title icon style | String | - | - |
| title | Modal title | String | - | - |
| content | Modal content text | String | - | - |
| width | Modal width | StringNumber | 50% | - |
| body-class | Custom class for the body area | String | - | - |
| border-radius | Modal border radius | String | 8px | - |
| center | Whether vertically centered | Boolean | - | - |
| show-border | Whether bordered | Boolean | true | - |
| top | Offset from the top | String | 0 | - |
| bottom | Offset from the bottom | String | 0 | - |
| mask-closable | Whether clicking the mask closes the modal | Boolean | true | - |
| hide-header | Whether to hide the header | Boolean | - | - |
| hide-footer | Whether to hide the footer | Boolean | - | - |
| hide-close | Whether to hide the close button | Boolean | - | - |
| fullscreen | Whether fullscreen | Boolean | - | - |
| ok-text | OK button text | String | OK | - |
| ok-btn-props | OK button props, passed through to Button | Object | - | - |
| cancel-text | Cancel button text | String | Cancel | - |
| cancel-btn-props | Cancel button props, passed through to Button | Object | - | - |
| hide-cancel | Whether to hide the cancel button | Boolean | - | - |
| hide-title-icon | Whether to hide title icon | Boolean | - | - |
| on-before-ok | Async callback before confirm; return true to close, false to keep open. Button shows loading automatically | Function | - | - |
Modal Events
| cancel | Triggered on cancel or close | - | - |
| confirm | Triggered after confirm | - | - |
Modal Slots
| default | Modal body content | - | - |
| header | Custom header | - | - |
| footer | Custom footer actions | - | - |