feat(theme): 完善顶部导航栏与底部菜单浅色暖色系适配及多端Tab生命周期同步

这个提交包含在:
wikiboss
2026-09-16 20:27:07 +08:00
父节点 9641dfba47
当前提交 1a56ba2682
共有 8 个文件被更改,包括 370 次插入 和 14 次删除

查看文件

@@ -10,6 +10,18 @@ export const THEME_KEYS = {
export type ThemeKey = (typeof THEME_KEYS)[keyof typeof THEME_KEYS];
export interface NavBarThemeTokens {
backgroundColor: string;
frontColor: '#ffffff' | '#000000';
}
export interface TabBarThemeTokens {
color: string;
selectedColor: string;
backgroundColor: string;
borderStyle: 'white' | 'black';
}
export interface ThemeTokens {
bgPrimary: string;
bgSurface: string;
@@ -26,6 +38,8 @@ export interface ThemeTokens {
textSecondary: string;
textMuted: string;
shadowBrand: string;
navBar: NavBarThemeTokens;
tabBar: TabBarThemeTokens;
}
export interface ThemeItem {
@@ -55,7 +69,17 @@ export const THEMES: Record<ThemeKey, ThemeItem> = {
textPrimary: '#F8FAFC',
textSecondary: '#94A3B8',
textMuted: '#64748B',
shadowBrand: '0 8rpx 24rpx rgba(99, 102, 241, 0.35)'
shadowBrand: '0 8rpx 24rpx rgba(99, 102, 241, 0.35)',
navBar: {
backgroundColor: '#0A0F1D',
frontColor: '#ffffff'
},
tabBar: {
color: '#94A3B8',
selectedColor: '#6366F1',
backgroundColor: '#151D30',
borderStyle: 'black'
}
}
},
[THEME_KEYS.WARM]: {
@@ -77,7 +101,17 @@ export const THEMES: Record<ThemeKey, ThemeItem> = {
textPrimary: '#1C1917',
textSecondary: '#57534E',
textMuted: '#78716C',
shadowBrand: '0 8rpx 24rpx rgba(234, 88, 12, 0.25)'
shadowBrand: '0 8rpx 24rpx rgba(234, 88, 12, 0.25)',
navBar: {
backgroundColor: '#FDFBF7',
frontColor: '#000000'
},
tabBar: {
color: '#78716C',
selectedColor: '#EA580C',
backgroundColor: '#FFFFFF',
borderStyle: 'white'
}
}
}
};

查看文件

@@ -158,4 +158,78 @@ describe('ThemeManager (TDD 测试套件: 暖色系与双主题设计系统)', (
}
});
});
describe('5. 顶部导航栏 (NavBar) 与底部菜单 (TabBar) 双主题规范校验', () => {
it('冷色系 NavBar 必须为深色黑底白字,TabBar 必须为深蓝卡片底', () => {
const coolTheme = THEMES[THEME_KEYS.COOL];
expect(coolTheme.tokens.navBar).toBeDefined();
expect(coolTheme.tokens.navBar.backgroundColor).toBe('#0A0F1D');
expect(coolTheme.tokens.navBar.frontColor).toBe('#ffffff');
expect(coolTheme.tokens.tabBar).toBeDefined();
expect(coolTheme.tokens.tabBar.backgroundColor).toBe('#151D30');
expect(coolTheme.tokens.tabBar.selectedColor).toBe('#6366F1');
});
it('浅色暖阳晨曦模式下,顶部 NavBar 与底部 TabBar 必须全部为浅色亮底', () => {
const warmTheme = THEMES[THEME_KEYS.WARM];
expect(warmTheme.tokens.navBar).toBeDefined();
expect(warmTheme.tokens.tabBar).toBeDefined();
// 顶部 NavBar 浅色底 (亮度 >= 0.85),文字为深黑 (#000000)
expect(getLuminance(warmTheme.tokens.navBar.backgroundColor)).toBeGreaterThanOrEqual(0.85);
expect(warmTheme.tokens.navBar.frontColor).toBe('#000000');
// 底部 TabBar 浅色底 (纯白或米白,亮度 >= 0.95),选中项高亮为曜橙
expect(getLuminance(warmTheme.tokens.tabBar.backgroundColor)).toBeGreaterThanOrEqual(0.95);
expect(warmTheme.tokens.tabBar.selectedColor).toBe('#EA580C');
expect(warmTheme.tokens.tabBar.borderStyle).toBe('white');
});
});
describe('6. 核心 Tab 页面多端生命周期与主题自适应门禁校验', () => {
const rootDir = path.resolve(__dirname, '../../');
const tabPages = [
path.join(rootDir, 'pwuniapp', 'pages', 'index', 'index.vue'),
path.join(rootDir, 'pwuniapp', 'pages', 'activity', 'list.vue'),
path.join(rootDir, 'pwuniapp', 'pages', 'order', 'list.vue'),
path.join(rootDir, 'pwuniapp', 'pages', 'user', 'index.vue'),
];
it('四大 Tab 页面必须全部引入并在 onShow 中调用 applyThemeToNativeUI', () => {
for (const pagePath of tabPages) {
expect(fs.existsSync(pagePath)).toBe(true);
const content = fs.readFileSync(pagePath, 'utf-8');
const relativeName = path.relative(rootDir, pagePath);
expect({
file: relativeName,
hasApplyTheme: content.includes('applyThemeToNativeUI'),
hasOnShow: content.includes('onShow')
}).toEqual({
file: relativeName,
hasApplyTheme: true,
hasOnShow: true
});
}
});
it('四大 Tab 页面必须包含 theme-warm 根容器类绑定与浅色样式适配', () => {
for (const pagePath of tabPages) {
const content = fs.readFileSync(pagePath, 'utf-8');
const relativeName = path.relative(rootDir, pagePath);
expect({
file: relativeName,
hasThemeWarmBind: content.includes('theme-warm'),
hasThemeWarmStyle: content.includes('.theme-warm')
}).toEqual({
file: relativeName,
hasThemeWarmBind: true,
hasThemeWarmStyle: true
});
}
});
});
});