Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/seven-papayas-glow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@primer/view-components': patch
---

Fixed SelectPanel multiselect accessibility: Use `aria-selected` instead of `aria-checked` for listbox option items.
2 changes: 1 addition & 1 deletion app/components/primer/alpha/select_panel.rb
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ def initialize(**system_arguments)
super(
p: 2,
role: "listbox",
aria_selection_variant: select_variant == :single ? :selected : :checked,
aria_selection_variant: :selected,
select_variant: select_variant == :multiple ? :multiple_checkbox : :single,
**system_arguments
)
Expand Down
2 changes: 1 addition & 1 deletion app/components/primer/alpha/select_panel_element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ export class SelectPanelElement extends HTMLElement {
}

get ariaSelectionType(): string {
return this.selectVariant === 'multiple' ? 'aria-checked' : 'aria-selected'
return 'aria-selected'
}

set selectVariant(variant: SelectVariant) {
Expand Down
68 changes: 27 additions & 41 deletions test/system/alpha/select_panel_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -211,18 +211,18 @@ def test_remembers_selections_on_filter
end

# Phaser should already be selected
assert_selector "[aria-checked=true]", text: "Phaser"
assert_selector "[aria-selected=true]", text: "Phaser"

click_on "Photon torpedo"

assert_selector "[aria-checked=true]", text: "Phaser"
assert_selector "[aria-checked=true]", text: "Photon torpedo"
assert_selector "[aria-selected=true]", text: "Phaser"
assert_selector "[aria-selected=true]", text: "Photon torpedo"

wait_for_items_to_load do
filter_results(query: "ph")
end

assert_selector "[aria-checked=true]", count: 2
assert_selector "[aria-selected=true]", count: 2
end

def test_pressing_down_arrow_in_filter_input_focuses_first_item
Expand Down Expand Up @@ -270,16 +270,14 @@ def test_pressing_enter_in_filter_input_checks_first_item
click_on_invoker_button

# nothing is checked initially
refute_selector "[aria-checked=true]"
refute_selector "[aria-selected=true]"

assert_equal active_element.tag_name, "input"

keyboard.type(:enter)

# pressing enter in the filter input does not close the panel
assert_selector "[aria-checked=true]", text: "Item 1"
refute_selector "[aria-selected]"
assert_selector "[aria-selected=true]", text: "Item 1"
end

def test_pressing_enter_in_filter_input_navigates_if_first_item_is_link
Expand Down Expand Up @@ -316,7 +314,6 @@ def test_single_select_item_checked

# clicking item closes panel, so checked item is hidden
assert_selector "[aria-selected=true]", text: "Item 2", visible: :hidden
refute_selector "[aria-checked]", visible: :hidden
end

def test_single_select_remote_fetch_item_checked
Expand All @@ -327,7 +324,6 @@ def test_single_select_remote_fetch_item_checked

# clicking item closes panel, so checked item is hidden
assert_selector "[aria-selected=true]", text: "Photon torpedo", visible: :hidden
refute_selector "[aria-checked]", visible: :hidden
end

def test_single_select_item_checked_via_keyboard_enter
Expand Down Expand Up @@ -359,7 +355,6 @@ def test_single_select_item_checked_via_keyboard_enter
keyboard.type(:tab, :down, :enter)

assert_selector "[aria-selected=true]", text: "Item 2", visible: :hidden
refute_selector "[aria-checked]", visible: :hidden
end

def test_single_select_item_checked_via_keyboard_space
Expand Down Expand Up @@ -391,7 +386,6 @@ def test_single_select_item_checked_via_keyboard_space
keyboard.type(:tab, :down, :space)

assert_selector "[aria-selected=true]", text: "Item 2", visible: :hidden
refute_selector "[aria-checked]", visible: :hidden
end

def test_single_select_item_unchecks_previously_checked_item
Expand All @@ -402,14 +396,12 @@ def test_single_select_item_unchecks_previously_checked_item

# clicking item closes panel, so checked item is hidden
assert_selector "[aria-selected=true]", text: "Item 3", visible: :hidden
refute_selector "[aria-checked]", visible: :hidden

click_on_invoker_button
click_on_second_item

# clicking item closes panel, so checked item is hidden
assert_selector "[aria-selected=true]", text: "Item 2", visible: :hidden
refute_selector "[aria-checked]", visible: :hidden
end

def test_single_select_item_unchecks_previously_checked_item_after_filtering
Expand All @@ -419,7 +411,6 @@ def test_single_select_item_unchecks_previously_checked_item_after_filtering

# clicking item closes panel, so checked item is hidden
assert_selector "[aria-selected=true]", text: "Phaser"
refute_selector "[aria-checked]"

wait_for_items_to_load do
filter_results(query: "ph")
Expand All @@ -431,7 +422,6 @@ def test_single_select_item_unchecks_previously_checked_item_after_filtering
# clicking item closes panel, so checked item is hidden
assert_selector "[aria-selected=false]", text: "Phaser"
assert_selector "[aria-selected=true]", text: "Photon torpedo"
refute_selector "[aria-checked]"
end

def test_single_selected_item_cannot_be_unchecked
Expand All @@ -445,7 +435,6 @@ def test_single_selected_item_cannot_be_unchecked

# clicking item closes panel, so checked item is hidden
assert_selector "[aria-selected=true]", text: "Item 2", visible: :hidden
refute_selector "[aria-checked]", visible: :hidden
end

def test_single_select_clears_input_on_selection
Expand Down Expand Up @@ -614,9 +603,8 @@ def test_multi_select_items_checked
click_on_third_item

# clicking item closes panel, so checked item is hidden
assert_selector "[aria-checked=true]", text: "Item 2"
assert_selector "[aria-checked=true]", text: "Item 3"
refute_selector "[aria-selected]", visible: :hidden
assert_selector "[aria-selected=true]", text: "Item 2"
assert_selector "[aria-selected=true]", text: "Item 3"
end

def test_multi_select_items_checked_via_keyboard_enter
Expand All @@ -633,17 +621,16 @@ def test_multi_select_items_checked_via_keyboard_enter
# select first item
keyboard.type(:tab, :enter)

assert_selector "[aria-checked=true]", count: 1
assert_selector "[aria-checked=true]", text: "Item 1"
assert_selector "[aria-selected=true]", count: 1
assert_selector "[aria-selected=true]", text: "Item 1"

# select second item
keyboard.type(:down, :enter)

assert_selector "[aria-checked=true]", count: 2
assert_selector "[aria-checked=true]", text: "Item 1"
assert_selector "[aria-checked=true]", text: "Item 2"
assert_selector "[aria-selected=true]", count: 2
assert_selector "[aria-selected=true]", text: "Item 1"
assert_selector "[aria-selected=true]", text: "Item 2"

refute_selector "[aria-selected]", visible: :hidden
end

def test_multi_select_items_checked_via_keyboard_space
Expand All @@ -660,17 +647,16 @@ def test_multi_select_items_checked_via_keyboard_space
# select first item
keyboard.type(:tab, :space)

assert_selector "[aria-checked=true]", count: 1
assert_selector "[aria-checked=true]", text: "Item 1"
assert_selector "[aria-selected=true]", count: 1
assert_selector "[aria-selected=true]", text: "Item 1"

# select second item
keyboard.type(:down, :space)

assert_selector "[aria-checked=true]", count: 2
assert_selector "[aria-checked=true]", text: "Item 1"
assert_selector "[aria-checked=true]", text: "Item 2"
assert_selector "[aria-selected=true]", count: 2
assert_selector "[aria-selected=true]", text: "Item 1"
assert_selector "[aria-selected=true]", text: "Item 2"

refute_selector "[aria-selected]", visible: :hidden
end

def test_multi_select_items_can_be_unchecked
Expand All @@ -680,13 +666,13 @@ def test_multi_select_items_can_be_unchecked
click_on_second_item
click_on_third_item

assert_selector "[aria-checked=true]", text: "Item 2"
assert_selector "[aria-checked=true]", text: "Item 3"
assert_selector "[aria-selected=true]", text: "Item 2"
assert_selector "[aria-selected=true]", text: "Item 3"

click_on_second_item
click_on_third_item

refute_selector "[aria-checked=true]"
refute_selector "[aria-selected=true]"
end

def test_multi_select_disabled_item_cannot_be_checked
Expand All @@ -696,7 +682,7 @@ def test_multi_select_disabled_item_cannot_be_checked

click_on_item_by_id("disabled")

refute_selector "[aria-checked=true]"
refute_selector "[aria-selected=true]"
end

def test_multi_select_does_not_allow_server_to_check_items_on_filter_if_selections_already_made
Expand All @@ -708,7 +694,7 @@ def test_multi_select_does_not_allow_server_to_check_items_on_filter_if_selectio
end

# Phaser should already be selected
assert_selector "[aria-checked=true]", text: "Phaser"
assert_selector "[aria-selected=true]", text: "Phaser"

# check torpedo, uncheck phaser
click_on "Photon torpedo"
Expand All @@ -720,8 +706,8 @@ def test_multi_select_does_not_allow_server_to_check_items_on_filter_if_selectio

# server will render phaser checked, but since the user has already made selections,
# the server-rendered selections should be ignored
refute_selector "[aria-checked=true]", text: "Phaser"
assert_selector "[aria-checked=true]", text: "Photon torpedo"
refute_selector "[aria-selected=true]", text: "Phaser"
assert_selector "[aria-selected=true]", text: "Photon torpedo"
end

def test_multi_select_allows_server_to_check_multiple_items
Expand All @@ -732,8 +718,8 @@ def test_multi_select_allows_server_to_check_multiple_items
click_on_invoker_button
end

assert_selector "[aria-checked=true]", text: "Phaser"
assert_selector "[aria-checked=true]", text: "Photon torpedo"
assert_selector "[aria-selected=true]", text: "Phaser"
assert_selector "[aria-selected=true]", text: "Photon torpedo"
end

def test_banner_scheme_is_passed_to_banner_component
Expand Down Expand Up @@ -804,7 +790,7 @@ def test_uncheck_item_via_js_api
click_on_invoker_button
click_on_item_by_id("item1")

assert_selector "li[data-item-id=item1] [aria-checked=true]"
assert_selector "li[data-item-id=item1] [aria-selected=true]"

evaluate_multiline_script(<<~JS)
const panel = document.querySelector('select-panel')
Expand Down
Loading