mirror of
https://github.com/zoriya/v10.git
synced 2026-08-16 02:45:09 +00:00
5.4 KiB
5.4 KiB
Menus Implementation
Design doc: internal/design/ui/menus.md
Branch: feat/menu-ui-component (PR #1078)
Overview
Three PRs along the dependency chain:
PR 1 (Core + DOM) → PR 2 (UI flat) → PR 3 (Submenus)
PR 1 — Core + DOM layer
Status: DONE — feat/menu-core-dom (PR #1503)
Files
New:
packages/core/src/core/ui/menu/menu-core.tspackages/core/src/core/ui/menu/menu-data-attrs.tspackages/core/src/core/ui/menu/menu-item-data-attrs.tspackages/core/src/core/ui/menu/menu-css-vars.tspackages/core/src/core/ui/menu/tests/menu-core.test.tspackages/core/src/dom/ui/menu/create-menu.tspackages/core/src/dom/ui/menu/tests/create-menu.test.tspackages/core/src/dom/ui/menu/tests/create-menu-helpers.ts
Modified:
packages/core/src/core/index.ts— add menu exportspackages/core/src/dom/index.ts— add menu exportspackages/core/src/core/ui/transition.ts— extractTransitionDataAttrspackages/core/src/core/ui/popover/popover-data-attrs.ts— spreadTransitionDataAttrspackages/core/src/core/ui/tooltip/tooltip-data-attrs.ts— spreadTransitionDataAttrspackages/core/src/core/ui/alert-dialog/alert-dialog-data-attrs.ts— spreadTransitionDataAttrs
Key decisions
MenuCorefollowsPopoverCorepattern:setProps+setInput(TransitionState)+getState()isSubmenuprop onMenuCore— suppressespopover="manual"ingetContentAttrsand disables positioning props for nested menusMenuItemDataAttrsis not constrained byStateAttrMapsince items have their own state, notMenuStatedata-directionbelongs in DOM layer alongsideNavigationState, not in core constantscreateMenu()composescreatePopover()internally; items stored as ordered array (registration order matches DOM order for standard React list rendering)destroy()cancels the open RAF and typeahead timer before delegating topopover.destroy()- Open RAF guards against
status === 'ending'to prevent highlight firing during a rapid open/close
PR 2 — UI layer: flat menu (React + HTML)
Status: OPEN — feat/menu-react-html (PR #1504)
React files (packages/react/src/ui/menu/)
context.tsx,index.parts.ts,index.tsmenu-root.tsx,menu-trigger.tsx,menu-content.tsxmenu-item.tsx,menu-label.tsx,menu-separator.tsx,menu-group.tsxmenu-radio-group.tsx,menu-radio-item.tsx,menu-checkbox-item.tsx,menu-item-indicator.tsx
HTML files (packages/html/src/ui/menu/)
menu-element.ts,menu-item-element.ts,menu-label-element.ts,menu-separator-element.tsmenu-group-element.ts,menu-radio-group-element.ts,menu-radio-item-element.tsmenu-checkbox-item-element.ts,menu-item-indicator-element.ts
Modified:
packages/react/src/ui/index.ts— add Menu exportpackages/html/src/define/ui/menu.ts— registration barrelpackages/html/src/ui/index.ts— add menu exports
Scope
- Fully functional flat single-level menu with items, radio groups, checkboxes, labels, separators
- No nested Root / Back / submenu navigation — that comes in PR 4
PR 3 — Submenu navigation
Status: OPEN — feat/menu-sub (PR pending)
Files
New DOM:
packages/core/src/dom/ui/menu/create-menu-view-transition.tspackages/core/src/dom/ui/menu/menu-viewport-transition.ts
New React:
packages/react/src/ui/menu/menu-back.tsxpackages/react/src/ui/menu/menu-view.tsx
New HTML:
packages/html/src/ui/menu/menu-back-element.tspackages/html/src/ui/menu/menu-view-element.ts
Modified:
packages/core/src/dom/ui/menu/create-menu.ts— addpush/poptoMenuApi,NavigationState, wire transitionpackages/react/src/ui/menu/menu-root.tsx— nested Root detects parent context → submenu modepackages/react/src/ui/menu/menu-content.tsx—data-submenu,data-direction, slide transition wiringpackages/react/src/ui/menu/index.parts.ts— exportMenu.BackandMenu.Viewpackages/html/src/ui/menu/menu-element.ts— nested<media-menu>+commandforsupportpackages/html/src/ui/menu/menu-item-element.ts—commandforattribute handlingpackages/core/src/dom/index.ts— add submenu and viewport transition exportspackages/html/src/define/ui/menu.ts— register<media-menu-back>and<media-menu-view>
Status: OPEN — branched off feat/menu-react-html
Scope
NavigationState: stack of{ menuId, triggerId }, direction, exitingMenuId, transitioningcreateMenuViewTransition(): generic menu view double-RAF lifecycle, data attribute hooks,getAnimations()settlemenu-viewport-transition.ts: shared root/child view measurement and--media-menu-width/heightsizingMenu.View/<media-menu-view>: optional root view wrapper for in-place view navigation; receivesdata-menu-root-viewwhile rootContent/<media-menu>acts as the shared viewport- Traditional flyout submenus are out of scope for this PR and should not require
Menu.View/<media-menu-view>when added later - Nested
Menu.Rootdetection via parentMenuContext→isSubmenu: trueprop, Trigger registers as parent item Menu.Back/<media-menu-back>: pops stack, focus restoration to trigger- Auto-back on
RadioItemselection in submenu - RTL: direction-agnostic JS, CSS handles
translateXflip via[dir="rtl"]