feat(sw): viewer layer bulb, popup toggle switch, footer layout and 1440px story inner
Deploy Storybook / deploy (push) Successful in 1m11s
Deploy Storybook / deploy (push) Successful in 1m11s
- SW Viewer layer popup: search + 전체 레이어 fixed, only the list scrolls; the all-layers control is the SWLayerVisibilityIcon bulb (role="switch"), one light #d2c8b4 line under it. - Example H and the layer popup AI docs follow the bulb layout (VIEWER, DESIGN_RULES, COMPONENT_CATALOG, COMPOSITION_PATTERNS, AI_GUIDE sync). - Popup toggle switch (Figma toggle_btn_new 633:75188 / 633:75902): one sw.css face for the HM UI Switch in SWPopup and SWViewerSwitch in SWViewerPanel; SW Header switches unchanged. - SW Footer stories: no inner scrollers, fluid screens; workspace fits the viewport. - SW Footer category tabs keep their positions when selected (divider slots kept, pocket edges drawn over the neighbours' padding). - Storybook .sb-page-inner: 1440px max from 1920px (was 80vw). - SW Header equal-split change was cancelled; header CSS unchanged. Verified: check:ai-docs PASS, viewer test 49 PASS (1 FAIL hover face + timeout pre-existing), footer-design-review 21 PASS, browser checks of switch/footer/inner. Not verified: footer-popup-viewer-refinement (needs full Storybook build), text-weight/hover tests, Switch 37x16 AI docs (deferred).
This commit is contained in:
1 parent
258e0a4b68
commit
c1549b2b4f
22 files changed
+121
-63
No files matched your search
@@ -109,17 +109,20 @@ export function LayerPanel({ demo, ...placement }: { demo: ViewerDemo } & PanelP
|
||||
const [query, setQuery] = useState("")
|
||||
const filtered = LAYERS.filter(layer => layer.name.toLowerCase().includes(query.trim().toLowerCase()))
|
||||
const set = (names: string[]) => demo.setHidden(new Set(names))
|
||||
// 2026-10-22: one switch for all layers. ON only when every layer is shown; a partial state reads OFF, so a click turns all on.
|
||||
// 2026-10-22: one bulb for all layers (was a switch). ON only when every layer is shown; a partial state reads OFF, so a click turns all on.
|
||||
const allVisible = demo.hidden.size === 0
|
||||
const setAll = (next: boolean) => { set(next ? [] : LAYERS.map(layer => layer.name)); demo.record(`layer:all=${next}`) }
|
||||
return (
|
||||
<SWViewerPanel title={`레이어 (${LAYERS.length}개)`} open={demo.panels.layers} onClose={() => demo.toggle("layers", false)} {...placement}>
|
||||
<SWViewerSection surface="plain" aria-label="레이어 목록">
|
||||
{/* 2026-10-22: search + 전체 레이어 stay fixed; only the layer list scrolls (.sw-viewer-story-layers). */}
|
||||
<SWViewerSection surface="plain" aria-label="레이어 목록" className="sw-viewer-story-layers">
|
||||
<div className="sw-viewer-story-toolbar">
|
||||
<SWViewerInput type="search" placeholder="레이어 검색" aria-label="레이어 검색" value={query} onChange={event => setQuery(event.currentTarget.value)} />
|
||||
{/* 2026-10-22: the section title (.hm-sw-viewer-section__title) names the switch row; the switch stays on that line. */}
|
||||
{/* 2026-10-22: the section title (.hm-sw-viewer-section__title) names the row; the bulb (same button as the rows)
|
||||
stays on that line and keeps the former switch semantics (role="switch", name 전체 레이어). */}
|
||||
<SWViewerSection surface="plain" title="전체 레이어" className="sw-viewer-story-all">
|
||||
<SWViewerSwitch aria-label="전체 레이어" checked={allVisible}
|
||||
onCheckedChange={next => { set(next ? [] : LAYERS.map(layer => layer.name)); demo.record(`layer:all=${next}`) }} />
|
||||
<button type="button" role="switch" aria-checked={allVisible} aria-label="전체 레이어" className="sw-viewer-story-bulb"
|
||||
title={allVisible ? "전체 숨기기" : "전체 표시하기"} onClick={() => setAll(!allVisible)}><SWLayerVisibilityIcon on={allVisible} /></button>
|
||||
</SWViewerSection>
|
||||
</div>
|
||||
{filtered.length === 0 ? <SWViewerHint>검색 결과가 없습니다 ("{query}")</SWViewerHint> : (
|
||||
|
||||
Reference in new issue
Block a user