Class: Primer::Alpha::ActionMenu
- Defined in:
- app/components/primer/alpha/action_menu.rb,
app/components/primer/alpha/action_menu/list.rb
Overview
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 ‘ActionMenu`s 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.
### ‘ActionMenu`s as form inputs
When using either the ‘single` or `multiple` select variants, `ActionMenu`s 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:
“‘erb <% 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:
“‘ruby 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:
“‘erb <%= 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:
“‘erb <%= 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.
|Name |Type |Default|Description| |:—————-|:————-|:——|:———-| |‘method` |`Symbol` |`:get` |The HTTP request method to use to submit the form. One of `:get`, `:post`, `:patch`, `:put`, `:delete`, or `:head`| |`name` |`String` |`nil` |The name of the field that will be sent to the server on submit.| |`value` |`String` |`nil` |The value of the field that will be sent to the server on submit.| |`input_arguments`|`Hash` |`{}` |Additional key/value pairs to emit as HTML attributes on the `<input type=“hidden”>` element.| |`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.|
The elements of the ‘inputs:` array will be emitted as HTML `<input type=“hidden”>` elements.
Defined Under Namespace
Classes: List
Constant Summary collapse
- DEFAULT_PRELOAD =
false
- DEFAULT_SELECT_VARIANT =
:none
- SELECT_VARIANT_OPTIONS =
[ :single, :multiple, DEFAULT_SELECT_VARIANT ].freeze
Constants inherited from Component
Component::INVALID_ARIA_LABEL_TAGS
Constants included from Status::Dsl
Constants included from ViewHelper
Constants included from TestSelectorHelper
TestSelectorHelper::TEST_SELECTOR_TAG
Constants included from FetchOrFallbackHelper
FetchOrFallbackHelper::InvalidValueError
Constants included from Primer::AttributesHelper
Primer::AttributesHelper::PLURAL_ARIA_ATTRIBUTES, Primer::AttributesHelper::PLURAL_DATA_ATTRIBUTES
Instance Attribute Summary collapse
-
#list ⇒ Object
readonly
Returns the value of attribute list.
-
#preload ⇒ Object
(also: #preload?)
readonly
Returns the value of attribute preload.
Instance Method Summary collapse
-
#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: {}, **system_arguments) ⇒ ActionMenu
constructor
A new instance of ActionMenu.
-
#with_avatar_item(**system_arguments, &block) ⇒ Object
Adds an avatar item to the list.
-
#with_divider(**system_arguments, &block) ⇒ Object
Adds a divider to the list.
-
#with_item(**system_arguments, &block) ⇒ Object
Adds a new item to the list.
-
#with_show_button(**system_arguments, &block) ⇒ Object
Button to activate the menu.
Methods inherited from Component
Methods included from JoinStyleArgumentsHelper
Methods included from TestSelectorHelper
Methods included from FetchOrFallbackHelper
#fetch_or_fallback, #fetch_or_fallback_boolean, #silence_deprecations?
Methods included from ClassNameHelper
Methods included from Primer::AttributesHelper
#aria, #data, #merge_aria, #merge_data, #merge_prefixed_attribute_hashes
Constructor Details
#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: {}, **system_arguments) ⇒ ActionMenu
Returns a new instance of ActionMenu.
158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 |
# File 'app/components/primer/alpha/action_menu.rb', line 158 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: {}, **system_arguments ) @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 = Primer::Alpha::Overlay.new( id: "#{@menu_id}-overlay", title: "Menu", visually_hide_title: true, anchor_align: anchor_align, anchor_side: anchor_side, size: size ) @list = Primer::Alpha::ActionMenu::List.new( menu_id: @menu_id, select_variant: select_variant, form_arguments: form_arguments ) end |
Instance Attribute Details
#list ⇒ Object (readonly)
Returns the value of attribute list.
143 144 145 |
# File 'app/components/primer/alpha/action_menu.rb', line 143 def list @list end |
#preload ⇒ Object (readonly) Also known as: preload?
Returns the value of attribute preload.
143 144 145 |
# File 'app/components/primer/alpha/action_menu.rb', line 143 def preload @preload end |
Instance Method Details
#with_avatar_item(**system_arguments, &block) ⇒ Object
Adds an avatar item to the list. Avatar items are a convenient way to accessibly add an item with a leading avatar image.
242 243 244 |
# File 'app/components/primer/alpha/action_menu.rb', line 242 def with_avatar_item(**system_arguments, &block) @list.with_avatar_item(**system_arguments, &block) end |
#with_divider(**system_arguments, &block) ⇒ Object
Adds a divider to the list.
230 231 232 |
# File 'app/components/primer/alpha/action_menu.rb', line 230 def with_divider(**system_arguments, &block) @list.with_divider(**system_arguments, &block) end |
#with_item(**system_arguments, &block) ⇒ Object
Adds a new item to the list.
223 224 225 |
# File 'app/components/primer/alpha/action_menu.rb', line 223 def with_item(**system_arguments, &block) @list.with_item(**system_arguments, &block) end |
#with_show_button(**system_arguments, &block) ⇒ Object
Button to activate the menu.
210 211 212 |
# File 'app/components/primer/alpha/action_menu.rb', line 210 def (**system_arguments, &block) @overlay.(**system_arguments, id: "#{@menu_id}-button", controls: "#{@menu_id}-list", &block) end |