Add one level of submenus to disclosure dropdowns [1/4]
🧩 About this stack (submenu support for disclosure dropdowns)This is a stack of 4 merge requests. Each one builds on the previous branch, so they are small and reviewable in isolation, but together they deliver one feature: submenus for disclosure dropdowns.
# Merge request Adds Target branch 1 (this MR) Actions submenus The submenu foundation + action rows main2 Selection submenus Rows that pick a value (listbox) MR 1 3 Search in selection submenus Search box inside the listbox submenu MR 2 4 Documentation Pajamas guidance, no code MR 3
👀 Just want to see/test the end result?The full experience lands incrementally in Storybook, under Base → Dropdowns → Disclosure Dropdown:
- This MR (1): story
NestedDropdown— hover/click a row to reveal a submenu of links and actions.- MR 2 adds story
NestedListboxSubmenu(choose a value, single + multi-select).- MR 3 extends
NestedListboxSubmenuwith a searchable submenu.Review order: read them bottom-to-top for context, but they merge top-to-bottom (1 → 2 → 3 → 4). Merging this MR retargets MR 2 onto
mainautomatically.
What does this MR do?
Adds the foundation for one level of submenus in disclosure dropdowns, plus the first submenu variant: action submenus (rows that reveal more links or actions).
submenu_mixin.jsholds behaviour shared by all submenu variants: positioning, hover intent, small-viewport handling, open/close, and registration with the owning dropdown.GlDisclosureDropdownItemNestedrenders a row that reveals more links or actions. Give an item achildrenarray, directly or viaitems.- Depth is capped at one level.
itemsValidatorrejects deeper trees andGlDisclosureDropdownlogs a warning explaining the rule, rather than silently truncating.
Shared files touched (worth extra review)
base_dropdown.vuelearns to treat nested panels as part of the dropdown for close/containment purposes.disclosure_dropdown.vuegains the submenu registry (one open at a time) plus focus delegation:focusNextItemnow resolves an event target to its owning row viaclosest, andfocusItemfocuses the row's button when the row itself isn't focusable.
Screenshots or screen recordings
Test in Storybook: Base → Dropdowns → Disclosure Dropdown → NestedDropdown.
Verification
- Tests: 24 new for the component (plus depth-validator and warning coverage); 423 in the suite for this branch; full package suite: 4213 passing.
- Lint: clean.
- Axe: 0 violations (submenus open + closed).
- Exports
GlDisclosureDropdownItemNested.
⚠️ Known CI failure
Visual baselines. The new NestedDropdown story has no baseline yet, so the visual test job will fail until baselines are regenerated (or the story is tagged skip-visual-test, as WithDynamicWrapperText does). This is expected and tracked, not a regression.
Related
Related to #3274. Supersedes the earlier single-MR attempt !6053 (closed).