SelectPanel replaces SelectMenu from Primer CSS
The Primer SelectPanel component in Primer ViewComponents should be used instead of the SelectMenu component from Primer CSS. SelectPanel provides accessibility improvements, supports multiple data fetching strategies, customizable filtering behavior, and other enhancements.
SelectPanel show_button slot renders a Primer button
SelectPanel uses a show_button slot that renders a Primer button, replacing the <summary> element used in SelectMenu. The show_button can be set with button text in an ERB template.
SelectPanel can be opened programmatically with show() method
Panels can be opened in JavaScript by calling the show() method on the select-panel element: document.querySelector('select-panel').show();
SelectPanel has dialog behavior built in
SelectPanel uses the native <dialog> element under the hood and exhibits dialog behavior: it traps focus, prevents scrolling content under the dialog, and appears anchored to its show button like a menu or popover. SelectMenu does not have these behaviors.
SelectPanel fetch strategies: remote, eventually_local, local
SelectPanel supports three fetch strategies via the fetch_strategy argument: ':remote' (default, fetches items whenever user types in filter input using <remote-input>), ':eventually_local' (fetches items once when panel opens using <include-fragment>), and ':local' (static list, no remote requests). For :remote and :eventually_local strategies, items are fetched using the URL provided in the src: argument.
SelectPanel static list uses item slot with label argument
When rendering a static list with the :local fetch strategy, use the item slot to define list items. The label: argument is required.
SelectPanel remote responses use ItemList component
When rendering a dynamic list where items are fetched from a remote server, the SelectPanel component expects remote responses to render instances of Primer::Alpha::SelectPanel::ItemList. The ItemList component is the same component that static SelectPanels use to render list items.
SelectPanel remote responses require text/fragment+html content type
The <include-fragment> and <remote-input> elements that SelectPanel uses require that responses have a content type of text/fragment+html.
SelectPanel item active state set with active: true
Items can be marked as checked by passing active: true to the item's constructor in SelectPanel.
SelectPanel select_variant options: single and multiple
SelectPanel automatically manages list item state. Selection behavior is controlled via the select_variant: argument with options ':single' (the default) and ':multiple' for multi-select support.
SelectPanel select_variant must match between panel and ItemList
When rendering panels and their corresponding dynamic list items, pass the same select_variant: argument to both SelectPanel.new and SelectPanel::ItemList.new, or unexpected behavior may occur.
SelectPanel items require value: argument for remote fetch with selection
When using the :remote fetch strategy in combination with single- or multi-select modes, list items must be uniquely identifiable via the value: argument so the component can track which items have been selected. This allows the component to reconcile client-side selections with server-reported selections. Neglecting to provide values can lead to unexpected selection behavior.
SelectPanel automatically displays Spinners during remote fetches
The SelectPanel component automatically displays Spinners during initial and subsequent remote fetches and announces to screen reader users when requests have succeeded or failed. There is no need to render custom spinners or make custom announcements.
SelectPanel show_button ERB example
<%= render(Primer::Alpha::SelectPanel.new) do |panel| %>
<% panel.with_show_button { "Click me" } %>
<% end %>
This example shows how to render a SelectPanel with a show_button that displays the text 'Click me'.
SelectPanel fetch_strategy configuration example
<%= render(Primer::Alpha::SelectPanel.new(
fetch_strategy: :remote,
src: probably_some_rails_path_helper
)) %>
This example shows how to configure a SelectPanel with the :remote fetch strategy and specify a src URL.
SelectPanel static item example
<%= render(Primer::Alpha::SelectPanel.new) do |panel| %>
<% panel.with_item(label: "My item") %>
<% end %>
This example shows how to render a SelectPanel with a static list item.
SelectPanel ItemList rendering example
<%= render(Primer::Alpha::SelectPanel::ItemList.new) do |list| %>
<% list.with_item(label: "My item") %>
<% end %>
This example shows how to render an ItemList component for use in remote responses.
SelectPanel active item example
<%= render(Primer::Alpha::SelectPanel.new) do |panel| %>
<% panel.with_item(label: "My item", active: true) %>
<% end %>
This example shows how to mark an item as active (checked) in a SelectPanel.
SelectPanel multiple select variant example
<%= render(Primer::Alpha::SelectPanel.new(
select_variant: :multiple
)) %>
This example shows how to configure a SelectPanel to support multi-select behavior.
SelectPanel item with value argument example
<%= render(Primer::Alpha::SelectPanel.new(
select_variant: :multiple,
fetch_strategy: :remote
)) do |panel| %>
<% panel.with_item(label: "Apples", content_arguments: { data: { value: "apples" } }) %>
<% panel.with_item(label: "Bananas", content_arguments: { data: { value: "bananas" } }) %>
<% end %>
This example shows how to provide unique identifiers via the value: argument for items in a remote SelectPanel with multi-select enabled.