diff --git a/docs/sw/home-menu-action-buttons-qa-2026-10-19/1080-recent-active.png b/docs/sw/home-menu-action-buttons-qa-2026-10-19/1080-recent-active.png new file mode 100644 index 0000000..025192c Binary files /dev/null and b/docs/sw/home-menu-action-buttons-qa-2026-10-19/1080-recent-active.png differ diff --git a/docs/sw/home-menu-action-buttons-qa-2026-10-19/1080-text-after-clicks.png b/docs/sw/home-menu-action-buttons-qa-2026-10-19/1080-text-after-clicks.png new file mode 100644 index 0000000..3d15fdd Binary files /dev/null and b/docs/sw/home-menu-action-buttons-qa-2026-10-19/1080-text-after-clicks.png differ diff --git a/docs/sw/home-menu-action-buttons-qa-2026-10-19/1920-after-clicks.png b/docs/sw/home-menu-action-buttons-qa-2026-10-19/1920-after-clicks.png new file mode 100644 index 0000000..439e0e1 Binary files /dev/null and b/docs/sw/home-menu-action-buttons-qa-2026-10-19/1920-after-clicks.png differ diff --git a/docs/sw/home-menu-action-buttons-qa-2026-10-19/1920-recent-open.png b/docs/sw/home-menu-action-buttons-qa-2026-10-19/1920-recent-open.png new file mode 100644 index 0000000..4f65ee9 Binary files /dev/null and b/docs/sw/home-menu-action-buttons-qa-2026-10-19/1920-recent-open.png differ diff --git a/docs/sw/home-menu-action-buttons-qa-2026-10-19/report.json b/docs/sw/home-menu-action-buttons-qa-2026-10-19/report.json new file mode 100644 index 0000000..c9e34bf --- /dev/null +++ b/docs/sw/home-menu-action-buttons-qa-2026-10-19/report.json @@ -0,0 +1,219 @@ +{ + "checks": [ + { + "name": "1920 tiles: 14 action tiles — no Active / aria-pressed / ring after the click", + "ok": true, + "data": [] + }, + { + "name": "Hover kept: Variant2 (ring + #FF5C00) while the pointer is on the tile", + "ok": true, + "data": { + "active": null, + "pressed": null, + "expanded": null, + "mark": "\"\"", + "ring": "1", + "color": "rgb(255, 92, 0)", + "bg": "rgba(0, 0, 0, 0)" + } + }, + { + "name": "Pressed: Variant3 only while held (Space down), Default after release", + "ok": true, + "data": { + "held": { + "active": null, + "pressed": null, + "expanded": null, + "mark": "\"\"", + "ring": "1", + "color": "rgb(255, 92, 0)", + "bg": "rgba(0, 0, 0, 0)" + }, + "released": { + "active": null, + "pressed": null, + "expanded": null, + "mark": "\"\"", + "ring": "0", + "color": "rgb(246, 244, 242)", + "bg": "rgba(0, 0, 0, 0)" + } + } + }, + { + "name": "최근파일 tile: Variant3 (Active, aria-expanded) while the list is open; re-click closes list and Active", + "ok": true, + "data": { + "rOpen": { + "tile": { + "active": "true", + "pressed": null, + "expanded": "true", + "mark": "\"\"", + "ring": "1", + "color": "rgb(255, 92, 0)", + "bg": "rgba(0, 0, 0, 0)" + }, + "list": true + }, + "rClosed": { + "tile": { + "active": null, + "pressed": null, + "expanded": "false", + "mark": "\"\"", + "ring": "0", + "color": "rgb(246, 244, 242)", + "bg": "rgba(0, 0, 0, 0)" + }, + "list": false + } + } + }, + { + "name": "최근파일: Escape closes the list → Active off", + "ok": true, + "data": { + "tile": { + "active": null, + "pressed": null, + "expanded": "false", + "mark": "\"\"", + "ring": "0", + "color": "rgb(246, 244, 242)", + "bg": "rgba(0, 0, 0, 0)" + }, + "list": false + } + }, + { + "name": "최근파일: opening a file closes the menu; reopening starts with 최근파일 off", + "ok": true, + "data": { + "afterFile": false, + "reopened": { + "active": null, + "pressed": null, + "expanded": "false", + "mark": "\"\"", + "ring": "0", + "color": "rgb(246, 244, 242)", + "bg": "rgba(0, 0, 0, 0)" + } + } + }, + { + "name": "home button keeps Home On while the menu is open", + "ok": true, + "data": true + }, + { + "name": "More tile keeps its Variant3 while its dropdown is open", + "ok": true, + "data": { + "active": "true", + "ring": "1", + "expanded": "true" + } + }, + { + "name": "1080 More text menu: 10 action rows — no Active, no ✓, no brown row after the click (dropdown stays open)", + "ok": true, + "data": { + "rowLeft": [], + "stillOpen": true + } + }, + { + "name": "text row Hover kept (#62533D + #FF5C00)", + "ok": true, + "data": { + "active": null, + "pressed": null, + "expanded": null, + "mark": "\"\"", + "ring": null, + "color": "rgb(255, 92, 0)", + "bg": "rgb(98, 83, 61)" + } + }, + { + "name": "text row Pressed only while held, nothing after release", + "ok": true, + "data": { + "rowHeld": { + "active": null, + "pressed": null, + "expanded": null, + "mark": "\"\"", + "ring": null, + "color": "rgb(255, 92, 0)", + "bg": "rgb(98, 83, 61)" + }, + "rowReleased": { + "active": null, + "pressed": null, + "expanded": null, + "mark": "\"\"", + "ring": null, + "color": "rgb(246, 244, 242)", + "bg": "rgba(0, 0, 0, 0)" + } + } + }, + { + "name": "최근파일 row: list opens; More stays Variant3; reopened dropdown shows 최근파일 Active with › (no ✓)", + "ok": true, + "data": { + "listOpen": true, + "moreWhileList": "true", + "rRow": { + "active": "true", + "pressed": null, + "expanded": "true", + "mark": "\"›\"", + "ring": null, + "color": "rgb(255, 92, 0)", + "bg": "rgb(98, 83, 61)" + } + } + }, + { + "name": "Escape (dropdown, then list): list closed → 최근파일 row and More off", + "ok": true, + "data": { + "rAfter": { + "list": false, + "more": null + }, + "rRow2": { + "active": null, + "pressed": null, + "expanded": "false", + "mark": "\"›\"", + "ring": null, + "color": "rgb(246, 244, 242)", + "bg": "rgba(0, 0, 0, 0)" + } + } + }, + { + "name": "More tile off once its dropdown and the list are closed", + "ok": true, + "data": null + }, + { + "name": "callbacks: action tile / text row → onItemSelect(active=false) without onActiveChange; 최근파일 → onActiveChange([recent]) + onItemSelect(active=true)", + "ok": true, + "data": "onItemSelect(open / recent, active=true)\nonActiveChange([recent])\nonItemSelect(setting / display, active=false)\nonItemSelect(working / save, active=false)\nonHomeMenuOpenChange(true, home)" + }, + { + "name": "no page errors", + "ok": true, + "data": [] + } + ], + "errors": [] +} \ No newline at end of file diff --git a/docs/sw/home-menu-joint-qa-2026-10-19/after-1024.png b/docs/sw/home-menu-joint-qa-2026-10-19/after-1024.png new file mode 100644 index 0000000..789041a Binary files /dev/null and b/docs/sw/home-menu-joint-qa-2026-10-19/after-1024.png differ diff --git a/docs/sw/home-menu-joint-qa-2026-10-19/after-1440.png b/docs/sw/home-menu-joint-qa-2026-10-19/after-1440.png new file mode 100644 index 0000000..4e87fec Binary files /dev/null and b/docs/sw/home-menu-joint-qa-2026-10-19/after-1440.png differ diff --git a/docs/sw/home-menu-joint-qa-2026-10-19/after-1920.png b/docs/sw/home-menu-joint-qa-2026-10-19/after-1920.png new file mode 100644 index 0000000..60ef404 Binary files /dev/null and b/docs/sw/home-menu-joint-qa-2026-10-19/after-1920.png differ diff --git a/docs/sw/home-menu-joint-qa-2026-10-19/after-390.png b/docs/sw/home-menu-joint-qa-2026-10-19/after-390.png new file mode 100644 index 0000000..3bd1348 Binary files /dev/null and b/docs/sw/home-menu-joint-qa-2026-10-19/after-390.png differ diff --git a/docs/sw/home-menu-joint-qa-2026-10-19/after-768.png b/docs/sw/home-menu-joint-qa-2026-10-19/after-768.png new file mode 100644 index 0000000..8fd16c5 Binary files /dev/null and b/docs/sw/home-menu-joint-qa-2026-10-19/after-768.png differ diff --git a/docs/sw/home-menu-joint-qa-2026-10-19/compare-joint.png b/docs/sw/home-menu-joint-qa-2026-10-19/compare-joint.png new file mode 100644 index 0000000..f2a68cc Binary files /dev/null and b/docs/sw/home-menu-joint-qa-2026-10-19/compare-joint.png differ diff --git a/docs/sw/home-menu-joint-qa-2026-10-19/geometry.json b/docs/sw/home-menu-joint-qa-2026-10-19/geometry.json new file mode 100644 index 0000000..d6b2901 --- /dev/null +++ b/docs/sw/home-menu-joint-qa-2026-10-19/geometry.json @@ -0,0 +1,271 @@ +{ + "results": [ + { + "vw": 1920, + "menu": { + "x": 375, + "y": 0, + "width": 1305, + "height": 77, + "top": 0, + "right": 1680, + "bottom": 77, + "left": 375 + }, + "panel": { + "x": 808, + "y": 77, + "width": 354, + "height": 752, + "top": 77, + "right": 1162, + "bottom": 829, + "left": 808 + }, + "list": { + "x": 808, + "y": 77, + "width": 354, + "height": 752, + "top": 77, + "right": 1162, + "bottom": 829, + "left": 808 + }, + "accent": "outline", + "listBorder": [ + "0px", + "1px", + "rgb(218, 104, 19)" + ], + "accentBox": { + "top": "47px", + "height": "30px", + "padding": "2px", + "radius": "3px" + }, + "joint": [], + "pageScroll": 0 + }, + { + "vw": 1440, + "menu": { + "x": 375, + "y": 0, + "width": 825, + "height": 77, + "top": 0, + "right": 1200, + "bottom": 77, + "left": 375 + }, + "panel": { + "x": 808, + "y": 77, + "width": 354, + "height": 752, + "top": 77, + "right": 1162, + "bottom": 829, + "left": 808 + }, + "list": { + "x": 808, + "y": 77, + "width": 354, + "height": 752, + "top": 77, + "right": 1162, + "bottom": 829, + "left": 808 + }, + "accent": "outline", + "listBorder": [ + "0px", + "1px", + "rgb(218, 104, 19)" + ], + "accentBox": { + "top": "47px", + "height": "30px", + "padding": "2px", + "radius": "3px" + }, + "joint": [], + "pageScroll": 0 + }, + { + "vw": 1024, + "menu": { + "x": 364, + "y": 0, + "width": 484, + "height": 77, + "top": 0, + "right": 848, + "bottom": 77, + "left": 364 + }, + "panel": { + "x": 670, + "y": 77, + "width": 354, + "height": 752, + "top": 77, + "right": 1024, + "bottom": 829, + "left": 670 + }, + "list": { + "x": 670, + "y": 77, + "width": 354, + "height": 752, + "top": 77, + "right": 1024, + "bottom": 829, + "left": 670 + }, + "accent": "outline", + "listBorder": [ + "0px", + "1px", + "rgb(218, 104, 19)" + ], + "accentBox": { + "top": "47px", + "height": "30px", + "padding": "2px", + "radius": "3px" + }, + "joint": [ + [ + 845, + 1024, + 75, + 77, + "linear-gradient(0deg, rgb(255, 81, 0) 0%" + ] + ], + "pageScroll": 0 + }, + { + "vw": 768, + "menu": { + "x": 304, + "y": 0, + "width": 288, + "height": 77, + "top": 0, + "right": 592, + "bottom": 77, + "left": 304 + }, + "panel": { + "x": 414, + "y": 77, + "width": 354, + "height": 752, + "top": 77, + "right": 768, + "bottom": 829, + "left": 414 + }, + "list": { + "x": 414, + "y": 77, + "width": 354, + "height": 752, + "top": 77, + "right": 768, + "bottom": 829, + "left": 414 + }, + "accent": "outline", + "listBorder": [ + "0px", + "1px", + "rgb(218, 104, 19)" + ], + "accentBox": { + "top": "47px", + "height": "30px", + "padding": "2px", + "radius": "3px" + }, + "joint": [ + [ + 589, + 768, + 75, + 77, + "linear-gradient(0deg, rgb(255, 81, 0) 0%" + ] + ], + "pageScroll": 0 + }, + { + "vw": 390, + "menu": { + "x": 161, + "y": 0, + "width": 165, + "height": 77, + "top": 0, + "right": 326, + "bottom": 77, + "left": 161 + }, + "panel": { + "x": 36, + "y": 77, + "width": 354, + "height": 752, + "top": 77, + "right": 390, + "bottom": 829, + "left": 36 + }, + "list": { + "x": 36, + "y": 77, + "width": 354, + "height": 752, + "top": 77, + "right": 390, + "bottom": 829, + "left": 36 + }, + "accent": "outline", + "listBorder": [ + "0px", + "1px", + "rgb(218, 104, 19)" + ], + "accentBox": { + "top": "47px", + "height": "30px", + "padding": "2px", + "radius": "3px" + }, + "joint": [ + [ + 36, + 164, + 75, + 77, + "linear-gradient(0deg, rgb(255, 81, 0) 0%" + ], + [ + 323, + 390, + 75, + 77, + "linear-gradient(0deg, rgb(255, 81, 0) 0%" + ] + ], + "pageScroll": 0 + } + ], + "errors": [] +} \ No newline at end of file diff --git a/docs/sw/home-menu-joint-qa-2026-10-19/joint-1024.png b/docs/sw/home-menu-joint-qa-2026-10-19/joint-1024.png new file mode 100644 index 0000000..019c1d0 Binary files /dev/null and b/docs/sw/home-menu-joint-qa-2026-10-19/joint-1024.png differ diff --git a/docs/sw/home-menu-joint-qa-2026-10-19/joint-390.png b/docs/sw/home-menu-joint-qa-2026-10-19/joint-390.png new file mode 100644 index 0000000..7d94f89 Binary files /dev/null and b/docs/sw/home-menu-joint-qa-2026-10-19/joint-390.png differ diff --git a/docs/sw/home-menu-joint-qa-2026-10-19/joint-768.png b/docs/sw/home-menu-joint-qa-2026-10-19/joint-768.png new file mode 100644 index 0000000..caba431 Binary files /dev/null and b/docs/sw/home-menu-joint-qa-2026-10-19/joint-768.png differ diff --git a/docs/sw/home-menu-more-placement-qa-2026-10-19/768-1-recent.png b/docs/sw/home-menu-more-placement-qa-2026-10-19/768-1-recent.png new file mode 100644 index 0000000..78d81d2 Binary files /dev/null and b/docs/sw/home-menu-more-placement-qa-2026-10-19/768-1-recent.png differ diff --git a/docs/sw/home-menu-more-placement-qa-2026-10-19/768-2-more.png b/docs/sw/home-menu-more-placement-qa-2026-10-19/768-2-more.png new file mode 100644 index 0000000..126b84e Binary files /dev/null and b/docs/sw/home-menu-more-placement-qa-2026-10-19/768-2-more.png differ diff --git a/docs/sw/home-menu-more-placement-qa-2026-10-19/768-3-recent.png b/docs/sw/home-menu-more-placement-qa-2026-10-19/768-3-recent.png new file mode 100644 index 0000000..78d81d2 Binary files /dev/null and b/docs/sw/home-menu-more-placement-qa-2026-10-19/768-3-recent.png differ diff --git a/docs/sw/home-menu-more-placement-qa-2026-10-19/compare-more-placement.png b/docs/sw/home-menu-more-placement-qa-2026-10-19/compare-more-placement.png new file mode 100644 index 0000000..a5f7047 Binary files /dev/null and b/docs/sw/home-menu-more-placement-qa-2026-10-19/compare-more-placement.png differ diff --git a/docs/sw/home-menu-more-placement-qa-2026-10-19/place-1080.png b/docs/sw/home-menu-more-placement-qa-2026-10-19/place-1080.png new file mode 100644 index 0000000..575236b Binary files /dev/null and b/docs/sw/home-menu-more-placement-qa-2026-10-19/place-1080.png differ diff --git a/docs/sw/home-menu-more-placement-qa-2026-10-19/place-1440.png b/docs/sw/home-menu-more-placement-qa-2026-10-19/place-1440.png new file mode 100644 index 0000000..19b675e Binary files /dev/null and b/docs/sw/home-menu-more-placement-qa-2026-10-19/place-1440.png differ diff --git a/docs/sw/home-menu-more-placement-qa-2026-10-19/place-1920.png b/docs/sw/home-menu-more-placement-qa-2026-10-19/place-1920.png new file mode 100644 index 0000000..439e0e1 Binary files /dev/null and b/docs/sw/home-menu-more-placement-qa-2026-10-19/place-1920.png differ diff --git a/docs/sw/home-menu-more-placement-qa-2026-10-19/place-390.png b/docs/sw/home-menu-more-placement-qa-2026-10-19/place-390.png new file mode 100644 index 0000000..ef78300 Binary files /dev/null and b/docs/sw/home-menu-more-placement-qa-2026-10-19/place-390.png differ diff --git a/docs/sw/home-menu-more-placement-qa-2026-10-19/place-768.png b/docs/sw/home-menu-more-placement-qa-2026-10-19/place-768.png new file mode 100644 index 0000000..ac9eea9 Binary files /dev/null and b/docs/sw/home-menu-more-placement-qa-2026-10-19/place-768.png differ diff --git a/docs/sw/home-menu-more-placement-qa-2026-10-19/report.json b/docs/sw/home-menu-more-placement-qa-2026-10-19/report.json new file mode 100644 index 0000000..a11ee62 --- /dev/null +++ b/docs/sw/home-menu-more-placement-qa-2026-10-19/report.json @@ -0,0 +1,3064 @@ +{ + "checks": [ + { + "name": "1920: full Figma row (5 groups), More hidden", + "ok": true, + "data": { + "vw": 1920, + "open": true, + "rowCount": 5, + "more": false, + "dropShown": false, + "list": false, + "overlap": false, + "recentActive": null, + "moreActive": null, + "gapToMore": null, + "menuTail": null, + "rowPad": 2, + "tileInset": null, + "badgeInset": null, + "dropLeftToTile": null, + "menu": { + "x": 375, + "y": 0, + "width": 1305, + "height": 77, + "top": 0, + "right": 1680, + "bottom": 77, + "left": 375 + }, + "win": { + "x": 1680, + "y": 0, + "width": 240, + "height": 48, + "top": 0, + "right": 1920, + "bottom": 48, + "left": 1680 + }, + "joints": 0, + "homeOn": true, + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "rowScroll": 0, + "pageScroll": 0 + } + }, + { + "name": "narrower: More directly after the last shown group (gap 0) — or at the row start when no group fits", + "ok": true, + "data": [ + [ + 1920, + 5, + null + ], + [ + 1440, + 2, + 0 + ], + [ + 1080, + 1, + 0 + ], + [ + 768, + 0, + 0 + ], + [ + 390, + 0, + 0 + ], + [ + 390, + 0, + 0 + ], + [ + 768, + 0, + 0 + ], + [ + 1080, + 1, + 0 + ], + [ + 1440, + 2, + 0 + ], + [ + 1920, + 5, + null + ] + ] + }, + { + "name": "background unchanged: the More section surface fills the rest, menu ends at the window area", + "ok": true, + "data": [ + [ + 1920, + null, + 1680, + 1680 + ], + [ + 1440, + 2, + 1200, + 1200 + ], + [ + 1080, + 2, + 840, + 840 + ], + [ + 768, + 2, + 592, + 592 + ], + [ + 390, + 2, + 326, + 326 + ], + [ + 390, + 2, + 326, + 326 + ], + [ + 768, + 2, + 592, + 592 + ], + [ + 1080, + 2, + 840, + 840 + ], + [ + 1440, + 2, + 1200, + 1200 + ], + [ + 1920, + null, + 1680, + 1680 + ] + ] + }, + { + "name": "⋯ tile and badge at the start of the More section (section padding 10 + border 1), right after the last group", + "ok": true, + "data": [ + [ + 1920, + null, + null + ], + [ + 1440, + 11, + 11 + ], + [ + 1080, + 11, + 11 + ], + [ + 768, + 11, + 11 + ], + [ + 390, + 11, + 11 + ], + [ + 390, + 11, + 11 + ], + [ + 768, + 11, + 11 + ], + [ + 1080, + 11, + 11 + ], + [ + 1440, + 11, + 11 + ], + [ + 1920, + null, + null + ] + ] + }, + { + "name": "More follows the group count both ways (same split down and up)", + "ok": true, + "data": [ + [ + 1920, + 5 + ], + [ + 1440, + 2 + ], + [ + 1080, + 1 + ], + [ + 768, + 0 + ], + [ + 390, + 0 + ], + [ + 390, + 0 + ], + [ + 768, + 0 + ], + [ + 1080, + 1 + ], + [ + 1440, + 2 + ], + [ + 1920, + 5 + ] + ] + }, + { + "name": "no horizontal scroll; menu stays left of the window area", + "ok": true, + "data": [ + [ + 1920, + 0, + 1680, + 1680 + ], + [ + 1440, + 0, + 1200, + 1200 + ], + [ + 1080, + 0, + 840, + 840 + ], + [ + 768, + 0, + 592, + 592 + ], + [ + 390, + 0, + 326, + 326 + ], + [ + 390, + 0, + 326, + 326 + ], + [ + 768, + 0, + 592, + 592 + ], + [ + 1080, + 0, + 840, + 840 + ], + [ + 1440, + 0, + 1200, + 1200 + ], + [ + 1920, + 0, + 1680, + 1680 + ] + ] + }, + { + "name": "Home On + #5F4B0F lines kept", + "ok": true, + "data": [ + [ + 1920, + true + ], + [ + 1440, + true + ], + [ + 1080, + true + ], + [ + 768, + true + ], + [ + 390, + true + ], + [ + 390, + true + ], + [ + 768, + true + ], + [ + 1080, + true + ], + [ + 1440, + true + ], + [ + 1920, + true + ] + ] + }, + { + "name": "1440: 최근파일 open → list only (no dropdown), ON on 최근파일", + "ok": true, + "data": { + "vw": 1440, + "open": true, + "rowCount": 2, + "more": true, + "dropShown": false, + "list": true, + "overlap": false, + "recentActive": "true", + "moreActive": null, + "gapToMore": 0, + "menuTail": 2, + "rowPad": 2, + "tileInset": 11, + "badgeInset": 11, + "dropLeftToTile": null, + "menu": { + "x": 375, + "y": 0, + "width": 825, + "height": 77, + "top": 0, + "right": 1200, + "bottom": 77, + "left": 375 + }, + "win": { + "x": 1200, + "y": 0, + "width": 240, + "height": 48, + "top": 0, + "right": 1440, + "bottom": 48, + "left": 1200 + }, + "joints": 0, + "homeOn": true, + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "rowScroll": 0, + "pageScroll": 0 + } + }, + { + "name": "1440: More while the list is open → list closed first, dropdown open under the ⋯ tile, no overlap", + "ok": true, + "data": { + "vw": 1440, + "open": true, + "rowCount": 2, + "more": true, + "dropShown": true, + "list": false, + "overlap": false, + "recentActive": null, + "moreActive": "true", + "gapToMore": 0, + "menuTail": 2, + "rowPad": 2, + "tileInset": 11, + "badgeInset": 11, + "dropLeftToTile": 0, + "menu": { + "x": 375, + "y": 0, + "width": 825, + "height": 77, + "top": 0, + "right": 1200, + "bottom": 77, + "left": 375 + }, + "win": { + "x": 1200, + "y": 0, + "width": 240, + "height": 48, + "top": 0, + "right": 1440, + "bottom": 48, + "left": 1200 + }, + "joints": 0, + "homeOn": true, + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "rowScroll": 0, + "pageScroll": 0 + } + }, + { + "name": "1440: 최근파일 again → dropdown closed, list open", + "ok": true, + "data": { + "vw": 1440, + "open": true, + "rowCount": 2, + "more": true, + "dropShown": false, + "list": true, + "overlap": false, + "recentActive": "true", + "moreActive": null, + "gapToMore": 0, + "menuTail": 2, + "rowPad": 2, + "tileInset": 11, + "badgeInset": 11, + "dropLeftToTile": null, + "menu": { + "x": 375, + "y": 0, + "width": 825, + "height": 77, + "top": 0, + "right": 1200, + "bottom": 77, + "left": 375 + }, + "win": { + "x": 1200, + "y": 0, + "width": 240, + "height": 48, + "top": 0, + "right": 1440, + "bottom": 48, + "left": 1200 + }, + "joints": 0, + "homeOn": true, + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "rowScroll": 0, + "pageScroll": 0 + } + }, + { + "name": "1440: preview kept, inside the viewport, no page scroll", + "ok": true, + "data": { + "left": 497, + "right": 807, + "page": 0 + } + }, + { + "name": "1440: keyboard Enter on More with the list open → list closed, dropdown open; Escape closes the dropdown, menu stays", + "ok": true, + "data": { + "s4": { + "vw": 1440, + "open": true, + "rowCount": 2, + "more": true, + "dropShown": true, + "list": false, + "overlap": false, + "recentActive": null, + "moreActive": "true", + "gapToMore": 0, + "menuTail": 2, + "rowPad": 2, + "tileInset": 11, + "badgeInset": 11, + "dropLeftToTile": 0, + "menu": { + "x": 375, + "y": 0, + "width": 825, + "height": 77, + "top": 0, + "right": 1200, + "bottom": 77, + "left": 375 + }, + "win": { + "x": 1200, + "y": 0, + "width": 240, + "height": 48, + "top": 0, + "right": 1440, + "bottom": 48, + "left": 1200 + }, + "joints": 0, + "homeOn": true, + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "rowScroll": 0, + "pageScroll": 0 + }, + "s5": { + "vw": 1440, + "open": true, + "rowCount": 2, + "more": true, + "dropShown": false, + "list": false, + "overlap": false, + "recentActive": null, + "moreActive": null, + "gapToMore": 0, + "menuTail": 2, + "rowPad": 2, + "tileInset": 11, + "badgeInset": 11, + "dropLeftToTile": null, + "menu": { + "x": 375, + "y": 0, + "width": 825, + "height": 77, + "top": 0, + "right": 1200, + "bottom": 77, + "left": 375 + }, + "win": { + "x": 1200, + "y": 0, + "width": 240, + "height": 48, + "top": 0, + "right": 1440, + "bottom": 48, + "left": 1200 + }, + "joints": 0, + "homeOn": true, + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "rowScroll": 0, + "pageScroll": 0 + } + } + }, + { + "name": "1080: 최근파일 open → list only (no dropdown), ON on 최근파일", + "ok": true, + "data": { + "vw": 1080, + "open": true, + "rowCount": 1, + "more": true, + "dropShown": false, + "list": true, + "overlap": false, + "recentActive": "true", + "moreActive": "true", + "gapToMore": 0, + "menuTail": 2, + "rowPad": 2, + "tileInset": 11, + "badgeInset": 11, + "dropLeftToTile": null, + "menu": { + "x": 201, + "y": 0, + "width": 639, + "height": 77, + "top": 0, + "right": 840, + "bottom": 77, + "left": 201 + }, + "win": { + "x": 840, + "y": 0, + "width": 240, + "height": 48, + "top": 0, + "right": 1080, + "bottom": 48, + "left": 840 + }, + "joints": 1, + "homeOn": true, + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "rowScroll": 0, + "pageScroll": 0 + } + }, + { + "name": "1080: More while the list is open → list closed first, dropdown open under the ⋯ tile, no overlap", + "ok": true, + "data": { + "vw": 1080, + "open": true, + "rowCount": 1, + "more": true, + "dropShown": true, + "list": false, + "overlap": false, + "recentActive": null, + "moreActive": "true", + "gapToMore": 0, + "menuTail": 2, + "rowPad": 2, + "tileInset": 11, + "badgeInset": 11, + "dropLeftToTile": 0, + "menu": { + "x": 201, + "y": 0, + "width": 639, + "height": 77, + "top": 0, + "right": 840, + "bottom": 77, + "left": 201 + }, + "win": { + "x": 840, + "y": 0, + "width": 240, + "height": 48, + "top": 0, + "right": 1080, + "bottom": 48, + "left": 840 + }, + "joints": 0, + "homeOn": true, + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "rowScroll": 0, + "pageScroll": 0 + } + }, + { + "name": "1080: 최근파일 again → dropdown closed, list open", + "ok": true, + "data": { + "vw": 1080, + "open": true, + "rowCount": 1, + "more": true, + "dropShown": false, + "list": true, + "overlap": false, + "recentActive": "true", + "moreActive": "true", + "gapToMore": 0, + "menuTail": 2, + "rowPad": 2, + "tileInset": 11, + "badgeInset": 11, + "dropLeftToTile": null, + "menu": { + "x": 201, + "y": 0, + "width": 639, + "height": 77, + "top": 0, + "right": 840, + "bottom": 77, + "left": 201 + }, + "win": { + "x": 840, + "y": 0, + "width": 240, + "height": 48, + "top": 0, + "right": 1080, + "bottom": 48, + "left": 840 + }, + "joints": 1, + "homeOn": true, + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "rowScroll": 0, + "pageScroll": 0 + } + }, + { + "name": "1080: preview kept, inside the viewport, no page scroll", + "ok": true, + "data": { + "left": 244, + "right": 554, + "page": 0 + } + }, + { + "name": "1080: keyboard Enter on More with the list open → list closed, dropdown open; Escape closes the dropdown, menu stays", + "ok": true, + "data": { + "s4": { + "vw": 1080, + "open": true, + "rowCount": 1, + "more": true, + "dropShown": true, + "list": false, + "overlap": false, + "recentActive": null, + "moreActive": "true", + "gapToMore": 0, + "menuTail": 2, + "rowPad": 2, + "tileInset": 11, + "badgeInset": 11, + "dropLeftToTile": 0, + "menu": { + "x": 201, + "y": 0, + "width": 639, + "height": 77, + "top": 0, + "right": 840, + "bottom": 77, + "left": 201 + }, + "win": { + "x": 840, + "y": 0, + "width": 240, + "height": 48, + "top": 0, + "right": 1080, + "bottom": 48, + "left": 840 + }, + "joints": 0, + "homeOn": true, + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "rowScroll": 0, + "pageScroll": 0 + }, + "s5": { + "vw": 1080, + "open": true, + "rowCount": 1, + "more": true, + "dropShown": false, + "list": false, + "overlap": false, + "recentActive": null, + "moreActive": null, + "gapToMore": 0, + "menuTail": 2, + "rowPad": 2, + "tileInset": 11, + "badgeInset": 11, + "dropLeftToTile": null, + "menu": { + "x": 201, + "y": 0, + "width": 639, + "height": 77, + "top": 0, + "right": 840, + "bottom": 77, + "left": 201 + }, + "win": { + "x": 840, + "y": 0, + "width": 240, + "height": 48, + "top": 0, + "right": 1080, + "bottom": 48, + "left": 840 + }, + "joints": 0, + "homeOn": true, + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "rowScroll": 0, + "pageScroll": 0 + } + } + }, + { + "name": "768: 최근파일 open → list only (no dropdown), ON on 최근파일", + "ok": true, + "data": { + "vw": 768, + "open": true, + "rowCount": 0, + "more": true, + "dropShown": false, + "list": true, + "overlap": false, + "recentActive": "true", + "moreActive": "true", + "gapToMore": 0, + "menuTail": 2, + "rowPad": 2, + "tileInset": 11, + "badgeInset": 11, + "dropLeftToTile": null, + "menu": { + "x": 304, + "y": 0, + "width": 288, + "height": 77, + "top": 0, + "right": 592, + "bottom": 77, + "left": 304 + }, + "win": { + "x": 592, + "y": 0, + "width": 176, + "height": 48, + "top": 0, + "right": 768, + "bottom": 48, + "left": 592 + }, + "joints": 1, + "homeOn": true, + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "rowScroll": 0, + "pageScroll": 0 + } + }, + { + "name": "768: More while the list is open → list closed first, dropdown open under the ⋯ tile, no overlap", + "ok": true, + "data": { + "vw": 768, + "open": true, + "rowCount": 0, + "more": true, + "dropShown": true, + "list": false, + "overlap": false, + "recentActive": null, + "moreActive": "true", + "gapToMore": 0, + "menuTail": 2, + "rowPad": 2, + "tileInset": 11, + "badgeInset": 11, + "dropLeftToTile": 0, + "menu": { + "x": 304, + "y": 0, + "width": 288, + "height": 77, + "top": 0, + "right": 592, + "bottom": 77, + "left": 304 + }, + "win": { + "x": 592, + "y": 0, + "width": 176, + "height": 48, + "top": 0, + "right": 768, + "bottom": 48, + "left": 592 + }, + "joints": 0, + "homeOn": true, + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "rowScroll": 0, + "pageScroll": 0 + } + }, + { + "name": "768: 최근파일 again → dropdown closed, list open", + "ok": true, + "data": { + "vw": 768, + "open": true, + "rowCount": 0, + "more": true, + "dropShown": false, + "list": true, + "overlap": false, + "recentActive": "true", + "moreActive": "true", + "gapToMore": 0, + "menuTail": 2, + "rowPad": 2, + "tileInset": 11, + "badgeInset": 11, + "dropLeftToTile": null, + "menu": { + "x": 304, + "y": 0, + "width": 288, + "height": 77, + "top": 0, + "right": 592, + "bottom": 77, + "left": 304 + }, + "win": { + "x": 592, + "y": 0, + "width": 176, + "height": 48, + "top": 0, + "right": 768, + "bottom": 48, + "left": 592 + }, + "joints": 1, + "homeOn": true, + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "rowScroll": 0, + "pageScroll": 0 + } + }, + { + "name": "768: preview kept, inside the viewport, no page scroll", + "ok": true, + "data": { + "left": 7, + "right": 317, + "page": 0 + } + }, + { + "name": "768: keyboard Enter on More with the list open → list closed, dropdown open; Escape closes the dropdown, menu stays", + "ok": true, + "data": { + "s4": { + "vw": 768, + "open": true, + "rowCount": 0, + "more": true, + "dropShown": true, + "list": false, + "overlap": false, + "recentActive": null, + "moreActive": "true", + "gapToMore": 0, + "menuTail": 2, + "rowPad": 2, + "tileInset": 11, + "badgeInset": 11, + "dropLeftToTile": 0, + "menu": { + "x": 304, + "y": 0, + "width": 288, + "height": 77, + "top": 0, + "right": 592, + "bottom": 77, + "left": 304 + }, + "win": { + "x": 592, + "y": 0, + "width": 176, + "height": 48, + "top": 0, + "right": 768, + "bottom": 48, + "left": 592 + }, + "joints": 0, + "homeOn": true, + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "rowScroll": 0, + "pageScroll": 0 + }, + "s5": { + "vw": 768, + "open": true, + "rowCount": 0, + "more": true, + "dropShown": false, + "list": false, + "overlap": false, + "recentActive": null, + "moreActive": null, + "gapToMore": 0, + "menuTail": 2, + "rowPad": 2, + "tileInset": 11, + "badgeInset": 11, + "dropLeftToTile": null, + "menu": { + "x": 304, + "y": 0, + "width": 288, + "height": 77, + "top": 0, + "right": 592, + "bottom": 77, + "left": 304 + }, + "win": { + "x": 592, + "y": 0, + "width": 176, + "height": 48, + "top": 0, + "right": 768, + "bottom": 48, + "left": 592 + }, + "joints": 0, + "homeOn": true, + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "rowScroll": 0, + "pageScroll": 0 + } + } + }, + { + "name": "390: 최근파일 open → list only (no dropdown), ON on 최근파일", + "ok": true, + "data": { + "vw": 390, + "open": true, + "rowCount": 0, + "more": true, + "dropShown": false, + "list": true, + "overlap": false, + "recentActive": "true", + "moreActive": "true", + "gapToMore": 0, + "menuTail": 2, + "rowPad": 2, + "tileInset": 11, + "badgeInset": 11, + "dropLeftToTile": null, + "menu": { + "x": 161, + "y": 0, + "width": 165, + "height": 77, + "top": 0, + "right": 326, + "bottom": 77, + "left": 161 + }, + "win": { + "x": 326, + "y": 0, + "width": 64, + "height": 48, + "top": 0, + "right": 390, + "bottom": 48, + "left": 326 + }, + "joints": 2, + "homeOn": true, + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "rowScroll": 0, + "pageScroll": 0 + } + }, + { + "name": "390: More while the list is open → list closed first, dropdown open under the ⋯ tile, no overlap", + "ok": true, + "data": { + "vw": 390, + "open": true, + "rowCount": 0, + "more": true, + "dropShown": true, + "list": false, + "overlap": false, + "recentActive": null, + "moreActive": "true", + "gapToMore": 0, + "menuTail": 2, + "rowPad": 2, + "tileInset": 11, + "badgeInset": 11, + "dropLeftToTile": 0, + "menu": { + "x": 161, + "y": 0, + "width": 165, + "height": 77, + "top": 0, + "right": 326, + "bottom": 77, + "left": 161 + }, + "win": { + "x": 326, + "y": 0, + "width": 64, + "height": 48, + "top": 0, + "right": 390, + "bottom": 48, + "left": 326 + }, + "joints": 0, + "homeOn": true, + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "rowScroll": 0, + "pageScroll": 0 + } + }, + { + "name": "390: 최근파일 again → dropdown closed, list open", + "ok": true, + "data": { + "vw": 390, + "open": true, + "rowCount": 0, + "more": true, + "dropShown": false, + "list": true, + "overlap": false, + "recentActive": "true", + "moreActive": "true", + "gapToMore": 0, + "menuTail": 2, + "rowPad": 2, + "tileInset": 11, + "badgeInset": 11, + "dropLeftToTile": null, + "menu": { + "x": 161, + "y": 0, + "width": 165, + "height": 77, + "top": 0, + "right": 326, + "bottom": 77, + "left": 161 + }, + "win": { + "x": 326, + "y": 0, + "width": 64, + "height": 48, + "top": 0, + "right": 390, + "bottom": 48, + "left": 326 + }, + "joints": 2, + "homeOn": true, + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "rowScroll": 0, + "pageScroll": 0 + } + }, + { + "name": "390: preview kept, inside the viewport, no page scroll", + "ok": false, + "data": { + "left": -275, + "right": 35, + "page": 0 + } + }, + { + "name": "390: keyboard Enter on More with the list open → list closed, dropdown open; Escape closes the dropdown, menu stays", + "ok": true, + "data": { + "s4": { + "vw": 390, + "open": true, + "rowCount": 0, + "more": true, + "dropShown": true, + "list": false, + "overlap": false, + "recentActive": null, + "moreActive": "true", + "gapToMore": 0, + "menuTail": 2, + "rowPad": 2, + "tileInset": 11, + "badgeInset": 11, + "dropLeftToTile": 0, + "menu": { + "x": 161, + "y": 0, + "width": 165, + "height": 77, + "top": 0, + "right": 326, + "bottom": 77, + "left": 161 + }, + "win": { + "x": 326, + "y": 0, + "width": 64, + "height": 48, + "top": 0, + "right": 390, + "bottom": 48, + "left": 326 + }, + "joints": 0, + "homeOn": true, + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "rowScroll": 0, + "pageScroll": 0 + }, + "s5": { + "vw": 390, + "open": true, + "rowCount": 0, + "more": true, + "dropShown": false, + "list": false, + "overlap": false, + "recentActive": null, + "moreActive": null, + "gapToMore": 0, + "menuTail": 2, + "rowPad": 2, + "tileInset": 11, + "badgeInset": 11, + "dropLeftToTile": null, + "menu": { + "x": 161, + "y": 0, + "width": 165, + "height": 77, + "top": 0, + "right": 326, + "bottom": 77, + "left": 161 + }, + "win": { + "x": 326, + "y": 0, + "width": 64, + "height": 48, + "top": 0, + "right": 390, + "bottom": 48, + "left": 326 + }, + "joints": 0, + "homeOn": true, + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "rowScroll": 0, + "pageScroll": 0 + } + } + }, + { + "name": "never both popups at once, never overlapping (every step)", + "ok": true, + "data": [ + [ + "1440 최근파일 open", + true, + false + ], + [ + "1440 More over open list", + false, + true + ], + [ + "1440 최근파일 again", + true, + false + ], + [ + "1440 Enter on More over open list", + false, + true + ], + [ + "1440 Escape", + false, + false + ], + [ + "1080 More open", + false, + true + ], + [ + "1080 최근파일 open", + true, + false + ], + [ + "1080 More over open list", + false, + true + ], + [ + "1080 최근파일 again", + true, + false + ], + [ + "1080 Enter on More over open list", + false, + true + ], + [ + "1080 Escape", + false, + false + ], + [ + "768 More open", + false, + true + ], + [ + "768 최근파일 open", + true, + false + ], + [ + "768 More over open list", + false, + true + ], + [ + "768 최근파일 again", + true, + false + ], + [ + "768 Enter on More over open list", + false, + true + ], + [ + "768 Escape", + false, + false + ], + [ + "390 More open", + false, + true + ], + [ + "390 최근파일 open", + true, + false + ], + [ + "390 More over open list", + false, + true + ], + [ + "390 최근파일 again", + true, + false + ], + [ + "390 Enter on More over open list", + false, + true + ], + [ + "390 Escape", + false, + false + ] + ] + }, + { + "name": "connector line where the list reaches past the menu (768 / 390 list steps)", + "ok": true, + "data": [ + [ + "1440 최근파일 open", + 0 + ], + [ + "1440 최근파일 again", + 0 + ], + [ + "1080 최근파일 open", + 1 + ], + [ + "1080 최근파일 again", + 1 + ], + [ + "768 최근파일 open", + 1 + ], + [ + "768 최근파일 again", + 1 + ], + [ + "390 최근파일 open", + 2 + ], + [ + "390 최근파일 again", + 2 + ] + ] + }, + { + "name": "no page scroll at any step", + "ok": true, + "data": [ + [ + "1440 최근파일 open", + 0 + ], + [ + "1440 More over open list", + 0 + ], + [ + "1440 최근파일 again", + 0 + ], + [ + "1440 Enter on More over open list", + 0 + ], + [ + "1440 Escape", + 0 + ], + [ + "1080 More open", + 0 + ], + [ + "1080 최근파일 open", + 0 + ], + [ + "1080 More over open list", + 0 + ], + [ + "1080 최근파일 again", + 0 + ], + [ + "1080 Enter on More over open list", + 0 + ], + [ + "1080 Escape", + 0 + ], + [ + "768 More open", + 0 + ], + [ + "768 최근파일 open", + 0 + ], + [ + "768 More over open list", + 0 + ], + [ + "768 최근파일 again", + 0 + ], + [ + "768 Enter on More over open list", + 0 + ], + [ + "768 Escape", + 0 + ], + [ + "390 More open", + 0 + ], + [ + "390 최근파일 open", + 0 + ], + [ + "390 More over open list", + 0 + ], + [ + "390 최근파일 again", + 0 + ], + [ + "390 Enter on More over open list", + 0 + ], + [ + "390 Escape", + 0 + ] + ] + }, + { + "name": "no page errors", + "ok": true, + "data": [] + } + ], + "place": [ + { + "vw": 1920, + "open": true, + "rowCount": 5, + "more": false, + "dropShown": false, + "list": false, + "overlap": false, + "recentActive": null, + "moreActive": null, + "gapToMore": null, + "menuTail": null, + "rowPad": 2, + "tileInset": null, + "badgeInset": null, + "dropLeftToTile": null, + "menu": { + "x": 375, + "y": 0, + "width": 1305, + "height": 77, + "top": 0, + "right": 1680, + "bottom": 77, + "left": 375 + }, + "win": { + "x": 1680, + "y": 0, + "width": 240, + "height": 48, + "top": 0, + "right": 1920, + "bottom": 48, + "left": 1680 + }, + "joints": 0, + "homeOn": true, + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "rowScroll": 0, + "pageScroll": 0 + }, + { + "vw": 1440, + "open": true, + "rowCount": 2, + "more": true, + "dropShown": false, + "list": false, + "overlap": false, + "recentActive": null, + "moreActive": null, + "gapToMore": 0, + "menuTail": 2, + "rowPad": 2, + "tileInset": 11, + "badgeInset": 11, + "dropLeftToTile": null, + "menu": { + "x": 375, + "y": 0, + "width": 825, + "height": 77, + "top": 0, + "right": 1200, + "bottom": 77, + "left": 375 + }, + "win": { + "x": 1200, + "y": 0, + "width": 240, + "height": 48, + "top": 0, + "right": 1440, + "bottom": 48, + "left": 1200 + }, + "joints": 0, + "homeOn": true, + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "rowScroll": 0, + "pageScroll": 0 + }, + { + "vw": 1080, + "open": true, + "rowCount": 1, + "more": true, + "dropShown": false, + "list": false, + "overlap": false, + "recentActive": null, + "moreActive": null, + "gapToMore": 0, + "menuTail": 2, + "rowPad": 2, + "tileInset": 11, + "badgeInset": 11, + "dropLeftToTile": null, + "menu": { + "x": 201, + "y": 0, + "width": 639, + "height": 77, + "top": 0, + "right": 840, + "bottom": 77, + "left": 201 + }, + "win": { + "x": 840, + "y": 0, + "width": 240, + "height": 48, + "top": 0, + "right": 1080, + "bottom": 48, + "left": 840 + }, + "joints": 0, + "homeOn": true, + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "rowScroll": 0, + "pageScroll": 0 + }, + { + "vw": 768, + "open": true, + "rowCount": 0, + "more": true, + "dropShown": false, + "list": false, + "overlap": false, + "recentActive": null, + "moreActive": null, + "gapToMore": 0, + "menuTail": 2, + "rowPad": 2, + "tileInset": 11, + "badgeInset": 11, + "dropLeftToTile": null, + "menu": { + "x": 304, + "y": 0, + "width": 288, + "height": 77, + "top": 0, + "right": 592, + "bottom": 77, + "left": 304 + }, + "win": { + "x": 592, + "y": 0, + "width": 176, + "height": 48, + "top": 0, + "right": 768, + "bottom": 48, + "left": 592 + }, + "joints": 0, + "homeOn": true, + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "rowScroll": 0, + "pageScroll": 0 + }, + { + "vw": 390, + "open": true, + "rowCount": 0, + "more": true, + "dropShown": false, + "list": false, + "overlap": false, + "recentActive": null, + "moreActive": null, + "gapToMore": 0, + "menuTail": 2, + "rowPad": 2, + "tileInset": 11, + "badgeInset": 11, + "dropLeftToTile": null, + "menu": { + "x": 161, + "y": 0, + "width": 165, + "height": 77, + "top": 0, + "right": 326, + "bottom": 77, + "left": 161 + }, + "win": { + "x": 326, + "y": 0, + "width": 64, + "height": 48, + "top": 0, + "right": 390, + "bottom": 48, + "left": 326 + }, + "joints": 0, + "homeOn": true, + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "rowScroll": 0, + "pageScroll": 0 + }, + { + "vw": 390, + "open": true, + "rowCount": 0, + "more": true, + "dropShown": false, + "list": false, + "overlap": false, + "recentActive": null, + "moreActive": null, + "gapToMore": 0, + "menuTail": 2, + "rowPad": 2, + "tileInset": 11, + "badgeInset": 11, + "dropLeftToTile": null, + "menu": { + "x": 161, + "y": 0, + "width": 165, + "height": 77, + "top": 0, + "right": 326, + "bottom": 77, + "left": 161 + }, + "win": { + "x": 326, + "y": 0, + "width": 64, + "height": 48, + "top": 0, + "right": 390, + "bottom": 48, + "left": 326 + }, + "joints": 0, + "homeOn": true, + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "rowScroll": 0, + "pageScroll": 0 + }, + { + "vw": 768, + "open": true, + "rowCount": 0, + "more": true, + "dropShown": false, + "list": false, + "overlap": false, + "recentActive": null, + "moreActive": null, + "gapToMore": 0, + "menuTail": 2, + "rowPad": 2, + "tileInset": 11, + "badgeInset": 11, + "dropLeftToTile": null, + "menu": { + "x": 304, + "y": 0, + "width": 288, + "height": 77, + "top": 0, + "right": 592, + "bottom": 77, + "left": 304 + }, + "win": { + "x": 592, + "y": 0, + "width": 176, + "height": 48, + "top": 0, + "right": 768, + "bottom": 48, + "left": 592 + }, + "joints": 0, + "homeOn": true, + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "rowScroll": 0, + "pageScroll": 0 + }, + { + "vw": 1080, + "open": true, + "rowCount": 1, + "more": true, + "dropShown": false, + "list": false, + "overlap": false, + "recentActive": null, + "moreActive": null, + "gapToMore": 0, + "menuTail": 2, + "rowPad": 2, + "tileInset": 11, + "badgeInset": 11, + "dropLeftToTile": null, + "menu": { + "x": 201, + "y": 0, + "width": 639, + "height": 77, + "top": 0, + "right": 840, + "bottom": 77, + "left": 201 + }, + "win": { + "x": 840, + "y": 0, + "width": 240, + "height": 48, + "top": 0, + "right": 1080, + "bottom": 48, + "left": 840 + }, + "joints": 0, + "homeOn": true, + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "rowScroll": 0, + "pageScroll": 0 + }, + { + "vw": 1440, + "open": true, + "rowCount": 2, + "more": true, + "dropShown": false, + "list": false, + "overlap": false, + "recentActive": null, + "moreActive": null, + "gapToMore": 0, + "menuTail": 2, + "rowPad": 2, + "tileInset": 11, + "badgeInset": 11, + "dropLeftToTile": null, + "menu": { + "x": 375, + "y": 0, + "width": 825, + "height": 77, + "top": 0, + "right": 1200, + "bottom": 77, + "left": 375 + }, + "win": { + "x": 1200, + "y": 0, + "width": 240, + "height": 48, + "top": 0, + "right": 1440, + "bottom": 48, + "left": 1200 + }, + "joints": 0, + "homeOn": true, + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "rowScroll": 0, + "pageScroll": 0 + }, + { + "vw": 1920, + "open": true, + "rowCount": 5, + "more": false, + "dropShown": false, + "list": false, + "overlap": false, + "recentActive": null, + "moreActive": null, + "gapToMore": null, + "menuTail": null, + "rowPad": 2, + "tileInset": null, + "badgeInset": null, + "dropLeftToTile": null, + "menu": { + "x": 375, + "y": 0, + "width": 1305, + "height": 77, + "top": 0, + "right": 1680, + "bottom": 77, + "left": 375 + }, + "win": { + "x": 1680, + "y": 0, + "width": 240, + "height": 48, + "top": 0, + "right": 1920, + "bottom": 48, + "left": 1680 + }, + "joints": 0, + "homeOn": true, + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "rowScroll": 0, + "pageScroll": 0 + } + ], + "steps": [ + { + "label": "1440 최근파일 open", + "vw": 1440, + "open": true, + "rowCount": 2, + "more": true, + "dropShown": false, + "list": true, + "overlap": false, + "recentActive": "true", + "moreActive": null, + "gapToMore": 0, + "menuTail": 2, + "rowPad": 2, + "tileInset": 11, + "badgeInset": 11, + "dropLeftToTile": null, + "menu": { + "x": 375, + "y": 0, + "width": 825, + "height": 77, + "top": 0, + "right": 1200, + "bottom": 77, + "left": 375 + }, + "win": { + "x": 1200, + "y": 0, + "width": 240, + "height": 48, + "top": 0, + "right": 1440, + "bottom": 48, + "left": 1200 + }, + "joints": 0, + "homeOn": true, + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "rowScroll": 0, + "pageScroll": 0 + }, + { + "label": "1440 More over open list", + "vw": 1440, + "open": true, + "rowCount": 2, + "more": true, + "dropShown": true, + "list": false, + "overlap": false, + "recentActive": null, + "moreActive": "true", + "gapToMore": 0, + "menuTail": 2, + "rowPad": 2, + "tileInset": 11, + "badgeInset": 11, + "dropLeftToTile": 0, + "menu": { + "x": 375, + "y": 0, + "width": 825, + "height": 77, + "top": 0, + "right": 1200, + "bottom": 77, + "left": 375 + }, + "win": { + "x": 1200, + "y": 0, + "width": 240, + "height": 48, + "top": 0, + "right": 1440, + "bottom": 48, + "left": 1200 + }, + "joints": 0, + "homeOn": true, + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "rowScroll": 0, + "pageScroll": 0 + }, + { + "label": "1440 최근파일 again", + "vw": 1440, + "open": true, + "rowCount": 2, + "more": true, + "dropShown": false, + "list": true, + "overlap": false, + "recentActive": "true", + "moreActive": null, + "gapToMore": 0, + "menuTail": 2, + "rowPad": 2, + "tileInset": 11, + "badgeInset": 11, + "dropLeftToTile": null, + "menu": { + "x": 375, + "y": 0, + "width": 825, + "height": 77, + "top": 0, + "right": 1200, + "bottom": 77, + "left": 375 + }, + "win": { + "x": 1200, + "y": 0, + "width": 240, + "height": 48, + "top": 0, + "right": 1440, + "bottom": 48, + "left": 1200 + }, + "joints": 0, + "homeOn": true, + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "rowScroll": 0, + "pageScroll": 0 + }, + { + "label": "1440 Enter on More over open list", + "vw": 1440, + "open": true, + "rowCount": 2, + "more": true, + "dropShown": true, + "list": false, + "overlap": false, + "recentActive": null, + "moreActive": "true", + "gapToMore": 0, + "menuTail": 2, + "rowPad": 2, + "tileInset": 11, + "badgeInset": 11, + "dropLeftToTile": 0, + "menu": { + "x": 375, + "y": 0, + "width": 825, + "height": 77, + "top": 0, + "right": 1200, + "bottom": 77, + "left": 375 + }, + "win": { + "x": 1200, + "y": 0, + "width": 240, + "height": 48, + "top": 0, + "right": 1440, + "bottom": 48, + "left": 1200 + }, + "joints": 0, + "homeOn": true, + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "rowScroll": 0, + "pageScroll": 0 + }, + { + "label": "1440 Escape", + "vw": 1440, + "open": true, + "rowCount": 2, + "more": true, + "dropShown": false, + "list": false, + "overlap": false, + "recentActive": null, + "moreActive": null, + "gapToMore": 0, + "menuTail": 2, + "rowPad": 2, + "tileInset": 11, + "badgeInset": 11, + "dropLeftToTile": null, + "menu": { + "x": 375, + "y": 0, + "width": 825, + "height": 77, + "top": 0, + "right": 1200, + "bottom": 77, + "left": 375 + }, + "win": { + "x": 1200, + "y": 0, + "width": 240, + "height": 48, + "top": 0, + "right": 1440, + "bottom": 48, + "left": 1200 + }, + "joints": 0, + "homeOn": true, + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "rowScroll": 0, + "pageScroll": 0 + }, + { + "label": "1080 More open", + "vw": 1080, + "open": true, + "rowCount": 1, + "more": true, + "dropShown": true, + "list": false, + "overlap": false, + "recentActive": null, + "moreActive": "true", + "gapToMore": 0, + "menuTail": 2, + "rowPad": 2, + "tileInset": 11, + "badgeInset": 11, + "dropLeftToTile": 0, + "menu": { + "x": 201, + "y": 0, + "width": 639, + "height": 77, + "top": 0, + "right": 840, + "bottom": 77, + "left": 201 + }, + "win": { + "x": 840, + "y": 0, + "width": 240, + "height": 48, + "top": 0, + "right": 1080, + "bottom": 48, + "left": 840 + }, + "joints": 0, + "homeOn": true, + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "rowScroll": 0, + "pageScroll": 0 + }, + { + "label": "1080 최근파일 open", + "vw": 1080, + "open": true, + "rowCount": 1, + "more": true, + "dropShown": false, + "list": true, + "overlap": false, + "recentActive": "true", + "moreActive": "true", + "gapToMore": 0, + "menuTail": 2, + "rowPad": 2, + "tileInset": 11, + "badgeInset": 11, + "dropLeftToTile": null, + "menu": { + "x": 201, + "y": 0, + "width": 639, + "height": 77, + "top": 0, + "right": 840, + "bottom": 77, + "left": 201 + }, + "win": { + "x": 840, + "y": 0, + "width": 240, + "height": 48, + "top": 0, + "right": 1080, + "bottom": 48, + "left": 840 + }, + "joints": 1, + "homeOn": true, + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "rowScroll": 0, + "pageScroll": 0 + }, + { + "label": "1080 More over open list", + "vw": 1080, + "open": true, + "rowCount": 1, + "more": true, + "dropShown": true, + "list": false, + "overlap": false, + "recentActive": null, + "moreActive": "true", + "gapToMore": 0, + "menuTail": 2, + "rowPad": 2, + "tileInset": 11, + "badgeInset": 11, + "dropLeftToTile": 0, + "menu": { + "x": 201, + "y": 0, + "width": 639, + "height": 77, + "top": 0, + "right": 840, + "bottom": 77, + "left": 201 + }, + "win": { + "x": 840, + "y": 0, + "width": 240, + "height": 48, + "top": 0, + "right": 1080, + "bottom": 48, + "left": 840 + }, + "joints": 0, + "homeOn": true, + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "rowScroll": 0, + "pageScroll": 0 + }, + { + "label": "1080 최근파일 again", + "vw": 1080, + "open": true, + "rowCount": 1, + "more": true, + "dropShown": false, + "list": true, + "overlap": false, + "recentActive": "true", + "moreActive": "true", + "gapToMore": 0, + "menuTail": 2, + "rowPad": 2, + "tileInset": 11, + "badgeInset": 11, + "dropLeftToTile": null, + "menu": { + "x": 201, + "y": 0, + "width": 639, + "height": 77, + "top": 0, + "right": 840, + "bottom": 77, + "left": 201 + }, + "win": { + "x": 840, + "y": 0, + "width": 240, + "height": 48, + "top": 0, + "right": 1080, + "bottom": 48, + "left": 840 + }, + "joints": 1, + "homeOn": true, + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "rowScroll": 0, + "pageScroll": 0 + }, + { + "label": "1080 Enter on More over open list", + "vw": 1080, + "open": true, + "rowCount": 1, + "more": true, + "dropShown": true, + "list": false, + "overlap": false, + "recentActive": null, + "moreActive": "true", + "gapToMore": 0, + "menuTail": 2, + "rowPad": 2, + "tileInset": 11, + "badgeInset": 11, + "dropLeftToTile": 0, + "menu": { + "x": 201, + "y": 0, + "width": 639, + "height": 77, + "top": 0, + "right": 840, + "bottom": 77, + "left": 201 + }, + "win": { + "x": 840, + "y": 0, + "width": 240, + "height": 48, + "top": 0, + "right": 1080, + "bottom": 48, + "left": 840 + }, + "joints": 0, + "homeOn": true, + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "rowScroll": 0, + "pageScroll": 0 + }, + { + "label": "1080 Escape", + "vw": 1080, + "open": true, + "rowCount": 1, + "more": true, + "dropShown": false, + "list": false, + "overlap": false, + "recentActive": null, + "moreActive": null, + "gapToMore": 0, + "menuTail": 2, + "rowPad": 2, + "tileInset": 11, + "badgeInset": 11, + "dropLeftToTile": null, + "menu": { + "x": 201, + "y": 0, + "width": 639, + "height": 77, + "top": 0, + "right": 840, + "bottom": 77, + "left": 201 + }, + "win": { + "x": 840, + "y": 0, + "width": 240, + "height": 48, + "top": 0, + "right": 1080, + "bottom": 48, + "left": 840 + }, + "joints": 0, + "homeOn": true, + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "rowScroll": 0, + "pageScroll": 0 + }, + { + "label": "768 More open", + "vw": 768, + "open": true, + "rowCount": 0, + "more": true, + "dropShown": true, + "list": false, + "overlap": false, + "recentActive": null, + "moreActive": "true", + "gapToMore": 0, + "menuTail": 2, + "rowPad": 2, + "tileInset": 11, + "badgeInset": 11, + "dropLeftToTile": 0, + "menu": { + "x": 304, + "y": 0, + "width": 288, + "height": 77, + "top": 0, + "right": 592, + "bottom": 77, + "left": 304 + }, + "win": { + "x": 592, + "y": 0, + "width": 176, + "height": 48, + "top": 0, + "right": 768, + "bottom": 48, + "left": 592 + }, + "joints": 0, + "homeOn": true, + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "rowScroll": 0, + "pageScroll": 0 + }, + { + "label": "768 최근파일 open", + "vw": 768, + "open": true, + "rowCount": 0, + "more": true, + "dropShown": false, + "list": true, + "overlap": false, + "recentActive": "true", + "moreActive": "true", + "gapToMore": 0, + "menuTail": 2, + "rowPad": 2, + "tileInset": 11, + "badgeInset": 11, + "dropLeftToTile": null, + "menu": { + "x": 304, + "y": 0, + "width": 288, + "height": 77, + "top": 0, + "right": 592, + "bottom": 77, + "left": 304 + }, + "win": { + "x": 592, + "y": 0, + "width": 176, + "height": 48, + "top": 0, + "right": 768, + "bottom": 48, + "left": 592 + }, + "joints": 1, + "homeOn": true, + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "rowScroll": 0, + "pageScroll": 0 + }, + { + "label": "768 More over open list", + "vw": 768, + "open": true, + "rowCount": 0, + "more": true, + "dropShown": true, + "list": false, + "overlap": false, + "recentActive": null, + "moreActive": "true", + "gapToMore": 0, + "menuTail": 2, + "rowPad": 2, + "tileInset": 11, + "badgeInset": 11, + "dropLeftToTile": 0, + "menu": { + "x": 304, + "y": 0, + "width": 288, + "height": 77, + "top": 0, + "right": 592, + "bottom": 77, + "left": 304 + }, + "win": { + "x": 592, + "y": 0, + "width": 176, + "height": 48, + "top": 0, + "right": 768, + "bottom": 48, + "left": 592 + }, + "joints": 0, + "homeOn": true, + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "rowScroll": 0, + "pageScroll": 0 + }, + { + "label": "768 최근파일 again", + "vw": 768, + "open": true, + "rowCount": 0, + "more": true, + "dropShown": false, + "list": true, + "overlap": false, + "recentActive": "true", + "moreActive": "true", + "gapToMore": 0, + "menuTail": 2, + "rowPad": 2, + "tileInset": 11, + "badgeInset": 11, + "dropLeftToTile": null, + "menu": { + "x": 304, + "y": 0, + "width": 288, + "height": 77, + "top": 0, + "right": 592, + "bottom": 77, + "left": 304 + }, + "win": { + "x": 592, + "y": 0, + "width": 176, + "height": 48, + "top": 0, + "right": 768, + "bottom": 48, + "left": 592 + }, + "joints": 1, + "homeOn": true, + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "rowScroll": 0, + "pageScroll": 0 + }, + { + "label": "768 Enter on More over open list", + "vw": 768, + "open": true, + "rowCount": 0, + "more": true, + "dropShown": true, + "list": false, + "overlap": false, + "recentActive": null, + "moreActive": "true", + "gapToMore": 0, + "menuTail": 2, + "rowPad": 2, + "tileInset": 11, + "badgeInset": 11, + "dropLeftToTile": 0, + "menu": { + "x": 304, + "y": 0, + "width": 288, + "height": 77, + "top": 0, + "right": 592, + "bottom": 77, + "left": 304 + }, + "win": { + "x": 592, + "y": 0, + "width": 176, + "height": 48, + "top": 0, + "right": 768, + "bottom": 48, + "left": 592 + }, + "joints": 0, + "homeOn": true, + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "rowScroll": 0, + "pageScroll": 0 + }, + { + "label": "768 Escape", + "vw": 768, + "open": true, + "rowCount": 0, + "more": true, + "dropShown": false, + "list": false, + "overlap": false, + "recentActive": null, + "moreActive": null, + "gapToMore": 0, + "menuTail": 2, + "rowPad": 2, + "tileInset": 11, + "badgeInset": 11, + "dropLeftToTile": null, + "menu": { + "x": 304, + "y": 0, + "width": 288, + "height": 77, + "top": 0, + "right": 592, + "bottom": 77, + "left": 304 + }, + "win": { + "x": 592, + "y": 0, + "width": 176, + "height": 48, + "top": 0, + "right": 768, + "bottom": 48, + "left": 592 + }, + "joints": 0, + "homeOn": true, + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "rowScroll": 0, + "pageScroll": 0 + }, + { + "label": "390 More open", + "vw": 390, + "open": true, + "rowCount": 0, + "more": true, + "dropShown": true, + "list": false, + "overlap": false, + "recentActive": null, + "moreActive": "true", + "gapToMore": 0, + "menuTail": 2, + "rowPad": 2, + "tileInset": 11, + "badgeInset": 11, + "dropLeftToTile": 0, + "menu": { + "x": 161, + "y": 0, + "width": 165, + "height": 77, + "top": 0, + "right": 326, + "bottom": 77, + "left": 161 + }, + "win": { + "x": 326, + "y": 0, + "width": 64, + "height": 48, + "top": 0, + "right": 390, + "bottom": 48, + "left": 326 + }, + "joints": 0, + "homeOn": true, + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "rowScroll": 0, + "pageScroll": 0 + }, + { + "label": "390 최근파일 open", + "vw": 390, + "open": true, + "rowCount": 0, + "more": true, + "dropShown": false, + "list": true, + "overlap": false, + "recentActive": "true", + "moreActive": "true", + "gapToMore": 0, + "menuTail": 2, + "rowPad": 2, + "tileInset": 11, + "badgeInset": 11, + "dropLeftToTile": null, + "menu": { + "x": 161, + "y": 0, + "width": 165, + "height": 77, + "top": 0, + "right": 326, + "bottom": 77, + "left": 161 + }, + "win": { + "x": 326, + "y": 0, + "width": 64, + "height": 48, + "top": 0, + "right": 390, + "bottom": 48, + "left": 326 + }, + "joints": 2, + "homeOn": true, + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "rowScroll": 0, + "pageScroll": 0 + }, + { + "label": "390 More over open list", + "vw": 390, + "open": true, + "rowCount": 0, + "more": true, + "dropShown": true, + "list": false, + "overlap": false, + "recentActive": null, + "moreActive": "true", + "gapToMore": 0, + "menuTail": 2, + "rowPad": 2, + "tileInset": 11, + "badgeInset": 11, + "dropLeftToTile": 0, + "menu": { + "x": 161, + "y": 0, + "width": 165, + "height": 77, + "top": 0, + "right": 326, + "bottom": 77, + "left": 161 + }, + "win": { + "x": 326, + "y": 0, + "width": 64, + "height": 48, + "top": 0, + "right": 390, + "bottom": 48, + "left": 326 + }, + "joints": 0, + "homeOn": true, + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "rowScroll": 0, + "pageScroll": 0 + }, + { + "label": "390 최근파일 again", + "vw": 390, + "open": true, + "rowCount": 0, + "more": true, + "dropShown": false, + "list": true, + "overlap": false, + "recentActive": "true", + "moreActive": "true", + "gapToMore": 0, + "menuTail": 2, + "rowPad": 2, + "tileInset": 11, + "badgeInset": 11, + "dropLeftToTile": null, + "menu": { + "x": 161, + "y": 0, + "width": 165, + "height": 77, + "top": 0, + "right": 326, + "bottom": 77, + "left": 161 + }, + "win": { + "x": 326, + "y": 0, + "width": 64, + "height": 48, + "top": 0, + "right": 390, + "bottom": 48, + "left": 326 + }, + "joints": 2, + "homeOn": true, + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "rowScroll": 0, + "pageScroll": 0 + }, + { + "label": "390 Enter on More over open list", + "vw": 390, + "open": true, + "rowCount": 0, + "more": true, + "dropShown": true, + "list": false, + "overlap": false, + "recentActive": null, + "moreActive": "true", + "gapToMore": 0, + "menuTail": 2, + "rowPad": 2, + "tileInset": 11, + "badgeInset": 11, + "dropLeftToTile": 0, + "menu": { + "x": 161, + "y": 0, + "width": 165, + "height": 77, + "top": 0, + "right": 326, + "bottom": 77, + "left": 161 + }, + "win": { + "x": 326, + "y": 0, + "width": 64, + "height": 48, + "top": 0, + "right": 390, + "bottom": 48, + "left": 326 + }, + "joints": 0, + "homeOn": true, + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "rowScroll": 0, + "pageScroll": 0 + }, + { + "label": "390 Escape", + "vw": 390, + "open": true, + "rowCount": 0, + "more": true, + "dropShown": false, + "list": false, + "overlap": false, + "recentActive": null, + "moreActive": null, + "gapToMore": 0, + "menuTail": 2, + "rowPad": 2, + "tileInset": 11, + "badgeInset": 11, + "dropLeftToTile": null, + "menu": { + "x": 161, + "y": 0, + "width": 165, + "height": 77, + "top": 0, + "right": 326, + "bottom": 77, + "left": 161 + }, + "win": { + "x": 326, + "y": 0, + "width": 64, + "height": 48, + "top": 0, + "right": 390, + "bottom": 48, + "left": 326 + }, + "joints": 0, + "homeOn": true, + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "rowScroll": 0, + "pageScroll": 0 + } + ], + "errors": [] +} \ No newline at end of file diff --git a/docs/sw/home-menu-more-placement-qa-2026-10-19/row-after-1280.png b/docs/sw/home-menu-more-placement-qa-2026-10-19/row-after-1280.png new file mode 100644 index 0000000..d75b07e Binary files /dev/null and b/docs/sw/home-menu-more-placement-qa-2026-10-19/row-after-1280.png differ diff --git a/docs/sw/home-menu-more-placement-qa-2026-10-19/row-after-1920.png b/docs/sw/home-menu-more-placement-qa-2026-10-19/row-after-1920.png new file mode 100644 index 0000000..439e0e1 Binary files /dev/null and b/docs/sw/home-menu-more-placement-qa-2026-10-19/row-after-1920.png differ diff --git a/docs/sw/home-menu-more-placement-qa-2026-10-19/row-after-390.png b/docs/sw/home-menu-more-placement-qa-2026-10-19/row-after-390.png new file mode 100644 index 0000000..ef78300 Binary files /dev/null and b/docs/sw/home-menu-more-placement-qa-2026-10-19/row-after-390.png differ diff --git a/docs/sw/home-menu-more-placement-qa-2026-10-19/row-after-520.png b/docs/sw/home-menu-more-placement-qa-2026-10-19/row-after-520.png new file mode 100644 index 0000000..81aa1c2 Binary files /dev/null and b/docs/sw/home-menu-more-placement-qa-2026-10-19/row-after-520.png differ diff --git a/docs/sw/home-menu-more-placement-qa-2026-10-19/row-after-960.png b/docs/sw/home-menu-more-placement-qa-2026-10-19/row-after-960.png new file mode 100644 index 0000000..fdc5198 Binary files /dev/null and b/docs/sw/home-menu-more-placement-qa-2026-10-19/row-after-960.png differ diff --git a/docs/sw/home-menu-more-qa-2026-10-19/1080-closed.png b/docs/sw/home-menu-more-qa-2026-10-19/1080-closed.png new file mode 100644 index 0000000..3b9de3b Binary files /dev/null and b/docs/sw/home-menu-more-qa-2026-10-19/1080-closed.png differ diff --git a/docs/sw/home-menu-more-qa-2026-10-19/1080-more-hover.png b/docs/sw/home-menu-more-qa-2026-10-19/1080-more-hover.png new file mode 100644 index 0000000..a51592d Binary files /dev/null and b/docs/sw/home-menu-more-qa-2026-10-19/1080-more-hover.png differ diff --git a/docs/sw/home-menu-more-qa-2026-10-19/1080-more-open.png b/docs/sw/home-menu-more-qa-2026-10-19/1080-more-open.png new file mode 100644 index 0000000..3cb26b2 Binary files /dev/null and b/docs/sw/home-menu-more-qa-2026-10-19/1080-more-open.png differ diff --git a/docs/sw/home-menu-more-qa-2026-10-19/1920-back.png b/docs/sw/home-menu-more-qa-2026-10-19/1920-back.png new file mode 100644 index 0000000..c5dcf7a Binary files /dev/null and b/docs/sw/home-menu-more-qa-2026-10-19/1920-back.png differ diff --git a/docs/sw/home-menu-more-qa-2026-10-19/768-recent-from-more.png b/docs/sw/home-menu-more-qa-2026-10-19/768-recent-from-more.png new file mode 100644 index 0000000..c7a010b Binary files /dev/null and b/docs/sw/home-menu-more-qa-2026-10-19/768-recent-from-more.png differ diff --git a/docs/sw/home-menu-more-qa-2026-10-19/page-1024.png b/docs/sw/home-menu-more-qa-2026-10-19/page-1024.png new file mode 100644 index 0000000..a5337cc Binary files /dev/null and b/docs/sw/home-menu-more-qa-2026-10-19/page-1024.png differ diff --git a/docs/sw/home-menu-more-qa-2026-10-19/page-390.png b/docs/sw/home-menu-more-qa-2026-10-19/page-390.png new file mode 100644 index 0000000..6c1b0aa Binary files /dev/null and b/docs/sw/home-menu-more-qa-2026-10-19/page-390.png differ diff --git a/docs/sw/home-menu-more-qa-2026-10-19/report.json b/docs/sw/home-menu-more-qa-2026-10-19/report.json new file mode 100644 index 0000000..0150fde --- /dev/null +++ b/docs/sw/home-menu-more-qa-2026-10-19/report.json @@ -0,0 +1,3588 @@ +{ + "checks": [ + { + "name": "all widths: 5 groups = row + More, order kept", + "ok": true, + "data": [ + [ + 1920, + [ + "작업중인 파일", + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ], + [] + ], + [ + 1680, + [ + "작업중인 파일", + "다른파일 열기", + "파일 손상시" + ], + [ + "My Setting", + "궁금하면" + ] + ], + [ + 1440, + [ + "작업중인 파일", + "다른파일 열기" + ], + [ + "파일 손상시", + "My Setting", + "궁금하면" + ] + ], + [ + 1280, + [ + "작업중인 파일", + "다른파일 열기" + ], + [ + "파일 손상시", + "My Setting", + "궁금하면" + ] + ], + [ + 1180, + [ + "작업중인 파일", + "다른파일 열기" + ], + [ + "파일 손상시", + "My Setting", + "궁금하면" + ] + ], + [ + 1080, + [ + "작업중인 파일" + ], + [ + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ] + ], + [ + 960, + [ + "작업중인 파일" + ], + [ + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ] + ], + [ + 768, + [], + [ + "작업중인 파일", + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ] + ], + [ + 640, + [], + [ + "작업중인 파일", + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ] + ], + [ + 520, + [], + [ + "작업중인 파일", + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ] + ], + [ + 390, + [], + [ + "작업중인 파일", + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ] + ], + [ + 390, + [], + [ + "작업중인 파일", + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ] + ], + [ + 520, + [], + [ + "작업중인 파일", + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ] + ], + [ + 640, + [], + [ + "작업중인 파일", + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ] + ], + [ + 768, + [], + [ + "작업중인 파일", + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ] + ], + [ + 960, + [ + "작업중인 파일" + ], + [ + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ] + ], + [ + 1080, + [ + "작업중인 파일" + ], + [ + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ] + ], + [ + 1180, + [ + "작업중인 파일", + "다른파일 열기" + ], + [ + "파일 손상시", + "My Setting", + "궁금하면" + ] + ], + [ + 1280, + [ + "작업중인 파일", + "다른파일 열기" + ], + [ + "파일 손상시", + "My Setting", + "궁금하면" + ] + ], + [ + 1440, + [ + "작업중인 파일", + "다른파일 열기" + ], + [ + "파일 손상시", + "My Setting", + "궁금하면" + ] + ], + [ + 1680, + [ + "작업중인 파일", + "다른파일 열기", + "파일 손상시" + ], + [ + "My Setting", + "궁금하면" + ] + ], + [ + 1920, + [ + "작업중인 파일", + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ], + [] + ] + ] + }, + { + "name": "1920: all 5 groups in the row, no More", + "ok": true, + "data": { + "vw": 1920, + "open": true, + "homeOn": true, + "homeHover": "1", + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "row": [ + "작업중인 파일", + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ], + "more": false, + "hidden": [], + "panelOpen": false, + "panelVisibility": null, + "rowScroll": 0, + "rowOverflowY": "hidden", + "pageScroll": 0, + "menu": { + "x": 375, + "y": 0, + "width": 1305, + "height": 77, + "top": 0, + "right": 1680, + "bottom": 77, + "left": 375 + }, + "moreRect": null, + "moreButton": null, + "panelRect": null, + "win": { + "x": 1680, + "y": 0, + "width": 240, + "height": 48, + "top": 0, + "right": 1920, + "bottom": 48, + "left": 1680 + }, + "homeRect": { + "x": 0, + "y": 0, + "width": 80, + "height": 48, + "top": 0, + "right": 80, + "bottom": 48, + "left": 0 + }, + "sub": null, + "subFromMore": null + } + }, + { + "name": "narrower: groups move into More (fewer in the row as the width shrinks)", + "ok": true, + "data": [ + [ + 1920, + 5 + ], + [ + 1680, + 3 + ], + [ + 1440, + 2 + ], + [ + 1280, + 2 + ], + [ + 1180, + 2 + ], + [ + 1080, + 1 + ], + [ + 960, + 1 + ], + [ + 768, + 0 + ], + [ + 640, + 0 + ], + [ + 520, + 0 + ], + [ + 390, + 0 + ] + ] + }, + { + "name": "wider again: same split as on the way down (automatic return)", + "ok": true, + "data": [ + [ + 390, + 0 + ], + [ + 520, + 0 + ], + [ + 640, + 0 + ], + [ + 768, + 0 + ], + [ + 960, + 1 + ], + [ + 1080, + 1 + ], + [ + 1180, + 2 + ], + [ + 1280, + 2 + ], + [ + 1440, + 2 + ], + [ + 1680, + 3 + ], + [ + 1920, + 5 + ] + ] + }, + { + "name": "no horizontal scroll anywhere (menu row, page)", + "ok": true, + "data": [ + [ + 1920, + 0, + 0, + "hidden" + ], + [ + 1680, + 0, + 0, + "hidden" + ], + [ + 1440, + 0, + 0, + "hidden" + ], + [ + 1280, + 0, + 0, + "hidden" + ], + [ + 1180, + 0, + 0, + "hidden" + ], + [ + 1080, + 0, + 0, + "hidden" + ], + [ + 960, + 0, + 0, + "hidden" + ], + [ + 768, + 0, + 0, + "hidden" + ], + [ + 640, + 0, + 0, + "hidden" + ], + [ + 520, + 0, + 0, + "hidden" + ], + [ + 390, + 0, + 0, + "hidden" + ], + [ + 390, + 0, + 0, + "hidden" + ], + [ + 520, + 0, + 0, + "hidden" + ], + [ + 640, + 0, + 0, + "hidden" + ], + [ + 768, + 0, + 0, + "hidden" + ], + [ + 960, + 0, + 0, + "hidden" + ], + [ + 1080, + 0, + 0, + "hidden" + ], + [ + 1180, + 0, + 0, + "hidden" + ], + [ + 1280, + 0, + 0, + "hidden" + ], + [ + 1440, + 0, + 0, + "hidden" + ], + [ + 1680, + 0, + 0, + "hidden" + ], + [ + 1920, + 0, + 0, + "hidden" + ] + ] + }, + { + "name": "menu (incl. More) stays left of the window area", + "ok": true, + "data": [ + [ + 1920, + 1680, + 1680 + ], + [ + 1680, + 1440, + 1440 + ], + [ + 1440, + 1200, + 1200 + ], + [ + 1280, + 1040, + 1040 + ], + [ + 1180, + 940, + 940 + ], + [ + 1080, + 840, + 840 + ], + [ + 960, + 784, + 784 + ], + [ + 768, + 592, + 592 + ], + [ + 640, + 464, + 464 + ], + [ + 520, + 456, + 456 + ], + [ + 390, + 326, + 326 + ], + [ + 390, + 326, + 326 + ], + [ + 520, + 456, + 456 + ], + [ + 640, + 464, + 464 + ], + [ + 768, + 592, + 592 + ], + [ + 960, + 784, + 784 + ], + [ + 1080, + 840, + 840 + ], + [ + 1180, + 940, + 940 + ], + [ + 1280, + 1040, + 1040 + ], + [ + 1440, + 1200, + 1200 + ], + [ + 1680, + 1440, + 1440 + ], + [ + 1920, + 1680, + 1680 + ] + ] + }, + { + "name": "with More: the menu still reaches the window area (covers the object area as the full menu)", + "ok": true, + "data": [ + [ + 1920, + 1680, + 1680 + ], + [ + 1680, + 1440, + 1440 + ], + [ + 1440, + 1200, + 1200 + ], + [ + 1280, + 1040, + 1040 + ], + [ + 1180, + 940, + 940 + ], + [ + 1080, + 840, + 840 + ], + [ + 960, + 784, + 784 + ], + [ + 768, + 592, + 592 + ], + [ + 640, + 464, + 464 + ], + [ + 520, + 456, + 456 + ], + [ + 390, + 326, + 326 + ], + [ + 390, + 326, + 326 + ], + [ + 520, + 456, + 456 + ], + [ + 640, + 464, + 464 + ], + [ + 768, + 592, + 592 + ], + [ + 960, + 784, + 784 + ], + [ + 1080, + 840, + 840 + ], + [ + 1180, + 940, + 940 + ], + [ + 1280, + 1040, + 1040 + ], + [ + 1440, + 1200, + 1200 + ], + [ + 1680, + 1440, + 1440 + ], + [ + 1920, + 1680, + 1680 + ] + ] + }, + { + "name": "More label = hidden count", + "ok": true, + "data": [ + "2개 그룹", + "3개 그룹", + "3개 그룹", + "3개 그룹", + "4개 그룹", + "4개 그룹", + "5개 그룹", + "5개 그룹", + "5개 그룹", + "5개 그룹", + "5개 그룹", + "5개 그룹", + "5개 그룹", + "5개 그룹", + "4개 그룹", + "4개 그룹", + "3개 그룹", + "3개 그룹", + "3개 그룹", + "2개 그룹" + ] + }, + { + "name": "Home On kept while open (logo border + #5F4B0F lines)", + "ok": true, + "data": [ + [ + 1920, + true, + "1" + ], + [ + 1680, + true, + "1" + ], + [ + 1440, + true, + "1" + ], + [ + 1280, + true, + "1" + ], + [ + 1180, + true, + "1" + ], + [ + 1080, + true, + "1" + ], + [ + 960, + true, + "1" + ], + [ + 768, + true, + "1" + ], + [ + 640, + true, + "1" + ], + [ + 520, + true, + "1" + ], + [ + 390, + true, + "1" + ], + [ + 390, + true, + "1" + ], + [ + 520, + true, + "1" + ], + [ + 640, + true, + "1" + ], + [ + 768, + true, + "1" + ], + [ + 960, + true, + "1" + ], + [ + 1080, + true, + "1" + ], + [ + 1180, + true, + "1" + ], + [ + 1280, + true, + "1" + ], + [ + 1440, + true, + "1" + ], + [ + 1680, + true, + "1" + ], + [ + 1920, + true, + "1" + ] + ] + }, + { + "name": "1080: More closed by default, dropdown not visible", + "ok": true, + "data": { + "vw": 1080, + "open": true, + "homeOn": true, + "homeHover": "1", + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "row": [ + "작업중인 파일" + ], + "more": true, + "moreLabel": "4개 그룹", + "moreExpanded": "false", + "moreActive": null, + "hidden": [ + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ], + "panelOpen": false, + "panelVisibility": "hidden", + "rowScroll": 0, + "rowOverflowY": "hidden", + "pageScroll": 0, + "menu": { + "x": 201, + "y": 0, + "width": 639, + "height": 77, + "top": 0, + "right": 840, + "bottom": 77, + "left": 201 + }, + "moreRect": { + "x": 543, + "y": 0, + "width": 295, + "height": 75, + "top": 0, + "right": 838, + "bottom": 75, + "left": 543 + }, + "moreButton": { + "x": 748, + "y": 23, + "width": 80, + "height": 46, + "top": 23, + "right": 828, + "bottom": 69, + "left": 748 + }, + "panelRect": { + "x": 567, + "y": 79, + "width": 271, + "height": 322, + "top": 79, + "right": 838, + "bottom": 401, + "left": 567 + }, + "win": { + "x": 840, + "y": 0, + "width": 240, + "height": 48, + "top": 0, + "right": 1080, + "bottom": 48, + "left": 840 + }, + "homeRect": { + "x": 0, + "y": 0, + "width": 80, + "height": 48, + "top": 0, + "right": 80, + "bottom": 48, + "left": 0 + }, + "sub": null, + "subFromMore": null + } + }, + { + "name": "More click opens the dropdown under More (right edges aligned, inside the viewport)", + "ok": true, + "data": { + "vw": 1080, + "open": true, + "homeOn": true, + "homeHover": "1", + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "row": [ + "작업중인 파일" + ], + "more": true, + "moreLabel": "4개 그룹", + "moreExpanded": "true", + "moreActive": "true", + "hidden": [ + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ], + "panelOpen": true, + "panelVisibility": "visible", + "rowScroll": 0, + "rowOverflowY": "hidden", + "pageScroll": 0, + "menu": { + "x": 201, + "y": 0, + "width": 639, + "height": 77, + "top": 0, + "right": 840, + "bottom": 77, + "left": 201 + }, + "moreRect": { + "x": 543, + "y": 0, + "width": 295, + "height": 75, + "top": 0, + "right": 838, + "bottom": 75, + "left": 543 + }, + "moreButton": { + "x": 748, + "y": 23, + "width": 80, + "height": 46, + "top": 23, + "right": 828, + "bottom": 69, + "left": 748 + }, + "panelRect": { + "x": 567, + "y": 79, + "width": 271, + "height": 322, + "top": 79, + "right": 838, + "bottom": 401, + "left": 567 + }, + "win": { + "x": 840, + "y": 0, + "width": 240, + "height": 48, + "top": 0, + "right": 1080, + "bottom": 48, + "left": 840 + }, + "homeRect": { + "x": 0, + "y": 0, + "width": 80, + "height": 48, + "top": 0, + "right": 80, + "bottom": 48, + "left": 0 + }, + "sub": null, + "subFromMore": null + } + }, + { + "name": "hidden tile Hover = Variant2 (ring + #FF5C00)", + "ok": true, + "data": { + "hover": true, + "ring": "1", + "color": "rgb(255, 92, 0)" + } + }, + { + "name": "hidden tile click = Variant3, dropdown stays open", + "ok": true, + "data": { + "active": "true", + "log": null, + "open": true + } + }, + { + "name": "Escape: closes the More dropdown only (menu stays open)", + "ok": true, + "data": { + "vw": 1080, + "open": true, + "homeOn": true, + "homeHover": "1", + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "row": [ + "작업중인 파일" + ], + "more": true, + "moreLabel": "4개 그룹", + "moreExpanded": "false", + "moreActive": null, + "hidden": [ + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ], + "panelOpen": false, + "panelVisibility": "hidden", + "rowScroll": 0, + "rowOverflowY": "hidden", + "pageScroll": 0, + "menu": { + "x": 201, + "y": 0, + "width": 639, + "height": 77, + "top": 0, + "right": 840, + "bottom": 77, + "left": 201 + }, + "moreRect": { + "x": 543, + "y": 0, + "width": 295, + "height": 75, + "top": 0, + "right": 838, + "bottom": 75, + "left": 543 + }, + "moreButton": { + "x": 748, + "y": 23, + "width": 80, + "height": 46, + "top": 23, + "right": 828, + "bottom": 69, + "left": 748 + }, + "panelRect": { + "x": 567, + "y": 79, + "width": 271, + "height": 322, + "top": 79, + "right": 838, + "bottom": 401, + "left": 567 + }, + "win": { + "x": 840, + "y": 0, + "width": 240, + "height": 48, + "top": 0, + "right": 1080, + "bottom": 48, + "left": 840 + }, + "homeRect": { + "x": 0, + "y": 0, + "width": 80, + "height": 48, + "top": 0, + "right": 80, + "bottom": 48, + "left": 0 + }, + "sub": null, + "subFromMore": null + } + }, + { + "name": "second Escape closes the menu → Home On off", + "ok": true, + "data": { + "vw": 1080, + "open": false, + "homeOn": false, + "homeHover": "0", + "lineTop": "rgba(0, 0, 0, 0)", + "lineBottom": "rgba(0, 0, 0, 0)", + "row": [], + "more": false, + "hidden": [], + "panelOpen": false, + "panelVisibility": null, + "rowScroll": null, + "rowOverflowY": null, + "pageScroll": 0, + "menu": null, + "moreRect": null, + "moreButton": null, + "panelRect": null, + "win": { + "x": 840, + "y": 0, + "width": 240, + "height": 48, + "top": 0, + "right": 1080, + "bottom": 48, + "left": 840 + }, + "homeRect": { + "x": 0, + "y": 0, + "width": 80, + "height": 48, + "top": 0, + "right": 80, + "bottom": 48, + "left": 0 + }, + "sub": null, + "subFromMore": null + } + }, + { + "name": "logo click reopens with the same split", + "ok": true, + "data": { + "vw": 1080, + "open": true, + "homeOn": true, + "homeHover": "1", + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "row": [ + "작업중인 파일" + ], + "more": true, + "moreLabel": "4개 그룹", + "moreExpanded": "false", + "moreActive": null, + "hidden": [ + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ], + "panelOpen": false, + "panelVisibility": "hidden", + "rowScroll": 0, + "rowOverflowY": "hidden", + "pageScroll": 0, + "menu": { + "x": 201, + "y": 0, + "width": 639, + "height": 77, + "top": 0, + "right": 840, + "bottom": 77, + "left": 201 + }, + "moreRect": { + "x": 543, + "y": 0, + "width": 295, + "height": 75, + "top": 0, + "right": 838, + "bottom": 75, + "left": 543 + }, + "moreButton": { + "x": 748, + "y": 23, + "width": 80, + "height": 46, + "top": 23, + "right": 828, + "bottom": 69, + "left": 748 + }, + "panelRect": { + "x": 567, + "y": 79, + "width": 271, + "height": 322, + "top": 79, + "right": 838, + "bottom": 401, + "left": 567 + }, + "win": { + "x": 840, + "y": 0, + "width": 240, + "height": 48, + "top": 0, + "right": 1080, + "bottom": 48, + "left": 840 + }, + "homeRect": { + "x": 0, + "y": 0, + "width": 80, + "height": 48, + "top": 0, + "right": 80, + "bottom": 48, + "left": 0 + }, + "sub": null, + "subFromMore": null + } + }, + { + "name": "768: 다른파일 열기 is inside More", + "ok": true, + "data": { + "vw": 768, + "open": true, + "homeOn": true, + "homeHover": "1", + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "row": [], + "more": true, + "moreLabel": "5개 그룹", + "moreExpanded": "false", + "moreActive": null, + "hidden": [ + "작업중인 파일", + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ], + "panelOpen": false, + "panelVisibility": "hidden", + "rowScroll": 0, + "rowOverflowY": "hidden", + "pageScroll": 0, + "menu": { + "x": 304, + "y": 0, + "width": 288, + "height": 77, + "top": 0, + "right": 592, + "bottom": 77, + "left": 304 + }, + "moreRect": { + "x": 306, + "y": 0, + "width": 284, + "height": 75, + "top": 0, + "right": 590, + "bottom": 75, + "left": 306 + }, + "moreButton": { + "x": 500, + "y": 23, + "width": 80, + "height": 46, + "top": 23, + "right": 580, + "bottom": 69, + "left": 500 + }, + "panelRect": { + "x": 240, + "y": 79, + "width": 350, + "height": 401, + "top": 79, + "right": 590, + "bottom": 480, + "left": 240 + }, + "win": { + "x": 592, + "y": 0, + "width": 176, + "height": 48, + "top": 0, + "right": 768, + "bottom": 48, + "left": 592 + }, + "homeRect": { + "x": 0, + "y": 0, + "width": 80, + "height": 48, + "top": 0, + "right": 80, + "bottom": 48, + "left": 0 + }, + "sub": null, + "subFromMore": null + } + }, + { + "name": "최근파일 in More: list opens under the More tile, dropdown closes, More = Variant3, inside the viewport", + "ok": true, + "data": { + "vw": 768, + "open": true, + "homeOn": true, + "homeHover": "1", + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "row": [], + "more": true, + "moreLabel": "5개 그룹", + "moreExpanded": "false", + "moreActive": "true", + "hidden": [ + "작업중인 파일", + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ], + "panelOpen": false, + "panelVisibility": "hidden", + "rowScroll": 0, + "rowOverflowY": "hidden", + "pageScroll": 0, + "menu": { + "x": 304, + "y": 0, + "width": 288, + "height": 77, + "top": 0, + "right": 592, + "bottom": 77, + "left": 304 + }, + "moreRect": { + "x": 306, + "y": 0, + "width": 284, + "height": 75, + "top": 0, + "right": 590, + "bottom": 75, + "left": 306 + }, + "moreButton": { + "x": 500, + "y": 23, + "width": 80, + "height": 46, + "top": 23, + "right": 580, + "bottom": 69, + "left": 500 + }, + "panelRect": { + "x": 240, + "y": 79, + "width": 350, + "height": 401, + "top": 79, + "right": 590, + "bottom": 480, + "left": 240 + }, + "win": { + "x": 592, + "y": 0, + "width": 176, + "height": 48, + "top": 0, + "right": 768, + "bottom": 48, + "left": 592 + }, + "homeRect": { + "x": 0, + "y": 0, + "width": 80, + "height": 48, + "top": 0, + "right": 80, + "bottom": 48, + "left": 0 + }, + "sub": { + "x": 414, + "y": 77, + "width": 354, + "height": 752, + "top": 77, + "right": 768, + "bottom": 829, + "left": 414 + }, + "subFromMore": false + } + }, + { + "name": "Escape closes the 최근파일 list first, menu stays", + "ok": true, + "data": { + "vw": 768, + "open": true, + "homeOn": true, + "homeHover": "1", + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "row": [], + "more": true, + "moreLabel": "5개 그룹", + "moreExpanded": "false", + "moreActive": null, + "hidden": [ + "작업중인 파일", + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ], + "panelOpen": false, + "panelVisibility": "hidden", + "rowScroll": 0, + "rowOverflowY": "hidden", + "pageScroll": 0, + "menu": { + "x": 304, + "y": 0, + "width": 288, + "height": 77, + "top": 0, + "right": 592, + "bottom": 77, + "left": 304 + }, + "moreRect": { + "x": 306, + "y": 0, + "width": 284, + "height": 75, + "top": 0, + "right": 590, + "bottom": 75, + "left": 306 + }, + "moreButton": { + "x": 500, + "y": 23, + "width": 80, + "height": 46, + "top": 23, + "right": 580, + "bottom": 69, + "left": 500 + }, + "panelRect": { + "x": 240, + "y": 79, + "width": 350, + "height": 401, + "top": 79, + "right": 590, + "bottom": 480, + "left": 240 + }, + "win": { + "x": 592, + "y": 0, + "width": 176, + "height": 48, + "top": 0, + "right": 768, + "bottom": 48, + "left": 592 + }, + "homeRect": { + "x": 0, + "y": 0, + "width": 80, + "height": 48, + "top": 0, + "right": 80, + "bottom": 48, + "left": 0 + }, + "sub": null, + "subFromMore": null + } + }, + { + "name": "widen to 1920 with the dropdown open: all groups back in the row, More removed", + "ok": true, + "data": { + "vw": 1920, + "open": true, + "homeOn": true, + "homeHover": "1", + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "row": [ + "작업중인 파일", + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ], + "more": false, + "hidden": [], + "panelOpen": false, + "panelVisibility": null, + "rowScroll": 0, + "rowOverflowY": "hidden", + "pageScroll": 0, + "menu": { + "x": 375, + "y": 0, + "width": 1305, + "height": 77, + "top": 0, + "right": 1680, + "bottom": 77, + "left": 375 + }, + "moreRect": null, + "moreButton": null, + "panelRect": null, + "win": { + "x": 1680, + "y": 0, + "width": 240, + "height": 48, + "top": 0, + "right": 1920, + "bottom": 48, + "left": 1680 + }, + "homeRect": { + "x": 0, + "y": 0, + "width": 80, + "height": 48, + "top": 0, + "right": 80, + "bottom": 48, + "left": 0 + }, + "sub": null, + "subFromMore": null + } + }, + { + "name": "no page errors", + "ok": true, + "data": [] + } + ], + "down": [ + { + "vw": 1920, + "open": true, + "homeOn": true, + "homeHover": "1", + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "row": [ + "작업중인 파일", + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ], + "more": false, + "hidden": [], + "panelOpen": false, + "panelVisibility": null, + "rowScroll": 0, + "rowOverflowY": "hidden", + "pageScroll": 0, + "menu": { + "x": 375, + "y": 0, + "width": 1305, + "height": 77, + "top": 0, + "right": 1680, + "bottom": 77, + "left": 375 + }, + "moreRect": null, + "moreButton": null, + "panelRect": null, + "win": { + "x": 1680, + "y": 0, + "width": 240, + "height": 48, + "top": 0, + "right": 1920, + "bottom": 48, + "left": 1680 + }, + "homeRect": { + "x": 0, + "y": 0, + "width": 80, + "height": 48, + "top": 0, + "right": 80, + "bottom": 48, + "left": 0 + }, + "sub": null, + "subFromMore": null + }, + { + "vw": 1680, + "open": true, + "homeOn": true, + "homeHover": "1", + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "row": [ + "작업중인 파일", + "다른파일 열기", + "파일 손상시" + ], + "more": true, + "moreLabel": "2개 그룹", + "moreExpanded": "false", + "moreActive": null, + "hidden": [ + "My Setting", + "궁금하면" + ], + "panelOpen": false, + "panelVisibility": "hidden", + "rowScroll": 0, + "rowOverflowY": "hidden", + "pageScroll": 0, + "menu": { + "x": 375, + "y": 0, + "width": 1065, + "height": 77, + "top": 0, + "right": 1440, + "bottom": 77, + "left": 375 + }, + "moreRect": { + "x": 1157, + "y": 0, + "width": 281, + "height": 75, + "top": 0, + "right": 1438, + "bottom": 75, + "left": 1157 + }, + "moreButton": { + "x": 1348, + "y": 23, + "width": 80, + "height": 46, + "top": 23, + "right": 1428, + "bottom": 69, + "left": 1348 + }, + "panelRect": { + "x": 1167, + "y": 79, + "width": 271, + "height": 164, + "top": 79, + "right": 1438, + "bottom": 243, + "left": 1167 + }, + "win": { + "x": 1440, + "y": 0, + "width": 240, + "height": 48, + "top": 0, + "right": 1680, + "bottom": 48, + "left": 1440 + }, + "homeRect": { + "x": 0, + "y": 0, + "width": 80, + "height": 48, + "top": 0, + "right": 80, + "bottom": 48, + "left": 0 + }, + "sub": null, + "subFromMore": null + }, + { + "vw": 1440, + "open": true, + "homeOn": true, + "homeHover": "1", + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "row": [ + "작업중인 파일", + "다른파일 열기" + ], + "more": true, + "moreLabel": "3개 그룹", + "moreExpanded": "false", + "moreActive": null, + "hidden": [ + "파일 손상시", + "My Setting", + "궁금하면" + ], + "panelOpen": false, + "panelVisibility": "hidden", + "rowScroll": 0, + "rowOverflowY": "hidden", + "pageScroll": 0, + "menu": { + "x": 375, + "y": 0, + "width": 825, + "height": 77, + "top": 0, + "right": 1200, + "bottom": 77, + "left": 375 + }, + "moreRect": { + "x": 977, + "y": 0, + "width": 221, + "height": 75, + "top": 0, + "right": 1198, + "bottom": 75, + "left": 977 + }, + "moreButton": { + "x": 1108, + "y": 23, + "width": 80, + "height": 46, + "top": 23, + "right": 1188, + "bottom": 69, + "left": 1108 + }, + "panelRect": { + "x": 927, + "y": 79, + "width": 271, + "height": 243, + "top": 79, + "right": 1198, + "bottom": 322, + "left": 927 + }, + "win": { + "x": 1200, + "y": 0, + "width": 240, + "height": 48, + "top": 0, + "right": 1440, + "bottom": 48, + "left": 1200 + }, + "homeRect": { + "x": 0, + "y": 0, + "width": 80, + "height": 48, + "top": 0, + "right": 80, + "bottom": 48, + "left": 0 + }, + "sub": null, + "subFromMore": null + }, + { + "vw": 1280, + "open": true, + "homeOn": true, + "homeHover": "1", + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "row": [ + "작업중인 파일", + "다른파일 열기" + ], + "more": true, + "moreLabel": "3개 그룹", + "moreExpanded": "false", + "moreActive": null, + "hidden": [ + "파일 손상시", + "My Setting", + "궁금하면" + ], + "panelOpen": false, + "panelVisibility": "hidden", + "rowScroll": 0, + "rowOverflowY": "hidden", + "pageScroll": 0, + "menu": { + "x": 315, + "y": 0, + "width": 725, + "height": 77, + "top": 0, + "right": 1040, + "bottom": 77, + "left": 315 + }, + "moreRect": { + "x": 917, + "y": 0, + "width": 121, + "height": 75, + "top": 0, + "right": 1038, + "bottom": 75, + "left": 917 + }, + "moreButton": { + "x": 948, + "y": 23, + "width": 80, + "height": 46, + "top": 23, + "right": 1028, + "bottom": 69, + "left": 948 + }, + "panelRect": { + "x": 767, + "y": 79, + "width": 271, + "height": 243, + "top": 79, + "right": 1038, + "bottom": 322, + "left": 767 + }, + "win": { + "x": 1040, + "y": 0, + "width": 240, + "height": 48, + "top": 0, + "right": 1280, + "bottom": 48, + "left": 1040 + }, + "homeRect": { + "x": 0, + "y": 0, + "width": 80, + "height": 48, + "top": 0, + "right": 80, + "bottom": 48, + "left": 0 + }, + "sub": null, + "subFromMore": null + }, + { + "vw": 1180, + "open": true, + "homeOn": true, + "homeHover": "1", + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "row": [ + "작업중인 파일", + "다른파일 열기" + ], + "more": true, + "moreLabel": "3개 그룹", + "moreExpanded": "false", + "moreActive": null, + "hidden": [ + "파일 손상시", + "My Setting", + "궁금하면" + ], + "panelOpen": false, + "panelVisibility": "hidden", + "rowScroll": 0, + "rowOverflowY": "hidden", + "pageScroll": 0, + "menu": { + "x": 215, + "y": 0, + "width": 725, + "height": 77, + "top": 0, + "right": 940, + "bottom": 77, + "left": 215 + }, + "moreRect": { + "x": 817, + "y": 0, + "width": 121, + "height": 75, + "top": 0, + "right": 938, + "bottom": 75, + "left": 817 + }, + "moreButton": { + "x": 848, + "y": 23, + "width": 80, + "height": 46, + "top": 23, + "right": 928, + "bottom": 69, + "left": 848 + }, + "panelRect": { + "x": 667, + "y": 79, + "width": 271, + "height": 243, + "top": 79, + "right": 938, + "bottom": 322, + "left": 667 + }, + "win": { + "x": 940, + "y": 0, + "width": 240, + "height": 48, + "top": 0, + "right": 1180, + "bottom": 48, + "left": 940 + }, + "homeRect": { + "x": 0, + "y": 0, + "width": 80, + "height": 48, + "top": 0, + "right": 80, + "bottom": 48, + "left": 0 + }, + "sub": null, + "subFromMore": null + }, + { + "vw": 1080, + "open": true, + "homeOn": true, + "homeHover": "1", + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "row": [ + "작업중인 파일" + ], + "more": true, + "moreLabel": "4개 그룹", + "moreExpanded": "false", + "moreActive": null, + "hidden": [ + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ], + "panelOpen": false, + "panelVisibility": "hidden", + "rowScroll": 0, + "rowOverflowY": "hidden", + "pageScroll": 0, + "menu": { + "x": 201, + "y": 0, + "width": 639, + "height": 77, + "top": 0, + "right": 840, + "bottom": 77, + "left": 201 + }, + "moreRect": { + "x": 543, + "y": 0, + "width": 295, + "height": 75, + "top": 0, + "right": 838, + "bottom": 75, + "left": 543 + }, + "moreButton": { + "x": 748, + "y": 23, + "width": 80, + "height": 46, + "top": 23, + "right": 828, + "bottom": 69, + "left": 748 + }, + "panelRect": { + "x": 567, + "y": 79, + "width": 271, + "height": 322, + "top": 79, + "right": 838, + "bottom": 401, + "left": 567 + }, + "win": { + "x": 840, + "y": 0, + "width": 240, + "height": 48, + "top": 0, + "right": 1080, + "bottom": 48, + "left": 840 + }, + "homeRect": { + "x": 0, + "y": 0, + "width": 80, + "height": 48, + "top": 0, + "right": 80, + "bottom": 48, + "left": 0 + }, + "sub": null, + "subFromMore": null + }, + { + "vw": 960, + "open": true, + "homeOn": true, + "homeHover": "1", + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "row": [ + "작업중인 파일" + ], + "more": true, + "moreLabel": "4개 그룹", + "moreExpanded": "false", + "moreActive": null, + "hidden": [ + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ], + "panelOpen": false, + "panelVisibility": "hidden", + "rowScroll": 0, + "rowOverflowY": "hidden", + "pageScroll": 0, + "menu": { + "x": 300, + "y": 0, + "width": 484, + "height": 77, + "top": 0, + "right": 784, + "bottom": 77, + "left": 300 + }, + "moreRect": { + "x": 642, + "y": 0, + "width": 140, + "height": 75, + "top": 0, + "right": 782, + "bottom": 75, + "left": 642 + }, + "moreButton": { + "x": 692, + "y": 23, + "width": 80, + "height": 46, + "top": 23, + "right": 772, + "bottom": 69, + "left": 692 + }, + "panelRect": { + "x": 511, + "y": 79, + "width": 271, + "height": 322, + "top": 79, + "right": 782, + "bottom": 401, + "left": 511 + }, + "win": { + "x": 784, + "y": 0, + "width": 176, + "height": 48, + "top": 0, + "right": 960, + "bottom": 48, + "left": 784 + }, + "homeRect": { + "x": 0, + "y": 0, + "width": 80, + "height": 48, + "top": 0, + "right": 80, + "bottom": 48, + "left": 0 + }, + "sub": null, + "subFromMore": null + }, + { + "vw": 768, + "open": true, + "homeOn": true, + "homeHover": "1", + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "row": [], + "more": true, + "moreLabel": "5개 그룹", + "moreExpanded": "false", + "moreActive": null, + "hidden": [ + "작업중인 파일", + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ], + "panelOpen": false, + "panelVisibility": "hidden", + "rowScroll": 0, + "rowOverflowY": "hidden", + "pageScroll": 0, + "menu": { + "x": 304, + "y": 0, + "width": 288, + "height": 77, + "top": 0, + "right": 592, + "bottom": 77, + "left": 304 + }, + "moreRect": { + "x": 306, + "y": 0, + "width": 284, + "height": 75, + "top": 0, + "right": 590, + "bottom": 75, + "left": 306 + }, + "moreButton": { + "x": 500, + "y": 23, + "width": 80, + "height": 46, + "top": 23, + "right": 580, + "bottom": 69, + "left": 500 + }, + "panelRect": { + "x": 240, + "y": 79, + "width": 350, + "height": 401, + "top": 79, + "right": 590, + "bottom": 480, + "left": 240 + }, + "win": { + "x": 592, + "y": 0, + "width": 176, + "height": 48, + "top": 0, + "right": 768, + "bottom": 48, + "left": 592 + }, + "homeRect": { + "x": 0, + "y": 0, + "width": 80, + "height": 48, + "top": 0, + "right": 80, + "bottom": 48, + "left": 0 + }, + "sub": null, + "subFromMore": null + }, + { + "vw": 640, + "open": true, + "homeOn": true, + "homeHover": "1", + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "row": [], + "more": true, + "moreLabel": "5개 그룹", + "moreExpanded": "false", + "moreActive": null, + "hidden": [ + "작업중인 파일", + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ], + "panelOpen": false, + "panelVisibility": "hidden", + "rowScroll": 0, + "rowOverflowY": "hidden", + "pageScroll": 0, + "menu": { + "x": 176, + "y": 0, + "width": 288, + "height": 77, + "top": 0, + "right": 464, + "bottom": 77, + "left": 176 + }, + "moreRect": { + "x": 178, + "y": 0, + "width": 284, + "height": 75, + "top": 0, + "right": 462, + "bottom": 75, + "left": 178 + }, + "moreButton": { + "x": 372, + "y": 23, + "width": 80, + "height": 46, + "top": 23, + "right": 452, + "bottom": 69, + "left": 372 + }, + "panelRect": { + "x": 112, + "y": 79, + "width": 350, + "height": 401, + "top": 79, + "right": 462, + "bottom": 480, + "left": 112 + }, + "win": { + "x": 464, + "y": 0, + "width": 176, + "height": 48, + "top": 0, + "right": 640, + "bottom": 48, + "left": 464 + }, + "homeRect": { + "x": 0, + "y": 0, + "width": 80, + "height": 48, + "top": 0, + "right": 80, + "bottom": 48, + "left": 0 + }, + "sub": null, + "subFromMore": null + }, + { + "vw": 520, + "open": true, + "homeOn": true, + "homeHover": "1", + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "row": [], + "more": true, + "moreLabel": "5개 그룹", + "moreExpanded": "false", + "moreActive": null, + "hidden": [ + "작업중인 파일", + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ], + "panelOpen": false, + "panelVisibility": "hidden", + "rowScroll": 0, + "rowOverflowY": "hidden", + "pageScroll": 0, + "menu": { + "x": 168, + "y": 0, + "width": 288, + "height": 77, + "top": 0, + "right": 456, + "bottom": 77, + "left": 168 + }, + "moreRect": { + "x": 170, + "y": 0, + "width": 284, + "height": 75, + "top": 0, + "right": 454, + "bottom": 75, + "left": 170 + }, + "moreButton": { + "x": 364, + "y": 23, + "width": 80, + "height": 46, + "top": 23, + "right": 444, + "bottom": 69, + "left": 364 + }, + "panelRect": { + "x": 104, + "y": 79, + "width": 350, + "height": 401, + "top": 79, + "right": 454, + "bottom": 480, + "left": 104 + }, + "win": { + "x": 456, + "y": 0, + "width": 64, + "height": 48, + "top": 0, + "right": 520, + "bottom": 48, + "left": 456 + }, + "homeRect": { + "x": 0, + "y": 0, + "width": 80, + "height": 48, + "top": 0, + "right": 80, + "bottom": 48, + "left": 0 + }, + "sub": null, + "subFromMore": null + }, + { + "vw": 390, + "open": true, + "homeOn": true, + "homeHover": "1", + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "row": [], + "more": true, + "moreLabel": "5개 그룹", + "moreExpanded": "false", + "moreActive": null, + "hidden": [ + "작업중인 파일", + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ], + "panelOpen": false, + "panelVisibility": "hidden", + "rowScroll": 0, + "rowOverflowY": "hidden", + "pageScroll": 0, + "menu": { + "x": 161, + "y": 0, + "width": 165, + "height": 77, + "top": 0, + "right": 326, + "bottom": 77, + "left": 161 + }, + "moreRect": { + "x": 163, + "y": 0, + "width": 161, + "height": 75, + "top": 0, + "right": 324, + "bottom": 75, + "left": 163 + }, + "moreButton": { + "x": 234, + "y": 23, + "width": 80, + "height": 46, + "top": 23, + "right": 314, + "bottom": 69, + "left": 234 + }, + "panelRect": { + "x": 0, + "y": 79, + "width": 350, + "height": 401, + "top": 79, + "right": 350, + "bottom": 480, + "left": 0 + }, + "win": { + "x": 326, + "y": 0, + "width": 64, + "height": 48, + "top": 0, + "right": 390, + "bottom": 48, + "left": 326 + }, + "homeRect": { + "x": 0, + "y": 0, + "width": 80, + "height": 48, + "top": 0, + "right": 80, + "bottom": 48, + "left": 0 + }, + "sub": null, + "subFromMore": null + } + ], + "up": [ + { + "vw": 390, + "open": true, + "homeOn": true, + "homeHover": "1", + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "row": [], + "more": true, + "moreLabel": "5개 그룹", + "moreExpanded": "false", + "moreActive": null, + "hidden": [ + "작업중인 파일", + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ], + "panelOpen": false, + "panelVisibility": "hidden", + "rowScroll": 0, + "rowOverflowY": "hidden", + "pageScroll": 0, + "menu": { + "x": 161, + "y": 0, + "width": 165, + "height": 77, + "top": 0, + "right": 326, + "bottom": 77, + "left": 161 + }, + "moreRect": { + "x": 163, + "y": 0, + "width": 161, + "height": 75, + "top": 0, + "right": 324, + "bottom": 75, + "left": 163 + }, + "moreButton": { + "x": 234, + "y": 23, + "width": 80, + "height": 46, + "top": 23, + "right": 314, + "bottom": 69, + "left": 234 + }, + "panelRect": { + "x": 0, + "y": 79, + "width": 350, + "height": 401, + "top": 79, + "right": 350, + "bottom": 480, + "left": 0 + }, + "win": { + "x": 326, + "y": 0, + "width": 64, + "height": 48, + "top": 0, + "right": 390, + "bottom": 48, + "left": 326 + }, + "homeRect": { + "x": 0, + "y": 0, + "width": 80, + "height": 48, + "top": 0, + "right": 80, + "bottom": 48, + "left": 0 + }, + "sub": null, + "subFromMore": null + }, + { + "vw": 520, + "open": true, + "homeOn": true, + "homeHover": "1", + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "row": [], + "more": true, + "moreLabel": "5개 그룹", + "moreExpanded": "false", + "moreActive": null, + "hidden": [ + "작업중인 파일", + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ], + "panelOpen": false, + "panelVisibility": "hidden", + "rowScroll": 0, + "rowOverflowY": "hidden", + "pageScroll": 0, + "menu": { + "x": 168, + "y": 0, + "width": 288, + "height": 77, + "top": 0, + "right": 456, + "bottom": 77, + "left": 168 + }, + "moreRect": { + "x": 170, + "y": 0, + "width": 284, + "height": 75, + "top": 0, + "right": 454, + "bottom": 75, + "left": 170 + }, + "moreButton": { + "x": 364, + "y": 23, + "width": 80, + "height": 46, + "top": 23, + "right": 444, + "bottom": 69, + "left": 364 + }, + "panelRect": { + "x": 104, + "y": 79, + "width": 350, + "height": 401, + "top": 79, + "right": 454, + "bottom": 480, + "left": 104 + }, + "win": { + "x": 456, + "y": 0, + "width": 64, + "height": 48, + "top": 0, + "right": 520, + "bottom": 48, + "left": 456 + }, + "homeRect": { + "x": 0, + "y": 0, + "width": 80, + "height": 48, + "top": 0, + "right": 80, + "bottom": 48, + "left": 0 + }, + "sub": null, + "subFromMore": null + }, + { + "vw": 640, + "open": true, + "homeOn": true, + "homeHover": "1", + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "row": [], + "more": true, + "moreLabel": "5개 그룹", + "moreExpanded": "false", + "moreActive": null, + "hidden": [ + "작업중인 파일", + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ], + "panelOpen": false, + "panelVisibility": "hidden", + "rowScroll": 0, + "rowOverflowY": "hidden", + "pageScroll": 0, + "menu": { + "x": 176, + "y": 0, + "width": 288, + "height": 77, + "top": 0, + "right": 464, + "bottom": 77, + "left": 176 + }, + "moreRect": { + "x": 178, + "y": 0, + "width": 284, + "height": 75, + "top": 0, + "right": 462, + "bottom": 75, + "left": 178 + }, + "moreButton": { + "x": 372, + "y": 23, + "width": 80, + "height": 46, + "top": 23, + "right": 452, + "bottom": 69, + "left": 372 + }, + "panelRect": { + "x": 112, + "y": 79, + "width": 350, + "height": 401, + "top": 79, + "right": 462, + "bottom": 480, + "left": 112 + }, + "win": { + "x": 464, + "y": 0, + "width": 176, + "height": 48, + "top": 0, + "right": 640, + "bottom": 48, + "left": 464 + }, + "homeRect": { + "x": 0, + "y": 0, + "width": 80, + "height": 48, + "top": 0, + "right": 80, + "bottom": 48, + "left": 0 + }, + "sub": null, + "subFromMore": null + }, + { + "vw": 768, + "open": true, + "homeOn": true, + "homeHover": "1", + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "row": [], + "more": true, + "moreLabel": "5개 그룹", + "moreExpanded": "false", + "moreActive": null, + "hidden": [ + "작업중인 파일", + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ], + "panelOpen": false, + "panelVisibility": "hidden", + "rowScroll": 0, + "rowOverflowY": "hidden", + "pageScroll": 0, + "menu": { + "x": 304, + "y": 0, + "width": 288, + "height": 77, + "top": 0, + "right": 592, + "bottom": 77, + "left": 304 + }, + "moreRect": { + "x": 306, + "y": 0, + "width": 284, + "height": 75, + "top": 0, + "right": 590, + "bottom": 75, + "left": 306 + }, + "moreButton": { + "x": 500, + "y": 23, + "width": 80, + "height": 46, + "top": 23, + "right": 580, + "bottom": 69, + "left": 500 + }, + "panelRect": { + "x": 240, + "y": 79, + "width": 350, + "height": 401, + "top": 79, + "right": 590, + "bottom": 480, + "left": 240 + }, + "win": { + "x": 592, + "y": 0, + "width": 176, + "height": 48, + "top": 0, + "right": 768, + "bottom": 48, + "left": 592 + }, + "homeRect": { + "x": 0, + "y": 0, + "width": 80, + "height": 48, + "top": 0, + "right": 80, + "bottom": 48, + "left": 0 + }, + "sub": null, + "subFromMore": null + }, + { + "vw": 960, + "open": true, + "homeOn": true, + "homeHover": "1", + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "row": [ + "작업중인 파일" + ], + "more": true, + "moreLabel": "4개 그룹", + "moreExpanded": "false", + "moreActive": null, + "hidden": [ + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ], + "panelOpen": false, + "panelVisibility": "hidden", + "rowScroll": 0, + "rowOverflowY": "hidden", + "pageScroll": 0, + "menu": { + "x": 300, + "y": 0, + "width": 484, + "height": 77, + "top": 0, + "right": 784, + "bottom": 77, + "left": 300 + }, + "moreRect": { + "x": 642, + "y": 0, + "width": 140, + "height": 75, + "top": 0, + "right": 782, + "bottom": 75, + "left": 642 + }, + "moreButton": { + "x": 692, + "y": 23, + "width": 80, + "height": 46, + "top": 23, + "right": 772, + "bottom": 69, + "left": 692 + }, + "panelRect": { + "x": 511, + "y": 79, + "width": 271, + "height": 322, + "top": 79, + "right": 782, + "bottom": 401, + "left": 511 + }, + "win": { + "x": 784, + "y": 0, + "width": 176, + "height": 48, + "top": 0, + "right": 960, + "bottom": 48, + "left": 784 + }, + "homeRect": { + "x": 0, + "y": 0, + "width": 80, + "height": 48, + "top": 0, + "right": 80, + "bottom": 48, + "left": 0 + }, + "sub": null, + "subFromMore": null + }, + { + "vw": 1080, + "open": true, + "homeOn": true, + "homeHover": "1", + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "row": [ + "작업중인 파일" + ], + "more": true, + "moreLabel": "4개 그룹", + "moreExpanded": "false", + "moreActive": null, + "hidden": [ + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ], + "panelOpen": false, + "panelVisibility": "hidden", + "rowScroll": 0, + "rowOverflowY": "hidden", + "pageScroll": 0, + "menu": { + "x": 201, + "y": 0, + "width": 639, + "height": 77, + "top": 0, + "right": 840, + "bottom": 77, + "left": 201 + }, + "moreRect": { + "x": 543, + "y": 0, + "width": 295, + "height": 75, + "top": 0, + "right": 838, + "bottom": 75, + "left": 543 + }, + "moreButton": { + "x": 748, + "y": 23, + "width": 80, + "height": 46, + "top": 23, + "right": 828, + "bottom": 69, + "left": 748 + }, + "panelRect": { + "x": 567, + "y": 79, + "width": 271, + "height": 322, + "top": 79, + "right": 838, + "bottom": 401, + "left": 567 + }, + "win": { + "x": 840, + "y": 0, + "width": 240, + "height": 48, + "top": 0, + "right": 1080, + "bottom": 48, + "left": 840 + }, + "homeRect": { + "x": 0, + "y": 0, + "width": 80, + "height": 48, + "top": 0, + "right": 80, + "bottom": 48, + "left": 0 + }, + "sub": null, + "subFromMore": null + }, + { + "vw": 1180, + "open": true, + "homeOn": true, + "homeHover": "1", + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "row": [ + "작업중인 파일", + "다른파일 열기" + ], + "more": true, + "moreLabel": "3개 그룹", + "moreExpanded": "false", + "moreActive": null, + "hidden": [ + "파일 손상시", + "My Setting", + "궁금하면" + ], + "panelOpen": false, + "panelVisibility": "hidden", + "rowScroll": 0, + "rowOverflowY": "hidden", + "pageScroll": 0, + "menu": { + "x": 215, + "y": 0, + "width": 725, + "height": 77, + "top": 0, + "right": 940, + "bottom": 77, + "left": 215 + }, + "moreRect": { + "x": 817, + "y": 0, + "width": 121, + "height": 75, + "top": 0, + "right": 938, + "bottom": 75, + "left": 817 + }, + "moreButton": { + "x": 848, + "y": 23, + "width": 80, + "height": 46, + "top": 23, + "right": 928, + "bottom": 69, + "left": 848 + }, + "panelRect": { + "x": 667, + "y": 79, + "width": 271, + "height": 243, + "top": 79, + "right": 938, + "bottom": 322, + "left": 667 + }, + "win": { + "x": 940, + "y": 0, + "width": 240, + "height": 48, + "top": 0, + "right": 1180, + "bottom": 48, + "left": 940 + }, + "homeRect": { + "x": 0, + "y": 0, + "width": 80, + "height": 48, + "top": 0, + "right": 80, + "bottom": 48, + "left": 0 + }, + "sub": null, + "subFromMore": null + }, + { + "vw": 1280, + "open": true, + "homeOn": true, + "homeHover": "1", + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "row": [ + "작업중인 파일", + "다른파일 열기" + ], + "more": true, + "moreLabel": "3개 그룹", + "moreExpanded": "false", + "moreActive": null, + "hidden": [ + "파일 손상시", + "My Setting", + "궁금하면" + ], + "panelOpen": false, + "panelVisibility": "hidden", + "rowScroll": 0, + "rowOverflowY": "hidden", + "pageScroll": 0, + "menu": { + "x": 315, + "y": 0, + "width": 725, + "height": 77, + "top": 0, + "right": 1040, + "bottom": 77, + "left": 315 + }, + "moreRect": { + "x": 917, + "y": 0, + "width": 121, + "height": 75, + "top": 0, + "right": 1038, + "bottom": 75, + "left": 917 + }, + "moreButton": { + "x": 948, + "y": 23, + "width": 80, + "height": 46, + "top": 23, + "right": 1028, + "bottom": 69, + "left": 948 + }, + "panelRect": { + "x": 767, + "y": 79, + "width": 271, + "height": 243, + "top": 79, + "right": 1038, + "bottom": 322, + "left": 767 + }, + "win": { + "x": 1040, + "y": 0, + "width": 240, + "height": 48, + "top": 0, + "right": 1280, + "bottom": 48, + "left": 1040 + }, + "homeRect": { + "x": 0, + "y": 0, + "width": 80, + "height": 48, + "top": 0, + "right": 80, + "bottom": 48, + "left": 0 + }, + "sub": null, + "subFromMore": null + }, + { + "vw": 1440, + "open": true, + "homeOn": true, + "homeHover": "1", + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "row": [ + "작업중인 파일", + "다른파일 열기" + ], + "more": true, + "moreLabel": "3개 그룹", + "moreExpanded": "false", + "moreActive": null, + "hidden": [ + "파일 손상시", + "My Setting", + "궁금하면" + ], + "panelOpen": false, + "panelVisibility": "hidden", + "rowScroll": 0, + "rowOverflowY": "hidden", + "pageScroll": 0, + "menu": { + "x": 375, + "y": 0, + "width": 825, + "height": 77, + "top": 0, + "right": 1200, + "bottom": 77, + "left": 375 + }, + "moreRect": { + "x": 977, + "y": 0, + "width": 221, + "height": 75, + "top": 0, + "right": 1198, + "bottom": 75, + "left": 977 + }, + "moreButton": { + "x": 1108, + "y": 23, + "width": 80, + "height": 46, + "top": 23, + "right": 1188, + "bottom": 69, + "left": 1108 + }, + "panelRect": { + "x": 927, + "y": 79, + "width": 271, + "height": 243, + "top": 79, + "right": 1198, + "bottom": 322, + "left": 927 + }, + "win": { + "x": 1200, + "y": 0, + "width": 240, + "height": 48, + "top": 0, + "right": 1440, + "bottom": 48, + "left": 1200 + }, + "homeRect": { + "x": 0, + "y": 0, + "width": 80, + "height": 48, + "top": 0, + "right": 80, + "bottom": 48, + "left": 0 + }, + "sub": null, + "subFromMore": null + }, + { + "vw": 1680, + "open": true, + "homeOn": true, + "homeHover": "1", + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "row": [ + "작업중인 파일", + "다른파일 열기", + "파일 손상시" + ], + "more": true, + "moreLabel": "2개 그룹", + "moreExpanded": "false", + "moreActive": null, + "hidden": [ + "My Setting", + "궁금하면" + ], + "panelOpen": false, + "panelVisibility": "hidden", + "rowScroll": 0, + "rowOverflowY": "hidden", + "pageScroll": 0, + "menu": { + "x": 375, + "y": 0, + "width": 1065, + "height": 77, + "top": 0, + "right": 1440, + "bottom": 77, + "left": 375 + }, + "moreRect": { + "x": 1157, + "y": 0, + "width": 281, + "height": 75, + "top": 0, + "right": 1438, + "bottom": 75, + "left": 1157 + }, + "moreButton": { + "x": 1348, + "y": 23, + "width": 80, + "height": 46, + "top": 23, + "right": 1428, + "bottom": 69, + "left": 1348 + }, + "panelRect": { + "x": 1167, + "y": 79, + "width": 271, + "height": 164, + "top": 79, + "right": 1438, + "bottom": 243, + "left": 1167 + }, + "win": { + "x": 1440, + "y": 0, + "width": 240, + "height": 48, + "top": 0, + "right": 1680, + "bottom": 48, + "left": 1440 + }, + "homeRect": { + "x": 0, + "y": 0, + "width": 80, + "height": 48, + "top": 0, + "right": 80, + "bottom": 48, + "left": 0 + }, + "sub": null, + "subFromMore": null + }, + { + "vw": 1920, + "open": true, + "homeOn": true, + "homeHover": "1", + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "row": [ + "작업중인 파일", + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ], + "more": false, + "hidden": [], + "panelOpen": false, + "panelVisibility": null, + "rowScroll": 0, + "rowOverflowY": "hidden", + "pageScroll": 0, + "menu": { + "x": 375, + "y": 0, + "width": 1305, + "height": 77, + "top": 0, + "right": 1680, + "bottom": 77, + "left": 375 + }, + "moreRect": null, + "moreButton": null, + "panelRect": null, + "win": { + "x": 1680, + "y": 0, + "width": 240, + "height": 48, + "top": 0, + "right": 1920, + "bottom": 48, + "left": 1680 + }, + "homeRect": { + "x": 0, + "y": 0, + "width": 80, + "height": 48, + "top": 0, + "right": 80, + "bottom": 48, + "left": 0 + }, + "sub": null, + "subFromMore": null + } + ], + "errors": [] +} \ No newline at end of file diff --git a/docs/sw/home-menu-more-text-qa-2026-10-19/narrow-1080-active.png b/docs/sw/home-menu-more-text-qa-2026-10-19/narrow-1080-active.png new file mode 100644 index 0000000..e074efd Binary files /dev/null and b/docs/sw/home-menu-more-text-qa-2026-10-19/narrow-1080-active.png differ diff --git a/docs/sw/home-menu-more-text-qa-2026-10-19/narrow-1080-closed.png b/docs/sw/home-menu-more-text-qa-2026-10-19/narrow-1080-closed.png new file mode 100644 index 0000000..3b9de3b Binary files /dev/null and b/docs/sw/home-menu-more-text-qa-2026-10-19/narrow-1080-closed.png differ diff --git a/docs/sw/home-menu-more-text-qa-2026-10-19/narrow-1080-hover.png b/docs/sw/home-menu-more-text-qa-2026-10-19/narrow-1080-hover.png new file mode 100644 index 0000000..b9b9fe1 Binary files /dev/null and b/docs/sw/home-menu-more-text-qa-2026-10-19/narrow-1080-hover.png differ diff --git a/docs/sw/home-menu-more-text-qa-2026-10-19/narrow-1080-open.png b/docs/sw/home-menu-more-text-qa-2026-10-19/narrow-1080-open.png new file mode 100644 index 0000000..7dd8275 Binary files /dev/null and b/docs/sw/home-menu-more-text-qa-2026-10-19/narrow-1080-open.png differ diff --git a/docs/sw/home-menu-more-text-qa-2026-10-19/narrow-1080-recent-preview.png b/docs/sw/home-menu-more-text-qa-2026-10-19/narrow-1080-recent-preview.png new file mode 100644 index 0000000..3bc7c34 Binary files /dev/null and b/docs/sw/home-menu-more-text-qa-2026-10-19/narrow-1080-recent-preview.png differ diff --git a/docs/sw/home-menu-more-text-qa-2026-10-19/narrow-768-recent-more.png b/docs/sw/home-menu-more-text-qa-2026-10-19/narrow-768-recent-more.png new file mode 100644 index 0000000..b5d015d Binary files /dev/null and b/docs/sw/home-menu-more-text-qa-2026-10-19/narrow-768-recent-more.png differ diff --git a/docs/sw/home-menu-more-text-qa-2026-10-19/narrow-768-recent.png b/docs/sw/home-menu-more-text-qa-2026-10-19/narrow-768-recent.png new file mode 100644 index 0000000..2138405 Binary files /dev/null and b/docs/sw/home-menu-more-text-qa-2026-10-19/narrow-768-recent.png differ diff --git a/docs/sw/home-menu-more-text-qa-2026-10-19/report.json b/docs/sw/home-menu-more-text-qa-2026-10-19/report.json new file mode 100644 index 0000000..b50f4cc --- /dev/null +++ b/docs/sw/home-menu-more-text-qa-2026-10-19/report.json @@ -0,0 +1,4471 @@ +{ + "checks": [ + { + "name": "all widths: 5 groups = Figma row + More text groups, order kept", + "ok": true, + "data": [ + [ + 1920, + [ + "작업중인 파일", + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ], + [] + ], + [ + 1680, + [ + "작업중인 파일", + "다른파일 열기", + "파일 손상시" + ], + [ + "My Setting", + "궁금하면" + ] + ], + [ + 1440, + [ + "작업중인 파일", + "다른파일 열기" + ], + [ + "파일 손상시", + "My Setting", + "궁금하면" + ] + ], + [ + 1280, + [ + "작업중인 파일", + "다른파일 열기" + ], + [ + "파일 손상시", + "My Setting", + "궁금하면" + ] + ], + [ + 1180, + [ + "작업중인 파일", + "다른파일 열기" + ], + [ + "파일 손상시", + "My Setting", + "궁금하면" + ] + ], + [ + 1080, + [ + "작업중인 파일" + ], + [ + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ] + ], + [ + 960, + [ + "작업중인 파일" + ], + [ + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ] + ], + [ + 768, + [], + [ + "작업중인 파일", + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ] + ], + [ + 640, + [], + [ + "작업중인 파일", + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ] + ], + [ + 520, + [], + [ + "작업중인 파일", + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ] + ], + [ + 390, + [], + [ + "작업중인 파일", + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ] + ], + [ + 390, + [], + [ + "작업중인 파일", + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ] + ], + [ + 520, + [], + [ + "작업중인 파일", + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ] + ], + [ + 640, + [], + [ + "작업중인 파일", + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ] + ], + [ + 768, + [], + [ + "작업중인 파일", + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ] + ], + [ + 960, + [ + "작업중인 파일" + ], + [ + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ] + ], + [ + 1080, + [ + "작업중인 파일" + ], + [ + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ] + ], + [ + 1180, + [ + "작업중인 파일", + "다른파일 열기" + ], + [ + "파일 손상시", + "My Setting", + "궁금하면" + ] + ], + [ + 1280, + [ + "작업중인 파일", + "다른파일 열기" + ], + [ + "파일 손상시", + "My Setting", + "궁금하면" + ] + ], + [ + 1440, + [ + "작업중인 파일", + "다른파일 열기" + ], + [ + "파일 손상시", + "My Setting", + "궁금하면" + ] + ], + [ + 1680, + [ + "작업중인 파일", + "다른파일 열기", + "파일 손상시" + ], + [ + "My Setting", + "궁금하면" + ] + ], + [ + 1920, + [ + "작업중인 파일", + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ], + [] + ] + ] + }, + { + "name": "1920: all 5 groups in the row, no More", + "ok": true, + "data": { + "vw": 1920, + "open": true, + "homeOn": true, + "homeHover": "1", + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "row": [ + "작업중인 파일", + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ], + "rowTilesOnly": true, + "more": false, + "hidden": [], + "hiddenItems": [], + "panelTiles": 0, + "dividers": [], + "panelOpen": false, + "panelVisibility": null, + "rowScroll": 0, + "rowOverflowX": "hidden", + "pageScroll": 0, + "menu": { + "x": 375, + "y": 0, + "width": 1305, + "height": 77, + "top": 0, + "right": 1680, + "bottom": 77, + "left": 375 + }, + "moreRect": null, + "moreButton": null, + "panelRect": null, + "win": { + "x": 1680, + "y": 0, + "width": 240, + "height": 48, + "top": 0, + "right": 1920, + "bottom": 48, + "left": 1680 + }, + "sub": null, + "subFromMore": null + } + }, + { + "name": "narrower: groups move into More; wider: they return (same split both ways)", + "ok": true, + "data": [ + [ + 1920, + 5 + ], + [ + 1680, + 3 + ], + [ + 1440, + 2 + ], + [ + 1280, + 2 + ], + [ + 1180, + 2 + ], + [ + 1080, + 1 + ], + [ + 960, + 1 + ], + [ + 768, + 0 + ], + [ + 640, + 0 + ], + [ + 520, + 0 + ], + [ + 390, + 0 + ], + [ + 390, + 0 + ], + [ + 520, + 0 + ], + [ + 640, + 0 + ], + [ + 768, + 0 + ], + [ + 960, + 1 + ], + [ + 1080, + 1 + ], + [ + 1180, + 2 + ], + [ + 1280, + 2 + ], + [ + 1440, + 2 + ], + [ + 1680, + 3 + ], + [ + 1920, + 5 + ] + ] + }, + { + "name": "row keeps the Figma tiles; dropdown has no tiles or icons", + "ok": true, + "data": [ + [ + 1920, + true, + 0 + ], + [ + 1680, + true, + 0 + ], + [ + 1440, + true, + 0 + ], + [ + 1280, + true, + 0 + ], + [ + 1180, + true, + 0 + ], + [ + 1080, + true, + 0 + ], + [ + 960, + true, + 0 + ], + [ + 768, + true, + 0 + ], + [ + 640, + true, + 0 + ], + [ + 520, + true, + 0 + ], + [ + 390, + true, + 0 + ], + [ + 390, + true, + 0 + ], + [ + 520, + true, + 0 + ], + [ + 640, + true, + 0 + ], + [ + 768, + true, + 0 + ], + [ + 960, + true, + 0 + ], + [ + 1080, + true, + 0 + ], + [ + 1180, + true, + 0 + ], + [ + 1280, + true, + 0 + ], + [ + 1440, + true, + 0 + ], + [ + 1680, + true, + 0 + ], + [ + 1920, + true, + 0 + ] + ] + }, + { + "name": "text groups: title + every item of that group as text, in order", + "ok": true, + "data": [ + [ + 1920, + [], + [] + ], + [ + 1680, + [ + "My Setting", + "궁금하면" + ], + [ + [ + "Display...", + "저장하기", + "불러오기" + ], + [ + "설명보기", + "문의하기", + "S/W정보" + ] + ] + ], + [ + 1440, + [ + "파일 손상시", + "My Setting", + "궁금하면" + ], + [ + [ + "복구하기", + "임시파일" + ], + [ + "Display...", + "저장하기", + "불러오기" + ], + [ + "설명보기", + "문의하기", + "S/W정보" + ] + ] + ], + [ + 1280, + [ + "파일 손상시", + "My Setting", + "궁금하면" + ], + [ + [ + "복구하기", + "임시파일" + ], + [ + "Display...", + "저장하기", + "불러오기" + ], + [ + "설명보기", + "문의하기", + "S/W정보" + ] + ] + ], + [ + 1180, + [ + "파일 손상시", + "My Setting", + "궁금하면" + ], + [ + [ + "복구하기", + "임시파일" + ], + [ + "Display...", + "저장하기", + "불러오기" + ], + [ + "설명보기", + "문의하기", + "S/W정보" + ] + ] + ], + [ + 1080, + [ + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ], + [ + [ + "찾아열기", + "최근파일", + "새파일" + ], + [ + "복구하기", + "임시파일" + ], + [ + "Display...", + "저장하기", + "불러오기" + ], + [ + "설명보기", + "문의하기", + "S/W정보" + ] + ] + ], + [ + 960, + [ + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ], + [ + [ + "찾아열기", + "최근파일", + "새파일" + ], + [ + "복구하기", + "임시파일" + ], + [ + "Display...", + "저장하기", + "불러오기" + ], + [ + "설명보기", + "문의하기", + "S/W정보" + ] + ] + ], + [ + 768, + [ + "작업중인 파일", + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ], + [ + [ + "저장", + "복사저장", + "내보내기", + "도면묶기" + ], + [ + "찾아열기", + "최근파일", + "새파일" + ], + [ + "복구하기", + "임시파일" + ], + [ + "Display...", + "저장하기", + "불러오기" + ], + [ + "설명보기", + "문의하기", + "S/W정보" + ] + ] + ], + [ + 640, + [ + "작업중인 파일", + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ], + [ + [ + "저장", + "복사저장", + "내보내기", + "도면묶기" + ], + [ + "찾아열기", + "최근파일", + "새파일" + ], + [ + "복구하기", + "임시파일" + ], + [ + "Display...", + "저장하기", + "불러오기" + ], + [ + "설명보기", + "문의하기", + "S/W정보" + ] + ] + ], + [ + 520, + [ + "작업중인 파일", + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ], + [ + [ + "저장", + "복사저장", + "내보내기", + "도면묶기" + ], + [ + "찾아열기", + "최근파일", + "새파일" + ], + [ + "복구하기", + "임시파일" + ], + [ + "Display...", + "저장하기", + "불러오기" + ], + [ + "설명보기", + "문의하기", + "S/W정보" + ] + ] + ], + [ + 390, + [ + "작업중인 파일", + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ], + [ + [ + "저장", + "복사저장", + "내보내기", + "도면묶기" + ], + [ + "찾아열기", + "최근파일", + "새파일" + ], + [ + "복구하기", + "임시파일" + ], + [ + "Display...", + "저장하기", + "불러오기" + ], + [ + "설명보기", + "문의하기", + "S/W정보" + ] + ] + ], + [ + 390, + [ + "작업중인 파일", + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ], + [ + [ + "저장", + "복사저장", + "내보내기", + "도면묶기" + ], + [ + "찾아열기", + "최근파일", + "새파일" + ], + [ + "복구하기", + "임시파일" + ], + [ + "Display...", + "저장하기", + "불러오기" + ], + [ + "설명보기", + "문의하기", + "S/W정보" + ] + ] + ], + [ + 520, + [ + "작업중인 파일", + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ], + [ + [ + "저장", + "복사저장", + "내보내기", + "도면묶기" + ], + [ + "찾아열기", + "최근파일", + "새파일" + ], + [ + "복구하기", + "임시파일" + ], + [ + "Display...", + "저장하기", + "불러오기" + ], + [ + "설명보기", + "문의하기", + "S/W정보" + ] + ] + ], + [ + 640, + [ + "작업중인 파일", + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ], + [ + [ + "저장", + "복사저장", + "내보내기", + "도면묶기" + ], + [ + "찾아열기", + "최근파일", + "새파일" + ], + [ + "복구하기", + "임시파일" + ], + [ + "Display...", + "저장하기", + "불러오기" + ], + [ + "설명보기", + "문의하기", + "S/W정보" + ] + ] + ], + [ + 768, + [ + "작업중인 파일", + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ], + [ + [ + "저장", + "복사저장", + "내보내기", + "도면묶기" + ], + [ + "찾아열기", + "최근파일", + "새파일" + ], + [ + "복구하기", + "임시파일" + ], + [ + "Display...", + "저장하기", + "불러오기" + ], + [ + "설명보기", + "문의하기", + "S/W정보" + ] + ] + ], + [ + 960, + [ + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ], + [ + [ + "찾아열기", + "최근파일", + "새파일" + ], + [ + "복구하기", + "임시파일" + ], + [ + "Display...", + "저장하기", + "불러오기" + ], + [ + "설명보기", + "문의하기", + "S/W정보" + ] + ] + ], + [ + 1080, + [ + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ], + [ + [ + "찾아열기", + "최근파일", + "새파일" + ], + [ + "복구하기", + "임시파일" + ], + [ + "Display...", + "저장하기", + "불러오기" + ], + [ + "설명보기", + "문의하기", + "S/W정보" + ] + ] + ], + [ + 1180, + [ + "파일 손상시", + "My Setting", + "궁금하면" + ], + [ + [ + "복구하기", + "임시파일" + ], + [ + "Display...", + "저장하기", + "불러오기" + ], + [ + "설명보기", + "문의하기", + "S/W정보" + ] + ] + ], + [ + 1280, + [ + "파일 손상시", + "My Setting", + "궁금하면" + ], + [ + [ + "복구하기", + "임시파일" + ], + [ + "Display...", + "저장하기", + "불러오기" + ], + [ + "설명보기", + "문의하기", + "S/W정보" + ] + ] + ], + [ + 1440, + [ + "파일 손상시", + "My Setting", + "궁금하면" + ], + [ + [ + "복구하기", + "임시파일" + ], + [ + "Display...", + "저장하기", + "불러오기" + ], + [ + "설명보기", + "문의하기", + "S/W정보" + ] + ] + ], + [ + 1680, + [ + "My Setting", + "궁금하면" + ], + [ + [ + "Display...", + "저장하기", + "불러오기" + ], + [ + "설명보기", + "문의하기", + "S/W정보" + ] + ] + ], + [ + 1920, + [], + [] + ] + ] + }, + { + "name": "divider between groups (1px top border on every group after the first)", + "ok": true, + "data": [ + [], + [ + "0px", + "1px" + ], + [ + "0px", + "1px", + "1px" + ], + [ + "0px", + "1px", + "1px" + ], + [ + "0px", + "1px", + "1px" + ], + [ + "0px", + "1px", + "1px", + "1px" + ], + [ + "0px", + "1px", + "1px", + "1px" + ], + [ + "0px", + "1px", + "1px", + "1px", + "1px" + ], + [ + "0px", + "1px", + "1px", + "1px", + "1px" + ], + [ + "0px", + "1px", + "1px", + "1px", + "1px" + ], + [ + "0px", + "1px", + "1px", + "1px", + "1px" + ], + [ + "0px", + "1px", + "1px", + "1px", + "1px" + ], + [ + "0px", + "1px", + "1px", + "1px", + "1px" + ], + [ + "0px", + "1px", + "1px", + "1px", + "1px" + ], + [ + "0px", + "1px", + "1px", + "1px", + "1px" + ], + [ + "0px", + "1px", + "1px", + "1px" + ], + [ + "0px", + "1px", + "1px", + "1px" + ], + [ + "0px", + "1px", + "1px" + ], + [ + "0px", + "1px", + "1px" + ], + [ + "0px", + "1px", + "1px" + ], + [ + "0px", + "1px" + ], + [] + ] + }, + { + "name": "no horizontal scroll (menu row, page)", + "ok": true, + "data": [ + [ + 1920, + 0, + 0 + ], + [ + 1680, + 0, + 0 + ], + [ + 1440, + 0, + 0 + ], + [ + 1280, + 0, + 0 + ], + [ + 1180, + 0, + 0 + ], + [ + 1080, + 0, + 0 + ], + [ + 960, + 0, + 0 + ], + [ + 768, + 0, + 0 + ], + [ + 640, + 0, + 0 + ], + [ + 520, + 0, + 0 + ], + [ + 390, + 0, + 0 + ], + [ + 390, + 0, + 0 + ], + [ + 520, + 0, + 0 + ], + [ + 640, + 0, + 0 + ], + [ + 768, + 0, + 0 + ], + [ + 960, + 0, + 0 + ], + [ + 1080, + 0, + 0 + ], + [ + 1180, + 0, + 0 + ], + [ + 1280, + 0, + 0 + ], + [ + 1440, + 0, + 0 + ], + [ + 1680, + 0, + 0 + ], + [ + 1920, + 0, + 0 + ] + ] + }, + { + "name": "Home On kept while open (logo border + #5F4B0F lines)", + "ok": true, + "data": [ + [ + 1920, + true + ], + [ + 1680, + true + ], + [ + 1440, + true + ], + [ + 1280, + true + ], + [ + 1180, + true + ], + [ + 1080, + true + ], + [ + 960, + true + ], + [ + 768, + true + ], + [ + 640, + true + ], + [ + 520, + true + ], + [ + 390, + true + ], + [ + 390, + true + ], + [ + 520, + true + ], + [ + 640, + true + ], + [ + 768, + true + ], + [ + 960, + true + ], + [ + 1080, + true + ], + [ + 1180, + true + ], + [ + 1280, + true + ], + [ + 1440, + true + ], + [ + 1680, + true + ], + [ + 1920, + true + ] + ] + }, + { + "name": "More click opens the text menu under More (right edges aligned, inside the viewport)", + "ok": true, + "data": { + "vw": 1080, + "open": true, + "homeOn": true, + "homeHover": "1", + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "row": [ + "작업중인 파일" + ], + "rowTilesOnly": true, + "more": true, + "moreLabel": "4개 그룹", + "moreExpanded": "true", + "moreActive": "true", + "hidden": [ + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ], + "hiddenItems": [ + [ + "찾아열기", + "최근파일", + "새파일" + ], + [ + "복구하기", + "임시파일" + ], + [ + "Display...", + "저장하기", + "불러오기" + ], + [ + "설명보기", + "문의하기", + "S/W정보" + ] + ], + "panelTiles": 0, + "dividers": [ + "0px", + "1px", + "1px", + "1px" + ], + "panelOpen": true, + "panelVisibility": "visible", + "rowScroll": 0, + "rowOverflowX": "hidden", + "pageScroll": 0, + "menu": { + "x": 201, + "y": 0, + "width": 639, + "height": 77, + "top": 0, + "right": 840, + "bottom": 77, + "left": 201 + }, + "moreRect": { + "x": 543, + "y": 0, + "width": 295, + "height": 75, + "top": 0, + "right": 838, + "bottom": 75, + "left": 543 + }, + "moreButton": { + "x": 748, + "y": 23, + "width": 80, + "height": 46, + "top": 23, + "right": 828, + "bottom": 69, + "left": 748 + }, + "panelRect": { + "x": 658, + "y": 79, + "width": 180, + "height": 471, + "top": 79, + "right": 838, + "bottom": 550, + "left": 658 + }, + "win": { + "x": 840, + "y": 0, + "width": 240, + "height": 48, + "top": 0, + "right": 1080, + "bottom": 48, + "left": 840 + }, + "sub": null, + "subFromMore": null + } + }, + { + "name": "text menu uses SW tokens (brown dropdown #27241D / #000 / 3px, title 12px 700 #D4CBBD, rows 14px 700 #F6F4F2 30px 12px, Noto Sans KR)", + "ok": true, + "data": { + "panelBg": "rgb(39, 36, 29)", + "panelBorder": "rgb(0, 0, 0)", + "radius": "3px", + "title": [ + "12px", + "700", + "rgb(212, 203, 189)" + ], + "item": [ + "14px", + "700", + "rgb(246, 244, 242)", + "30px", + "12px" + ], + "family": "\"Noto Sans KR\"" + } + }, + { + "name": "text row Hover: #62533D row, #FF5C00 text (SW brown row hover)", + "ok": true, + "data": { + "hover": true, + "bg": "rgb(98, 83, 61)", + "color": "rgb(255, 92, 0)" + } + }, + { + "name": "text row click: Active (aria-pressed, ✓, orange on brown), dropdown stays open, same callbacks as the tile", + "ok": true, + "data": { + "act": { + "active": "true", + "pressed": "true", + "mark": "\"✓\"", + "bg": "rgb(98, 83, 61)", + "color": "rgb(255, 92, 0)", + "open": true, + "log": "" + }, + "before": "" + } + }, + { + "name": "second click: back to default", + "ok": true, + "data": null + }, + { + "name": "Escape closes only the dropdown (focus on More)", + "ok": true, + "data": { + "s": { + "vw": 1080, + "open": true, + "homeOn": true, + "homeHover": "1", + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "row": [ + "작업중인 파일" + ], + "rowTilesOnly": true, + "more": true, + "moreLabel": "4개 그룹", + "moreExpanded": "false", + "moreActive": null, + "hidden": [ + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ], + "hiddenItems": [ + [ + "찾아열기", + "최근파일", + "새파일" + ], + [ + "복구하기", + "임시파일" + ], + [ + "Display...", + "저장하기", + "불러오기" + ], + [ + "설명보기", + "문의하기", + "S/W정보" + ] + ], + "panelTiles": 0, + "dividers": [ + "0px", + "1px", + "1px", + "1px" + ], + "panelOpen": false, + "panelVisibility": "hidden", + "rowScroll": 0, + "rowOverflowX": "hidden", + "pageScroll": 0, + "menu": { + "x": 201, + "y": 0, + "width": 639, + "height": 77, + "top": 0, + "right": 840, + "bottom": 77, + "left": 201 + }, + "moreRect": { + "x": 543, + "y": 0, + "width": 295, + "height": 75, + "top": 0, + "right": 838, + "bottom": 75, + "left": 543 + }, + "moreButton": { + "x": 748, + "y": 23, + "width": 80, + "height": 46, + "top": 23, + "right": 828, + "bottom": 69, + "left": 748 + }, + "panelRect": { + "x": 658, + "y": 79, + "width": 180, + "height": 471, + "top": 79, + "right": 838, + "bottom": 550, + "left": 658 + }, + "win": { + "x": 840, + "y": 0, + "width": 240, + "height": 48, + "top": 0, + "right": 1080, + "bottom": 48, + "left": 840 + }, + "sub": null, + "subFromMore": null + }, + "focused": "MORE" + } + }, + { + "name": "keyboard: ArrowDown on More opens on the first row, ArrowDown next, ArrowUp back to More", + "ok": true, + "data": [ + "find-open", + "recent", + "MORE" + ] + }, + { + "name": "keyboard: Enter on 최근파일 opens the list under More, focus back on More", + "ok": true, + "data": { + "s": { + "vw": 1080, + "open": true, + "homeOn": true, + "homeHover": "1", + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "row": [ + "작업중인 파일" + ], + "rowTilesOnly": true, + "more": true, + "moreLabel": "4개 그룹", + "moreExpanded": "false", + "moreActive": "true", + "hidden": [ + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ], + "hiddenItems": [ + [ + "찾아열기", + "최근파일", + "새파일" + ], + [ + "복구하기", + "임시파일" + ], + [ + "Display...", + "저장하기", + "불러오기" + ], + [ + "설명보기", + "문의하기", + "S/W정보" + ] + ], + "panelTiles": 0, + "dividers": [ + "0px", + "1px", + "1px", + "1px" + ], + "panelOpen": false, + "panelVisibility": "hidden", + "rowScroll": 0, + "rowOverflowX": "hidden", + "pageScroll": 0, + "menu": { + "x": 201, + "y": 0, + "width": 639, + "height": 77, + "top": 0, + "right": 840, + "bottom": 77, + "left": 201 + }, + "moreRect": { + "x": 543, + "y": 0, + "width": 295, + "height": 75, + "top": 0, + "right": 838, + "bottom": 75, + "left": 543 + }, + "moreButton": { + "x": 748, + "y": 23, + "width": 80, + "height": 46, + "top": 23, + "right": 828, + "bottom": 69, + "left": 748 + }, + "panelRect": { + "x": 658, + "y": 79, + "width": 180, + "height": 471, + "top": 79, + "right": 838, + "bottom": 550, + "left": 658 + }, + "win": { + "x": 840, + "y": 0, + "width": 240, + "height": 48, + "top": 0, + "right": 1080, + "bottom": 48, + "left": 840 + }, + "sub": { + "x": 726, + "y": 77, + "width": 354, + "height": 752, + "top": 77, + "right": 1080, + "bottom": 829, + "left": 726 + }, + "subFromMore": false + }, + "f": "MORE" + } + }, + { + "name": "keyboard path: no page scroll with the list (and a hovered preview) open", + "ok": true, + "data": 0 + }, + { + "name": "1080: 2-depth preview flips to the left of the list (no room on the right), inside the viewport, no page scroll", + "ok": true, + "data": { + "side": "left", + "left": 415, + "right": 725, + "page": 0 + } + }, + { + "name": "Escape closes the list, menu stays", + "ok": true, + "data": { + "vw": 1080, + "open": true, + "homeOn": true, + "homeHover": "1", + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "row": [ + "작업중인 파일" + ], + "rowTilesOnly": true, + "more": true, + "moreLabel": "4개 그룹", + "moreExpanded": "false", + "moreActive": null, + "hidden": [ + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ], + "hiddenItems": [ + [ + "찾아열기", + "최근파일", + "새파일" + ], + [ + "복구하기", + "임시파일" + ], + [ + "Display...", + "저장하기", + "불러오기" + ], + [ + "설명보기", + "문의하기", + "S/W정보" + ] + ], + "panelTiles": 0, + "dividers": [ + "0px", + "1px", + "1px", + "1px" + ], + "panelOpen": false, + "panelVisibility": "hidden", + "rowScroll": 0, + "rowOverflowX": "hidden", + "pageScroll": 0, + "menu": { + "x": 201, + "y": 0, + "width": 639, + "height": 77, + "top": 0, + "right": 840, + "bottom": 77, + "left": 201 + }, + "moreRect": { + "x": 543, + "y": 0, + "width": 295, + "height": 75, + "top": 0, + "right": 838, + "bottom": 75, + "left": 543 + }, + "moreButton": { + "x": 748, + "y": 23, + "width": 80, + "height": 46, + "top": 23, + "right": 828, + "bottom": 69, + "left": 748 + }, + "panelRect": { + "x": 658, + "y": 79, + "width": 180, + "height": 471, + "top": 79, + "right": 838, + "bottom": 550, + "left": 658 + }, + "win": { + "x": 840, + "y": 0, + "width": 240, + "height": 48, + "top": 0, + "right": 1080, + "bottom": 48, + "left": 840 + }, + "sub": null, + "subFromMore": null + } + }, + { + "name": "최근파일 row (›, aria-expanded) opens the existing list under More, dropdown closes, More = Variant3, no page scroll", + "ok": true, + "data": { + "recentRow": { + "mark": "\"›\"", + "expanded": "false" + }, + "s": { + "vw": 768, + "open": true, + "homeOn": true, + "homeHover": "1", + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "row": [], + "rowTilesOnly": true, + "more": true, + "moreLabel": "5개 그룹", + "moreExpanded": "false", + "moreActive": "true", + "hidden": [ + "작업중인 파일", + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ], + "hiddenItems": [ + [ + "저장", + "복사저장", + "내보내기", + "도면묶기" + ], + [ + "찾아열기", + "최근파일", + "새파일" + ], + [ + "복구하기", + "임시파일" + ], + [ + "Display...", + "저장하기", + "불러오기" + ], + [ + "설명보기", + "문의하기", + "S/W정보" + ] + ], + "panelTiles": 0, + "dividers": [ + "0px", + "1px", + "1px", + "1px", + "1px" + ], + "panelOpen": false, + "panelVisibility": "hidden", + "rowScroll": 0, + "rowOverflowX": "hidden", + "pageScroll": 0, + "menu": { + "x": 304, + "y": 0, + "width": 288, + "height": 77, + "top": 0, + "right": 592, + "bottom": 77, + "left": 304 + }, + "moreRect": { + "x": 306, + "y": 0, + "width": 284, + "height": 75, + "top": 0, + "right": 590, + "bottom": 75, + "left": 306 + }, + "moreButton": { + "x": 500, + "y": 23, + "width": 80, + "height": 46, + "top": 23, + "right": 580, + "bottom": 69, + "left": 500 + }, + "panelRect": { + "x": 410, + "y": 79, + "width": 180, + "height": 624, + "top": 79, + "right": 590, + "bottom": 703, + "left": 410 + }, + "win": { + "x": 592, + "y": 0, + "width": 176, + "height": 48, + "top": 0, + "right": 768, + "bottom": 48, + "left": 592 + }, + "sub": { + "x": 414, + "y": 77, + "width": 354, + "height": 752, + "top": 77, + "right": 768, + "bottom": 829, + "left": 414 + }, + "subFromMore": false + } + } + }, + { + "name": "the 최근파일 list is the existing SWRecentFiles (15 rows)", + "ok": true, + "data": 15 + }, + { + "name": "reopened More: 최근파일 row shows Active while its list is open", + "ok": true, + "data": { + "active": "true", + "expanded": "true", + "bg": "rgb(98, 83, 61)" + } + }, + { + "name": "widen to 1920: all groups back in the Figma row, More removed", + "ok": true, + "data": { + "vw": 1920, + "open": true, + "homeOn": true, + "homeHover": "1", + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "row": [ + "작업중인 파일", + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ], + "rowTilesOnly": true, + "more": false, + "hidden": [], + "hiddenItems": [], + "panelTiles": 0, + "dividers": [], + "panelOpen": false, + "panelVisibility": null, + "rowScroll": 0, + "rowOverflowX": "hidden", + "pageScroll": 0, + "menu": { + "x": 375, + "y": 0, + "width": 1305, + "height": 77, + "top": 0, + "right": 1680, + "bottom": 77, + "left": 375 + }, + "moreRect": null, + "moreButton": null, + "panelRect": null, + "win": { + "x": 1680, + "y": 0, + "width": 240, + "height": 48, + "top": 0, + "right": 1920, + "bottom": 48, + "left": 1680 + }, + "sub": { + "x": 808, + "y": 77, + "width": 354, + "height": 752, + "top": 77, + "right": 1162, + "bottom": 829, + "left": 808 + }, + "subFromMore": false + } + }, + { + "name": "text row click fires the same callbacks as the tile (onActiveChange + onItemSelect with section)", + "ok": true, + "data": "onItemSelect(open / find-open, active=true)\nonActiveChange([find-open])\nonHomeMenuOpenChange(true, home)" + }, + { + "name": "no page errors", + "ok": true, + "data": [] + } + ], + "down": [ + { + "vw": 1920, + "open": true, + "homeOn": true, + "homeHover": "1", + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "row": [ + "작업중인 파일", + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ], + "rowTilesOnly": true, + "more": false, + "hidden": [], + "hiddenItems": [], + "panelTiles": 0, + "dividers": [], + "panelOpen": false, + "panelVisibility": null, + "rowScroll": 0, + "rowOverflowX": "hidden", + "pageScroll": 0, + "menu": { + "x": 375, + "y": 0, + "width": 1305, + "height": 77, + "top": 0, + "right": 1680, + "bottom": 77, + "left": 375 + }, + "moreRect": null, + "moreButton": null, + "panelRect": null, + "win": { + "x": 1680, + "y": 0, + "width": 240, + "height": 48, + "top": 0, + "right": 1920, + "bottom": 48, + "left": 1680 + }, + "sub": null, + "subFromMore": null + }, + { + "vw": 1680, + "open": true, + "homeOn": true, + "homeHover": "1", + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "row": [ + "작업중인 파일", + "다른파일 열기", + "파일 손상시" + ], + "rowTilesOnly": true, + "more": true, + "moreLabel": "2개 그룹", + "moreExpanded": "false", + "moreActive": null, + "hidden": [ + "My Setting", + "궁금하면" + ], + "hiddenItems": [ + [ + "Display...", + "저장하기", + "불러오기" + ], + [ + "설명보기", + "문의하기", + "S/W정보" + ] + ], + "panelTiles": 0, + "dividers": [ + "0px", + "1px" + ], + "panelOpen": false, + "panelVisibility": "hidden", + "rowScroll": 0, + "rowOverflowX": "hidden", + "pageScroll": 0, + "menu": { + "x": 375, + "y": 0, + "width": 1065, + "height": 77, + "top": 0, + "right": 1440, + "bottom": 77, + "left": 375 + }, + "moreRect": { + "x": 1157, + "y": 0, + "width": 281, + "height": 75, + "top": 0, + "right": 1438, + "bottom": 75, + "left": 1157 + }, + "moreButton": { + "x": 1348, + "y": 23, + "width": 80, + "height": 46, + "top": 23, + "right": 1428, + "bottom": 69, + "left": 1348 + }, + "panelRect": { + "x": 1258, + "y": 79, + "width": 180, + "height": 255, + "top": 79, + "right": 1438, + "bottom": 334, + "left": 1258 + }, + "win": { + "x": 1440, + "y": 0, + "width": 240, + "height": 48, + "top": 0, + "right": 1680, + "bottom": 48, + "left": 1440 + }, + "sub": null, + "subFromMore": null + }, + { + "vw": 1440, + "open": true, + "homeOn": true, + "homeHover": "1", + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "row": [ + "작업중인 파일", + "다른파일 열기" + ], + "rowTilesOnly": true, + "more": true, + "moreLabel": "3개 그룹", + "moreExpanded": "false", + "moreActive": null, + "hidden": [ + "파일 손상시", + "My Setting", + "궁금하면" + ], + "hiddenItems": [ + [ + "복구하기", + "임시파일" + ], + [ + "Display...", + "저장하기", + "불러오기" + ], + [ + "설명보기", + "문의하기", + "S/W정보" + ] + ], + "panelTiles": 0, + "dividers": [ + "0px", + "1px", + "1px" + ], + "panelOpen": false, + "panelVisibility": "hidden", + "rowScroll": 0, + "rowOverflowX": "hidden", + "pageScroll": 0, + "menu": { + "x": 375, + "y": 0, + "width": 825, + "height": 77, + "top": 0, + "right": 1200, + "bottom": 77, + "left": 375 + }, + "moreRect": { + "x": 977, + "y": 0, + "width": 221, + "height": 75, + "top": 0, + "right": 1198, + "bottom": 75, + "left": 977 + }, + "moreButton": { + "x": 1108, + "y": 23, + "width": 80, + "height": 46, + "top": 23, + "right": 1188, + "bottom": 69, + "left": 1108 + }, + "panelRect": { + "x": 1018, + "y": 79, + "width": 180, + "height": 348, + "top": 79, + "right": 1198, + "bottom": 427, + "left": 1018 + }, + "win": { + "x": 1200, + "y": 0, + "width": 240, + "height": 48, + "top": 0, + "right": 1440, + "bottom": 48, + "left": 1200 + }, + "sub": null, + "subFromMore": null + }, + { + "vw": 1280, + "open": true, + "homeOn": true, + "homeHover": "1", + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "row": [ + "작업중인 파일", + "다른파일 열기" + ], + "rowTilesOnly": true, + "more": true, + "moreLabel": "3개 그룹", + "moreExpanded": "false", + "moreActive": null, + "hidden": [ + "파일 손상시", + "My Setting", + "궁금하면" + ], + "hiddenItems": [ + [ + "복구하기", + "임시파일" + ], + [ + "Display...", + "저장하기", + "불러오기" + ], + [ + "설명보기", + "문의하기", + "S/W정보" + ] + ], + "panelTiles": 0, + "dividers": [ + "0px", + "1px", + "1px" + ], + "panelOpen": false, + "panelVisibility": "hidden", + "rowScroll": 0, + "rowOverflowX": "hidden", + "pageScroll": 0, + "menu": { + "x": 315, + "y": 0, + "width": 725, + "height": 77, + "top": 0, + "right": 1040, + "bottom": 77, + "left": 315 + }, + "moreRect": { + "x": 917, + "y": 0, + "width": 121, + "height": 75, + "top": 0, + "right": 1038, + "bottom": 75, + "left": 917 + }, + "moreButton": { + "x": 948, + "y": 23, + "width": 80, + "height": 46, + "top": 23, + "right": 1028, + "bottom": 69, + "left": 948 + }, + "panelRect": { + "x": 858, + "y": 79, + "width": 180, + "height": 348, + "top": 79, + "right": 1038, + "bottom": 427, + "left": 858 + }, + "win": { + "x": 1040, + "y": 0, + "width": 240, + "height": 48, + "top": 0, + "right": 1280, + "bottom": 48, + "left": 1040 + }, + "sub": null, + "subFromMore": null + }, + { + "vw": 1180, + "open": true, + "homeOn": true, + "homeHover": "1", + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "row": [ + "작업중인 파일", + "다른파일 열기" + ], + "rowTilesOnly": true, + "more": true, + "moreLabel": "3개 그룹", + "moreExpanded": "false", + "moreActive": null, + "hidden": [ + "파일 손상시", + "My Setting", + "궁금하면" + ], + "hiddenItems": [ + [ + "복구하기", + "임시파일" + ], + [ + "Display...", + "저장하기", + "불러오기" + ], + [ + "설명보기", + "문의하기", + "S/W정보" + ] + ], + "panelTiles": 0, + "dividers": [ + "0px", + "1px", + "1px" + ], + "panelOpen": false, + "panelVisibility": "hidden", + "rowScroll": 0, + "rowOverflowX": "hidden", + "pageScroll": 0, + "menu": { + "x": 215, + "y": 0, + "width": 725, + "height": 77, + "top": 0, + "right": 940, + "bottom": 77, + "left": 215 + }, + "moreRect": { + "x": 817, + "y": 0, + "width": 121, + "height": 75, + "top": 0, + "right": 938, + "bottom": 75, + "left": 817 + }, + "moreButton": { + "x": 848, + "y": 23, + "width": 80, + "height": 46, + "top": 23, + "right": 928, + "bottom": 69, + "left": 848 + }, + "panelRect": { + "x": 758, + "y": 79, + "width": 180, + "height": 348, + "top": 79, + "right": 938, + "bottom": 427, + "left": 758 + }, + "win": { + "x": 940, + "y": 0, + "width": 240, + "height": 48, + "top": 0, + "right": 1180, + "bottom": 48, + "left": 940 + }, + "sub": null, + "subFromMore": null + }, + { + "vw": 1080, + "open": true, + "homeOn": true, + "homeHover": "1", + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "row": [ + "작업중인 파일" + ], + "rowTilesOnly": true, + "more": true, + "moreLabel": "4개 그룹", + "moreExpanded": "false", + "moreActive": null, + "hidden": [ + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ], + "hiddenItems": [ + [ + "찾아열기", + "최근파일", + "새파일" + ], + [ + "복구하기", + "임시파일" + ], + [ + "Display...", + "저장하기", + "불러오기" + ], + [ + "설명보기", + "문의하기", + "S/W정보" + ] + ], + "panelTiles": 0, + "dividers": [ + "0px", + "1px", + "1px", + "1px" + ], + "panelOpen": false, + "panelVisibility": "hidden", + "rowScroll": 0, + "rowOverflowX": "hidden", + "pageScroll": 0, + "menu": { + "x": 201, + "y": 0, + "width": 639, + "height": 77, + "top": 0, + "right": 840, + "bottom": 77, + "left": 201 + }, + "moreRect": { + "x": 543, + "y": 0, + "width": 295, + "height": 75, + "top": 0, + "right": 838, + "bottom": 75, + "left": 543 + }, + "moreButton": { + "x": 748, + "y": 23, + "width": 80, + "height": 46, + "top": 23, + "right": 828, + "bottom": 69, + "left": 748 + }, + "panelRect": { + "x": 658, + "y": 79, + "width": 180, + "height": 471, + "top": 79, + "right": 838, + "bottom": 550, + "left": 658 + }, + "win": { + "x": 840, + "y": 0, + "width": 240, + "height": 48, + "top": 0, + "right": 1080, + "bottom": 48, + "left": 840 + }, + "sub": null, + "subFromMore": null + }, + { + "vw": 960, + "open": true, + "homeOn": true, + "homeHover": "1", + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "row": [ + "작업중인 파일" + ], + "rowTilesOnly": true, + "more": true, + "moreLabel": "4개 그룹", + "moreExpanded": "false", + "moreActive": null, + "hidden": [ + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ], + "hiddenItems": [ + [ + "찾아열기", + "최근파일", + "새파일" + ], + [ + "복구하기", + "임시파일" + ], + [ + "Display...", + "저장하기", + "불러오기" + ], + [ + "설명보기", + "문의하기", + "S/W정보" + ] + ], + "panelTiles": 0, + "dividers": [ + "0px", + "1px", + "1px", + "1px" + ], + "panelOpen": false, + "panelVisibility": "hidden", + "rowScroll": 0, + "rowOverflowX": "hidden", + "pageScroll": 0, + "menu": { + "x": 300, + "y": 0, + "width": 484, + "height": 77, + "top": 0, + "right": 784, + "bottom": 77, + "left": 300 + }, + "moreRect": { + "x": 642, + "y": 0, + "width": 140, + "height": 75, + "top": 0, + "right": 782, + "bottom": 75, + "left": 642 + }, + "moreButton": { + "x": 692, + "y": 23, + "width": 80, + "height": 46, + "top": 23, + "right": 772, + "bottom": 69, + "left": 692 + }, + "panelRect": { + "x": 602, + "y": 79, + "width": 180, + "height": 471, + "top": 79, + "right": 782, + "bottom": 550, + "left": 602 + }, + "win": { + "x": 784, + "y": 0, + "width": 176, + "height": 48, + "top": 0, + "right": 960, + "bottom": 48, + "left": 784 + }, + "sub": null, + "subFromMore": null + }, + { + "vw": 768, + "open": true, + "homeOn": true, + "homeHover": "1", + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "row": [], + "rowTilesOnly": true, + "more": true, + "moreLabel": "5개 그룹", + "moreExpanded": "false", + "moreActive": null, + "hidden": [ + "작업중인 파일", + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ], + "hiddenItems": [ + [ + "저장", + "복사저장", + "내보내기", + "도면묶기" + ], + [ + "찾아열기", + "최근파일", + "새파일" + ], + [ + "복구하기", + "임시파일" + ], + [ + "Display...", + "저장하기", + "불러오기" + ], + [ + "설명보기", + "문의하기", + "S/W정보" + ] + ], + "panelTiles": 0, + "dividers": [ + "0px", + "1px", + "1px", + "1px", + "1px" + ], + "panelOpen": false, + "panelVisibility": "hidden", + "rowScroll": 0, + "rowOverflowX": "hidden", + "pageScroll": 0, + "menu": { + "x": 304, + "y": 0, + "width": 288, + "height": 77, + "top": 0, + "right": 592, + "bottom": 77, + "left": 304 + }, + "moreRect": { + "x": 306, + "y": 0, + "width": 284, + "height": 75, + "top": 0, + "right": 590, + "bottom": 75, + "left": 306 + }, + "moreButton": { + "x": 500, + "y": 23, + "width": 80, + "height": 46, + "top": 23, + "right": 580, + "bottom": 69, + "left": 500 + }, + "panelRect": { + "x": 410, + "y": 79, + "width": 180, + "height": 624, + "top": 79, + "right": 590, + "bottom": 703, + "left": 410 + }, + "win": { + "x": 592, + "y": 0, + "width": 176, + "height": 48, + "top": 0, + "right": 768, + "bottom": 48, + "left": 592 + }, + "sub": null, + "subFromMore": null + }, + { + "vw": 640, + "open": true, + "homeOn": true, + "homeHover": "1", + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "row": [], + "rowTilesOnly": true, + "more": true, + "moreLabel": "5개 그룹", + "moreExpanded": "false", + "moreActive": null, + "hidden": [ + "작업중인 파일", + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ], + "hiddenItems": [ + [ + "저장", + "복사저장", + "내보내기", + "도면묶기" + ], + [ + "찾아열기", + "최근파일", + "새파일" + ], + [ + "복구하기", + "임시파일" + ], + [ + "Display...", + "저장하기", + "불러오기" + ], + [ + "설명보기", + "문의하기", + "S/W정보" + ] + ], + "panelTiles": 0, + "dividers": [ + "0px", + "1px", + "1px", + "1px", + "1px" + ], + "panelOpen": false, + "panelVisibility": "hidden", + "rowScroll": 0, + "rowOverflowX": "hidden", + "pageScroll": 0, + "menu": { + "x": 176, + "y": 0, + "width": 288, + "height": 77, + "top": 0, + "right": 464, + "bottom": 77, + "left": 176 + }, + "moreRect": { + "x": 178, + "y": 0, + "width": 284, + "height": 75, + "top": 0, + "right": 462, + "bottom": 75, + "left": 178 + }, + "moreButton": { + "x": 372, + "y": 23, + "width": 80, + "height": 46, + "top": 23, + "right": 452, + "bottom": 69, + "left": 372 + }, + "panelRect": { + "x": 282, + "y": 79, + "width": 180, + "height": 624, + "top": 79, + "right": 462, + "bottom": 703, + "left": 282 + }, + "win": { + "x": 464, + "y": 0, + "width": 176, + "height": 48, + "top": 0, + "right": 640, + "bottom": 48, + "left": 464 + }, + "sub": null, + "subFromMore": null + }, + { + "vw": 520, + "open": true, + "homeOn": true, + "homeHover": "1", + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "row": [], + "rowTilesOnly": true, + "more": true, + "moreLabel": "5개 그룹", + "moreExpanded": "false", + "moreActive": null, + "hidden": [ + "작업중인 파일", + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ], + "hiddenItems": [ + [ + "저장", + "복사저장", + "내보내기", + "도면묶기" + ], + [ + "찾아열기", + "최근파일", + "새파일" + ], + [ + "복구하기", + "임시파일" + ], + [ + "Display...", + "저장하기", + "불러오기" + ], + [ + "설명보기", + "문의하기", + "S/W정보" + ] + ], + "panelTiles": 0, + "dividers": [ + "0px", + "1px", + "1px", + "1px", + "1px" + ], + "panelOpen": false, + "panelVisibility": "hidden", + "rowScroll": 0, + "rowOverflowX": "hidden", + "pageScroll": 0, + "menu": { + "x": 168, + "y": 0, + "width": 288, + "height": 77, + "top": 0, + "right": 456, + "bottom": 77, + "left": 168 + }, + "moreRect": { + "x": 170, + "y": 0, + "width": 284, + "height": 75, + "top": 0, + "right": 454, + "bottom": 75, + "left": 170 + }, + "moreButton": { + "x": 364, + "y": 23, + "width": 80, + "height": 46, + "top": 23, + "right": 444, + "bottom": 69, + "left": 364 + }, + "panelRect": { + "x": 274, + "y": 79, + "width": 180, + "height": 624, + "top": 79, + "right": 454, + "bottom": 703, + "left": 274 + }, + "win": { + "x": 456, + "y": 0, + "width": 64, + "height": 48, + "top": 0, + "right": 520, + "bottom": 48, + "left": 456 + }, + "sub": null, + "subFromMore": null + }, + { + "vw": 390, + "open": true, + "homeOn": true, + "homeHover": "1", + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "row": [], + "rowTilesOnly": true, + "more": true, + "moreLabel": "5개 그룹", + "moreExpanded": "false", + "moreActive": null, + "hidden": [ + "작업중인 파일", + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ], + "hiddenItems": [ + [ + "저장", + "복사저장", + "내보내기", + "도면묶기" + ], + [ + "찾아열기", + "최근파일", + "새파일" + ], + [ + "복구하기", + "임시파일" + ], + [ + "Display...", + "저장하기", + "불러오기" + ], + [ + "설명보기", + "문의하기", + "S/W정보" + ] + ], + "panelTiles": 0, + "dividers": [ + "0px", + "1px", + "1px", + "1px", + "1px" + ], + "panelOpen": false, + "panelVisibility": "hidden", + "rowScroll": 0, + "rowOverflowX": "hidden", + "pageScroll": 0, + "menu": { + "x": 161, + "y": 0, + "width": 165, + "height": 77, + "top": 0, + "right": 326, + "bottom": 77, + "left": 161 + }, + "moreRect": { + "x": 163, + "y": 0, + "width": 161, + "height": 75, + "top": 0, + "right": 324, + "bottom": 75, + "left": 163 + }, + "moreButton": { + "x": 234, + "y": 23, + "width": 80, + "height": 46, + "top": 23, + "right": 314, + "bottom": 69, + "left": 234 + }, + "panelRect": { + "x": 144, + "y": 79, + "width": 180, + "height": 624, + "top": 79, + "right": 324, + "bottom": 703, + "left": 144 + }, + "win": { + "x": 326, + "y": 0, + "width": 64, + "height": 48, + "top": 0, + "right": 390, + "bottom": 48, + "left": 326 + }, + "sub": null, + "subFromMore": null + } + ], + "up": [ + { + "vw": 390, + "open": true, + "homeOn": true, + "homeHover": "1", + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "row": [], + "rowTilesOnly": true, + "more": true, + "moreLabel": "5개 그룹", + "moreExpanded": "false", + "moreActive": null, + "hidden": [ + "작업중인 파일", + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ], + "hiddenItems": [ + [ + "저장", + "복사저장", + "내보내기", + "도면묶기" + ], + [ + "찾아열기", + "최근파일", + "새파일" + ], + [ + "복구하기", + "임시파일" + ], + [ + "Display...", + "저장하기", + "불러오기" + ], + [ + "설명보기", + "문의하기", + "S/W정보" + ] + ], + "panelTiles": 0, + "dividers": [ + "0px", + "1px", + "1px", + "1px", + "1px" + ], + "panelOpen": false, + "panelVisibility": "hidden", + "rowScroll": 0, + "rowOverflowX": "hidden", + "pageScroll": 0, + "menu": { + "x": 161, + "y": 0, + "width": 165, + "height": 77, + "top": 0, + "right": 326, + "bottom": 77, + "left": 161 + }, + "moreRect": { + "x": 163, + "y": 0, + "width": 161, + "height": 75, + "top": 0, + "right": 324, + "bottom": 75, + "left": 163 + }, + "moreButton": { + "x": 234, + "y": 23, + "width": 80, + "height": 46, + "top": 23, + "right": 314, + "bottom": 69, + "left": 234 + }, + "panelRect": { + "x": 144, + "y": 79, + "width": 180, + "height": 624, + "top": 79, + "right": 324, + "bottom": 703, + "left": 144 + }, + "win": { + "x": 326, + "y": 0, + "width": 64, + "height": 48, + "top": 0, + "right": 390, + "bottom": 48, + "left": 326 + }, + "sub": null, + "subFromMore": null + }, + { + "vw": 520, + "open": true, + "homeOn": true, + "homeHover": "1", + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "row": [], + "rowTilesOnly": true, + "more": true, + "moreLabel": "5개 그룹", + "moreExpanded": "false", + "moreActive": null, + "hidden": [ + "작업중인 파일", + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ], + "hiddenItems": [ + [ + "저장", + "복사저장", + "내보내기", + "도면묶기" + ], + [ + "찾아열기", + "최근파일", + "새파일" + ], + [ + "복구하기", + "임시파일" + ], + [ + "Display...", + "저장하기", + "불러오기" + ], + [ + "설명보기", + "문의하기", + "S/W정보" + ] + ], + "panelTiles": 0, + "dividers": [ + "0px", + "1px", + "1px", + "1px", + "1px" + ], + "panelOpen": false, + "panelVisibility": "hidden", + "rowScroll": 0, + "rowOverflowX": "hidden", + "pageScroll": 0, + "menu": { + "x": 168, + "y": 0, + "width": 288, + "height": 77, + "top": 0, + "right": 456, + "bottom": 77, + "left": 168 + }, + "moreRect": { + "x": 170, + "y": 0, + "width": 284, + "height": 75, + "top": 0, + "right": 454, + "bottom": 75, + "left": 170 + }, + "moreButton": { + "x": 364, + "y": 23, + "width": 80, + "height": 46, + "top": 23, + "right": 444, + "bottom": 69, + "left": 364 + }, + "panelRect": { + "x": 274, + "y": 79, + "width": 180, + "height": 624, + "top": 79, + "right": 454, + "bottom": 703, + "left": 274 + }, + "win": { + "x": 456, + "y": 0, + "width": 64, + "height": 48, + "top": 0, + "right": 520, + "bottom": 48, + "left": 456 + }, + "sub": null, + "subFromMore": null + }, + { + "vw": 640, + "open": true, + "homeOn": true, + "homeHover": "1", + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "row": [], + "rowTilesOnly": true, + "more": true, + "moreLabel": "5개 그룹", + "moreExpanded": "false", + "moreActive": null, + "hidden": [ + "작업중인 파일", + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ], + "hiddenItems": [ + [ + "저장", + "복사저장", + "내보내기", + "도면묶기" + ], + [ + "찾아열기", + "최근파일", + "새파일" + ], + [ + "복구하기", + "임시파일" + ], + [ + "Display...", + "저장하기", + "불러오기" + ], + [ + "설명보기", + "문의하기", + "S/W정보" + ] + ], + "panelTiles": 0, + "dividers": [ + "0px", + "1px", + "1px", + "1px", + "1px" + ], + "panelOpen": false, + "panelVisibility": "hidden", + "rowScroll": 0, + "rowOverflowX": "hidden", + "pageScroll": 0, + "menu": { + "x": 176, + "y": 0, + "width": 288, + "height": 77, + "top": 0, + "right": 464, + "bottom": 77, + "left": 176 + }, + "moreRect": { + "x": 178, + "y": 0, + "width": 284, + "height": 75, + "top": 0, + "right": 462, + "bottom": 75, + "left": 178 + }, + "moreButton": { + "x": 372, + "y": 23, + "width": 80, + "height": 46, + "top": 23, + "right": 452, + "bottom": 69, + "left": 372 + }, + "panelRect": { + "x": 282, + "y": 79, + "width": 180, + "height": 624, + "top": 79, + "right": 462, + "bottom": 703, + "left": 282 + }, + "win": { + "x": 464, + "y": 0, + "width": 176, + "height": 48, + "top": 0, + "right": 640, + "bottom": 48, + "left": 464 + }, + "sub": null, + "subFromMore": null + }, + { + "vw": 768, + "open": true, + "homeOn": true, + "homeHover": "1", + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "row": [], + "rowTilesOnly": true, + "more": true, + "moreLabel": "5개 그룹", + "moreExpanded": "false", + "moreActive": null, + "hidden": [ + "작업중인 파일", + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ], + "hiddenItems": [ + [ + "저장", + "복사저장", + "내보내기", + "도면묶기" + ], + [ + "찾아열기", + "최근파일", + "새파일" + ], + [ + "복구하기", + "임시파일" + ], + [ + "Display...", + "저장하기", + "불러오기" + ], + [ + "설명보기", + "문의하기", + "S/W정보" + ] + ], + "panelTiles": 0, + "dividers": [ + "0px", + "1px", + "1px", + "1px", + "1px" + ], + "panelOpen": false, + "panelVisibility": "hidden", + "rowScroll": 0, + "rowOverflowX": "hidden", + "pageScroll": 0, + "menu": { + "x": 304, + "y": 0, + "width": 288, + "height": 77, + "top": 0, + "right": 592, + "bottom": 77, + "left": 304 + }, + "moreRect": { + "x": 306, + "y": 0, + "width": 284, + "height": 75, + "top": 0, + "right": 590, + "bottom": 75, + "left": 306 + }, + "moreButton": { + "x": 500, + "y": 23, + "width": 80, + "height": 46, + "top": 23, + "right": 580, + "bottom": 69, + "left": 500 + }, + "panelRect": { + "x": 410, + "y": 79, + "width": 180, + "height": 624, + "top": 79, + "right": 590, + "bottom": 703, + "left": 410 + }, + "win": { + "x": 592, + "y": 0, + "width": 176, + "height": 48, + "top": 0, + "right": 768, + "bottom": 48, + "left": 592 + }, + "sub": null, + "subFromMore": null + }, + { + "vw": 960, + "open": true, + "homeOn": true, + "homeHover": "1", + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "row": [ + "작업중인 파일" + ], + "rowTilesOnly": true, + "more": true, + "moreLabel": "4개 그룹", + "moreExpanded": "false", + "moreActive": null, + "hidden": [ + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ], + "hiddenItems": [ + [ + "찾아열기", + "최근파일", + "새파일" + ], + [ + "복구하기", + "임시파일" + ], + [ + "Display...", + "저장하기", + "불러오기" + ], + [ + "설명보기", + "문의하기", + "S/W정보" + ] + ], + "panelTiles": 0, + "dividers": [ + "0px", + "1px", + "1px", + "1px" + ], + "panelOpen": false, + "panelVisibility": "hidden", + "rowScroll": 0, + "rowOverflowX": "hidden", + "pageScroll": 0, + "menu": { + "x": 300, + "y": 0, + "width": 484, + "height": 77, + "top": 0, + "right": 784, + "bottom": 77, + "left": 300 + }, + "moreRect": { + "x": 642, + "y": 0, + "width": 140, + "height": 75, + "top": 0, + "right": 782, + "bottom": 75, + "left": 642 + }, + "moreButton": { + "x": 692, + "y": 23, + "width": 80, + "height": 46, + "top": 23, + "right": 772, + "bottom": 69, + "left": 692 + }, + "panelRect": { + "x": 602, + "y": 79, + "width": 180, + "height": 471, + "top": 79, + "right": 782, + "bottom": 550, + "left": 602 + }, + "win": { + "x": 784, + "y": 0, + "width": 176, + "height": 48, + "top": 0, + "right": 960, + "bottom": 48, + "left": 784 + }, + "sub": null, + "subFromMore": null + }, + { + "vw": 1080, + "open": true, + "homeOn": true, + "homeHover": "1", + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "row": [ + "작업중인 파일" + ], + "rowTilesOnly": true, + "more": true, + "moreLabel": "4개 그룹", + "moreExpanded": "false", + "moreActive": null, + "hidden": [ + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ], + "hiddenItems": [ + [ + "찾아열기", + "최근파일", + "새파일" + ], + [ + "복구하기", + "임시파일" + ], + [ + "Display...", + "저장하기", + "불러오기" + ], + [ + "설명보기", + "문의하기", + "S/W정보" + ] + ], + "panelTiles": 0, + "dividers": [ + "0px", + "1px", + "1px", + "1px" + ], + "panelOpen": false, + "panelVisibility": "hidden", + "rowScroll": 0, + "rowOverflowX": "hidden", + "pageScroll": 0, + "menu": { + "x": 201, + "y": 0, + "width": 639, + "height": 77, + "top": 0, + "right": 840, + "bottom": 77, + "left": 201 + }, + "moreRect": { + "x": 543, + "y": 0, + "width": 295, + "height": 75, + "top": 0, + "right": 838, + "bottom": 75, + "left": 543 + }, + "moreButton": { + "x": 748, + "y": 23, + "width": 80, + "height": 46, + "top": 23, + "right": 828, + "bottom": 69, + "left": 748 + }, + "panelRect": { + "x": 658, + "y": 79, + "width": 180, + "height": 471, + "top": 79, + "right": 838, + "bottom": 550, + "left": 658 + }, + "win": { + "x": 840, + "y": 0, + "width": 240, + "height": 48, + "top": 0, + "right": 1080, + "bottom": 48, + "left": 840 + }, + "sub": null, + "subFromMore": null + }, + { + "vw": 1180, + "open": true, + "homeOn": true, + "homeHover": "1", + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "row": [ + "작업중인 파일", + "다른파일 열기" + ], + "rowTilesOnly": true, + "more": true, + "moreLabel": "3개 그룹", + "moreExpanded": "false", + "moreActive": null, + "hidden": [ + "파일 손상시", + "My Setting", + "궁금하면" + ], + "hiddenItems": [ + [ + "복구하기", + "임시파일" + ], + [ + "Display...", + "저장하기", + "불러오기" + ], + [ + "설명보기", + "문의하기", + "S/W정보" + ] + ], + "panelTiles": 0, + "dividers": [ + "0px", + "1px", + "1px" + ], + "panelOpen": false, + "panelVisibility": "hidden", + "rowScroll": 0, + "rowOverflowX": "hidden", + "pageScroll": 0, + "menu": { + "x": 215, + "y": 0, + "width": 725, + "height": 77, + "top": 0, + "right": 940, + "bottom": 77, + "left": 215 + }, + "moreRect": { + "x": 817, + "y": 0, + "width": 121, + "height": 75, + "top": 0, + "right": 938, + "bottom": 75, + "left": 817 + }, + "moreButton": { + "x": 848, + "y": 23, + "width": 80, + "height": 46, + "top": 23, + "right": 928, + "bottom": 69, + "left": 848 + }, + "panelRect": { + "x": 758, + "y": 79, + "width": 180, + "height": 348, + "top": 79, + "right": 938, + "bottom": 427, + "left": 758 + }, + "win": { + "x": 940, + "y": 0, + "width": 240, + "height": 48, + "top": 0, + "right": 1180, + "bottom": 48, + "left": 940 + }, + "sub": null, + "subFromMore": null + }, + { + "vw": 1280, + "open": true, + "homeOn": true, + "homeHover": "1", + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "row": [ + "작업중인 파일", + "다른파일 열기" + ], + "rowTilesOnly": true, + "more": true, + "moreLabel": "3개 그룹", + "moreExpanded": "false", + "moreActive": null, + "hidden": [ + "파일 손상시", + "My Setting", + "궁금하면" + ], + "hiddenItems": [ + [ + "복구하기", + "임시파일" + ], + [ + "Display...", + "저장하기", + "불러오기" + ], + [ + "설명보기", + "문의하기", + "S/W정보" + ] + ], + "panelTiles": 0, + "dividers": [ + "0px", + "1px", + "1px" + ], + "panelOpen": false, + "panelVisibility": "hidden", + "rowScroll": 0, + "rowOverflowX": "hidden", + "pageScroll": 0, + "menu": { + "x": 315, + "y": 0, + "width": 725, + "height": 77, + "top": 0, + "right": 1040, + "bottom": 77, + "left": 315 + }, + "moreRect": { + "x": 917, + "y": 0, + "width": 121, + "height": 75, + "top": 0, + "right": 1038, + "bottom": 75, + "left": 917 + }, + "moreButton": { + "x": 948, + "y": 23, + "width": 80, + "height": 46, + "top": 23, + "right": 1028, + "bottom": 69, + "left": 948 + }, + "panelRect": { + "x": 858, + "y": 79, + "width": 180, + "height": 348, + "top": 79, + "right": 1038, + "bottom": 427, + "left": 858 + }, + "win": { + "x": 1040, + "y": 0, + "width": 240, + "height": 48, + "top": 0, + "right": 1280, + "bottom": 48, + "left": 1040 + }, + "sub": null, + "subFromMore": null + }, + { + "vw": 1440, + "open": true, + "homeOn": true, + "homeHover": "1", + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "row": [ + "작업중인 파일", + "다른파일 열기" + ], + "rowTilesOnly": true, + "more": true, + "moreLabel": "3개 그룹", + "moreExpanded": "false", + "moreActive": null, + "hidden": [ + "파일 손상시", + "My Setting", + "궁금하면" + ], + "hiddenItems": [ + [ + "복구하기", + "임시파일" + ], + [ + "Display...", + "저장하기", + "불러오기" + ], + [ + "설명보기", + "문의하기", + "S/W정보" + ] + ], + "panelTiles": 0, + "dividers": [ + "0px", + "1px", + "1px" + ], + "panelOpen": false, + "panelVisibility": "hidden", + "rowScroll": 0, + "rowOverflowX": "hidden", + "pageScroll": 0, + "menu": { + "x": 375, + "y": 0, + "width": 825, + "height": 77, + "top": 0, + "right": 1200, + "bottom": 77, + "left": 375 + }, + "moreRect": { + "x": 977, + "y": 0, + "width": 221, + "height": 75, + "top": 0, + "right": 1198, + "bottom": 75, + "left": 977 + }, + "moreButton": { + "x": 1108, + "y": 23, + "width": 80, + "height": 46, + "top": 23, + "right": 1188, + "bottom": 69, + "left": 1108 + }, + "panelRect": { + "x": 1018, + "y": 79, + "width": 180, + "height": 348, + "top": 79, + "right": 1198, + "bottom": 427, + "left": 1018 + }, + "win": { + "x": 1200, + "y": 0, + "width": 240, + "height": 48, + "top": 0, + "right": 1440, + "bottom": 48, + "left": 1200 + }, + "sub": null, + "subFromMore": null + }, + { + "vw": 1680, + "open": true, + "homeOn": true, + "homeHover": "1", + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "row": [ + "작업중인 파일", + "다른파일 열기", + "파일 손상시" + ], + "rowTilesOnly": true, + "more": true, + "moreLabel": "2개 그룹", + "moreExpanded": "false", + "moreActive": null, + "hidden": [ + "My Setting", + "궁금하면" + ], + "hiddenItems": [ + [ + "Display...", + "저장하기", + "불러오기" + ], + [ + "설명보기", + "문의하기", + "S/W정보" + ] + ], + "panelTiles": 0, + "dividers": [ + "0px", + "1px" + ], + "panelOpen": false, + "panelVisibility": "hidden", + "rowScroll": 0, + "rowOverflowX": "hidden", + "pageScroll": 0, + "menu": { + "x": 375, + "y": 0, + "width": 1065, + "height": 77, + "top": 0, + "right": 1440, + "bottom": 77, + "left": 375 + }, + "moreRect": { + "x": 1157, + "y": 0, + "width": 281, + "height": 75, + "top": 0, + "right": 1438, + "bottom": 75, + "left": 1157 + }, + "moreButton": { + "x": 1348, + "y": 23, + "width": 80, + "height": 46, + "top": 23, + "right": 1428, + "bottom": 69, + "left": 1348 + }, + "panelRect": { + "x": 1258, + "y": 79, + "width": 180, + "height": 255, + "top": 79, + "right": 1438, + "bottom": 334, + "left": 1258 + }, + "win": { + "x": 1440, + "y": 0, + "width": 240, + "height": 48, + "top": 0, + "right": 1680, + "bottom": 48, + "left": 1440 + }, + "sub": null, + "subFromMore": null + }, + { + "vw": 1920, + "open": true, + "homeOn": true, + "homeHover": "1", + "lineTop": "rgb(95, 75, 15)", + "lineBottom": "rgb(95, 75, 15)", + "row": [ + "작업중인 파일", + "다른파일 열기", + "파일 손상시", + "My Setting", + "궁금하면" + ], + "rowTilesOnly": true, + "more": false, + "hidden": [], + "hiddenItems": [], + "panelTiles": 0, + "dividers": [], + "panelOpen": false, + "panelVisibility": null, + "rowScroll": 0, + "rowOverflowX": "hidden", + "pageScroll": 0, + "menu": { + "x": 375, + "y": 0, + "width": 1305, + "height": 77, + "top": 0, + "right": 1680, + "bottom": 77, + "left": 375 + }, + "moreRect": null, + "moreButton": null, + "panelRect": null, + "win": { + "x": 1680, + "y": 0, + "width": 240, + "height": 48, + "top": 0, + "right": 1920, + "bottom": 48, + "left": 1680 + }, + "sub": null, + "subFromMore": null + } + ], + "errors": [] +} \ No newline at end of file diff --git a/docs/sw/home-menu-more-text-qa-2026-10-19/wide-1920.png b/docs/sw/home-menu-more-text-qa-2026-10-19/wide-1920.png new file mode 100644 index 0000000..439e0e1 Binary files /dev/null and b/docs/sw/home-menu-more-text-qa-2026-10-19/wide-1920.png differ diff --git a/docs/sw/home-on-qa-2026-10-19/compare-full.png b/docs/sw/home-on-qa-2026-10-19/compare-full.png new file mode 100644 index 0000000..b0a8a00 Binary files /dev/null and b/docs/sw/home-on-qa-2026-10-19/compare-full.png differ diff --git a/docs/sw/home-on-qa-2026-10-19/compare-left.png b/docs/sw/home-on-qa-2026-10-19/compare-left.png new file mode 100644 index 0000000..5cff03b Binary files /dev/null and b/docs/sw/home-on-qa-2026-10-19/compare-left.png differ diff --git a/docs/sw/home-on-qa-2026-10-19/compare-right.png b/docs/sw/home-on-qa-2026-10-19/compare-right.png new file mode 100644 index 0000000..57c9837 Binary files /dev/null and b/docs/sw/home-on-qa-2026-10-19/compare-right.png differ diff --git a/docs/sw/sw-header-design-spec.md b/docs/sw/sw-header-design-spec.md index 6e72f2a..3970b6e 100644 --- a/docs/sw/sw-header-design-spec.md +++ b/docs/sw/sw-header-design-spec.md @@ -517,6 +517,18 @@ Composed Controls의 기존 레이어·색상·상세보기 예제는 보존하 검증(2026-10-16, Storybook `SW / Header / Responsive`, 18개 폭): 1920 / 1800 / 1799 / 1770 / 1600 / 1440 / 1280 / 1180 / 1179 / 1080 / 1079 / 900 / 899 / 768 / 640 / 639 / 560 / 390에서 헤더 가로 스크롤 0, 요소 겹침 0, 객체 수정 면 밖으로 넘침 0. 필드 값·라벨 잘림은 390px의 레이어명 1건뿐입니다. 각 폭에서 더보기 항목 선택 시 Callback이 호출되고, 선택 상태가 반영되며, 메뉴가 닫히는 것을 확인했습니다(속성Bar·속성창 체크 전환, 인쇄·팝업 가이드 Callback 포함). 실제 Viewport 1799 / 1079 / 390에서도 같은 결과입니다. +### 12.1 실측 More — 실제 사용 가능한 공간 기준 (2026-10-19) + +2026-10-19 사용자 요청("고정된 화면 너비만 기준으로 처리하지 말고 실제 사용 가능한 공간을 기준으로")에 따라 위 Breakpoint 위에 실측 단계를 더했습니다. Breakpoint 표는 그대로이며, 기본 구성(추가 요소 없음)의 배치는 바뀌지 않습니다. + +- 측정 대상: 객체 수정 영역의 in-flow 내용. 측정하는 동안(`data-measuring`, 같은 Layout Effect 안에서 설정·해제, 그려지지 않음) 영역 안 요소는 줄거나 늘지 않고 auto margin도 0이므로 실제로 필요한 폭이 드러납니다. 구성형(`controls`) 파일명은 기본 디자인의 최소 파일명 폭(96px)으로 계산합니다. +- 이동 순서: Breakpoint 단계 순서 그대로 선·문자·치수스타일 → 그리기모드(라벨만 숨김) → 속성 블록(상세보기·속성Bar·속성창, 기본 구성에서는 한 덩어리) → 색상 → 인쇄·K(구성형만, 기본 구성에서는 창 영역이라 Breakpoint 유지). 같은 단계는 오른쪽부터. 대표 칸(레이어 또는 More에서 고른 필드)은 이동하지 않습니다. 로고 오른쪽 Open(`documentOpenPlacement="header"`)은 가장 먼저 옮겨지고 가장 늦게 돌아옵니다. +- 복귀: 옮긴 직후 그 이동으로 생긴 공간(More 버튼 등장·여백 변화 포함)을 한 번 측정해 두고, 남은 공간이 그만큼 생기면 역순으로 원래 자리에 돌아옵니다(경계에서 깜박임 없음). +- 메뉴를 열고 닫아도 위치·폭은 바뀌지 않습니다. Dropdown·로고 메뉴·More 목록·Tooltip은 positioned 층이라 측정에서 제외됩니다. +- 한계: `leading`·`tools`처럼 호스트가 넣은 요소는 More로 옮기지 않습니다(More 항목이 없음). 그 요소만으로도 공간이 부족하면 기존처럼 대표 필드가 줄어듭니다. + +상세 검증: [홈 메뉴 통합·실측 More 보고](./sw-header-home-menu-responsive-2026-10-19.md). + ## 13. 컴포넌트 분리 기준 - 공개: `SWHeader`(전체), `SWHeaderHome`, `SWHeaderDocumentTitle`, `SWHeaderLayerControl`, `SWHeaderLayerMenu`(레이어 필드 + Dropdown, §5.2), `SWHeaderColorMenu` · `SWHeaderLineStyleMenu` · `SWHeaderTextStyleMenu` · `SWHeaderDimensionStyleMenu`(§5.3), `SWHeaderLinePreview` · `swHeaderLinePatterns`, `SWHeaderInput` · `parseSWHeaderColor` · `parseSWHeaderNumber`(§5.5), `SWHeaderColorControl`, `SWHeaderLineStyle`, `SWHeaderTextStyle`, `SWHeaderDimensionStyle`, `SWHeaderProperties`, `SWHeaderActions`, `SWHeaderWindowControls`, `SWTheme`(단독 사용 시 토큰 범위). @@ -540,6 +552,7 @@ Composed Controls의 기존 레이어·색상·상세보기 예제는 보존하 | `--hm-sw-header-arrow-color` | `#47AF91` | 파일명 화살표 | | `--hm-sw-header-hover` | `rgba(255,255,255,.08)` | 더보기 메뉴 항목 Hover 배경 | | `--hm-sw-header-hover-border-gradient` / `-hover-border-width` | Figma 홈 hover gradient / 1px | Hover 테두리(§11.1) | +| `--hm-sw-header-home-on-line-color` / `-home-on-line-width` | `#5F4B0F` / 2px | Home On(로고 메뉴 열림, Figma 662:67267): Header 전폭 상·하단 선. 로고는 Hover 테두리 유지 | | `--hm-sw-header-document-menu-width` / `-document-menu-background` / `-document-menu-border-color` / `-document-menu-border-width` | 310px / `#103127` / `#041611` / 1px | 문서 Dropdown(§5.1) | | `--hm-sw-header-document-menu-shadow` / `-document-menu-inset-shadow` / `-document-menu-divider-color` | `0 2px 4px rgba(0,0,0,.25)` / `inset 0 4px 8px rgba(0,0,0,.4)` / `rgba(194,217,210,.2)` | 문서 Dropdown(§5.1) | | `--hm-sw-header-document-list-max-height` | 320px | 목록 내부 스크롤 시작 높이(구현값) | diff --git a/docs/sw/sw-header-home-menu-responsive-2026-10-19.md b/docs/sw/sw-header-home-menu-responsive-2026-10-19.md new file mode 100644 index 0000000..3e769da --- /dev/null +++ b/docs/sw/sw-header-home-menu-responsive-2026-10-19.md @@ -0,0 +1,76 @@ +# SW Header 홈 메뉴 통합 · 실측 More (2026-10-19) + +> 브랜치 `feature/sw-home-menu`(기준 `c542bdc`, 작업 전 미커밋 `packages/sw/src/theme/sw-viewer.css` 3줄 보존). **Commit·Push 하지 않았습니다(승인 대기).** +> 검증: Storybook 개발 서버(포트 6025, 6024는 다른 세션이 사용 중)와 Claude 내장 브라우저(Chromium). 이 PC에는 기존 `*.browser.mjs`가 쓰는 Playwright 런타임이 없어 그 스크립트는 실행하지 않았습니다. + +## 1. 요청과 결과 + +| 요청 | 결과 | +|---|---| +| `SW / Home Menu` 기능·디자인을 `SW / Header`로 통합 | `SW / Header` → `Home Menu`(`sw-header--home-menu`) 한 페이지에 로고 클릭 열기/닫기·이벤트 기록, 헤더 폭 조절, Figma 26:10591 비교, Default/Hover/Active, 최근파일 하위 패널, 속성창·SWPopup·Escape 통합. `Overview` 로고도 같은 홈 메뉴를 엶 | +| 홈 버튼 클릭 → 열림, 다시 클릭 → 닫힘 | 기존 `SWHeader homeMenu` 동작 그대로(코드 변경 없음). 5개 섹션·15개 타일·Hover·하위 패널 유지 | +| SW 일반 모드 전용 | `SWViewer*` 코드·Story 변경 없음. 뷰어 Story에 홈 메뉴 0개 | +| 반응형 더보기: 실제 사용 가능한 공간 기준, 넓어지면 원위치, 순서·기능 유지 | `SWHeader` 실측 More 추가(아래 §2). Breakpoint는 그대로 | +| 메뉴 열고 닫을 때 헤더 요소 위치·폭 유지 | 측정에서 positioned 층(Dropdown·홈 메뉴·More 목록·Tooltip) 제외. 열기/닫기 전후 좌표 동일 확인 | +| `SW / Home Menu` 사이드바 제거, 컴포넌트·Export·스타일·AI 지침 유지 | Story 파일을 `sw-header-home-menu.stories.tsx`로 옮기고 title `SW/Header`. `SWHomeMenu`·`SWRecentFiles`·Export·`sw-home-menu.css`(패키지)·AI 지침 삭제 없음 | + +## 2. 실측 More 동작 + +- 기존 Breakpoint(1800 / 1180 / 1080 / 900 / 640 / 520)를 먼저 적용하고, 그 위에서 객체 수정 영역의 실제 남은 공간을 측정합니다. +- 측정: Layout Effect 안에서 `data-measuring`을 잠깐 붙여(그려지지 않음) 영역 안 요소가 줄거나 늘지 않고 auto margin이 0인 상태의 in-flow 폭을 읽습니다. 구성형 파일명은 최소 96px로 계산합니다. +- 이동 순서: Open(로고 오른쪽) → 선·문자·치수스타일 → 그리기모드 → 속성 블록 → 색상 → (구성형) 인쇄·K. 같은 단계는 오른쪽부터. 대표 칸은 이동하지 않습니다. +- 복귀: 옮긴 직후 생긴 공간을 한 번 측정해 두고 그만큼 공간이 생기면 역순으로 복귀. 기본 구성은 아무것도 옮기지 않으면 기존 CSS 전용 배치를 그대로 씁니다. +- 공개 API 변경 없음(추가 Prop 없음). 내부 상태·`data-squeezed` 속성·CSS만 추가. + +## 3. 변경 파일 + +| 파일 | 내용 | +|---|---| +| `packages/sw/src/components/sw-header/SWHeader.tsx` | 실측 More(측정 함수·이동 순서·상태·Layout Effect), Open 이동 판정을 같은 측정으로 통일 | +| `packages/sw/src/theme/sw.css` | `data-measuring` 측정 규칙, 옮겨진 그리기모드·속성 블록 자리 보정 | +| `src/sw/sw-home-menu.stories.tsx` → `src/sw/sw-header-home-menu.stories.tsx` | title `SW/Header`, 대표 Story `Home Menu`, 나머지 `verification` 태그(`sw-header--home-menu-*`) | +| `src/sw/sw-header.stories.tsx` | `Overview`에 홈 메뉴 연결, `Responsive More`에 "실제 사용 가능한 공간 기준" 섹션 | +| `src/sw/sw-header-overview.tsx` | 선택 `homeMenuSections` Prop | +| `src/sw/sw-home-menu.css`, `src/sw/sw-stories.css` | Story 전용 폭 조절 컨트롤 배치 | +| `packages/sw/tests/home-menu-integration.browser.mjs`, `packages/sw/tests/storybook-inventory.mjs` | 새 Story ID·제목 기대값, 이동 ID 표 | +| `docs/sw/sw-header-design-spec.md` §12.1, `docs/sw/sw-header-usage.md`, `packages/sw/README.md`, `packages/sw/ai/DESIGN_RULES.md` §7, `packages/sw/ai/COMPONENT_CATALOG.md` | 실측 More·Storybook 위치 | + +보존: `packages/sw/src/theme/sw-viewer.css`의 작업 전 미커밋 변경(`.hm-sw-viewer-menu-root { display: contents; }`)은 손대지 않았습니다. 과거 검증 보고서는 수정하지 않았습니다. + +## 4. 검증 + +| 항목 | 결과 | 방법 | +|---|---|---| +| SW typecheck / 앱 `tsc -b` / SW build | PASS | `npm run typecheck -w @hm-design/sw`, `npx tsc -b`, `npm run build -w @hm-design/sw` | +| AI 문서 | PASS / 32/32 | `npm run check:ai-docs`, `node packages/sw/tests/ai-docs.check.mjs` | +| Storybook 메뉴 | PASS | `index.json`: SW title = Header·Popup·Viewer(`SW/Home Menu` 없음), `sw-header--home-menu` 표시, 홈 메뉴 하위 14개 `verification` | +| 기존 Header Story 배치 회귀 | PASS(기본 구성 변화 없음) | 작업 전 dist로 기록한 요소 좌표·폭과 비교: Overview·Interactive States·Logo Slot·Document Dropdown·Responsive More(19폭)·K Guide·Hidden Sub Controls 동일. 차이는 `Document Open`(§5)뿐 | +| 이동한 홈 메뉴 Story 배치 | PASS 18/18 | 옛 `sw-home-menu--*`와 새 `sw-header--home-menu-*` 6개 × 1920/1280/768 좌표 동일(메뉴 x·폭 포함) | +| 홈 메뉴 열기/닫기 | PASS | 로고 클릭 → 메뉴 1·섹션 5·타일 15·`aria-expanded=true`·Focus 메뉴 안, 재클릭 → 닫힘, `onHomeClick` 미호출, 열기/닫기 전후 Header 좌표 동일. `Overview`에서도 열기/닫기 확인 | +| Hover·하위 패널·Escape | PASS | 실제 포인터 Hover 시 라벨 `#FF5C00`, 최근파일 → 하위 패널·outline 강조, Escape 1회 패널만 닫힘, 2회 메뉴 닫힘·로고로 Focus | +| 좁은 화면 더보기 · 폭 변경 재배치 | PASS | `Responsive More` 실측 섹션(로고 오른쪽 버튼 2개 + 도구 1개): 1920→390 축소 시 치수 → 문자 → 그리기모드 → 속성 블록 → 색상 순 이동, 겹침·가로 스크롤 0(520까지), 390→1920 확대 시 역순 복귀, 추가 요소 끄면 기본 CSS 배치로 복귀 | +| 더보기 안 메뉴 선택 · 팝업 | PASS | 1180: More 목록 = 선/문자/치수스타일·속성Bar·속성창(순서 유지). 속성창 → 팝업(`role=dialog`) 열림·Focus 안, Escape 닫힘·More로 Focus 복귀. 선스타일 → 대표 칸·Dropdown 열림·Focus, 레이어는 More로 | +| 헤더 요소 위치·폭 유지 | PASS | More 열기, 속성창 열기/닫기, 홈 메뉴, 레이어 Dropdown, 문서 Dropdown 각각 전후 좌표 동일 | +| SW 뷰어 모드 영향 | PASS | 뷰어 코드·Story diff 없음, `SW/Viewer` 3개 Story 렌더 오류 0·홈 메뉴 0 | +| Storybook production build | PASS | `npm run build-storybook`(인덱스 358개, SW title = Header·Popup·Viewer, `SW/Header` 27개) | + +참고: 내장 브라우저 창이 숨겨진 상태라 ResizeObserver가 프레임이 그려질 때만 실행됩니다. 폭 변경 검증은 각 단계마다 화면 프레임을 갱신한 뒤 측정했습니다. + +## 5. 의도된 배치 변화 (`Document Open` Story) + +로고 오른쪽 Open을 쓰는 기본 구성은 작업 전 아래 폭에서 실제로 겹쳤습니다(기존 판정이 `scrollWidth`만 봐서 감지 못함). 이제 Open(필요하면 메뉴 1개)이 More로 이동합니다. + +| 프레임 | 작업 전 | 작업 후 | +|---|---|---| +| 1800 | 치수스타일이 속성 블록과 겹침 | Open·치수스타일 → More | +| 1180 / 1080 | 색상이 More와 겹침 | Open → More | +| 900 | 색상이 More와 3px 겹침 | Open → More | +| 640 | 레이어가 More와 겹침 | Open → More | +| 구성형 768 | Open이 More에 있음 | Open 표시(파일명 200px ≥ 최소 96px) | + +## 6. NOT VERIFIED · 한계 + +- 기존 Playwright 스크립트(`home-menu-integration.browser.mjs` 등): 이 PC에 런타임 없음. ID만 갱신했고 실행하지 않았습니다. +- Firefox·Safari, 실제 소비 앱(`HMDesignSwTest`) 재검증, 픽셀 단위 스크린샷 비교(좌표·폭 비교로 대신함). +- 호스트 요소(`leading`·`tools`)는 More로 옮기지 않습니다. 390px에 로고 오른쪽 버튼 2개 + 도구를 함께 넣으면 대표 필드가 0까지 줄고 도구와 More가 겹칩니다(옮길 메뉴가 더 없음). +- 기존 동작 관찰(이번 변경과 무관, 수정하지 않음): 홈 메뉴에서 Escape로 닫을 때 Story 기록에 `onHomeMenuOpenChange(false, escape)`·`onActiveChange([])`가 2회씩 남습니다. 이전 Story(`sw-header--home-menu-header-composition`, 구 `sw-home-menu--header-composition`)에서도 같습니다. diff --git a/docs/sw/sw-header-usage.md b/docs/sw/sw-header-usage.md index 774d421..4283dae 100644 --- a/docs/sw/sw-header-usage.md +++ b/docs/sw/sw-header-usage.md @@ -371,6 +371,7 @@ import { SWHeaderInput, parseSWHeaderNumber, SWTheme } from "@hm-design/sw" - 레이어는 그동안 더보기로 이동하며, 더보기 → 레이어로 원래 배치로 돌아갑니다. 이미 화면에 있는 필드는 더보기에 나오지 않습니다. - 전환은 UI 상태입니다. 데이터 Callback은 호출되지 않고, 필드 클릭과 같은 `on*Open` 1회와 `on*MenuOpenChange(true)`만 호출됩니다. 값은 그대로 유지됩니다. - 폭이 넓어져 그 필드가 다시 보이는 단계에서는 1920 기준 배치로 돌아갑니다(Breakpoint 1800 / 1180 / 1080 / 900 / 640 / 520은 그대로). +- 실측 More(2026-10-19): Breakpoint 위에서 객체 수정 영역의 실제 남은 공간도 측정합니다. `leading`·`tools`·긴 라벨·사이드 패널 등으로 공간이 모자라면 표시할 수 없는 메뉴만 더보기로 옮기고, 공간이 다시 생기면 원래 자리·순서로 돌려놓습니다. 메뉴를 열고 닫는 것만으로는 Header 요소의 위치·폭이 바뀌지 않습니다([명세 §12.1](./sw-header-design-spec.md#121-실측-more--실제-사용-가능한-공간-기준-2026-10-19)). - Dropdown 데이터(`colors` 등)가 없는 필드도 같은 방식으로 대표 칸에 표시됩니다(목록 없이 `on*Open`만). ## 8. 하위 컴포넌트 재사용 @@ -406,7 +407,7 @@ import type { CSSProperties } from "react" - 기존 뷰어 `Toolbar.tsx`의 파일명(`fileName`)은 `documentTitle`로, 패널 토글(`propsOpen` 등)은 `propertyPanelOpen` + `onPropertyPanelToggle`로 연결할 수 있습니다. - 뷰어의 파일 열기·샘플·Model/Layout 탭·2.5D·어두운 배경·로드 상태는 Figma SW Header에 없는 뷰어 전용 도구입니다. 필요하면 `tools` 슬롯에 호스트가 렌더링합니다(스타일은 호스트 책임). - 헤더 높이는 49px입니다. 고정 배치(`position: fixed`)는 `className`·`style`로 호스트에서 지정합니다. -- 반응형은 모두 헤더 자신의 폭(container query)을 기준으로 하므로 사이드 패널 때문에 헤더가 좁아져도 동작합니다. 단계(1800 / 1180 / 1080 / 900 / 640 / 520)는 [디자인 명세 §12](./sw-header-design-spec.md#12-반응형)를 따릅니다. +- 반응형은 모두 헤더 자신의 폭(container query)을 기준으로 하므로 사이드 패널 때문에 헤더가 좁아져도 동작합니다. 단계(1800 / 1180 / 1080 / 900 / 640 / 520)는 [디자인 명세 §12](./sw-header-design-spec.md#12-반응형)를 따르고, 그 위에서 실제 남은 공간을 측정해 부족한 메뉴만 더보기로 옮깁니다([§12.1](./sw-header-design-spec.md#121-실측-more--실제-사용-가능한-공간-기준-2026-10-19)). - 뷰어는 현재 `@hm-design/ui`의 SWHeader 패턴을 사용합니다. 이 패키지로 바꾸는 작업은 이번 범위가 아닙니다. ## 10.1 상호작용 상태 @@ -454,7 +455,9 @@ Tooltip은 45 × 17px, 검정 80% 배경과 흰색 12px/400 글자입니다. Too npm run storybook ``` -현재(2026-10-19) `SW / Header`에는 33개 Story가 있습니다. Story ID·분류·용도 전체 표는 [1차 정리 보고 §2](./sw-first-pass-cleanup-review-2026-10-19.md#2-storybook-전체-목록-및-분류)를 봅니다. 아래 문단은 Story를 추가한 시점별 설명입니다. +현재(2026-10-19, 홈 메뉴 통합 후) `SW / Header`에는 27개 Story가 있습니다(사이드바 기본 표시 12개 + `verification` 태그 15개). 이전 시점의 Story 표는 [1차 정리 보고 §2](./sw-first-pass-cleanup-review-2026-10-19.md#2-storybook-전체-목록-및-분류), 홈 메뉴 통합 후 목록은 [홈 메뉴 통합·실측 More 보고](./sw-header-home-menu-responsive-2026-10-19.md)를 봅니다. 아래 문단은 Story를 추가한 시점별 설명입니다. + +2026-10-19 홈 메뉴 통합: 기존 `SW / Home Menu` 메뉴는 사이드바에서 제거하고 `SW / Header`로 옮겼습니다. 사이드바에는 `Home Menu`(`sw-header--home-menu`: 로고 클릭 열기/닫기·이벤트 기록, 헤더 폭 조절, Figma 26:10591 비교, Default/Hover/Active, 최근파일 하위 패널, 속성창·SWPopup·Escape 통합) 하나만 표시합니다. Figma 비교 캔버스·Variant·데이터 변경·단독 사용·속성Bar 비교 등은 `sw-header--home-menu-*` ID의 `verification` 태그 Story로 남아 직접 URL과 사이드바 태그 필터로 엽니다. `Overview`의 로고도 같은 홈 메뉴를 엽니다. `Responsive More` 첫 섹션 "실제 사용 가능한 공간 기준"은 헤더 폭 Range와 로고 오른쪽 버튼·추가 도구·홈 메뉴 On/Off로 실측 More의 이동·복귀를 확인합니다. 홈 메뉴는 SW 일반 모드 전용이며 `SW / Viewer`에는 없습니다. `SW / Header` 아래 Story: Overview, Default, Controls, Interactive States(인쇄·팝업 가이드·최소화·종료 Default/Hover 비교와 Callback 기록 포함), Responsive, Composed Controls, Logo Slot(기본 임시 로고 / 사용자 지정 로고 / 로고 미전달), Document Dropdown(Default / Hover / Open / 선택 / 여러 문서 / 문서 없음 / 긴 파일명 / 좁은 화면), Layer Dropdown(Layer Default / Hover / Open(Figma 8행) / Row Hover / 전구·눈꽃·자물쇠 4상태 3배 확대 / 선택·Toggle Callback 기록과 상태표 / 여러 상태·현재 레이어 / 긴 레이어명 / 20개 스크롤 / 레이어 없음 / 레이어 상세 / 상태 표시 전용 / 좁은 화면 1440–390). Responsive Story는 헤더 폭 18개(1920–390, 각 단계 경계 전후 포함) 프레임을 나열합니다. 모든 단계가 헤더 폭 기준이므로 Viewport를 바꾸지 않아도 확인할 수 있습니다. @@ -644,9 +647,9 @@ Figma 26:10591의 2단 Header 메뉴입니다. 기본 숨김, 로고 클릭으 onHomeMenuOpenChange={(open, reason) => {}} /> // reason: home | escape | background | outside | select | file | document ``` -- `sections`: `{ id, title, items: [{ id, label, icon, hoverIcon?, toggle?, panel?, disabled?, hidden?, onSelect? }] }[]`. 최근파일은 타일의 `panel: `(선택). +- `sections`: `{ id, title, items: [{ id, label, icon, hoverIcon?, toggle?, panel?, disabled?, hidden?, onSelect? }] }[]`. 최근파일은 타일의 `panel: `(선택). `panel`이 없는 항목은 실행 버튼입니다(클릭 시 `onSelect`/`onItemSelect`, 클릭 후 ON 유지 없음). 최근파일만 목록이 열린 동안 Active이며, 유지형이 필요하면 `toggle: true`. - 이벤트 우선순위: `homeMenu`가 있으면 로고 클릭은 메뉴 토글만 하고 `onHomeClick`은 호출되지 않습니다. `homeMenu`가 없으면 기존과 같이 `onHomeClick`만 호출됩니다. - New / Open은 문서 Dropdown 안 그대로입니다(`documentOpenPlacement` 기본 `"menu"`). 메뉴가 열리면 필드·문서 Dropdown이 닫히고, 문서 Dropdown을 열면 메뉴가 닫힙니다. -- 위치: 객체 수정 영역 −2px ~ 창 영역(DOM 측정, 1920에서 x 375 · 폭 1305). 좁은 폭에서는 메뉴 안 가로 스크롤. +- 위치: 객체 수정 영역 −2px ~ 창 영역(DOM 측정, 1920에서 x 375 · 폭 1305). 좁은 폭에서는 가로 스크롤 없이 들어가는 섹션만 표시하고 나머지는 끝의 더보기(⋯) 섹션으로 옮깁니다(Dropdown은 섹션 제목 + 기능 텍스트 목록, 타일과 같은 Hover·Active·클릭, 폭이 넓어지면 자동 복귀, 배지 문구 `homeMenu.moreLabel`). - Escape: 하위 패널 → 메뉴 순서, 닫히면 로고로 Focus. 속성창·`SWPopup`과 같은 Escape 순서(Focus가 모두 밖이면 최근 사용 하나). - 상세: 패키지 [카탈로그 5절](../../packages/sw/ai/COMPONENT_CATALOG.md), [통합 검증 기록](./sw-home-menu-integration-2026-10-19.md). diff --git a/docs/sw/sw-home-menu-integration-2026-10-19.md b/docs/sw/sw-home-menu-integration-2026-10-19.md index 936a10d..102cc32 100644 --- a/docs/sw/sw-home-menu-integration-2026-10-19.md +++ b/docs/sw/sw-home-menu-integration-2026-10-19.md @@ -33,6 +33,6 @@ ## 남은 항목 - 미실행: 독립 React 19 Tarball 소비 설치, SW + HM UI CSS 동시 사용, Figma 스크린샷 픽셀 비교(배치·크기는 DOM 실측으로만 확인), Firefox·Safari. -- 좁은 폭: 메뉴는 접히지 않고 메뉴 안에서 가로 스크롤(1440 825px, 1080 639px, 768·520 288px, 390 165px). 좁은 폭 디자인은 없습니다. -- 디자인 승인 대기(미적용): 속성Bar 차이 3건, 열림 상태 Header 상·하단 `#5F4B0F` 선, 폰트 차이. +- 좁은 폭: (2026-10-19 후속 수정) 가로 스크롤 대신 측정형 더보기(⋯). 들어가는 섹션만 앞에서부터 Figma 타일로 표시하고 나머지는 더보기 Dropdown의 텍스트 메뉴(섹션 제목 + 항목, 구분선)로 이동, 폭이 넓어지면 복귀. 실측(capture-responsive): 1920 5개, 1680 3+더보기, 1440·1280·1180 2+더보기, 1080·960 1+더보기, 768 이하 더보기만. 메뉴 행·페이지 가로 스크롤 0. +- 디자인 승인 대기(미적용): 속성Bar 차이 3건, 폰트 차이. 열림 상태 Header 상·하단 `#5F4B0F` 선과 로고 Home On은 2026-10-19 사용자 요청으로 적용(Figma 662:67267). - Task A의 기존 제한(넓은 `tools` + 390px에서 파일명·레이어 폭 0)은 이번 통합 범위 밖입니다. diff --git a/packages/sw/README.md b/packages/sw/README.md index dd62cd0..6c0cdda 100644 --- a/packages/sw/README.md +++ b/packages/sw/README.md @@ -44,6 +44,7 @@ import "@hm-design/sw/styles.css" /> ``` - 반응형 More: 좁은 헤더에서 더보기의 필드를 고르면 그 필드가 첫 칸(레이어 자리)에 표시되고 Dropdown이 바로 아래 열립니다. 레이어는 더보기에서 다시 고를 수 있으며, 전환은 UI 상태라 데이터 Callback을 호출하지 않습니다([명세 §5.4](../../docs/sw/sw-header-design-spec.md#54-반응형-more--대표-필드-전환-2026-10-16)). +- 실측 More(2026-10-19): Breakpoint 위에서 객체 수정 영역의 실제 남은 공간을 측정해 표시할 수 없는 메뉴만 More로 옮기고, 공간이 생기면 원래 자리·순서로 돌려놓습니다. 메뉴 열기·닫기는 Header 요소의 위치·폭을 바꾸지 않습니다([명세 §12.1](../../docs/sw/sw-header-design-spec.md#121-실측-more--실제-사용-가능한-공간-기준-2026-10-19)). Storybook의 홈 메뉴 예제는 `SW / Header` → `Home Menu`입니다. - Text Stroke: Figma에 Stroke가 있는 텍스트만 검정 외곽선(14·16px 1.3px, 12px 1px)을 표시합니다. 자기 색 0.3px Stroke는 2026-10-16 추가 수정으로 제거했습니다. 더보기·Tooltip·`+ New`/`Open`은 제외([명세 §6.1](../../docs/sw/sw-header-design-spec.md#61-text-stroke-2026-10-16)). - `SWHeaderInput`: 레이어 상세 등 상세 영역에서 쓰는 수정 가능 Input(Figma 26:11656, Default / Hover / 편집, caret `#E60403`). `value`(확정값) · `onValueChange`(임시값) · `onCommit`(Enter·Focus 이동, 유효 + 변경 시) · `onCancel`(Escape) · `valueType`(`text` / `number`) · `parse` · `readOnly` · `disabled`([명세 §5.5](../../docs/sw/sw-header-design-spec.md#55-레이어-상세-버튼--수정-가능한-input-2026-10-16)). - Peer: `react`, `react-dom` `^19.0.0`. 런타임 dependency는 없습니다. diff --git a/packages/sw/ai/COMPONENT_CATALOG.md b/packages/sw/ai/COMPONENT_CATALOG.md index dafaf6a..de546f0 100644 --- a/packages/sw/ai/COMPONENT_CATALOG.md +++ b/packages/sw/ai/COMPONENT_CATALOG.md @@ -35,6 +35,7 @@ SW 공식 기준 Header(Figma 26:8944, 1920 × 49). 로고 · 파일 · 객체 - 데이터 배열(`layers`, `colors`, `lineTypes`/`lineWeights`, `textStyles`, `dimensionStyles`, `documents`)을 주지 않으면 해당 필드는 Dropdown 없는 버튼입니다. - 반응형(More·대표 필드 전환·창 영역 축소)은 **`SWHeader` 안에서만** 동작합니다(CSS container `hm-sw-header`). 조합형 구성이 반응형이어야 하면 `controls` + `documentOpenPlacement` + `leading` + `tools`로 `SWHeader` 안에서 구성합니다(예제 F). - 로고 옆 Open은 실제 공간을 측정해 넘칠 때만 More로 이동하고, 그 시점보다 Open 폭만큼 넓어지면 돌아옵니다. Open이 보이는 동안 파일명이 먼저 줄고 레이어 필드는 Figma 폭을 유지합니다. +- 메뉴도 고정 폭만이 아니라 실제 남은 공간을 기준으로 More에 옮기고 공간이 생기면 원래 자리·순서로 돌려놓습니다(Breakpoint는 그대로, 추가 Prop 없음). 메뉴를 열고 닫아도 Header 요소의 위치·폭은 바뀌지 않습니다. ```tsx setId(l.id)} onClose={closeWindow} /> ``` @@ -96,9 +97,9 @@ Figma 26:10591(home on), 타일 15종 26:11355 … 26:11631, 섹션 제목 26:12 | 컴포넌트 | 용도 | 주요 Props | 크기·동작 | 검증 | |---|---|---|---|---| -| `SWHomeMenu` | 2단 메뉴 전체(섹션 여러 개). 보통 `SWHeader homeMenu`로 씀 | `sections`(`SWHomeMenuSectionData[]`) 또는 `children`, `open`/`defaultOpen`(false)/`onOpenChange(open, reason)`, `activeIds`/`defaultActiveIds`/`onActiveChange`, `selection`(`multiple` 기본 / `single`), `onItemSelect`, `closeOnBackgroundClick`(true), `closeOnSelect`(false), `closeOnEscape`(true), `closeOnOutsideClick`(false), `autoFocus`(true), `returnFocusRef`, `accent`(`auto`/`sections`/`outline`) | 높이 77(섹션 75 + 강조 2), 섹션 폭은 타일 수로 자동. 좁으면 메뉴 안 가로 스크롤 | ✅ | +| `SWHomeMenu` | 2단 메뉴 전체(섹션 여러 개). 보통 `SWHeader homeMenu`로 씀 | `sections`(`SWHomeMenuSectionData[]`) 또는 `children`, `open`/`defaultOpen`(false)/`onOpenChange(open, reason)`, `activeIds`/`defaultActiveIds`/`onActiveChange`, `selection`(`multiple` 기본 / `single`), `onItemSelect`, `closeOnBackgroundClick`(true), `closeOnSelect`(false), `closeOnEscape`(true), `closeOnOutsideClick`(false), `autoFocus`(true), `returnFocusRef`, `accent`(`auto`/`sections`/`outline`), `moreLabel`("더보기") | 높이 77(섹션 75 + 강조 2), 섹션 폭은 타일 수로 자동. 좁으면 들어가는 섹션만 표시하고 나머지는 더보기(⋯) Dropdown의 텍스트 메뉴(섹션 제목 + 항목, 같은 Active·Callback·하위 패널)로 이동(가로 스크롤 없음, 넓어지면 복귀) | ✅ | | `SWHomeMenuSection` | 섹션(제목 badge + 타일 그룹) | `title`, `children` | badge 폭 = 글자 + 46px | ✅ | -| `SWHomeMenuItem` | 80 × 46 타일(Default / Hover / Active) | 데이터 `SWHomeMenuItemData`: `id`, `label`, `icon`, `hoverIcon`, `toggle`(true = 켜고 끄기, false = 실행만), `panel`, `panelLabel`, `disabled`, `hidden`, `title`, `onSelect`. 메뉴 밖 단독이면 `active`/`defaultActive`/`onActiveChange` | Hover·Active = 주황 gradient 1px 테두리 + `#FF5C00` 아이콘·글자 | ✅ | +| `SWHomeMenuItem` | 80 × 46 타일(Default / Hover / Active) | 데이터 `SWHomeMenuItemData`: `id`, `label`, `icon`, `hoverIcon`, `toggle`(기본: `panel` 있는 항목만 true = 패널이 열린 동안 Active, 나머지는 실행 버튼 = 클릭 후 ON 없음. true = 켜고 끄기 유지), `panel`, `panelLabel`, `disabled`, `hidden`, `title`, `onSelect`. 메뉴 밖 단독이면 `active`/`defaultActive`/`onActiveChange` | Hover·Active = 주황 gradient 1px 테두리 + `#FF5C00` 아이콘·글자 | ✅ | | `SWRecentFiles` | 선택 하위 패널: 최근파일 목록 + 2뎁스 미리보기 | `files`(`SWFileEntry[]`: `id`, `name`, `path`, `badge`, `preview`, `previewTitle`, `disabled`), `onFileOpen`, `onFileHover`, `renderPreview`, `closeOnOpen`(true), `emptyText` | 폭 354, 행 50, 미리보기 310 × 270 | ✅ | - **Header 연결:** `SWHeader`의 `homeMenu`에 `SWHomeMenu` Props를 주면 됩니다. 기본 숨김, 로고 클릭 열기, 다시 클릭 닫기. 위치는 SWHeader가 실제 DOM으로 정합니다(객체 수정 영역 −2px ~ 창 영역, 고정 x 없음. `controls`에 `document`가 있으면 파일명 오른쪽 −2px부터). 로고·파일명·창 영역은 가리지 않습니다. diff --git a/packages/sw/ai/DESIGN_RULES.md b/packages/sw/ai/DESIGN_RULES.md index 4f95949..a54d0ae 100644 --- a/packages/sw/ai/DESIGN_RULES.md +++ b/packages/sw/ai/DESIGN_RULES.md @@ -83,7 +83,9 @@ Container `hm-sw-header` 기준 Breakpoint: **< 1800** 선/문자/치수스타일 → More, **< 1180** 그리기모드 숨김, **< 1080** 상세보기 → More·창 이동 24px(창 영역 176), **< 900** 색상 → More, **< 640** 인쇄·K → More·창 이동 숨김(창 영역 64), **< 520** 레이어 상태 아이콘 숨김. More에서 고른 필드는 첫 칸(레이어 자리)에 표시되고 Dropdown이 바로 열립니다(UI 상태만, 데이터 Callback 없음). -로고 클릭 메뉴는 좁은 폭에서 접히지 않고 메뉴 안에서 가로 스크롤합니다(좁은 폭 전용 디자인 없음, §12). +실측 More(2026-10-19): Breakpoint 위에서 객체 수정 영역의 실제 남은 공간을 측정해, `leading`·`tools`·긴 라벨 등으로 표시할 수 없는 메뉴만 같은 단계 순서(선/문자/치수 → 그리기모드 → 속성 블록 → 색상 → 구성형의 인쇄·K, 같은 단계는 오른쪽부터)로 More에 옮기고 공간이 생기면 역순으로 돌려놓습니다. 로고 옆 Open이 가장 먼저 옮겨집니다. 메뉴 열기·닫기는 Header 요소의 위치·폭을 바꾸지 않습니다. 호스트 요소(`leading`·`tools`)는 More로 옮기지 않으므로 폭이 좁은 화면에는 많이 넣지 않습니다. + +로고 클릭 메뉴는 좁은 폭에서는 가로 스크롤 없이 들어가는 섹션만 앞에서부터 보여 주고, 나머지는 끝의 더보기(⋯) 섹션으로 옮깁니다(2026-10-19 사용자 확정, Figma에 좁은 폭 디자인 없음). 더보기를 누르면 옮긴 섹션이 텍스트 메뉴(섹션 제목 + 기능 텍스트 목록, 그룹 사이 구분선)로 아래 Dropdown에 열리고, 폭이 넓어지면 원래 자리로 돌아갑니다. 화면에 남은 섹션은 Figma 타일 그대로입니다(§12). 조합 Header(개별 컴포넌트)에는 이 규칙이 적용되지 않습니다. 필요한 컨트롤만 배치하고 폭 정책은 소비 앱이 정합니다. @@ -163,11 +165,11 @@ Container `hm-sw-header` 기준 Breakpoint: **< 1800** 선/문자/치수스타 | 크기 | 메뉴 높이 77(섹션 75 + 하단 강조 2), 그룹 46, 타일 80 × 46, 아이콘 18 슬롯, 섹션 폭은 타일 수로 자동 | — | | 섹션 면 | 세로 gradient 면 + 1px `#081813` + 안쪽 1px `#20190E`, 아래 모서리 3px | `--hm-sw-home-menu-section-*` | | 섹션 제목 | Figma tit_* badge(9-slice), 글자 400 검정 | `--hm-sw-home-menu-title-color` | -| 타일 상태 | Default 아이콘 `#B6B4AF` · Hover·Active 주황 gradient 1px 테두리 + 아이콘·글자 `#FF5C00`, 1px 위·왼쪽 이동. 라벨 700 | `--hm-sw-home-menu-item-*`, `--hm-sw-home-menu-icon-color` | +| 타일 상태 | Default 아이콘 `#B6B4AF` · Hover·Pressed(누르는 동안)·Active 주황 gradient 1px 테두리 + 아이콘·글자 `#FF5C00`, 1px 위·왼쪽 이동. 라벨 700. 최근파일 외 항목은 실행 버튼: 클릭 후 ON 유지 없음(2026-10-19 사용자 확정). Active 유지는 하위 패널 타일(최근파일, 목록이 열린 동안)과 더보기·홈 버튼(메뉴가 열린 동안)만. 유지형이 필요하면 `toggle: true` | `--hm-sw-home-menu-item-*`, `--hm-sw-home-menu-icon-color` | | 하단 강조 | `sections` = 섹션마다 주황 띠, `outline` = 메뉴 전체 2px 외곽선(하위 패널이 열린 동안, `auto` 기본) | `--hm-sw-home-menu-accent-*` | -| 최근파일 패널 | 폭 354, 행 50, 배경 `#27241D`, 주황 테두리, 행 Hover `#62533D` + `#FF5C00`, 미리보기 310 × 270 | `--hm-sw-recent-files-*` | +| 최근파일 패널 | 폭 354, 행 50, 배경 `#27241D`, 주황 테두리, 행 Hover `#62533D` + `#FF5C00`, 미리보기 310 × 270. 미리보기 위치: 목록 오른쪽(Figma) → 오른쪽에 공간이 없으면 왼쪽 → 좌우 모두 없으면(예: 390) 목록 위에 겹쳐 Hover 행 바로 아래(목록 왼쪽 1px 안쪽, 4면 테두리·radius 4, 크기·색 동일), 화면 아래 공간이 없으면 행 바로 위(2026-10-19 사용자 확정, Figma 없음). 가로 스크롤 없음 | `--hm-sw-recent-files-*` | | 동작 | 기본 숨김 → 로고 클릭 열기 → 다시 클릭 닫기. 메뉴 빈 곳 클릭 닫기(Figma CLOSE). Escape: 하위 패널 → 메뉴, 닫히면 로고로 Focus. 메뉴 밖 클릭은 닫지 않음(Figma overlay 기준) | — | -| 좁은 폭 | 접는 디자인이 없어 메뉴 안 가로 스크롤(의도된 동작, 겹침·잘림 없음) | — | +| 좁은 폭 | 측정해 들어가는 섹션만 표시, 나머지는 끝의 더보기(⋯) 섹션(기존 섹션·타일 부품, 배지 `moreLabel` 기본 "더보기", 타일 "N개 그룹")으로 이동. 메뉴 배경·폭·높이·테두리·강조선은 그대로(더보기 섹션 면이 남는 폭을 채워 객체 수정 영역을 계속 덮음)이고, 더보기 배지·⋯ 타일만 마지막으로 표시된 섹션 바로 오른쪽에 붙음. 전체가 들어가는 폭에서는 더보기 숨김. 더보기 Dropdown과 최근파일 목록은 동시에 열리지 않음: 더보기를 열면 열린 목록을 먼저 닫고, Dropdown에서 최근파일을 고르면 Dropdown을 닫고 목록을 엶. Dropdown = 텍스트 메뉴(SW brown Dropdown: 배경 `#27241D`·테두리 `#000`·radius 3, 제목 12px 700 `#D4CBBD`, 행 30px·14px 700·좌우 12, 그룹 구분선 = 레이어 footer 선), ⋯ 타일 아래 왼쪽 정렬(화면 안으로 맞춤). 행 Hover = Pressed = Active = `#62533D` + `#FF5C00`. 일반 행은 클릭 후 ON·✓ 없음, 최근파일 행(›)만 목록이 열린 동안 Active. ✓는 `toggle: true` 행에만. 클릭·Callback·상태 규칙은 타일과 같음. ↓(더보기) = 첫 행, ↑/↓ 이동. Escape: Dropdown → 하위 패널 → 메뉴. 더보기 안 최근파일은 Dropdown을 닫고 더보기 타일 아래(화면 안으로 맞춤)에 기존 최근파일 목록으로 열림, 미리보기는 오른쪽에 공간이 없으면 왼쪽, 좌우 모두 없으면 목록 위 행 아래(최근파일 패널 행 참고). 목록이 메뉴 밖으로 나가는 부분은 메뉴 하단 강조선(2px, 같은 gradient)이 목록 상단으로 이어짐(실측 위치 기준, `--hm-sw-home-menu-accent-outline-width`). 가로 스크롤 없음 | `--hm-sw-home-menu-more-*` | -- 열림 상태 Header 상·하단 `#5F4B0F` 2px 선(Figma home on)과 로고 열림 표시는 **적용하지 않습니다**(디자인 승인 대기). 임의로 추가하지 않습니다. +- Home On(Figma 662:67267, 2026-10-19 사용자 확정): 메뉴가 열려 있는 동안 SWHeader가 자동으로 로고에 노란 Hover 테두리를 유지하고, Header 전폭 상·하단에 `#5F4B0F` 2px 선(`--hm-sw-header-home-on-line-color` / `-width`)을 그립니다. 닫으면 기본 상태로 돌아갑니다. 크기·위치 변화가 없고 SW 일반 모드 전용입니다(뷰어 모드에는 없음). 소비 코드에서 별도 class나 상태를 추가하지 않습니다. - 새 색·크기는 위 토큰만 `style`로 덮어씁니다. `hm-sw-home-menu*` class를 소비 코드에 쓰지 않습니다. diff --git a/packages/sw/src/components/sw-header/SWHeader.tsx b/packages/sw/src/components/sw-header/SWHeader.tsx index 51c6b37..49284eb 100644 --- a/packages/sw/src/components/sw-header/SWHeader.tsx +++ b/packages/sw/src/components/sw-header/SWHeader.tsx @@ -42,6 +42,34 @@ const frameControls: readonly SWHeaderFrameControlId[] = ["home", "windowMove", const subControls: readonly SWHeaderSubControlId[] = ["documentNew", "documentOpen", "layerFreeze", "layerLock"] const isMenu = (id: string): id is SWHeaderMenuId => id in menuSlot +/** + * Order in which visible parts move into More when the measured object area has no room left (on top of the + * breakpoints): the breakpoint tier order — line / text / dimension style, 그리기모드, the property block, color, + * print / K — and within a tier the rightmost part first. The representative field never moves. + */ +const squeezeRank: Partial> = { + lineStyle: 0, textStyle: 0, dimensionStyle: 0, drawingMode: 1, details: 2, propertyBar: 2, propertyPanel: 2, color: 3, print: 4, popupGuide: 4, +} + +/** + * Room left in the object area (negative: missing) when nothing in it shrinks, grows or takes free space through an + * auto margin (`data-measuring`, see sw.css "Measured More"). Read and reset in one layout effect, never painted. + * Only in-flow children count: dropdowns, tooltips and other positioned layers never change the result. + */ +function measureRoom(header: HTMLElement, area: HTMLElement) { + header.setAttribute("data-measuring", "") + const style = getComputedStyle(area) + const end = area.getBoundingClientRect().right - parseFloat(style.borderRightWidth) - parseFloat(style.paddingRight) + let used = area.getBoundingClientRect().left + parseFloat(style.borderLeftWidth) + parseFloat(style.paddingLeft) + for (const child of Array.from(area.children)) { + const childStyle = getComputedStyle(child) + if (childStyle.display === "none" || childStyle.position === "absolute" || childStyle.position === "fixed") continue + used = Math.max(used, child.getBoundingClientRect().right + parseFloat(childStyle.marginRight)) + } + header.removeAttribute("data-measuring") + return end - used +} + /** * Menu order: listed known ids first (duplicates and unknown ids ignored), missing ids after them in * the default order. Menus only swap places among the slots menus already take; other parts never move. @@ -170,8 +198,9 @@ export const SWHeader = forwardRef(function SWHeader const enabled = (id: SWHeaderControlId) => configuration.some(item => item.id === id) // Default design with removed object parts: same structure and breakpoints, but the script decides what // moves into More (the CSS alone assumes every field is present). Untouched defaults stay CSS-only. - // Sub-items live inside a part and never change the layout mode. - const scripted = controls !== undefined || [...removed].some(id => !frameControls.includes(id as SWHeaderFrameControlId) && !subControls.includes(id as SWHeaderSubControlId)) + // Sub-items live inside a part and never change the layout mode. Parts measured into More also need the script. + const [squeezed, setSqueezed] = useState([]) + const scripted = controls !== undefined || squeezed.length > 0 || [...removed].some(id => !frameControls.includes(id as SWHeaderFrameControlId) && !subControls.includes(id as SWHeaderSubControlId)) const layerStates = { showFreeze: shown("layerFreeze"), showLock: shown("layerLock") } const presentRef = useRef(new Set(configuration.map(item => item.id))) presentRef.current = new Set(configuration.map(item => item.id)) @@ -214,6 +243,7 @@ export const SWHeader = forwardRef(function SWHeader const [headerWidth, setHeaderWidth] = useState(1920) + const [, setAreaWidth] = useState(0) const [barOffset, setBarOffset] = useState(0) // Open next to the logo (documentOpenPlacement="header") moves into More when the measured header has no room. const openInHeader = documentOpenPlacement === "header" && shown("documentOpen") @@ -228,6 +258,8 @@ export const SWHeader = forwardRef(function SWHeader const update = () => { const bounds = header.getBoundingClientRect() setHeaderWidth(bounds.width) + // The object area can change alone (leading content, file name, window area): it re-runs the measured More. + setAreaWidth(panelAnchorRef.current?.getBoundingClientRect().width ?? 0) setBarOffset((panelAnchorRef.current?.getBoundingClientRect().left ?? bounds.left) - bounds.left) } const observer = new ResizeObserver(update) @@ -237,8 +269,7 @@ export const SWHeader = forwardRef(function SWHeader return () => observer.disconnect() }, []) // Space for the parts right of the logo, measured: the file name gives way first (its CSS clamp subtracts - // --hm-sw-header-leading-width). Open moves into More only when the bar or object area really overflows, - // and returns once the header is wider than at that moment by the Open width (no flicker at the edge). + // --hm-sw-header-leading-width). Open and the other parts move into More by measurement (see "Measured More"). useLayoutEffect(() => { const header = fieldsRef.current?.closest(".hm-sw-header") if (!header) return @@ -248,22 +279,6 @@ export const SWHeader = forwardRef(function SWHeader if (value) header.style.setProperty("--hm-sw-header-leading-width", value) else header.style.removeProperty("--hm-sw-header-leading-width") } - if (!openInHeader) { - collapseRef.current = null - if (openCollapsed) setOpenCollapsed(false) - return - } - if (!openCollapsed) { - const bar = header.querySelector(":scope > .hm-sw-header__bar") - const overflow = [bar, panelAnchorRef.current].some(element => !!element && element.scrollWidth - element.clientWidth > 1) - const open = leadingRef.current?.querySelector("[data-document-open]") - if (overflow && open) { - collapseRef.current = { at: header.getBoundingClientRect().width, width: open.getBoundingClientRect().width + 2 } - setOpenCollapsed(true) - } - } else if (collapseRef.current && headerWidth >= collapseRef.current.at + collapseRef.current.width) { - setOpenCollapsed(false) - } }) // Logo (home) menu: SWHeader owns its open state; a logo click toggles it instead of calling onHomeClick. @@ -303,9 +318,23 @@ export const SWHeader = forwardRef(function SWHeader const menuIds = configuration.map(item => item.id).filter((id): id is SWHeaderMenuId => id in menuSlot) const baseMenu = menuIds.includes("layer") ? "layer" : menuIds[0] const validPromoted = promoted && enabled(promoted) ? promoted : null - const isOverflow = (id: SWHeaderControlId) => id === "color" ? headerWidth < 900 : ["lineStyle", "textStyle", "dimensionStyle"].includes(id) ? headerWidth < 1800 : ["propertyBar", "propertyPanel", "details"].includes(id) ? headerWidth < 1080 : ["print", "popupGuide"].includes(id) ? headerWidth < 640 : false + const breakpointOverflow = (id: SWHeaderControlId) => id === "color" ? headerWidth < 900 : ["lineStyle", "textStyle", "dimensionStyle"].includes(id) ? headerWidth < 1800 : ["propertyBar", "propertyPanel", "details"].includes(id) ? headerWidth < 1080 : ["print", "popupGuide"].includes(id) ? headerWidth < 640 : id === "drawingMode" ? headerWidth < 1180 : false + // Measured More: the parts that can move (the default layout moves the property block as one part; print / K sit in + // the window area there and keep the breakpoint). Keys of the moved parts are kept in move order. + const squeezeGroups = (controls === undefined + ? [...menuIds.map(id => ({ key: id as string, ids: [id] as SWHeaderControlId[] })), { key: "drawingMode", ids: ["drawingMode"] as SWHeaderControlId[] }, + { key: "properties", ids: ["details", "propertyBar", "propertyPanel"] as SWHeaderControlId[] }] + : configuration.map(item => ({ key: item.id as string, ids: [item.id] }))) + .map((group, index) => ({ ...group, ids: group.ids.filter(id => enabled(id) && squeezeRank[id] !== undefined), index })) + .filter(group => group.ids.length > 0) + const squeezedIds = new Set(squeezeGroups.filter(group => squeezed.includes(group.key)).flatMap(group => group.ids)) + const isOverflow = (id: SWHeaderControlId) => breakpointOverflow(id) || squeezedIds.has(id) const representative = validPromoted && isOverflow(validPromoted) ? validPromoted : baseMenu const fieldHidden = (id: SWHeaderMenuId) => id !== representative && (isOverflow(id) || (id === baseMenu && representative !== baseMenu)) + // Next part to move: shown now, never the representative slot, lowest tier first, rightmost first within a tier. + const squeezeCandidates = squeezeGroups + .filter(group => !squeezed.includes(group.key) && !group.ids.some(id => id === baseMenu || id === validPromoted || (isMenu(id) ? fieldHidden(id) : isOverflow(id)))) + .sort((a, b) => (squeezeRank[a.ids[0]] ?? 0) - (squeezeRank[b.ids[0]] ?? 0) || b.index - a.index) // Removal is structural: close stale internal dropdown state silently, never send data callbacks. const controlKey = configuration.map(item => item.id).join(",") useEffect(() => { @@ -315,6 +344,51 @@ export const SWHeader = forwardRef(function SWHeader if (!enabled("propertyBar")) setInternalBarOpen(false) }, [controlKey, openMenu, promoted]) + // Measured More (2026-10-19): on top of the breakpoints, parts move into More while the object area has no room for + // them (leading content, tools, labels, a side panel) and return once the room they freed is back, so the header + // never relies on fixed widths alone. Open next to the logo moves first and returns last. One part per pass; the + // passes are synchronous layout effects, so only the final layout is painted. Opening a menu never moves a part: + // dropdowns and the logo menu are positioned layers, which the measurement ignores. + const squeezeRef = useRef(new Map()) + useLayoutEffect(() => { + const header = fieldsRef.current?.closest(".hm-sw-header") + const area = panelAnchorRef.current + // Wait for the measured header width (breakpoint state) to be rendered first. + if (!header || !area || Math.abs(header.getBoundingClientRect().width - headerWidth) > 0.5) return + if (!openInHeader) { + collapseRef.current = null + if (openCollapsed) return setOpenCollapsed(false) + } + // Parts removed from the configuration leave the list silently. + const valid = squeezed.filter(key => squeezeGroups.some(group => group.key === key)) + if (valid.length !== squeezed.length) return setSqueezed(valid) + const room = measureRoom(header, area) + const last = squeezed[squeezed.length - 1] + const metrics = last === undefined ? undefined : squeezeRef.current.get(last) + // The room a part frees is measured once, right after it moved (More appearing and padding changes included). + if (metrics && metrics.room === undefined) metrics.room = room - metrics.before + if (room < -0.5) { + const open = openShown ? leadingRef.current?.querySelector("[data-document-open]") : null + if (open) { + collapseRef.current = { at: header.getBoundingClientRect().width, width: open.getBoundingClientRect().width + 2 } + return setOpenCollapsed(true) + } + const next = squeezeCandidates[0] + if (next) { + squeezeRef.current.set(next.key, { before: room }) + setSqueezed([...squeezed, next.key]) + } + } else if (last !== undefined) { + if (room >= (metrics?.room ?? Infinity) - 0.5) { + squeezeRef.current.delete(last) + setSqueezed(squeezed.slice(0, -1)) + } + } else if (openCollapsed && collapseRef.current && headerWidth >= collapseRef.current.at + collapseRef.current.width) { + // Open returns once the header is wider than when it moved by the Open width (no flicker at the edge). + setOpenCollapsed(false) + } + }) + const hasMenu: Record = { layer: layers !== undefined, color: colors !== undefined, @@ -518,7 +592,7 @@ export const SWHeader = forwardRef(function SWHeader }) return ( -
+
setHomeOpen(!homeOpen, "home") : onHomeClick} interactive={shown("home")} logo={logo} logoSrc={logoSrc} logoAlt={logoAlt} aria-expanded={homeMenu && shown("home") ? homeOpen : undefined} aria-controls={homeOpen ? homeMenu?.id ?? homeMenuId : undefined} /> @@ -527,19 +601,19 @@ export const SWHeader = forwardRef(function SWHeader {leading}
} {controls === undefined && enabled("document") && documentNode} -
- {controls === undefined && enabled("drawingMode") && {drawingModeLabel}} +
+ {controls === undefined && enabled("drawingMode") && !squeezedIds.has("drawingMode") && {drawingModeLabel}}
{controls ? configuration.map(config => { - const hidden = config.id in menuSlot ? fieldHidden(config.id as SWHeaderMenuId) : isOverflow(config.id) || (config.id === "drawingMode" && headerWidth < 1180) + const hidden = config.id in menuSlot ? fieldHidden(config.id as SWHeaderMenuId) : isOverflow(config.id) return
{presence(config.id, configuredNodes[config.id])}
}) : scripted ? menuIds.map(id => (
{presence(id, fieldNodes[id])}
)) : menuIds.map(id => {fieldNodes[id]})} {tools}
- {moreItems.some(item => item.visible !== false) && } - {controls === undefined && } + {moreItems.some(item => item.visible !== false) && 0} />} + {controls === undefined && !squeezed.includes("properties") && }
{windowShown &&
{actionsShown && } diff --git a/packages/sw/src/components/sw-header/components/SWHeaderHome.tsx b/packages/sw/src/components/sw-header/components/SWHeaderHome.tsx index b8eaaf6..a891e4e 100644 --- a/packages/sw/src/components/sw-header/components/SWHeaderHome.tsx +++ b/packages/sw/src/components/sw-header/components/SWHeaderHome.tsx @@ -15,7 +15,7 @@ export interface SWHeaderHomeProps { * SWHeader always shows the logo; only the home action can be removed. Default true. */ interactive?: boolean - /** Logo menu state (SWHeader `homeMenu`). No visual change: Figma has no open look for the logo. */ + /** Logo menu state (SWHeader `homeMenu`). The Home On look is drawn by SWHeader (`data-home-menu-open`, Figma 662:67267). */ "aria-expanded"?: boolean "aria-controls"?: string } diff --git a/packages/sw/src/components/sw-home-menu/SWHomeMenu.tsx b/packages/sw/src/components/sw-home-menu/SWHomeMenu.tsx index 30d48ee..78db656 100644 --- a/packages/sw/src/components/sw-home-menu/SWHomeMenu.tsx +++ b/packages/sw/src/components/sw-home-menu/SWHomeMenu.tsx @@ -1,5 +1,5 @@ import { - createContext, forwardRef, useCallback, useContext, useEffect, useId, useImperativeHandle, useLayoutEffect, useMemo, useRef, useState, + Children, createContext, forwardRef, useCallback, useContext, useEffect, useId, useImperativeHandle, useLayoutEffect, useMemo, useRef, useState, type ButtonHTMLAttributes, type CSSProperties, type KeyboardEvent, type MouseEvent, type ReactNode, } from "react" import { useSWPopupStack } from "../sw-header/components/SWHeaderPropertyPanel" @@ -19,13 +19,26 @@ interface WindowContextValue { } const WindowContext = createContext(null) const SectionContext = createContext(undefined) +/** + * How sections and items draw: `tile` (Figma row), `text` (inside the More dropdown: title + text rows, same + * selection / Active / panel logic) or `measure` (invisible tile copy that gives the natural widths; no registration). + */ +type Presentation = "tile" | "text" | "measure" +const PresentationContext = createContext("tile") /** For content inside a panel (e.g. SWRecentFiles): close the whole menu after opening a file. */ export function useSWHomeMenuClose() { return useContext(WindowContext)?.close } -const ITEM_SELECTOR = ".hm-sw-home-menu__item:not(:disabled)" +const ITEM_SELECTOR = ":is(.hm-sw-home-menu__item, .hm-sw-home-menu__text-item):not(:disabled)" +const TEXT_ITEM_SELECTOR = ".hm-sw-home-menu__text-item:not(:disabled)" +/** Tiles / text rows that can take focus now (the closed More dropdown stays laid out but hidden; the measure copy is hidden). */ +const focusableItems = (root: Element | null, selector = ITEM_SELECTOR) => + Array.from(root?.querySelectorAll(selector) ?? []).filter(item => getComputedStyle(item).visibility !== "hidden") +const ROW = ":scope > .hm-sw-home-menu__sections" +const MORE_PANEL = ":scope > .hm-sw-home-menu__more-panel" +const MEASURE = ":scope > .hm-sw-home-menu__measure" /** * While open, the menu is on the SW popup Escape stack (SWPopup / property window): Escape with the focus outside @@ -41,13 +54,14 @@ function SWHomeMenuEscapeEntry({ onEscape, raiseRef }: { onEscape: () => void; r * default; the host toggles `open` from SWHeader `onHomeClick` (logo click / re-click). Sections of 80 x 46 tiles; * a tile may open an optional sub panel under the menu (Figma 최근파일 662:67331 → ). Every text, * icon, item and action is host data. Only the menu is drawn: the home button and window area stay those of - * . Render it inside (or next to SWHeader). + * . Render it inside (or next to SWHeader). Narrower than its sections, it never scrolls: the + * trailing sections move into a More (⋯) section and return when the width allows (`moreLabel`). */ export const SWHomeMenu = forwardRef(function SWHomeMenu({ sections, children, open: openProp, defaultOpen = false, onOpenChange, activeIds: activeProp, defaultActiveIds, onActiveChange, selection = "multiple", onItemSelect, closeOnBackgroundClick = true, closeOnSelect = false, closeOnEscape = true, closeOnOutsideClick = false, autoFocus = true, returnFocusRef, accent = "auto", - className, style, onClick, onKeyDown, ...rest + moreLabel = "더보기", className, style, onClick, onKeyDown, ...rest }, ref) { const [internalOpen, setInternalOpen] = useState(defaultOpen) const open = openProp ?? internalOpen @@ -91,16 +105,104 @@ export const SWHomeMenu = forwardRef(function S onOpenChange?.(false, reason) }, [openProp, onOpenChange, returnFocusRef, setActive]) - // Opening (not the first render): remember the focus to return to, then focus the first tile. + // Sections in order (data or children). The leading ones that fit stay in the row; the rest move into More. + const nodes = sections + ? sections.filter(section => !section.hidden).map(section => ( + + {section.items.filter(item => !item.hidden).map(item => )} + + )) + : Children.toArray(children) + const [fit, setFit] = useState(Number.POSITIVE_INFINITY) + const rowCount = Math.min(fit, nodes.length) + const overflowCount = nodes.length - rowCount + const [moreOpenState, setMoreOpen] = useState(false) + const moreOpen = moreOpenState && overflowCount > 0 + const moreId = useId() + const moreButtonRef = useRef(null) + const morePanelRef = useRef(null) + const [moreLeft, setMoreLeft] = useState(0) + const [, setResized] = useState(0) + const pendingFocus = useRef(false) + // Keyboard (ArrowDown on More): focus the first text row once the dropdown is shown. + const pendingMoreFocus = useRef(false) + + // Opening (not the first render): remember the focus to return to; the first tile is focused once the row is measured. const wasOpen = useRef(open) useLayoutEffect(() => { if (open && !wasOpen.current) { const active = document.activeElement previousFocus.current = active instanceof HTMLElement && !rootRef.current?.contains(active) ? active : null - if (autoFocus) rootRef.current?.querySelector(ITEM_SELECTOR)?.focus() + pendingFocus.current = autoFocus } wasOpen.current = open }, [open, autoFocus]) + useEffect(() => { if (!open || overflowCount === 0) setMoreOpen(false) }, [open, overflowCount]) + + // Measured More (2026-10-19): one synchronous read before paint, like SWHeader's measured More. data-measuring lets + // the menu take all the room its host gives it (so the available width does not depend on what is shown). The + // natural tile widths come from the invisible measure copy (every section as a tile + the More section), because + // the moved sections are text rows in the dropdown. + useLayoutEffect(() => { + const root = rootRef.current + const row = root?.querySelector(ROW) + const [tiles, moreCopy] = Array.from(root?.querySelector(MEASURE)?.children ?? []) + if (!open || !root || !row || !tiles || !moreCopy) return + root.setAttribute("data-measuring", "") + const available = root.getBoundingClientRect().width + const rowStyle = getComputedStyle(row) + const padding = parseFloat(rowStyle.paddingLeft) + parseFloat(rowStyle.paddingRight) + const widths = Array.from(tiles.children, section => section.getBoundingClientRect().width) + const moreWidth = moreCopy.firstElementChild?.getBoundingClientRect().width ?? 0 + root.removeAttribute("data-measuring") + // 0: not laid out yet (e.g. SWHeader before its placement) — keep the current split. + if (available < 1) return + let next = widths.length + if (widths.reduce((sum, width) => sum + width, 0) + padding > available + 0.5) { + let room = available - padding - moreWidth + next = 0 + while (next < widths.length && widths[next] <= room + 0.5) room -= widths[next++] + } + if (next !== rowCount) { setFit(next); return } + // Dropdown under the ⋯ tile (left edges aligned, like the sub panel at its tile), kept inside the viewport. + const panel = root.querySelector(MORE_PANEL) + if (moreOpen && pendingMoreFocus.current) { + pendingMoreFocus.current = false + focusableItems(panel, TEXT_ITEM_SELECTOR)[0]?.focus() + } + const moreTile = moreButtonRef.current + if (moreTile && panel) { + const origin = root.getBoundingClientRect() + const left = Math.max(Math.min(moreTile.getBoundingClientRect().left - origin.left, document.documentElement.clientWidth - origin.left - panel.offsetWidth), -origin.left) + if (Math.abs(left - moreLeft) > 0.1) setMoreLeft(left) + } + if (pendingFocus.current) { + pendingFocus.current = false + focusableItems(root)[0]?.focus() + } + }) + // The host's room can change without a render (window resize, a standalone container): measure again. + useEffect(() => { + const root = rootRef.current + if (!open || !root?.parentElement) return + const observer = new ResizeObserver(() => setResized(count => count + 1)) + observer.observe(root.parentElement) + const header = root.closest(".hm-sw-header") + if (header) observer.observe(header) + return () => observer.disconnect() + }, [open]) + + // A click outside the dropdown and its More tile closes the dropdown (the menu stays open). + useEffect(() => { + if (!moreOpen) return + const onPointerDown = (event: PointerEvent) => { + const target = event.target as Node + if (morePanelRef.current?.contains(target) || moreButtonRef.current?.closest(".hm-sw-home-menu__more")?.contains(target)) return + setMoreOpen(false) + } + document.addEventListener("pointerdown", onPointerDown) + return () => document.removeEventListener("pointerdown", onPointerDown) + }, [moreOpen]) useEffect(() => { if (!open || !closeOnOutsideClick) return @@ -114,21 +216,42 @@ export const SWHomeMenu = forwardRef(function S }, [open, closeOnOutsideClick, close, returnFocusRef]) // Panel position: under the menu, 1px right of its tile's left edge (Figma 최근파일 808 vs tile 807). + // A tile inside More opens its panel under the More tile (the dropdown closes, see the dropdown click). const [panelLeft, setPanelLeft] = useState(0) + const [panelFromMore, setPanelFromMore] = useState(false) + // Accent joint: the parts of the panel's top edge outside the menu (narrow widths: the panel is kept in the + // viewport and may reach past the menu). Measured with the panel position; empty while it stays under the menu. + const [joint, setJoint] = useState([]) useLayoutEffect(() => { if (!openPanelId || !rootRef.current) return const root = rootRef.current const measure = () => { const tile = root.querySelector(`[data-item-id="${CSS.escape(openPanelId)}"]`) - if (tile) setPanelLeft(tile.getBoundingClientRect().left - root.getBoundingClientRect().left + 1) + const inMore = !!tile?.closest(".hm-sw-home-menu__more-panel") + const anchor = inMore ? moreButtonRef.current : tile + setPanelFromMore(inMore) + if (!anchor) return + // Kept inside the viewport (narrow widths: no page scroll); at 1920 it stays at its tile as in Figma. + const origin = root.getBoundingClientRect() + const panel = root.querySelector(":scope > .hm-sw-home-menu__panel") + const tileLeft = anchor.getBoundingClientRect().left - origin.left + 1 + const left = panel ? Math.max(Math.min(tileLeft, document.documentElement.clientWidth - origin.left - panel.offsetWidth), -origin.left) : tileLeft + setPanelLeft(left) + // Each joint starts inside the menu's rounded bottom corner, so the accent runs on without a notch. + const right = left + (panel?.offsetWidth ?? 0) + const corner = parseFloat(getComputedStyle(root, "::after").borderBottomRightRadius) || 0 + const next: { left: number; width: number }[] = [] + if (panel && left < 0) next.push({ left, width: Math.min(right, corner) - left }) + if (panel && right > origin.width) { const start = Math.max(left, origin.width - corner); next.push({ left: start, width: right - start }) } + setJoint(current => JSON.stringify(current) === JSON.stringify(next) ? current : next) } measure() - const scroller = root.querySelector(".hm-sw-home-menu__sections") - scroller?.addEventListener("scroll", measure) const observer = new ResizeObserver(measure) observer.observe(root) - return () => { scroller?.removeEventListener("scroll", measure); observer.disconnect() } - }, [openPanelId]) + const panel = root.querySelector(":scope > .hm-sw-home-menu__panel") + if (panel) observer.observe(panel) + return () => observer.disconnect() + }, [openPanelId, rowCount]) const context = useMemo(() => ({ isActive: id => activeIds.includes(id), @@ -137,7 +260,8 @@ export const SWHomeMenu = forwardRef(function S close, select: (item, section) => { const { activeIds: current, onItemSelect: notify, selection: mode, closeOnSelect: closeAfter, panels: known } = latest.current - const toggle = item.toggle !== false + // Action items (the default without a panel) only run: no Active after the click (2026-10-19). + const toggle = item.toggle ?? item.panel != null const active = toggle && !current.includes(item.id) const event: SWHomeMenuSelectEvent = { item, section, active } if (toggle) { @@ -156,13 +280,33 @@ export const SWHomeMenu = forwardRef(function S const raiseRef = useRef<(() => void) | null>(null) if (!open) return null - /** Escape: an open sub panel closes first (focus back on its tile when it was inside), then the menu. */ + /** Closes the open sub panel: its tile returns to Default (same event as a second click on it). */ + const closePanel = () => { + if (!openPanelId) return + setActive(activeIds.filter(id => id !== openPanelId), { item: { id: openPanelId, label: panels[openPanelId]?.label ?? openPanelId }, active: false }) + } + /** + * The More dropdown and a sub panel never show together (they would cover each other): opening the dropdown closes + * the open panel first; a panel row inside the dropdown closes the dropdown (see the dropdown click); a click + * outside the dropdown (e.g. the 최근파일 tile in the row) closes it. + */ + const openMore = () => { + closePanel() + setMoreOpen(true) + } + + /** Escape: the More dropdown closes first, then an open sub panel (focus back on its tile when it was inside), then the menu. */ const escape = () => { + if (moreOpen) { + const focusInside = morePanelRef.current?.contains(document.activeElement) + setMoreOpen(false) + if (focusInside) moreButtonRef.current?.focus() + return + } if (openPanelId) { - const item = { id: openPanelId, label: panels[openPanelId]?.label ?? openPanelId } const focusInside = rootRef.current?.contains(document.activeElement) - setActive(activeIds.filter(id => id !== openPanelId), { item, active: false }) - if (focusInside) rootRef.current?.querySelector(`[data-item-id="${CSS.escape(openPanelId)}"]`)?.focus() + closePanel() + if (focusInside) (panelFromMore ? moreButtonRef.current : rootRef.current?.querySelector(`[data-item-id="${CSS.escape(openPanelId)}"]`))?.focus() return } close("escape") @@ -172,7 +316,7 @@ export const SWHomeMenu = forwardRef(function S onClick?.(event) if (event.defaultPrevented || !closeOnBackgroundClick) return const target = event.target as Element - if (!target.closest("button, a, input, [role='listbox'], .hm-sw-home-menu__panel")) close("background") + if (!target.closest("button, a, input, [role='listbox'], .hm-sw-home-menu__panel, .hm-sw-home-menu__more-panel")) close("background") } const handleKeyDown = (event: KeyboardEvent) => { @@ -184,14 +328,34 @@ export const SWHomeMenu = forwardRef(function S escape() return } - // ArrowDown on the tile of the open sub panel moves into the panel (keyboard access, not in Figma). - if (event.key === "ArrowDown" && openPanelId && (document.activeElement as HTMLElement | null)?.dataset.itemId === openPanelId) { + const focused = document.activeElement as HTMLElement | null + const onMore = !!focused && focused === moreButtonRef.current + // ArrowDown on the tile of the open sub panel (or on More, for a panel opened from it) moves into the panel + // (keyboard access, not in Figma). + if (event.key === "ArrowDown" && openPanelId && (focused?.dataset.itemId === openPanelId || (onMore && panelFromMore))) { const first = rootRef.current?.querySelector(".hm-sw-home-menu__panel :is(button, [href], input, [tabindex]):not(:disabled, [tabindex='-1'])") if (first) { event.preventDefault(); first.focus() } return } + // More dropdown: ArrowDown on More opens it on its first text row; ArrowUp / ArrowDown move through the rows and + // ArrowUp on the first row goes back to More. + if (event.key === "ArrowDown" && onMore) { + event.preventDefault() + if (moreOpen) focusableItems(morePanelRef.current, TEXT_ITEM_SELECTOR)[0]?.focus() + else { pendingMoreFocus.current = true; openMore() } + return + } + if ((event.key === "ArrowDown" || event.key === "ArrowUp") && focused && morePanelRef.current?.contains(focused)) { + const rows = focusableItems(morePanelRef.current, TEXT_ITEM_SELECTOR) + const index = rows.indexOf(focused) + if (index < 0) return + event.preventDefault() + if (event.key === "ArrowUp" && index === 0) moreButtonRef.current?.focus() + else rows[Math.min(rows.length - 1, Math.max(0, index + (event.key === "ArrowDown" ? 1 : -1)))]?.focus() + return + } if (!["ArrowLeft", "ArrowRight", "Home", "End"].includes(event.key)) return - const items = Array.from(rootRef.current?.querySelectorAll(ITEM_SELECTOR) ?? []) + const items = focusableItems(rootRef.current) const index = items.indexOf(document.activeElement as HTMLElement) if (index < 0) return event.preventDefault() @@ -202,6 +366,9 @@ export const SWHomeMenu = forwardRef(function S const resolvedAccent = accent === "auto" ? (openPanelId ? "outline" : "sections") : accent const openPanel = openPanelId ? panels[openPanelId] : undefined + // More tile: Variant3 while its dropdown is open or a panel of a tile inside it is open. + const moreActive = moreOpen || (!!openPanel && panelFromMore) + const hiddenTitles = sections?.filter(section => !section.hidden).slice(rowCount).map(section => section.title) return ( @@ -213,6 +380,7 @@ export const SWHomeMenu = forwardRef(function S className={`hm-sw-home-menu${className ? ` ${className}` : ""}`} data-accent={resolvedAccent} data-panel-open={openPanel ? "true" : undefined} + data-overflow={overflowCount > 0 || undefined} style={{ "--hm-sw-home-menu-title-art": `url("${titleBadge}")`, ...style } as CSSProperties} onClick={handleClick} onKeyDown={handleKeyDown} @@ -221,19 +389,65 @@ export const SWHomeMenu = forwardRef(function S > {closeOnEscape && }
- {sections - ? sections.filter(section => !section.hidden).map(section => ( - - {section.items.filter(item => !item.hidden).map(item => )} - - )) - : children} + {nodes.slice(0, rowCount)} + {overflowCount > 0 && ( + // The existing section + tile parts (badge, group, Hover / Variant3); only the ⋯ icon is new. + + + + )}
+ {overflowCount > 0 && ( + // Always laid out (positioned before it shows), visible only while open. The moved sections draw as text + // groups (title + rows) with the same items: selection, Active, panels and callbacks are unchanged. + // A row with a sub panel (최근파일) closes the dropdown; its panel opens under More. +
{ + if (!(event.target as Element).closest(".hm-sw-home-menu__text-item[aria-expanded]")) return + setMoreOpen(false) + moreButtonRef.current?.focus() + }}> + {nodes.slice(rowCount)} +
+ )} + {openPanel && ( + // The accent continues over the panel's top edge where it reaches past the menu (outline accent only). + resolvedAccent === "outline" && joint.map(part => ( +
) @@ -250,6 +464,15 @@ export interface SWHomeMenuSectionProps { /** Figma section (e.g. Frame 2408): title badge + tile group. Its width follows the number of tiles. */ export function SWHomeMenuSection({ title, children, section, className }: SWHomeMenuSectionProps) { const titleId = useId() + // Inside the More dropdown: the section title over a text list of its items (not in Figma, 2026-10-19). + if (useContext(PresentationContext) === "text") return ( + +
+ {title} +
{children}
+
+
+ ) return (
@@ -277,25 +500,32 @@ export interface SWHomeMenuItemProps extends Omit void } -/** Figma tile 80 x 46 with Default / Variant2 (Hover) / Variant3 (Active, same look as Variant2). */ +/** Figma tile 80 x 46 with Default / Variant2 (Hover) / Variant3 (pressed, or Active for a panel tile; same look as Variant2). */ export function SWHomeMenuItem({ item: itemProp, itemId, label, icon, hoverIcon, toggle, panel, panelLabel, active: activeProp, defaultActive = false, onActiveChange, onSelect, disabled, title, className, onClick, ...rest }: SWHomeMenuItemProps) { const host = useContext(WindowContext) const section = useContext(SectionContext) + const presentation = useContext(PresentationContext) const generatedId = useId() const item: SWHomeMenuItemData = itemProp ?? { id: itemId ?? generatedId, label: label ?? "", icon, hoverIcon, toggle, panel, panelLabel, disabled, title, onSelect, "aria-label": rest["aria-label"], } const [ownActive, setOwnActive] = useState(defaultActive) - const toggles = item.toggle !== false - const active = toggles && (host ? host.isActive(item.id) : activeProp ?? ownActive) + // Toggle by default only for a tile with a sub panel (최근파일: Active while its panel is open) and, outside a menu, + // for a tile given active / defaultActive / onActiveChange. Every other tile is an action button: Hover and the + // pressed moment (:active) only, nothing stays on after the click (2026-10-19 user decision). + const toggles = item.toggle ?? (host ? item.panel != null : activeProp !== undefined || defaultActive || onActiveChange !== undefined) + // Inside a menu, host-given activeIds still draw Variant3 (display only, e.g. the Figma Variant3 set); a click on an + // action tile never changes them. + const active = host ? host.isActive(item.id) : toggles && (activeProp ?? ownActive) const isDisabled = item.disabled ?? disabled const hasPanel = host != null && item.panel != null - const register = host?.registerPanel + // The measure copy never registers: the visible tile or text row of the same item does. + const register = presentation === "measure" ? undefined : host?.registerPanel useLayoutEffect(() => { if (!register) return register(item.id, item.panel ?? undefined, item.panelLabel ?? item.label) @@ -317,6 +547,31 @@ export function SWHomeMenuItem({ item.onSelect?.({ item, active: next }) } + if (presentation === "measure") return ( + + ) + // More dropdown row: the label only; Hover / Active / disabled and the click are the tile's (Active = ✓, panel = ›). + if (presentation === "text") return ( + + ) return (
{current && preview != null && ( - ) } -export const CaptureDefault: Story = { name: "비교 캔버스 · Default", tags: ["!autodocs"], render: () => } -export const CaptureActive: Story = { name: "비교 캔버스 · Variant3", tags: ["!autodocs"], render: () => } -export const CaptureOutline: Story = { name: "비교 캔버스 · outline", tags: ["!autodocs"], render: () => } -export const CaptureRecent: Story = { name: "비교 캔버스 · 최근파일", tags: ["!autodocs"], render: () => } +export const HomeMenuCaptureDefault: Story = { name: "Home Menu · 비교 캔버스 · Default", tags: ["!autodocs", "verification"], render: () => } +export const HomeMenuCaptureActive: Story = { name: "Home Menu · 비교 캔버스 · Variant3", tags: ["!autodocs", "verification"], render: () => } +export const HomeMenuCaptureOutline: Story = { name: "Home Menu · 비교 캔버스 · outline", tags: ["!autodocs", "verification"], render: () => } +export const HomeMenuCaptureRecent: Story = { name: "Home Menu · 비교 캔버스 · 최근파일", tags: ["!autodocs", "verification"], render: () => } -export const HeaderComposition: Story = { - name: "Header 조합 · 로고 클릭", +export const HomeMenuHeaderComposition: Story = { + name: "Home Menu · Header 조합 · 로고 클릭", + tags: ["verification"], render: () => ( + description="SWHeader의 homeMenu 하나로 연결합니다. 로고 클릭 = 열기/닫기(onHomeClick은 호출하지 않음), 메뉴 빈 곳 클릭 = 닫기(Figma CLOSE), 타일 클릭 = 실행(누르는 동안만 Variant3, 클릭 후 ON 없음), 최근파일만 목록이 열린 동안 Variant3. Escape는 하위 패널 → 메뉴 순으로 닫고 로고로 Focus를 돌립니다. ←/→/Home/End로 타일을 이동합니다. New / Open은 문서 Dropdown 안에 그대로 있고, Dropdown을 열면 메뉴가 닫힙니다." /> {log => log} @@ -129,8 +206,9 @@ export const HeaderComposition: Story = { ), } -export const Variants: Story = { - name: "3가지 Variant", +export const HomeMenuVariants: Story = { + name: "Home Menu · 3가지 Variant", + tags: ["verification"], render: () => ( - + - + - - - - {figmaHomeMenuSections.map(section => ( - - - ))} -
섹션제목 노드타일 (노드)
{section.title}{figmaTitleNodes[section.id]}{section.items.map(item => `${item.label} (${figmaTileNodes[item.id]})`).join(" · ")}
-
+ {tileTable}
), } @@ -161,7 +231,7 @@ function DynamicDemo() { const [sections, setSections] = useState(figmaHomeMenuSections) const [selection, setSelection] = useState<"multiple" | "single">("multiple") const [accent, setAccent] = useState("auto") - const [activeIds, setActiveIds] = useState(["save"]) + const [activeIds, setActiveIds] = useState([]) const [count, setCount] = useState(1) const { entries, record } = useLog() const update = (sectionId: string, change: (items: readonly SWHomeMenuItemData[]) => SWHomeMenuItemData[]) => @@ -195,8 +265,9 @@ function DynamicDemo() { ) } -export const DynamicData: Story = { - name: "Props · 데이터 변경", +export const HomeMenuDynamicData: Story = { + name: "Home Menu · Props · 데이터 변경", + tags: ["verification"], render: () => ( - record(describe(event))}> + record(describe(event))}> @@ -231,8 +302,9 @@ function StandaloneDemo() { ) } -export const Standalone: Story = { - name: "단독 사용 · 조합형", +export const HomeMenuStandalone: Story = { + name: "Home Menu · 단독 사용 · 조합형", + tags: ["verification"], render: () => ( ( ) } -export const PropertyBarCheck: Story = { - name: "속성Bar 비교 (26:10492)", +export const HomeMenuPropertyBarCheck: Story = { + name: "Home Menu · 속성Bar 비교 (26:10492)", + tags: ["verification"], render: () => ( ), } -export const CapturePropertyBar: Story = { - name: "비교 캔버스 · 속성Bar", tags: ["!autodocs"], +export const HomeMenuCapturePropertyBar: Story = { + name: "Home Menu · 비교 캔버스 · 속성Bar", tags: ["!autodocs", "verification"], render: () => {}} />, } /** Integration: logo menu + property window + SWPopup at the same time (Escape stack and focus). */ @@ -327,8 +401,9 @@ function IntegrationDemo() { ) } -export const Integration: Story = { - name: "통합 · Popup · Escape", +export const HomeMenuIntegration: Story = { + name: "Home Menu · 통합 · Popup · Escape", + tags: ["verification"], render: () => ( } +export const HomeMenuCaptureResponsive: Story = { name: "Home Menu · 비교 캔버스 · 반응형", tags: ["!autodocs", "verification"], render: () => } diff --git a/src/sw/sw-header-overview.tsx b/src/sw/sw-header-overview.tsx index ad18451..6ec3a7f 100644 --- a/src/sw/sw-header-overview.tsx +++ b/src/sw/sw-header-overview.tsx @@ -2,6 +2,7 @@ import { useId, useLayoutEffect, useRef, useState, type CSSProperties } from "re import { SWHeader, parseSWHeaderColor, type SWHeaderProps, type SWHeaderProperty, type SWHeaderPropertyGroup, type SWHeaderPropertySelection, type SWHeaderPropertyMenus, type SWHeaderColorMode, type SWHeaderLayer, type SWHeaderLineWeight, + type SWHomeMenuSectionData, } from "@hm-design/sw" import { StoryPage, StoryPageHeader } from "@/components/story-page" @@ -13,10 +14,12 @@ interface OverviewProps { propertyFixture: (selection: Selection) => SWHeaderProperty[] propertySelection: (selection: Selection) => SWHeaderPropertySelection barFixture: SWHeaderProperty[] + /** Logo (home) menu of the SW normal mode: the logo opens and closes it (SWHeader homeMenu). */ + homeMenuSections?: readonly SWHomeMenuSectionData[] } /** Storybook host only; dropdowns, validation, editing and focus use the public SW components. */ -export function SWHeaderOverview({ initial, fixtures, propertyGroups, propertyFixture, propertySelection, barFixture }: OverviewProps) { +export function SWHeaderOverview({ initial, fixtures, propertyGroups, propertyFixture, propertySelection, barFixture, homeMenuSections }: OverviewProps) { const controlId = useId() const slotRef = useRef(null) const headerRef = useRef(null) @@ -185,7 +188,9 @@ export function SWHeaderOverview({ initial, fixtures, propertyGroups, propertyFi expandedGroupIds: expanded, onExpandedGroupsChange: setExpanded, onPropertyChange, menus, shapeContent: emptyShape ? null : undefined, onOverviewClick: () => changeExample("all"), }} - onHomeClick={() => record("onHomeClick")} onPrint={() => record("onPrint")} onPopupGuide={() => record("onPopupGuide")} + onHomeClick={() => record("onHomeClick")} + homeMenu={homeMenuSections && { sections: homeMenuSections, onItemSelect: event => record(`onItemSelect(${event.item.id}, ${event.active})`) }} + onHomeMenuOpenChange={(open, reason) => record(`homeMenuOpen(${open}, ${reason})`)} onPrint={() => record("onPrint")} onPopupGuide={() => record("onPopupGuide")} onMinimize={() => record("onMinimize")} onClose={() => record("onClose")} onWindowMoveStart={() => record("onWindowMoveStart")} />
diff --git a/src/sw/sw-header.stories.tsx b/src/sw/sw-header.stories.tsx index 553ca7b..2babce6 100644 --- a/src/sw/sw-header.stories.tsx +++ b/src/sw/sw-header.stories.tsx @@ -6,12 +6,14 @@ import { type SWHeaderColorMode, type SWHeaderColorOption, type SWHeaderColorValue, type SWHeaderDimensionStyleOption, type SWHeaderDocument, type SWHeaderLayer, type SWHeaderLineStyleValue, type SWHeaderLineType, type SWHeaderLineWeight, type SWHeaderMenuId, type SWHeaderProps, type SWHeaderTextStyleOption, type SWHeaderProperty, type SWHeaderPropertyGroup, type SWHeaderPropertySelection, type SWHeaderPropertyMenus, type SWHeaderPropertyShapeContent, + SWRecentFiles, SWToolButton, } from "@hm-design/sw" import "@hm-design/sw/styles.css" import { SWHeaderMenuDetail } from "../../packages/sw/src/components/sw-header/components/SWHeaderDropdown" import { StoryPage, StoryPageHeader, StorySection } from "@/components/story-page" import "./sw-stories.css" import { SWHeaderOverview } from "./sw-header-overview" +import { figmaHomeMenuSections, figmaRecentFiles, withRecentFiles } from "./sw-home-menu-fixture" import placeholderLogo from "./assets/sw-header-logo-placeholder.svg" // Owner: docs/sw/sw-header-design-spec.md (Figma rj6wpsfk24lOWvWiVRAANP, node 26:8944 "header_green"). @@ -179,12 +181,16 @@ function InteractiveHeader(props: Partial) { ) } +// Logo menu of the Overview (Figma 26:10591 sample, same fixture as the Home Menu Story). +const OVERVIEW_HOME_MENU = withRecentFiles(figmaHomeMenuSections, ) + export const Overview: Story = { parameters: { controls: { disable: true } }, render: () => , + propertyGroups={PROPERTY_GROUPS} propertyFixture={propertyFixture} propertySelection={propertySelection} barFixture={BAR_FIXTURE} + homeMenuSections={OVERVIEW_HOME_MENU} />, } export const InteractiveStates: Story = { @@ -776,6 +782,44 @@ function StyleDemo({ width, ...props }: StyleHostProps & { width: number }) { const MORE_WIDTHS = [1920, 1800, 1799, 1440, 1180, 1179, 1080, 1079, 900, 899, 768, 640, 639, 520, 519, 390] +/** + * Measured More (2026-10-19): the header width comes from a range input and the host adds content the breakpoints + * do not know about (buttons next to the logo, extra tools). Parts move into More only while the real room is + * missing and return to their own place, in their own order, once it is back. Range / checkboxes are Storybook controls. + */ +function MeasuredMoreDemo() { + const [width, setWidth] = useState(1920) + const [leading, setLeading] = useState(true) + const [tools, setTools] = useState(true) + const [homeMenu, setHomeMenu] = useState(true) + const [barOpen, setBarOpen] = useState(false) + const [panelOpen, setPanelOpen] = useState(false) + const [log, setLog] = useState([]) + const record = (line: string) => setLog(lines => [...lines.slice(-7), line]) + return ( + <> +
+ + + + +
+

Callback: {log.length ? log.join(" → ") : "없음"}

+ + record("leading: 저장")}>저장 record("leading: 내보내기")}>내보내기 : undefined} + tools={tools ? record("tools: 측정")}>측정 : undefined} + homeMenu={homeMenu ? { sections: OVERVIEW_HOME_MENU, onItemSelect: event => record(`onItemSelect(${event.item.id})`) } : undefined} + onHomeMenuOpenChange={(open, reason) => record(`homeMenuOpen(${open}, ${reason})`)} + onPrint={() => record("onPrint")} onPopupGuide={() => record("onPopupGuide")} + propertyBarOpen={barOpen} onPropertyBarOpenChange={next => { setBarOpen(next); record(`propertyBarOpen(${next})`) }} + propertyPanelOpen={panelOpen} onPropertyPanelOpenChange={next => { setPanelOpen(next); record(`propertyPanelOpen(${next})`) }} + propertyPanel={{ selection: { id: "none", title: "선택된 객체 없음", kind: "none" } }} /> + + + ) +} + export const ResponsiveMore: Story = { name: "Responsive More", parameters: { controls: { disable: true } }, @@ -784,8 +828,11 @@ export const ResponsiveMore: Story = { + + + diff --git a/src/sw/sw-home-menu.css b/src/sw/sw-home-menu.css index 0fc2a1e..c3837b9 100644 --- a/src/sw/sw-home-menu.css +++ b/src/sw/sw-home-menu.css @@ -1,4 +1,4 @@ -/* Storybook layout only for SW / Home Menu (frames, logs, fixtures). The menu itself uses no story class. */ +/* Storybook layout only for the SW / Header Home Menu Stories (frames, logs, fixtures). The menu itself uses no story class. */ .sw-home-menu-story__scroll { overflow-x: auto; } .sw-home-menu-story__frame { position: relative; min-height: 80px; } .sw-home-menu-story__overlay { position: absolute; top: 0; z-index: 3; } @@ -11,4 +11,8 @@ .sw-home-menu-story__table { border-collapse: collapse; font-size: 13px; } .sw-home-menu-story__table :is(th, td) { padding: 4px 8px; border: 1px solid #ccc; text-align: left; } .sw-home-menu-story__tall .sw-home-menu-story__frame { height: 860px; } -.sw-home-menu-story__figma-row { display: flex; align-items: flex-start; gap: 16px; margin-top: 12px; } +.sw-home-menu-story__figma-row { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 16px; margin-top: 12px; } +.sw-home-menu-story__figma-row > img { max-width: 100%; height: auto; } +.sw-home-menu-story__figma-fit { display: block; width: 100%; height: auto; margin-top: 12px; } +.sw-home-menu-story__width { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; font-size: 13px; } +.sw-home-menu-story__width input { width: min(480px, 60vw); } diff --git a/src/sw/sw-stories.css b/src/sw/sw-stories.css index 9074602..0c0530a 100644 --- a/src/sw/sw-stories.css +++ b/src/sw/sw-stories.css @@ -70,3 +70,7 @@ .sw-overview-stage .hm-sw-header__document:has(.hm-sw-header__document-menu) { z-index: 3; } .sw-overview-status { flex: 0 0 auto; display: flex; flex-wrap: wrap; gap: 4px 16px; font-size: 12px; min-width: 0; } .sw-overview-status output { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } +/* Responsive More measured section: Storybook controls (width range, host content toggles) above the frame. */ +.sw-story-measured-controls { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 16px; margin-bottom: 8px; font-size: 13px; } +.sw-story-measured-controls label { display: inline-flex; align-items: center; gap: 6px; } +.sw-story-measured-controls input[type="range"] { width: min(480px, 60vw); }