Modal
UiModal presents content in an overlay; UiConfirmModal adds confirm / cancel actions. Open and close them through their exposed handle (showDialog / closeDialog).
Open a modal
<script setup lang="ts">
import { ref } from 'vue'
const modal = ref()
</script>
<template>
<UiButton variant="filled" text="Open" @click="modal.showDialog()" />
<UiModal ref="modal" title="Profile" size="md">
<template #body>
<p>Modal content…</p>
</template>
</UiModal>
</template>
Start in a field
When a modal opens, the browser focuses its first focusable element, often the close button. To start in a field, mark the field autofocus. On a Colorffy input the attribute lands on the component's wrapper, so UiModal focuses the control inside it:
<template>
<UiModal ref="modal" title="Invite members" size="md">
<template #body>
<UiInputTags id="emails" v-model="emails" label="Email addresses" autofocus />
</template>
</UiModal>
</template>
Pick a mode and size
<template>
<UiModal ref="sheet" mode="side-sheet" size="lg" title="Filters" />
</template>
Confirm a destructive action
<script setup lang="ts">
import { ref } from 'vue'
const confirm = ref()
function remove() {
// delete, then close
confirm.value.closeDialog()
}
</script>
<template>
<UiConfirmModal
ref="confirm"
variant="danger"
title="Delete item?"
message="This can't be undone."
confirm-label="Delete"
cancel-label="Cancel"
@confirm="remove"
/>
</template>
UiModal props
| Prop | Type | Default | Description |
|---|---|---|---|
mode | 'modal' | 'side-sheet' | 'headless' | — | Dialog shape. |
size | 'sm' | 'md' | 'lg' | 'fullscreen' | — | Dialog size: up to --cffy-container-md (28rem), --cffy-container-2xl (42rem) or --cffy-container-4xl (56rem); fullscreen fills the viewport. |
title | string | null | — | Header title. |
message | string | null | — | Body message. |
closeOnClickOutside | boolean | true | Dismiss when clicking the backdrop. |
showAsModal | boolean | null | true | Legacy modal toggle. |
customClass / bodyDialogClass | string | string[] | Record<string, boolean> | null | — | Extra classes. |
Exposed: showDialog(), closeDialog().
Emits: close, whenever the dialog closes: closeDialog(), a click outside, or Esc.
Slots: #header (defaults to title), #body (defaults to message), #footer.
UiConfirmModal
Extends UiModal with:
| Prop | Type | Default | Description |
|---|---|---|---|
variant | 'danger' | 'warning' | 'success' | 'primary' | 'danger' | Icon and confirm-button color. |
confirmLabel | string | null | 'Delete' | Confirm button label. |
cancelLabel | string | 'Cancel' | Cancel button label. |
isLoading | boolean | false | Loading state on the confirm button. |
loadingLabel | string | 'Deleting...' | Text while loading. |
Emits: confirm (the dialog stays open until you call closeDialog()), and close whenever it closes: the cancel button, a click outside, Esc or closeDialog().
Slots: #messages — extra body content, rendered after title and message.
CSS variables
Every dialog (UiModal, UiConfirmModal, side sheets) reads these variables. Set them on :root to restyle all dialogs. On screens below 992px the bottom sheet keeps its own motion and top-rounded corners.
:root {
--cffy-dialog-radius: var(--cffy-radius-xl);
--cffy-dialog-backdrop-color: color-mix(in oklab, black 60%, transparent);
--cffy-dialog-duration: var(--cffy-duration-400);
}
| Variable | Default | Controls |
|---|---|---|
--cffy-dialog-bg-color / --cffy-dialog-color | --cffy-surface-overlay / --cffy-on-background | Background, and title and body text |
--cffy-dialog-border-color | --cffy-outline-overlay | Border |
--cffy-dialog-radius | --cffy-shape-container (12px) | Corners of modals, side sheets and confirms |
--cffy-dialog-shadow | --cffy-shadow-xl | Shadow |
--cffy-dialog-padding | --cffy-space-16 | Content padding |
--cffy-dialog-spacing | --cffy-space-20 | Space around the body and between footer buttons (half) |
--cffy-dialog-max-size | 90% | Maximum width and height |
--cffy-dialog-title-font-size / --cffy-dialog-title-font-weight | --cffy-fs-base / --cffy-fw-700 | Title |
--cffy-dialog-subtitle-color / --cffy-dialog-subtitle-font-size | --cffy-muted-a10 / --cffy-fs-2xs | Subtitle |
--cffy-dialog-icon-bg-color / --cffy-dialog-icon-color | --cffy-primary-a10 / --cffy-on-primary | Headless-mode icon |
--cffy-dialog-backdrop-color | --cffy-overlay-backdrop | Backdrop behind modals |
--cffy-dialog-backdrop-blur | 5px | Blur with dialog-backdrop-blur |
--cffy-dialog-easing / --cffy-dialog-duration | --cffy-ease-overshoot-soft / --cffy-duration-600 | Opening animation of modals and side sheets |