chore: update page style mobile #20
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog'
|
||||
import BaihuDialog from '@/components/ui/BaihuDialog.vue'
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
@@ -22,19 +22,16 @@ function handleClick() {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<span v-bind="$attrs" class="truncate block cursor-pointer hover:text-primary" :title="text || '-'"
|
||||
@click="handleClick">
|
||||
<span v-bind="$attrs" class="truncate block cursor-pointer hover:text-primary transition-colors" :title="text || '-'"
|
||||
@click.stop="handleClick">
|
||||
{{ text || '-' }}
|
||||
</span>
|
||||
|
||||
<Dialog v-model:open="showDialog">
|
||||
<DialogContent class="sm:max-w-[600px]">
|
||||
<DialogHeader>
|
||||
<DialogTitle>{{ title }}</DialogTitle>
|
||||
</DialogHeader>
|
||||
<div class="max-h-[400px] overflow-y-auto">
|
||||
<pre class="text-sm whitespace-pre-wrap break-all font-mono bg-muted p-3 rounded-lg">{{ text }}</pre>
|
||||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
<BaihuDialog v-model:open="showDialog" :title="title">
|
||||
<div class="max-h-[60vh] overflow-y-auto custom-scrollbar">
|
||||
<p class="text-[15px] leading-relaxed text-foreground/80 break-all whitespace-pre-wrap font-sans">
|
||||
{{ text }}
|
||||
</p>
|
||||
</div>
|
||||
</BaihuDialog>
|
||||
</template>
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
<script setup lang="ts">
|
||||
import { X } from 'lucide-vue-next'
|
||||
import * as Icons from 'lucide-vue-next'
|
||||
import { computed } from 'vue'
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
DialogDescription,
|
||||
DialogClose
|
||||
} from '@/components/ui/dialog'
|
||||
|
||||
interface Props {
|
||||
open: boolean
|
||||
title?: string
|
||||
description?: string
|
||||
icon?: string
|
||||
size?: 'sm' | 'md' | 'lg' | 'xl' | 'full'
|
||||
showClose?: boolean
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
title: '',
|
||||
description: '',
|
||||
size: 'md',
|
||||
showClose: true,
|
||||
icon: ''
|
||||
})
|
||||
|
||||
const iconComponent = computed(() => {
|
||||
if (!props.icon) return null
|
||||
return (Icons as any)[props.icon]
|
||||
})
|
||||
|
||||
const emit = defineEmits<{
|
||||
'update:open': [value: boolean]
|
||||
}>()
|
||||
|
||||
const sizeClasses = {
|
||||
sm: 'sm:max-w-[425px]',
|
||||
md: 'sm:max-w-[600px]',
|
||||
lg: 'sm:max-w-[800px]',
|
||||
xl: 'sm:max-w-[1000px]',
|
||||
full: 'sm:max-w-[95vw] h-[90vh]'
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Dialog :open="open" @update:open="emit('update:open', $event)">
|
||||
<DialogContent
|
||||
:show-close-button="false"
|
||||
:class="[
|
||||
'overflow-hidden border-none p-0 bg-background/90 backdrop-blur-xl shadow-2xl ring-1 ring-black/5 dark:ring-white/10 rounded-xl',
|
||||
sizeClasses[size],
|
||||
'transition-all duration-300'
|
||||
]"
|
||||
>
|
||||
<!-- 统一的 Header 风格 (参考日志详情) -->
|
||||
<div class="flex items-center justify-between px-4 h-11 border-b bg-muted/20 shrink-0">
|
||||
<DialogHeader class="space-y-1 text-left flex-1 min-w-0">
|
||||
<div class="flex items-center gap-2">
|
||||
<component :is="iconComponent" v-if="iconComponent" class="h-4 w-4 text-primary shrink-0" />
|
||||
<DialogTitle class="text-[13px] font-normal text-muted-foreground tracking-wide truncate">
|
||||
{{ title }}
|
||||
</DialogTitle>
|
||||
</div>
|
||||
<DialogDescription v-if="description" class="text-xs text-muted-foreground/60 leading-relaxed truncate">
|
||||
{{ description }}
|
||||
</DialogDescription>
|
||||
<DialogDescription v-else class="sr-only">
|
||||
{{ title || '提示对话框' }}
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
||||
<DialogClose
|
||||
v-if="showClose"
|
||||
class="h-7 w-7 rounded-md opacity-70 transition-all hover:opacity-100 hover:bg-muted flex items-center justify-center -mr-1"
|
||||
>
|
||||
<X class="h-4 w-4 text-muted-foreground" />
|
||||
<span class="sr-only">关闭</span>
|
||||
</DialogClose>
|
||||
</div>
|
||||
|
||||
<!-- 内容区域 (保持整洁简洁) -->
|
||||
<div class="p-6">
|
||||
<div class="animate-in fade-in slide-in-from-bottom-1 duration-400">
|
||||
<slot />
|
||||
</div>
|
||||
|
||||
<!-- 底部插槽 -->
|
||||
<div v-if="$slots.footer" class="mt-8 flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2 gap-2">
|
||||
<slot name="footer" />
|
||||
</div>
|
||||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
:deep([data-state='open']) {
|
||||
animation: baihu-dialog-in 0.3s cubic-bezier(0.16, 1, 0.3, 1);
|
||||
}
|
||||
|
||||
:deep([data-state='closed']) {
|
||||
animation: baihu-dialog-out 0.2s cubic-bezier(0.16, 1, 0.3, 1);
|
||||
}
|
||||
|
||||
@keyframes baihu-dialog-in {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translate(-50%, -48%) scale(0.96);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translate(-50%, -50%) scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes baihu-dialog-out {
|
||||
from {
|
||||
opacity: 1;
|
||||
transform: translate(-50%, -50%) scale(1);
|
||||
}
|
||||
to {
|
||||
opacity: 0;
|
||||
transform: translate(-50%, -48%) scale(0.96);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user