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
@@ -12,7 +12,6 @@ const Icon = ({ d }: { d: string }) => (
|
||||
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true"><path d={d} /></svg>
|
||||
)
|
||||
const icons = {
|
||||
open: <Icon d="M3 7h6l2 2h10v10H3z" />,
|
||||
fit: <Icon d="M3 8V3h5M16 3h5v5M21 16v5h-5M8 21H3v-5" />,
|
||||
layers: <Icon d="M12 3l9 5-9 5-9-5 9-5zM3 13l9 5 9-5" />,
|
||||
options: <Icon d="M4 6h10M18 6h2M4 12h4M12 12h8M4 18h12M20 18h0" />,
|
||||
@@ -28,25 +27,23 @@ export function ExampleHViewerMode({ onEvent }: { onEvent?: (name: string) => vo
|
||||
const [zoomSpeed, setZoomSpeed] = useState(1)
|
||||
const [about, setAbout] = useState(false)
|
||||
|
||||
// File open: the header button after the logo (icon + label, icon only when the header is narrow). File name click:
|
||||
// the sample list only (no Open / + New).
|
||||
const openFile = () => onEvent?.("file:open")
|
||||
const samples = [{ id: "sample-a", name: "BasicSample.dwg", title: "기본 도면 · DWG" }, { id: "sample-b", name: "simple.dxf", title: "기본 도형 · DXF" }]
|
||||
const groups: SWViewerHeaderGroup[] = [
|
||||
{ id: "file", label: "파일", items: [
|
||||
{ type: "button", id: "open", label: "파일 열기", icon: icons.open, iconOnlyBelow: 560 },
|
||||
{ type: "menu", id: "samples", label: "샘플", moreLabel: "샘플 도면", collapseBelow: 1180, entries: [
|
||||
{ type: "item", id: "sample-a", label: "기본 도면 · DWG", onSelect: () => setFileName("BasicSample.dwg") },
|
||||
{ type: "submenu", id: "recent", label: "최근 도면", entries: [{ type: "item", id: "recent-1", label: "simple.dxf", onSelect: () => setFileName("simple.dxf") }] },
|
||||
] },
|
||||
] },
|
||||
{ id: "space", label: "도면 공간", surface: "field", hidden: !fileName, items: [
|
||||
{ type: "tabs", id: "space", label: "모델과 배치 선택", collapseBelow: 1180, value: space, onValueChange: setSpace,
|
||||
options: [{ value: "model", label: "Model", count: 1200 }, { value: "layout", label: "Layout", count: 40 }] },
|
||||
] },
|
||||
{ id: "view", label: "화면 보기", surface: "field", items: [
|
||||
{ type: "button", id: "fit", label: "전체 보기", icon: icons.fit, iconOnlyBelow: 560, disabled: !fileName },
|
||||
// Measured steps: full while it fits, icon only next, then into More (the numbers only give the order).
|
||||
{ type: "button", id: "fit", label: "전체 보기", icon: icons.fit, iconOnlyBelow: 560, collapseBelow: 1180, disabled: !fileName },
|
||||
{ type: "switch", id: "depth", label: "2.5D", checked: depth, collapseBelow: 1180, onCheckedChange: setDepth },
|
||||
] },
|
||||
{ id: "panels", label: "패널", placement: "end", items: [
|
||||
{ type: "toggle", id: "layers", label: "레이어", icon: icons.layers, pressed: panels.layers, collapseBelow: 900, onPressedChange: layers => setPanels({ ...panels, layers }) },
|
||||
{ type: "toggle", id: "options", label: "설정", icon: icons.options, pressed: panels.options, collapseBelow: 900, onPressedChange: options => setPanels({ ...panels, options }) },
|
||||
{ type: "toggle", id: "layers", label: "레이어", icon: icons.layers, pressed: panels.layers, iconOnlyBelow: 900, onPressedChange: layers => setPanels({ ...panels, layers }) },
|
||||
{ type: "toggle", id: "options", label: "설정", icon: icons.options, pressed: panels.options, iconOnlyBelow: 900, onPressedChange: options => setPanels({ ...panels, options }) },
|
||||
] },
|
||||
]
|
||||
|
||||
@@ -54,6 +51,7 @@ export function ExampleHViewerMode({ onEvent }: { onEvent?: (name: string) => vo
|
||||
<>
|
||||
{/* No logo prop: nothing is drawn on the cap (no "HM" text). Pass logoSrc / logo to show the program's logo. */}
|
||||
<SWViewerHeader documentTitle={fileName} groups={groups}
|
||||
documents={samples} activeDocumentId={samples.find(sample => sample.name === fileName)?.id} onDocumentSelect={sample => setFileName(sample.name)} onDocumentOpen={openFile} documentOpenLabel="파일 열기"
|
||||
onCommand={command => onEvent?.(`${command.itemId}/${command.id}${command.value === undefined ? "" : `=${String(command.value)}`}`)}
|
||||
trailing={<>
|
||||
<SWViewerStatus state={fileName ? "ready" : "idle"} />
|
||||
|
||||
Reference in new issue
Block a user