feat(sw): viewer header logo menu and file list; simplify SW Storybook
SW Viewer Header (approved optional props, public export names unchanged at 170): - SWViewerHeader: logoMenu, documents, activeDocumentId, onDocumentSelect, onDocumentOpen, documentOpenLabel; measured responsive toggles (full -> icons -> More) with the SWHeader More / file-list styling. - SW AI guides, ExampleH, viewer/text-weight/theme-inheritance tests and the logo-document-menu tests with their QA record. SW Storybook cleanup (Story IDs and test fixtures kept): - Sidebar: Overview -> "SW Header" (first), 전체 Footer -> "SW Footer", Footer/Viewer responsive pages -> "Responsive More", Viewer content-variants -> "Settings Popup" (merges the settings popup page). - Hidden by the verification tag (direct URL kept): Header Dropdown, Document Open, Interactive States, Document Dropdown, Hidden Sub Controls, Home Menu standalone; Footer tool groups / custom content / parts; SW/Theme; Viewer menu groups / item states / variable size / settings panel / Header + Dropdown. - Removed demo UI: Overview size and callback output (demo data and selection only with &verification), Home Menu Figma node table and width demo, Header Responsive More reduced to 1440 / 768 / 390, Popup reopen button, property-panel comparison captions, Viewer context-menu demo (&verification only). - Tests: storybook-inventory records the hidden and renamed Stories; overview / range-cross-browser / viewer open the demo controls with &verification; integrated-popup reloads the Story instead of the reopen button; dropdown-consolidation asserts Dropdown is hidden from the sidebar and still opens by its direct URL.
This commit is contained in:
1 parent
46119eacb5
commit
23d522c136
57 files changed
+2623
-333
No files matched your search
@@ -114,6 +114,131 @@ button.hm-sw-viewer-header__brand { text-align: left; }
|
||||
}
|
||||
.hm-sw-viewer-header__document-name { min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
|
||||
|
||||
/* Logo menu (2026-10-21): the brand cap is the trigger of the SWHeader `...` menu (SWHeaderMore, sw.css). The wrapper
|
||||
takes the cap's place in the row but is not positioned: the cap keeps its own layer (z-index 2 over the file name,
|
||||
like the SWHeader logo), and the menu is placed by the header container itself — flush under the header's bottom
|
||||
border (100% of its padding box + its 1px border) at the left edge of the cap, at any header height or width. */
|
||||
.hm-sw-viewer-header__logo-menu.hm-sw-header__more {
|
||||
position: static;
|
||||
display: flex;
|
||||
flex: 0 0 auto;
|
||||
height: calc(var(--hm-sw-viewer-height) - 2px);
|
||||
margin-left: 0;
|
||||
}
|
||||
.hm-sw-viewer-header__logo-menu > .hm-sw-header__more-menu {
|
||||
top: calc(100% + 1px);
|
||||
left: 0;
|
||||
font-size: var(--hm-sw-header-font-size);
|
||||
font-weight: 400;
|
||||
line-height: normal;
|
||||
}
|
||||
|
||||
/* Logo menu (2026-10-21): the size, spacing and type of the viewer header dropdowns (SWViewerMenu); its colors are
|
||||
those of the SWHeader `...` menu it is (sw.css .hm-sw-header__more-menu: face, border, shadow, hover); its place
|
||||
stays flush under the header. Only this menu: the document list stays the SWHeader file-name list. */
|
||||
.hm-sw-viewer-header__logo-menu > .hm-sw-header__more-menu {
|
||||
min-width: 160px;
|
||||
padding: 4px;
|
||||
border-width: 1px;
|
||||
border-radius: var(--hm-sw-viewer-radius);
|
||||
color: var(--hm-sw-header-text-color);
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
line-height: 20px;
|
||||
}
|
||||
.hm-sw-viewer-header__logo-menu .hm-sw-header__more-item {
|
||||
gap: 8px;
|
||||
min-height: var(--hm-sw-viewer-menu-item-height);
|
||||
padding: 0 12px;
|
||||
color: inherit;
|
||||
}
|
||||
.hm-sw-viewer-header__logo-menu .hm-sw-header__more-item:is(:hover, :focus):not(:disabled) { background: var(--hm-sw-header-hover); outline: none; }
|
||||
.hm-sw-viewer-header__logo-menu .hm-sw-header__more-item:disabled { opacity: 0.5; }
|
||||
/* Title = SWViewerMenu label, directly above its items (one group, no divider); icons = SWViewerMenu icon slot. */
|
||||
.hm-sw-viewer-header__logo-menu .hm-sw-header__more-title { min-height: 0; padding: 6px 12px; font-size: 12px; font-weight: 500; line-height: 18px; }
|
||||
|
||||
/* Document list (2026-10-21): the SWHeader file-name button and dropdown (SWHeaderDocumentTitle) fill the well.
|
||||
The button draws the well (border, gradient), sized to the viewer row; the text keeps the viewer inset. */
|
||||
.hm-sw-viewer-header__document[data-list] {
|
||||
--hm-sw-header-bar-height: calc(var(--hm-sw-viewer-height) - 2px);
|
||||
padding: 0;
|
||||
border: 0;
|
||||
background: none;
|
||||
font-size: var(--hm-sw-header-font-size);
|
||||
line-height: normal;
|
||||
}
|
||||
|
||||
/* Header Open (2026-10-21, `onDocumentOpen`): SWHeader's documentOpenPlacement="header" surface (SWToolButton
|
||||
appearance="document", the file-name surface at its content width) right after the logo, sized to the viewer row,
|
||||
with the label after a folder icon (no border, no face). Icon only when the header has no room (measured,
|
||||
SWViewerHeader); the file name after it has no left padding (2026-10-21 user request). */
|
||||
.hm-sw-viewer-header > .hm-sw-header__document[data-tool] {
|
||||
--hm-sw-header-bar-height: calc(var(--hm-sw-viewer-height) - 2px);
|
||||
font-size: var(--hm-sw-header-font-size);
|
||||
line-height: normal;
|
||||
}
|
||||
.hm-sw-viewer-header .hm-sw-viewer-header__open { padding: 0 12px 0 16px; }
|
||||
.hm-sw-viewer-header__open .hm-sw-header__document-name { display: inline-flex; align-items: center; gap: 8px; overflow: visible; }
|
||||
.hm-sw-viewer-header__open-icon {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex: 0 0 auto;
|
||||
width: var(--hm-sw-viewer-button-height);
|
||||
height: var(--hm-sw-viewer-button-height);
|
||||
/* 2026-10-21 user request: no border and no face (transparent); the icon keeps its color, size and place. */
|
||||
border: 0;
|
||||
background: transparent;
|
||||
box-shadow: none;
|
||||
text-shadow: none;
|
||||
}
|
||||
.hm-sw-viewer-header__open-icon > svg { width: var(--hm-sw-viewer-icon-size); height: var(--hm-sw-viewer-icon-size); }
|
||||
.hm-sw-viewer-header > .hm-sw-header__document[data-tool] + .hm-sw-viewer-header__document { padding-left: 0; }
|
||||
.hm-sw-viewer-header__document[data-list] > .hm-sw-header__document { flex: 1 1 auto; min-width: 0; }
|
||||
/* No file open button before it: the file name starts 10px after the slanted logo edge (at mid height), as in
|
||||
SWHeader (text 10px after its home slant; measured 10.5px here with 18px). */
|
||||
.hm-sw-viewer-header__document[data-list] .hm-sw-header__document-button { padding: 0 16px 0 18px; }
|
||||
/* After the file open button (2026-10-21 user decision): 8px in. */
|
||||
.hm-sw-viewer-header > .hm-sw-header__document[data-tool] + .hm-sw-viewer-header__document[data-list] .hm-sw-header__document-button { padding: 0 16px 0 8px; }
|
||||
/* The list (SWHeader face, placement and rows unchanged) is never narrower than the file-name button it opens from:
|
||||
its outer width is at least the button's (100% of the wrapper, plus the two borders the list starts left of it) and
|
||||
at least the SWHeader list width; longer rows widen it. min-width wins over the SWHeader max-width. */
|
||||
.hm-sw-viewer-header__document[data-list] .hm-sw-header__document-menu {
|
||||
width: max-content;
|
||||
min-width: max(
|
||||
calc(var(--hm-sw-header-document-menu-width) + 2 * var(--hm-sw-header-document-menu-border-width)),
|
||||
calc(100% + 2 * var(--hm-sw-header-document-menu-border-width))
|
||||
);
|
||||
}
|
||||
/* Viewer header dropdown colors (2026-10-21): the menus of the header — menu buttons, More and their submenus — use the
|
||||
colors of the SWHeader `...` menu (sw.css .hm-sw-header__more-menu): its face and shadow (fixed values there), the
|
||||
object border token, the header text, secondary text at 80% (as its values) and the white 8% row hover with the text
|
||||
unchanged. Size, spacing and type stay SWViewerMenu. A standalone SWViewerMenu (context menu) and the document list
|
||||
keep their own colors. */
|
||||
.hm-sw-viewer-header .hm-sw-viewer-menu[data-surface] {
|
||||
border-color: var(--hm-sw-header-object-border-color);
|
||||
background: #0e3d2f;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.5);
|
||||
color: var(--hm-sw-header-text-color);
|
||||
}
|
||||
.hm-sw-viewer-header .hm-sw-viewer-menu .hm-sw-viewer-menu__item:is(:focus, :hover, [data-state="open"]):not([aria-disabled]) {
|
||||
background: var(--hm-sw-header-hover);
|
||||
color: inherit;
|
||||
}
|
||||
.hm-sw-viewer-header .hm-sw-viewer-menu :is(.hm-sw-viewer-menu__label, .hm-sw-viewer-menu__shortcut, .hm-sw-viewer-menu__chevron) { color: inherit; opacity: 0.8; }
|
||||
.hm-sw-viewer-header .hm-sw-viewer-menu .hm-sw-viewer-menu__separator { background: var(--hm-sw-header-document-menu-divider-color); }
|
||||
|
||||
/* Measured responsive steps (2026-10-21, SWViewerHeader measureRoom): set only inside one layout pass, never painted.
|
||||
Every part at its natural width: the file name at its text width up to its usual flex basis, the object surface
|
||||
neither stretched nor shrunk, the trailing area without its auto margin. */
|
||||
.hm-sw-viewer-header[data-measuring] .hm-sw-viewer-header__document { flex: 0 0 auto; width: max-content; max-width: clamp(140px, 25cqw, 360px); }
|
||||
.hm-sw-viewer-header[data-measuring] .hm-sw-viewer-header__object { flex: 0 0 auto; }
|
||||
.hm-sw-viewer-header[data-measuring] .hm-sw-viewer-header__actions { margin-left: 0; }
|
||||
/* While the logo menu or the document list is open, the header takes the viewer dropdown layer (SWViewerMenu, 60) so
|
||||
the parts hanging below it stay above SWViewerPanel popups (41+). Inside, the SWHeader order is kept: the logo cap
|
||||
(z-index 2) over the file name and its list (z-index 1), so an open list never covers the logo. Closed: no layer. */
|
||||
.hm-sw-viewer-header:has(> .hm-sw-viewer-header__logo-menu > .hm-sw-header__more-menu, > .hm-sw-viewer-header__document .hm-sw-header__document-menu) { z-index: 60; }
|
||||
|
||||
.hm-sw-viewer-header__object {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
Reference in new issue
Block a user