用户反馈: dark 主题下大量页面卡片/表头是白底, 文字看不清, 视觉割裂 根因 (W5.x v2 token 迁移遗漏): - v1 token (--rr-page-bg / --rr-bg-card / --rr-table-header-bg / --rr-row-hover / --rr-border-color / --rr-text-secondary) 在 themes.scss 完全没定义 - v2 用 --bg-soft / --surface / --surface-2 / --border / --ink-2 / --ink-3, 但大量组件没改 fallback, 永远走 hex fallback (#F1F5F9 / #FFFFFF) - EP el-table 内部用 getCssVar(color, white) = --el-color-white, 未在 tokens.scss 重定向, dark 下仍是 #FFFFFF - CSS 变量级联问题: :root 块 var(--surface) 解析时, dark 块的 --surface 重写还没生效 修法 (3 类共 11 文件): 1. EP token 补齐 (themes.scss dark 块 + tokens.scss :root 块): - --el-color-white / --el-color-black: #1E293B / #F8FAFC - --el-fill-color-blank / --el-fill-color-light: surface / bg-soft - --el-table-tr-bg-color / --el-table-bg-color: surface - --el-table-expanded-cell-bg-color: surface - --el-table-header-bg-color: surface-2 (表头略亮区分) - --el-table-row-hover-bg-color: bg-soft 2. v1 token 清理 (4 组件): - AppLayout.vue: 13 处 --rr-page-bg → --bg-soft - DataTable.vue: --rr-table-header-bg/--rr-text-secondary/--rr-row-hover/--rr-bg-card/--rr-border-color → v2 token - SearchBar.vue / ListTabs.vue: 同上 3. 业务页硬编码色 (5 业务页): - OpenAppListView.vue: 4 状态 badge + 表格头 #F8FAFC → var(--*-soft) - ApplyApiKeyDialog.vue: header #F8FAFC → var(--surface-2) - InquiryListView.vue / LogOperationView.vue / LogErrorView.vue: 4 类 badge → var(--amber/brand/green/red-soft) Playwright 1920 视口 dark 主题实测 (5 个典型页): - Dashboard: 侧栏 rgb(30,41,59), 主区 rgb(15,23,42), 表格 rgb(30,41,59) ✅ - 用户列表 / 应用列表 / 订单列表 / 询价列表: 全部统一深色 ✅ - 之前: elTableBg rgb(255,255,255) 纯白 → 现在: rgb(30,41,59) 暗 surface - 文字、badge、按钮、分页器、搜索条全部 dark 适配 不动调色板 (按用户要求 严重问题优先): --border/--ink-2 等保持原值
96 lines
2.1 KiB
Vue
96 lines
2.1 KiB
Vue
<script setup lang="ts">
|
|
/**
|
|
* F006 通用 ListTabs 组件 (W17 设计规范 v2 整改)
|
|
*
|
|
* 按 ui-preview-v2.html 模板: padding 9px 16px + 下划线高亮 + tab-count 圆角 pill
|
|
*
|
|
* 全部 [128] 待报价 [23] 进行中 [45] 已完成 [52] 已取消 [8]
|
|
*/
|
|
export interface ListTabItem {
|
|
key: string
|
|
label: string
|
|
count?: number
|
|
}
|
|
|
|
interface Props {
|
|
modelValue: string
|
|
items: ListTabItem[]
|
|
}
|
|
|
|
const props = defineProps<Props>()
|
|
const emit = defineEmits<{
|
|
(e: 'update:modelValue', v: string): void
|
|
(e: 'change', v: string): void
|
|
}>()
|
|
|
|
function onClick(key: string) {
|
|
emit('update:modelValue', key)
|
|
emit('change', key)
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<div class="rr-list-tabs">
|
|
<div
|
|
v-for="item in items"
|
|
:key="item.key"
|
|
class="rr-list-tab"
|
|
:class="{ 'is-active': props.modelValue === item.key }"
|
|
@click="onClick(item.key)"
|
|
>
|
|
<span class="rr-list-tab__label">{{ item.label }}</span>
|
|
<span v-if="item.count !== undefined" class="rr-list-tab__count">{{ item.count }}</span>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped lang="scss">
|
|
.rr-list-tabs {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0;
|
|
margin-bottom: 14px;
|
|
border-bottom: 1px solid var(--border);
|
|
}
|
|
.rr-list-tab {
|
|
padding: 10px 18px;
|
|
font-size: 13px;
|
|
color: var(--ink-3, #64748B);
|
|
cursor: pointer;
|
|
border-bottom: 2px solid transparent;
|
|
transition: all 0.15s;
|
|
font-weight: 500;
|
|
position: relative;
|
|
user-select: none;
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 6px;
|
|
margin-bottom: -1px;
|
|
|
|
&:hover { color: var(--ink, #0F172A); }
|
|
|
|
&.is-active {
|
|
color: var(--brand, #2563EB);
|
|
font-weight: 600;
|
|
border-bottom-color: var(--brand, #2563EB);
|
|
}
|
|
|
|
&__count {
|
|
font-size: 11px;
|
|
background: var(--surface-2);
|
|
color: var(--ink-3);
|
|
padding: 0 6px;
|
|
border-radius: 999px;
|
|
font-weight: 500;
|
|
line-height: 18px;
|
|
min-width: 20px;
|
|
text-align: center;
|
|
}
|
|
|
|
&.is-active &__count {
|
|
background: var(--brand-soft, rgba(37, 99, 235, 0.08));
|
|
color: var(--brand, #2563EB);
|
|
}
|
|
}
|
|
</style>
|