fix(comparison): domain bars use a share variable instead of an inline style
The design-language check forbids inline style objects. The bar length now travels as --bar-share and comparison.css applies it as the width.
This commit is contained in:
parent
01dabc9c3a
commit
2ebacf6201
|
|
@ -1,4 +1,4 @@
|
||||||
import { useId, useMemo, useState } from 'react';
|
import { useId, useMemo, useState, type CSSProperties } from 'react';
|
||||||
import { useOptionalApp } from '../../app/AppProvider';
|
import { useOptionalApp } from '../../app/AppProvider';
|
||||||
import type { FindingRecord } from '../../domain/finding';
|
import type { FindingRecord } from '../../domain/finding';
|
||||||
import { FindingFirstRead } from '../finding-reader/FindingFirstRead';
|
import { FindingFirstRead } from '../finding-reader/FindingFirstRead';
|
||||||
|
|
@ -71,6 +71,8 @@ export const date = (value: string) => {
|
||||||
return Number.isNaN(parsed.getTime()) ? value : parsed.toLocaleDateString('en-GB', { day: 'numeric', month: 'short', year: 'numeric' });
|
return Number.isNaN(parsed.getTime()) ? value : parsed.toLocaleDateString('en-GB', { day: 'numeric', month: 'short', year: 'numeric' });
|
||||||
};
|
};
|
||||||
const rounded = (value?: number) => value === undefined ? undefined : Math.round(value);
|
const rounded = (value?: number) => value === undefined ? undefined : Math.round(value);
|
||||||
|
/** Domain bar length as a share of the widest bar; the stylesheet reads it as `--bar-share`. */
|
||||||
|
const barStyle = (share: number): CSSProperties => ({ '--bar-share': `${share * 100}%` } as CSSProperties);
|
||||||
|
|
||||||
function Delta({ before, after }: { before?: number; after?: number }) {
|
function Delta({ before, after }: { before?: number; after?: number }) {
|
||||||
if (before === undefined || after === undefined) return <span className="comparison-delta is-neutral">—</span>;
|
if (before === undefined || after === undefined) return <span className="comparison-delta is-neutral">—</span>;
|
||||||
|
|
@ -286,9 +288,9 @@ function DomainComparison({ projectId, baseline, target }: { projectId?: string;
|
||||||
<span role="cell">{domain.onlyIn
|
<span role="cell">{domain.onlyIn
|
||||||
? <span className="comparison-tile__note comparison-domain__only">{domain.onlyInSources.map(sourceName).join(', ')} only in {domain.onlyIn === 'target' ? 'B' : 'A'} · not comparable</span>
|
? <span className="comparison-tile__note comparison-domain__only">{domain.onlyInSources.map(sourceName).join(', ')} only in {domain.onlyIn === 'target' ? 'B' : 'A'} · not comparable</span>
|
||||||
: <span className="comparison-domain__bars" aria-label={`${domain.resolved} resolved, ${domain.worse} new or regressed`}>
|
: <span className="comparison-domain__bars" aria-label={`${domain.resolved} resolved, ${domain.worse} new or regressed`}>
|
||||||
<span className="comparison-domain__bar is-better" style={{ width: `${domain.resolved / widest * 100}%` }}/>
|
<span className="comparison-domain__bar is-better" style={barStyle(domain.resolved / widest)}/>
|
||||||
<span className="comparison-domain__axis"/>
|
<span className="comparison-domain__axis"/>
|
||||||
<span className="comparison-domain__bar is-worse" style={{ width: `${domain.worse / widest * 100}%` }}/>
|
<span className="comparison-domain__bar is-worse" style={barStyle(domain.worse / widest)}/>
|
||||||
</span>}</span>
|
</span>}</span>
|
||||||
</div>;
|
</div>;
|
||||||
})}
|
})}
|
||||||
|
|
|
||||||
|
|
@ -103,7 +103,7 @@
|
||||||
.comparison-domain__legend { display: flex; justify-content: space-between; gap: var(--space-2); }
|
.comparison-domain__legend { display: flex; justify-content: space-between; gap: var(--space-2); }
|
||||||
.comparison-domain__bars { display: grid; grid-template-columns: 1fr 1px 1fr; align-items: center; height: 16px; }
|
.comparison-domain__bars { display: grid; grid-template-columns: 1fr 1px 1fr; align-items: center; height: 16px; }
|
||||||
.comparison-domain__axis { height: 16px; background: var(--border-strong); }
|
.comparison-domain__axis { height: 16px; background: var(--border-strong); }
|
||||||
.comparison-domain__bar { height: 8px; }
|
.comparison-domain__bar { --bar-share: 0%; width: var(--bar-share); height: 8px; }
|
||||||
.comparison-domain__bar.is-better { justify-self: end; background: var(--outcome-pass); }
|
.comparison-domain__bar.is-better { justify-self: end; background: var(--outcome-pass); }
|
||||||
.comparison-domain__bar.is-worse { justify-self: start; background: var(--outcome-fail); }
|
.comparison-domain__bar.is-worse { justify-self: start; background: var(--outcome-fail); }
|
||||||
.comparison-domain__only { margin: 0; }
|
.comparison-domain__only { margin: 0; }
|
||||||
|
|
|
||||||
|
|
@ -143,8 +143,8 @@ describe('Comparison Engine Compare tab', () => {
|
||||||
const rows = [...host.querySelectorAll('.comparison-domain:not(.is-header)')];
|
const rows = [...host.querySelectorAll('.comparison-domain:not(.is-header)')];
|
||||||
const cells = (row: Element) => [...row.children].map(cell => cell.textContent);
|
const cells = (row: Element) => [...row.children].map(cell => cell.textContent);
|
||||||
expect(cells(rows[0]).slice(0, 5)).toEqual(['Identity & Authentication', '48', '→', '55', '▲ +7']);
|
expect(cells(rows[0]).slice(0, 5)).toEqual(['Identity & Authentication', '48', '→', '55', '▲ +7']);
|
||||||
expect(rows[0].querySelector<HTMLElement>('.comparison-domain__bar.is-better')?.style.width).toBe('100%');
|
expect(rows[0].querySelector<HTMLElement>('.comparison-domain__bar.is-better')?.style.getPropertyValue('--bar-share')).toBe('100%');
|
||||||
expect(rows[0].querySelector<HTMLElement>('.comparison-domain__bar.is-worse')?.style.width).toBe('25%');
|
expect(rows[0].querySelector<HTMLElement>('.comparison-domain__bar.is-worse')?.style.getPropertyValue('--bar-share')).toBe('25%');
|
||||||
expect(cells(rows[1])).toEqual(['Cloud & Collaboration', '—', '→', '46', '○ Only in B', 'Maester only in B · not comparable']);
|
expect(cells(rows[1])).toEqual(['Cloud & Collaboration', '—', '→', '46', '○ Only in B', 'Maester only in B · not comparable']);
|
||||||
expect(cells(rows[2])[4]).toBe('▼ −3');
|
expect(cells(rows[2])[4]).toBe('▼ −3');
|
||||||
expect(rows[2].querySelector('.comparison-delta')?.className).toContain('is-worse');
|
expect(rows[2].querySelector('.comparison-delta')?.className).toContain('is-worse');
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue