feat(documents): timeline date-range filter with density bars (#385) #478

Merged
marcel merged 52 commits from feat/issue-385-timeline-density-filter into main 2026-05-08 12:27:17 +02:00
2 changed files with 20 additions and 2 deletions
Showing only changes of commit 153752a901 - Show all commits

View File

@@ -22,7 +22,7 @@ let {
aria-label={m.timeline_zoom_reset()}
title={m.timeline_zoom_reset()}
onclick={onresetzoom}
class="hover:text-ink-1 inline-flex h-6 items-center justify-center gap-1 rounded-sm px-2 text-xs text-ink-3 hover:bg-canvas"
class="hover:text-ink-1 inline-flex h-11 min-w-[44px] items-center justify-center gap-1 rounded-sm px-3 text-xs text-ink-3 hover:bg-canvas"
>
</button>
@@ -33,7 +33,7 @@ let {
data-testid="timeline-clear"
aria-label={m.timeline_clear_selection()}
onclick={onclearselection}
class="hover:text-ink-1 inline-flex h-6 w-6 items-center justify-center rounded-full text-ink-3 hover:bg-canvas"
class="hover:text-ink-1 inline-flex h-11 w-11 items-center justify-center rounded-full text-ink-3 hover:bg-canvas"
>
×
</button>

View File

@@ -308,6 +308,24 @@ describe('TimelineDensityFilter — zoom', () => {
});
});
describe('TimelineDensityFilter — touch targets', () => {
it('reset-zoom button is at least 44×44 (WCAG 2.5.8)', async () => {
render(TimelineDensityFilter, makeProps({ zoomFrom: '1915-08-01', zoomTo: '1915-09-30' }));
const resetBtn = document.querySelector('[data-testid="timeline-zoom-reset"]') as HTMLElement;
expect(resetBtn.classList.contains('h-11')).toBe(true);
expect(resetBtn.className).toMatch(/min-w-\[44px\]/);
expect(resetBtn.className).not.toMatch(/(?:^|\s)h-6(?:$|\s)/);
});
it('clear-selection button is at least 44×44 (WCAG 2.5.8)', async () => {
render(TimelineDensityFilter, makeProps({ from: '1915-08-01', to: '1915-09-30' }));
const clearBtn = document.querySelector('[data-testid="timeline-clear"]') as HTMLElement;
expect(clearBtn.classList.contains('h-11')).toBe(true);
expect(clearBtn.classList.contains('w-11')).toBe(true);
expect(clearBtn.className).not.toMatch(/(?:^|\s)h-6(?:$|\s)/);
});
});
describe('TimelineDensityFilter — accessibility', () => {
it('Y-axis labels meet the 12px minimum font floor (Tailwind text-xs)', async () => {
render(TimelineDensityFilter, makeProps());