fix(journey-editor): clear liveAnnounce 500ms after move; document svelte-ignore suppressions
All checks were successful
CI / Unit & Component Tests (pull_request) Successful in 3m26s
CI / OCR Service Tests (pull_request) Successful in 22s
CI / Backend Unit Tests (pull_request) Successful in 3m49s
CI / fail2ban Regex (pull_request) Successful in 45s
CI / Semgrep Security Scan (pull_request) Successful in 23s
CI / Compose Bucket Idempotency (pull_request) Successful in 1m5s

NVDA+Chrome and VoiceOver+Safari can re-announce a persistent non-empty
aria-live region when adjacent DOM mutations occur. Clearing with a
500ms delay gives the announcement time to fire once before going quiet.

The two svelte-ignore a11y_no_static_element_interactions suppressions are
given preceding comments explaining the keyboard accessibility contract so
they are not mistaken for unaddressed tech debt.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-06-09 16:47:30 +02:00
parent dfc065b727
commit 4572572c94

View File

@@ -155,6 +155,10 @@ async function handleMoveUp(index: number) {
newPosition: index
});
await handleReorder(ids);
// Clear so the live region does not re-announce on unrelated DOM mutations
setTimeout(() => {
liveAnnounce = '';
}, 500);
}
async function handleMoveDown(index: number) {
@@ -167,6 +171,10 @@ async function handleMoveDown(index: number) {
newPosition: index + 2
});
await handleReorder(ids);
// Clear so the live region does not re-announce on unrelated DOM mutations
setTimeout(() => {
liveAnnounce = '';
}, 500);
}
async function save(nextStatus: 'DRAFT' | 'PUBLISHED') {
@@ -237,6 +245,7 @@ async function save(nextStatus: 'DRAFT' | 'PUBLISHED') {
</p>
{/if}
<!-- pointer events managed by createBlockDragDrop; keyboard reorder available via move-up/down buttons on each item -->
<!-- svelte-ignore a11y_no_static_element_interactions -->
<div
bind:this={listEl}
@@ -248,6 +257,7 @@ async function save(nextStatus: 'DRAFT' | 'PUBLISHED') {
<p class="font-sans text-sm text-ink-3">{m.journey_empty_state()}</p>
{/if}
{#each items as item, i (item.id)}
<!-- pointerdown initiates drag; the drag handle button inside is the semantic interactive element -->
<!-- svelte-ignore a11y_no_static_element_interactions -->
<div
data-block-wrapper