Context Menu
Examples
| Positioning | Screenshot |
|---|---|
| Container position: below Container justify to caret: left Caret justify to trigger: center | |
| Container position: above Container justify to caret: right Caret justify to trigger: center | |
| Container position: left Container align to caret: start Caret align to trigger: end | |
| Container position: right Container align to caret: end Caret align to trigger: center | |
| Container position: left Container align to caret: center Caret align to trigger: center |
Usage
Dos:
- Use short and precise labels for menu items.
- Use as few menu items as possible.
Donts:
- Don’t overwhelm users with expansive lists of menu items. Keep the list length manageable by including fewer than 10–12 items, to avoid choice overload.
Implementation notes
The Context Menu involves 2 main elements:
trigger: typically a button, which is intended to open thecontainerwhen clicked.container: the menu itself, which is hidden until activated by thetrigger.
To initialize interactive behavior and make the component accessible, we use JavaScript that will identify triggers by querying for the bux-context-menu__trigger class, then looking for each trigger's corresponding container by finding the first element occuring after the trigger in the DOM order that has the bux-context-menu__container class. This allows for some flexibility in your DOM structure, but typically it's easiest to put the container element immediately after its trigger.
The Twig template relies on the JavaScript and CSS portions of the component to fill in several important attributes -- see the Accessibility section for more information.
Keeping the menu open on clicks outside the container
By default, the menu will collapse if the user clicks outside of the container. To override this behavior and keep the menu open until the user clicks the trigger again or presses Escape, you can add the data-stay-open="true" attribute to the trigger element. This can also be passed in as the stay_open variable in the Twig template.
Positioning
By default, the container will open beneath the trigger element, with the caret justified to the trigger's center, and the container justified to the start of the caret. This is powered by an underlying popover system, and you can adjust it with classes on the trigger and container.
First, on the container element, specify:
- how to position the container relative to the trigger
- Above:
container--position-above-trigger - Below:
container--position-below-trigger - Left of:
container--position-left-of-trigger - Right of:
container--position-right-of-trigger
- Above:
- and how to justify or align the container to the caret:
- If the container is above or below the trigger, the caret will be on the bottom or top of the container, respectively, so you'll justify the container and caret.
- Left:
container--justify-caret-left - Center:
container--justify-caret-center - Right:
container--justify-caret-right
- Left:
- If the container is left of or right of the trigger, the caret will be on the right or left side of the container, respectively, so you'll align the container and caret.
- Top/start:
container--align-caret-start - Center:
container--align-caret-center - Bottom/end:
container--align-caret-end
- Top/start:
- If the container is above or below the trigger, the caret will be on the bottom or top of the container, respectively, so you'll justify the container and caret.
Then, on the caret element, you can specify how the caret should align or justify to the trigger
- If the container is above or below the trigger, the caret will be pointing to the top or bottom of the trigger, respectively, so you'll justify the caret and trigger.
- Left:
caret--justify-trigger-left - Center:
caret--justify-trigger-center - Right:
caret--justify-trigger-right
- Left:
- If the container is right of or left of the trigger, the caret will be pointing to the right or left side of the trigger, respectively, so you'll align the caret and trigger.
- Top/start:
caret--align-trigger-start - Center:
caret--align-trigger-center - Bottom/end:
caret--align-trigger-end
- Top/start:
Accessibility
Relationships
On page load, the JavaScript for this component will set up the relationship between the trigger by generating a unique DOM ID, assigning it to the container, and setting the trigger's aria-owns to it. On expand and collapse, the trigger gets updated with aria-expanded="true" and aria-expanded="false", respectively.
Hiding when collapsed
When collapsed, the container is hidden visually, from find-in-page behavior, and from accessible technology with inert and display: none. The trigger element should have a descriptive label. For instance, in an icon button, this could be visually hidden text inside the button.
Focus management
When collapsed, the container's items are not focusable due to display: none and inert. When expanded, the JavaScript will set focus to the first item in the list. From there, focus is trapped in the component by keydown listeners, and will move from the last item in the menu back up to the trigger.
Keyboard navigation
TabandArrowDown: moves focus to the next item in the menu. Will move back to the trigger button if pressed from the last item in the menu.Shift+TabandArrowUp: moves focus to the previous item in the menu. Will move to the last item in the menu if pressed from the trigger button.Home: moves focus to the first item in the menu.End: moves focus to the last item in the menu.Escape: closes the menu.