The CModalDanger component is an organism that extends the BModal component with preset styling for dangerous or destructive actions. It features error-colored primary button and full-width button layout.
Props
state
Record<string, any> | null
default:"null"
The state object for form management
schema
Record<string, any> | null
default:"null"
The schema for form validation
The description text explaining the dangerous action
Simple text content for the modal body (alternative to default slot)
Text for the primary (danger) button. Default is “Eliminar” (Delete in Spanish)
Text for the secondary (cancel) button. Default is “Cancelar” (Cancel in Spanish)
Model
Controls the open/closed state of the modal
Events
Emitted when the primary (danger) button is clicked
on-click-secondary-button
Emitted when the secondary (cancel) button is clicked
Slots
Custom body content (only used when text prop is not provided)
Preset Configuration
The component automatically applies:
- Primary Button Color:
error (red/danger color)
- Button Layout: Full-width blocks (
has-buttons-block)
- Default Primary Text: “Eliminar” (Delete)
- Default Secondary Text: “Cancelar” (Cancel)
Usage
Basic Delete Confirmation
<template>
<div>
<UButton color="error" @click="isOpen = true">Delete Item</UButton>
<CModalDanger
v-model="isOpen"
title="Delete Item"
description="This action cannot be undone"
text="Are you sure you want to delete this item? All associated data will be permanently removed."
@on-click-primary-button="handleDelete"
/>
</div>
</template>
<script setup>
const isOpen = ref(false)
function handleDelete() {
console.log('Item deleted')
isOpen.value = false
}
</script>
Custom Button Text
<template>
<CModalDanger
v-model="isOpen"
title="Remove User"
description="Permanent account deletion"
text="This will permanently delete the user account and all associated data."
primary-button-text="Remove User"
secondary-button-text="Keep User"
@on-click-primary-button="handleRemoveUser"
/>
</template>
With Custom Content
<template>
<CModalDanger
v-model="isOpen"
title="Delete Project"
description="This will affect multiple resources"
@on-click-primary-button="handleDelete"
>
<div class="space-y-3">
<p class="font-semibold">The following will be deleted:</p>
<ul class="list-disc list-inside space-y-1">
<li>{{ itemCount }} tasks</li>
<li>{{ fileCount }} files</li>
<li>{{ memberCount }} team members will lose access</li>
</ul>
<p class="text-error font-medium">
This action is irreversible!
</p>
</div>
</CModalDanger>
</template>
<script setup>
const itemCount = ref(42)
const fileCount = ref(156)
const memberCount = ref(8)
</script>
With Form Validation
<template>
<CModalDanger
v-model="isOpen"
title="Delete Account"
description="Type DELETE to confirm"
:state="formState"
:schema="formSchema"
@on-click-primary-button="handleDeleteAccount"
>
<UFormField label="Type DELETE to confirm" name="confirmation">
<UInput
v-model="formState.confirmation"
placeholder="DELETE"
/>
</UFormField>
</CModalDanger>
</template>
<script setup>
import { z } from 'zod'
const isOpen = ref(false)
const formState = reactive({
confirmation: ''
})
const formSchema = z.object({
confirmation: z.literal('DELETE', {
errorMap: () => ({ message: 'You must type DELETE to confirm' })
})
})
function handleDeleteAccount() {
console.log('Account deleted')
isOpen.value = false
}
</script>
Batch Delete Confirmation
<template>
<div>
<UButton
color="error"
:disabled="selectedItems.length === 0"
@click="isOpen = true"
>
Delete Selected ({{ selectedItems.length }})
</UButton>
<CModalDanger
v-model="isOpen"
title="Delete Multiple Items"
description="Bulk deletion warning"
:text="`You are about to delete ${selectedItems.length} items. This cannot be undone.`"
primary-button-text="Delete All"
@on-click-primary-button="handleBulkDelete"
/>
</div>
</template>
<script setup>
const selectedItems = ref([1, 2, 3, 4, 5])
function handleBulkDelete() {
console.log('Deleting items:', selectedItems.value)
selectedItems.value = []
isOpen.value = false
}
</script>
Deactivate vs Delete
<template>
<CModalDanger
v-model="isOpen"
title="Deactivate User"
description="Temporary suspension"
text="The user will be deactivated but their data will be preserved. You can reactivate them later."
primary-button-text="Deactivate"
@on-click-primary-button="handleDeactivate"
@on-click-secondary-button="handleCancel"
/>
</template>
Best Practices
- Clear Communication: Always provide clear title and description explaining the consequence
- Specific Actions: Use specific button text (“Delete Project” vs generic “Delete”)
- Additional Context: Include details about what will be affected
- Confirmation: For critical actions, require typing confirmation or additional verification
- Undo Information: If possible, mention if the action can be undone or recovered
Styling
The modal inherits all styling from BModal but overrides:
- Primary button color is always
error
- Buttons are always full-width (
has-buttons-block)
Source: /home/daytona/workspace/source/app/components/c/modal/c-modal-danger.vue:70