Files
console-dev/app/config/openvue.js
T
2026-11-07 07:08:48 +08:00

87 lines
2.9 KiB
JavaScript

/** OpenVue 客户端统一配置:中文交互文案、蓝色主色以及 .app-dark 暗色切换。 */
import { definePreset } from "@openvue/themes";
import Aura from "@openvue/themes/aura";
import { normalizeStyle } from "vue";
import locale from "./locale.zh-CN.json";
// 列宽只取声明,不让接口数据、骨架或空态参与浏览器的自动列宽分配。
// 百分比宽度原来用于自动布局的伸缩提示;固定布局改用原有最小宽度或统一默认宽度。
function columnWidth(props) {
const style = normalizeStyle([props.style, props.headerStyle]) ?? {};
const width =
style.width && !String(style.width).includes("%") ? style.width : undefined;
const minimum = style.minWidth ?? style["min-width"];
return width && minimum
? `max(${width}, ${minimum})`
: width || minimum || "12rem";
}
// 使用 MIT 许可的主题包,并采用控制台的 blue/slate/zinc 配色。
// 只覆盖 Aura 的语义色阶,保留组件自身设计令牌;浅色用 slate,深色用 zinc。
const preset = definePreset(Aura, {
semantic: {
primary: Object.fromEntries(
[50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950].map((shade) => [
shade,
`{blue.${shade}}`,
]),
),
colorScheme: {
light: {
// 普通字号白字按钮至少4.5:1;浅色主色从blue-600起,hover/active继续加深,暗色令牌不变。
primary: {
color: "{primary.600}",
contrastColor: "#ffffff",
hoverColor: "{primary.700}",
activeColor: "{primary.800}",
},
surface: Object.fromEntries(
[0, 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950].map(
(shade) => [shade, shade === 0 ? "#ffffff" : `{slate.${shade}}`],
),
),
},
dark: {
surface: Object.fromEntries(
[0, 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950].map(
(shade) => [shade, shade === 0 ? "#ffffff" : `{zinc.${shade}}`],
),
),
},
},
},
});
export default {
ripple: true,
locale,
theme: { preset, options: { darkModeSelector: ".app-dark" } },
// 列标题与单元格同次渲染,移除手机卡片对后补布局标签的依赖。
pt: {
datatable: {
table: ({ instance }) => ({
style: {
tableLayout: "fixed",
width: "100%",
minWidth: `calc(${
(instance.columns ?? [])
.filter((column) => !column.props?.hidden)
.map((column) => columnWidth(column.props ?? {}))
.join(" + ") || "0px"
})`,
},
}),
column: {
headerCell: ({ props }) => ({
style: { width: columnWidth(props) },
}),
bodyCell: ({ props }) => ({
style: { width: columnWidth(props) },
"data-label":
typeof props.header === "string" ? props.header.trim() : "",
}),
},
},
},
};