class Primer::Alpha::ActionMenu
“‘
})
event.detail.checked // boolean: whether or not the result of the activation checked the item
event.detail.item // Element: the <li> item that was activated
document.querySelector(“action-menu”).addEventListener(“itemActivated”, (event: CustomEvent<ItemActivatedEvent>) => {
“`typescript
The `<action-menu>` element fires an `itemActivated` event whenever an item is activated (eg. clicked) via the mouse or keyboard.
#### Events
* `uncheckItem(item: Element)`: Unchecks the item. Only has an effect in multi-select mode, since items cannot be unchecked in single-select mode.
* `checkItem(item: Element)`: Checks the item. Only has an effect in single- and multi-select modes.
* `disableItem(item: Element)`: Disables the item, i.e. makes it unclickable by the mouse and keyboard.
* `enableItem(item: Element)`: Enables the item, i.e. makes it clickable by the mouse and keyboard.
* `hideItem(item: Element)`: Hides the item, i.e. makes it invisible.
* `showItem(item: Element)`: Shows the item, i.e. makes it visible.
#### State methods
“`
<% end %>
<% menu.with_item(item_id: “my-id”) %>
<%= render(Primer::Alpha::ActionMenu.new) do |menu| %>
“`erb
HTML attribute. Item IDs can be provided by passing an `item_id:` attribute when adding items to the list, eg:
NOTE: Item IDs are special values provided by the user that are attached to `ActionMenu` items as the `data-item-id`
* `isItemDisabled(item: Element): boolean`: Returns `true` if the item is disabled, `false` otherwise.
* `isItemHidden(item: Element): boolean`: Returns `true` if the item is hidden, `false` otherwise.
* `isItemChecked(item: Element): boolean`: Returns `true` if the item is checked, `false` otherwise.
* `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.
#### Query methods
`ActionMenu`s render an `<action-menu>` custom element that exposes behavior to the client.
### JavaScript API
[WAI-ARIA Authoring Practices](www.w3.org/TR/wai-aria-practices-1.2/#menu).
Additional information around the keyboard functionality and implementation can be found on the
nested inside of it. When a menu item is selected, the menu will close immediately.
The action for the menu item needs to be on the element with `role=“menuitem”`. Semantics are removed for everything
@accessibility
The elements of the `inputs:` array will be emitted as HTML `<input type=“hidden”>` elements.
|`inputs` |`Array<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.|
|`input_arguments`|`Hash` |`{}` |Additional key/value pairs to emit as HTML attributes on the `<input type=“hidden”>` element.|
|`value` |`String` |`nil` |The value of the field that will be sent to the server on submit.|
|`name` |`String` |`nil` |The name of the field that will be sent to the server on submit.|
|`method` |`Symbol` |`:get` |The HTTP request method to use to submit the form. One of `:get`, `:post`, `:patch`, `:put`, `:delete`, or `:head`|
|:—————-|:————-|:——|:———-|
|Name |Type |Default|Description|
The following table summarizes the arguments allowed in the `form_arguments:` hash mentioned above.
### Form arguments
“`
<% end %>
) %>
}
}],
value: “some value”,
name: “some_other_field”,
}, {
value: “repository”
name: “group_by”,
inputs: [{
method: :post,
form_arguments: {
href: update_repo_grouping_path,
label: “Repository”,
<% menu.with_item(
<% menu.with_show_button { “Group By” } %>
<%= render(Primer::Alpha::ActionMenu.new) do |menu| %>
“`erb
the `inputs:` argument:
It is possible to include multiple fields on submit. Instead of passing the `name:` and `value:` arguments, pass an array via
is given, the name, eg. `“group_by”`, will be used as the value.
the URL passed in the `href:` argument, including a parameter named `“group_by”` with a value of `“repository”`. If no value
Make sure to specify `method: :post`, as the default is `:get`. When clicked, the list item will submit a POST request to
“`
<% end %>
) %>
}
value: “repository”
name: “group_by”,
method: :post,
form_arguments: {
href: update_repo_grouping_path,
label: “Repository”,
<% menu.with_item(
<%= render(Primer::Alpha::ActionMenu.new) do |menu| %>
“`erb
the `form_arguments:` argument to the appropriate item:
also permit navigation via `POST` requests. To enable this behavior, include the `href:` argument as normal, but also pass
Whereas `ActionMenu` items normally permit navigation via `<a>` tags which make HTTP `get` requests, `ActionMenu` items
### `ActionMenu` items that submit forms
“`
end
end
params.permit(:merge_strategy)
def merge_strategy_params
private
end
puts “You chose #{merge_strategy_params}”
def update
class MergeStrategyController < ApplicationController
“`ruby
corresponding `MergeStrategyController` that might be written to handle the form 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
The value of the ‘data: { value: … }` argument is sent to the server on submit, keyed using the name provided above
“`
<% end %>
<% end %>
<% menu.with_item(label: “Theirs”, data: { value: “theirs” }) %>
<% menu.with_item(label: “Ours”, data: { value: “ours” }) %>
<% menu.with_item(label: “Recursive”, data: { value: “recursive” }) %>
<% menu.with_item(label: “Fast forward”, data: { value: “fast_forward” }) %>
<%= render(Primer::Alpha::ActionMenu.new(form_arguments: { builder: f, name: “merge_strategy” })) do |menu| %>
<% form_with(url: update_merge_strategy_path) do |f| %>
“`erb
`form_arguments:` argument, including the Rails form builder object and the name of the field:
similarly to how HTML `<select>` boxes behave, and play nicely with Rails’ built-in form mechanisms. Pass arguments via the
When using either the ‘single` or `multiple` select variants, `ActionMenu`s can be used as form inputs. They behave very
### `ActionMenu`s as form inputs
For more information, see the documentation on supported arguments below.
Pass `dynamic_label: true` to enable dynamic label behavior, and pass `dynamic_label_prefix: “<string>”` to set a custom prefix.
Dynamic labels can also be prefixed with custom text.
When using the `single` select variant, an optional label indicating the selected item can be displayed inside the menu button.
### Dynamic labels
supported arguments below.
Use the `select_variant:` option to control which variant the `ActionMenu` uses. For more information, see the documentation on
multiple items may be selected and check marks will appear next to each selected item.
when clicked, which will cause a check mark to appear to the left of the item text. When the `multiple` select variant is chosen,
`single` and `multiple` select variants. The single select variant allows a single item to be “selected” (i.e. marked “active”)
While `ActionMenu`s default to a list of buttons that can link to other pages, copy text to the clipboard, etc, they also support
### Select variants
The only allowed elements for the `Item` components are: `:a`, `:button`, and `:clipboard-copy`. The default is `:button`.
users interact with buttons, actions, or other controls.
ActionMenu is used for actions, navigation, to display secondary options, or single/multi select lists. They appear when
def before_render
def before_render content raise ArgumentError, "`items` cannot be set when `src` is specified" if @src.present? && @list.items.any? end
def initialize(
-
system_arguments
(Hash
) -- <%= link_to_system_arguments_docs %>. -
overlay_arguments
(Hash
) -- Arguments to pass to the underlying <%= link_to_component(Primer::Alpha::Overlay) %> -
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. -
select_variant
(Symbol
) -- <%= one_of(Primer::Alpha::ActionMenu::SELECT_VARIANT_OPTIONS) %> -
dynamic_label_prefix
(String
) -- If provided, the prefix is prepended to the dynamic label and displayed in the show button. -
dynamic_label
(Boolean
) -- Whether or not to display the text of the currently selected item in the show button. -
preload
(Boolean
) -- When true, and src is present, loads the `include-fragment` on trigger hover. -
src
(String
) -- Used with an `include-fragment` element to load menu content from the given source URL. -
size
(Symbol
) -- <%= one_of(Primer::Alpha::Overlay::SIZE_OPTIONS) %>. -
anchor_side
(Symbol
) -- <%= one_of(Primer::Alpha::Overlay::ANCHOR_SIDE_OPTIONS) %>. -
anchor_align
(Symbol
) -- <%= one_of(Primer::Alpha::Overlay::ANCHOR_ALIGN_OPTIONS) %>. -
menu_id
(String
) -- Id of the menu.
def initialize( menu_id: self.class.generate_id, anchor_align: Primer::Alpha::Overlay::DEFAULT_ANCHOR_ALIGN, anchor_side: Primer::Alpha::Overlay::DEFAULT_ANCHOR_SIDE, size: Primer::Alpha::Overlay::DEFAULT_SIZE, src: nil, preload: DEFAULT_PRELOAD, dynamic_label: false, dynamic_label_prefix: nil, select_variant: DEFAULT_SELECT_VARIANT, form_arguments: {}, overlay_arguments: {}, **system_arguments ) @menu_id = menu_id @src = src @preload = fetch_or_fallback_boolean(preload, DEFAULT_PRELOAD) @system_arguments = deny_tag_argument(**system_arguments) @system_arguments[:preload] = true if @src.present? && preload? @select_variant = fetch_or_fallback(SELECT_VARIANT_OPTIONS, select_variant, DEFAULT_SELECT_VARIANT) @system_arguments[:tag] = :"action-menu" @system_arguments[:"data-select-variant"] = select_variant @system_arguments[:"data-dynamic-label"] = "" if dynamic_label @system_arguments[:"data-dynamic-label-prefix"] = dynamic_label_prefix if dynamic_label_prefix.present? overlay_arguments[:data] = merge_data( overlay_arguments, data: { target: "action-menu.overlay" } ) @overlay = Primer::Alpha::Overlay.new( id: "#{@menu_id}-overlay", title: "Menu", visually_hide_title: true, anchor_align: anchor_align, anchor_side: anchor_side, size: size, **overlay_arguments ) @list = Primer::Alpha::ActionMenu::List.new( menu_id: @menu_id, select_variant: select_variant, form_arguments: form_arguments ) end
def render?
def render? @list.items.any? || @src.present? end
def with_avatar_item(**system_arguments, &block)
-
system_arguments
(Hash
) -- The arguments accepted by <%= link_to_component(Primer::Alpha::ActionList::Item) %>. -
avatar_arguments
(Hash
) -- Optional. The arguments accepted by <%= link_to_component(Primer::Beta::Avatar) %>. -
full_name_scheme
(Symbol
) -- Optional. How to display the user's full name. -
full_name
(String
) -- Optional. The user's full name. -
username
(String
) -- The username associated with the avatar. -
src
(String
) -- The source url of the avatar image.
def with_avatar_item(**system_arguments, &block) @list.with_avatar_item(**system_arguments, &block) end
def with_divider(**system_arguments, &block)
-
system_arguments
(Hash
) -- The arguments accepted by <%= link_to_component(Primer::Alpha::ActionList) %>'s `divider` slot.
def with_divider(**system_arguments, &block) @list.with_divider(**system_arguments, &block) end
def with_group(**system_arguments, &block)
def with_group(**system_arguments, &block) @list.with_group(**system_arguments, &block) end
def with_item(**system_arguments, &block)
-
system_arguments
(Hash
) -- The arguments accepted by <%= link_to_component(Primer::Alpha::ActionList::Item) %>.
def with_item(**system_arguments, &block) @list.with_item(**system_arguments, &block) end
def with_show_button(**system_arguments, &block)
-
system_arguments
(Hash
) -- The arguments accepted by <%= link_to_component(Primer::Alpha::Overlay) %>'s `show_button` slot.
def with_show_button(**system_arguments, &block) @overlay.with_show_button(**system_arguments, id: "#{@menu_id}-button", controls: "#{@menu_id}-list") do |button| evaluate_block(button, &block) end end