dueling-picklist
About Dueling-Picklist
Accessibility
This component is essentially 2 ARIA listboxes side by side, so we follow the ARIA practices guide to help implement their interaction in an accessible way. Some additional details, supplementary to the ARIA guide include:
Markup
aria-multiselectable="true"should be set on each listboxaria-selectedshould be placed on eachrole="option", and set tofalseby defaultaria-labelledbyis used to identify the list to the user and should point to the list labelaria-describedbyis used to provide operation instructions for the Drag and Drop interactiontabindexshould be set to "0" when an item is selected and "-1" otherwise
Focus Management
- Initially, nothing should be selected and the first item in each list should have
tabindex="0" - When an item is focused, it becomes selected
- When focus leaves the list, the last selected item remains selected and focusable. When focus returns to the list focus is placed on the last selected item.
- When moving items:
- With the move button: the items are unselected and added to the target list. The focus should remain on the move button.
- With a keyboard shortcut: focus remains on the item, but in the target list. Since the item is focused, it is also selected.
- If there are already selected items in the target list, they stay selected and the new items are added below them.
Keyboard Interactions
- Each list has a single focusable option inside. There is only ever one focusable option per list and it is expected that a user will use their arrow keys, and some modifier keys, to perform all actions.
- Because we support drag and drop re-ordering within a list, we implement the second multi-select keyboard model.
upanddownarrows move focus and selection, witharia-selected="true". Any previously selected items are deselected.shift + upandshift + downmove focus and creates addition selectionsctrl + downorctrl + upmoves focus but selection remains where it isctrl + spacetoggles selection on the focused option, in addition to previous selectionsctrl + aselects all options in the listcmd/ctrl + rightandcmd/ctrl + leftMoves selected items between listsspacetoggles "Drag and Drop" mode. When in "Drag and Drop" mode:upanddownarrows move the selected items within the current list
Base
Group Label
A Dueling Picklist should have a group label, similar to using a fieldset and legend on grouped form controls. To achieve this, wrap the Dueling Picklist in an slds-form-element and add a div with the same class names that are applied to a legend element in a fieldset, slds-form-element__label slds-form-element__legend.
Labeling the group
It is important that the
slds-form-element<div>has therole="group"attribute applied, along witharia-labelledby, whose value is the ID of the visible group label.
<div class="slds-form-element" role="group" aria-labelledby="picklist-group-label">
<span id="picklist-group-label" class="slds-form-element__label slds-form-element__legend">Select Options</span>
<div class="slds-form-element__control">Responsive
To make the dueling picklist responsive or use it within narrow regions, apply the class slds-dueling-picklist__column_responsive to the <div>s with class slds-dueling-picklist__column that contain options (not the columns that only contain buttons). Any items longer than the space available will truncate with ellipses.
<div class="slds-form-element" role="group" aria-labelledby="picklist-group-label">
<span id="picklist-group-label" class="slds-form-element__label slds-form-element__legend">Select Options</span>
<div class="slds-form-element__control">Adjusting Height
To adjust the height of the listboxes, set the height using an inline style on _both_ of the
<div>s with classslds-dueling-picklist__column. If you are setting it based on a maximum number of items being shown before scrolling, you can setheight = (2.25rem * numItems) + 1rem.
<div class="slds-dueling-list">
<div class="slds-dueling-list__column">
<span class="slds-form-element__label" id="label-1">Available Languages</span>Edit Mode
If the user needs to select multiple options for a field, like a list of languages supported, then use a dueling picklist without the re-order arrows on the right.
Helpful Assistive Text
The assistive text content in the
option-drag-label<div>should provide clear instructions on how to drag and drop with a keyboard.
<div class="slds-form-element" role="group" aria-labelledby="picklist-group-label">
<span id="picklist-group-label" class="slds-form-element__label slds-form-element__legend">Select Options</span>
<div class="slds-form-element__control">Selected Item
Aria Selected
aria-selectedshould be placed on eachrole="option", and set totruewhen the item is selected.
<div class="slds-form-element" role="group" aria-labelledby="picklist-group-label">
<span id="picklist-group-label" class="slds-form-element__label slds-form-element__legend">Select Options</span>
<div class="slds-form-element__control">Multiple Selected Items
<div class="slds-form-element" role="group" aria-labelledby="picklist-group-label">
<span id="picklist-group-label" class="slds-form-element__label slds-form-element__legend">Select Options</span>
<div class="slds-form-element__control">Dropped Items
Aria Live
The
drag-live-region<div>witharia-live="assertive"should update as items are moved to provide context about the state and location of the items.
<div class="slds-dueling-list">
<div class="slds-assistive-text" id="drag-live-region" aria-live="assertive">Arabic and German: Moved to Selected Languages.</div>
</div><div class="slds-form-element" role="group" aria-labelledby="picklist-group-label">
<span id="picklist-group-label" class="slds-form-element__label slds-form-element__legend">Select Options</span>
<div class="slds-form-element__control">Locked Items
If items are not able to be removed or reordered from the selected list, a lock icon appears next to the item name.
Aria Disabled and Assistive Text
For each locked item,
aria-disabled="true"must be applied to.slds-listbox__optionand assistive text (.slds-assistive-text) must be added to.slds-icon_container.
<div class="slds-form-element" role="group" aria-labelledby="picklist-group-label">
<span id="picklist-group-label" class="slds-form-element__label slds-form-element__legend">Select Options</span>
<div class="slds-form-element__control">With Reordering
If the order of the selected options matters, include the vertical arrows to the right. This allows the user to reorder the second listbox of options.
<div class="slds-form-element" role="group" aria-labelledby="picklist-group-label">
<span id="picklist-group-label" class="slds-form-element__label slds-form-element__legend">Select Options</span>
<div class="slds-form-element__control">The following examples show the process of selecting an item, moving it within a list, and dropping it in a final position.
Aria Live
Pay attention to the
drag-live-region<div>witharia-live="assertive". This should update as items are moved to provide context about the state and location of the items at all times.
Item Selected
<div class="slds-form-element" role="group" aria-labelledby="picklist-group-label">
<span id="picklist-group-label" class="slds-form-element__label slds-form-element__legend">Select Options</span>
<div class="slds-form-element__control">Item Grabbed
Within a list, users are able to drag and drop an item.
<div class="slds-form-element" role="group" aria-labelledby="picklist-group-label">
<span id="picklist-group-label" class="slds-form-element__label slds-form-element__legend">Select Options</span>
<div class="slds-form-element__control">Item Moved Within a List
<div class="slds-form-element" role="group" aria-labelledby="picklist-group-label">
<span id="picklist-group-label" class="slds-form-element__label slds-form-element__legend">Select Options</span>
<div class="slds-form-element__control">Item Dropped in a List
<div class="slds-form-element" role="group" aria-labelledby="picklist-group-label">
<span id="picklist-group-label" class="slds-form-element__label slds-form-element__legend">Select Options</span>
<div class="slds-form-element__control">Disabled
If the user is not able to interact with the dueling picklist, then it should be marked as disabled.
Aria Disabled
In disabled mode, both list boxes
ul[role=listbox]should receivearia-disabled="true", and all directional buttons should receive thedisabledattribute.
Utility Class
The class
slds-is-disabledshould also be applied to the divs with the classslds-dueling-list_options.
<div class="slds-form-element" role="group" aria-labelledby="picklist-group-label">
<span id="picklist-group-label" class="slds-form-element__label slds-form-element__legend">Select Options</span>
<div class="slds-form-element__control">Required
<div class="slds-form-element" role="group" aria-labelledby="picklist-group-label">
<span id="picklist-group-label" class="slds-form-element__label slds-form-element__legend">
<abbr class="slds-required" title="required">* </abbr>Select Options</span>With Tooltip
If some contextual information regarding the dueling picklist is needed, add a tooltip next to the group label.
<div class="demo-only" style="padding-top:3rem">
<div class="slds-form-element" role="group" aria-labelledby="picklist-group-label">
<span id="picklist-group-label" class="slds-form-element__label slds-form-element__legend">Select Options</span>Required With Tooltip
<div class="demo-only" style="padding-top:3rem">
<div class="slds-form-element" role="group" aria-labelledby="picklist-group-label">
<span id="picklist-group-label" class="slds-form-element__label slds-form-element__legend">View Mode
When the user is done selecting options, or is in view mode of the field, they are presented with a comma separated list.
<div class="slds-dueling-list">
<div class="slds-form-element">
<span class="slds-form-element__label">Selected Languages</span>