Skip to content

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 ​

Preview

1. 声明式组件 (MessageBox)

2. 命令式便捷方法 (Functional Helpers)

最新交互状态:尚未触发任何弹窗

Installation ​

pnpm dlx brutx-vue@latest add message-box

Usage ​

Declarative Component Usage ​

Control visibility via v-model:open:

vue
<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:

vue
<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:

vue
<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 PaletteUse Case
infobg-brutal-info text-brutal-info-foregroundGeneral notices and regular confirmations
successbg-brutal-success text-brutal-success-foregroundSuccessful operation confirmations
warningbg-brutal-accent text-brutal-accent-foregroundDestructive or irreversible action warnings (showConfirm default)
errorbg-brutal-destructive text-brutal-destructive-foregroundCritical 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:

vue
<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 ​

MessageBox — Props
NameTypeDefaultDescription
open
boolean | undefined
true
Controls dialog visibility and supports v-model:open. The dialog defaults to open when this prop is omitted.
Details

Declared type

boolean | undefined

Literal values

  • false
  • true

Default value details

Resolved value
true

Source

MessageBox.vue:31

packages/ui/src/components/message-box/MessageBox.vue

title
string | undefined
undefined
Sets the dialog title; the localized default title is used when omitted.
Details

Declared type

string | undefined

Default value details

Resolved value
undefined

Source

MessageBox.vue:32

packages/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.
Details

Declared type

string | undefined

Default value details

Resolved value
undefined

Source

MessageBox.vue:33

packages/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.
Details

Declared type

MessageBoxType | undefined

Literal values

  • "error"
  • "info"
  • "success"
  • "warning"

Referenced types

MessageBoxType
Type definition — MessageBoxType
export type MessageBoxType = NonNullable<MessageBoxIconVariantProps['type']>

Default value details

Resolved value
"info"

Source

MessageBox.vue:34

packages/ui/src/components/message-box/MessageBox.vue

showCancelButton
boolean | undefined
true
Controls whether the cancel button is shown.
Details

Declared type

boolean | undefined

Literal values

  • false
  • true

Default value details

Resolved value
true

Source

MessageBox.vue:35

packages/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.
Details

Declared type

boolean | undefined

Literal values

  • false
  • true

Default value details

Resolved value
true

Source

MessageBox.vue:36

packages/ui/src/components/message-box/MessageBox.vue

confirmButtonText
string | undefined
undefined
Sets the confirm button label; the localized default label is used when omitted.
Details

Declared type

string | undefined

Default value details

Resolved value
undefined

Source

MessageBox.vue:37

packages/ui/src/components/message-box/MessageBox.vue

cancelButtonText
string | undefined
undefined
Sets the cancel button label; the localized default label is used when omitted.
Details

Declared type

string | undefined

Default value details

Resolved value
undefined

Source

MessageBox.vue:38

packages/ui/src/components/message-box/MessageBox.vue

confirmButtonClass
string | undefined
undefined
Additional CSS classes applied to the confirm button.
Details

Declared type

string | undefined

Default value details

Resolved value
undefined

Source

MessageBox.vue:39

packages/ui/src/components/message-box/MessageBox.vue

cancelButtonClass
string | undefined
undefined
Additional CSS classes applied to the cancel button.
Details

Declared type

string | undefined

Default value details

Resolved value
undefined

Source

MessageBox.vue:40

packages/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.
Details

Declared type

boolean | undefined

Literal values

  • false
  • true

Default value details

Resolved value
false

Source

MessageBox.vue:41

packages/ui/src/components/message-box/MessageBox.vue

inputPlaceholder
string | undefined
undefined
Sets the placeholder shown while the prompt input is empty.
Details

Declared type

string | undefined

Default value details

Resolved value
undefined

Source

MessageBox.vue:42

packages/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.
Details

Declared type

string | undefined

Default value details

Resolved value
""

Source

MessageBox.vue:43

packages/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.
Details

Declared type

RegExp | undefined

Default value details

Resolved value
undefined

Source

MessageBox.vue:44

packages/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.
Details

Declared type

string | undefined

Default value details

Resolved value
undefined

Source

MessageBox.vue:45

packages/ui/src/components/message-box/MessageBox.vue

zIndex
number | undefined
undefined
Sets the z-index for both the backdrop and dialog content.
Details

Declared type

number | undefined

Default value details

Resolved value
undefined

Source

MessageBox.vue:46

packages/ui/src/components/message-box/MessageBox.vue

class
string | undefined
undefined
Additional CSS classes applied to the dialog card container.
Details

Declared type

string | undefined

Default value details

Resolved value
undefined

Source

MessageBox.vue:47

packages/ui/src/components/message-box/MessageBox.vue

MessageBox — Events
NameSignature or typeDescription
@update:open
[val: boolean]
Emits the updated boolean visibility value so v-model:open can be synchronized.
Details

Declared type

[val: boolean]

Literal values

  • false
  • true

Source

MessageBox.vue

packages/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.
Details

Declared type

[val?: string | undefined]

Source

MessageBox.vue

packages/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.
Details

Declared type

[]

Source

MessageBox.vue

packages/ui/src/components/message-box/MessageBox.vue

Accessibility ​

  • Keyboard Navigation: Press Escape to 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:

ts
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:

ts
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.

Brute force builds.