mirror of
https://github.com/Kuingsmile/PicList.git
synced 2026-06-07 00:30:14 +08:00
✨ Feature(custom): support duplicate config and the UI of confirm/input box is optimized
This commit is contained in:
@@ -1,51 +1,61 @@
|
||||
<template>
|
||||
<Teleport to="body">
|
||||
<div v-if="showInputBoxVisible" class="inputbox-overlay">
|
||||
<div class="inputbox-container" @click.stop>
|
||||
<div class="inputbox-header">
|
||||
<h3 class="inputbox-title">
|
||||
{{ inputBoxOptions.title || t('pages.inputBox.title') }}
|
||||
</h3>
|
||||
<button class="inputbox-close" @click="handleInputBoxCancel">
|
||||
<X :size="20" />
|
||||
</button>
|
||||
</div>
|
||||
<div class="inputbox-content">
|
||||
<textarea
|
||||
v-if="inputBoxOptions.multiLine"
|
||||
v-model="inputBoxValue"
|
||||
:placeholder="inputBoxOptions.placeholder"
|
||||
class="inputbox-textarea"
|
||||
rows="4"
|
||||
@keyup.ctrl.enter="handleInputBoxConfirm"
|
||||
@keyup.escape="handleInputBoxCancel"
|
||||
/>
|
||||
<input
|
||||
v-else
|
||||
v-model="inputBoxValue"
|
||||
:placeholder="inputBoxOptions.placeholder"
|
||||
class="inputbox-input"
|
||||
type="text"
|
||||
@keyup.enter="handleInputBoxConfirm"
|
||||
@keyup.escape="handleInputBoxCancel"
|
||||
/>
|
||||
</div>
|
||||
<div class="inputbox-actions">
|
||||
<button class="inputbox-btn cancel-btn" @click="handleInputBoxCancel">
|
||||
{{ t('common.cancel') }}
|
||||
</button>
|
||||
<button class="inputbox-btn confirm-btn primary" @click="handleInputBoxConfirm">
|
||||
{{ t('common.confirm') }}
|
||||
</button>
|
||||
</div>
|
||||
<Transition name="inputbox-fade">
|
||||
<div v-if="showInputBoxVisible" class="inputbox-overlay" @click="handleInputBoxCancel">
|
||||
<Transition name="inputbox-scale">
|
||||
<div v-if="showInputBoxVisible" class="inputbox-container" @click.stop>
|
||||
<button class="inputbox-close" @click="handleInputBoxCancel">
|
||||
<X :size="20" />
|
||||
</button>
|
||||
|
||||
<div class="inputbox-body">
|
||||
<h3 class="inputbox-title">
|
||||
{{ inputBoxOptions.title || t('pages.inputBox.title') }}
|
||||
</h3>
|
||||
|
||||
<div class="inputbox-content">
|
||||
<textarea
|
||||
v-if="inputBoxOptions.multiLine"
|
||||
ref="textareaRef"
|
||||
v-model="inputBoxValue"
|
||||
:placeholder="inputBoxOptions.placeholder"
|
||||
class="inputbox-textarea"
|
||||
rows="4"
|
||||
@keyup.ctrl.enter="handleInputBoxConfirm"
|
||||
@keyup.meta.enter="handleInputBoxConfirm"
|
||||
@keyup.escape="handleInputBoxCancel"
|
||||
/>
|
||||
<input
|
||||
v-else
|
||||
ref="inputRef"
|
||||
v-model="inputBoxValue"
|
||||
:placeholder="inputBoxOptions.placeholder"
|
||||
class="inputbox-input"
|
||||
type="text"
|
||||
@keyup.enter="handleInputBoxConfirm"
|
||||
@keyup.escape="handleInputBoxCancel"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="inputbox-actions">
|
||||
<button class="inputbox-btn cancel-btn" @click="handleInputBoxCancel">
|
||||
{{ t('common.cancel') }}
|
||||
</button>
|
||||
<button class="inputbox-btn confirm-btn" :disabled="!inputBoxValue.trim()" @click="handleInputBoxConfirm">
|
||||
{{ t('common.confirm') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</Transition>
|
||||
</div>
|
||||
</div>
|
||||
</Transition>
|
||||
</Teleport>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { X } from 'lucide-vue-next'
|
||||
import { onBeforeMount, onBeforeUnmount, reactive, ref } from 'vue'
|
||||
import { nextTick, onBeforeMount, onBeforeUnmount, reactive, ref } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import $bus from '@/utils/bus'
|
||||
@@ -55,6 +65,8 @@ import type { IShowInputBoxOption } from '#/types/types'
|
||||
const { t } = useI18n()
|
||||
const inputBoxValue = ref('')
|
||||
const showInputBoxVisible = ref(false)
|
||||
const inputRef = ref<HTMLInputElement>()
|
||||
const textareaRef = ref<HTMLTextAreaElement>()
|
||||
const inputBoxOptions = reactive({
|
||||
title: '',
|
||||
placeholder: '',
|
||||
@@ -67,12 +79,21 @@ function handleIpcInputBoxEvent(options: IShowInputBoxOption) {
|
||||
initInputBoxValue(options)
|
||||
}
|
||||
|
||||
function initInputBoxValue(options: IShowInputBoxOption) {
|
||||
async function initInputBoxValue(options: IShowInputBoxOption) {
|
||||
inputBoxValue.value = options.value || ''
|
||||
inputBoxOptions.title = options.title || ''
|
||||
inputBoxOptions.placeholder = options.placeholder || ''
|
||||
inputBoxOptions.multiLine = options.multiLine || false
|
||||
showInputBoxVisible.value = true
|
||||
|
||||
await nextTick()
|
||||
if (inputBoxOptions.multiLine) {
|
||||
textareaRef.value?.focus()
|
||||
textareaRef.value?.select()
|
||||
} else {
|
||||
inputRef.value?.focus()
|
||||
inputRef.value?.select()
|
||||
}
|
||||
}
|
||||
|
||||
function handleInputBoxCancel() {
|
||||
@@ -106,6 +127,36 @@ export default {
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* Transitions */
|
||||
.inputbox-fade-enter-active,
|
||||
.inputbox-fade-leave-active {
|
||||
transition: opacity 0.2s ease;
|
||||
}
|
||||
|
||||
.inputbox-fade-enter-from,
|
||||
.inputbox-fade-leave-to {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.inputbox-scale-enter-active {
|
||||
transition: all 0.25s cubic-bezier(0.34, 1.56, 0.64, 1);
|
||||
}
|
||||
|
||||
.inputbox-scale-leave-active {
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.inputbox-scale-enter-from {
|
||||
opacity: 0;
|
||||
transform: scale(0.9) translateY(-10px);
|
||||
}
|
||||
|
||||
.inputbox-scale-leave-to {
|
||||
opacity: 0;
|
||||
transform: scale(0.95);
|
||||
}
|
||||
|
||||
/* Overlay */
|
||||
.inputbox-overlay {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
@@ -113,15 +164,19 @@ export default {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background: rgb(0 0 0 / 50%);
|
||||
padding: 1rem;
|
||||
background: rgb(0 0 0 / 40%);
|
||||
backdrop-filter: blur(4px);
|
||||
}
|
||||
|
||||
/* Container */
|
||||
.inputbox-container {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
border-radius: 0.75rem;
|
||||
width: 90%;
|
||||
max-width: 32rem;
|
||||
max-height: 80vh;
|
||||
border: 1px solid rgb(229 231 235);
|
||||
border-radius: 1rem;
|
||||
width: 100%;
|
||||
max-width: 28rem;
|
||||
background: white;
|
||||
box-shadow:
|
||||
0 20px 25px -5px rgb(0 0 0 / 10%),
|
||||
@@ -130,45 +185,30 @@ export default {
|
||||
|
||||
:root.dark .inputbox-container,
|
||||
:root.auto.dark .inputbox-container {
|
||||
border: 1px solid rgb(55 65 81);
|
||||
border-color: rgb(55 65 81);
|
||||
background: rgb(31 41 55);
|
||||
}
|
||||
|
||||
.inputbox-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 1.5rem 1.5rem 0;
|
||||
}
|
||||
|
||||
.inputbox-title {
|
||||
margin: 0;
|
||||
font-size: 1.25rem;
|
||||
font-weight: 600;
|
||||
color: rgb(17 24 39);
|
||||
}
|
||||
|
||||
:root.dark .inputbox-title,
|
||||
:root.auto.dark .inputbox-title {
|
||||
color: rgb(243 244 246);
|
||||
}
|
||||
|
||||
/* Close Button */
|
||||
.inputbox-close {
|
||||
position: absolute;
|
||||
top: 1rem;
|
||||
right: 1rem;
|
||||
z-index: 10;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border: none;
|
||||
border-radius: 0.25rem;
|
||||
padding: 0.25rem;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
border-radius: 0.5rem;
|
||||
padding: 0.375rem;
|
||||
color: rgb(107 114 128);
|
||||
background: none;
|
||||
background: transparent;
|
||||
transition: all 0.15s ease;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.inputbox-close:hover {
|
||||
color: rgb(17 24 39);
|
||||
color: rgb(75 85 99);
|
||||
background: rgb(243 244 246);
|
||||
}
|
||||
|
||||
@@ -179,29 +219,55 @@ export default {
|
||||
|
||||
:root.dark .inputbox-close:hover,
|
||||
:root.auto.dark .inputbox-close:hover {
|
||||
color: rgb(243 244 246);
|
||||
color: rgb(209 213 219);
|
||||
background: rgb(55 65 81);
|
||||
}
|
||||
|
||||
.inputbox-content {
|
||||
padding: 1rem 1.5rem;
|
||||
/* Body */
|
||||
.inputbox-body {
|
||||
padding: 2rem 2rem 1.5rem;
|
||||
}
|
||||
|
||||
.inputbox-title {
|
||||
margin: 0 0 1.25rem;
|
||||
padding-right: 2rem;
|
||||
font-size: 1.125rem;
|
||||
font-weight: 600;
|
||||
line-height: 1.4;
|
||||
color: rgb(17 24 39);
|
||||
}
|
||||
|
||||
:root.dark .inputbox-title,
|
||||
:root.auto.dark .inputbox-title {
|
||||
color: rgb(243 244 246);
|
||||
}
|
||||
|
||||
.inputbox-content {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* Input */
|
||||
.inputbox-input {
|
||||
border: 1px solid rgb(209 213 219);
|
||||
border-radius: 0.5rem;
|
||||
border: 1.5px solid rgb(229 231 235);
|
||||
border-radius: 0.625rem;
|
||||
padding: 0.75rem 1rem;
|
||||
width: 100%;
|
||||
font-size: 0.875rem;
|
||||
font-size: 0.9375rem;
|
||||
font-family: inherit;
|
||||
color: rgb(17 24 39);
|
||||
background: white;
|
||||
background: rgb(249 250 251);
|
||||
outline: none;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.inputbox-input:hover {
|
||||
border-color: rgb(209 213 219);
|
||||
background: white;
|
||||
}
|
||||
|
||||
.inputbox-input:focus {
|
||||
border-color: rgb(59 130 246);
|
||||
background: white;
|
||||
box-shadow: 0 0 0 3px rgb(59 130 246 / 10%);
|
||||
}
|
||||
|
||||
@@ -209,23 +275,31 @@ export default {
|
||||
color: rgb(156 163 175);
|
||||
}
|
||||
|
||||
/* Textarea */
|
||||
.inputbox-textarea {
|
||||
border: 1px solid rgb(209 213 219);
|
||||
border-radius: 0.375rem;
|
||||
padding: 0.5rem 0.75rem;
|
||||
border: 1.5px solid rgb(229 231 235);
|
||||
border-radius: 0.625rem;
|
||||
padding: 0.75rem 1rem;
|
||||
width: 100%;
|
||||
min-height: 4rem;
|
||||
font-size: 0.875rem;
|
||||
min-height: 6rem;
|
||||
font-size: 0.9375rem;
|
||||
font-family: inherit;
|
||||
line-height: 1.6;
|
||||
color: rgb(17 24 39);
|
||||
background: white;
|
||||
background: rgb(249 250 251);
|
||||
outline: none;
|
||||
resize: vertical;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.inputbox-textarea:hover {
|
||||
border-color: rgb(209 213 219);
|
||||
background: white;
|
||||
}
|
||||
|
||||
.inputbox-textarea:focus {
|
||||
border-color: rgb(59 130 246);
|
||||
background: white;
|
||||
box-shadow: 0 0 0 3px rgb(59 130 246 / 10%);
|
||||
}
|
||||
|
||||
@@ -233,16 +307,24 @@ export default {
|
||||
color: rgb(156 163 175);
|
||||
}
|
||||
|
||||
/* Dark Mode - Input */
|
||||
:root.dark .inputbox-input,
|
||||
:root.auto.dark .inputbox-input {
|
||||
border-color: rgb(75 85 99);
|
||||
border-color: rgb(55 65 81);
|
||||
color: rgb(243 244 246);
|
||||
background: rgb(55 65 81);
|
||||
}
|
||||
|
||||
:root.dark .inputbox-input:hover,
|
||||
:root.auto.dark .inputbox-input:hover {
|
||||
border-color: rgb(75 85 99);
|
||||
background: rgb(55 65 81);
|
||||
}
|
||||
|
||||
:root.dark .inputbox-input:focus,
|
||||
:root.auto.dark .inputbox-input:focus {
|
||||
border-color: rgb(59 130 246);
|
||||
background: rgb(55 65 81);
|
||||
box-shadow: 0 0 0 3px rgb(59 130 246 / 10%);
|
||||
}
|
||||
|
||||
@@ -251,16 +333,24 @@ export default {
|
||||
color: rgb(107 114 128);
|
||||
}
|
||||
|
||||
/* Dark Mode - Textarea */
|
||||
:root.dark .inputbox-textarea,
|
||||
:root.auto.dark .inputbox-textarea {
|
||||
border-color: rgb(75 85 99);
|
||||
border-color: rgb(55 65 81);
|
||||
color: rgb(243 244 246);
|
||||
background: rgb(55 65 81);
|
||||
}
|
||||
|
||||
:root.dark .inputbox-textarea:hover,
|
||||
:root.auto.dark .inputbox-textarea:hover {
|
||||
border-color: rgb(75 85 99);
|
||||
background: rgb(55 65 81);
|
||||
}
|
||||
|
||||
:root.dark .inputbox-textarea:focus,
|
||||
:root.auto.dark .inputbox-textarea:focus {
|
||||
border-color: rgb(59 130 246);
|
||||
background: rgb(55 65 81);
|
||||
box-shadow: 0 0 0 3px rgb(59 130 246 / 10%);
|
||||
}
|
||||
|
||||
@@ -269,51 +359,103 @@ export default {
|
||||
color: rgb(107 114 128);
|
||||
}
|
||||
|
||||
/* Actions */
|
||||
.inputbox-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
padding: 0 1.5rem 1.5rem;
|
||||
border-top: 1px solid rgb(243 244 246);
|
||||
padding: 1rem 1.5rem;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
|
||||
:root.dark .inputbox-actions,
|
||||
:root.auto.dark .inputbox-actions {
|
||||
border-top-color: rgb(55 65 81);
|
||||
}
|
||||
|
||||
.inputbox-btn {
|
||||
flex: 1;
|
||||
border: none;
|
||||
border-radius: 0.375rem;
|
||||
padding: 0.5rem 1rem;
|
||||
min-width: 4rem;
|
||||
border-radius: 0.5rem;
|
||||
padding: 0.625rem 1.25rem;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 500;
|
||||
transition: all 0.15s ease;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.inputbox-btn:active {
|
||||
transform: scale(0.98);
|
||||
}
|
||||
|
||||
.inputbox-btn:disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.inputbox-btn:disabled:active {
|
||||
transform: none;
|
||||
}
|
||||
|
||||
/* Cancel Button */
|
||||
.cancel-btn {
|
||||
border: 1px solid rgb(209 213 219);
|
||||
border: 1px solid rgb(229 231 235);
|
||||
color: rgb(75 85 99);
|
||||
background: rgb(243 244 246);
|
||||
background: white;
|
||||
}
|
||||
|
||||
.cancel-btn:hover {
|
||||
background: rgb(229 231 235);
|
||||
border-color: rgb(209 213 219);
|
||||
background: rgb(249 250 251);
|
||||
}
|
||||
|
||||
:root.dark .cancel-btn,
|
||||
:root.auto.dark .cancel-btn {
|
||||
border-color: rgb(75 85 99);
|
||||
border-color: rgb(55 65 81);
|
||||
color: rgb(209 213 219);
|
||||
background: rgb(55 65 81);
|
||||
}
|
||||
|
||||
:root.dark .cancel-btn:hover,
|
||||
:root.auto.dark .cancel-btn:hover {
|
||||
border-color: rgb(75 85 99);
|
||||
background: rgb(75 85 99);
|
||||
}
|
||||
|
||||
.confirm-btn.primary {
|
||||
/* Confirm Button */
|
||||
.confirm-btn {
|
||||
border: none;
|
||||
color: white;
|
||||
background: rgb(59 130 246);
|
||||
background: linear-gradient(135deg, rgb(59 130 246) 0%, rgb(37 99 235) 100%);
|
||||
box-shadow: 0 1px 2px 0 rgb(0 0 0 / 5%);
|
||||
}
|
||||
|
||||
.confirm-btn.primary:hover {
|
||||
background: rgb(37 99 235);
|
||||
.confirm-btn:hover:not(:disabled) {
|
||||
background: linear-gradient(135deg, rgb(37 99 235) 0%, rgb(29 78 216) 100%);
|
||||
box-shadow: 0 4px 12px rgb(59 130 246 / 40%);
|
||||
}
|
||||
|
||||
/* Responsive */
|
||||
@media (width <= 640px) {
|
||||
.inputbox-overlay {
|
||||
align-items: flex-end;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.inputbox-container {
|
||||
border-radius: 1rem 1rem 0 0;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.inputbox-body {
|
||||
padding: 1.75rem 1.5rem 1.25rem;
|
||||
}
|
||||
|
||||
.inputbox-actions {
|
||||
flex-direction: column-reverse;
|
||||
}
|
||||
|
||||
.inputbox-btn {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,42 +1,41 @@
|
||||
<template>
|
||||
<div v-if="isOpen" class="messagebox-overlay" @click="onCancel">
|
||||
<div class="messagebox-container" @click.stop>
|
||||
<div class="messagebox-header">
|
||||
<h3 class="messagebox-title">
|
||||
{{ title }}
|
||||
</h3>
|
||||
<button v-if="showClose" class="messagebox-close" @click="onCancel">×</button>
|
||||
</div>
|
||||
<div class="messagebox-content">
|
||||
<div v-if="type" class="messagebox-icon">
|
||||
<component :is="iconComponent" :size="48" />
|
||||
<Transition name="messagebox-fade">
|
||||
<div v-if="isOpen" class="messagebox-overlay" @click="onCancel">
|
||||
<Transition name="messagebox-scale">
|
||||
<div v-if="isOpen" class="messagebox-container" @click.stop>
|
||||
<button v-if="showClose" class="messagebox-close" @click="onCancel">
|
||||
<XIcon :size="20" />
|
||||
</button>
|
||||
|
||||
<div class="messagebox-body">
|
||||
<div class="messagebox-main">
|
||||
<div v-if="type" class="messagebox-icon-wrapper" :class="`messagebox-icon-${type}`">
|
||||
<component :is="iconComponent" :size="24" :stroke-width="2.5" />
|
||||
</div>
|
||||
|
||||
<div class="messagebox-content">
|
||||
<h3 class="messagebox-title">{{ title }}</h3>
|
||||
<p class="messagebox-message">{{ message }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="messagebox-actions" :class="{ center }">
|
||||
<button class="messagebox-btn cancel-btn" @click="onCancel">
|
||||
{{ cancelButtonText }}
|
||||
</button>
|
||||
<button class="messagebox-btn confirm-btn" :class="confirmButtonClass" @click="onConfirm">
|
||||
{{ confirmButtonText }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="messagebox-message">
|
||||
<p>{{ message }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="center" class="messagebox-actions center">
|
||||
<button class="messagebox-btn cancel-btn" @click="onCancel">
|
||||
{{ cancelButtonText }}
|
||||
</button>
|
||||
<button class="messagebox-btn confirm-btn" :class="confirmButtonClass" @click="onConfirm">
|
||||
{{ confirmButtonText }}
|
||||
</button>
|
||||
</div>
|
||||
<div v-else class="messagebox-actions">
|
||||
<button class="messagebox-btn confirm-btn" :class="confirmButtonClass" @click="onConfirm">
|
||||
{{ confirmButtonText }}
|
||||
</button>
|
||||
<button class="messagebox-btn cancel-btn" @click="onCancel">
|
||||
{{ cancelButtonText }}
|
||||
</button>
|
||||
</div>
|
||||
</Transition>
|
||||
</div>
|
||||
</div>
|
||||
</Transition>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { AlertTriangle, CheckCircle, Info, XCircle } from 'lucide-vue-next'
|
||||
import { AlertTriangle, CheckCircle, Info, X as XIcon, XCircle } from 'lucide-vue-next'
|
||||
import { computed } from 'vue'
|
||||
|
||||
interface Props {
|
||||
@@ -109,6 +108,36 @@ export default {
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* Transitions */
|
||||
.messagebox-fade-enter-active,
|
||||
.messagebox-fade-leave-active {
|
||||
transition: opacity 0.2s ease;
|
||||
}
|
||||
|
||||
.messagebox-fade-enter-from,
|
||||
.messagebox-fade-leave-to {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.messagebox-scale-enter-active {
|
||||
transition: all 0.25s cubic-bezier(0.34, 1.56, 0.64, 1);
|
||||
}
|
||||
|
||||
.messagebox-scale-leave-active {
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.messagebox-scale-enter-from {
|
||||
opacity: 0;
|
||||
transform: scale(0.9) translateY(-10px);
|
||||
}
|
||||
|
||||
.messagebox-scale-leave-to {
|
||||
opacity: 0;
|
||||
transform: scale(0.95);
|
||||
}
|
||||
|
||||
/* Overlay */
|
||||
.messagebox-overlay {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
@@ -116,15 +145,19 @@ export default {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background: rgb(0 0 0 / 50%);
|
||||
padding: 1rem;
|
||||
background: rgb(0 0 0 / 40%);
|
||||
backdrop-filter: blur(4px);
|
||||
}
|
||||
|
||||
/* Container */
|
||||
.messagebox-container {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
border-radius: 0.75rem;
|
||||
width: 90%;
|
||||
max-width: 32rem;
|
||||
max-height: 80vh;
|
||||
border: 1px solid rgb(229 231 235);
|
||||
border-radius: 1rem;
|
||||
width: 100%;
|
||||
max-width: 26rem;
|
||||
background: white;
|
||||
box-shadow:
|
||||
0 20px 25px -5px rgb(0 0 0 / 10%),
|
||||
@@ -133,46 +166,30 @@ export default {
|
||||
|
||||
:root.dark .messagebox-container,
|
||||
:root.auto.dark .messagebox-container {
|
||||
border: 1px solid rgb(55 65 81);
|
||||
border-color: rgb(55 65 81);
|
||||
background: rgb(31 41 55);
|
||||
}
|
||||
|
||||
.messagebox-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 1.5rem 1.5rem 0;
|
||||
}
|
||||
|
||||
.messagebox-title {
|
||||
margin: 0;
|
||||
font-size: 1.25rem;
|
||||
font-weight: 600;
|
||||
color: rgb(17 24 39);
|
||||
}
|
||||
|
||||
:root.dark .messagebox-title,
|
||||
:root.auto.dark .messagebox-title {
|
||||
color: rgb(243 244 246);
|
||||
}
|
||||
|
||||
/* Close Button */
|
||||
.messagebox-close {
|
||||
position: absolute;
|
||||
top: 1rem;
|
||||
right: 1rem;
|
||||
z-index: 10;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border: none;
|
||||
border-radius: 0.25rem;
|
||||
padding: 0;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
font-size: 1.5rem;
|
||||
border-radius: 0.5rem;
|
||||
padding: 0.375rem;
|
||||
color: rgb(107 114 128);
|
||||
background: none;
|
||||
background: transparent;
|
||||
transition: all 0.15s ease;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.messagebox-close:hover {
|
||||
color: rgb(17 24 39);
|
||||
color: rgb(75 85 99);
|
||||
background: rgb(243 244 246);
|
||||
}
|
||||
|
||||
@@ -183,120 +200,246 @@ export default {
|
||||
|
||||
:root.dark .messagebox-close:hover,
|
||||
:root.auto.dark .messagebox-close:hover {
|
||||
color: rgb(243 244 246);
|
||||
color: rgb(209 213 219);
|
||||
background: rgb(55 65 81);
|
||||
}
|
||||
|
||||
.messagebox-content {
|
||||
/* Body */
|
||||
.messagebox-body {
|
||||
padding: 1.75rem 2rem 1.5rem;
|
||||
}
|
||||
|
||||
.messagebox-main {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
padding: 1rem 1.5rem;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.messagebox-icon {
|
||||
/* Icon Wrapper */
|
||||
.messagebox-icon-wrapper {
|
||||
display: flex;
|
||||
flex-shrink: 0;
|
||||
color: rgb(107 114 128);
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: 0.625rem;
|
||||
width: 3rem;
|
||||
height: 3rem;
|
||||
animation: icon-pop 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
|
||||
}
|
||||
|
||||
.messagebox-icon svg[data-lucide='alert-triangle'] {
|
||||
@keyframes icon-pop {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: scale(0);
|
||||
}
|
||||
|
||||
50% {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
.messagebox-icon-warning {
|
||||
color: rgb(245 158 11);
|
||||
background: rgb(254 243 199);
|
||||
}
|
||||
|
||||
.messagebox-icon svg[data-lucide='info'] {
|
||||
:root.dark .messagebox-icon-warning,
|
||||
:root.auto.dark .messagebox-icon-warning {
|
||||
color: rgb(251 191 36);
|
||||
background: rgb(120 53 15 / 30%);
|
||||
}
|
||||
|
||||
.messagebox-icon-info {
|
||||
color: rgb(59 130 246);
|
||||
background: rgb(219 234 254);
|
||||
}
|
||||
|
||||
.messagebox-icon svg[data-lucide='check-circle'] {
|
||||
:root.dark .messagebox-icon-info,
|
||||
:root.auto.dark .messagebox-icon-info {
|
||||
color: rgb(96 165 250);
|
||||
background: rgb(30 58 138 / 30%);
|
||||
}
|
||||
|
||||
.messagebox-icon-success {
|
||||
color: rgb(34 197 94);
|
||||
background: rgb(220 252 231);
|
||||
}
|
||||
|
||||
.messagebox-icon svg[data-lucide='x-circle'] {
|
||||
:root.dark .messagebox-icon-success,
|
||||
:root.auto.dark .messagebox-icon-success {
|
||||
color: rgb(74 222 128);
|
||||
background: rgb(20 83 45 / 30%);
|
||||
}
|
||||
|
||||
.messagebox-icon-error {
|
||||
color: rgb(239 68 68);
|
||||
background: rgb(254 226 226);
|
||||
}
|
||||
|
||||
:root.dark .messagebox-icon-error,
|
||||
:root.auto.dark .messagebox-icon-error {
|
||||
color: rgb(248 113 113);
|
||||
background: rgb(127 29 29 / 30%);
|
||||
}
|
||||
|
||||
/* Content */
|
||||
.messagebox-content {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.messagebox-title {
|
||||
margin: 0 0 0.375rem;
|
||||
font-size: 1.0625rem;
|
||||
font-weight: 600;
|
||||
line-height: 1.4;
|
||||
color: rgb(17 24 39);
|
||||
}
|
||||
|
||||
:root.dark .messagebox-title,
|
||||
:root.auto.dark .messagebox-title {
|
||||
color: rgb(243 244 246);
|
||||
}
|
||||
|
||||
.messagebox-message {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.messagebox-message p {
|
||||
margin: 0;
|
||||
font-size: 0.9375rem;
|
||||
line-height: 1.5;
|
||||
color: rgb(107 114 128);
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
:root.dark .messagebox-message p,
|
||||
:root.auto.dark .messagebox-message p {
|
||||
:root.dark .messagebox-message,
|
||||
:root.auto.dark .messagebox-message {
|
||||
color: rgb(156 163 175);
|
||||
}
|
||||
|
||||
/* Actions */
|
||||
.messagebox-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
padding: 0 1.5rem 1.5rem;
|
||||
border-top: 1px solid rgb(243 244 246);
|
||||
padding: 1rem 1.5rem;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
|
||||
:root.dark .messagebox-actions,
|
||||
:root.auto.dark .messagebox-actions {
|
||||
border-top-color: rgb(55 65 81);
|
||||
}
|
||||
|
||||
.messagebox-actions.center {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.messagebox-btn {
|
||||
flex: 1;
|
||||
border: none;
|
||||
border-radius: 0.375rem;
|
||||
padding: 0.5rem 1rem;
|
||||
min-width: 4rem;
|
||||
border-radius: 0.5rem;
|
||||
padding: 0.625rem 1.25rem;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 500;
|
||||
transition: all 0.15s ease;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.messagebox-btn:active {
|
||||
transform: scale(0.98);
|
||||
}
|
||||
|
||||
/* Cancel Button */
|
||||
.cancel-btn {
|
||||
border: 1px solid rgb(209 213 219);
|
||||
border: 1px solid rgb(229 231 235);
|
||||
color: rgb(75 85 99);
|
||||
background: rgb(243 244 246);
|
||||
background: white;
|
||||
}
|
||||
|
||||
.cancel-btn:hover {
|
||||
background: rgb(229 231 235);
|
||||
border-color: rgb(209 213 219);
|
||||
background: rgb(249 250 251);
|
||||
}
|
||||
|
||||
:root.dark .cancel-btn,
|
||||
:root.auto.dark .cancel-btn {
|
||||
border-color: rgb(75 85 99);
|
||||
border-color: rgb(55 65 81);
|
||||
color: rgb(209 213 219);
|
||||
background: rgb(55 65 81);
|
||||
}
|
||||
|
||||
:root.dark .cancel-btn:hover,
|
||||
:root.auto.dark .cancel-btn:hover {
|
||||
border-color: rgb(75 85 99);
|
||||
background: rgb(75 85 99);
|
||||
}
|
||||
|
||||
.confirm-btn.primary {
|
||||
/* Confirm Buttons */
|
||||
.confirm-btn {
|
||||
border: none;
|
||||
color: white;
|
||||
background: rgb(59 130 246);
|
||||
box-shadow: 0 1px 2px 0 rgb(0 0 0 / 5%);
|
||||
}
|
||||
|
||||
.confirm-btn.primary {
|
||||
background: linear-gradient(135deg, rgb(59 130 246) 0%, rgb(37 99 235) 100%);
|
||||
}
|
||||
|
||||
.confirm-btn.primary:hover {
|
||||
background: rgb(37 99 235);
|
||||
background: linear-gradient(135deg, rgb(37 99 235) 0%, rgb(29 78 216) 100%);
|
||||
box-shadow: 0 4px 12px rgb(59 130 246 / 40%);
|
||||
}
|
||||
|
||||
.confirm-btn.danger {
|
||||
color: white;
|
||||
background: rgb(239 68 68);
|
||||
background: linear-gradient(135deg, rgb(239 68 68) 0%, rgb(220 38 38) 100%);
|
||||
}
|
||||
|
||||
.confirm-btn.danger:hover {
|
||||
background: rgb(220 38 38);
|
||||
background: linear-gradient(135deg, rgb(220 38 38) 0%, rgb(185 28 28) 100%);
|
||||
box-shadow: 0 4px 12px rgb(239 68 68 / 40%);
|
||||
}
|
||||
|
||||
.confirm-btn.success {
|
||||
color: white;
|
||||
background: rgb(34 197 94);
|
||||
background: linear-gradient(135deg, rgb(34 197 94) 0%, rgb(22 163 74) 100%);
|
||||
}
|
||||
|
||||
.confirm-btn.success:hover {
|
||||
background: rgb(22 163 74);
|
||||
background: linear-gradient(135deg, rgb(22 163 74) 0%, rgb(21 128 61) 100%);
|
||||
box-shadow: 0 4px 12px rgb(34 197 94 / 40%);
|
||||
}
|
||||
|
||||
/* Responsive */
|
||||
@media (width <= 640px) {
|
||||
.messagebox-overlay {
|
||||
align-items: flex-end;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.messagebox-container {
|
||||
border-radius: 1rem 1rem 0 0;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.messagebox-body {
|
||||
padding: 1.5rem 1.5rem 1.25rem;
|
||||
}
|
||||
|
||||
.messagebox-main {
|
||||
gap: 0.875rem;
|
||||
}
|
||||
|
||||
.messagebox-icon-wrapper {
|
||||
width: 2.75rem;
|
||||
height: 2.75rem;
|
||||
}
|
||||
|
||||
.messagebox-actions {
|
||||
flex-direction: column-reverse;
|
||||
}
|
||||
|
||||
.messagebox-btn {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -194,7 +194,6 @@ export default {
|
||||
color: rgb(75 85 99);
|
||||
flex: 1;
|
||||
line-height: 1.25rem;
|
||||
word-break: break-word;
|
||||
overflow-wrap: break-word;
|
||||
hyphens: auto;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user