mirror of
https://github.com/Syngnat/GoNavi.git
synced 2026-08-12 17:44:14 +08:00
🎨 style(transaction): 手动事务提交按钮改用 warn 独立配色并修复待提交条数看不见
- 手动事务的「提交」按钮不再跟随主题强调色:它是需要用户显式决断的状态,与普通主操作同色时 无法区分。改用 warn 实心填充,与已是 danger 的「回滚」形成语义配对。 原先是 accent-soft 底 + accent-2 文字,同色系淡色叠淡色,文字本身对比就很低 - 修复待提交条数徽标的数字看不见:底色原为硬编码 rgba(22,163,74,.18)、文字为 --gn-accent-2, 而按钮底是 --gn-accent —— 三者几乎同色,实测对比度仅 1.10–1.17, 静止状态数字完全不可见,只有 hover 把按钮压暗后才显现(DataGrid 与 SQL 编辑器两处同病) - 新增 --gn-on-warn / --gn-warn-hover / --gn-warn-active / --gn-warn-badge-bg / --gn-accent-badge-bg。前景色按亮度择优,因为 warn 跨度很大(#9f5f1d ~ #ebcb8b); 徽标底色的叠加方向也随前景色反向偏移,写死半透明白会让浅色主题的白字只剩 2.65 - 补 3 项不变式测试:warn 标签与徽标数字对比度均 ≥4.5、warn 三态逐级加深且互不相同。 该用例已实测抓住浅色主题 warm-paper 的徽标对比不足 实测:徽标数字对比度由 1.10–1.17 提升到 ≥4.5;warn 标签 7.59–11.80。
This commit is contained in:
@@ -262,38 +262,50 @@ body[data-ui-version="v2"] .gn-v2-query-transaction-commit-button {
|
||||
display: inline-flex !important;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
border-color: transparent !important;
|
||||
background: var(--gn-accent-soft) !important;
|
||||
color: var(--gn-accent-2) !important;
|
||||
/* 待提交事务用 warn 实心填充,刻意不跟随主题强调色:
|
||||
它是需要用户显式决断的状态,与普通主操作同色时无法区分(回滚用 danger,二者语义配对)。
|
||||
原先是 accent-soft 底 + accent-2 文字,两者都是同一色系的淡色,实测文字对比极低。 */
|
||||
border-color: var(--gn-warn) !important;
|
||||
background: var(--gn-warn) !important;
|
||||
color: var(--gn-on-warn, #17130a) !important;
|
||||
font-weight: 750 !important;
|
||||
transition: background-color 120ms ease, box-shadow 120ms ease, border-color 120ms ease !important;
|
||||
}
|
||||
|
||||
body[data-ui-version="v2"] .gn-v2-query-transaction-commit-button:hover,
|
||||
body[data-ui-version="v2"] .gn-v2-query-transaction-commit-button:focus,
|
||||
body[data-ui-version="v2"] .gn-v2-query-transaction-commit-button:focus-visible,
|
||||
body[data-ui-version="v2"] .gn-v2-query-transaction-commit-button:active {
|
||||
border-color: rgba(22, 163, 74, 0.18) !important;
|
||||
background: color-mix(in srgb, var(--gn-accent-soft) 80%, rgba(22, 163, 74, 0.28)) !important;
|
||||
color: var(--gn-accent-2) !important;
|
||||
box-shadow: 0 0 0 1px rgba(22, 163, 74, 0.12), 0 6px 14px rgba(22, 163, 74, 0.12) !important;
|
||||
body[data-ui-version="v2"] .gn-v2-query-transaction-commit-button:focus-visible {
|
||||
border-color: var(--gn-warn-hover, var(--gn-warn)) !important;
|
||||
background: var(--gn-warn-hover, var(--gn-warn)) !important;
|
||||
color: var(--gn-on-warn, #17130a) !important;
|
||||
box-shadow: var(--gn-shadow-sm), inset 0 0.5px 0 rgba(255, 255, 255, 0.15) !important;
|
||||
}
|
||||
|
||||
body[data-ui-version="v2"] .gn-v2-query-transaction-commit-button:active {
|
||||
border-color: var(--gn-warn-active, var(--gn-warn)) !important;
|
||||
background: var(--gn-warn-active, var(--gn-warn)) !important;
|
||||
color: var(--gn-on-warn, #17130a) !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
/* 待提交条数徽标:底色用白色半透明叠加而非硬编码绿色,文字用 on-warn。
|
||||
原先底是 rgba(22,163,74,.18)、文字是 --gn-accent-2,与按钮底色几乎同色
|
||||
(实测对比度仅 1.10–1.17),静止状态下数字完全看不见,只有 hover 变暗后才显现。 */
|
||||
body[data-ui-version="v2"] .gn-v2-query-transaction-commit-button .gn-v2-toolbar-kbd {
|
||||
margin-left: 0;
|
||||
min-width: 18px;
|
||||
justify-content: center;
|
||||
border: none;
|
||||
background: rgba(22, 163, 74, 0.18);
|
||||
color: var(--gn-accent-2);
|
||||
background: var(--gn-warn-badge-bg, rgba(255, 255, 255, 0.35));
|
||||
color: var(--gn-on-warn, #17130a);
|
||||
}
|
||||
|
||||
body[data-ui-version="v2"] .gn-v2-query-transaction-commit-button:hover .gn-v2-toolbar-kbd,
|
||||
body[data-ui-version="v2"] .gn-v2-query-transaction-commit-button:focus .gn-v2-toolbar-kbd,
|
||||
body[data-ui-version="v2"] .gn-v2-query-transaction-commit-button:focus-visible .gn-v2-toolbar-kbd,
|
||||
body[data-ui-version="v2"] .gn-v2-query-transaction-commit-button:active .gn-v2-toolbar-kbd {
|
||||
background: rgba(22, 163, 74, 0.24);
|
||||
color: var(--gn-accent-2);
|
||||
background: var(--gn-warn-badge-bg, rgba(255, 255, 255, 0.42));
|
||||
color: var(--gn-on-warn, #17130a);
|
||||
}
|
||||
|
||||
body[data-ui-version="v2"] .gn-v2-query-toolbar-icon-action.ant-btn,
|
||||
|
||||
@@ -105,6 +105,60 @@ const parseHexColor = (value: string): [number, number, number] | null => {
|
||||
];
|
||||
};
|
||||
|
||||
const channelLuminance = (channel: number): number => {
|
||||
const c = channel / 255;
|
||||
return c <= 0.04045 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4;
|
||||
};
|
||||
|
||||
/**
|
||||
* readableOnColor 按底色亮度挑选可读的前景色。
|
||||
*
|
||||
* warn 在各预设间跨度很大(浅色主题为 #9f5f1d 这类深琥珀,深色主题为 #ebcb8b 这类浅琥珀),
|
||||
* 固定用深色或白色都会在另一端失效,因此按相对亮度择优。
|
||||
*/
|
||||
const DARK_ON_COLOR = '#17130a';
|
||||
|
||||
const readableOnColor = (background: string): string => {
|
||||
const rgb = parseHexColor(background);
|
||||
if (!rgb) {
|
||||
return '#ffffff';
|
||||
}
|
||||
const relativeLuminance = (channels: [number, number, number]): number => (
|
||||
0.2126 * channelLuminance(channels[0])
|
||||
+ 0.7152 * channelLuminance(channels[1])
|
||||
+ 0.0722 * channelLuminance(channels[2])
|
||||
);
|
||||
const contrast = (a: number, b: number): number => {
|
||||
const [hi, lo] = a >= b ? [a, b] : [b, a];
|
||||
return (hi + 0.05) / (lo + 0.05);
|
||||
};
|
||||
|
||||
const backgroundLuminance = relativeLuminance(rgb);
|
||||
const darkRgb = parseHexColor(DARK_ON_COLOR);
|
||||
const darkContrast = darkRgb
|
||||
? contrast(backgroundLuminance, relativeLuminance(darkRgb))
|
||||
: 1;
|
||||
const whiteContrast = contrast(backgroundLuminance, 1);
|
||||
return darkContrast >= whiteContrast ? DARK_ON_COLOR : '#ffffff';
|
||||
};
|
||||
|
||||
/**
|
||||
* badgeBackground 计算「按钮内计数徽标」的底色。
|
||||
*
|
||||
* 叠加方向必须跟随前景色,不能写死成半透明白:
|
||||
* warn 在浅色主题下是深琥珀(#9f5f1d),前景色随之取白,此时若把徽标底往白色叠加,
|
||||
* 白字只剩 2.65 的对比度;反之深色主题的浅琥珀底配深字,则必须往白色叠加。
|
||||
* 因此按前景色是深还是浅,决定徽标底往相反方向偏移。
|
||||
*/
|
||||
const badgeBackground = (base: string, onColor: string): string => {
|
||||
const rgb = parseHexColor(onColor);
|
||||
// 前景偏深时把徽标底往白色偏移,前景偏浅(白字)时往黑色偏移。
|
||||
const onIsDark = rgb
|
||||
? 0.2126 * channelLuminance(rgb[0]) + 0.7152 * channelLuminance(rgb[1]) + 0.0722 * channelLuminance(rgb[2]) < 0.5
|
||||
: true;
|
||||
return mixHex(base, onIsDark ? '#ffffff' : '#000000', 0.65);
|
||||
};
|
||||
|
||||
/** mixHex 按 ratio 保留 accent、其余混入 towards,返回十六进制。 */
|
||||
const mixHex = (accent: string, towards: string, ratio: number): string => {
|
||||
const a = parseHexColor(accent);
|
||||
@@ -177,6 +231,15 @@ body[data-custom-theme][data-ui-version="v2"] {
|
||||
--gn-accent-hover: ${mixHex(palette.accent, accentStateAnchor(palette), ACCENT_HOVER_RATIO)};
|
||||
--gn-accent-active: ${mixHex(palette.accent, accentStateAnchor(palette), ACCENT_ACTIVE_RATIO)};
|
||||
|
||||
/* 手动事务的「提交」按钮刻意不跟随主题强调色:待提交事务是需要用户显式决断的状态,
|
||||
若与普通主操作同色则无法区分(回滚已用 danger,提交用 warn 形成语义配对)。
|
||||
on-warn 按亮度择优,因为 warn 在各预设间跨度很大(#9f5f1d ~ #ebcb8b)。 */
|
||||
--gn-on-warn: ${readableOnColor(palette.warn)};
|
||||
--gn-warn-hover: ${mixHex(palette.warn, accentStateAnchor(palette), ACCENT_HOVER_RATIO)};
|
||||
--gn-warn-active: ${mixHex(palette.warn, accentStateAnchor(palette), ACCENT_ACTIVE_RATIO)};
|
||||
--gn-warn-badge-bg: ${badgeBackground(palette.warn, readableOnColor(palette.warn))};
|
||||
--gn-accent-badge-bg: ${badgeBackground(palette.accent, palette.onAccent)};
|
||||
|
||||
--gn-ant-primary: ${palette.accent};
|
||||
--gn-ant-primary-hover: ${mixHex(palette.accent, accentStateAnchor(palette), ACCENT_HOVER_RATIO)};
|
||||
--gn-ant-primary-active: ${mixHex(palette.accent, accentStateAnchor(palette), ACCENT_ACTIVE_RATIO)};
|
||||
|
||||
@@ -102,3 +102,48 @@ describe('内置主题的主要操作按钮三态', () => {
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* 手动事务「提交」按钮用 warn 实心填充,刻意不跟随主题强调色。
|
||||
* 回归背景:原先用 accent-soft 底 + accent-2 文字,与普通主操作同色系且文字对比极低;
|
||||
* 待提交条数徽标更是用硬编码绿底 + accent-2 文字,实测对比度仅 1.10–1.17,
|
||||
* 静止状态下数字完全看不见,只有 hover 把按钮压暗后才显现。
|
||||
*/
|
||||
describe('手动事务提交按钮的 warn 配色', () => {
|
||||
it('warn 前景色在每个主题下都达到正文可读级(≥4.5)', () => {
|
||||
for (const preset of BUILTIN_CUSTOM_THEME_PRESETS) {
|
||||
const warn = readToken(preset.css, '--gn-warn');
|
||||
const onWarn = readToken(preset.css, '--gn-on-warn');
|
||||
expect(
|
||||
contrastRatio(onWarn, warn),
|
||||
`${preset.id} 的 warn 标签对比度不足`,
|
||||
).toBeGreaterThanOrEqual(4.5);
|
||||
}
|
||||
});
|
||||
|
||||
it('待提交条数徽标的数字在静止状态即可读(≥4.5)', () => {
|
||||
for (const preset of BUILTIN_CUSTOM_THEME_PRESETS) {
|
||||
const onWarn = readToken(preset.css, '--gn-on-warn');
|
||||
const badgeHex = readToken(preset.css, '--gn-warn-badge-bg');
|
||||
expect(
|
||||
contrastRatio(onWarn, badgeHex),
|
||||
`${preset.id} 的徽标数字对比度不足`,
|
||||
).toBeGreaterThanOrEqual(4.5);
|
||||
}
|
||||
});
|
||||
|
||||
it('warn 的三态同样逐级加深且互不相同', () => {
|
||||
for (const preset of BUILTIN_CUSTOM_THEME_PRESETS) {
|
||||
const warn = readToken(preset.css, '--gn-warn');
|
||||
const hover = readToken(preset.css, '--gn-warn-hover');
|
||||
const active = readToken(preset.css, '--gn-warn-active');
|
||||
|
||||
expect(hover, `${preset.id} 的 warn hover 不应等于基色`).not.toBe(warn);
|
||||
expect(active, `${preset.id} 的 warn active 不应等于 hover`).not.toBe(hover);
|
||||
expect(
|
||||
contrastRatio(warn, hover),
|
||||
`${preset.id} 的 warn base→hover 对比度不足`,
|
||||
).toBeGreaterThanOrEqual(MIN_STATE_DELTA);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -4091,10 +4091,21 @@ body[data-ui-version="v2"] .gn-v2-data-grid .gn-v2-commit-button:disabled {
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
/* 待提交条数徽标:底色改用白色半透明叠加、文字改用 on-accent。
|
||||
原先底是硬编码的 rgba(22,163,74,.18)、文字是 --gn-accent-2,
|
||||
而按钮底色是 --gn-accent —— 三者几乎同色(实测对比度仅 1.10–1.17),
|
||||
静止状态下数字完全看不见,只有 hover 把按钮压暗后才显现。 */
|
||||
body[data-ui-version="v2"] .gn-v2-data-grid .gn-v2-commit-button .gn-v2-toolbar-kbd {
|
||||
border: none;
|
||||
background: rgba(22, 163, 74, 0.18);
|
||||
color: var(--gn-accent-2);
|
||||
background: var(--gn-accent-badge-bg, rgba(255, 255, 255, 0.35));
|
||||
color: var(--gn-on-accent, #17130a);
|
||||
}
|
||||
|
||||
body[data-ui-version="v2"] .gn-v2-data-grid .gn-v2-commit-button:hover .gn-v2-toolbar-kbd,
|
||||
body[data-ui-version="v2"] .gn-v2-data-grid .gn-v2-commit-button:focus-visible .gn-v2-toolbar-kbd,
|
||||
body[data-ui-version="v2"] .gn-v2-data-grid .gn-v2-commit-button:active .gn-v2-toolbar-kbd {
|
||||
background: var(--gn-accent-badge-bg, rgba(255, 255, 255, 0.42));
|
||||
color: var(--gn-on-accent, #17130a);
|
||||
}
|
||||
|
||||
body[data-ui-version="v2"] .gn-v2-data-grid .gn-v2-ai-insight-button {
|
||||
|
||||
Reference in New Issue
Block a user