Files
cz-web/src/components/ConfirmDialog.vue
2026-10-01 17:24:57 +08:00

148 lines
2.9 KiB
Vue

<script setup lang="ts">
interface Props {
title?: string
message?: string
confirmText?: string
cancelText?: string
danger?: boolean
}
withDefaults(defineProps<Props>(), {
title: '提示',
message: '',
confirmText: '确认',
cancelText: '取消',
danger: false,
})
const visible = defineModel<boolean>('visible', { default: false })
const emit = defineEmits<{ confirm: []; cancel: [] }>()
function onConfirm(): void {
emit('confirm')
visible.value = false
}
function onCancel(): void {
emit('cancel')
visible.value = false
}
</script>
<template>
<Teleport to="body">
<div v-if="visible" class="confirm-dialog" @click.self="onCancel">
<div class="confirm-dialog__panel">
<h3 class="confirm-dialog__title">
{{ title }}
</h3>
<div class="confirm-dialog__body">
<slot>{{ message }}</slot>
</div>
<div class="confirm-dialog__footer">
<button class="confirm-dialog__btn" @click="onCancel">
{{ cancelText }}
</button>
<button
class="confirm-dialog__btn confirm-dialog__btn--confirm"
:class="{ 'is-danger': danger }"
@click="onConfirm"
>
{{ confirmText }}
</button>
</div>
</div>
</div>
</Teleport>
</template>
<style lang="less" scoped>
.confirm-dialog {
position: fixed;
inset: 0;
z-index: 1000;
.flex(row, center);
background: transparent;
&__panel {
width: 660px;
max-width: calc(100vw - 32px);
padding: @spacing-base;
border-radius: @radius-lg;
background: @white;
box-shadow: @shadow-lg;
}
&__title {
position: relative;
margin-bottom: @spacing-base;
padding-left: 12px;
font-size: 12px;
font-weight: 700;
color: @heading-color;
line-height: 20px;
&::before {
content: '';
position: absolute;
left: 0;
top: 3px;
width: 3px;
height: 14px;
border-radius: 2px;
background: @primary-strong;
}
}
&__body {
margin-bottom: @spacing-lg;
font-size: 11px;
color: @text-color;
line-height: 1.7;
}
&__footer {
.flex(row, flex-start);
gap: @spacing-sm;
}
&__btn {
flex: 1;
height: 36px;
padding: 0 @spacing-base;
border: none;
border-radius: @profile-radius;
background: @profile-quiet-btn;
color: @text-color;
font-size: 12px;
font-weight: 500;
transition: all 0.2s;
&:hover {
border: none;
background: darken(@profile-quiet-btn, 4%);
color: @text-color;
}
&--confirm {
background: @primary-strong;
color: @white;
&:hover {
background: darken(@primary-strong, 6%);
color: @white;
}
&.is-danger {
background: @danger-color;
&:hover {
background: darken(@danger-color, 6%);
}
}
}
}
}
</style>