Skip to content

Commit 032531a

Browse files
committed
feat(a11y): make the 'unselect' action invert the selection
Replace the select-all/unselect-all toggle with three distinct actions: Select all (visible), Invert (flip each visible violation's selected state), and Clear selection.
1 parent c9f7d28 commit 032531a

3 files changed

Lines changed: 38 additions & 12 deletions

File tree

plugins/a11y/src/spa/app.tsx

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -148,16 +148,27 @@ export function App() {
148148
return keys.length > 0 && keys.every(k => selected().has(k))
149149
})
150150

151-
// Select all / unselect all — toggles the whole visible set at once.
152-
function toggleSelectAll() {
151+
// Select every visible (filtered) violation.
152+
function selectAll() {
153+
const keys = visibleKeys()
154+
if (keys.length === 0)
155+
return
156+
setSelected((prev) => {
157+
const next = new Set(prev)
158+
for (const k of keys)
159+
next.add(k)
160+
return next
161+
})
162+
}
163+
// Invert the selection across the visible violations (selected ↔ unselected).
164+
function invertSelection() {
153165
const keys = visibleKeys()
154166
if (keys.length === 0)
155167
return
156-
const allSel = keys.every(k => selected().has(k))
157168
setSelected((prev) => {
158169
const next = new Set(prev)
159170
for (const k of keys) {
160-
if (allSel)
171+
if (next.has(k))
161172
next.delete(k)
162173
else
163174
next.add(k)
@@ -362,7 +373,8 @@ export function App() {
362373
routeCount={routes().length}
363374
selectedCount={selectedItems().length}
364375
allSelected={allVisibleSelected()}
365-
onToggleSelectAll={toggleSelectAll}
376+
onSelectAll={selectAll}
377+
onInvertSelection={invertSelection}
366378
onClearSelection={clearSelection}
367379
autoScan={autoScan()}
368380
onToggleAutoScan={setAutoScan}

plugins/a11y/src/spa/components/SummaryBar.stories.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ const base = {
2323
routeCount: 3,
2424
selectedCount: 0,
2525
allSelected: false,
26-
onToggleSelectAll: noop,
26+
onSelectAll: noop,
27+
onInvertSelection: noop,
2728
onClearSelection: noop,
2829
autoScan: true,
2930
onToggleAutoScan: noop,

plugins/a11y/src/spa/components/SummaryBar.tsx

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@ interface SummaryBarProps {
1515
selectedCount: number
1616
/** Whether every currently-visible violation is selected. */
1717
allSelected: boolean
18-
/** Select all visible violations, or unselect them when all are selected. */
19-
onToggleSelectAll: () => void
18+
/** Select all visible violations. */
19+
onSelectAll: () => void
20+
/** Invert the selection across the visible violations. */
21+
onInvertSelection: () => void
2022
/** Clear the entire selection (including any hidden by the filter). */
2123
onClearSelection: () => void
2224
autoScan: boolean
@@ -51,11 +53,22 @@ export function SummaryBar(props: SummaryBarProps) {
5153
<button
5254
type="button"
5355
class={ACTION}
54-
onClick={() => props.onToggleSelectAll()}
55-
title={props.allSelected ? 'Unselect all visible violations' : 'Select all visible violations'}
56+
onClick={() => props.onSelectAll()}
57+
disabled={props.allSelected}
58+
title="Select all visible violations"
5659
>
57-
<span aria-hidden class={`shrink-0 ${props.allSelected ? 'i-ph-check-square-duotone' : 'i-ph-square-duotone'}`} />
58-
{props.allSelected ? 'Unselect all' : 'Select all'}
60+
<span aria-hidden class="i-ph-check-square-duotone shrink-0" />
61+
Select all
62+
</button>
63+
64+
<button
65+
type="button"
66+
class={ACTION}
67+
onClick={() => props.onInvertSelection()}
68+
title="Invert the selection across the visible violations"
69+
>
70+
<span aria-hidden class="i-ph-selection-inverse-duotone shrink-0" />
71+
Invert
5972
</button>
6073

6174
<Show when={props.selectedCount > 0}>

0 commit comments

Comments
 (0)