Action menu

Action menu is composed of action list and overlay patterns used for quick actions and selections.

v0.23.0AlphaNot reviewed for accessibility

Description

ActionMenu is used for actions, navigation, to display secondary options, or single/multi select lists. They appear when users interact with buttons, actions, or other controls.

The only allowed elements for the Item components are: :a, :button, and :clipboard-copy. The default is :button.

Select variants

While ActionMenus default to a list of buttons that can link to other pages, copy text to the clipboard, etc, they also support single and multiple select variants. The single select variant allows a single item to be "selected" (i.e. marked "active") when clicked, which will cause a check mark to appear to the left of the item text. When the multiple select variant is chosen, multiple items may be selected and check marks will appear next to each selected item.

Use the select_variant: option to control which variant the ActionMenu uses. For more information, see the documentation on supported arguments below.

Dynamic labels

When using the single select variant, an optional label indicating the selected item can be displayed inside the menu button. Dynamic labels can also be prefixed with custom text.

Pass dynamic_label: true to enable dynamic label behavior, and pass dynamic_label_prefix: "<string>" to set a custom prefix. For more information, see the documentation on supported arguments below.

ActionMenus as form inputs

When using either the single or multiple select variants, ActionMenus can be used as form inputs. They behave very similarly to how HTML <select> boxes behave, and play nicely with Rails' built-in form mechanisms. Pass arguments via the form_arguments: argument, including the Rails form builder object and the name of the field:

<% form_with(url: update_merge_strategy_path) do |f| %>
<%= render(Primer::Alpha::ActionMenu.new(form_arguments: { builder: f, name: "merge_strategy" })) do |menu| %>
<% menu.with_item(label: "Fast forward", data: { value: "fast_forward" }) %>
<% menu.with_item(label: "Recursive", data: { value: "recursive" }) %>
<% menu.with_item(label: "Ours", data: { value: "ours" }) %>
<% menu.with_item(label: "Theirs", data: { value: "theirs" }) %>
<% end %>
<% end %>

The value of the data: { value: ... } argument is sent to the server on submit, keyed using the name provided above (eg. "merge_strategy"). If no value is provided for an item, the value of that item is the item's label. Here's the corresponding MergeStrategyController that might be written to handle the form above:

class MergeStrategyController < ApplicationController
def update
puts "You chose #{merge_strategy_params[:merge_strategy]}"
end
private
def merge_strategy_params
params.permit(:merge_strategy)
end
end

ActionMenu items that submit forms

Whereas ActionMenu items normally permit navigation via <a> tags which make HTTP get requests, ActionMenu items also permit navigation via POST requests. To enable this behavior, include the href: argument as normal, but also pass the form_arguments: argument to the appropriate item:

<%= render(Primer::Alpha::ActionMenu.new) do |menu| %>
<% menu.with_item(
label: "Repository",
href: update_repo_grouping_path,
form_arguments: {
method: :post,
name: "group_by",
value: "repository"
}
) %>
<% end %>

Make sure to specify method: :post, as the default is :get. When clicked, the list item will submit a POST request to the URL passed in the href: argument, including a parameter named "group_by" with a value of "repository". If no value is given, the name, eg. "group_by", will be used as the value.

It is possible to include multiple fields on submit. Instead of passing the name: and value: arguments, pass an array via the inputs: argument:

<%= render(Primer::Alpha::ActionMenu.new) do |menu| %>
<% menu.with_show_button { "Group By" } %>
<% menu.with_item(
label: "Repository",
href: update_repo_grouping_path,
form_arguments: {
method: :post,
inputs: [{
name: "group_by",
value: "repository"
}, {
name: "some_other_field",
value: "some value",
}],
}
) %>
<% end %>

Form arguments

The following table summarizes the arguments allowed in the form_arguments: hash mentioned above.

NameTypeDefaultDescription
methodSymbol:getThe HTTP request method to use to submit the form. One of :get, :post, :patch, :put, :delete, or :head
nameStringnilThe name of the field that will be sent to the server on submit.
valueStringnilThe value of the field that will be sent to the server on submit.
input_argumentsHash{}Additional key/value pairs to emit as HTML attributes on the <input type="hidden"> element.
inputsArray<Hash>[]An array of hashes representing HTML <input type="hidden"> elements. Must contain at least name: and value: keys. If additional key/value pairs are provided, they are emitted as HTML attributes on the <input> element. This argument supercedes the name:, value:, and :input_arguments arguments listed above.

The elements of the inputs: array will be emitted as HTML <input type="hidden"> elements.

JavaScript API

ActionLists render an <action-list> custom element that exposes behavior to the client. For all these methods, itemId refers to the value of the item_id: argument (see below) that is used to populate the data-item-id HTML attribute.

Query methods

  • getItemById(itemId: string): Element: Returns the item's HTML <li> element. The return value can be passed as the item argument to the other methods listed below.
  • isItemChecked(item: Element): boolean: Returns true if the item is checked, false otherwise.
  • isItemHidden(item: Element): boolean: Returns true if the item is hidden, false otherwise.
  • isItemDisabled(item: Element): boolean: Returns true if the item is disabled, false otherwise.

State methods

  • showItem(item: Element): Shows the item, i.e. makes it visible.
  • hideItem(item: Element): Hides the item, i.e. makes it invisible.
  • enableItem(item: Element): Enables the item, i.e. makes it clickable by the mouse and keyboard.
  • disableItem(item: Element): Disables the item, i.e. makes it unclickable by the mouse and keyboard.
  • checkItem(item: Element): Checks the item. Only has an effect in single- and multi-select modes.
  • uncheckItem(item: Element): Unchecks the item. Only has an effect in multi-select mode, since items cannot be unchecked in single-select mode.

Events

The <action-menu> element fires an itemActivated event whenever an item is activated (eg. clicked) via the mouse or keyboard.

document.querySelector("action-menu").addEventListener("itemActivated", (event: ItemActivatedEvent) => {
event.item // Element: the <li> item that was activated
event.checked // boolean: whether or not the result of the activation checked the item
})

Accessibility

The action for the menu item needs to be on the element with role="menuitem". Semantics are removed for everything nested inside of it. When a menu item is selected, the menu will close immediately.

Additional information around the keyboard functionality and implementation can be found on the WAI-ARIA Authoring Practices.

Arguments

NameDefaultDescription
menu_id

self.class.generate_id

String

Id of the menu.

anchor_align

:start

Symbol

One of :center, :end, or :start..

anchor_side

:outside_bottom

Symbol

One of :inside_bottom, :inside_center, :inside_left, :inside_right, :inside_top, :outside_bottom, :outside_left, :outside_right, or :outside_top..

size

:auto

Symbol

One of :auto, :large, :medium, :medium_portrait, :small, or :xlarge..

src

nil

String

Used with an include-fragment element to load menu content from the given source URL.

preload

false

Boolean

When true, and src is present, loads the include-fragment on trigger hover.

dynamic_label

false

Boolean

Whether or not to display the text of the currently selected item in the show button.

dynamic_label_prefix

nil

String

If provided, the prefix is prepended to the dynamic label and displayed in the show button.

select_variant

:none

Symbol

One of :multiple, :none, or :single.

form_arguments

{}

Hash

Allows an ActionMenu 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.

system_arguments

N/A

Hash

Examples

Slots

show_button

Button to activate the menu.

NameDefaultDescription
system_arguments

N/A

Hash

The arguments accepted by Overlay's show_button slot.

items

Adds a new item to the list.

NameDefaultDescription
system_arguments

N/A

Hash

The arguments accepted by ActionList::Item.

Methods

list

Returns the value of attribute list.

preload

Returns the value of attribute preload.

preload?

Returns the value of attribute preload.

with_show_button

Button to activate the menu.

NameDefaultDescription
system_arguments

N/A

Hash

The arguments accepted by Overlay's show_button slot.

with_item

Adds a new item to the list.

NameDefaultDescription
system_arguments

N/A

Hash

The arguments accepted by ActionList::Item.

with_divider

Adds a divider to the list.

NameDefaultDescription
system_arguments

N/A

Hash

The arguments accepted by ActionList's divider slot.

with_avatar_item

Adds an avatar item to the list. Avatar items are a convenient way to accessibly add an item with a leading avatar image.

NameDefaultDescription
src

N/A

String

The source url of the avatar image.

username

N/A

String

The username associated with the avatar.

full_name

N/A

String

Optional. The user's full name.

full_name_scheme

N/A

Symbol

Optional. How to display the user's full name.

avatar_arguments

N/A

Hash

Optional. The arguments accepted by Avatar.

system_arguments

N/A

Hash

The arguments accepted by ActionList::Item.

ActionMenu::List

This component is part of ActionMenu and should not be used as a standalone component.

Arguments

NameDefaultDescription
system_arguments

N/A

Hash

The arguments accepted by ActionList

Methods

items

Returns the value of attribute items.

ActionMenu::Heading

Heading used to describe groups within an action menu.

ActionMenu::ListWrapper

This component is part of ActionMenu and should not be used as a standalone component.

Arguments

NameDefaultDescription
menu_id

N/A

String

ID of the parent menu.

system_arguments

N/A

Hash

The arguments accepted by ActionList

Slots

heading

Heading text rendered above the list of items.

NameDefaultDescription
component_klass

N/A

Class

The class to use instead of the default ActionList::Heading.

system_arguments

N/A

Hash

The arguments accepted by component_klass.

items

Items. Items can be individual items, avatar items, or dividers. See the documentation for #with_item, #with_divider, and #with_avatar_item respectively for more information.

ActionMenu::Group

This component is part of ActionMenu and should not be used as a standalone component.

Arguments

NameDefaultDescription
id

self.class.generate_id

String

HTML ID value.

role

nil

Boolean

ARIA role describing the function of the list. listbox and menu are a common values.

item_classes

nil

String

Additional CSS classes to attach to items.

scheme

:full

Symbol

One of :full or :inset. inset children are offset (vertically and horizontally) from list edges. full (default) children are flush (vertically and horizontally) with list edges.

show_dividers

false

Boolean

Display a divider above each item in the list when it does not follow a header or divider.

select_variant

:none

Symbol

How items may be selected in the list. One of :multiple, :multiple_checkbox, :none, or :single.

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 ActionMenu instead of using this feature directly.

system_arguments

N/A

Hash

Slots

heading

Heading text rendered above the list of items.

NameDefaultDescription
component_klass

N/A

Class

The class to use instead of the default ActionList::Heading.

system_arguments

N/A

Hash

The arguments accepted by component_klass.

items

Items. Items can be individual items, avatar items, or dividers. See the documentation for #with_item, #with_divider, and #with_avatar_item respectively for more information.

Methods

with_heading

Heading text rendered above the list of items.

NameDefaultDescription
system_arguments

N/A

Hash

The arguments accepted by ActionMenu::Heading.