First commit
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
<script setup lang="ts">
|
||||
import DsButton from "../actions/DsButton.vue";
|
||||
import DsDialog from "./DsDialog.vue";
|
||||
|
||||
const model = defineModel<boolean>({ default: false });
|
||||
const emit = defineEmits<{ confirm: []; cancel: [] }>();
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
title: string;
|
||||
description?: string;
|
||||
confirmLabel?: string;
|
||||
cancelLabel?: string;
|
||||
danger?: boolean;
|
||||
loading?: boolean;
|
||||
}>(),
|
||||
{
|
||||
description: undefined,
|
||||
confirmLabel: "Confirmar",
|
||||
cancelLabel: "Cancelar",
|
||||
danger: false,
|
||||
loading: false,
|
||||
},
|
||||
);
|
||||
|
||||
function confirm() {
|
||||
emit("confirm");
|
||||
if (!props.loading) model.value = false;
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<DsDialog
|
||||
v-model="model"
|
||||
:title="title"
|
||||
:description="description"
|
||||
@cancel="emit('cancel')"
|
||||
>
|
||||
<slot />
|
||||
<template #footer>
|
||||
<DsButton
|
||||
variant="secondary"
|
||||
@click="
|
||||
model = false;
|
||||
emit('cancel');
|
||||
"
|
||||
>{{ cancelLabel }}</DsButton
|
||||
>
|
||||
<DsButton
|
||||
:variant="danger ? 'danger' : 'primary'"
|
||||
:loading="loading"
|
||||
@click="confirm"
|
||||
>{{ confirmLabel }}</DsButton
|
||||
>
|
||||
</template>
|
||||
</DsDialog>
|
||||
</template>
|
||||
@@ -0,0 +1,89 @@
|
||||
<script setup lang="ts">
|
||||
import { nextTick, onBeforeUnmount, onMounted, ref, useId, watch } from "vue";
|
||||
import DsIconButton from "../actions/DsIconButton.vue";
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
title: string;
|
||||
description?: string;
|
||||
closeLabel?: string;
|
||||
closeOnBackdrop?: boolean;
|
||||
}>(),
|
||||
{
|
||||
description: undefined,
|
||||
closeLabel: "Cerrar diálogo",
|
||||
closeOnBackdrop: true,
|
||||
},
|
||||
);
|
||||
const model = defineModel<boolean>({ default: false });
|
||||
const emit = defineEmits<{ close: []; cancel: [] }>();
|
||||
const dialog = ref<HTMLDialogElement | null>(null);
|
||||
const titleId = useId();
|
||||
const descriptionId = useId();
|
||||
let previousFocus: HTMLElement | null = null;
|
||||
|
||||
async function syncDialog(open: boolean) {
|
||||
await nextTick();
|
||||
if (open && dialog.value && !dialog.value.open) {
|
||||
previousFocus = document.activeElement as HTMLElement | null;
|
||||
dialog.value.showModal();
|
||||
} else if (!open && dialog.value?.open) {
|
||||
dialog.value.close();
|
||||
previousFocus?.focus();
|
||||
}
|
||||
}
|
||||
|
||||
watch(model, syncDialog);
|
||||
onMounted(() => syncDialog(model.value));
|
||||
|
||||
function requestClose(cancelled = false) {
|
||||
model.value = false;
|
||||
if (cancelled) emit("cancel");
|
||||
emit("close");
|
||||
}
|
||||
|
||||
function onCancel(event: Event) {
|
||||
event.preventDefault();
|
||||
requestClose(true);
|
||||
}
|
||||
|
||||
function onBackdrop(event: MouseEvent) {
|
||||
if (props.closeOnBackdrop && event.target === dialog.value)
|
||||
requestClose(true);
|
||||
}
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
if (dialog.value?.open) dialog.value.close();
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<dialog
|
||||
ref="dialog"
|
||||
class="ds-dialog"
|
||||
:aria-labelledby="titleId"
|
||||
:aria-describedby="description ? descriptionId : undefined"
|
||||
@cancel="onCancel"
|
||||
@click="onBackdrop"
|
||||
>
|
||||
<div class="ds-dialog__header">
|
||||
<div>
|
||||
<h2 :id="titleId" class="ds-dialog__title">{{ title }}</h2>
|
||||
<p
|
||||
v-if="description"
|
||||
:id="descriptionId"
|
||||
class="ds-dialog__description"
|
||||
>
|
||||
{{ description }}
|
||||
</p>
|
||||
</div>
|
||||
<DsIconButton :label="closeLabel" @click="requestClose(true)"
|
||||
>×</DsIconButton
|
||||
>
|
||||
</div>
|
||||
<div class="ds-dialog__body"><slot /></div>
|
||||
<footer v-if="$slots.footer" class="ds-dialog__footer">
|
||||
<slot name="footer" :close="requestClose" />
|
||||
</footer>
|
||||
</dialog>
|
||||
</template>
|
||||
Reference in New Issue
Block a user