Skip to content

Commit

Permalink
[ActionList] If role='listbox' is used on an ActionList default items…
Browse files Browse the repository at this point in the history
… to role='option' (#2925)

Co-authored-by: kendallgassner <kendallgassner@users.noreply.github.com>
Co-authored-by: Jon Rohan <rohan@github.com>
  • Loading branch information
3 people authored Jun 28, 2024
1 parent 235544d commit 6c730c4
Show file tree
Hide file tree
Showing 8 changed files with 59 additions and 5 deletions.
5 changes: 5 additions & 0 deletions .changeset/short-ligers-smile.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@primer/view-components': patch
---

Update ActionList such that if role='listbox' is passed in the items render as options
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 14 additions & 2 deletions app/components/primer/alpha/action_list.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,19 @@ class ActionList < Primer::Component

MENU_ROLE = :menu
DEFAULT_MENU_ITEM_ROLE = :menuitem

LIST_BOX_ITEM_ROLE = :option
DEFAULT_SCHEME = :full
SCHEME_MAPPINGS = {
DEFAULT_SCHEME => nil,
:inset => "ActionListWrap--inset"
}.freeze
SCHEME_OPTIONS = SCHEME_MAPPINGS.keys.freeze

DEFAULT_ARIA_SELECTION_VARIANT = :checked
ARIA_SELECTION_VARIANT_OPTIONS = [
:selected,
DEFAULT_ARIA_SELECTION_VARIANT,
].freeze
DEFAULT_SELECT_VARIANT = :none
SELECT_VARIANT_OPTIONS = [
:single,
Expand Down Expand Up @@ -115,14 +120,15 @@ def custom_element_name
}
}

attr_reader :id, :select_variant, :role
attr_reader :id, :select_variant, :role, :aria_selection_variant

# @param id [String] HTML ID value.
# @param role [Boolean] ARIA role describing the function of the list. listbox and menu are a common values.
# @param item_classes [String] Additional CSS classes to attach to items.
# @param scheme [Symbol] <%= one_of(Primer::Alpha::ActionList::SCHEME_OPTIONS) %> `inset` children are offset (vertically and horizontally) from list edges. `full` (default) children are flush (vertically and horizontally) with list edges.
# @param show_dividers [Boolean] Display a divider above each item in the list when it does not follow a header or divider.
# @param select_variant [Symbol] How items may be selected in the list. <%= one_of(Primer::Alpha::ActionList::SELECT_VARIANT_OPTIONS) %>
# @param aria_selection_variant [Symbol] Specifies which aria selection to use. <%= one_of(Primer::Alpha::ActionList::ARIA_SELECTION_VARIANT_OPTIONS) %?
# @param form_arguments [Hash] Allows an `ActionList` to act as a select list in multi- and single-select modes. Pass the `builder:` and `name:` options to this hash. `builder:` should be an instance of `ActionView::Helpers::FormBuilder`, which are created by the standard Rails `#form_with` and `#form_for` helpers. The `name:` option is the desired name of the field that will be included in the params sent to the server on form submission. *NOTE*: Consider using an <%= link_to_component(Primer::Alpha::ActionMenu) %> instead of using this feature directly.
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
def initialize(
Expand All @@ -131,6 +137,7 @@ def initialize(
item_classes: nil,
scheme: DEFAULT_SCHEME,
show_dividers: false,
aria_selection_variant: DEFAULT_ARIA_SELECTION_VARIANT,
select_variant: DEFAULT_SELECT_VARIANT,
form_arguments: {},
**system_arguments
Expand All @@ -143,6 +150,7 @@ def initialize(
@scheme = fetch_or_fallback(SCHEME_OPTIONS, scheme, DEFAULT_SCHEME)
@show_dividers = show_dividers
@select_variant = select_variant
@aria_selection_variant = aria_selection_variant
@system_arguments[:classes] = class_names(
SCHEME_MAPPINGS[@scheme],
system_arguments[:classes],
Expand Down Expand Up @@ -229,6 +237,10 @@ def allows_selection?
single_select? || multi_select?
end

def acts_as_listbox?
@system_arguments[:role] == "listbox"
end

def acts_as_menu?
@system_arguments[:role] == :menu || @system_arguments[:role] == :group
end
Expand Down
8 changes: 5 additions & 3 deletions app/components/primer/alpha/action_list/item.rb
Original file line number Diff line number Diff line change
Expand Up @@ -271,13 +271,15 @@ def initialize(
end

@content_arguments[:role] = role ||
if @list.allows_selection?
if @list.acts_as_listbox?
ActionList::LIST_BOX_ITEM_ROLE
elsif @list.allows_selection?
ActionList::SELECT_VARIANT_ROLE_MAP[@list.select_variant]
elsif @list.acts_as_menu?
ActionList::DEFAULT_MENU_ITEM_ROLE
end

@system_arguments[:role] = @list.acts_as_menu? ? :none : nil
@system_arguments[:role] = @list.acts_as_menu? || @list.acts_as_listbox? ? :none : nil

@description_wrapper_arguments = {
classes: class_names(
Expand All @@ -293,7 +295,7 @@ def before_render
if @list.allows_selection?
@content_arguments[:aria] = merge_aria(
@content_arguments,
{ aria: { checked: active? } }
{ aria: @list.aria_selection_variant == :selected ? {selected: active?} : { checked: active? } }
)
end

Expand Down
19 changes: 19 additions & 0 deletions previews/primer/alpha/action_list_preview.rb
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,25 @@ def long_label_show_tooltip_with_truncate_label(truncate_label: :none)
end
end
end

# @label Listbox
def listbox(
role: "listbox",
aria_selection_variant: :selected,
scheme: Primer::Alpha::ActionList::DEFAULT_SCHEME,
show_dividers: false
)
render(Primer::Alpha::ActionList.new(
role: role,
scheme: scheme,
show_dividers: show_dividers
)) do |component|
component.with_heading(title: "Action List")
component.with_item(label: "Item one", href: "/", active: true)
component.with_item(label: "Item two", href: "/")
component.with_item(label: "Item three", href: "/")
end
end
end
end
end
6 changes: 6 additions & 0 deletions static/constants.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@
"Primer::Alpha::ActionBar::Item": {
},
"Primer::Alpha::ActionList": {
"LIST_BOX_ITEM_ROLE": "option",
"DEFAULT_MENU_ITEM_ROLE": "menuitem",
"DEFAULT_ARIA_SELECTION_VARIANT": "checked",
"DEFAULT_ROLE": "list",
"DEFAULT_SCHEME": "full",
"DEFAULT_SELECT_VARIANT": "none",
Expand All @@ -42,6 +44,10 @@
"multiple_checkbox",
"none"
],
"ARIA_SELECTION_VARIANT_OPTIONS": [
"selected",
"checked"
],
"SELECT_VARIANT_ROLE_MAP": {
"single": "menuitemradio",
"multiple": "menuitemcheckbox",
Expand Down
10 changes: 10 additions & 0 deletions test/components/alpha/action_list_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,16 @@ def test_uses_correct_menu_and_item_roles_when_multi_select
end
end

def test_uses_correct_item_role_when_role_set_to_option
render_inline(Primer::Alpha::ActionList.new(aria: { label: "List" }, role: "listbox")) do |component|
component.with_item(label: "Item 1")
end

assert_selector("ul.ActionListWrap[role=listbox]") do |list|
list.assert_selector("li.ActionListItem button[role=option]")
end
end

def test_uses_correct_item_role_when_role_set_to_menu
render_inline(Primer::Alpha::ActionList.new(aria: { label: "List" }, role: :menu)) do |component|
component.with_item(label: "Item 1")
Expand Down

0 comments on commit 6c730c4

Please sign in to comment.