feat(sw): integrated improvement 0.2.0 (popup content, header open, tool buttons)
SW package 0.2.0 integrated improvement (Task A, steps 1-8). All new props are
optional; existing SW Stories are pixel-identical to the previous build (28/28).
- Build reproducibility: dist text normalized to LF, dist/build-info.json
(commit, dirty, tool versions, no timestamp), packages/sw/.gitattributes
(eol=lf). LF checkouts give identical dist and tarball.
- SWHeader: documentOpenPlacement ("menu" default | "header": Open right of
the logo in the existing document-button look, reusing onDocumentOpen and
documentOpenLabel, no duplicate Open in the dropdown), leading slot,
hiddenControls sub-items documentNew / documentOpen / layerFreeze /
layerLock. Open moves into More on measured overflow (with hysteresis).
- showNew / showOpen (SWHeaderDocumentTitle), showFreeze / showLock (layer
menu, field, property window list).
- SWToolButton (text / pill / document) and SWToolGroup (radio selection),
reusing the existing toggle, pill and file-name looks.
- SWPopup / SWPopupSection / SWPopupRow on the shared property window frame;
SWHeaderPropertyPanel gains children, title, autoFocus and optional
selection / properties / groups. Escape stack for several popups.
- Field dropdowns inside a popup use the shared fixed overlay
(useSWFixedDropdownPosition), so the scrolling body no longer clips them.
- AI guide, examples E/F, README, Storybook (SW/Header/Options, SW/Tool,
SW/Popup) and verification record docs/sw/sw-integrated-improvement-2026-10-19.md.
- Regression scripts rescoped for the intended changes (unused-removal 81/81,
overview 52/54 with the two pre-existing historical assertions).
Known limitation (unresolved): tools / leading content (incl. SWToolGroup)
does not move into More. With a wide tool bar the configured fields shrink
instead; in Example F the document name and layer field reach 0px at 390px.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
5faa1f1ffe
commit
55179b4577
138 files changed
+17194
-162
No files matched your search
@@ -0,0 +1,50 @@
|
||||
// Example F — a viewer header: logo → Open → file → layer → color → K, plus a tool bar (Model / Layout, 2.5D,
|
||||
// Fit) after the menus. Everything is SWHeader props, so the existing responsive More serves the whole layout
|
||||
// (Open moves into More when the measured header has no room). No freeze / lock, no "+ New" in this product.
|
||||
import { useState } from "react"
|
||||
import { SWHeader, SWToolButton, SWToolGroup } from "@hm-design/sw"
|
||||
import { colors, documents, layers } from "./sample-data"
|
||||
|
||||
// The program supplies its icons (24 x 23 box of a pill button). Colors: the existing print icon fill #B6D0C9,
|
||||
// hover --hm-sw-header-selected-color (#FFC600), as in DESIGN_RULES §2.
|
||||
const FitIcon = ({ color }: { color: string }) => (
|
||||
<svg viewBox="0 0 24 23" width="24" height="23" aria-hidden="true">
|
||||
<path d="M2 8V2h6M16 2h6v6M22 15v6h-6M8 21H2v-6" fill="none" stroke={color} strokeWidth="2" />
|
||||
</svg>
|
||||
)
|
||||
|
||||
export function ExampleFViewerToolbar({ onEvent }: { onEvent?: (name: string) => void }) {
|
||||
const [activeLayerId, setActiveLayerId] = useState("0")
|
||||
const [view, setView] = useState<"model" | "layout">("model")
|
||||
const [depth, setDepth] = useState(false)
|
||||
return (
|
||||
<SWHeader
|
||||
documentTitle={documents[0].name}
|
||||
documents={documents}
|
||||
activeDocumentId="doc-1"
|
||||
documentOpenPlacement="header"
|
||||
documentOpenLabel="파일 열기"
|
||||
onDocumentOpen={() => onEvent?.("document:open")}
|
||||
onDocumentSelect={document => onEvent?.(`document:${document.id}`)}
|
||||
controls={[{ id: "document" }, { id: "layer" }, { id: "color" }, { id: "popupGuide" }]}
|
||||
hiddenControls={["documentNew", "layerFreeze", "layerLock"]}
|
||||
layers={layers}
|
||||
activeLayerId={activeLayerId}
|
||||
onLayerSelect={layer => { setActiveLayerId(layer.id); onEvent?.(`layer:${layer.id}`) }}
|
||||
colors={colors}
|
||||
onColorSelect={option => onEvent?.(`color:${option.id}`)}
|
||||
tools={<>
|
||||
<SWToolGroup label="보기" selection="single">
|
||||
<SWToolButton pressed={view === "model"} onClick={() => { setView("model"); onEvent?.("view:model") }}>Model</SWToolButton>
|
||||
<SWToolButton pressed={view === "layout"} onClick={() => { setView("layout"); onEvent?.("view:layout") }}>Layout</SWToolButton>
|
||||
</SWToolGroup>
|
||||
<SWToolGroup label="표시">
|
||||
<SWToolButton pressed={depth} onClick={() => { setDepth(!depth); onEvent?.(`2.5d:${!depth}`) }}>2.5D</SWToolButton>
|
||||
</SWToolGroup>
|
||||
<SWToolGroup appearance="pill" aria-label="화면">
|
||||
<SWToolButton appearance="pill" icon={<FitIcon color="#B6D0C9" />} hoverIcon={<FitIcon color="var(--hm-sw-header-selected-color)" />} onClick={() => onEvent?.("fit")}>화면 맞춤</SWToolButton>
|
||||
</SWToolGroup>
|
||||
</>}
|
||||
/>
|
||||
)
|
||||
}
|
||||
Reference in new issue
Block a user