Appearance
Modal
A modal can be used in a variaty of ways. It can be used to display a message to the user, ask for a confirmation or to display a form. The appropriate type can be set with the type property.
Example Usage
vue
<template>
<SkButton class="mr-s mb-s" @click="modal.open()">Open Alert</SkButton>
<SkButton class="mr-s mb-s" @click="modal2.open()">Async Confirm</SkButton>
<SkButton class="mr-s mb-s" @click="programmaticConfirm()">Programmatic Confirm</SkButton>
<SkButton class="mr-s mb-s" @click="programmaticPrompt()">Programmatic Prompt</SkButton>
<SkModal
ref="modal"
type="alert"
title="Ich bin ein einfaches Modal"
description="Das ist meine Beschreibung. "
action-text="Ok, verstanden"
class="bg-orange"
/>
<SkModal
ref="modal2"
type="confirm"
title="Möchtest du wirklich löschen?"
action-text="Löschen"
:action="deleteDummyItem"
>
<h1>Wirklich löschen?</h1>
<p>Das kann nicht rückgängig gemacht werden.</p>
<template #footer="{ action, close, loading }">
<SkButton type="secondary" @click="close()">Abbrechen</SkButton>
<SkButton v-if="!loading" type="primary" @click="action()">Löschen</SkButton>
<SkButton v-else type="primary" :loading="true">Löschen...</SkButton>
</template>
</SkModal>
</template>
<script setup>
import { onMounted, ref } from 'vue';
// import { useModal } from '@/composables';
const modal = ref(undefined);
const modal2 = ref(undefined);
// const { createModal } = useModal();
let createModal = undefined;
async function deleteDummyItem() {
const prom = new Promise((resolve, reject) => {
setTimeout(() => {
Math.random() > 0.5 ? resolve() : reject('This is an error');
}, 1000);
});
await prom;
}
// this is only neccessary for server side rendering
onMounted(async () => {
const { useModal } = await import('my-lib/composables');
createModal = useModal().createModal;
});
// two different usecases
async function programmaticPrompt() {
const modal3 = await createModal({
title: 'Vergib einen Namen',
description: 'Wie soll die Serie heißen?',
actionText: 'Speichern',
type: 'prompt',
});
const result = await modal3.open();
alert(result);
}
async function programmaticConfirm() {
const modal4 = await createModal({
title: 'Element wirklich löschen?',
description: 'Dies kann nicht rückgängig gemacht werden.',
actionText: 'Löschen',
type: 'confirm',
});
modal4.action(async () => {
await deleteDummyItem();
});
modal4.open();
}
</script>Composable
You can use the useModal composable to create a modal instance. This can be used to open and close the modal programmatically.
vue
<script setup>
import { useModal } from '@/composables';
const { createModal } = useModal();
async function programmaticConfirm() {
const modal4 = await createModal({
title: 'Element wirklich löschen?',
// ... other component props
})
.action(async () => {
// some async action
})
.open();
}
</script>Reference
Props
| Name | Type | Default | Description |
|---|---|---|---|
| type | String | 'confirm' | Type of modal - 'alert', 'prompt' or 'confirm' |
| title | String | 'Are you sure?' | Title text shown in modal |
| actionText | String | Text for action button | |
| action | Function | Callback for action button | |
| description | String | Descriptive text shown under title |
Events
| Name | Description |
|---|---|
| close | Emitted when modal closes |
| confirm | Emitted when action is confirmed |
| error | Emitted on any error |
Methods
| Method | Description |
|---|---|
| open() | Open the modal |
| close() | Close the modal |
| action() | Set callback for action button, can be an async function to automaticly show loading state |
Exposed
| Property | Type | Description |
|---|---|---|
| loading | Boolean | Loading state |
| el | Element | Modal element reference |
Slots
| Name | Description |
|---|---|
| default | Default slot for modal content |
| footer | Footer slot for action buttons |
Slot Props
The footer slot is provided the following props:
| Prop | Type | Description |
|---|---|---|
| action | Function | Call this prop to trigger the primary action |
| close | Function | Call this prop to close the modal |
| loading | Boolean | Indicates background action is in progress |
For example:
<template #footer="{ action, close, loading }">
<button :disabled="loading" @click="action">
Confirm
</button>
<button @click="close">
Cancel
</button>
</template>The default slot does not have any provided props. Any content can be passed to this slot, for example:
<template #default>
<p>Custom modal content</p>
</template>