diff --git a/frontend/src/lib/document/TimelineDensityFilter.svelte b/frontend/src/lib/document/TimelineDensityFilter.svelte index 973d3c1b..d13d6e61 100644 --- a/frontend/src/lib/document/TimelineDensityFilter.svelte +++ b/frontend/src/lib/document/TimelineDensityFilter.svelte @@ -225,6 +225,19 @@ const dragWindowRightPct = $derived.by(() => { }); const tickIndices = $derived(tickIndicesFor(filled)); + +// While dragging, expose the live preview range to assistive tech via a +// polite live region. Empty text outside drag avoids announcing residual state. +const dragLiveMessage = $derived.by(() => { + if (!isDragging || dragLowIndex === null || dragHighIndex === null) return ''; + const fromLabel = filled[dragLowIndex]?.month; + const toLabel = filled[dragHighIndex]?.month; + if (!fromLabel || !toLabel) return ''; + return m.timeline_dragging_aria_live({ + from: formatTickLabel(fromLabel, getLocale()), + to: formatTickLabel(toLabel, getLocale()) + }); +}); const omitTickYear = $derived.by(() => { if (filled.length === 0 || filled[0].month.length === 4) return false; const firstYear = filled[0].month.slice(0, 4); @@ -306,6 +319,10 @@ const omitTickYear = $derived.by(() => { +
+ {dragLiveMessage} +
+
{#if isZoomed}