Destructive Action Modal
A safety-first pattern for confirming irreversible or high-impact actions using a modal and clear visual warnings.
Demo
Implementation
vue
<script setup lang="ts">
import { ref } from 'vue';
// 1. Component Imports (Default)
import CLModal from '@codeandfunction/callaloo/CLModal';
import CLButton from '@codeandfunction/callaloo/CLButton';
import CLText from '@codeandfunction/callaloo/CLText';
import { useToast } from '@codeandfunction/callaloo/composables/useToast';
// 2. Enum & Type Imports (Named)
import {
CLColors,
CLColorVariants,
CLIconNames,
CLTextTypes,
CLBorderRadius,
CLButtonTypes
} from '@codeandfunction/callaloo';
// 3. State & Logic
const isModalOpen = ref(false);
const isDeleting = ref(false);
const toast = useToast();
const openModal = (): void => {
isModalOpen.value = true;
};
const closeModal = (): void => {
isModalOpen.value = false;
};
const handleDelete = async (): Promise<void> => {
isDeleting.value = true;
await new Promise(resolve => setTimeout(resolve, 2000));
isDeleting.value = false;
isModalOpen.value = false;
toast.showToast({
color: CLColors.Success,
message: 'Project deleted successfully!',
title: 'Success',
});
};
</script>
<template>
<div class="pattern-preview">
<div class="modal-demo-container">
<CLButton
:color="CLColors.Danger"
:icon-before="CLIconNames.Trash"
:type="CLButtonTypes.Button"
@click="openModal"
>
Delete Project
</CLButton>
<CLModal
modal-id="delete-confirmation"
:is-open="isModalOpen"
title="Confirm Deletion"
:on-close="closeModal"
max-width="450px"
:border-radius="CLBorderRadius.Medium"
>
<template #body>
<div class="warning-content">
<CLText :type="CLTextTypes.Body">Are you sure you want to delete the project <strong>"Callaloo Documentation"</strong>?
This action cannot be undone.
</CLText>
<CLText :type="CLTextTypes.Small" :color="CLColors.Neutral">All associated data, including components, assets, and version history, will be permanently removed.
</CLText>
</div>
</template>
<template #footer>
<div class="modal-footer-actions">
<CLButton
:variant="CLColorVariants.Ghost"
:color="CLColors.Neutral"
:type="CLButtonTypes.Button"
@click="closeModal"
:disabled="isDeleting"
>
Cancel
</CLButton>
<CLButton
:color="CLColors.Danger"
:type="CLButtonTypes.Button"
@click="handleDelete"
:busy="isDeleting"
:disabled="isDeleting"
>
Delete Permanently
</CLButton>
</div>
</template>
</CLModal>
</div>
</div>
</template>
<style scoped>
.pattern-preview {
display: flex;
flex-direction: column;
flex: 1;
}
.modal-demo-container {
display: flex;
flex: 1;
justify-content: center;
align-items: center;
padding: 4rem 2rem;
}
.modal-footer-actions {
display: flex;
justify-content: flex-end;
gap: 1rem;
width: 100%;
}
.warning-content {
display: flex;
flex-direction: column;
gap: 1rem;
}
</style>