This commit is contained in:
xingyu4j
2025-12-26 14:00:55 +08:00
26 changed files with 447 additions and 49 deletions

View File

@@ -14,8 +14,9 @@
}
html {
@apply text-foreground bg-background font-sans text-[100%];
@apply text-foreground bg-background font-sans;
font-size: var(--font-size-base, 16px);
font-variation-settings: normal;
line-height: 1.15;
text-size-adjust: 100%;

View File

@@ -93,6 +93,7 @@
/* 基本文字大小 */
--font-size-base: 16px;
--menu-font-size: calc(var(--font-size-base) * 0.875);
/* =============component & UI============= */

View File

@@ -208,4 +208,39 @@ function treeToString(tree: any[], nodeId: number | string) {
return str;
}
export { filterTree, handleTree, mapTree, traverseTreeValues, treeToString };
/**
* 对树形结构数据进行递归排序
* @param treeData - 树形数据数组
* @param sortFunction - 排序函数,用于定义排序规则
* @param options - 配置选项,包括子节点属性名
* @returns 排序后的树形数据
*/
function sortTree<T extends Record<string, any>>(
treeData: T[],
sortFunction: (a: T, b: T) => number,
options?: TreeConfigOptions,
): T[] {
const { childProps } = options || {
childProps: 'children',
};
return treeData.toSorted(sortFunction).map((item) => {
const children = item[childProps];
if (children && Array.isArray(children) && children.length > 0) {
return {
...item,
[childProps]: sortTree(children, sortFunction, options),
};
}
return item;
});
}
export {
filterTree,
handleTree,
mapTree,
sortTree,
traverseTreeValues,
treeToString,
};

View File

@@ -113,6 +113,7 @@ exports[`defaultPreferences immutability test > should not modify the config obj
"colorPrimary": "hsl(212 100% 45%)",
"colorSuccess": "hsl(144 57% 58%)",
"colorWarning": "hsl(42 84% 61%)",
"fontSize": 16,
"mode": "dark",
"radius": "0.5",
"semiDarkHeader": false,

View File

@@ -116,6 +116,7 @@ const defaultPreferences: Preferences = {
colorWarning: 'hsl(42 84% 61%)',
mode: 'dark',
radius: '0.5',
fontSize: 16,
semiDarkHeader: false,
semiDarkSidebar: false,
},

View File

@@ -141,7 +141,10 @@ class PreferenceManager {
private handleUpdates(updates: DeepPartial<Preferences>) {
const themeUpdates = updates.theme || {};
const appUpdates = updates.app || {};
if (themeUpdates && Object.keys(themeUpdates).length > 0) {
if (
(themeUpdates && Object.keys(themeUpdates).length > 0) ||
Reflect.has(themeUpdates, 'fontSize')
) {
updateCSSVariables(this.state);
}

View File

@@ -239,6 +239,8 @@ interface ThemePreferences {
colorSuccess: string;
/** 警告色 */
colorWarning: string;
/** 字体大小单位px */
fontSize: number;
/** 当前主题 */
mode: ThemeModeType;
/** 圆角 */

View File

@@ -66,6 +66,19 @@ function updateCSSVariables(preferences: Preferences) {
if (Reflect.has(theme, 'radius')) {
document.documentElement.style.setProperty('--radius', `${radius}rem`);
}
// 更新字体大小
if (Reflect.has(theme, 'fontSize')) {
const fontSize = theme.fontSize;
document.documentElement.style.setProperty(
'--font-size-base',
`${fontSize}px`,
);
document.documentElement.style.setProperty(
'--menu-font-size',
`calc(${fontSize}px * 0.875)`,
);
}
}
/**

View File

@@ -388,7 +388,7 @@ $namespace: vben;
padding: var(--menu-item-padding-y) var(--menu-item-padding-x);
margin: 0 var(--menu-item-margin-x) var(--menu-item-margin-y)
var(--menu-item-margin-x);
font-size: var(--menu-font-size);
font-size: var(--menu-font-size) !important;
color: var(--menu-item-color);
white-space: nowrap;
text-decoration: none;
@@ -433,6 +433,7 @@ $namespace: vben;
max-width: var(--menu-title-width);
overflow: hidden;
text-overflow: ellipsis;
font-size: var(--menu-font-size) !important;
white-space: nowrap;
opacity: 1;
}
@@ -444,7 +445,7 @@ $namespace: vben;
.#{$namespace}-menu__popup-container,
.#{$namespace}-menu {
--menu-title-width: 140px;
--menu-item-icon-size: 16px;
--menu-item-icon-size: var(--font-size-base, 16px);
--menu-item-height: 38px;
--menu-item-padding-y: 21px;
--menu-item-padding-x: 12px;
@@ -458,7 +459,6 @@ $namespace: vben;
--menu-item-collapse-margin-x: 0px;
--menu-item-radius: 0px;
--menu-item-indent: 16px;
--menu-font-size: 14px;
&.is-dark {
--menu-background-color: hsl(var(--menu));
@@ -752,7 +752,7 @@ $namespace: vben;
}
.#{$namespace}-menu__icon {
display: block;
font-size: 20px !important;
font-size: calc(var(--font-size-base, 16px) * 1.25) !important;
transition: all 0.25s ease;
}
@@ -760,7 +760,7 @@ $namespace: vben;
display: inline-flex;
margin-top: 8px;
margin-bottom: 0;
font-size: 12px;
font-size: calc(var(--font-size-base, 16px) * 0.75);
font-weight: 400;
line-height: normal;
transition: all 0.25s ease;
@@ -785,7 +785,7 @@ $namespace: vben;
width: 100%;
height: 100%;
padding: 0 var(--menu-item-padding-x);
font-size: var(--menu-font-size);
font-size: var(--menu-font-size) !important;
line-height: var(--menu-item-height);
}
}
@@ -812,9 +812,14 @@ $namespace: vben;
.#{$namespace}-sub-menu-content {
height: var(--menu-item-height);
font-size: var(--menu-font-size) !important;
@include menu-item;
* {
font-size: inherit !important;
}
&__icon-arrow {
position: absolute;
top: 50%;

View File

@@ -102,7 +102,7 @@ $namespace: vben;
}
.#{$namespace}-normal-menu__icon {
font-size: 20px;
font-size: calc(var(--font-size-base, 16px) * 1.25);
}
}
@@ -146,14 +146,14 @@ $namespace: vben;
&__icon {
max-height: 20px;
font-size: 20px;
font-size: calc(var(--font-size-base, 16px) * 1.25);
transition: all 0.25s ease;
}
&__name {
margin-top: 8px;
margin-bottom: 0;
font-size: 12px;
font-size: calc(var(--font-size-base, 16px) * 0.75);
font-weight: 400;
transition: all 0.25s ease;
}