style: 全站使用背景分层替代装饰边框并统一直角
This commit is contained in:
@@ -89,7 +89,7 @@ describe('微信风格明暗主题', () => {
|
||||
|
||||
it.each([false, true])('明暗模式 %s 的组件表面、语义色与业务 CSS 一致,主要文字保持可读', dark => {
|
||||
const state = setup(dark)
|
||||
const { common, Menu, Button, Layout } = state.overrides.value
|
||||
const { common, Menu, Button, Layout, Input, Select } = state.overrides.value
|
||||
const css = readFileSync('src/admin.css', 'utf8')
|
||||
const lightTokens = css.match(/:root\s*\{([^}]+)\}/)![1]!
|
||||
const darkTokens = css.match(/:root\[data-theme='dark'\]\s*\{([^}]+)\}/)![1]!
|
||||
@@ -119,8 +119,13 @@ describe('微信风格明暗主题', () => {
|
||||
itemColorActiveCollapsed: tokens.selected,
|
||||
itemTextColorActive: tokens['accent-text']
|
||||
})
|
||||
// 圆角调整只用于导航,表单、普通按钮和弹窗仍保留原有主题。
|
||||
expect(common?.borderRadius).toBe('6px')
|
||||
// 全站直角;输入区域与普通按钮共享底色,保持明暗模式一致。
|
||||
expect(common?.borderRadius).toBe('0px')
|
||||
expect(common?.borderRadiusSmall).toBe('0px')
|
||||
expect(Input?.color).toBe(tokens.control)
|
||||
expect(Button?.color).toBe(tokens.control)
|
||||
expect(Button?.colorHover).toBe(tokens['control-hover'])
|
||||
expect(Select?.peers?.InternalSelection?.color).toBe(tokens.control)
|
||||
expect(Button?.textColorPrimary).toBe(tokens['on-accent'])
|
||||
for (const background of [common!.primaryColor!, common!.primaryColorHover!, common!.primaryColorPressed!]) {
|
||||
expect(contrast(String(Button!.textColorPrimary), background)).toBeGreaterThanOrEqual(4.5)
|
||||
|
||||
@@ -39,6 +39,18 @@ export function useTheme() {
|
||||
const info = dark ? '#91a8d2' : '#576b95'
|
||||
const danger = dark ? '#fa7373' : '#a93232'
|
||||
const warning = dark ? '#e8b66a' : '#916019'
|
||||
const control = dark ? '#2b2b2b' : '#f0f0f0'
|
||||
const controlHover = dark ? '#353535' : '#e5e5e5'
|
||||
// 静态边界交给底色;聚焦与错误边框仍由控件的状态主题负责。
|
||||
const focusBorder = `1px solid ${accentText}`
|
||||
const selection = {
|
||||
color: control,
|
||||
colorActive: control,
|
||||
border: 'none',
|
||||
borderHover: 'none',
|
||||
borderFocus: focusBorder,
|
||||
borderActive: focusBorder
|
||||
}
|
||||
return {
|
||||
common: {
|
||||
primaryColor: primary,
|
||||
@@ -61,7 +73,8 @@ export function useTheme() {
|
||||
warningColorHover: warning,
|
||||
warningColorPressed: warning,
|
||||
warningColorSuppl: warning,
|
||||
borderRadius: '6px',
|
||||
borderRadius: '0px',
|
||||
borderRadiusSmall: '0px',
|
||||
bodyColor: body,
|
||||
cardColor: surface,
|
||||
modalColor: surface,
|
||||
@@ -80,6 +93,15 @@ export function useTheme() {
|
||||
"-apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Microsoft YaHei', sans-serif"
|
||||
},
|
||||
Button: {
|
||||
color: control,
|
||||
colorHover: controlHover,
|
||||
colorPressed: controlHover,
|
||||
colorFocus: controlHover,
|
||||
border: 'none',
|
||||
borderHover: 'none',
|
||||
borderPressed: 'none',
|
||||
borderDisabled: 'none',
|
||||
borderFocus: focusBorder,
|
||||
textColorPrimary: onPrimary,
|
||||
textColorHoverPrimary: onPrimary,
|
||||
textColorPressedPrimary: onPrimary,
|
||||
@@ -88,6 +110,55 @@ export function useTheme() {
|
||||
textColorTextPrimary: accentText,
|
||||
textColorGhostPrimary: accentText
|
||||
},
|
||||
Input: {
|
||||
color: control,
|
||||
colorHover: controlHover,
|
||||
colorFocus: control,
|
||||
border: 'none',
|
||||
borderHover: 'none',
|
||||
borderDisabled: 'none',
|
||||
borderFocus: focusBorder,
|
||||
groupLabelBorder: 'none'
|
||||
},
|
||||
Select: { peers: { InternalSelection: selection } },
|
||||
Card: { borderColor: 'transparent' },
|
||||
Drawer: { headerBorderBottom: 'none', footerBorderTop: 'none' },
|
||||
Alert: {
|
||||
border: 'none',
|
||||
borderInfo: 'none',
|
||||
borderSuccess: 'none',
|
||||
borderWarning: 'none',
|
||||
borderError: 'none'
|
||||
},
|
||||
Collapse: { dividerColor: 'transparent' },
|
||||
Table: {
|
||||
borderColor: 'transparent',
|
||||
borderColorModal: 'transparent',
|
||||
borderColorPopover: 'transparent',
|
||||
thColor: control,
|
||||
thColorModal: control,
|
||||
thColorPopover: control,
|
||||
tdColorStriped: subtle,
|
||||
tdColorStripedModal: subtle,
|
||||
tdColorStripedPopover: subtle
|
||||
},
|
||||
DataTable: {
|
||||
borderColor: 'transparent',
|
||||
borderColorModal: 'transparent',
|
||||
borderColorPopover: 'transparent',
|
||||
thColor: control,
|
||||
tdColorStriped: subtle,
|
||||
tdColorHover: selected
|
||||
},
|
||||
Radio: {
|
||||
buttonBorderColor: 'transparent',
|
||||
buttonBorderColorActive: 'transparent',
|
||||
buttonBorderColorHover: 'transparent',
|
||||
buttonColor: control,
|
||||
buttonColorActive: selected,
|
||||
buttonTextColorActive: accentText,
|
||||
buttonBoxShadowFocus: `inset 0 0 0 1px ${accentText}`
|
||||
},
|
||||
Layout: {
|
||||
color: body,
|
||||
headerColor: surface,
|
||||
@@ -104,12 +175,25 @@ export function useTheme() {
|
||||
itemIconColorActive: accentText,
|
||||
itemIconColorActiveHover: accentText
|
||||
},
|
||||
Tabs: { tabTextColorActiveLine: accentText, tabTextColorHoverLine: accentText, barColor: primary },
|
||||
Tag: { textColorPrimary: accentText },
|
||||
Tabs: {
|
||||
tabTextColorActiveLine: accentText,
|
||||
tabTextColorHoverLine: accentText,
|
||||
barColor: primary,
|
||||
tabBorderColor: 'transparent'
|
||||
},
|
||||
Tag: {
|
||||
textColorPrimary: accentText,
|
||||
border: 'none',
|
||||
borderPrimary: 'none',
|
||||
borderInfo: 'none',
|
||||
borderSuccess: 'none',
|
||||
borderWarning: 'none',
|
||||
borderError: 'none'
|
||||
},
|
||||
Checkbox: { checkMarkColor: onPrimary },
|
||||
Switch: { railColorActive: primary },
|
||||
Progress: { fillColor: primary }
|
||||
}
|
||||
} satisfies GlobalThemeOverrides
|
||||
})
|
||||
/** 系统切换只更新 system 模式下的实际显示。 */
|
||||
function syncSystem(event: MediaQueryListEvent) {
|
||||
|
||||
Reference in New Issue
Block a user