updates
This commit is contained in:
parent
b02d66cc2b
commit
8b9602ff4c
|
|
@ -20,11 +20,6 @@ const props = withDefaults(defineProps<Props>(), {
|
||||||
// 定义 Emits (声明组件会触发哪些事件)
|
// 定义 Emits (声明组件会触发哪些事件)
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(e: 'change', payload: { keyword: string, filters: FilterState }): void
|
(e: 'change', payload: { keyword: string, filters: FilterState }): void
|
||||||
|
|
||||||
// // 当点击下拉菜单里的“确定”时触发,回传筛选对象
|
|
||||||
// (e: 'confirm', filters: FilterState): void;
|
|
||||||
// // 当点击右侧“搜索”按钮时触发,回传搜索关键词
|
|
||||||
// (e: 'search', keyword: string): void;
|
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
// --- 类型定义 ---
|
// --- 类型定义 ---
|
||||||
|
|
@ -45,41 +40,10 @@ const filters: FilterConfig[] = [
|
||||||
|
|
||||||
// 按照截图还原的省份数据
|
// 按照截图还原的省份数据
|
||||||
const locations = [
|
const locations = [
|
||||||
'不限',
|
'不限', '北京', '天津', '河北', '山西', '内蒙古', '辽宁', '吉林', '黑龙江',
|
||||||
'北京',
|
'上海', '江苏', '浙江', '安徽', '福建', '江西', '山东', '河南', '湖北',
|
||||||
'天津',
|
'湖南', '广东', '广西', '海南', '重庆', '四川', '贵州', '云南', '西藏',
|
||||||
'河北',
|
'陕西', '甘肃', '青海', '宁夏', '新疆', '台湾', '香港', '澳门',
|
||||||
'山西',
|
|
||||||
'内蒙古',
|
|
||||||
'辽宁',
|
|
||||||
'吉林',
|
|
||||||
'黑龙江',
|
|
||||||
'上海',
|
|
||||||
'江苏',
|
|
||||||
'浙江',
|
|
||||||
'安徽',
|
|
||||||
'福建',
|
|
||||||
'江西',
|
|
||||||
'山东',
|
|
||||||
'河南',
|
|
||||||
'湖北',
|
|
||||||
'湖南',
|
|
||||||
'广东',
|
|
||||||
'广西',
|
|
||||||
'海南',
|
|
||||||
'重庆',
|
|
||||||
'四川',
|
|
||||||
'贵州',
|
|
||||||
'云南',
|
|
||||||
'西藏',
|
|
||||||
'陕西',
|
|
||||||
'甘肃',
|
|
||||||
'青海',
|
|
||||||
'宁夏',
|
|
||||||
'新疆',
|
|
||||||
'台湾',
|
|
||||||
'香港',
|
|
||||||
'澳门',
|
|
||||||
]
|
]
|
||||||
|
|
||||||
// --- 状态 ---
|
// --- 状态 ---
|
||||||
|
|
@ -95,19 +59,13 @@ const selectedFilters = reactive({
|
||||||
sort: '默认',
|
sort: '默认',
|
||||||
})
|
})
|
||||||
|
|
||||||
// 临时选中的值(用于在点击“确定”之前暂存,如果需要这种逻辑的话,本例为了简单直接修改 selectedFilters)
|
|
||||||
// 如果要严格复刻逻辑,通常点击选项时只变色,点确定才生效。这里简化为点击即选中高亮。
|
|
||||||
|
|
||||||
// --- 计算属性 ---
|
// --- 计算属性 ---
|
||||||
function getLabel(key: FilterKey) {
|
function getLabel(key: FilterKey) {
|
||||||
// 如果不是默认值,可以显示选中的值,否则显示标题
|
|
||||||
// 这里为了保持截图样式,保持显示标题
|
|
||||||
const map = { location: '位置', type: '类型', major: '专业', sort: '排序' }
|
const map = { location: '位置', type: '类型', major: '专业', sort: '排序' }
|
||||||
return map[key]
|
return map[key]
|
||||||
}
|
}
|
||||||
|
|
||||||
const countSelected = computed(() => {
|
const countSelected = computed(() => {
|
||||||
// 简单计算:如果当前打开的是位置,且选的不是不限,则为1,否则0
|
|
||||||
if (activeFilter.value === 'location') {
|
if (activeFilter.value === 'location') {
|
||||||
return selectedFilters.location !== '不限' ? 1 : 0
|
return selectedFilters.location !== '不限' ? 1 : 0
|
||||||
}
|
}
|
||||||
|
|
@ -115,7 +73,6 @@ const countSelected = computed(() => {
|
||||||
})
|
})
|
||||||
|
|
||||||
function shouldShowFilter(filter: FilterConfig) {
|
function shouldShowFilter(filter: FilterConfig) {
|
||||||
// 显示所有非排序过滤器,或者当排序过滤器启用时显示排序过滤器
|
|
||||||
return filter.key !== 'sort' || (filter.key === 'sort' && props.sortEnabled)
|
return filter.key !== 'sort' || (filter.key === 'sort' && props.sortEnabled)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -146,15 +103,12 @@ function clearCurrentFilter() {
|
||||||
// 确定按钮
|
// 确定按钮
|
||||||
function confirmSelection() {
|
function confirmSelection() {
|
||||||
emit('change', { keyword: searchQuery.value, filters: { ...selectedFilters } })
|
emit('change', { keyword: searchQuery.value, filters: { ...selectedFilters } })
|
||||||
// 使用展开运算符 {...} 创建副本,防止父组件修改影响子组件(可选)
|
|
||||||
// emit('confirm', { ...selectedFilters });
|
|
||||||
activeFilter.value = null // 关闭菜单
|
activeFilter.value = null // 关闭菜单
|
||||||
}
|
}
|
||||||
|
|
||||||
// 搜索按钮
|
// 搜索按钮
|
||||||
function handleSearch() {
|
function handleSearch() {
|
||||||
emit('change', { keyword: searchQuery.value, filters: { ...selectedFilters } })
|
emit('change', { keyword: searchQuery.value, filters: { ...selectedFilters } })
|
||||||
// emit('search', searchQuery.value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- 点击外部关闭逻辑 ---
|
// --- 点击外部关闭逻辑 ---
|
||||||
|
|
@ -174,8 +128,9 @@ onUnmounted(() => {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<!-- 最外层容器,用于定位下拉菜单和监听点击外部事件 -->
|
<!-- 最外层容器 -->
|
||||||
<div ref="containerRef" class="relative mx-auto max-w-5xl w-full select-none text-sm text-gray-600 font-sans">
|
<!-- Update: text-gray-600 -> dark:text-slate-300 -->
|
||||||
|
<div ref="containerRef" class="relative mx-auto w-full max-w-5xl select-none font-sans text-sm text-gray-600 dark:text-slate-300">
|
||||||
<!-- 顶部栏:筛选按钮组 + 搜索框 -->
|
<!-- 顶部栏:筛选按钮组 + 搜索框 -->
|
||||||
<div class="flex flex-wrap items-center justify-between gap-4">
|
<div class="flex flex-wrap items-center justify-between gap-4">
|
||||||
<!-- 左侧:4个下拉筛选器 -->
|
<!-- 左侧:4个下拉筛选器 -->
|
||||||
|
|
@ -187,14 +142,30 @@ onUnmounted(() => {
|
||||||
class="relative"
|
class="relative"
|
||||||
>
|
>
|
||||||
<!-- 筛选器按钮 -->
|
<!-- 筛选器按钮 -->
|
||||||
|
<!-- Update:
|
||||||
|
bg-white -> dark:bg-slate-800
|
||||||
|
border-gray-200 -> dark:border-slate-700
|
||||||
|
ring-blue-200 -> dark:ring-blue-900 (Focus ring 变深)
|
||||||
|
-->
|
||||||
<button
|
<button
|
||||||
class="h-9 w-24 flex items-center justify-between border rounded bg-white px-3 transition-colors hover:border-blue-400"
|
class="flex h-9 w-24 items-center justify-between rounded border px-3 transition-colors hover:border-blue-400"
|
||||||
:class="activeFilter === filter.key ? 'border-blue-500 ring-1 ring-blue-200' : 'border-gray-200'"
|
:class="[
|
||||||
|
activeFilter === filter.key
|
||||||
|
? 'border-blue-500 ring-1 ring-blue-200 dark:ring-blue-900'
|
||||||
|
: 'border-gray-200 dark:border-slate-700',
|
||||||
|
'bg-white dark:bg-slate-800'
|
||||||
|
]"
|
||||||
@click="toggleFilter(filter.key)"
|
@click="toggleFilter(filter.key)"
|
||||||
>
|
>
|
||||||
<span class="truncate">{{ getLabel(filter.key) }}</span>
|
<span class="truncate">{{ getLabel(filter.key) }}</span>
|
||||||
<!-- 下箭头图标 -->
|
<!-- 下箭头图标 -->
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-3 w-3 text-gray-400 transition-transform duration-200" :class="{ 'rotate-180': activeFilter === filter.key }" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
<!-- Update: text-gray-400 -> dark:text-slate-500 -->
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
class="h-3 w-3 text-gray-400 transition-transform duration-200 dark:text-slate-500"
|
||||||
|
:class="{ 'rotate-180': activeFilter === filter.key }"
|
||||||
|
fill="none" viewBox="0 0 24 24" stroke="currentColor"
|
||||||
|
>
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" />
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" />
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -205,17 +176,19 @@ onUnmounted(() => {
|
||||||
<div class="flex flex-wrap items-center">
|
<div class="flex flex-wrap items-center">
|
||||||
<div class="relative">
|
<div class="relative">
|
||||||
<div class="pointer-events-none absolute inset-y-0 left-0 flex items-center pl-3">
|
<div class="pointer-events-none absolute inset-y-0 left-0 flex items-center pl-3">
|
||||||
<svg class="h-4 w-4 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" /></svg>
|
<!-- Update: Icon 颜色 -->
|
||||||
|
<svg class="h-4 w-4 text-gray-400 dark:text-slate-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" /></svg>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- Update: 输入框颜色适配 -->
|
||||||
<input
|
<input
|
||||||
v-model="searchQuery"
|
v-model="searchQuery"
|
||||||
type="text"
|
type="text"
|
||||||
class="h-9 w-50 border border-gray-300 rounded-l bg-white py-2 pl-9 pr-4 text-gray-700 focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-200 placeholder-gray-400"
|
class="h-9 w-50 rounded-l border border-gray-300 py-2 pl-9 pr-4 text-gray-700 placeholder-gray-400 focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-200 dark:bg-slate-800 dark:border-slate-700 dark:text-slate-200 dark:placeholder-slate-500 dark:focus:ring-blue-900"
|
||||||
placeholder="输入院校名称"
|
placeholder="输入院校名称"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
class="h-9 rounded-r bg-blue-500 px-6 text-white transition-colors active:bg-blue-700 hover:bg-blue-600 focus:outline-none"
|
class="h-9 rounded-r bg-blue-500 px-6 text-white transition-colors hover:bg-blue-600 focus:outline-none active:bg-blue-700"
|
||||||
@click="handleSearch"
|
@click="handleSearch"
|
||||||
>
|
>
|
||||||
搜索
|
搜索
|
||||||
|
|
@ -224,7 +197,6 @@ onUnmounted(() => {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 下拉菜单面板 (绝对定位) -->
|
<!-- 下拉菜单面板 (绝对定位) -->
|
||||||
<!-- 使用 Transition 添加简单的淡入淡出效果 -->
|
|
||||||
<transition
|
<transition
|
||||||
enter-active-class="transition duration-100 ease-out"
|
enter-active-class="transition duration-100 ease-out"
|
||||||
enter-from-class="transform scale-95 opacity-0"
|
enter-from-class="transform scale-95 opacity-0"
|
||||||
|
|
@ -233,25 +205,27 @@ onUnmounted(() => {
|
||||||
leave-from-class="transform scale-100 opacity-100"
|
leave-from-class="transform scale-100 opacity-100"
|
||||||
leave-to-class="transform scale-95 opacity-0"
|
leave-to-class="transform scale-95 opacity-0"
|
||||||
>
|
>
|
||||||
<!-- style="min-width: 600px;" -->
|
<!-- Update: 面板背景与边框 -->
|
||||||
<div
|
<div
|
||||||
v-if="activeFilter"
|
v-if="activeFilter"
|
||||||
class="absolute left-0 top-full z-50 mt-2 border border-gray-100 rounded-lg bg-white p-5 shadow-xl"
|
class="absolute left-0 top-full z-50 mt-2 border border-gray-100 bg-white p-5 shadow-xl rounded-lg dark:bg-slate-800 dark:border-slate-700"
|
||||||
>
|
>
|
||||||
<!-- 下拉内容区域 -->
|
<!-- 下拉内容区域 -->
|
||||||
|
|
||||||
<!-- 1. 位置 (Location) 内容 -->
|
<!-- 1. 位置 (Location) 内容 -->
|
||||||
<div v-if="activeFilter === 'location'">
|
<div v-if="activeFilter === 'location'">
|
||||||
<div class="flex items-start gap-4">
|
<div class="flex items-start gap-4">
|
||||||
<span class="mt-1 shrink-0 text-gray-400 font-medium">院校所属</span>
|
<!-- Update: 标签文字颜色 -->
|
||||||
<div class="xs:grid-cols-3 grid gap-2 lg:grid-cols-6 md:grid-cols-5 sm:grid-cols-3">
|
<span class="mt-1 shrink-0 font-medium text-gray-400 dark:text-slate-500">院校所属</span>
|
||||||
|
<div class="grid gap-2 sm:grid-cols-3 md:grid-cols-5 lg:grid-cols-6 xs:grid-cols-3">
|
||||||
|
<!-- Update: 选项 Tag 的选中/未选中态 -->
|
||||||
<button
|
<button
|
||||||
v-for="city in locations"
|
v-for="city in locations"
|
||||||
:key="city"
|
:key="city"
|
||||||
class="rounded px-3 py-1.5 text-center transition-colors hover:text-blue-500"
|
class="rounded px-3 py-1.5 text-center transition-colors hover:text-blue-500 dark:hover:text-blue-400"
|
||||||
:class="selectedFilters.location === city
|
:class="selectedFilters.location === city
|
||||||
? 'bg-blue-50 text-blue-500 font-medium'
|
? 'bg-blue-50 text-blue-500 font-medium dark:bg-blue-900/40 dark:text-blue-400'
|
||||||
: 'text-gray-600 bg-gray-50 hover:bg-gray-100'"
|
: 'text-gray-600 bg-gray-50 hover:bg-gray-100 dark:bg-slate-700 dark:text-slate-300 dark:hover:bg-slate-600'"
|
||||||
@click="selectOption('location', city)"
|
@click="selectOption('location', city)"
|
||||||
>
|
>
|
||||||
{{ city }}
|
{{ city }}
|
||||||
|
|
@ -260,19 +234,21 @@ onUnmounted(() => {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 2. 其他筛选器占位内容 (类型、专业、排序) -->
|
<!-- 2. 其他筛选器占位内容 -->
|
||||||
<div v-else class="p-4 text-center text-gray-400">
|
<div v-else class="p-4 text-center text-gray-400 dark:text-slate-500">
|
||||||
这里是 {{ filters.find(f => f.key === activeFilter)?.label }} 的筛选选项
|
这里是 {{ filters.find(f => f.key === activeFilter)?.label }} 的筛选选项
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 底部操作按钮 -->
|
<!-- 底部操作按钮 -->
|
||||||
<div class="mt-6 flex items-center justify-between border-t border-gray-100 pt-4">
|
<!-- Update: 分割线颜色 -->
|
||||||
<div class="text-gray-500">
|
<div class="mt-6 flex items-center justify-between border-t border-gray-100 pt-4 dark:border-slate-700">
|
||||||
已选 <span class="text-blue-500 font-bold">{{ countSelected }}</span> 个
|
<div class="text-gray-500 dark:text-slate-400">
|
||||||
|
已选 <span class="font-bold text-blue-500 dark:text-blue-400">{{ countSelected }}</span> 个
|
||||||
</div>
|
</div>
|
||||||
<div class="flex gap-3">
|
<div class="flex gap-3">
|
||||||
|
<!-- Update: 清空按钮 Hover 背景 -->
|
||||||
<button
|
<button
|
||||||
class="border border-blue-500 rounded px-4 py-1.5 text-blue-500 transition-colors hover:bg-blue-50"
|
class="rounded border border-blue-500 px-4 py-1.5 text-blue-500 transition-colors hover:bg-blue-50 dark:text-blue-400 dark:border-blue-500 dark:hover:bg-blue-900/20"
|
||||||
@click="clearCurrentFilter"
|
@click="clearCurrentFilter"
|
||||||
>
|
>
|
||||||
清空已选
|
清空已选
|
||||||
|
|
@ -288,11 +264,4 @@ onUnmounted(() => {
|
||||||
</div>
|
</div>
|
||||||
</transition>
|
</transition>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
/*
|
|
||||||
如果你的 tailwind 配置没有自动移除按钮的默认样式,可能需要以下代码。
|
|
||||||
一般在 tailwind base 中已经处理好了。
|
|
||||||
*/
|
|
||||||
</style>
|
|
||||||
|
|
@ -120,16 +120,14 @@ const overlayPositionClass = computed(() => {
|
||||||
|
|
||||||
// 2. 箭头的位置与旋转 (相对于 Popover)
|
// 2. 箭头的位置与旋转 (相对于 Popover)
|
||||||
const arrowPositionClass = computed(() => {
|
const arrowPositionClass = computed(() => {
|
||||||
const base = 'absolute h-3 w-3 bg-white border-slate-200 z-[-1]' // z-index -1 保证在阴影下方,但需要父级不遮挡
|
// Update: 增加了 dark:bg-slate-800 和 dark:border-slate-700
|
||||||
|
const base = 'absolute h-3 w-3 bg-white dark:bg-slate-800 border-slate-200 dark:border-slate-700 z-[-1]'
|
||||||
|
|
||||||
// 基础偏移量
|
// 基础偏移量
|
||||||
// const centerOffset = props.arrowPointAtCenter ? 'left-1/2 -translate-x-1/2' : ''
|
|
||||||
// 如果不是 PointAtCenter,根据 Left/Right 微调箭头位置,避免靠太边
|
|
||||||
const hAlign = props.arrowPointAtCenter ? '' : (props.placement.includes('left') ? 'left-4' : props.placement.includes('right') ? 'right-4' : '')
|
const hAlign = props.arrowPointAtCenter ? '' : (props.placement.includes('left') ? 'left-4' : props.placement.includes('right') ? 'right-4' : '')
|
||||||
const vAlign = props.arrowPointAtCenter ? '' : (props.placement.includes('top') ? 'top-3' : props.placement.includes('bottom') ? 'bottom-3' : '')
|
const vAlign = props.arrowPointAtCenter ? '' : (props.placement.includes('top') ? 'top-3' : props.placement.includes('bottom') ? 'bottom-3' : '')
|
||||||
|
|
||||||
// 12个方向的箭头逻辑
|
// 12个方向的箭头逻辑
|
||||||
// 核心原理:Top 气泡,箭头在 Bottom,边框是 右下 (旋转45度)
|
|
||||||
if (props.placement.startsWith('top')) {
|
if (props.placement.startsWith('top')) {
|
||||||
return `${base} -bottom-1.5 border-b border-r rotate-45 ${props.placement === 'top' || props.arrowPointAtCenter ? 'left-1/2 -translate-x-1/2' : hAlign}`
|
return `${base} -bottom-1.5 border-b border-r rotate-45 ${props.placement === 'top' || props.arrowPointAtCenter ? 'left-1/2 -translate-x-1/2' : hAlign}`
|
||||||
}
|
}
|
||||||
|
|
@ -145,7 +143,7 @@ const arrowPositionClass = computed(() => {
|
||||||
return ''
|
return ''
|
||||||
})
|
})
|
||||||
|
|
||||||
// 3. 过渡动画方向 (Transform Origin)
|
// 3. 过渡动画方向
|
||||||
const transitionOriginClass = computed(() => {
|
const transitionOriginClass = computed(() => {
|
||||||
if (props.placement.startsWith('top'))
|
if (props.placement.startsWith('top'))
|
||||||
return 'origin-bottom'
|
return 'origin-bottom'
|
||||||
|
|
@ -162,9 +160,13 @@ const transitionOriginClass = computed(() => {
|
||||||
const okBtnClass = computed(() => {
|
const okBtnClass = computed(() => {
|
||||||
const base = 'rounded px-3 py-1 text-xs text-white transition-colors'
|
const base = 'rounded px-3 py-1 text-xs text-white transition-colors'
|
||||||
switch (props.okType) {
|
switch (props.okType) {
|
||||||
case 'danger': return `${base} bg-red-500 hover:bg-red-600 border border-red-500`
|
case 'danger':
|
||||||
case 'default': return 'rounded px-3 py-1 text-xs text-slate-600 border border-slate-200 hover:border-blue-400 hover:text-blue-500 transition-colors bg-white'
|
return `${base} bg-red-500 hover:bg-red-600 border border-red-500`
|
||||||
default: return `${base} bg-blue-600 hover:bg-blue-700 border border-blue-600`
|
case 'default':
|
||||||
|
// Update: 默认按钮在暗色模式下背景透明/深色,文字变浅,边框变深
|
||||||
|
return 'rounded px-3 py-1 text-xs text-slate-600 dark:text-slate-300 border border-slate-200 dark:border-slate-600 hover:border-blue-400 hover:text-blue-500 transition-colors bg-white dark:bg-slate-800'
|
||||||
|
default:
|
||||||
|
return `${base} bg-blue-600 hover:bg-blue-700 border border-blue-600`
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
@ -187,8 +189,13 @@ const okBtnClass = computed(() => {
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
v-if="isVisible"
|
v-if="isVisible"
|
||||||
class="absolute z-50 w-45 cursor-default border border-slate-200 rounded-lg bg-white p-3 shadow-xl"
|
class="absolute z-50 w-45 cursor-default border rounded-lg p-3 shadow-xl"
|
||||||
:class="[overlayPositionClass, transitionOriginClass]"
|
:class="[
|
||||||
|
overlayPositionClass,
|
||||||
|
transitionOriginClass,
|
||||||
|
// Update: 容器背景、边框适配 Dark Mode
|
||||||
|
'bg-white dark:bg-slate-800 border-slate-200 dark:border-slate-700'
|
||||||
|
]"
|
||||||
@click.stop
|
@click.stop
|
||||||
>
|
>
|
||||||
<!-- Arrow -->
|
<!-- Arrow -->
|
||||||
|
|
@ -198,18 +205,20 @@ const okBtnClass = computed(() => {
|
||||||
<div class="relative z-10 flex items-start gap-3">
|
<div class="relative z-10 flex items-start gap-3">
|
||||||
<div class="mt-0.5 flex-shrink-0">
|
<div class="mt-0.5 flex-shrink-0">
|
||||||
<slot name="icon">
|
<slot name="icon">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 text-orange-500" viewBox="0 0 20 20" fill="currentColor">
|
<!-- Update: Icon 颜色微调适配暗色 -->
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 text-orange-500 dark:text-orange-400" viewBox="0 0 20 20" fill="currentColor">
|
||||||
<path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z" clip-rule="evenodd" />
|
<path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z" clip-rule="evenodd" />
|
||||||
</svg>
|
</svg>
|
||||||
</slot>
|
</slot>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-1">
|
<div class="flex-1">
|
||||||
<div class="break-words text-sm text-slate-800 font-bold">
|
<!-- Update: 文字颜色适配 -->
|
||||||
|
<div class="break-words text-sm font-bold text-slate-800 dark:text-slate-100">
|
||||||
<slot name="title">
|
<slot name="title">
|
||||||
{{ title }}
|
{{ title }}
|
||||||
</slot>
|
</slot>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="description || $slots.description" class="mt-1 break-words text-xs text-slate-500">
|
<div v-if="description || $slots.description" class="mt-1 break-words text-xs text-slate-500 dark:text-slate-400">
|
||||||
<slot name="description">
|
<slot name="description">
|
||||||
{{ description }}
|
{{ description }}
|
||||||
</slot>
|
</slot>
|
||||||
|
|
@ -222,7 +231,12 @@ const okBtnClass = computed(() => {
|
||||||
<slot name="cancelButton">
|
<slot name="cancelButton">
|
||||||
<button
|
<button
|
||||||
v-if="showCancel"
|
v-if="showCancel"
|
||||||
class="rounded px-2 py-1 text-xs text-slate-500 transition-colors hover:bg-slate-100"
|
class="rounded px-2 py-1 text-xs transition-colors"
|
||||||
|
:class="[
|
||||||
|
// Update: 取消按钮颜色适配
|
||||||
|
'text-slate-500 dark:text-slate-400',
|
||||||
|
'hover:bg-slate-100 dark:hover:bg-slate-700'
|
||||||
|
]"
|
||||||
:disabled="cancelButtonProps.disabled"
|
:disabled="cancelButtonProps.disabled"
|
||||||
@click="handleCancel"
|
@click="handleCancel"
|
||||||
>
|
>
|
||||||
|
|
@ -248,4 +262,4 @@ const okBtnClass = computed(() => {
|
||||||
</div>
|
</div>
|
||||||
</Transition>
|
</Transition>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -801,7 +801,7 @@ function deletePlan(planId: string) {
|
||||||
<!-- 注意:bg-white 是为了遮挡滚动的文字,group-hover:bg-slate-50 是为了保持 hover 效果 -->
|
<!-- 注意:bg-white 是为了遮挡滚动的文字,group-hover:bg-slate-50 是为了保持 hover 效果 -->
|
||||||
<td
|
<td
|
||||||
rowspan="4"
|
rowspan="4"
|
||||||
class="sticky left-0 z-20 border-r border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-900 p-4 align-top shadow-[4px_0_8px_-4px_rgba(0,0,0,0.1)] group-hover:bg-slate-50 dark:group-hover:bg-slate-800/50"
|
class="sticky left-0 z-20 border-r border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-900 p-4 align-top shadow-[4px_0_8px_-4px_rgba(0,0,0,0.1)] group-hover:bg-slate-50 dark:group-hover:bg-slate-800"
|
||||||
>
|
>
|
||||||
<div class="mb-1 w-52 truncate text-left text-base text-slate-900 dark:text-slate-100 font-bold" :title="school.schoolName">
|
<div class="mb-1 w-52 truncate text-left text-base text-slate-900 dark:text-slate-100 font-bold" :title="school.schoolName">
|
||||||
{{ school.schoolName }}
|
{{ school.schoolName }}
|
||||||
|
|
@ -831,7 +831,7 @@ function deletePlan(planId: string) {
|
||||||
|
|
||||||
<td
|
<td
|
||||||
rowspan="4"
|
rowspan="4"
|
||||||
class="border-r border-slate-100 bg-white p-2 text-center align-top group-hover:bg-slate-50"
|
class="border-r border-slate-100 dark:border-slate-800 bg-white dark:bg-slate-900 p-2 text-center align-top group-hover:bg-slate-50 dark:group-hover:bg-slate-800"
|
||||||
>
|
>
|
||||||
<div class="mb-2 text-lg font-bold text-slate-900 dark:text-slate-100">
|
<div class="mb-2 text-lg font-bold text-slate-900 dark:text-slate-100">
|
||||||
{{ school.enrollProbability }}%
|
{{ school.enrollProbability }}%
|
||||||
|
|
@ -851,7 +851,7 @@ function deletePlan(planId: string) {
|
||||||
|
|
||||||
<td
|
<td
|
||||||
rowspan="4"
|
rowspan="4"
|
||||||
class="border-r border-slate-100 bg-white p-2 text-center align-top group-hover:bg-slate-50"
|
class="border-r border-slate-100 dark:border-slate-800 bg-white dark:bg-slate-900 p-2 text-center align-top group-hover:bg-slate-50 dark:group-hover:bg-slate-800"
|
||||||
>
|
>
|
||||||
<div class="text-lg font-medium text-slate-900 dark:text-slate-100">
|
<div class="text-lg font-medium text-slate-900 dark:text-slate-100">
|
||||||
{{ school.planNum }}人
|
{{ school.planNum }}人
|
||||||
|
|
@ -870,7 +870,7 @@ function deletePlan(planId: string) {
|
||||||
<!-- Sticky Right: 操作 -->
|
<!-- Sticky Right: 操作 -->
|
||||||
<td
|
<td
|
||||||
rowspan="4"
|
rowspan="4"
|
||||||
class="sticky right-0 z-20 border-l border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-900 p-4 text-center align-middle shadow-[-4px_0_8px_-4px_rgba(0,0,0,0.1)] group-hover:bg-slate-50 dark:group-hover:bg-slate-800/50"
|
class="sticky right-0 z-20 border-l border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-900 p-4 text-center align-middle shadow-[-4px_0_8px_-4px_rgba(0,0,0,0.1)] group-hover:bg-slate-50 dark:group-hover:bg-slate-800"
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
class="whitespace-nowrap border border-blue-500 rounded-full bg-white dark:bg-slate-900 px-3 py-1.5 text-xs text-blue-500 dark:text-blue-400 transition-colors hover:bg-blue-50 dark:hover:bg-blue-900/20"
|
class="whitespace-nowrap border border-blue-500 rounded-full bg-white dark:bg-slate-900 px-3 py-1.5 text-xs text-blue-500 dark:text-blue-400 transition-colors hover:bg-blue-50 dark:hover:bg-blue-900/20"
|
||||||
|
|
@ -1272,7 +1272,7 @@ function deletePlan(planId: string) {
|
||||||
省内招生人数
|
省内招生人数
|
||||||
</th>
|
</th>
|
||||||
<th
|
<th
|
||||||
class="sticky right-0 bg-slate-100 px-6 py-3 text-center shadow-[-4px_0_8px_-4px_rgba(0,0,0,0.1)]"
|
class="sticky right-0 px-6 py-3 text-center shadow-[-4px_0_8px_-4px_rgba(0,0,0,0.1)]"
|
||||||
>
|
>
|
||||||
加入志愿
|
加入志愿
|
||||||
</th>
|
</th>
|
||||||
|
|
@ -1325,7 +1325,7 @@ function deletePlan(planId: string) {
|
||||||
|
|
||||||
<!-- 操作列:加入/移除 -->
|
<!-- 操作列:加入/移除 -->
|
||||||
<td
|
<td
|
||||||
class="sticky right-0 bg-white dark:bg-slate-900 px-6 py-4 text-center shadow-[-4px_0_8px_-4px_rgba(0,0,0,0.1)] group-hover:bg-blue-50/30 dark:group-hover:bg-blue-900/10"
|
class="sticky right-0 border-l border-slate-100 dark:border-slate-800 bg-white dark:bg-slate-900 px-6 py-4 text-center shadow-[-4px_0_8px_-4px_rgba(0,0,0,0.1)] group-hover:bg-blue-50 dark:group-hover:bg-slate-800"
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
class="min-w-[90px] rounded-full px-3 py-1.5 text-xs font-medium transition-all duration-200"
|
class="min-w-[90px] rounded-full px-3 py-1.5 text-xs font-medium transition-all duration-200"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue