MessageBox
A Neo-Brutalist structured feedback modal component built on top of reka-ui's Dialog primitives. Supports confirmation dialogs, status badges, Prompt input validation, and provides three usage modes: declarative component, imperative functional helpers (showMessageBox / showConfirm / showAlert / showPrompt), and Composable (useMessageBox).
Preview
1. 声明式组件 (MessageBox)
2. 命令式便捷方法 (Functional Helpers)
Installation
pnpm dlx brutx-vue@latest add message-boxUsage
Declarative Component Usage
Control visibility via v-model:open:
<script setup>
import { ref } from 'vue'
import { MessageBox, Button } from 'brutx-ui-vue'
const isOpen = ref(false)
function handleConfirm() {
console.log('Action confirmed')
}
</script>
<template>
<Button @click="isOpen = true">Open Confirmation</Button>
<MessageBox
v-model:open="isOpen"
title="Important Notice"
message="This action will permanently sync all configurations. Continue?"
type="warning"
@confirm="handleConfirm"
/>
</template>Imperative Helper Functions
Trigger dialogs directly without template markup:
<script setup>
import { showConfirm, showAlert, showPrompt } from 'brutx-ui-vue'
async function handleConfirm() {
const isConfirmed = await showConfirm('Are you sure you want to delete the selected items?')
if (isConfirmed) {
console.log('Deletion confirmed')
}
}
async function handleAlert() {
await showAlert('Operation completed successfully!')
}
async function handlePrompt() {
const result = await showPrompt('Please enter a new project name:', {
inputValue: 'My Project',
inputPattern: /^[A-Za-z0-9_-]+$/,
inputErrorMessage: 'Only alphanumeric characters, underscores, and hyphens are supported',
})
if (result.action === 'confirm') {
console.log('Input value:', result.value)
}
}
</script>
<template>
<div class="flex flex-wrap gap-3">
<button @click="handleConfirm">Confirmation Dialog (showConfirm)</button>
<button @click="handleAlert">Alert Dialog (showAlert)</button>
<button @click="handlePrompt">Prompt Dialog (showPrompt)</button>
</div>
</template>Composable API (useMessageBox)
Gain reactive control methods inside components:
<script setup>
import { useMessageBox } from 'brutx-ui-vue'
const { confirm, prompt, alert } = useMessageBox()
async function deleteRecord() {
const confirmed = await confirm('Are you sure you want to delete this record?', {
title: 'Delete Warning',
confirmButtonText: 'Yes, Delete',
cancelButtonText: 'Cancel',
})
if (confirmed) {
// Perform deletion
}
}
</script>
<template>
<button @click="deleteRecord">Delete Record</button>
</template>Type Variants
Four status variants mapped to bold Neo-Brutalist color palettes:
Type (type) | Color Palette | Use Case |
|---|---|---|
info | bg-brutal-info text-brutal-info-foreground | General notices and regular confirmations |
success | bg-brutal-success text-brutal-success-foreground | Successful operation confirmations |
warning | bg-brutal-accent text-brutal-accent-foreground | Destructive or irreversible action warnings (showConfirm default) |
error | bg-brutal-destructive text-brutal-destructive-foreground | Critical exceptions and blocker notifications |
Prompt Input & Regex Validation
Enable showInput and pass inputPattern for user input scenarios. When the input does not match the regex, confirmation is blocked and inputErrorMessage is displayed:
<script setup>
import { showPrompt } from 'brutx-ui-vue'
async function renameFile() {
const result = await showPrompt('Please enter the new filename:', {
title: 'Rename File',
inputPlaceholder: 'e.g. index.ts',
inputPattern: /^[a-zA-Z0-9_-]+\.[a-zA-Z0-9]+$/,
inputErrorMessage: 'Please provide a filename with a valid extension',
})
if (result.action === 'confirm') {
console.log('New filename:', result.value)
}
}
</script>API Reference
| Name | Type | Default | Description |
|---|---|---|---|
open | boolean | undefined | true | Controls dialog visibility and supports v-model:open. The dialog defaults to open when this prop is omitted. |
DetailsDeclared typeboolean | undefined Literal values
Default value details
Sourcepackages/ui/src/components/message-box/MessageBox.vue | |||
title | string | undefined | undefined | Sets the dialog title; the localized default title is used when omitted. |
DetailsDeclared typestring | undefined Default value details
Sourcepackages/ui/src/components/message-box/MessageBox.vue | |||
message | string | undefined | undefined | Sets the body message. When empty, the dialog description uses the title as fallback text. |
DetailsDeclared typestring | undefined Default value details
Sourcepackages/ui/src/components/message-box/MessageBox.vue | |||
type | MessageBoxType | undefined | "info" | Selects the info, success, warning, or error state and the status icon shown beside the title. |
DetailsDeclared typeMessageBoxType | undefined Literal values
Referenced types MessageBoxType Type definition — MessageBoxTypeexport type MessageBoxType = NonNullable<MessageBoxIconVariantProps['type']> Default value details
Sourcepackages/ui/src/components/message-box/MessageBox.vue | |||
showCancelButton | boolean | undefined | true | Controls whether the cancel button is shown. |
DetailsDeclared typeboolean | undefined Literal values
Default value details
Sourcepackages/ui/src/components/message-box/MessageBox.vue | |||
showCloseButton | boolean | undefined | true | Controls whether the close button is shown at the right of the title bar. |
DetailsDeclared typeboolean | undefined Literal values
Default value details
Sourcepackages/ui/src/components/message-box/MessageBox.vue | |||
confirmButtonText | string | undefined | undefined | Sets the confirm button label; the localized default label is used when omitted. |
DetailsDeclared typestring | undefined Default value details
Sourcepackages/ui/src/components/message-box/MessageBox.vue | |||
cancelButtonText | string | undefined | undefined | Sets the cancel button label; the localized default label is used when omitted. |
DetailsDeclared typestring | undefined Default value details
Sourcepackages/ui/src/components/message-box/MessageBox.vue | |||
confirmButtonClass | string | undefined | undefined | Additional CSS classes applied to the confirm button. |
DetailsDeclared typestring | undefined Default value details
Sourcepackages/ui/src/components/message-box/MessageBox.vue | |||
cancelButtonClass | string | undefined | undefined | Additional CSS classes applied to the cancel button. |
DetailsDeclared typestring | undefined Default value details
Sourcepackages/ui/src/components/message-box/MessageBox.vue | |||
showInput | boolean | undefined | false | Shows an input field for prompt-style interaction; when enabled, the confirm event includes its value. |
DetailsDeclared typeboolean | undefined Literal values
Default value details
Sourcepackages/ui/src/components/message-box/MessageBox.vue | |||
inputPlaceholder | string | undefined | undefined | Sets the placeholder shown while the prompt input is empty. |
DetailsDeclared typestring | undefined Default value details
Sourcepackages/ui/src/components/message-box/MessageBox.vue | |||
inputValue | string | undefined | "" | Sets the initial value of the prompt input; subsequent typing is held in component state. |
DetailsDeclared typestring | undefined Default value details
Sourcepackages/ui/src/components/message-box/MessageBox.vue | |||
inputPattern | RegExp | undefined | undefined | A regular expression used to validate the prompt value on confirmation. A mismatch shows the error text and neither emits confirm nor closes the dialog. |
DetailsDeclared typeRegExp | undefined Default value details
Sourcepackages/ui/src/components/message-box/MessageBox.vue | |||
inputErrorMessage | string | undefined | undefined | Sets the error text shown when input validation fails; the localized default message is used when omitted. |
DetailsDeclared typestring | undefined Default value details
Sourcepackages/ui/src/components/message-box/MessageBox.vue | |||
zIndex | number | undefined | undefined | Sets the z-index for both the backdrop and dialog content. |
DetailsDeclared typenumber | undefined Default value details
Sourcepackages/ui/src/components/message-box/MessageBox.vue | |||
class | string | undefined | undefined | Additional CSS classes applied to the dialog card container. |
DetailsDeclared typestring | undefined Default value details
Sourcepackages/ui/src/components/message-box/MessageBox.vue | |||
| Name | Signature or type | Description |
|---|---|---|
@update:open | [val: boolean] | Emits the updated boolean visibility value so v-model:open can be synchronized. |
DetailsDeclared type[val: boolean] Literal values
Sourcepackages/ui/src/components/message-box/MessageBox.vue | ||
@confirm | [val?: string | undefined] | Emitted after confirmation passes validation. It carries the input string when showInput is enabled, otherwise no payload, and then requests the dialog to close. |
DetailsDeclared type[val?: string | undefined] Sourcepackages/ui/src/components/message-box/MessageBox.vue | ||
@cancel | [] | Emitted when the user cancels, activates the close button, interacts outside the dialog, or presses Escape. It carries no payload. |
DetailsDeclared type[] Sourcepackages/ui/src/components/message-box/MessageBox.vue | ||
Accessibility
- Keyboard Navigation: Press
Escapeto dismiss the topmost active dialog layer according to the global LIFO stack. - Focus Management: Automatically traps focus within the dialog content upon mounting (focuses the confirm button or prompt input), and restores focus to the previously active element upon closing.
- ARIA Semantics: Implements
role="alertdialog"/role="dialog"semantic landmarks with proper labeling for screen readers. - High-Contrast Visibility: Built on high-contrast 3px Neo-Brutalist borders and semantic color palettes satisfying WCAG AAA contrast ratio standards.
Imperative & Composable API
showMessageBox(options)
Low-level imperative mounting handle based on host controller:
import { showMessageBox, type MessageBoxResult } from 'brutx-ui-vue'
const { close, promise } = showMessageBox({
title: 'System Notice',
message: 'Core service upgraded successfully.',
type: 'success',
})
const result: MessageBoxResult = await promise
// result.action: 'confirm' | 'cancel' | 'destroy'Deterministic Non-Rejecting Promise Contract
The Promise returned by MessageBox functional APIs always resolves (never rejects), eliminating unhandled rejection errors. Use result.action to branch interaction paths:
export type MessageBoxAction = 'confirm' | 'cancel' | 'destroy'
export interface MessageBoxResult {
/** confirm: Confirm button; cancel: Cancel/ESC/backdrop/close button; destroy: manual destroy */
action: MessageBoxAction
/** Input text value on confirm (Prompt mode) */
value?: string
}FAQ
Q: Do multiple stacked modals cause z-index collisions?
A: No. The underlying host controller manages an active LIFO overlay stack. Each new layer automatically increments z-index by OVERLAY_Z_INDEX_STEP = 10 and routes ESC events to the topmost active modal.
Q: Is it safe to call in SSR environments?
A: Yes. All functional and composable APIs include built-in SSR guards. In server-side environments without a DOM, showConfirm safely returns false, showPrompt returns { action: 'cancel' }, and showAlert resolves immediately.