mirror of
https://github.com/Syngnat/GoNavi.git
synced 2026-08-10 00:33:28 +08:00
🐛 fix(driver-manager): 修复进度条越界与按钮对比度 (#773)
- 为驱动进度条增加稳定样式边界并允许控件收缩 - 优化设置中心嵌入布局的版本与进度网格轨道 - 将浅色主按钮调整为满足 AA 对比度的深绿底白字 - 增加嵌入布局和颜色对比度回归测试 Refs #773
This commit is contained in:
@@ -2245,6 +2245,12 @@ body[data-platform='windows'] .titlebar-window-controls {
|
||||
.driver-manager-control-block {
|
||||
display: grid;
|
||||
gap: 4px;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.driver-manager-progress.ant-progress-line {
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.driver-manager-control-label,
|
||||
@@ -2466,7 +2472,7 @@ body[data-platform='windows'] .titlebar-window-controls {
|
||||
|
||||
.driver-manager-shell.is-embedded .driver-manager-card-controls {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(150px, 1fr) minmax(110px, 0.7fr);
|
||||
grid-template-columns: minmax(0, 1fr) minmax(96px, 0.7fr);
|
||||
align-content: start;
|
||||
gap: 7px 12px;
|
||||
}
|
||||
|
||||
56
frontend/src/components/DriverManagerModal.layout.test.ts
Normal file
56
frontend/src/components/DriverManagerModal.layout.test.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
import { readFileSync } from 'node:fs';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
import { readV2ThemeCss } from '../test/readV2ThemeCss';
|
||||
|
||||
const appCss = readFileSync(
|
||||
fileURLToPath(new globalThis.URL('../App.css', import.meta.url)),
|
||||
'utf8',
|
||||
);
|
||||
const v2ThemeCss = readV2ThemeCss();
|
||||
|
||||
const relativeLuminance = (hex: string): number => {
|
||||
const channels = [1, 3, 5]
|
||||
.map((offset) => Number.parseInt(hex.slice(offset, offset + 2), 16) / 255)
|
||||
.map((channel) => (
|
||||
channel <= 0.04045 ? channel / 12.92 : ((channel + 0.055) / 1.055) ** 2.4
|
||||
));
|
||||
return 0.2126 * channels[0] + 0.7152 * channels[1] + 0.0722 * channels[2];
|
||||
};
|
||||
|
||||
const contrastRatio = (foreground: string, background: string): number => {
|
||||
const light = Math.max(relativeLuminance(foreground), relativeLuminance(background));
|
||||
const dark = Math.min(relativeLuminance(foreground), relativeLuminance(background));
|
||||
return (light + 0.05) / (dark + 0.05);
|
||||
};
|
||||
|
||||
const readHexToken = (cssBlock: string, token: string): string => {
|
||||
const match = cssBlock.match(new RegExp(`${token}\\s*:\\s*(#[0-9a-f]{6})`, 'i'));
|
||||
if (!match?.[1]) throw new Error(`Missing token ${token}`);
|
||||
return match[1];
|
||||
};
|
||||
|
||||
describe('DriverManagerModal embedded layout', () => {
|
||||
it('keeps the version and progress controls shrinkable inside the settings panel', () => {
|
||||
expect(appCss).toMatch(
|
||||
/\.driver-manager-shell\.is-embedded \.driver-manager-card-controls\s*\{[^}]*grid-template-columns:\s*minmax\(0,\s*1fr\)\s+minmax\(96px,\s*0\.7fr\)/s,
|
||||
);
|
||||
expect(appCss).toMatch(
|
||||
/\.driver-manager-control-block\s*\{[^}]*min-width:\s*0/s,
|
||||
);
|
||||
expect(appCss).toMatch(
|
||||
/\.driver-manager-progress\.ant-progress-line\s*\{[^}]*width:\s*100%[^}]*min-width:\s*0/s,
|
||||
);
|
||||
});
|
||||
|
||||
it('keeps light-theme primary buttons at accessible contrast', () => {
|
||||
const lightBlock = v2ThemeCss.match(
|
||||
/body\[data-ui-version="v2"\]\[data-theme="light"\]\s*\{([^}]*)\}/s,
|
||||
)?.[1];
|
||||
expect(lightBlock).toBeTruthy();
|
||||
const foreground = readHexToken(lightBlock || '', '--gn-on-accent');
|
||||
const background = readHexToken(lightBlock || '', '--gn-accent-strong');
|
||||
expect(contrastRatio(foreground, background)).toBeGreaterThanOrEqual(4.5);
|
||||
});
|
||||
});
|
||||
@@ -98,7 +98,7 @@ vi.mock('antd', () => {
|
||||
})}
|
||||
</select>
|
||||
);
|
||||
const Progress = () => <div data-progress="true" />;
|
||||
const Progress = (props: any) => <div data-progress="true" {...props} />;
|
||||
const Tag = ({ children }: any) => <span>{children}</span>;
|
||||
const Switch = ({ checked, onChange, disabled }: any) => (
|
||||
<button type="button" disabled={disabled} data-switch-checked={String(checked)} onClick={() => onChange?.(!checked)}>
|
||||
@@ -245,6 +245,7 @@ describe('DriverManagerModal toolbar actions', () => {
|
||||
background: 'transparent',
|
||||
});
|
||||
expect(findButton(embeddedRenderer!, t('driver.modal.card.action.install')).props.size).toBe('small');
|
||||
expect(embeddedRenderer!.root.findByProps({ 'data-progress': 'true' }).props.className).toBe('driver-manager-progress');
|
||||
|
||||
let modalRenderer: ReactTestRenderer;
|
||||
await act(async () => {
|
||||
|
||||
@@ -1805,9 +1805,9 @@ const DriverManagerModal: React.FC<{ open: boolean; onClose: () => void; onBack?
|
||||
{row.builtIn ? (
|
||||
<Text type="secondary">{t('driver.modal.card.noInstallNeeded')}</Text>
|
||||
) : hasActiveProgress ? (
|
||||
<Progress percent={progress.percent} status={progress.status} size="small" />
|
||||
<Progress className="driver-manager-progress" percent={progress.percent} status={progress.status} size="small" />
|
||||
) : (
|
||||
<Progress percent={0} size="small" />
|
||||
<Progress className="driver-manager-progress" percent={0} size="small" />
|
||||
)}
|
||||
</div>
|
||||
{renderDriverActions(row)}
|
||||
|
||||
@@ -48,9 +48,8 @@ body[data-ui-version="v2"][data-theme="light"] {
|
||||
--gn-accent: #15803d;
|
||||
--gn-accent-2: #166534;
|
||||
--gn-accent-soft: #dcfce7;
|
||||
/* --gn-on-accent 此前未定义,所有 var(--gn-on-accent, #fff) 都回退成白字:
|
||||
白字压在 #16a34a 上仅 3.30,不满足 WCAG AA 的 4.5。深绿可得 4.52。 */
|
||||
--gn-on-accent: #052e16;
|
||||
/* 浅色主题的主操作使用深绿填充,白色前景对 #15803d 的对比度为 5.02。 */
|
||||
--gn-on-accent: #ffffff;
|
||||
--gn-accent-strong: #15803d;
|
||||
--gn-accent-strong-hover: #126634;
|
||||
--gn-accent-strong-active: #0d4d27;
|
||||
|
||||
Reference in New Issue
Block a user