feat(sw): integrate home menu into SWHeader (Task A + B)

Combine Task A (e8409ef, SW 0.2.0 integrated improvement) with Task B
(396539d, Figma-based SWHomeMenu / SWHomeMenuSection / SWHomeMenuItem /
SWRecentFiles). Task B's 84 new files are taken unchanged except for the
public-import Storybook update and joining the popup Escape stack.

- Export the home menu from @hm-design/sw
- SWHeader homeMenu / homeMenuOpen / defaultHomeMenuOpen /
  onHomeMenuOpenChange: hidden by default, the logo toggles it (onHomeClick
  is not called while homeMenu is set), placed from the measured header,
  closes with / closes the document and field dropdowns
- Logo aria-expanded / aria-controls; menu layer CSS (z-index 20)
- AI catalog / patterns / design rules, example G, README, usage guide
- Storybook SW/Home Menu uses @hm-design/sw; integration story

Verified: SW typecheck, tsc -b, SW build, Storybook build, AI docs 22/22,
28/28 existing SW shots pixel-identical, regression 96 PASS / 0 FAIL,
home menu checks 22/22. Not run: tarball consumer install.
This commit is contained in:
shkim4 committed 2026-10-19 15:39:47 +09:00
1 parent e8409eff44
commit 1472e51f47
110 files changed
+6463 -17

No files matched your search

@@ -0,0 +1,34 @@
{
"browser": "155.0.8059.80",
"shots": [
"overview-1920.png",
"detail-buttons-1920.png",
"interactive-states-1920.png",
"window-move-motion-1920.png",
"logo-slot-1920.png",
"document-dropdown-1920.png",
"responsive-more-1920.png",
"k-guide-1920.png",
"property-panel-compare-1920.png",
"composed-controls-1920.png",
"overview-1800.png",
"overview-1440.png",
"overview-1180.png",
"overview-1080.png",
"overview-900.png",
"overview-768.png",
"overview-640.png",
"overview-520.png",
"overview-390.png",
"responsive-more-1800.png",
"responsive-more-1440.png",
"responsive-more-1180.png",
"responsive-more-1080.png",
"responsive-more-900.png",
"responsive-more-768.png",
"responsive-more-640.png",
"responsive-more-520.png",
"responsive-more-390.png"
],
"errors": []
}
@@ -0,0 +1,34 @@
{
"browser": "155.0.8059.80",
"shots": [
"overview-1920.png",
"detail-buttons-1920.png",
"interactive-states-1920.png",
"window-move-motion-1920.png",
"logo-slot-1920.png",
"document-dropdown-1920.png",
"responsive-more-1920.png",
"k-guide-1920.png",
"property-panel-compare-1920.png",
"composed-controls-1920.png",
"overview-1800.png",
"overview-1440.png",
"overview-1180.png",
"overview-1080.png",
"overview-900.png",
"overview-768.png",
"overview-640.png",
"overview-520.png",
"overview-390.png",
"responsive-more-1800.png",
"responsive-more-1440.png",
"responsive-more-1180.png",
"responsive-more-1080.png",
"responsive-more-900.png",
"responsive-more-768.png",
"responsive-more-640.png",
"responsive-more-520.png",
"responsive-more-390.png"
],
"errors": []
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

@@ -0,0 +1,363 @@
{
"browser": "155.0.8059.80",
"checks": [
{
"name": "Storybook SW titles: Header, Tool, Popup, Home Menu; no SW/Header/Options",
"status": "PASS",
"data": [
"SW/Header",
"SW/Home Menu",
"SW/Popup",
"SW/Tool"
]
},
{
"name": "menu at Figma x 375, width 1305, height 77 (measured, no fixed x); header stays 49",
"status": "PASS",
"data": {
"left": 375,
"width": 1305,
"height": 77,
"headerHeight": 49,
"sections": [
340,
260,
180,
260,
261
],
"tiles": 15,
"tileSizes": [
"80x46"
],
"titles": 5,
"badgeInlined": true,
"icons": 30,
"iconsLoaded": 30
}
},
{
"name": "5 sections 340/260/180/260/261, 15 tiles 80x46, 5 titles",
"status": "PASS",
"data": {
"left": 375,
"width": 1305,
"height": 77,
"headerHeight": 49,
"sections": [
340,
260,
180,
260,
261
],
"tiles": 15,
"tileSizes": [
"80x46"
],
"titles": 5,
"badgeInlined": true,
"icons": 30,
"iconsLoaded": 30
}
},
{
"name": "title badge SVG and 30 tile icons render",
"status": "PASS",
"data": {
"left": 375,
"width": 1305,
"height": 77,
"headerHeight": 49,
"sections": [
340,
260,
180,
260,
261
],
"tiles": 15,
"tileSizes": [
"80x46"
],
"titles": 5,
"badgeInlined": true,
"icons": 30,
"iconsLoaded": 30
}
},
{
"name": "hidden by default (not in DOM), logo aria-expanded=false",
"status": "PASS"
},
{
"name": "logo click opens, aria-expanded=true, aria-controls → menu id",
"status": "PASS"
},
{
"name": "tile Hover: label #FF5C00",
"status": "PASS",
"data": "rgb(255, 92, 0)"
},
{
"name": "tile click → Active (aria-pressed true), re-click → Default",
"status": "PASS",
"data": "true"
},
{
"name": "logo re-click closes; onHomeClick never called while homeMenu is set",
"status": "PASS",
"data": "onHomeMenuOpenChange(false, home)\nonItemSelect(working / save, active=false)\nonActiveChange([])\nonItemSelect(working / save, active=true)\nonActiveChange([save])\nonHomeMenuOpenChange(true, home)"
},
{
"name": "Escape inside closes the menu and returns focus to the logo",
"status": "PASS"
},
{
"name": "click on the menu background closes it (Figma CLOSE)",
"status": "PASS"
},
{
"name": "recent panel opens (outline accent); Escape closes the panel, then the menu",
"status": "PASS",
"data": {
"panelOpen": true,
"panelFirst": true
}
},
{
"name": "opening the document dropdown closes the menu (reason document); New / Open stay in the dropdown",
"status": "PASS",
"data": "C0020101-006-평면및종단면도(06)\nC0020101-007-횡단면도\n+ New\nOpen"
},
{
"name": "opening the menu closes the document dropdown",
"status": "PASS"
},
{
"name": "no separate Open button next to the logo (documentOpenPlacement=\"menu\")",
"status": "PASS"
},
{
"name": "focus outside: Escape closes the most recent (menu), then the popup",
"status": "PASS",
"data": {
"step1": {
"menu": 0,
"popup": 1
},
"step2": {
"menu": 0,
"popup": 0
}
}
},
{
"name": "popup opened after the menu: Escape outside closes the popup first, menu stays",
"status": "PASS",
"data": {
"menu": 1,
"popup": 0
}
},
{
"name": "Escape inside the popup closes only the popup",
"status": "PASS",
"data": {
"menu": 1,
"popup": 0
}
},
{
"name": "Escape inside the menu closes only the menu (popup stays), focus → logo",
"status": "PASS",
"data": {
"menu": 0,
"popup": 1,
"focusHome": true
}
},
{
"name": "every width: menu starts at object area −2px, ends at the window area, covers neither logo nor file name, header 49, no page scroll",
"status": "PASS",
"data": [
{
"width": 1920,
"headerHeight": 49,
"start": 0,
"endGap": 0,
"coversHome": false,
"coversDocument": false,
"menuWidth": 1305,
"scrolls": false,
"pageScroll": false
},
{
"width": 1440,
"headerHeight": 49,
"start": 0,
"endGap": 0,
"coversHome": false,
"coversDocument": false,
"menuWidth": 825,
"scrolls": true,
"pageScroll": false
},
{
"width": 1080,
"headerHeight": 49,
"start": 0,
"endGap": 0,
"coversHome": false,
"coversDocument": false,
"menuWidth": 639,
"scrolls": true,
"pageScroll": false
},
{
"width": 768,
"headerHeight": 49,
"start": 0,
"endGap": 0,
"coversHome": false,
"coversDocument": false,
"menuWidth": 288,
"scrolls": true,
"pageScroll": false
},
{
"width": 520,
"headerHeight": 49,
"start": 0,
"endGap": 0,
"coversHome": false,
"coversDocument": false,
"menuWidth": 288,
"scrolls": true,
"pageScroll": false
},
{
"width": 390,
"headerHeight": 49,
"start": 0,
"endGap": 0,
"coversHome": false,
"coversDocument": false,
"menuWidth": 165,
"scrolls": true,
"pageScroll": false
}
]
},
{
"name": "without homeMenu: logo click calls onHomeClick, renders no menu, no aria-expanded",
"status": "PASS",
"data": [
"[SWHeader Overview] onHomeClick"
]
},
{
"name": "no page / console errors",
"status": "PASS",
"data": []
}
],
"errors": [],
"data": {
"titles": [
"SW/Header",
"SW/Home Menu",
"SW/Popup",
"SW/Tool"
],
"geometry": {
"left": 375,
"width": 1305,
"height": 77,
"headerHeight": 49,
"sections": [
340,
260,
180,
260,
261
],
"tiles": 15,
"tileSizes": [
"80x46"
],
"titles": 5,
"badgeInlined": true,
"icons": 30,
"iconsLoaded": 30
},
"responsive": [
{
"width": 1920,
"headerHeight": 49,
"start": 0,
"endGap": 0,
"coversHome": false,
"coversDocument": false,
"menuWidth": 1305,
"scrolls": false,
"pageScroll": false
},
{
"width": 1440,
"headerHeight": 49,
"start": 0,
"endGap": 0,
"coversHome": false,
"coversDocument": false,
"menuWidth": 825,
"scrolls": true,
"pageScroll": false
},
{
"width": 1080,
"headerHeight": 49,
"start": 0,
"endGap": 0,
"coversHome": false,
"coversDocument": false,
"menuWidth": 639,
"scrolls": true,
"pageScroll": false
},
{
"width": 768,
"headerHeight": 49,
"start": 0,
"endGap": 0,
"coversHome": false,
"coversDocument": false,
"menuWidth": 288,
"scrolls": true,
"pageScroll": false
},
{
"width": 520,
"headerHeight": 49,
"start": 0,
"endGap": 0,
"coversHome": false,
"coversDocument": false,
"menuWidth": 288,
"scrolls": true,
"pageScroll": false
},
{
"width": 390,
"headerHeight": 49,
"start": 0,
"endGap": 0,
"coversHome": false,
"coversDocument": false,
"menuWidth": 165,
"scrolls": true,
"pageScroll": false
}
]
}
}
@@ -0,0 +1,146 @@
{
"total": 28,
"same": 28,
"results": [
{
"file": "composed-controls-1920.png",
"status": "SAME",
"changed": 0
},
{
"file": "detail-buttons-1920.png",
"status": "SAME",
"changed": 0
},
{
"file": "document-dropdown-1920.png",
"status": "SAME",
"changed": 0
},
{
"file": "interactive-states-1920.png",
"status": "SAME",
"changed": 0
},
{
"file": "k-guide-1920.png",
"status": "SAME",
"changed": 0
},
{
"file": "logo-slot-1920.png",
"status": "SAME",
"changed": 0
},
{
"file": "overview-1080.png",
"status": "SAME",
"changed": 0
},
{
"file": "overview-1180.png",
"status": "SAME",
"changed": 0
},
{
"file": "overview-1440.png",
"status": "SAME",
"changed": 0
},
{
"file": "overview-1800.png",
"status": "SAME",
"changed": 0
},
{
"file": "overview-1920.png",
"status": "SAME",
"changed": 0
},
{
"file": "overview-390.png",
"status": "SAME",
"changed": 0
},
{
"file": "overview-520.png",
"status": "SAME",
"changed": 0
},
{
"file": "overview-640.png",
"status": "SAME",
"changed": 0
},
{
"file": "overview-768.png",
"status": "SAME",
"changed": 0
},
{
"file": "overview-900.png",
"status": "SAME",
"changed": 0
},
{
"file": "property-panel-compare-1920.png",
"status": "SAME",
"changed": 0
},
{
"file": "responsive-more-1080.png",
"status": "SAME",
"changed": 0
},
{
"file": "responsive-more-1180.png",
"status": "SAME",
"changed": 0
},
{
"file": "responsive-more-1440.png",
"status": "SAME",
"changed": 0
},
{
"file": "responsive-more-1800.png",
"status": "SAME",
"changed": 0
},
{
"file": "responsive-more-1920.png",
"status": "SAME",
"changed": 0
},
{
"file": "responsive-more-390.png",
"status": "SAME",
"changed": 0
},
{
"file": "responsive-more-520.png",
"status": "SAME",
"changed": 0
},
{
"file": "responsive-more-640.png",
"status": "SAME",
"changed": 0
},
{
"file": "responsive-more-768.png",
"status": "SAME",
"changed": 0
},
{
"file": "responsive-more-900.png",
"status": "SAME",
"changed": 0
},
{
"file": "window-move-motion-1920.png",
"status": "SAME",
"changed": 0
}
]
}