feat(webkit): add the Menu compound and move MenuItem into it - #853
Merged
Conversation
A vertical, hierarchical navigation menu: groups that separate rows under a title, condensed rows that expand in place behind an indent rail, and drill rows that replace the menu with a second-level menu. It owns no shell — a host (usually Sidebar) supplies the surface, the scroll region and the width. MenuItem moves into the compound's folder so it is a real sub-component rather than a sibling reached across folders. Its ./menu-item export path, props, events, slots and every default are unchanged, so this is additive for consumers. Two drifts against the rows around it are fixed: an empty icon box no longer renders (it reserved a column the row did not use, pushing an icon-less label off the column its siblings hold), and the anchor and button branches now share one label class, so a menu no longer renders two text sizes depending on whether a row happens to carry an href. Its spec folds into .specs/menu.md — a sub-component of a compound is documented in the compound's spec, the way menu-sub and menu-group already are — and .specs/menu-item.md is removed.
… rows 30 added — Menu's five stories (Default, Types, Condensed, Drill, Disabled) across the six modes. 8 modified — the Sidebar stories compose MenuItem, so they pick up the label class moving to .text-label-md and the icon box no longer rendering when empty. Only the mobile and tablet renders move: on the narrower canvases the same shift crosses the 1% pixel threshold that desktop absorbs.
gabriel-lisboa-azion
marked this pull request as ready for review
August 5, 2026 00:58
The inline submenu indent was spacing-sm + spacing-md, which pushed nested rows far enough right that a two-level tree read as two unrelated lists. Step the second term down to spacing-xs so the rail and the nested label stay in one column.
… root CodeQL flagged all six `Menu.<Part>` reads in the compound-API test as property access on an undefined base: its extractor cannot resolve the default export of a `.vue` module, so the compound root is statically undefined and each member access looks like a null dereference. Assert the root once with `expect(Menu).toBeDefined()` and read the members through `?.`. The contract is unchanged — a member that is not attached still fails on `undefined !== expected` — and the guard turns a would-be runtime TypeError into a direct "Menu is undefined" failure.
…dent The 12 refreshed snapshots are Menu's Types and Condensed stories across all six modes — the only two that render inline sub-content, so the only two the narrower --menu-indent moves. Every other baseline is byte-identical.
isaque-bock-azion
approved these changes
Aug 5, 2026
guilherme-santana-azion
approved these changes
Aug 5, 2026
Merged
isaque-bock-azion
added a commit
that referenced
this pull request
Aug 5, 2026
Brings the Menu compound (#853); menu-item resolved keeping main's semantics in canonical token syntax, the retired menu-item spec deleted, the compound's new files canonicalized and the catalog regenerated.
gabriel-lisboa-azion
added a commit
that referenced
this pull request
Aug 5, 2026
The Menu landed on main in #853 as a squash, so every menu file came back as an add/add conflict against this branch's copy. Main's side wins throughout: it is strictly newer, carrying both the tightened inline sub-content indent (spacing-sm + spacing-xs) and the guarded compound assertions. The sidebar baselines this branch deleted stay deleted: it folded the header search and profile footer stories into the richer Default and Resizable ones, so their snapshots are obsolete. The remaining baseline conflicts take main's copy and are regenerated in CI on top of this merge.
gabriel-lisboa-azion
added a commit
that referenced
this pull request
Aug 10, 2026
Bring 254 commits of main's webkit into the sample branch, keeping the illustration system that lives only here. Resolution: - Visual baselines (51 PNGs): main's — CI-generated, main is authoritative. - Sidebar / Menu / Switch cluster: main's. The same two commits exist on both sides (unsquashed locally, squash-merged as #853/#854 on main); main carries the reviewed final state. - Illustration tokens (animate.js, keyframes.js, .size-limit.json, DESIGN.md): kept — main's side held no competing change. - code-block.md / webkit-ui-craft SKILL.md: kept HEAD's frontmatter; both bodies are supersets of main's. - Generated artifacts (theme dist v4 globals.css/.scss, catalog.json): regenerated from the merged sources rather than hand-merged.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A vertical, hierarchical navigation menu. It owns no shell and no layout of its own — a host (usually
Sidebar, but any scroll container works) supplies the surface, the scroll region and the width — and renders three structures through one compound:Unlike
navigation-menu(the horizontal megamenu) this menu is vertical, recursive, and owns a view stack. Its box model follows Cloudflare Kumo'sSidebar; permigration.mdonly the structure is adopted, with every value expressed in our own tokens — the mapping is in the spec's Tokens section.MenuItem moves into the compound
menu-item.vuemoves fromnavigation/menu-item/tonavigation/menu/menu-item/, so it is a real sub-component rather than a sibling reached across folders. This is additive for consumers: the./menu-itemexport path still resolves, and its props, events, slots and every default are unchanged. In the catalog it becomeskind: subcomponent, parent: menu, exactly likemenu-groupandcommand-menu-item.Two drifts against the rows it sits beside are fixed:
size-8box with no glyph in it reserved a column the row did not use, so an icon-less row's label sat off the column its siblings hold and a nesting rail anchored to blank space..text-label-sm(12px) and.text-body-sm(14px), so the same menu rendered two sizes depending on whether a row happened to carry anhref— children came out smaller than their parents. Both are.text-label-md.Specs
.specs/menu-item.mdis removed and its Props / Events / Slots fold into.specs/menu.md's Sub-components entry forMenu.Item— a sub-component of a compound is documented in the compound's spec, the waymenu-subandmenu-groupalready are.MenuItem.stories.jsis likewise removed; the rows are documented throughMenu.stories.js, andmenu-item.test.tsrenders the component directly instead of composing a story fixture (whichtesting.mdallows).sidebar-group.test.tshere carries only the moved import path. Its story-fixture rewrite belongs to the stacked Sidebar PR, which is what makes the Sidebar stories composeMenu.Deliberately out of scope
The wider row redesign (a
size-3icon,var(--primary)on the selected icon,::before/::afterghost layers replacing the roottransition-colors) is a visual breaking change and lands later as aspec_version: 2revision on a major. This PR renders today's row: correct behaviour, old visuals.Follow-up in this PR
Linux visual baselines still to be regenerated via CI (the new
Menustories add baselines, and the label-class change moves the existingSidebar-composed ones).