Files
RenewCMS/web/src/components/DirectoryDialog.vue
T

120 lines
2.8 KiB
Vue

<script setup lang="ts">
import { SHEET_CONTENT_CLASS, SHEET_FOOTER_CLASS } from '@/components/sheetClasses'
import { t } from '@/i18n'
import { computed } from 'vue'
import type { DirectoryNotice } from '@/lib/directoryTypes'
const props = withDefaults(
defineProps<{
title: string
description: string
confirmLabel: string
pendingLabel: string
cancelLabel?: string
tone?: 'danger' | 'neutral'
pending?: boolean
notice?: DirectoryNotice | null
closable?: boolean
confirmDisabled?: boolean
}>(),
{
cancelLabel: '',
tone: 'danger',
pending: false,
notice: null,
closable: false,
confirmDisabled: false,
},
)
const emit = defineEmits<{ confirm: []; close: [] }>()
const open = defineModel<boolean>('open', { default: true })
const confirmText = computed(() => (props.pending ? props.pendingLabel : props.confirmLabel))
const closeButton = computed(() =>
props.closable && !props.pending
? { class: 'size-7 justify-center text-muted max-md:size-11' }
: false,
)
function onOpenChange(value: boolean) {
if (!value && props.pending) {
return
}
open.value = value
if (!value) {
emit('close')
}
}
function onCancel() {
onOpenChange(false)
}
</script>
<template>
<UModal
:open="open"
:title="title"
:description="description"
:dismissible="!pending"
:close="closeButton"
:content="{ role: 'alertdialog', 'aria-busy': pending ? 'true' : undefined }"
:ui="{
content: `${SHEET_CONTENT_CLASS} sm:top-35 sm:max-w-115`,
header: 'min-h-0 px-6 pt-5 pb-0 sm:px-6',
title: 'text-lg/6 font-semibold',
description: 'mt-1 text-sm text-muted text-pretty',
body: 'px-6 pt-5 pb-0 sm:px-6 sm:pt-5 sm:pb-0',
footer: SHEET_FOOTER_CLASS,
}"
@update:open="onOpenChange"
>
<template #body>
<div class="flex flex-col gap-4">
<UAlert
v-if="notice"
role="alert"
color="error"
variant="soft"
icon="i-lucide-circle-x"
:title="notice.title"
:description="notice.description"
:ui="{
root: 'items-start gap-2.5 px-3.5 py-3',
title: 'font-semibold',
description: 'text-toned',
}"
/>
<slot />
</div>
</template>
<template #footer>
<div class="flex w-full flex-col-reverse gap-2 sm:flex-row sm:justify-end">
<UButton
color="neutral"
variant="outline"
block
class="h-11 justify-center text-sm text-highlighted disabled:text-dimmed disabled:opacity-100 sm:h-8 sm:w-auto sm:px-3"
:disabled="pending"
@click="onCancel"
>
{{ cancelLabel || t('Cancel') }}
</UButton>
<UButton
:color="tone === 'danger' ? 'error' : 'primary'"
:loading="pending"
:disabled="pending || confirmDisabled"
block
class="h-11 justify-center text-sm sm:h-8 sm:w-auto sm:px-3"
@click="emit('confirm')"
>
{{ confirmText }}
</UButton>
</div>
</template>
</UModal>
</template>