fix(timeline): keep the Thema bucket-header label in a fixed ink, not the tag token
The tinted bucket-header chip painted the saturated --c-tag-* token AS its label text over a 18% wash of the same token. For the light tokens that fails WCAG AA: amber ≈3.0:1, sand ≈3.2:1, sage ≈3.4:1 (only sienna, the one the test used, passed). Move the tint to the chip fill + dot and render the label in a fixed dark ink so every token clears 4.5:1 while the chip still reads as tinted. Refs #827
This commit is contained in:
@@ -28,10 +28,12 @@ const TAG_COLORS = new Set([
|
|||||||
let { name, color }: { name: string; color: string | null } = $props();
|
let { name, color }: { name: string; color: string | null } = $props();
|
||||||
|
|
||||||
const token = $derived(color && TAG_COLORS.has(color) ? color : null);
|
const token = $derived(color && TAG_COLORS.has(color) ? color : null);
|
||||||
|
// The tint paints the chip's fill + dot only — never the label text. The saturated
|
||||||
|
// --c-tag-* tokens used AS text over their own wash drop below WCAG AA 4.5:1 for the
|
||||||
|
// light tokens (amber ≈3.0, sand ≈3.2, sage ≈3.4); a fixed dark ink keeps every token
|
||||||
|
// legible while the 18% wash still reads as a genuinely tinted chip (REQ-015).
|
||||||
const chipStyle = $derived(
|
const chipStyle = $derived(
|
||||||
token
|
token ? `background-color: color-mix(in srgb, var(--c-tag-${token}) 18%, transparent)` : ''
|
||||||
? `background-color: color-mix(in srgb, var(--c-tag-${token}) 14%, transparent); color: var(--c-tag-${token})`
|
|
||||||
: ''
|
|
||||||
);
|
);
|
||||||
const dotStyle = $derived(token ? `background-color: var(--c-tag-${token})` : '');
|
const dotStyle = $derived(token ? `background-color: var(--c-tag-${token})` : '');
|
||||||
</script>
|
</script>
|
||||||
@@ -44,7 +46,6 @@ const dotStyle = $derived(token ? `background-color: var(--c-tag-${token})` : ''
|
|||||||
class:border={!token}
|
class:border={!token}
|
||||||
class:border-line={!token}
|
class:border-line={!token}
|
||||||
class:bg-surface={!token}
|
class:bg-surface={!token}
|
||||||
class:text-ink-3={!token}
|
|
||||||
>
|
>
|
||||||
<span class="sr-only">{m.timeline_tag_chip_label()}: </span>
|
<span class="sr-only">{m.timeline_tag_chip_label()}: </span>
|
||||||
<span
|
<span
|
||||||
@@ -54,7 +55,10 @@ const dotStyle = $derived(token ? `background-color: var(--c-tag-${token})` : ''
|
|||||||
class="inline-block h-2 w-2 flex-shrink-0 rounded-sm"
|
class="inline-block h-2 w-2 flex-shrink-0 rounded-sm"
|
||||||
class:bg-ink-3={!token}
|
class:bg-ink-3={!token}
|
||||||
></span>
|
></span>
|
||||||
<span style="overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0"
|
<span
|
||||||
>{name}</span
|
data-testid="bucket-header-chip-label"
|
||||||
|
style="overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0"
|
||||||
|
class:text-ink={token}
|
||||||
|
class:text-ink-3={!token}>{name}</span
|
||||||
>
|
>
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@@ -41,4 +41,17 @@ describe('BucketHeaderChip (REQ-015/009)', () => {
|
|||||||
expect(document.body.textContent).toContain(evil);
|
expect(document.body.textContent).toContain(evil);
|
||||||
expect(document.querySelector('img')).toBeNull();
|
expect(document.querySelector('img')).toBeNull();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('paints the label in a fixed ink colour, never the saturated tag token (contrast, REQ-015)', () => {
|
||||||
|
// A saturated --c-tag-* token used as TEXT over its own wash fails 4.5:1 for the
|
||||||
|
// light tokens (amber/sand/sage ≈ 3:1). The tint must go to the background + dot;
|
||||||
|
// the label keeps a guaranteed-contrast ink token.
|
||||||
|
render(BucketHeaderChip, { name: 'Weihnachten', color: 'amber' });
|
||||||
|
const chip = document.querySelector('[data-testid="bucket-header-chip"]') as HTMLElement;
|
||||||
|
expect(chip.getAttribute('style') ?? '').not.toContain('color: var(--c-tag-');
|
||||||
|
const label = document.querySelector('[data-testid="bucket-header-chip-label"]') as HTMLElement;
|
||||||
|
expect(label.className).toContain('text-ink');
|
||||||
|
// still genuinely tinted — the token paints the wash and the dot
|
||||||
|
expect(document.body.innerHTML).toContain('var(--c-tag-amber)');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user