refactor(storybook): consolidate dropdown stories into composed controls

This commit is contained in:
shkim4 committed 2026-10-19 12:30:29 +09:00
1 parent c165753bbe
commit 9482d45f34
74 files changed
+38833 -283

No files matched your search

File diff suppressed because it is too large. Load diff
@@ -0,0 +1 @@
{"v":5,"entries":{"foundation-color--all":{"type":"story","subtype":"story","id":"foundation-color--all","name":"Color","title":"Foundation/Color","importPath":"./src/foundation/color.stories.tsx","tags":["dev","test","manifest"],"exportName":"All"},"foundation-typography--all":{"type":"story","subtype":"story","id":"foundation-typography--all","name":"Typography","title":"Foundation/Typography","importPath":"./src/foundation/typography.stories.tsx","tags":["dev","test","manifest"],"exportName":"All"},"foundation-layout--all":{"type":"story","subtype":"story","id":"foundation-layout--all","name":"Layout","title":"Foundation/Layout","importPath":"./src/foundation/layout.stories.tsx","tags":["dev","test","manifest"],"exportName":"All"},"components-form-button--all":{"type":"story","subtype":"story","id":"components-form-button--all","name":"Button","title":"Components/Form/Button","importPath":"./src/components/button.stories.tsx","componentPath":"./packages/ui/dist/index.js","tags":["dev","test","manifest"],"exportName":"All"},"components-form-button--roles":{"type":"story","subtype":"story","id":"components-form-button--roles","name":"Roles","title":"Components/Form/Button","importPath":"./src/components/button.stories.tsx","componentPath":"./packages/ui/dist/index.js","tags":["dev","test","manifest","verification"],"exportName":"Roles"},"components-form-button--sizes":{"type":"story","subtype":"story","id":"components-form-button--sizes","name":"Sizes","title":"Components/Form/Button","importPath":"./src/components/button.stories.tsx","componentPath":"./packages/ui/dist/index.js","tags":["dev","test","manifest","verification"],"exportName":"Sizes"},"components-form-button--states":{"type":"story","subtype":"story","id":"components-form-button--states","name":"Brand States","title":"Components/Form/Button","importPath":"./src/components/button.stories.tsx","componentPath":"./packages/ui/dist/index.js","tags":["dev","test","manifest","verification"],"exportName":"States"},"components-form-button--standard-states":{"type":"story","subtype":"story","id":"components-form-button--standard-states","name":"Standard States","title":"Components/Form/Button","importPath":"./src/components/button.stories.tsx","componentPath":"./packages/ui/dist/index.js","tags":["dev","test","manifest","verification"],"exportName":"StandardStates"},"components-form-button--long-label":{"type":"story","subtype":"story","id":"components-form-button--long-label","name":"Long Label","title":"Components/Form/Button","importPath":"./src/components/button.stories.tsx","componentPath":"./packages/ui/dist/index.js","tags":["dev","test","manifest","verification"],"exportName":"LongLabel"},"components-form-button--korean-labels":{"type":"story","subtype":"story","id":"components-form-button--korean-labels","name":"Korean Labels","title":"Components/Form/Button","importPath":"./src/components/button.stories.tsx","componentPath":"./packages/ui/dist/index.js","tags":["dev","test","manifest","verification"],"exportName":"KoreanLabels"},"components-form-button--icon-text-narrow":{"type":"story","subtype":"story","id":"components-form-button--icon-text-narrow","name":"Icon Text Narrow","title":"Components/Form/Button","importPath":"./src/components/button.stories.tsx","componentPath":"./packages/ui/dist/index.js","tags":["dev","test","manifest","verification"],"exportName":"IconTextNarrow"},"components-form-button--destructive":{"type":"story","subtype":"story","id":"components-form-button--destructive","name":"Destructive","title":"Components/Form/Button","importPath":"./src/components/button.stories.tsx","componentPath":"./packages/ui/dist/index.js","tags":["dev","test","manifest","verification"],"exportName":"Destructive"},"components-form-button--playground":{"type":"story","subtype":"story","id":"components-form-button--playground","name":"Playground","title":"Components/Form/Button","importPath":"./src/components/button.stories.tsx","componentPath":"./packages/ui/dist/index.js","tags":["dev","test","manifest","verification"],"exportName":"Playground"},"components-form-button--compatibility":{"type":"story","subtype":"story","id":"components-form-button--compatibility","name":"Compatibility","title":"Components/Form/Button","importPath":"./src/components/button.stories.tsx","componentPath":"./packages/ui/dist/index.js","tags":["dev","test","manifest","verification"],"exportName":"Compatibility"},"components-form-input--all":{"type":"story","subtype":"story","id":"components-form-input--all","name":"Input","title":"Components/Form/Input","importPath":"./src/components/input.stories.tsx","componentPath":"./packages/ui/dist/index.js","tags":["dev","test","manifest","play-fn"],"exportName":"All"},"components-form-input--default":{"type":"story","subtype":"story","id":"components-form-input--default","name":"Default","title":"Components/Form/Input","importPath":"./src/components/input.stories.tsx","componentPath":"./packages/ui/dist/index.js","tags":Line truncated
@@ -0,0 +1,230 @@
PASS 28 -> 24 SW Stories, exactly four approved Dropdown retirements
PASS Dropdown group has only Composed Controls with original ID
PASS all non-SW index entries identical
PASS all retained declarations identical outside imports, meta and ComposedDemo
PASS runtime, API, AI template, Overview, existing CSS/assets and Storybook configuration untouched
PASS render sw-header--detail-buttons
PASS render sw-header--overview
PASS render sw-header--interactive-states
PASS render sw-header--window-move-motion
PASS render sw-header--logo-slot
PASS render sw-header--document-dropdown
PASS render sw-header--responsive-more
PASS render sw-header--layer-detail-input
PASS render sw-header--property-panel
PASS render sw-header--property-panel-variants
PASS render sw-header--k-guide
PASS render sw-header--additional-hover
PASS render sw-header--property-bar
PASS render sw-header--dynamic-controls
PASS render sw-header--colorize
PASS render sw-header--composition
PASS render sw-header--property-panel-none
PASS render sw-header--property-panel-all
PASS render sw-header--property-panel-circle
PASS render sw-header--property-panel-expanded
PASS render sw-header--property-panel-compare
PASS render sw-header--property-shape-slot
PASS render sw-header--property-fields
PASS render sw-header--composed-controls
PASS one copy of five Dropdown fields and the details group
PASS composition wraps without page overflow or scaling at 390
PASS 레이어 Hover does not open at 390
PASS 레이어 overlay in viewport, not clipped or covered at 390
PASS 레이어 selected and expanded at 390
PASS 레이어 Escape closes and restores focus at 390
PASS 레이어 trigger toggles closed at 390
PASS 레이어 outside click closes at 390
PASS 색상 Hover does not open at 390
PASS 색상 overlay in viewport, not clipped or covered at 390
PASS 색상 selected and expanded at 390
PASS 색상 Escape closes and restores focus at 390
PASS 색상 trigger toggles closed at 390
PASS 색상 outside click closes at 390
PASS 선스타일 Hover does not open at 390
PASS 선스타일 overlay in viewport, not clipped or covered at 390
PASS 선스타일 selected and expanded at 390
PASS 선스타일 Escape closes and restores focus at 390
PASS 선스타일 trigger toggles closed at 390
PASS 선스타일 outside click closes at 390
PASS 문자스타일 Hover does not open at 390
PASS 문자스타일 overlay in viewport, not clipped or covered at 390
PASS 문자스타일 selected and expanded at 390
PASS 문자스타일 Escape closes and restores focus at 390
PASS 문자스타일 trigger toggles closed at 390
PASS 문자스타일 outside click closes at 390
PASS 치수스타일 Hover does not open at 390
PASS 치수스타일 overlay in viewport, not clipped or covered at 390
PASS 치수스타일 selected and expanded at 390
PASS 치수스타일 Escape closes and restores focus at 390
PASS 치수스타일 trigger toggles closed at 390
PASS 치수스타일 outside click closes at 390
PASS composition wraps without page overflow or scaling at 768
PASS 레이어 Hover does not open at 768
PASS 레이어 overlay in viewport, not clipped or covered at 768
PASS 레이어 selected and expanded at 768
PASS 레이어 Escape closes and restores focus at 768
PASS 레이어 trigger toggles closed at 768
PASS 레이어 outside click closes at 768
PASS 색상 Hover does not open at 768
PASS 색상 overlay in viewport, not clipped or covered at 768
PASS 색상 selected and expanded at 768
PASS 색상 Escape closes and restores focus at 768
PASS 색상 trigger toggles closed at 768
PASS 색상 outside click closes at 768
PASS 선스타일 Hover does not open at 768
PASS 선스타일 overlay in viewport, not clipped or covered at 768
PASS 선스타일 selected and expanded at 768
PASS 선스타일 Escape closes and restores focus at 768
PASS 선스타일 trigger toggles closed at 768
PASS 선스타일 outside click closes at 768
PASS 문자스타일 Hover does not open at 768
PASS 문자스타일 overlay in viewport, not clipped or covered at 768
PASS 문자스타일 selected and expanded at 768
PASS 문자스타일 Escape closes and restores focus at 768
PASS 문자스타일 trigger toggles closed at 768
PASS 문자스타일 outside click closes at 768
PASS 치수스타일 Hover does not open at 768
PASS 치수스타일 overlay in viewport, not clipped or covered at 768
PASS 치수스타일 selected and expanded at 768
PASS 치수스타일 Escape closes and restores focus at 768
PASS 치수스타일 trigger toggles closed at 768
PASS 치수스타일 outside click closes at 768
PASS composition wraps without page overflow or scaling at 1280
PASS 레이어 Hover does not open at 1280
PASS 레이어 overlay in viewport, not clipped or covered at 1280
PASS 레이어 selected and expanded at 1280
PASS 레이어 Escape closes and restores focus at 1280
PASS 레이어 trigger toggles closed at 1280
PASS 레이어 outside click closes at 1280
PASS 색상 Hover does not open at 1280
PASS 색상 overlay in viewport, not clipped or covered at 1280
PASS 색상 selected and expanded at 1280
PASS 색상 Escape closes and restores focus at 1280
PASS 색상 trigger toggles closed at 1280
PASS 색상 outside click closes at 1280
PASS 선스타일 Hover does not open at 1280
PASS 선스타일 overlay in viewport, not clipped or covered at 1280
PASS 선스타일 selected and expanded at 1280
PASS 선스타일 Escape closes and restores focus at 1280
PASS 선스타일 trigger toggles closed at 1280
PASS 선스타일 outside click closes at 1280
PASS 문자스타일 Hover does not open at 1280
PASS 문자스타일 overlay in viewport, not clipped or covered at 1280
PASS 문자스타일 selected and expanded at 1280
PASS 문자스타일 Escape closes and restores focus at 1280
PASS 문자스타일 trigger toggles closed at 1280
PASS 문자스타일 outside click closes at 1280
PASS 치수스타일 Hover does not open at 1280
PASS 치수스타일 overlay in viewport, not clipped or covered at 1280
PASS 치수스타일 selected and expanded at 1280
PASS 치수스타일 Escape closes and restores focus at 1280
PASS 치수스타일 trigger toggles closed at 1280
PASS 치수스타일 outside click closes at 1280
PASS composition wraps without page overflow or scaling at 1440
PASS 레이어 Hover does not open at 1440
PASS 레이어 overlay in viewport, not clipped or covered at 1440
PASS 레이어 selected and expanded at 1440
PASS 레이어 Escape closes and restores focus at 1440
PASS 레이어 trigger toggles closed at 1440
PASS 레이어 outside click closes at 1440
PASS 색상 Hover does not open at 1440
PASS 색상 overlay in viewport, not clipped or covered at 1440
PASS 색상 selected and expanded at 1440
PASS 색상 Escape closes and restores focus at 1440
PASS 색상 trigger toggles closed at 1440
PASS 색상 outside click closes at 1440
PASS 선스타일 Hover does not open at 1440
PASS 선스타일 overlay in viewport, not clipped or covered at 1440
PASS 선스타일 selected and expanded at 1440
PASS 선스타일 Escape closes and restores focus at 1440
PASS 선스타일 trigger toggles closed at 1440
PASS 선스타일 outside click closes at 1440
PASS 문자스타일 Hover does not open at 1440
PASS 문자스타일 overlay in viewport, not clipped or covered at 1440
PASS 문자스타일 selected and expanded at 1440
PASS 문자스타일 Escape closes and restores focus at 1440
PASS 문자스타일 trigger toggles closed at 1440
PASS 문자스타일 outside click closes at 1440
PASS 치수스타일 Hover does not open at 1440
PASS 치수스타일 overlay in viewport, not clipped or covered at 1440
PASS 치수스타일 selected and expanded at 1440
PASS 치수스타일 Escape closes and restores focus at 1440
PASS 치수스타일 trigger toggles closed at 1440
PASS 치수스타일 outside click closes at 1440
PASS keyboard opens layer menu and focuses current row
PASS keyboard moves to next layer row
PASS onLayerSelect callback exactly once
PASS layer selection appears, closes and restores focus
PASS selected layer retains original row Hover background
PASS onLayerVisibilityChange callback exactly once
PASS onLayerVisibilityChange toggles only its own state, menu remains open
PASS onLayerFreezeChange callback exactly once
PASS onLayerFreezeChange toggles only its own state, menu remains open
PASS onLayerLockChange callback exactly once
PASS onLayerLockChange toggles only its own state, menu remains open
PASS disabled layer selection and toggles blocked
PASS full color menu: seven palette chips, two user colors, modes, RGB and pick
PASS onColorSelect callback exactly once
PASS color palette updates displayed RGB and leaves menu open
PASS onColorModeChange callback exactly once
PASS ByBlock On and displayed mode
PASS onColorInput callback exactly once
PASS RGB commit clears mode and updates chip
PASS invalid RGB restores without callback
PASS onColorPick callback exactly once
PASS color pick closes and restores focus
PASS color changes leave layer, line, text and dimension values intact
PASS all original line rows and weights retained
PASS onLineTypeSelect callback exactly once
PASS selected line retains original row Hover and preview
PASS onLineWeightSelect callback exactly once
PASS onLineWeightValueChange callback exactly once
PASS onLineScaleChange callback exactly once
PASS line type, editable weight and scale update independently; menu stays open
PASS invalid scale restores, no callback
PASS 문자스타일 full two-item list retained
PASS onTextStyleSelect callback exactly once
PASS 문자스타일 selection displayed, closes, focus returns
PASS 치수스타일 full two-item list retained
PASS onDimensionStyleSelect callback exactly once
PASS 치수스타일 selection displayed, closes, focus returns
PASS 레이어 detail Hover uses existing text opacity
PASS onLayerDetail callback exactly once
PASS 레이어 detail closes, focus returns, no fabricated popup
PASS 색상 detail Hover uses existing text opacity
PASS onColorDetail callback exactly once
PASS 색상 detail closes, focus returns, no fabricated popup
PASS 선스타일 detail Hover uses existing text opacity
PASS onLineStyleDetail callback exactly once
PASS 선스타일 detail closes, focus returns, no fabricated popup
PASS 문자스타일 detail Hover uses existing text opacity
PASS onTextStyleDetail callback exactly once
PASS 문자스타일 detail closes, focus returns, no fabricated popup
PASS 치수스타일 detail Hover uses existing text opacity
PASS onDimensionStyleDetail callback exactly once
PASS 치수스타일 detail closes, focus returns, no fabricated popup
PASS opening another control leaves exactly one menu and preserves selection
PASS keyboard Tab enters the open color controls
PASS details opens existing 28px property Bar
PASS details opens existing 314px property panel with focus
PASS property Bar and panel share edited state
PASS property panel close returns focus
PASS property panel Escape returns focus
PASS narrow details panel keeps natural width and fits viewport
PASS all seven actionable controls Disabled
PASS Disabled controls block callbacks and overlays
PASS callback-free layer icons become readonly status images
PASS missing detail callback keeps safe no-op and menu open
PASS retained long layer scenario
PASS long layer name preserved with full title
PASS retained many layer scenario
PASS long layer list scrolls internally
PASS all 40 user colors accessible with palette scroll
PASS retained empty layer scenario
PASS Overview keeps one Header at 49px and 16:9 Stage
PASS Window Move Motion retains only nine 3x steps
PASS manager shows Dropdown group with the single Composed Controls page
PASS retired Dropdown links absent in manager
PASS no browser console or page errors
{"status":"PASS","checks":229,"errors":[]}
@@ -0,0 +1,30 @@
PASS 28 -> 24 SW Stories, exactly four approved Dropdown retirements
PASS Dropdown group has only Composed Controls with original ID
PASS all non-SW index entries identical
PASS all retained declarations identical outside imports, meta and ComposedDemo
PASS runtime, API, AI template, Overview, existing CSS/assets and Storybook configuration untouched
PASS User line weight still updates displayed numeric value
PASS weight mode label preserves the shared numeric value
PASS details opens existing 28px property Bar
PASS details opens existing 314px property panel with focus
PASS property Bar and panel share edited state
PASS property panel weight edit appears in composed line field
PASS property panel close returns focus
PASS property panel Escape returns focus
PASS narrow details panel keeps natural width and fits viewport
PASS all seven actionable controls Disabled
PASS Disabled controls block callbacks and overlays
PASS callback-free layer icons become readonly status images
PASS missing detail callback keeps safe no-op and menu open
PASS retained long layer scenario
PASS long layer name preserved with full title
PASS retained many layer scenario
PASS long layer list scrolls internally
PASS all 40 user colors accessible with palette scroll
PASS retained empty layer scenario
PASS Overview keeps one Header at 49px and 16:9 Stage
PASS Window Move Motion retains only nine 3x steps
PASS manager shows Dropdown group with the single Composed Controls page
PASS retired Dropdown links absent in manager
PASS no browser console or page errors
{"status":"PASS","checks":29,"errors":[]}
@@ -0,0 +1,216 @@
PASS 28 -> 24 SW Stories, exactly four approved Dropdown retirements
PASS Dropdown group has only Composed Controls with original ID
PASS all non-SW index entries identical
PASS all retained declarations identical outside imports, meta and ComposedDemo
PASS runtime, API, AI template, Overview, existing CSS/assets and Storybook configuration untouched
PASS render sw-header--detail-buttons
PASS render sw-header--overview
PASS render sw-header--interactive-states
PASS render sw-header--window-move-motion
PASS render sw-header--logo-slot
PASS render sw-header--document-dropdown
PASS render sw-header--responsive-more
PASS render sw-header--layer-detail-input
PASS render sw-header--property-panel
PASS render sw-header--property-panel-variants
PASS render sw-header--k-guide
PASS render sw-header--additional-hover
PASS render sw-header--property-bar
PASS render sw-header--dynamic-controls
PASS render sw-header--colorize
PASS render sw-header--composition
PASS render sw-header--property-panel-none
PASS render sw-header--property-panel-all
PASS render sw-header--property-panel-circle
PASS render sw-header--property-panel-expanded
PASS render sw-header--property-panel-compare
PASS render sw-header--property-shape-slot
PASS render sw-header--property-fields
PASS render sw-header--composed-controls
PASS one copy of five Dropdown fields and the details group
PASS composition wraps without page overflow or scaling at 390
PASS 레이어 Hover does not open at 390
PASS 레이어 overlay in viewport, not clipped or covered at 390
PASS 레이어 selected and expanded at 390
PASS 레이어 Escape closes and restores focus at 390
PASS 레이어 trigger toggles closed at 390
PASS 레이어 outside click closes at 390
PASS 색상 Hover does not open at 390
PASS 색상 overlay in viewport, not clipped or covered at 390
PASS 색상 selected and expanded at 390
PASS 색상 Escape closes and restores focus at 390
PASS 색상 trigger toggles closed at 390
PASS 색상 outside click closes at 390
PASS 선스타일 Hover does not open at 390
PASS 선스타일 overlay in viewport, not clipped or covered at 390
PASS 선스타일 selected and expanded at 390
PASS 선스타일 Escape closes and restores focus at 390
PASS 선스타일 trigger toggles closed at 390
PASS 선스타일 outside click closes at 390
PASS 문자스타일 Hover does not open at 390
PASS 문자스타일 overlay in viewport, not clipped or covered at 390
PASS 문자스타일 selected and expanded at 390
PASS 문자스타일 Escape closes and restores focus at 390
PASS 문자스타일 trigger toggles closed at 390
PASS 문자스타일 outside click closes at 390
PASS 치수스타일 Hover does not open at 390
PASS 치수스타일 overlay in viewport, not clipped or covered at 390
PASS 치수스타일 selected and expanded at 390
PASS 치수스타일 Escape closes and restores focus at 390
PASS 치수스타일 trigger toggles closed at 390
PASS 치수스타일 outside click closes at 390
PASS composition wraps without page overflow or scaling at 768
PASS 레이어 Hover does not open at 768
PASS 레이어 overlay in viewport, not clipped or covered at 768
PASS 레이어 selected and expanded at 768
PASS 레이어 Escape closes and restores focus at 768
PASS 레이어 trigger toggles closed at 768
PASS 레이어 outside click closes at 768
PASS 색상 Hover does not open at 768
PASS 색상 overlay in viewport, not clipped or covered at 768
PASS 색상 selected and expanded at 768
PASS 색상 Escape closes and restores focus at 768
PASS 색상 trigger toggles closed at 768
PASS 색상 outside click closes at 768
PASS 선스타일 Hover does not open at 768
PASS 선스타일 overlay in viewport, not clipped or covered at 768
PASS 선스타일 selected and expanded at 768
PASS 선스타일 Escape closes and restores focus at 768
PASS 선스타일 trigger toggles closed at 768
PASS 선스타일 outside click closes at 768
PASS 문자스타일 Hover does not open at 768
PASS 문자스타일 overlay in viewport, not clipped or covered at 768
PASS 문자스타일 selected and expanded at 768
PASS 문자스타일 Escape closes and restores focus at 768
PASS 문자스타일 trigger toggles closed at 768
PASS 문자스타일 outside click closes at 768
PASS 치수스타일 Hover does not open at 768
PASS 치수스타일 overlay in viewport, not clipped or covered at 768
PASS 치수스타일 selected and expanded at 768
PASS 치수스타일 Escape closes and restores focus at 768
PASS 치수스타일 trigger toggles closed at 768
PASS 치수스타일 outside click closes at 768
PASS composition wraps without page overflow or scaling at 1280
PASS 레이어 Hover does not open at 1280
PASS 레이어 overlay in viewport, not clipped or covered at 1280
PASS 레이어 selected and expanded at 1280
PASS 레이어 Escape closes and restores focus at 1280
PASS 레이어 trigger toggles closed at 1280
PASS 레이어 outside click closes at 1280
PASS 색상 Hover does not open at 1280
PASS 색상 overlay in viewport, not clipped or covered at 1280
PASS 색상 selected and expanded at 1280
PASS 색상 Escape closes and restores focus at 1280
PASS 색상 trigger toggles closed at 1280
PASS 색상 outside click closes at 1280
PASS 선스타일 Hover does not open at 1280
PASS 선스타일 overlay in viewport, not clipped or covered at 1280
PASS 선스타일 selected and expanded at 1280
PASS 선스타일 Escape closes and restores focus at 1280
PASS 선스타일 trigger toggles closed at 1280
PASS 선스타일 outside click closes at 1280
PASS 문자스타일 Hover does not open at 1280
PASS 문자스타일 overlay in viewport, not clipped or covered at 1280
PASS 문자스타일 selected and expanded at 1280
PASS 문자스타일 Escape closes and restores focus at 1280
PASS 문자스타일 trigger toggles closed at 1280
PASS 문자스타일 outside click closes at 1280
PASS 치수스타일 Hover does not open at 1280
PASS 치수스타일 overlay in viewport, not clipped or covered at 1280
PASS 치수스타일 selected and expanded at 1280
PASS 치수스타일 Escape closes and restores focus at 1280
PASS 치수스타일 trigger toggles closed at 1280
PASS 치수스타일 outside click closes at 1280
PASS composition wraps without page overflow or scaling at 1440
PASS 레이어 Hover does not open at 1440
PASS 레이어 overlay in viewport, not clipped or covered at 1440
PASS 레이어 selected and expanded at 1440
PASS 레이어 Escape closes and restores focus at 1440
PASS 레이어 trigger toggles closed at 1440
PASS 레이어 outside click closes at 1440
PASS 색상 Hover does not open at 1440
PASS 색상 overlay in viewport, not clipped or covered at 1440
PASS 색상 selected and expanded at 1440
PASS 색상 Escape closes and restores focus at 1440
PASS 색상 trigger toggles closed at 1440
PASS 색상 outside click closes at 1440
PASS 선스타일 Hover does not open at 1440
PASS 선스타일 overlay in viewport, not clipped or covered at 1440
PASS 선스타일 selected and expanded at 1440
PASS 선스타일 Escape closes and restores focus at 1440
PASS 선스타일 trigger toggles closed at 1440
PASS 선스타일 outside click closes at 1440
PASS 문자스타일 Hover does not open at 1440
PASS 문자스타일 overlay in viewport, not clipped or covered at 1440
PASS 문자스타일 selected and expanded at 1440
PASS 문자스타일 Escape closes and restores focus at 1440
PASS 문자스타일 trigger toggles closed at 1440
PASS 문자스타일 outside click closes at 1440
PASS 치수스타일 Hover does not open at 1440
PASS 치수스타일 overlay in viewport, not clipped or covered at 1440
PASS 치수스타일 selected and expanded at 1440
PASS 치수스타일 Escape closes and restores focus at 1440
PASS 치수스타일 trigger toggles closed at 1440
PASS 치수스타일 outside click closes at 1440
PASS keyboard opens layer menu and focuses current row
PASS keyboard moves to next layer row
PASS onLayerSelect callback exactly once
PASS layer selection appears, closes and restores focus
PASS onLayerVisibilityChange callback exactly once
PASS onLayerVisibilityChange toggles only its own state, menu remains open
PASS onLayerFreezeChange callback exactly once
PASS onLayerFreezeChange toggles only its own state, menu remains open
PASS onLayerLockChange callback exactly once
PASS onLayerLockChange toggles only its own state, menu remains open
PASS disabled layer selection and toggles blocked
PASS full color menu: seven palette chips, two user colors, modes, RGB and pick
PASS onColorSelect callback exactly once
PASS color palette updates displayed RGB and leaves menu open
PASS onColorModeChange callback exactly once
PASS ByBlock On and displayed mode
PASS onColorInput callback exactly once
PASS RGB commit clears mode and updates chip
PASS invalid RGB restores without callback
PASS onColorPick callback exactly once
PASS color pick closes and restores focus
PASS color changes leave layer, line, text and dimension values intact
PASS all original line rows and weights retained
PASS onLineTypeSelect callback exactly once
PASS onLineWeightSelect callback exactly once
PASS onLineWeightValueChange callback exactly once
PASS onLineScaleChange callback exactly once
PASS line type, editable weight and scale update independently; menu stays open
PASS invalid scale restores, no callback
PASS 문자스타일 full two-item list retained
PASS onTextStyleSelect callback exactly once
PASS 문자스타일 selection displayed, closes, focus returns
PASS 치수스타일 full two-item list retained
PASS onDimensionStyleSelect callback exactly once
PASS 치수스타일 selection displayed, closes, focus returns
PASS 레이어 detail Hover uses existing text opacity
PASS onLayerDetail callback exactly once
PASS 레이어 detail closes, focus returns, no fabricated popup
PASS 색상 detail Hover uses existing text opacity
PASS onColorDetail callback exactly once
PASS 색상 detail closes, focus returns, no fabricated popup
PASS 선스타일 detail Hover uses existing text opacity
PASS onLineStyleDetail callback exactly once
PASS 선스타일 detail closes, focus returns, no fabricated popup
PASS 문자스타일 detail Hover uses existing text opacity
PASS onTextStyleDetail callback exactly once
PASS 문자스타일 detail closes, focus returns, no fabricated popup
PASS 치수스타일 detail Hover uses existing text opacity
PASS onDimensionStyleDetail callback exactly once
PASS 치수스타일 detail closes, focus returns, no fabricated popup
PASS opening another control leaves exactly one menu and preserves selection
PASS keyboard Tab enters the open color controls
PASS details opens existing 28px property Bar
FAIL details opens existing 314px property panel with focus undefined
FAIL property Bar and panel share edited state undefined
PASS property panel close returns focus
PASS property panel Escape returns focus
PASS all seven actionable controls Disabled
FAIL callback-free layer icons become readonly status images undefined
PASS missing detail callback keeps safe no-op and menu open
FAIL suite completes "locator.selectOption: Timeout 6000ms exceeded.\nCall log:\n\u001b[2m - waiting for getByLabel('목록 데이터', { exact: true })\u001b[22m\n\n at D:\\디자인시스템\\HMDesign-SW\\packages\\sw\\tests\\dropdown-consolidation.browser.mjs:194:54"
{"status":"FAIL","checks":215,"errors":[]}
@@ -0,0 +1,25 @@
PASS 28 -> 24 SW Stories, exactly four approved Dropdown retirements
PASS Dropdown group has only Composed Controls with original ID
PASS all non-SW index entries identical
PASS all retained declarations identical outside imports, meta and ComposedDemo
PASS runtime, API, AI template, Overview, existing CSS/assets and Storybook configuration untouched
PASS details opens existing 28px property Bar
FAIL details opens existing 314px property panel with focus {"width":314,"focused":false,"active":"<button type=\"button\" class=\"hm-sw-header__toggle\" data-property-panel-trigger=\"\" aria-pressed=\"true\" aria-haspopup=\"dialog\" aria-expanded=\"true\" aria-controls=\"_r_0_\" data-selected=\"true\">속성창</button>"}
FAIL property Bar and panel share edited state "4.0526"
PASS property panel close returns focus
PASS property panel Escape returns focus
PASS all seven actionable controls Disabled
PASS callback-free layer icons become readonly status images
PASS missing detail callback keeps safe no-op and menu open
PASS retained long layer scenario
PASS long layer name preserved with full title
PASS retained many layer scenario
PASS long layer list scrolls internally
PASS all 40 user colors accessible with palette scroll
PASS retained empty layer scenario
PASS Overview keeps one Header at 49px and 16:9 Stage
PASS Window Move Motion retains only nine 3x steps
PASS manager shows Dropdown group with the single Composed Controls page
PASS retired Dropdown links absent in manager
PASS no browser console or page errors
{"status":"FAIL","checks":24,"errors":[]}
@@ -0,0 +1,7 @@
PASS 28 -> 24 SW Stories, exactly four approved Dropdown retirements
PASS Dropdown group has only Composed Controls with original ID
PASS all non-SW index entries identical
PASS all retained declarations identical outside imports, meta and ComposedDemo
PASS runtime, API, AI template, Overview, existing CSS/assets and Storybook configuration untouched
FAIL suite completes "page.goto: net::ERR_NETWORK_ACCESS_DENIED at http://127.0.0.1:13170/iframe.html?id=sw-header--detail-buttons&viewMode=story\nCall log:\n\u001b[2m - navigating to \"http://127.0.0.1:13170/iframe.html?id=sw-header--detail-buttons&viewMode=story\", waiting until \"load\"\u001b[22m\n\n at go (D:\\디자인시스템\\HMDesign-SW\\packages\\sw\\tests\\dropdown-consolidation.browser.mjs:59:16)\n at D:\\디자인시스템\\HMDesign-SW\\packages\\sw\\tests\\dropdown-consolidation.browser.mjs:65:11"
{"status":"FAIL","checks":6,"errors":[]}
File diff suppressed because it is too large. Load diff
Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

File diff suppressed because it is too large. Load diff
@@ -0,0 +1,849 @@
{
"before": [
{
"type": "story",
"subtype": "story",
"id": "sw-header--detail-buttons",
"name": "Detail Buttons (Shared States)",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest",
"verification"
],
"exportName": "DetailButtons"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--overview",
"name": "Overview",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "Overview"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--interactive-states",
"name": "Interactive States",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "InteractiveStates"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--window-move-motion",
"name": "Window Move Motion",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "WindowMoveMotion"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--composed-controls",
"name": "Composed Controls",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "ComposedControls"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--logo-slot",
"name": "Logo Slot",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "LogoSlot"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--document-dropdown",
"name": "Document Dropdown",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "DocumentDropdown"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--layer-dropdown",
"name": "Layer Dropdown",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "LayerDropdown"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--color-dropdown",
"name": "Color Dropdown",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "ColorDropdown"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--line-style-dropdown",
"name": "Line Style Dropdown",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "LineStyleDropdown"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--text-dimension-style-dropdown",
"name": "Text · Dimension Style Dropdown",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "TextDimensionStyleDropdown"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--responsive-more",
"name": "Responsive More",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "ResponsiveMore"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--layer-detail-input",
"name": "Layer Detail · Input",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "LayerDetailInput"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel",
"name": "Property Panel",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanel"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-variants",
"name": "Property Panel Variants",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelVariants"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--k-guide",
"name": "K Guide",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "KGuide"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--additional-hover",
"name": "Additional Hover",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "AdditionalHover"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-bar",
"name": "Property Bar",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyBar"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--dynamic-controls",
"name": "Dynamic Controls",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "DynamicControls"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--colorize",
"name": "Colorize",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "Colorize"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--composition",
"name": "Composition (Visibility · Order)",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "Composition"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-none",
"name": "Property Panel · 선택 없음",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelNone"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-all",
"name": "Property Panel · 전체 선택",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelAll"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-circle",
"name": "Property Panel · 원 1개",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelCircle"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-expanded",
"name": "Property Panel · 모두 펼침",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelExpanded"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-compare",
"name": "Property Panel · 4개 비교",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelCompare"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-shape-slot",
"name": "Property Panel · 형상 Slot",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyShapeSlot"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-fields",
"name": "Property Panel · 필드 13개",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyFields"
}
],
"after": [
{
"type": "story",
"subtype": "story",
"id": "sw-header--detail-buttons",
"name": "Detail Buttons (Shared States)",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest",
"verification"
],
"exportName": "DetailButtons"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--overview",
"name": "Overview",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "Overview"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--interactive-states",
"name": "Interactive States",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "InteractiveStates"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--window-move-motion",
"name": "Window Move Motion",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "WindowMoveMotion"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--logo-slot",
"name": "Logo Slot",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "LogoSlot"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--document-dropdown",
"name": "Document Dropdown",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "DocumentDropdown"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--responsive-more",
"name": "Responsive More",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "ResponsiveMore"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--layer-detail-input",
"name": "Layer Detail · Input",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "LayerDetailInput"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel",
"name": "Property Panel",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanel"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-variants",
"name": "Property Panel Variants",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelVariants"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--k-guide",
"name": "K Guide",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "KGuide"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--additional-hover",
"name": "Additional Hover",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "AdditionalHover"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-bar",
"name": "Property Bar",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyBar"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--dynamic-controls",
"name": "Dynamic Controls",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "DynamicControls"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--colorize",
"name": "Colorize",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "Colorize"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--composition",
"name": "Composition (Visibility · Order)",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "Composition"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-none",
"name": "Property Panel · 선택 없음",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelNone"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-all",
"name": "Property Panel · 전체 선택",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelAll"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-circle",
"name": "Property Panel · 원 1개",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelCircle"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-expanded",
"name": "Property Panel · 모두 펼침",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelExpanded"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-compare",
"name": "Property Panel · 4개 비교",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelCompare"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-shape-slot",
"name": "Property Panel · 형상 Slot",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyShapeSlot"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-fields",
"name": "Property Panel · 필드 13개",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyFields"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--composed-controls",
"name": "Composed Controls",
"title": "SW/Header/Dropdown",
"importPath": "./src/sw/sw-header-dropdown.stories.tsx",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "ComposedControls"
}
],
"removed": [
{
"type": "story",
"subtype": "story",
"id": "sw-header--layer-dropdown",
"name": "Layer Dropdown",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "LayerDropdown"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--color-dropdown",
"name": "Color Dropdown",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "ColorDropdown"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--line-style-dropdown",
"name": "Line Style Dropdown",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "LineStyleDropdown"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--text-dimension-style-dropdown",
"name": "Text · Dimension Style Dropdown",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "TextDimensionStyleDropdown"
}
]
}
@@ -0,0 +1,55 @@
PASS 24 retained Story IDs, names and tags; only approved Dropdown retirements
PASS retained non-Overview declarations byte-identical; relocated composition separately verified
PASS retired Dropdown IDs absent
PASS package production source untouched
PASS 16:9 fitted to both Inner dimensions at 1920x1080
PASS 16:9 fitted to both Inner dimensions at 1440x900
PASS 16:9 fitted to both Inner dimensions at 1280x720
PASS 16:9 fitted to both Inner dimensions at 768x600
PASS 16:9 fitted to both Inner dimensions at 390x844
PASS 16:9 fitted to both Inner dimensions at 1000x500
PASS one Header and no duplicate fixed Figma specimen
PASS document selection updates Header and Callback
PASS layer selection updates shared data
PASS existing layer Detail callback closes list
PASS color selection invokes host callback
PASS line selection updates Header
PASS ByLayer weight mode does not turn numeric property into a mode string
PASS text style selection updates Header
PASS dimension style selection updates Header
PASS opening another dropdown closes the previous one
PASS Escape closes Header dropdown
PASS outside click closes Header dropdown
PASS Bar Enter commits state
PASS Bar validates min=0
PASS Bar Escape cancels edit
PASS Header opens panel with same Bar value
PASS numeric weight property remains numeric after ByLayer mode
PASS Header layer value shared with panel
PASS panel edit updates the Bar
PASS panel number validation rejects negative radius
PASS panel Layer dropdown updates Header shared value
PASS panel line dropdown updates Header shared value
PASS panel color dropdown updates Header shared value
PASS panel RGB validation rejects out-of-range value
PASS gauge keyboard editing commits host state
PASS first Escape cancels draft and retains panel
PASS next Escape closes panel and restores Header focus
PASS panel Close button restores focus
PASS external Props update Bar
PASS Bar ReadOnly
PASS Bar Disabled
PASS dynamic Bar field added
PASS dynamic field shared with panel
PASS dynamic field removed from both
PASS shape Slot can be empty without changing panel structure
PASS original panel size none:314x256
PASS original panel size all:314x361
PASS original panel size circle:314x658
PASS original panel size expanded:314x754
PASS expanded popup bottom accessible through internal scroll
PASS small Inner reaches full popup bottom with native Header and popup dimensions
PASS narrow popup Escape restores More focus
PASS actual Storybook manager iframe fits its own Inner
PASS no browser errors
{"status":"PASS","checks":54,"failures":[]}
@@ -0,0 +1,362 @@
[
{
"type": "story",
"subtype": "story",
"id": "sw-header--detail-buttons",
"name": "Detail Buttons (Shared States)",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest",
"verification"
],
"exportName": "DetailButtons"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--overview",
"name": "Overview",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "Overview"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--interactive-states",
"name": "Interactive States",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "InteractiveStates"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--window-move-motion",
"name": "Window Move Motion",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "WindowMoveMotion"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--logo-slot",
"name": "Logo Slot",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "LogoSlot"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--document-dropdown",
"name": "Document Dropdown",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "DocumentDropdown"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--responsive-more",
"name": "Responsive More",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "ResponsiveMore"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--layer-detail-input",
"name": "Layer Detail · Input",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "LayerDetailInput"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel",
"name": "Property Panel",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanel"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-variants",
"name": "Property Panel Variants",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelVariants"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--k-guide",
"name": "K Guide",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "KGuide"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--additional-hover",
"name": "Additional Hover",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "AdditionalHover"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-bar",
"name": "Property Bar",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyBar"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--dynamic-controls",
"name": "Dynamic Controls",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "DynamicControls"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--colorize",
"name": "Colorize",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "Colorize"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--composition",
"name": "Composition (Visibility · Order)",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "Composition"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-none",
"name": "Property Panel · 선택 없음",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelNone"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-all",
"name": "Property Panel · 전체 선택",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelAll"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-circle",
"name": "Property Panel · 원 1개",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelCircle"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-expanded",
"name": "Property Panel · 모두 펼침",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelExpanded"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-compare",
"name": "Property Panel · 4개 비교",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelCompare"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-shape-slot",
"name": "Property Panel · 형상 Slot",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyShapeSlot"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-fields",
"name": "Property Panel · 필드 13개",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyFields"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--composed-controls",
"name": "Composed Controls",
"title": "SW/Header/Dropdown",
"importPath": "./src/sw/sw-header-dropdown.stories.tsx",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "ComposedControls"
}
]
@@ -0,0 +1,423 @@
[
{
"type": "story",
"subtype": "story",
"id": "sw-header--detail-buttons",
"name": "Detail Buttons (Shared States)",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest",
"verification"
],
"exportName": "DetailButtons"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--overview",
"name": "Overview",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "Overview"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--interactive-states",
"name": "Interactive States",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "InteractiveStates"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--window-move-motion",
"name": "Window Move Motion",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "WindowMoveMotion"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--composed-controls",
"name": "Composed Controls",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "ComposedControls"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--logo-slot",
"name": "Logo Slot",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "LogoSlot"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--document-dropdown",
"name": "Document Dropdown",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "DocumentDropdown"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--layer-dropdown",
"name": "Layer Dropdown",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "LayerDropdown"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--color-dropdown",
"name": "Color Dropdown",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "ColorDropdown"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--line-style-dropdown",
"name": "Line Style Dropdown",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "LineStyleDropdown"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--text-dimension-style-dropdown",
"name": "Text · Dimension Style Dropdown",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "TextDimensionStyleDropdown"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--responsive-more",
"name": "Responsive More",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "ResponsiveMore"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--layer-detail-input",
"name": "Layer Detail · Input",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "LayerDetailInput"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel",
"name": "Property Panel",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanel"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-variants",
"name": "Property Panel Variants",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelVariants"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--k-guide",
"name": "K Guide",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "KGuide"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--additional-hover",
"name": "Additional Hover",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "AdditionalHover"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-bar",
"name": "Property Bar",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyBar"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--dynamic-controls",
"name": "Dynamic Controls",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "DynamicControls"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--colorize",
"name": "Colorize",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "Colorize"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--composition",
"name": "Composition (Visibility · Order)",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "Composition"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-none",
"name": "Property Panel · 선택 없음",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelNone"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-all",
"name": "Property Panel · 전체 선택",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelAll"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-circle",
"name": "Property Panel · 원 1개",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelCircle"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-expanded",
"name": "Property Panel · 모두 펼침",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelExpanded"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-compare",
"name": "Property Panel · 4개 비교",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelCompare"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-shape-slot",
"name": "Property Panel · 형상 Slot",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyShapeSlot"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-fields",
"name": "Property Panel · 필드 13개",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyFields"
}
]
@@ -0,0 +1,669 @@
{
"baseCommit": "50bf5bda8e956a4973b923d64131f2f2285bd38c",
"checks": [
{
"name": "24 retained Story IDs, names and tags; only approved Dropdown retirements",
"status": "PASS"
},
{
"name": "retained non-Overview declarations byte-identical; relocated composition separately verified",
"status": "PASS"
},
{
"name": "retired Dropdown IDs absent",
"status": "PASS"
},
{
"name": "package production source untouched",
"status": "PASS"
},
{
"name": "16:9 fitted to both Inner dimensions at 1920x1080",
"status": "PASS",
"data": {
"stage": {
"x": 360,
"y": 264.25,
"w": 1200,
"h": 675,
"right": 1560,
"bottom": 939.25
},
"slot": {
"x": 360,
"y": 169.5,
"w": 1200,
"h": 864.5,
"right": 1560,
"bottom": 1034
},
"header": {
"x": 360,
"y": 264.25,
"w": 1200,
"h": 49,
"right": 1560,
"bottom": 313.25
},
"viewport": {
"w": 1920,
"h": 1080
},
"overflow": 0
}
},
{
"name": "16:9 fitted to both Inner dimensions at 1440x900",
"status": "PASS",
"data": {
"stage": {
"x": 120,
"y": 174.25,
"w": 1200,
"h": 675,
"right": 1320,
"bottom": 849.25
},
"slot": {
"x": 120,
"y": 169.5,
"w": 1200,
"h": 684.5,
"right": 1320,
"bottom": 854
},
"header": {
"x": 120,
"y": 174.25,
"w": 1200,
"h": 49,
"right": 1320,
"bottom": 223.25
},
"viewport": {
"w": 1440,
"h": 900
},
"overflow": 0
}
},
{
"name": "16:9 fitted to both Inner dimensions at 1280x720",
"status": "PASS",
"data": {
"stage": {
"x": 191.5625,
"y": 169.5,
"w": 896.875,
"h": 504.5,
"right": 1088.4375,
"bottom": 674
},
"slot": {
"x": 38.40625,
"y": 169.5,
"w": 1203.1875,
"h": 504.5,
"right": 1241.59375,
"bottom": 674
},
"header": {
"x": 191.5625,
"y": 169.5,
"w": 896.875,
"h": 49,
"right": 1088.4375,
"bottom": 218.5
},
"viewport": {
"w": 1280,
"h": 720
},
"overflow": 0
}
},
{
"name": "16:9 fitted to both Inner dimensions at 768x600",
"status": "PASS",
"data": {
"stage": {
"x": 42.21875,
"y": 169.5,
"w": 683.546875,
"h": 384.5,
"right": 725.765625,
"bottom": 554
},
"slot": {
"x": 23.046875,
"y": 169.5,
"w": 721.90625,
"h": 384.5,
"right": 744.953125,
"bottom": 554
},
"header": {
"x": 42.21875,
"y": 169.5,
"w": 683.546875,
"h": 49,
"right": 725.765625,
"bottom": 218.5
},
"viewport": {
"w": 768,
"h": 600
},
"overflow": 0
}
},
{
"name": "16:9 fitted to both Inner dimensions at 390x844",
"status": "PASS",
"data": {
"stage": {
"x": 16,
"y": 383.0625,
"w": 358,
"h": 201.375,
"right": 374,
"bottom": 584.4375
},
"slot": {
"x": 16,
"y": 169.5,
"w": 358,
"h": 628.5,
"right": 374,
"bottom": 798
},
"header": {
"x": 16,
"y": 383.0625,
"w": 390,
"h": 49,
"right": 406,
"bottom": 432.0625
},
"viewport": {
"w": 390,
"h": 844
},
"overflow": 0
}
},
{
"name": "16:9 fitted to both Inner dimensions at 1000x500",
"status": "PASS",
"data": {
"stage": {
"x": 247.109375,
"y": 169.5,
"w": 505.765625,
"h": 284.5,
"right": 752.875,
"bottom": 454
},
"slot": {
"x": 30,
"y": 169.5,
"w": 940,
"h": 284.5,
"right": 970,
"bottom": 454
},
"header": {
"x": 247.109375,
"y": 169.5,
"w": 505.765625,
"h": 49,
"right": 752.875,
"bottom": 218.5
},
"viewport": {
"w": 1000,
"h": 500
},
"overflow": 0
}
},
{
"name": "one Header and no duplicate fixed Figma specimen",
"status": "PASS"
},
{
"name": "document selection updates Header and Callback",
"status": "PASS",
"data": "onDocumentClick → documentOpen(true) → onDocumentSelect(doc-2) → documentOpen(false)"
},
{
"name": "layer selection updates shared data",
"status": "PASS",
"data": "onDocumentClick → documentOpen(true) → onDocumentSelect(doc-2) → documentOpen(false) → onLayerOpen → onLayerSelect(layer, CC-D GNL)"
},
{
"name": "existing layer Detail callback closes list",
"status": "PASS"
},
{
"name": "color selection invokes host callback",
"status": "PASS",
"data": "onLayerOpen → onLayerSelect(layer, CC-D GNL) → onLayerOpen → onLayerDetail → onColorOpen → onColorSelect(color, 255,255,255)"
},
{
"name": "line selection updates Header",
"status": "PASS",
"data": "onLayerOpen → onLayerDetail → onColorOpen → onColorSelect(color, 255,255,255) → onLineStyleOpen → onLineTypeSelect(line, CENTER)"
},
{
"name": "ByLayer weight mode does not turn numeric property into a mode string",
"status": "PASS"
},
{
"name": "text style selection updates Header",
"status": "PASS",
"data": "onColorSelect(color, 255,255,255) → onLineStyleOpen → onLineTypeSelect(line, CENTER) → onLineWeightSelect(w-bylayer) → onTextStyleOpen → onTextStyleSelect(dotum)"
},
{
"name": "dimension style selection updates Header",
"status": "PASS",
"data": "onLineTypeSelect(line, CENTER) → onLineWeightSelect(w-bylayer) → onTextStyleOpen → onTextStyleSelect(dotum) → onDimensionStyleOpen → onDimensionStyleSelect(iso-25)"
},
{
"name": "opening another dropdown closes the previous one",
"status": "PASS"
},
{
"name": "Escape closes Header dropdown",
"status": "PASS"
},
{
"name": "outside click closes Header dropdown",
"status": "PASS"
},
{
"name": "Bar Enter commits state",
"status": "PASS"
},
{
"name": "Bar validates min=0",
"status": "PASS"
},
{
"name": "Bar Escape cancels edit",
"status": "PASS"
},
{
"name": "Header opens panel with same Bar value",
"status": "PASS"
},
{
"name": "numeric weight property remains numeric after ByLayer mode",
"status": "PASS"
},
{
"name": "Header layer value shared with panel",
"status": "PASS"
},
{
"name": "panel edit updates the Bar",
"status": "PASS"
},
{
"name": "panel number validation rejects negative radius",
"status": "PASS"
},
{
"name": "panel Layer dropdown updates Header shared value",
"status": "PASS"
},
{
"name": "panel line dropdown updates Header shared value",
"status": "PASS"
},
{
"name": "panel color dropdown updates Header shared value",
"status": "PASS"
},
{
"name": "panel RGB validation rejects out-of-range value",
"status": "PASS"
},
{
"name": "gauge keyboard editing commits host state",
"status": "PASS"
},
{
"name": "first Escape cancels draft and retains panel",
"status": "PASS"
},
{
"name": "next Escape closes panel and restores Header focus",
"status": "PASS"
},
{
"name": "panel Close button restores focus",
"status": "PASS"
},
{
"name": "external Props update Bar",
"status": "PASS"
},
{
"name": "Bar ReadOnly",
"status": "PASS"
},
{
"name": "Bar Disabled",
"status": "PASS"
},
{
"name": "dynamic Bar field added",
"status": "PASS"
},
{
"name": "dynamic field shared with panel",
"status": "PASS"
},
{
"name": "dynamic field removed from both",
"status": "PASS"
},
{
"name": "shape Slot can be empty without changing panel structure",
"status": "PASS"
},
{
"name": "original panel size none:314x256",
"status": "PASS",
"data": {
"x": 1000,
"y": 301.25,
"width": 314,
"height": 256
}
},
{
"name": "original panel size all:314x361",
"status": "PASS",
"data": {
"x": 1000,
"y": 301.25,
"width": 314,
"height": 361
}
},
{
"name": "original panel size circle:314x658",
"status": "PASS",
"data": {
"x": 1000,
"y": 301.25,
"width": 314,
"height": 658
}
},
{
"name": "original panel size expanded:314x754",
"status": "PASS",
"data": {
"x": 1000,
"y": 301.25,
"width": 314,
"height": 754
}
},
{
"name": "expanded popup bottom accessible through internal scroll",
"status": "PASS"
},
{
"name": "small Inner reaches full popup bottom with native Header and popup dimensions",
"status": "PASS",
"data": {
"top": 630,
"left": 16,
"height": 201,
"scrollHeight": 831,
"width": 358,
"scrollWidth": 390
}
},
{
"name": "narrow popup Escape restores More focus",
"status": "PASS"
},
{
"name": "actual Storybook manager iframe fits its own Inner",
"status": "PASS",
"data": {
"width": 1071.59375,
"height": 602.765625,
"slotWidth": 1071.59375,
"slotHeight": 744.5,
"viewportWidth": 1140,
"viewportHeight": 960
}
},
{
"name": "no browser errors",
"status": "PASS",
"data": []
}
],
"errors": [],
"sizes": [
{
"stage": {
"x": 360,
"y": 264.25,
"w": 1200,
"h": 675,
"right": 1560,
"bottom": 939.25
},
"slot": {
"x": 360,
"y": 169.5,
"w": 1200,
"h": 864.5,
"right": 1560,
"bottom": 1034
},
"header": {
"x": 360,
"y": 264.25,
"w": 1200,
"h": 49,
"right": 1560,
"bottom": 313.25
},
"viewport": {
"w": 1920,
"h": 1080
},
"overflow": 0
},
{
"stage": {
"x": 120,
"y": 174.25,
"w": 1200,
"h": 675,
"right": 1320,
"bottom": 849.25
},
"slot": {
"x": 120,
"y": 169.5,
"w": 1200,
"h": 684.5,
"right": 1320,
"bottom": 854
},
"header": {
"x": 120,
"y": 174.25,
"w": 1200,
"h": 49,
"right": 1320,
"bottom": 223.25
},
"viewport": {
"w": 1440,
"h": 900
},
"overflow": 0
},
{
"stage": {
"x": 191.5625,
"y": 169.5,
"w": 896.875,
"h": 504.5,
"right": 1088.4375,
"bottom": 674
},
"slot": {
"x": 38.40625,
"y": 169.5,
"w": 1203.1875,
"h": 504.5,
"right": 1241.59375,
"bottom": 674
},
"header": {
"x": 191.5625,
"y": 169.5,
"w": 896.875,
"h": 49,
"right": 1088.4375,
"bottom": 218.5
},
"viewport": {
"w": 1280,
"h": 720
},
"overflow": 0
},
{
"stage": {
"x": 42.21875,
"y": 169.5,
"w": 683.546875,
"h": 384.5,
"right": 725.765625,
"bottom": 554
},
"slot": {
"x": 23.046875,
"y": 169.5,
"w": 721.90625,
"h": 384.5,
"right": 744.953125,
"bottom": 554
},
"header": {
"x": 42.21875,
"y": 169.5,
"w": 683.546875,
"h": 49,
"right": 725.765625,
"bottom": 218.5
},
"viewport": {
"w": 768,
"h": 600
},
"overflow": 0
},
{
"stage": {
"x": 16,
"y": 383.0625,
"w": 358,
"h": 201.375,
"right": 374,
"bottom": 584.4375
},
"slot": {
"x": 16,
"y": 169.5,
"w": 358,
"h": 628.5,
"right": 374,
"bottom": 798
},
"header": {
"x": 16,
"y": 383.0625,
"w": 390,
"h": 49,
"right": 406,
"bottom": 432.0625
},
"viewport": {
"w": 390,
"h": 844
},
"overflow": 0
},
{
"stage": {
"x": 247.109375,
"y": 169.5,
"w": 505.765625,
"h": 284.5,
"right": 752.875,
"bottom": 454
},
"slot": {
"x": 30,
"y": 169.5,
"w": 940,
"h": 284.5,
"right": 970,
"bottom": 454
},
"header": {
"x": 247.109375,
"y": 169.5,
"w": 505.765625,
"h": 49,
"right": 752.875,
"bottom": 218.5
},
"viewport": {
"w": 1000,
"h": 500
},
"overflow": 0
}
],
"browser": "155.0.8059.80",
"managerOrder": [
"sw-header--overview",
"sw-header--interactive-states",
"sw-header--window-move-motion",
"sw-header--logo-slot",
"sw-header--document-dropdown",
"sw-header--responsive-more",
"sw-header--layer-detail-input",
"sw-header--property-panel",
"sw-header--property-panel-variants",
"sw-header--k-guide",
"sw-header--additional-hover",
"sw-header--property-bar",
"sw-header--dynamic-controls",
"sw-header--colorize",
"sw-header--composition",
"sw-header--property-panel-none",
"sw-header--property-panel-all",
"sw-header--property-panel-circle",
"sw-header--property-panel-expanded",
"sw-header--property-panel-compare",
"sw-header--property-shape-slot",
"sw-header--property-fields"
],
"status": "PASS"
}
@@ -0,0 +1,24 @@
[
"sw-header--overview",
"sw-header--interactive-states",
"sw-header--window-move-motion",
"sw-header--logo-slot",
"sw-header--document-dropdown",
"sw-header--responsive-more",
"sw-header--layer-detail-input",
"sw-header--property-panel",
"sw-header--property-panel-variants",
"sw-header--k-guide",
"sw-header--additional-hover",
"sw-header--property-bar",
"sw-header--dynamic-controls",
"sw-header--colorize",
"sw-header--composition",
"sw-header--property-panel-none",
"sw-header--property-panel-all",
"sw-header--property-panel-circle",
"sw-header--property-panel-expanded",
"sw-header--property-panel-compare",
"sw-header--property-shape-slot",
"sw-header--property-fields"
]
Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 230 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

@@ -0,0 +1,114 @@
{
"mode": "preservation",
"browser": "155.0.8059.80",
"checks": [
{
"name": "required responsive width 390",
"status": "PASS",
"data": {
"height": 49,
"overflow": 0,
"documentOverflow": 0
}
},
{
"name": "required responsive width 768",
"status": "PASS",
"data": {
"height": 49,
"overflow": 0,
"documentOverflow": 0
}
},
{
"name": "required responsive width 1280",
"status": "PASS",
"data": {
"height": 49,
"overflow": 0,
"documentOverflow": 0
}
},
{
"name": "required responsive width 1440",
"status": "PASS",
"data": {
"height": 49,
"overflow": 0,
"documentOverflow": 0
}
},
{
"name": "preserve property panel none",
"status": "PASS",
"data": {
"x": 360,
"y": 204.5,
"width": 314,
"height": 256
}
},
{
"name": "preserve property panel all",
"status": "PASS",
"data": {
"x": 360,
"y": 204.5,
"width": 314,
"height": 361
}
},
{
"name": "preserve property panel circle",
"status": "PASS",
"data": {
"x": 360,
"y": 204.5,
"width": 314,
"height": 658
}
},
{
"name": "preserve property panel expanded",
"status": "PASS",
"data": {
"x": 360,
"y": 204.5,
"width": 314,
"height": 754
}
},
{
"name": "preserve window motion 1400ms",
"status": "PASS"
},
{
"name": "window motion leave clears animations",
"status": "PASS"
},
{
"name": "preserve K guide animation",
"status": "PASS"
},
{
"name": "K guide leave closes",
"status": "PASS"
},
{
"name": "preserve Colorize size",
"status": "PASS"
},
{
"name": "preserve editable Input",
"status": "PASS"
},
{
"name": "no browser errors",
"status": "PASS",
"data": []
}
],
"errors": [],
"styles": {},
"status": "PASS"
}
@@ -0,0 +1,14 @@
{
"mode": "preservation",
"browser": "155.0.8059.80",
"checks": [
{
"name": "suite completed",
"status": "FAIL",
"data": "page.goto: net::ERR_NETWORK_ACCESS_DENIED at http://127.0.0.1:13169/iframe.html?id=sw-header--composition&viewMode=story\nCall log:\n\u001b[2m - navigating to \"http://127.0.0.1:13169/iframe.html?id=sw-header--composition&viewMode=story\", waiting until \"load\"\u001b[22m\n\n at goto (D:\\디자인시스템\\HMDesign-SW\\packages\\sw\\tests\\detail-buttons.browser.mjs:26:14)\n at D:\\디자인시스템\\HMDesign-SW\\packages\\sw\\tests\\detail-buttons.browser.mjs:46:11"
}
],
"errors": [],
"styles": {},
"status": "FAIL"
}
File diff suppressed because it is too large. Load diff
Binary file not shown.

After

Width:  |  Height:  |  Size: 222 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

@@ -0,0 +1,177 @@
{
"baseCommit": "c165753bbe24de6581c66704bde4ba3246049ec2",
"checks": [
{
"name": "28 -> 24 SW Stories, exactly four approved Dropdown retirements",
"status": "PASS"
},
{
"name": "Dropdown group has only Composed Controls with original ID",
"status": "PASS"
},
{
"name": "all non-SW index entries identical",
"status": "PASS"
},
{
"name": "all retained declarations identical outside imports, meta and ComposedDemo",
"status": "PASS"
},
{
"name": "runtime, API, AI template, Overview, existing CSS/assets and Storybook configuration untouched",
"status": "PASS"
},
{
"name": "User line weight still updates displayed numeric value",
"status": "PASS"
},
{
"name": "weight mode label preserves the shared numeric value",
"status": "PASS"
},
{
"name": "details opens existing 28px property Bar",
"status": "PASS"
},
{
"name": "details opens existing 314px property panel with focus",
"status": "PASS",
"data": {
"width": 314,
"focused": true,
"active": "<div id=\"_r_0_\" tabindex=\"-1\" class=\"hm-sw-property\" data-selection-kind=\"single\" role=\"dialog\" aria-modal=\"false\" aria-labelledby=\"_r_b_\" style=\"position: fixed; left: 207px; top: 295.5px; width: 314px; max-height: 700.5px;\"><div class=\"hm-sw-property__titlebar\"><img class=\"hm-sw-property__title-art\" alt=\"\" src=\"data:image/svg+xml,%3csvg%20preserveAspectRatio='none'%20overflow='visible'%20style='display:%20block;'%20width='308'%20height='38'%20viewBox='0%200%20308%2038'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cg%20id='Union'%20filter='url(%23filter0_d_0_140)'%3e%3cmask%20id='path-1-inside-1_0_140'%20fill='white'%3e%3cpath%20fill-rule='evenodd'%20clip-rule='evenodd'%20d='M252%206H0V33C0%2034.6569%201.34314%2036%203%2036H252H260H270.947C276.28%2036%20280.369%2029.2601%20284.685%2022.1464C289.05%2014.9502%20293.648%207.37149%20300%206H260H252Z'/%3e%3c/mask%3e%3cpath%20fill-rule='evenodd'%20clip-rule='evenodd'%20d='M252%206H0V33C0%2034.6569%201.34314%2036%203%2036H252H260H270.947C276.28%2036%20280.369%2029.2601%20284.685%2022.1464C289.05%2014.9502%20293.648%207.37149%20300%206H260H252Z'%20fill='%23211D13'/%3e%3cpath%20d='M0%206V5H-1V6H0ZM284.685%2022.1464L285.54%2022.665V22.665L284.685%2022.1464ZM300%206L300.211%206.97748L300%205V6ZM0%206V7H252V6V5H0V6ZM0%2033H1V6H0H-1V33H0ZM3%2036V35C1.89543%2035%201%2034.1046%201%2033H0H-1C-1%2035.2091%200.790855%2037%203%2037V36ZM252%2036V35H3V36V37H252V36ZM252%2036V37H260V36V35H252V36ZM260%2036V37H270.947V36V35H260V36ZM270.947%2036V37C274.062%2037%20276.672%2035.0311%20278.953%2032.3953C281.248%2029.7442%20283.395%2026.2%20285.54%2022.665L284.685%2022.1464L283.83%2021.6277C281.658%2025.2064%20279.603%2028.5891%20277.441%2031.0864C275.266%2033.5989%20273.165%2035%20270.947%2035V36ZM284.685%2022.1464L285.54%2022.665C287.732%2019.051%20289.933%2015.4276%20292.363%2012.5318C294.799%209.62962%20297.357%207.59367%20300.211%206.97748L300%206L299.789%205.02252C296.291%205.77782%20293.374%208.21697%20290.831%2011.246C288.284%2014.2816%20286.003%2018.0456%20283.83%2021.6277L284.685%2022.1464ZM300%206V5H260V6V7H300V6ZM260%206V5H252V6V7H260V6Z'%20fill='url(%23paint0_linear_0_140)'%20mask='url(%23path-1-inside-1_0_140)'/%3e%3c/g%3e%3cdefs%3e%3cfilter%20id='filter0_d_0_140'%20x='0'%20y='0'%20width='308'%20height='38'%20filterUnits='userSpaceOnUse'%20color-interpolation-filters='sRGB'%3e%3cfeFlood%20flood-opacity='0'%20result='BackgroundImageFix'/%3e%3cfeColorMatrix%20in='SourceAlpha'%20type='matrix'%20values='0%200%200%200%200%200%200%200%200%200%200%200%200%200%200%200%200%200%20127%200'%20result='hardAlpha'/%3e%3cfeOffset%20dx='4'%20dy='-2'/%3e%3cfeGaussianBlur%20stdDeviation='2'/%3e%3cfeComposite%20in2='hardAlpha'%20operator='out'/%3e%3cfeColorMatrix%20type='matrix'%20values='0%200%200%200%200%200%200%200%200%200%200%200%200%200%200%200%200%200%200.4%200'/%3e%3cfeBlend%20mode='normal'%20in2='BackgroundImageFix'%20result='effect1_dropShadow_0_140'/%3e%3cfeBlend%20mode='normal'%20in='SourceGraphic'%20in2='effect1_dropShadow_0_140'%20result='shape'/%3e%3c/filter%3e%3clinearGradient%20id='paint0_linear_0_140'%20x1='150'%20y1='6'%20x2='150'%20y2='36'%20gradientUnits='userSpaceOnUse'%3e%3cstop%20stop-color='%23493927'/%3e%3cstop%20offset='0.17'%20stop-color='%236F5739'/%3e%3cstop%20offset='0.505'%20stop-color='%23A38663'/%3e%3cstop%20offset='0.849271'%20stop-color='%232C2213'/%3e%3cstop%20offset='1'%20stop-color='%23413A2B'/%3e%3c/linearGradient%3e%3c/defs%3e%3c/svg%3e\"><span id=\"_r_b_\" class=\"hm-sw-property__title\" title=\"선택된 객체 - 원1\">선택된 객체 - 원1</span><button type=\"button\" class=\"hm-sw-property__close\" aria-label=\"속성창 닫기\"><img class=\"hm-sw-property__close-default\" alt=\"\" src=\"data:image/svg+xml,%3csvg%20width='44'%20height='30'%20viewBox='0%200%2044%2030'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cg%20id='2.%20&amp;%23237;&amp;%23151;&amp;%23164;&amp;%23235;&amp;%23141;&amp;%23148;'%3e%3cg%20id='btn_close%20popup'%3e%3cg%20id='Property%201=Default'%3e%3cg%20id='Rectangle%207347'%3e%3cpath%20d='M41%200.5C42.3807%200.5%2043.5%201.61929%2043.5%203V29.5H0.5V0.5H41Z'%20fill='url(%23paint0_linear_25_48)'/%3e%3cpath%20d='M41%200.5C42.3807%200.5%2043.5%201.61929%2043.5%203V29.5H0.5V0.5H41Z'%20fill='black'%20fill-opacity='0.4'/%3e%3cpath%20d='M41%200.5C42.3807%200.5%2043.5%201.61929%2043.5%203V29.5H0.5V0.5H41Z'%20stroke='url(%23paint1_linear_25_48)'/%3e%3c/g%3e%3cg%20id='Group%202894'%20filter='url(%23filter0_d_25_48)'%3e%3cpath%20id='Line%20940'%20d='M26%209L35.0909%2018.0909'%20stroke='%23969696'%20stroke-width='1.5'%20stroke-linecap='round'/%3e%3cpath%20id='Line%20941'%20d='M35.2891%209L26.1982%2018.0909'%20stroke='%23969696'%20stroke-width='1.5'%20stroke-linecap='round'/%3e%3c/g%3e%3c/g%3e%3c/g%3e%3c/g%3e%3cdefs%3e%3cfilter%20id='filter0_d_25_48'%20x='21.25'%20y='4.25'%20width='18.7891'%20height='18.5918'%20filterUnits='userSpaceOnUse'%20color-interpolation-filters='sRGB'Line truncated
}
},
{
"name": "property Bar and panel share edited state",
"status": "PASS",
"data": "12.5"
},
{
"name": "property panel weight edit appears in composed line field",
"status": "PASS"
},
{
"name": "property panel close returns focus",
"status": "PASS"
},
{
"name": "property panel Escape returns focus",
"status": "PASS"
},
{
"name": "narrow details panel keeps natural width and fits viewport",
"status": "PASS",
"data": {
"width": 314,
"left": 72,
"right": 386,
"bottom": 840,
"overflow": 0
}
},
{
"name": "all seven actionable controls Disabled",
"status": "PASS"
},
{
"name": "Disabled controls block callbacks and overlays",
"status": "PASS"
},
{
"name": "callback-free layer icons become readonly status images",
"status": "PASS"
},
{
"name": "missing detail callback keeps safe no-op and menu open",
"status": "PASS"
},
{
"name": "retained long layer scenario",
"status": "PASS"
},
{
"name": "long layer name preserved with full title",
"status": "PASS"
},
{
"name": "retained many layer scenario",
"status": "PASS"
},
{
"name": "long layer list scrolls internally",
"status": "PASS"
},
{
"name": "all 40 user colors accessible with palette scroll",
"status": "PASS"
},
{
"name": "retained empty layer scenario",
"status": "PASS"
},
{
"name": "Overview keeps one Header at 49px and 16:9 Stage",
"status": "PASS"
},
{
"name": "Window Move Motion retains only nine 3x steps",
"status": "PASS"
},
{
"name": "manager shows Dropdown group with the single Composed Controls page",
"status": "PASS"
},
{
"name": "retired Dropdown links absent in manager",
"status": "PASS"
},
{
"name": "no browser console or page errors",
"status": "PASS",
"data": []
}
],
"errors": [],
"callbacks": [
"onLineStyleOpen",
"lineStyleOpen(true)",
"onLineWeightSelect(weight, 0.25)",
"onLineWeightValueChange(weight, 0.5)",
"onLineWeightSelect(w-bylayer)",
"onLineWeightSelect(weight, 0.25)",
"lineStyleOpen(false)",
"onPropertyBarOpenChange(true)",
"onPropertyPanelOpenChange(true)",
"onPropertyChange(radius, 12.5)",
"onPropertyChange(weight, 0.75)",
"onPropertyPanelOpenChange(false)",
"onPropertyPanelOpenChange(true)",
"onPropertyPanelOpenChange(false)",
"onPropertyPanelOpenChange(true)",
"onPropertyPanelOpenChange(false)",
"onPropertyBarOpenChange(false)",
"onLayerOpen",
"layerOpen(true)",
"layerOpen(false)",
"onColorOpen",
"colorOpen(true)",
"colorOpen(false)",
"onLayerOpen",
"layerOpen(true)",
"onLayerSelect(layer, Sample-매우-긴-레이어-이름-Ellipsis-확인용-Layer-Name-0123456789)",
"layerOpen(false)",
"onLayerOpen",
"layerOpen(true)",
"layerOpen(false)",
"onColorOpen",
"colorOpen(true)",
"colorOpen(false)",
"onLayerOpen",
"layerOpen(true)",
"layerOpen(false)"
],
"geometry": [],
"browser": "155.0.8059.80",
"status": "PASS"
}
@@ -0,0 +1,849 @@
{
"before": [
{
"type": "story",
"subtype": "story",
"id": "sw-header--detail-buttons",
"name": "Detail Buttons (Shared States)",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest",
"verification"
],
"exportName": "DetailButtons"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--overview",
"name": "Overview",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "Overview"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--interactive-states",
"name": "Interactive States",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "InteractiveStates"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--window-move-motion",
"name": "Window Move Motion",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "WindowMoveMotion"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--composed-controls",
"name": "Composed Controls",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "ComposedControls"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--logo-slot",
"name": "Logo Slot",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "LogoSlot"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--document-dropdown",
"name": "Document Dropdown",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "DocumentDropdown"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--layer-dropdown",
"name": "Layer Dropdown",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "LayerDropdown"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--color-dropdown",
"name": "Color Dropdown",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "ColorDropdown"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--line-style-dropdown",
"name": "Line Style Dropdown",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "LineStyleDropdown"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--text-dimension-style-dropdown",
"name": "Text · Dimension Style Dropdown",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "TextDimensionStyleDropdown"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--responsive-more",
"name": "Responsive More",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "ResponsiveMore"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--layer-detail-input",
"name": "Layer Detail · Input",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "LayerDetailInput"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel",
"name": "Property Panel",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanel"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-variants",
"name": "Property Panel Variants",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelVariants"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--k-guide",
"name": "K Guide",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "KGuide"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--additional-hover",
"name": "Additional Hover",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "AdditionalHover"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-bar",
"name": "Property Bar",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyBar"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--dynamic-controls",
"name": "Dynamic Controls",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "DynamicControls"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--colorize",
"name": "Colorize",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "Colorize"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--composition",
"name": "Composition (Visibility · Order)",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "Composition"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-none",
"name": "Property Panel · 선택 없음",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelNone"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-all",
"name": "Property Panel · 전체 선택",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelAll"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-circle",
"name": "Property Panel · 원 1개",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelCircle"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-expanded",
"name": "Property Panel · 모두 펼침",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelExpanded"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-compare",
"name": "Property Panel · 4개 비교",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelCompare"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-shape-slot",
"name": "Property Panel · 형상 Slot",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyShapeSlot"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-fields",
"name": "Property Panel · 필드 13개",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyFields"
}
],
"after": [
{
"type": "story",
"subtype": "story",
"id": "sw-header--detail-buttons",
"name": "Detail Buttons (Shared States)",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest",
"verification"
],
"exportName": "DetailButtons"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--overview",
"name": "Overview",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "Overview"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--interactive-states",
"name": "Interactive States",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "InteractiveStates"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--window-move-motion",
"name": "Window Move Motion",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "WindowMoveMotion"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--logo-slot",
"name": "Logo Slot",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "LogoSlot"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--document-dropdown",
"name": "Document Dropdown",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "DocumentDropdown"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--responsive-more",
"name": "Responsive More",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "ResponsiveMore"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--layer-detail-input",
"name": "Layer Detail · Input",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "LayerDetailInput"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel",
"name": "Property Panel",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanel"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-variants",
"name": "Property Panel Variants",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelVariants"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--k-guide",
"name": "K Guide",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "KGuide"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--additional-hover",
"name": "Additional Hover",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "AdditionalHover"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-bar",
"name": "Property Bar",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyBar"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--dynamic-controls",
"name": "Dynamic Controls",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "DynamicControls"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--colorize",
"name": "Colorize",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "Colorize"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--composition",
"name": "Composition (Visibility · Order)",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "Composition"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-none",
"name": "Property Panel · 선택 없음",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelNone"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-all",
"name": "Property Panel · 전체 선택",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelAll"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-circle",
"name": "Property Panel · 원 1개",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelCircle"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-expanded",
"name": "Property Panel · 모두 펼침",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelExpanded"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-compare",
"name": "Property Panel · 4개 비교",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelCompare"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-shape-slot",
"name": "Property Panel · 형상 Slot",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyShapeSlot"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-fields",
"name": "Property Panel · 필드 13개",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyFields"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--composed-controls",
"name": "Composed Controls",
"title": "SW/Header/Dropdown",
"importPath": "./src/sw/sw-header-dropdown.stories.tsx",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "ComposedControls"
}
],
"removed": [
{
"type": "story",
"subtype": "story",
"id": "sw-header--layer-dropdown",
"name": "Layer Dropdown",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "LayerDropdown"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--color-dropdown",
"name": "Color Dropdown",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "ColorDropdown"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--line-style-dropdown",
"name": "Line Style Dropdown",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "LineStyleDropdown"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--text-dimension-style-dropdown",
"name": "Text · Dimension Style Dropdown",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "TextDimensionStyleDropdown"
}
]
}
@@ -0,0 +1,35 @@
{
"baseCommit": "c165753bbe24de6581c66704bde4ba3246049ec2",
"checks": [
{
"name": "28 -> 24 SW Stories, exactly four approved Dropdown retirements",
"status": "PASS"
},
{
"name": "Dropdown group has only Composed Controls with original ID",
"status": "PASS"
},
{
"name": "all non-SW index entries identical",
"status": "PASS"
},
{
"name": "all retained declarations identical outside imports, meta and ComposedDemo",
"status": "PASS"
},
{
"name": "runtime, API, AI template, Overview, existing CSS/assets and Storybook configuration untouched",
"status": "PASS"
},
{
"name": "suite completes",
"status": "FAIL",
"data": "page.goto: net::ERR_NETWORK_ACCESS_DENIED at http://127.0.0.1:13170/iframe.html?id=sw-header--detail-buttons&viewMode=story\nCall log:\n\u001b[2m - navigating to \"http://127.0.0.1:13170/iframe.html?id=sw-header--detail-buttons&viewMode=story\", waiting until \"load\"\u001b[22m\n\n at go (D:\\디자인시스템\\HMDesign-SW\\packages\\sw\\tests\\dropdown-consolidation.browser.mjs:59:16)\n at D:\\디자인시스템\\HMDesign-SW\\packages\\sw\\tests\\dropdown-consolidation.browser.mjs:65:11"
}
],
"errors": [],
"callbacks": [],
"geometry": [],
"browser": "155.0.8059.80",
"status": "FAIL"
}
File diff suppressed because it is too large. Load diff
Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

File diff suppressed because it is too large. Load diff
@@ -0,0 +1,849 @@
{
"before": [
{
"type": "story",
"subtype": "story",
"id": "sw-header--detail-buttons",
"name": "Detail Buttons (Shared States)",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest",
"verification"
],
"exportName": "DetailButtons"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--overview",
"name": "Overview",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "Overview"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--interactive-states",
"name": "Interactive States",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "InteractiveStates"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--window-move-motion",
"name": "Window Move Motion",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "WindowMoveMotion"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--composed-controls",
"name": "Composed Controls",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "ComposedControls"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--logo-slot",
"name": "Logo Slot",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "LogoSlot"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--document-dropdown",
"name": "Document Dropdown",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "DocumentDropdown"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--layer-dropdown",
"name": "Layer Dropdown",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "LayerDropdown"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--color-dropdown",
"name": "Color Dropdown",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "ColorDropdown"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--line-style-dropdown",
"name": "Line Style Dropdown",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "LineStyleDropdown"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--text-dimension-style-dropdown",
"name": "Text · Dimension Style Dropdown",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "TextDimensionStyleDropdown"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--responsive-more",
"name": "Responsive More",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "ResponsiveMore"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--layer-detail-input",
"name": "Layer Detail · Input",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "LayerDetailInput"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel",
"name": "Property Panel",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanel"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-variants",
"name": "Property Panel Variants",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelVariants"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--k-guide",
"name": "K Guide",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "KGuide"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--additional-hover",
"name": "Additional Hover",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "AdditionalHover"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-bar",
"name": "Property Bar",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyBar"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--dynamic-controls",
"name": "Dynamic Controls",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "DynamicControls"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--colorize",
"name": "Colorize",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "Colorize"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--composition",
"name": "Composition (Visibility · Order)",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "Composition"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-none",
"name": "Property Panel · 선택 없음",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelNone"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-all",
"name": "Property Panel · 전체 선택",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelAll"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-circle",
"name": "Property Panel · 원 1개",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelCircle"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-expanded",
"name": "Property Panel · 모두 펼침",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelExpanded"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-compare",
"name": "Property Panel · 4개 비교",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelCompare"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-shape-slot",
"name": "Property Panel · 형상 Slot",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyShapeSlot"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-fields",
"name": "Property Panel · 필드 13개",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyFields"
}
],
"after": [
{
"type": "story",
"subtype": "story",
"id": "sw-header--detail-buttons",
"name": "Detail Buttons (Shared States)",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest",
"verification"
],
"exportName": "DetailButtons"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--overview",
"name": "Overview",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "Overview"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--interactive-states",
"name": "Interactive States",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "InteractiveStates"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--window-move-motion",
"name": "Window Move Motion",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "WindowMoveMotion"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--logo-slot",
"name": "Logo Slot",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "LogoSlot"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--document-dropdown",
"name": "Document Dropdown",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "DocumentDropdown"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--responsive-more",
"name": "Responsive More",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "ResponsiveMore"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--layer-detail-input",
"name": "Layer Detail · Input",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "LayerDetailInput"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel",
"name": "Property Panel",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanel"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-variants",
"name": "Property Panel Variants",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelVariants"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--k-guide",
"name": "K Guide",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "KGuide"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--additional-hover",
"name": "Additional Hover",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "AdditionalHover"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-bar",
"name": "Property Bar",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyBar"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--dynamic-controls",
"name": "Dynamic Controls",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "DynamicControls"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--colorize",
"name": "Colorize",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "Colorize"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--composition",
"name": "Composition (Visibility · Order)",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "Composition"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-none",
"name": "Property Panel · 선택 없음",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelNone"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-all",
"name": "Property Panel · 전체 선택",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelAll"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-circle",
"name": "Property Panel · 원 1개",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelCircle"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-expanded",
"name": "Property Panel · 모두 펼침",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelExpanded"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-compare",
"name": "Property Panel · 4개 비교",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelCompare"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-shape-slot",
"name": "Property Panel · 형상 Slot",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyShapeSlot"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-fields",
"name": "Property Panel · 필드 13개",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyFields"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--composed-controls",
"name": "Composed Controls",
"title": "SW/Header/Dropdown",
"importPath": "./src/sw/sw-header-dropdown.stories.tsx",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "ComposedControls"
}
],
"removed": [
{
"type": "story",
"subtype": "story",
"id": "sw-header--layer-dropdown",
"name": "Layer Dropdown",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "LayerDropdown"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--color-dropdown",
"name": "Color Dropdown",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "ColorDropdown"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--line-style-dropdown",
"name": "Line Style Dropdown",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "LineStyleDropdown"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--text-dimension-style-dropdown",
"name": "Text · Dimension Style Dropdown",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "TextDimensionStyleDropdown"
}
]
}
File diff suppressed because it is too large. Load diff
Binary file not shown.

After

Width:  |  Height:  |  Size: 222 KiB

@@ -0,0 +1,140 @@
{
"baseCommit": "c165753bbe24de6581c66704bde4ba3246049ec2",
"checks": [
{
"name": "28 -> 24 SW Stories, exactly four approved Dropdown retirements",
"status": "PASS"
},
{
"name": "Dropdown group has only Composed Controls with original ID",
"status": "PASS"
},
{
"name": "all non-SW index entries identical",
"status": "PASS"
},
{
"name": "all retained declarations identical outside imports, meta and ComposedDemo",
"status": "PASS"
},
{
"name": "runtime, API, AI template, Overview, existing CSS/assets and Storybook configuration untouched",
"status": "PASS"
},
{
"name": "details opens existing 28px property Bar",
"status": "PASS"
},
{
"name": "details opens existing 314px property panel with focus",
"status": "FAIL",
"data": {
"width": 314,
"focused": false,
"active": "<button type=\"button\" class=\"hm-sw-header__toggle\" data-property-panel-trigger=\"\" aria-pressed=\"true\" aria-haspopup=\"dialog\" aria-expanded=\"true\" aria-controls=\"_r_0_\" data-selected=\"true\">속성창</button>"
}
},
{
"name": "property Bar and panel share edited state",
"status": "FAIL",
"data": "4.0526"
},
{
"name": "property panel close returns focus",
"status": "PASS"
},
{
"name": "property panel Escape returns focus",
"status": "PASS"
},
{
"name": "all seven actionable controls Disabled",
"status": "PASS"
},
{
"name": "callback-free layer icons become readonly status images",
"status": "PASS"
},
{
"name": "missing detail callback keeps safe no-op and menu open",
"status": "PASS"
},
{
"name": "retained long layer scenario",
"status": "PASS"
},
{
"name": "long layer name preserved with full title",
"status": "PASS"
},
{
"name": "retained many layer scenario",
"status": "PASS"
},
{
"name": "long layer list scrolls internally",
"status": "PASS"
},
{
"name": "all 40 user colors accessible with palette scroll",
"status": "PASS"
},
{
"name": "retained empty layer scenario",
"status": "PASS"
},
{
"name": "Overview keeps one Header at 49px and 16:9 Stage",
"status": "PASS"
},
{
"name": "Window Move Motion retains only nine 3x steps",
"status": "PASS"
},
{
"name": "manager shows Dropdown group with the single Composed Controls page",
"status": "PASS"
},
{
"name": "retired Dropdown links absent in manager",
"status": "PASS"
},
{
"name": "no browser console or page errors",
"status": "PASS",
"data": []
}
],
"errors": [],
"callbacks": [
"onPropertyBarOpenChange(true)",
"onPropertyPanelOpenChange(true)",
"onPropertyChange(radius, 12.5)",
"onPropertyPanelOpenChange(false)",
"onPropertyPanelOpenChange(true)",
"onPropertyPanelOpenChange(false)",
"onPropertyBarOpenChange(false)",
"onLayerOpen",
"layerOpen(true)",
"layerOpen(false)",
"onColorOpen",
"colorOpen(true)",
"colorOpen(false)",
"onLayerOpen",
"layerOpen(true)",
"onLayerSelect(layer, Sample-매우-긴-레이어-이름-Ellipsis-확인용-Layer-Name-0123456789)",
"layerOpen(false)",
"onLayerOpen",
"layerOpen(true)",
"layerOpen(false)",
"onColorOpen",
"colorOpen(true)",
"colorOpen(false)",
"onLayerOpen",
"layerOpen(true)",
"layerOpen(false)"
],
"geometry": [],
"browser": "155.0.8059.80",
"status": "FAIL"
}
@@ -0,0 +1,849 @@
{
"before": [
{
"type": "story",
"subtype": "story",
"id": "sw-header--detail-buttons",
"name": "Detail Buttons (Shared States)",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest",
"verification"
],
"exportName": "DetailButtons"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--overview",
"name": "Overview",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "Overview"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--interactive-states",
"name": "Interactive States",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "InteractiveStates"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--window-move-motion",
"name": "Window Move Motion",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "WindowMoveMotion"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--composed-controls",
"name": "Composed Controls",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "ComposedControls"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--logo-slot",
"name": "Logo Slot",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "LogoSlot"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--document-dropdown",
"name": "Document Dropdown",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "DocumentDropdown"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--layer-dropdown",
"name": "Layer Dropdown",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "LayerDropdown"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--color-dropdown",
"name": "Color Dropdown",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "ColorDropdown"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--line-style-dropdown",
"name": "Line Style Dropdown",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "LineStyleDropdown"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--text-dimension-style-dropdown",
"name": "Text · Dimension Style Dropdown",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "TextDimensionStyleDropdown"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--responsive-more",
"name": "Responsive More",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "ResponsiveMore"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--layer-detail-input",
"name": "Layer Detail · Input",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "LayerDetailInput"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel",
"name": "Property Panel",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanel"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-variants",
"name": "Property Panel Variants",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelVariants"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--k-guide",
"name": "K Guide",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "KGuide"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--additional-hover",
"name": "Additional Hover",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "AdditionalHover"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-bar",
"name": "Property Bar",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyBar"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--dynamic-controls",
"name": "Dynamic Controls",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "DynamicControls"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--colorize",
"name": "Colorize",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "Colorize"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--composition",
"name": "Composition (Visibility · Order)",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "Composition"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-none",
"name": "Property Panel · 선택 없음",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelNone"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-all",
"name": "Property Panel · 전체 선택",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelAll"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-circle",
"name": "Property Panel · 원 1개",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelCircle"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-expanded",
"name": "Property Panel · 모두 펼침",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelExpanded"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-compare",
"name": "Property Panel · 4개 비교",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelCompare"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-shape-slot",
"name": "Property Panel · 형상 Slot",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyShapeSlot"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-fields",
"name": "Property Panel · 필드 13개",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyFields"
}
],
"after": [
{
"type": "story",
"subtype": "story",
"id": "sw-header--detail-buttons",
"name": "Detail Buttons (Shared States)",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest",
"verification"
],
"exportName": "DetailButtons"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--overview",
"name": "Overview",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "Overview"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--interactive-states",
"name": "Interactive States",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "InteractiveStates"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--window-move-motion",
"name": "Window Move Motion",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "WindowMoveMotion"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--logo-slot",
"name": "Logo Slot",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "LogoSlot"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--document-dropdown",
"name": "Document Dropdown",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "DocumentDropdown"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--responsive-more",
"name": "Responsive More",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "ResponsiveMore"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--layer-detail-input",
"name": "Layer Detail · Input",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "LayerDetailInput"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel",
"name": "Property Panel",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanel"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-variants",
"name": "Property Panel Variants",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelVariants"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--k-guide",
"name": "K Guide",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "KGuide"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--additional-hover",
"name": "Additional Hover",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "AdditionalHover"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-bar",
"name": "Property Bar",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyBar"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--dynamic-controls",
"name": "Dynamic Controls",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "DynamicControls"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--colorize",
"name": "Colorize",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "Colorize"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--composition",
"name": "Composition (Visibility · Order)",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "Composition"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-none",
"name": "Property Panel · 선택 없음",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelNone"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-all",
"name": "Property Panel · 전체 선택",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelAll"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-circle",
"name": "Property Panel · 원 1개",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelCircle"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-expanded",
"name": "Property Panel · 모두 펼침",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelExpanded"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-compare",
"name": "Property Panel · 4개 비교",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelCompare"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-shape-slot",
"name": "Property Panel · 형상 Slot",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyShapeSlot"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-fields",
"name": "Property Panel · 필드 13개",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyFields"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--composed-controls",
"name": "Composed Controls",
"title": "SW/Header/Dropdown",
"importPath": "./src/sw/sw-header-dropdown.stories.tsx",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "ComposedControls"
}
],
"removed": [
{
"type": "story",
"subtype": "story",
"id": "sw-header--layer-dropdown",
"name": "Layer Dropdown",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "LayerDropdown"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--color-dropdown",
"name": "Color Dropdown",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "ColorDropdown"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--line-style-dropdown",
"name": "Line Style Dropdown",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "LineStyleDropdown"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--text-dimension-style-dropdown",
"name": "Text · Dimension Style Dropdown",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "TextDimensionStyleDropdown"
}
]
}
@@ -0,0 +1,849 @@
{
"before": [
{
"type": "story",
"subtype": "story",
"id": "sw-header--detail-buttons",
"name": "Detail Buttons (Shared States)",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest",
"verification"
],
"exportName": "DetailButtons"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--overview",
"name": "Overview",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "Overview"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--interactive-states",
"name": "Interactive States",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "InteractiveStates"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--window-move-motion",
"name": "Window Move Motion",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "WindowMoveMotion"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--composed-controls",
"name": "Composed Controls",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "ComposedControls"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--logo-slot",
"name": "Logo Slot",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "LogoSlot"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--document-dropdown",
"name": "Document Dropdown",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "DocumentDropdown"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--layer-dropdown",
"name": "Layer Dropdown",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "LayerDropdown"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--color-dropdown",
"name": "Color Dropdown",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "ColorDropdown"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--line-style-dropdown",
"name": "Line Style Dropdown",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "LineStyleDropdown"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--text-dimension-style-dropdown",
"name": "Text · Dimension Style Dropdown",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "TextDimensionStyleDropdown"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--responsive-more",
"name": "Responsive More",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "ResponsiveMore"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--layer-detail-input",
"name": "Layer Detail · Input",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "LayerDetailInput"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel",
"name": "Property Panel",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanel"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-variants",
"name": "Property Panel Variants",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelVariants"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--k-guide",
"name": "K Guide",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "KGuide"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--additional-hover",
"name": "Additional Hover",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "AdditionalHover"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-bar",
"name": "Property Bar",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyBar"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--dynamic-controls",
"name": "Dynamic Controls",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "DynamicControls"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--colorize",
"name": "Colorize",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "Colorize"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--composition",
"name": "Composition (Visibility · Order)",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "Composition"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-none",
"name": "Property Panel · 선택 없음",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelNone"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-all",
"name": "Property Panel · 전체 선택",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelAll"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-circle",
"name": "Property Panel · 원 1개",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelCircle"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-expanded",
"name": "Property Panel · 모두 펼침",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelExpanded"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-compare",
"name": "Property Panel · 4개 비교",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelCompare"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-shape-slot",
"name": "Property Panel · 형상 Slot",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyShapeSlot"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-fields",
"name": "Property Panel · 필드 13개",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyFields"
}
],
"after": [
{
"type": "story",
"subtype": "story",
"id": "sw-header--detail-buttons",
"name": "Detail Buttons (Shared States)",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest",
"verification"
],
"exportName": "DetailButtons"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--overview",
"name": "Overview",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "Overview"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--interactive-states",
"name": "Interactive States",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "InteractiveStates"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--window-move-motion",
"name": "Window Move Motion",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "WindowMoveMotion"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--logo-slot",
"name": "Logo Slot",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "LogoSlot"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--document-dropdown",
"name": "Document Dropdown",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "DocumentDropdown"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--responsive-more",
"name": "Responsive More",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "ResponsiveMore"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--layer-detail-input",
"name": "Layer Detail · Input",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "LayerDetailInput"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel",
"name": "Property Panel",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanel"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-variants",
"name": "Property Panel Variants",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelVariants"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--k-guide",
"name": "K Guide",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "KGuide"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--additional-hover",
"name": "Additional Hover",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "AdditionalHover"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-bar",
"name": "Property Bar",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyBar"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--dynamic-controls",
"name": "Dynamic Controls",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "DynamicControls"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--colorize",
"name": "Colorize",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "Colorize"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--composition",
"name": "Composition (Visibility · Order)",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "Composition"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-none",
"name": "Property Panel · 선택 없음",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelNone"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-all",
"name": "Property Panel · 전체 선택",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelAll"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-circle",
"name": "Property Panel · 원 1개",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelCircle"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-expanded",
"name": "Property Panel · 모두 펼침",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelExpanded"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-panel-compare",
"name": "Property Panel · 4개 비교",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyPanelCompare"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-shape-slot",
"name": "Property Panel · 형상 Slot",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyShapeSlot"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--property-fields",
"name": "Property Panel · 필드 13개",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "PropertyFields"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--composed-controls",
"name": "Composed Controls",
"title": "SW/Header/Dropdown",
"importPath": "./src/sw/sw-header-dropdown.stories.tsx",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "ComposedControls"
}
],
"removed": [
{
"type": "story",
"subtype": "story",
"id": "sw-header--layer-dropdown",
"name": "Layer Dropdown",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "LayerDropdown"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--color-dropdown",
"name": "Color Dropdown",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "ColorDropdown"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--line-style-dropdown",
"name": "Line Style Dropdown",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "LineStyleDropdown"
},
{
"type": "story",
"subtype": "story",
"id": "sw-header--text-dimension-style-dropdown",
"name": "Text · Dimension Style Dropdown",
"title": "SW/Header",
"importPath": "./src/sw/sw-header.stories.tsx",
"componentPath": "./packages/sw/dist/index.js",
"tags": [
"dev",
"test",
"manifest"
],
"exportName": "TextDimensionStyleDropdown"
}
]
}
@@ -0,0 +1,422 @@
> hm-design-system-poc@0.1.0 prebuild-storybook
> npm run check:theme-defaults && npm run build:packages
> hm-design-system-poc@0.1.0 check:theme-defaults
> node scripts/theme-defaults.mjs --check
Theme defaults: 92 JSON colors / 94 contract defaults; generated outputs match
> hm-design-system-poc@0.1.0 build:packages
> npm run build:org-chart && npm run build:ui && npm run build:center-graphic && npm run build:org-chart-react && npm run build:sw
> hm-design-system-poc@0.1.0 build:org-chart
> npm run build -w @hm-design/org-chart
> @hm-design/org-chart@0.1.0 build
> node build.mjs
vite v8.3.0 building client environment for production...
transforming...
✓ 70 modules transformed.
rendering chunks...
computing gzip size...
dist/index.js 2,450.52 kB │ gzip: 1,648.92 kB
✓ built in 99ms
vite v8.3.0 building client environment for production...
transforming...
✓ 70 modules transformed.
rendering chunks...
computing gzip size...
dist/orgchart.browser.js 2,456.85 kB │ gzip: 1,649.32 kB
✓ built in 82ms
> hm-design-system-poc@0.1.0 build:ui
> npm run build -w @hm-design/ui
> @hm-design/ui@0.1.0 build
> node ../../scripts/build-package.mjs ui
vite v8.3.0 building client environment for production...
transforming...
✓ 70 modules transformed.
rendering chunks...
computing gzip size...
dist/theme/index.js 25.18 kB │ gzip: 3.98 kB
dist/index.js 120.43 kB │ gzip: 21.30 kB
✓ built in 56ms
> hm-design-system-poc@0.1.0 build:center-graphic
> npm run build -w @hm-design/center-graphic
> @hm-design/center-graphic@0.1.0 build
> node ../../scripts/build-package.mjs center-graphic
vite v8.3.0 building client environment for production...
transforming...
✓ 145 modules transformed.
rendering chunks...
computing gzip size...
dist/style.css 88.68 kB │ gzip: 20.14 kB
dist/reference.js 0.65 kB │ gzip: 0.23 kB
dist/index.js 1.86 kB │ gzip: 0.84 kB
dist/FacilityBatch-PtW_fbvn.js 1,675.84 kB │ gzip: 276.13 kB
✓ built in 125ms
> hm-design-system-poc@0.1.0 build:org-chart-react
> npm run build -w @hm-design/org-chart-react
> @hm-design/org-chart-react@0.1.0 build
> node build.mjs
vite v8.3.0 building client environment for production...
transforming...
✓ 5 modules transformed.
rendering chunks...
computing gzip size...
dist/index.js 0.09 kB │ gzip: 0.09 kB
dist/hm-dialog.js 4.39 kB │ gzip: 1.80 kB
dist/OrgChart-DZlWXlj3.js 10.50 kB │ gzip: 2.63 kB
✓ built in 34ms
> hm-design-system-poc@0.1.0 build:sw
> npm run build -w @hm-design/sw
> @hm-design/sw@0.1.0 build
> node build.mjs
vite v8.3.0 building client environment for production...
transforming...
✓ 69 modules transformed.
rendering chunks...
computing gzip size...
dist/styles.css 100.39 kB │ gzip: 23.57 kB
dist/index.js 712.25 kB │ gzip: 337.98 kB
✓ built in 125ms
> hm-design-system-poc@0.1.0 build-storybook
> storybook build -o storybook-static --disable-telemetry
T Building storybook v10.6.1
|
o Cleaning outputDir: storybook-static
|
o Loading presets
|
o Building manager..
|
• Building open services..
|
• Building preview..
|
• Copying static files: public\fonts at storybook-static\fonts
|
• Copying static files: themes at storybook-static\themes
| Vite vite v8.3.0 building client environment for production...
transforming...
Found 1 warning while optimizing generated CSS:
│ }
│ .bg-\[var\(\.\.\.\)\] {
│ background-color: var(...);
┆ ^-- Unexpected token Delim('.')
┆
│ }
│ .bg-background {
✓ 3104 modules transformed.
|
! Vite [lightningcss minify] 'host-context' is not recognized as a valid
| pseudo-class. Did you mean '::host-context' (pseudo-element) or is
| this a typo?
| 1322 | background-color: var(--hm-orgchart-dialog-close-hover);
| 1323 | }
| 1324 | :host-context(.dark) .hm-orgchart-employee-dialog-close:hover,
| | ^
| 1325 | .dark .hm-orgchart-employee-dialog-close:hover {
| 1326 | background-color: color-mix(in oklab,
| var(--hm-orgchart-dialog-close-hover) 50%, transparent);
rendering chunks...
computing gzip size...
| Vite storybook-static/assets/input-26-11656-BIXt51ww.png
| 5.09 kB
| storybook-static/iframe.html
| 19.07 kB │ gzip: 5.42 kB
| storybook-static/assets/NotoSansKR-variable-k7NQXPol.ttf
| 10,414.58 kB
| storybook-static/assets/sw-header-dropdown-BSCl7vok.css
| 0.54 kB │ gzip: 0.25 kB
| storybook-static/assets/data-table-x0avmA1M.css
| 0.89 kB │ gzip: 0.32 kB
| storybook-static/assets/department-colors-preview-C8o8mgn-.css
| 1.12 kB │ gzip: 0.39 kB
| storybook-static/assets/org-chart-stories-CVVpQeIs.css
| 1.15 kB │ gzip: 0.39 kB
| storybook-static/assets/org-chart-expanded-BQqXfdmZ.css
| 1.34 kB │ gzip: 0.43 kB
| storybook-static/assets/story-page-B9TObVPB.css
| 1.74 kB │ gzip: 0.49 kB
| storybook-static/assets/designer-theme-Bv3QXGf0.css
| 2.88 kB │ gzip: 0.85 kB
| storybook-static/assets/reference-CElszmAj.css
| 3.13 kB │ gzip: 0.87 kB
| storybook-static/assets/center-stories-MLQreMPw.css
| 6.77 kB │ gzip: 1.49 kB
| storybook-static/assets/dashboard-layout-cwHZMCdB.css
| 6.90 kB │ gzip: 1.21 kB
| storybook-static/assets/engine-DrWcIejL.css
| 15.64 kB │ gzip: 3.10 kB
| storybook-static/assets/center-shared-CBSMPY7X.css
| 55.67 kB │ gzip: 10.48 kB
| storybook-static/assets/sw-header-CUYjY3HM.css
| 73.13 kB │ gzip: 13.58 kB
| storybook-static/assets/style-BhhUui7W.css
| 93.80 kB │ gzip: 12.41 kB
| storybook-static/assets/iframe-BW1xNYqB.css
| 237.20 kB │ gzip: 36.15 kB
| storybook-static/assets/iframe-CM3jaXUy.js
| 0.04 kB │ gzip: 0.06 kB
| storybook-static/assets/center-stories-Cr38slYE.js
| 0.09 kB │ gzip: 0.11 kB
| storybook-static/assets/org-chart-stories-BU9b3y-N.js
| 0.09 kB │ gzip: 0.11 kB
| storybook-static/assets/chart-column-ApneaDex.js
| 0.41 kB │ gzip: 0.29 kB
| storybook-static/assets/sw-header-dropdown.stories-Br2KV7lK.js
| 0.45 kB │ gzip: 0.32 kB
| storybook-static/assets/layout-grid-nh8HaGyO.js
| 0.48 kB │ gzip: 0.28 kB
| storybook-static/assets/italic-C1ba_qaZ.js
| 0.58 kB │ gzip: 0.36 kB
| storybook-static/assets/org-chart-full-composition.stories-GPbb_d5m.js
| 0.59 kB │ gzip: 0.39 kB
| storybook-static/assets/org-chart-p1.stories-DCQDpc-7.js
| 0.59 kB │ gzip: 0.40 kB
| storybook-static/assets/org-chart-department-colors.stories-DlGcicb6.js
| 0.60 kB │ gzip: 0.39 kB
| storybook-static/assets/settings-BcjI-E_q.js
| 0.62 kB │ gzip: 0.34 kB
| storybook-static/assets/org-chart-summary.stories-BzJ-mgGU.js
| 0.76 kB │ gzip: 0.40 kB
| storybook-static/assets/center-information.stories-6HqwRiNF.js
| 0.94 kB │ gzip: 0.63 kB
| storybook-static/assets/sample-users-CAqvNHXG.js
| 0.94 kB │ gzip: 0.67 kB
| storybook-static/assets/center-spatial.stories-CboGruP9.js
| 0.97 kB │ gzip: 0.65 kB
| storybook-static/assets/rolldown-runtime-DkW27tQK.js
| 1.19 kB │ gzip: 0.67 kB
| storybook-static/assets/preload-helper-VEOc_cSF.js
| 1.33 kB │ gzip: 0.75 kB
| storybook-static/assets/center-title.stories-b8Wy3Ztf.js
| 1.36 kB │ gzip: 0.88 kB
| storybook-static/assets/org-chart-overview-internal.stories-BPU5gFtT.js
| 1.43 kB │ gzip: 0.68 kB
| storybook-static/assets/org-chart-cards.stories-BwbprX0H.js
| 1.60 kB │ gzip: 0.92 kB
| storybook-static/assets/color.stories-rTNYqFGa.js
| 1.80 kB │ gzip: 1.03 kB
| storybook-static/assets/center-facility.stories-rC1YSGB-.js
| 1.90 kB │ gzip: 1.08 kB
| storybook-static/assets/loading-screen.stories-DM7ZiXRM.js
| 1.96 kB │ gzip: 1.04 kB
| storybook-static/assets/story-board-BS1Lr-yO.js
| 1.99 kB │ gzip: 0.89 kB
| storybook-static/assets/skeleton.stories-DsJBAwBV.js
| 2.10 kB │ gzip: 1.00 kB
| storybook-static/assets/story-page-Mm2B99xD.js
| 2.13 kB │ gzip: 0.70 kB
| storybook-static/assets/verification-state-e4eWHzJv.js
| 2.15 kB │ gzip: 1.05 kB
| storybook-static/assets/hover-card.stories-BSYsBygc.js
| 2.34 kB │ gzip: 1.09 kB
| storybook-static/assets/alert-dialog.stories-DnPRvVvA.js
| 2.48 kB │ gzip: 1.08 kB
| storybook-static/assets/separator.stories-DS9FQl-a.js
| 2.56 kB │ gzip: 1.16 kB
| storybook-static/assets/dropdown-menu.stories-DhPAoBTd.js
| 2.58 kB │ gzip: 1.29 kB
| storybook-static/assets/badge.stories-BFD0yR97.js
| 2.61 kB │ gzip: 1.23 kB
| storybook-static/assets/tooltip.stories-CRsgQDV8.js
| 2.65 kB │ gzip: 1.23 kB
| storybook-static/assets/publisher-regression.stories-gqXx-G7G.js
| 2.70 kB │ gzip: 1.15 kB
| storybook-static/assets/calendar.stories-D-j6PsiQ.js
| 2.79 kB │ gzip: 1.31 kB
| storybook-static/assets/switch.stories-DloSC1FQ.js
| 2.86 kB │ gzip: 1.28 kB
| storybook-static/assets/reference-CpMdp9Z2.js
| 2.88 kB │ gzip: 1.24 kB
| storybook-static/assets/context-menu.stories-C6ouCdKo.js
| 2.95 kB │ gzip: 1.47 kB
| storybook-static/assets/center-shared-D5aDdCPk.js
| 2.96 kB │ gzip: 1.36 kB
| storybook-static/assets/scroll-area.stories-CbpxFrLA.js
| 3.02 kB │ gzip: 1.30 kB
| storybook-static/assets/popover.stories-BsyQhoN0.js
| 3.05 kB │ gzip: 1.30 kB
| storybook-static/assets/aspect-ratio.stories-kgdclnC3.js
| 3.06 kB │ gzip: 1.51 kB
| storybook-static/assets/typography.stories-BuPkVjvt.js
| 3.07 kB │ gzip: 1.42 kB
| storybook-static/assets/pagination.stories-BWacQvjk.js
| 3.12 kB │ gzip: 1.50 kB
| storybook-static/assets/alert.stories-BU4brxEo.js
| 3.16 kB │ gzip: 1.30 kB
| storybook-static/assets/label.stories-Co7JdTv_.js
| 3.19 kB │ gzip: 1.39 kB
| storybook-static/assets/collapsible.stories-BVS88QON.js
| 3.19 kB │ gzip: 1.50 kB
| storybook-static/assets/drawer.stories-BaSmHqM9.js
| 3.23 kB │ gzip: 1.47 kB
| storybook-static/assets/radio-group.stories-CY98TK9E.js
| 3.24 kB │ gzip: 1.47 kB
| storybook-static/assets/avatar.stories-B9kjzvNC.js
| 3.30 kB │ gzip: 1.45 kB
| storybook-static/assets/page-header.stories-DxMFUAUK.js
| 3.32 kB │ gzip: 1.31 kB
| storybook-static/assets/menubar.stories-BZAo0241.js
| 3.33 kB │ gzip: 1.39 kB
| storybook-static/assets/command.stories-CP2PC1uv.js
| 3.33 kB │ gzip: 1.58 kB
| storybook-static/assets/center-overview.stories-DZnWZVER.js
| 3.36 kB │ gzip: 1.77 kB
| storybook-static/assets/filter-bar.stories-Dgdi_xO9.js
| 3.43 kB │ gzip: 1.72 kB
| storybook-static/assets/sheet.stories-nRLRzV3s.js
| 3.51 kB │ gzip: 1.44 kB
| storybook-static/assets/progress.stories-BzPPdTqn.js
| 3.52 kB │ gzip: 1.61 kB
| storybook-static/assets/breadcrumb.stories-CkfH0o7s.js
| 3.55 kB │ gzip: 1.52 kB
| storybook-static/assets/card.stories-B9eBmSdv.js
| 3.74 kB │ gzip: 1.63 kB
| storybook-static/assets/navigation-menu.stories-y8VEFDG7.js
| 3.86 kB │ gzip: 1.62 kB
| storybook-static/assets/resizable.stories-Bfn9K0Nk.js
| 3.96 kB │ gzip: 1.46 kB
| storybook-static/assets/specimens-CfJadLKx.js
| 4.13 kB │ gzip: 1.36 kB
| storybook-static/assets/sonner.stories-C9ye_86f.js
| 4.22 kB │ gzip: 1.83 kB
| storybook-static/assets/checkbox.stories-D4QqZExp.js
| 4.39 kB │ gzip: 1.66 kB
| storybook-static/assets/date-picker.stories-CXxvbfRt.js
| 4.45 kB │ gzip: 1.69 kB
| storybook-static/assets/slider.stories-BaEcELmo.js
| 4.53 kB │ gzip: 1.86 kB
| storybook-static/assets/org-chart-page-previews-B9UHOhrw.js
| 4.70 kB │ gzip: 2.05 kB
| storybook-static/assets/carousel.stories-CFBnwgrn.js
| 4.75 kB │ gzip: 1.91 kB
| storybook-static/assets/layout.stories-B5WhBKHK.js
| 4.79 kB │ gzip: 1.92 kB
| storybook-static/assets/table.stories-SuBClsGw.js
| 4.86 kB │ gzip: 2.02 kB
| storybook-static/assets/combobox.stories-CESx8Ovx.js
| 5.03 kB │ gzip: 2.07 kB
| storybook-static/assets/accordion.stories-C3OMv2ip.js
| 5.05 kB │ gzip: 1.82 kB
| storybook-static/assets/OrgChart-DZlWXlj3-StGMIe9Z.js
| 5.35 kB │ gzip: 1.95 kB
| storybook-static/assets/dialog.stories-DGXlEQmD.js
| 5.53 kB │ gzip: 2.13 kB
| storybook-static/assets/toggle.stories-DdsH4L9p.js
| 5.81 kB │ gzip: 2.13 kB
| storybook-static/assets/data-table.stories-DRD5_UXH.js
| 5.92 kB │ gzip: 2.52 kB
| storybook-static/assets/textarea.stories-C4WSH5RY.js
| 5.99 kB │ gzip: 2.44 kB
| storybook-static/assets/runtime-loader.stories-BTlqK2s3.js
| 6.18 kB │ gzip: 2.45 kB
| storybook-static/assets/toggle-group.stories-CbADHYlr.js
| 6.57 kB │ gzip: 2.23 kB
| storybook-static/assets/react-Q1GcV6wX.js
| 7.87 kB │ gzip: 3.01 kB
| storybook-static/assets/input.stories-BIkica6o.js
| 8.32 kB │ gzip: 3.05 kB
| storybook-static/assets/button.stories-D8c2hiIQ.js
| 9.65 kB │ gzip: 3.62 kB
| storybook-static/assets/select.stories-C3Bu4-JC.js
| 10.52 kB │ gzip: 3.39 kB
| storybook-static/assets/tabs.stories-BkbEXPXb.js
| 11.57 kB │ gzip: 4.13 kB
| storybook-static/assets/org-chart.stories-DY26ETCZ.js
| 12.54 kB │ gzip: 4.16 kB
| storybook-static/assets/designer-theme.stories-DcOn8dQk.js
| 14.62 kB │ gzip: 5.52 kB
| storybook-static/assets/gnb.stories-DoBpBpnv.js
| 16.56 kB │ gzip: 5.83 kB
| storybook-static/assets/theme-CZw7CMzf.js
| 18.61 kB │ gzip: 3.18 kB
| storybook-static/assets/lnb.stories-IcrUvnU4.js
| 23.06 kB │ gzip: 6.43 kB
| storybook-static/assets/dashboard-layout.stories-BsHMb7vS.js
| 23.84 kB │ gzip: 6.25 kB
| storybook-static/vite-inject-mocker-entry.js
| 27.84 kB │ gzip: 9.66 kB
| storybook-static/assets/reference-data-Dp4dBiCx.js
| 40.42 kB │ gzip: 9.43 kB
| storybook-static/assets/runtime-theme.stories-BzbQhxD8.js
| 61.92 kB │ gzip: 11.60 kB
| storybook-static/assets/org-chart-expanded.stories-CjNJ1pKM.js
| 79.03 kB │ gzip: 10.07 kB
| storybook-static/assets/react-18-BvgwGLVw.js
| 207.62 kB │ gzip: 65.12 kB
| storybook-static/assets/core-component-preview-8X6qo9xO.js
| 258.40 kB │ gzip: 146.05 kB
| storybook-static/assets/sw-header.stories-BN0C1_7E.js
| 755.22 kB │ gzip: 356.75 kB
| storybook-static/assets/reference-CABTZJen.js
| 1,644.48 kB │ gzip: 270.35 kB
| storybook-static/assets/iframe-yx4EHWsw.js
| 1,754.32 kB │ gzip: 503.66 kB
| storybook-static/assets/style-CNeiB0x2.js
| 2,359.94 kB │ gzip: 1,631.23 kB
|
! Vite [plugin builtin:vite-reporter]
| (!) Some chunks are larger than 500 kB after minification. Consider:
| - Using dynamic import() to code-split the application
| - Use build.rolldownOptions.output.codeSplitting to improve chunking:
| ]8;;https://rolldown.rs/reference/OutputOptions.codeSplittinghttps://rolldown.rs/reference/OutputOptions.codeSplitting]8;;
| - Adjust chunk size limit for this warning via
| build.chunkSizeWarningLimit.
| Vite ✓ built in 8.01s
|
! Vite [PLUGIN_TIMINGS] JavaScript callbacks ran for 7.0s of this 8.0s
| build (88%).
| The slowest callbacks, timed inside each callback (the wait before a
| callback starts is excluded, the time it awaits is included):
| - plugin storybook:react-docgen-plugin transform (63%, 5.0s, 3104
| calls)
| Additional callback time came from the callbacks below and from
| callbacks under 1s.
| 3 callbacks are listed without a time. Their calls overlapped, so the
| time inside one call includes work from other calls. To find their
| cost, profile the build with `node --cpu-prof`:
| - plugin vite:asset load (31 calls)
| - plugin @tailwindcss/vite:generate:build transform (20 calls)
| - plugin vite:css transform (20 calls)
| See ]8;;https://rolldown.rs/reference/InputOptions.checks#bundlertimingshttps://rolldown.rs/reference/InputOptions.checks#bundlertimings]8;;
| for more details.
|
o Output directory: D:/디자인시스템/HMDesign-SW/storybook-static
|
— Storybook build completed successfully
@@ -0,0 +1,422 @@
> hm-design-system-poc@0.1.0 prebuild-storybook
> npm run check:theme-defaults && npm run build:packages
> hm-design-system-poc@0.1.0 check:theme-defaults
> node scripts/theme-defaults.mjs --check
Theme defaults: 92 JSON colors / 94 contract defaults; generated outputs match
> hm-design-system-poc@0.1.0 build:packages
> npm run build:org-chart && npm run build:ui && npm run build:center-graphic && npm run build:org-chart-react && npm run build:sw
> hm-design-system-poc@0.1.0 build:org-chart
> npm run build -w @hm-design/org-chart
> @hm-design/org-chart@0.1.0 build
> node build.mjs
vite v8.3.0 building client environment for production...
transforming...
✓ 70 modules transformed.
rendering chunks...
computing gzip size...
dist/index.js 2,450.52 kB │ gzip: 1,648.92 kB
✓ built in 108ms
vite v8.3.0 building client environment for production...
transforming...
✓ 70 modules transformed.
rendering chunks...
computing gzip size...
dist/orgchart.browser.js 2,456.85 kB │ gzip: 1,649.32 kB
✓ built in 91ms
> hm-design-system-poc@0.1.0 build:ui
> npm run build -w @hm-design/ui
> @hm-design/ui@0.1.0 build
> node ../../scripts/build-package.mjs ui
vite v8.3.0 building client environment for production...
transforming...
✓ 70 modules transformed.
rendering chunks...
computing gzip size...
dist/theme/index.js 25.18 kB │ gzip: 3.98 kB
dist/index.js 120.43 kB │ gzip: 21.30 kB
✓ built in 63ms
> hm-design-system-poc@0.1.0 build:center-graphic
> npm run build -w @hm-design/center-graphic
> @hm-design/center-graphic@0.1.0 build
> node ../../scripts/build-package.mjs center-graphic
vite v8.3.0 building client environment for production...
transforming...
✓ 145 modules transformed.
rendering chunks...
computing gzip size...
dist/style.css 88.68 kB │ gzip: 20.14 kB
dist/reference.js 0.65 kB │ gzip: 0.23 kB
dist/index.js 1.86 kB │ gzip: 0.84 kB
dist/FacilityBatch-PtW_fbvn.js 1,675.84 kB │ gzip: 276.13 kB
✓ built in 120ms
> hm-design-system-poc@0.1.0 build:org-chart-react
> npm run build -w @hm-design/org-chart-react
> @hm-design/org-chart-react@0.1.0 build
> node build.mjs
vite v8.3.0 building client environment for production...
transforming...
✓ 5 modules transformed.
rendering chunks...
computing gzip size...
dist/index.js 0.09 kB │ gzip: 0.09 kB
dist/hm-dialog.js 4.39 kB │ gzip: 1.80 kB
dist/OrgChart-DZlWXlj3.js 10.50 kB │ gzip: 2.63 kB
✓ built in 35ms
> hm-design-system-poc@0.1.0 build:sw
> npm run build -w @hm-design/sw
> @hm-design/sw@0.1.0 build
> node build.mjs
vite v8.3.0 building client environment for production...
transforming...
✓ 69 modules transformed.
rendering chunks...
computing gzip size...
dist/styles.css 100.39 kB │ gzip: 23.57 kB
dist/index.js 712.25 kB │ gzip: 337.98 kB
✓ built in 145ms
> hm-design-system-poc@0.1.0 build-storybook
> storybook build -o storybook-static --disable-telemetry
T Building storybook v10.6.1
|
o Cleaning outputDir: storybook-static
|
o Loading presets
|
o Building manager..
|
• Building open services..
|
• Building preview..
|
• Copying static files: public\fonts at storybook-static\fonts
|
• Copying static files: themes at storybook-static\themes
| Vite vite v8.3.0 building client environment for production...
transforming...
Found 1 warning while optimizing generated CSS:
│ }
│ .bg-\[var\(\.\.\.\)\] {
│ background-color: var(...);
┆ ^-- Unexpected token Delim('.')
┆
│ }
│ .bg-background {
✓ 3104 modules transformed.
|
! Vite [lightningcss minify] 'host-context' is not recognized as a valid
| pseudo-class. Did you mean '::host-context' (pseudo-element) or is
| this a typo?
| 1322 | background-color: var(--hm-orgchart-dialog-close-hover);
| 1323 | }
| 1324 | :host-context(.dark) .hm-orgchart-employee-dialog-close:hover,
| | ^
| 1325 | .dark .hm-orgchart-employee-dialog-close:hover {
| 1326 | background-color: color-mix(in oklab,
| var(--hm-orgchart-dialog-close-hover) 50%, transparent);
rendering chunks...
computing gzip size...
| Vite storybook-static/assets/input-26-11656-BIXt51ww.png
| 5.09 kB
| storybook-static/iframe.html
| 19.07 kB │ gzip: 5.42 kB
| storybook-static/assets/NotoSansKR-variable-k7NQXPol.ttf
| 10,414.58 kB
| storybook-static/assets/sw-header-dropdown-BSCl7vok.css
| 0.54 kB │ gzip: 0.25 kB
| storybook-static/assets/data-table-x0avmA1M.css
| 0.89 kB │ gzip: 0.32 kB
| storybook-static/assets/department-colors-preview-C8o8mgn-.css
| 1.12 kB │ gzip: 0.39 kB
| storybook-static/assets/org-chart-stories-CVVpQeIs.css
| 1.15 kB │ gzip: 0.39 kB
| storybook-static/assets/org-chart-expanded-BQqXfdmZ.css
| 1.34 kB │ gzip: 0.43 kB
| storybook-static/assets/story-page-B9TObVPB.css
| 1.74 kB │ gzip: 0.49 kB
| storybook-static/assets/designer-theme-Bv3QXGf0.css
| 2.88 kB │ gzip: 0.85 kB
| storybook-static/assets/reference-CElszmAj.css
| 3.13 kB │ gzip: 0.87 kB
| storybook-static/assets/center-stories-MLQreMPw.css
| 6.77 kB │ gzip: 1.49 kB
| storybook-static/assets/dashboard-layout-cwHZMCdB.css
| 6.90 kB │ gzip: 1.21 kB
| storybook-static/assets/engine-DrWcIejL.css
| 15.64 kB │ gzip: 3.10 kB
| storybook-static/assets/center-shared-CBSMPY7X.css
| 55.67 kB │ gzip: 10.48 kB
| storybook-static/assets/sw-header-CUYjY3HM.css
| 73.13 kB │ gzip: 13.58 kB
| storybook-static/assets/style-BhhUui7W.css
| 93.80 kB │ gzip: 12.41 kB
| storybook-static/assets/iframe-BW1xNYqB.css
| 237.20 kB │ gzip: 36.15 kB
| storybook-static/assets/iframe-C2Ijtbuw.js
| 0.04 kB │ gzip: 0.06 kB
| storybook-static/assets/center-stories-Cr38slYE.js
| 0.09 kB │ gzip: 0.11 kB
| storybook-static/assets/org-chart-stories-BU9b3y-N.js
| 0.09 kB │ gzip: 0.11 kB
| storybook-static/assets/chart-column-DpiKBR5R.js
| 0.41 kB │ gzip: 0.29 kB
| storybook-static/assets/sw-header-dropdown.stories-CwPUbLU3.js
| 0.45 kB │ gzip: 0.32 kB
| storybook-static/assets/layout-grid-DoBd3gNc.js
| 0.48 kB │ gzip: 0.28 kB
| storybook-static/assets/italic-_Mzf7EWp.js
| 0.58 kB │ gzip: 0.36 kB
| storybook-static/assets/org-chart-full-composition.stories-C8ILQ5mU.js
| 0.59 kB │ gzip: 0.39 kB
| storybook-static/assets/org-chart-p1.stories-GdxcPbhX.js
| 0.59 kB │ gzip: 0.40 kB
| storybook-static/assets/org-chart-department-colors.stories-wqlPV7Gm.js
| 0.60 kB │ gzip: 0.39 kB
| storybook-static/assets/settings-DwTwWkL3.js
| 0.62 kB │ gzip: 0.34 kB
| storybook-static/assets/org-chart-summary.stories-CiewzCY0.js
| 0.76 kB │ gzip: 0.39 kB
| storybook-static/assets/center-information.stories-DBOI5xJm.js
| 0.94 kB │ gzip: 0.63 kB
| storybook-static/assets/sample-users-CAqvNHXG.js
| 0.94 kB │ gzip: 0.67 kB
| storybook-static/assets/center-spatial.stories-OpQYHOa5.js
| 0.97 kB │ gzip: 0.64 kB
| storybook-static/assets/rolldown-runtime-DkW27tQK.js
| 1.19 kB │ gzip: 0.67 kB
| storybook-static/assets/preload-helper-VEOc_cSF.js
| 1.33 kB │ gzip: 0.75 kB
| storybook-static/assets/center-title.stories-DRm0gD4S.js
| 1.36 kB │ gzip: 0.88 kB
| storybook-static/assets/org-chart-overview-internal.stories-DePzsuN4.js
| 1.43 kB │ gzip: 0.68 kB
| storybook-static/assets/org-chart-cards.stories-2oHAoXvE.js
| 1.60 kB │ gzip: 0.92 kB
| storybook-static/assets/color.stories-CduR6VWP.js
| 1.80 kB │ gzip: 1.03 kB
| storybook-static/assets/center-facility.stories-1va29H8K.js
| 1.90 kB │ gzip: 1.07 kB
| storybook-static/assets/loading-screen.stories-B__9iwMY.js
| 1.96 kB │ gzip: 1.03 kB
| storybook-static/assets/story-board-DIRZiqIX.js
| 1.99 kB │ gzip: 0.89 kB
| storybook-static/assets/skeleton.stories-DFlPsZvN.js
| 2.10 kB │ gzip: 1.00 kB
| storybook-static/assets/story-page-DKKaAfvg.js
| 2.13 kB │ gzip: 0.69 kB
| storybook-static/assets/verification-state-C1QH-6Td.js
| 2.15 kB │ gzip: 1.05 kB
| storybook-static/assets/hover-card.stories-CjlpW3dD.js
| 2.34 kB │ gzip: 1.08 kB
| storybook-static/assets/alert-dialog.stories-C_PaKmoT.js
| 2.48 kB │ gzip: 1.07 kB
| storybook-static/assets/separator.stories-dztanf4R.js
| 2.56 kB │ gzip: 1.16 kB
| storybook-static/assets/dropdown-menu.stories-D7aAEo04.js
| 2.58 kB │ gzip: 1.28 kB
| storybook-static/assets/badge.stories-B_PyBGwt.js
| 2.61 kB │ gzip: 1.23 kB
| storybook-static/assets/tooltip.stories-DHulF3J2.js
| 2.65 kB │ gzip: 1.23 kB
| storybook-static/assets/publisher-regression.stories-IMADB1_-.js
| 2.70 kB │ gzip: 1.15 kB
| storybook-static/assets/calendar.stories-BUBkFt6X.js
| 2.79 kB │ gzip: 1.31 kB
| storybook-static/assets/switch.stories-C7x75XRD.js
| 2.86 kB │ gzip: 1.28 kB
| storybook-static/assets/reference-CzvcR5qJ.js
| 2.88 kB │ gzip: 1.24 kB
| storybook-static/assets/context-menu.stories-BjT7sL2t.js
| 2.95 kB │ gzip: 1.47 kB
| storybook-static/assets/center-shared-5YMvceaA.js
| 2.96 kB │ gzip: 1.36 kB
| storybook-static/assets/scroll-area.stories-DnJp7lvg.js
| 3.02 kB │ gzip: 1.30 kB
| storybook-static/assets/popover.stories-_jMm21-V.js
| 3.05 kB │ gzip: 1.30 kB
| storybook-static/assets/aspect-ratio.stories-BWETPes3.js
| 3.06 kB │ gzip: 1.51 kB
| storybook-static/assets/typography.stories-Dyeh6lq6.js
| 3.07 kB │ gzip: 1.42 kB
| storybook-static/assets/pagination.stories-bqK1tES3.js
| 3.12 kB │ gzip: 1.50 kB
| storybook-static/assets/alert.stories-DF-JBAyG.js
| 3.16 kB │ gzip: 1.30 kB
| storybook-static/assets/label.stories-lKaTDheO.js
| 3.19 kB │ gzip: 1.39 kB
| storybook-static/assets/collapsible.stories-7EHEDHCV.js
| 3.19 kB │ gzip: 1.50 kB
| storybook-static/assets/drawer.stories-BIE0Jg6N.js
| 3.23 kB │ gzip: 1.47 kB
| storybook-static/assets/radio-group.stories-Qg2WoP84.js
| 3.24 kB │ gzip: 1.47 kB
| storybook-static/assets/avatar.stories-D_fFlwhG.js
| 3.30 kB │ gzip: 1.45 kB
| storybook-static/assets/page-header.stories-DcvSabHi.js
| 3.32 kB │ gzip: 1.30 kB
| storybook-static/assets/menubar.stories-B9wSx0Bf.js
| 3.33 kB │ gzip: 1.39 kB
| storybook-static/assets/command.stories-Ci8OudxU.js
| 3.33 kB │ gzip: 1.58 kB
| storybook-static/assets/center-overview.stories-D6iiBBF0.js
| 3.36 kB │ gzip: 1.77 kB
| storybook-static/assets/filter-bar.stories-4azgJAXb.js
| 3.43 kB │ gzip: 1.72 kB
| storybook-static/assets/sheet.stories-B75WuBVv.js
| 3.51 kB │ gzip: 1.44 kB
| storybook-static/assets/progress.stories-BYIyqVpe.js
| 3.52 kB │ gzip: 1.60 kB
| storybook-static/assets/breadcrumb.stories-CaT23aSa.js
| 3.55 kB │ gzip: 1.53 kB
| storybook-static/assets/card.stories-W_BlQ7HI.js
| 3.74 kB │ gzip: 1.63 kB
| storybook-static/assets/navigation-menu.stories-Cj-FwZvU.js
| 3.86 kB │ gzip: 1.62 kB
| storybook-static/assets/resizable.stories-olfYybED.js
| 3.96 kB │ gzip: 1.47 kB
| storybook-static/assets/specimens-BWHSykrP.js
| 4.13 kB │ gzip: 1.37 kB
| storybook-static/assets/sonner.stories-DFFh1Il5.js
| 4.22 kB │ gzip: 1.83 kB
| storybook-static/assets/checkbox.stories-DKf9QgFa.js
| 4.39 kB │ gzip: 1.66 kB
| storybook-static/assets/date-picker.stories-BUOYLiRT.js
| 4.45 kB │ gzip: 1.68 kB
| storybook-static/assets/slider.stories-wnVIyMA_.js
| 4.53 kB │ gzip: 1.86 kB
| storybook-static/assets/org-chart-page-previews-Cn1V8VsY.js
| 4.70 kB │ gzip: 2.05 kB
| storybook-static/assets/carousel.stories-CSLYQEO0.js
| 4.75 kB │ gzip: 1.91 kB
| storybook-static/assets/layout.stories-B9tSy8dZ.js
| 4.79 kB │ gzip: 1.92 kB
| storybook-static/assets/table.stories-C8R2AHOe.js
| 4.86 kB │ gzip: 2.02 kB
| storybook-static/assets/combobox.stories-L3-325iN.js
| 5.03 kB │ gzip: 2.07 kB
| storybook-static/assets/accordion.stories-Ckgl_KDR.js
| 5.05 kB │ gzip: 1.81 kB
| storybook-static/assets/OrgChart-DZlWXlj3-B1As9Irb.js
| 5.35 kB │ gzip: 1.95 kB
| storybook-static/assets/dialog.stories-4K6-xjHX.js
| 5.53 kB │ gzip: 2.13 kB
| storybook-static/assets/toggle.stories-CR020H9k.js
| 5.81 kB │ gzip: 2.13 kB
| storybook-static/assets/data-table.stories-DpUf_oZv.js
| 5.92 kB │ gzip: 2.52 kB
| storybook-static/assets/textarea.stories-DY7qK2k5.js
| 5.99 kB │ gzip: 2.43 kB
| storybook-static/assets/runtime-loader.stories-CuO_gd5n.js
| 6.18 kB │ gzip: 2.44 kB
| storybook-static/assets/toggle-group.stories-S8Pg4vrJ.js
| 6.57 kB │ gzip: 2.23 kB
| storybook-static/assets/react-Q1GcV6wX.js
| 7.87 kB │ gzip: 3.01 kB
| storybook-static/assets/input.stories-CfI8Ka6g.js
| 8.32 kB │ gzip: 3.05 kB
| storybook-static/assets/button.stories-DrNOjnzN.js
| 9.65 kB │ gzip: 3.62 kB
| storybook-static/assets/select.stories-Ce8N0i9A.js
| 10.52 kB │ gzip: 3.39 kB
| storybook-static/assets/tabs.stories-34fbAscx.js
| 11.57 kB │ gzip: 4.13 kB
| storybook-static/assets/org-chart.stories-CSXs_inh.js
| 12.54 kB │ gzip: 4.16 kB
| storybook-static/assets/designer-theme.stories-DLyYiHPD.js
| 14.62 kB │ gzip: 5.51 kB
| storybook-static/assets/gnb.stories-DZIeMpkp.js
| 16.56 kB │ gzip: 5.83 kB
| storybook-static/assets/theme-CZw7CMzf.js
| 18.61 kB │ gzip: 3.18 kB
| storybook-static/assets/lnb.stories-DiuLXiPF.js
| 23.06 kB │ gzip: 6.43 kB
| storybook-static/assets/dashboard-layout.stories-DIF2K0IC.js
| 23.84 kB │ gzip: 6.26 kB
| storybook-static/vite-inject-mocker-entry.js
| 27.84 kB │ gzip: 9.66 kB
| storybook-static/assets/reference-data-Dp4dBiCx.js
| 40.42 kB │ gzip: 9.43 kB
| storybook-static/assets/runtime-theme.stories-KsXiA_U6.js
| 61.92 kB │ gzip: 11.60 kB
| storybook-static/assets/org-chart-expanded.stories-EwBJZVYq.js
| 79.03 kB │ gzip: 10.07 kB
| storybook-static/assets/react-18-DVWgMqFw.js
| 207.62 kB │ gzip: 65.12 kB
| storybook-static/assets/core-component-preview-6q_xPzUt.js
| 258.40 kB │ gzip: 146.05 kB
| storybook-static/assets/sw-header.stories-B8TX4vCI.js
| 755.24 kB │ gzip: 356.76 kB
| storybook-static/assets/reference-CFT3e7tu.js
| 1,644.48 kB │ gzip: 270.35 kB
| storybook-static/assets/iframe-C-f76Kkf.js
| 1,754.32 kB │ gzip: 503.68 kB
| storybook-static/assets/style-CNeiB0x2.js
| 2,359.94 kB │ gzip: 1,631.23 kB
|
! Vite [plugin builtin:vite-reporter]
| (!) Some chunks are larger than 500 kB after minification. Consider:
| - Using dynamic import() to code-split the application
| - Use build.rolldownOptions.output.codeSplitting to improve chunking:
| ]8;;https://rolldown.rs/reference/OutputOptions.codeSplittinghttps://rolldown.rs/reference/OutputOptions.codeSplitting]8;;
| - Adjust chunk size limit for this warning via
| build.chunkSizeWarningLimit.
| Vite ✓ built in 5.46s
|
! Vite [PLUGIN_TIMINGS] JavaScript callbacks ran for 4.8s of this 5.4s
| build (88%).
| The slowest callbacks, timed inside each callback (the wait before a
| callback starts is excluded, the time it awaits is included):
| - plugin storybook:react-docgen-plugin transform (62%, 3.4s, 3104
| calls)
| Additional callback time came from the callbacks below and from
| callbacks under 1s.
| 3 callbacks are listed without a time. Their calls overlapped, so the
| time inside one call includes work from other calls. To find their
| cost, profile the build with `node --cpu-prof`:
| - plugin vite:asset load (31 calls)
| - plugin @tailwindcss/vite:generate:build transform (20 calls)
| - plugin vite:css transform (20 calls)
| See ]8;;https://rolldown.rs/reference/InputOptions.checks#bundlertimingshttps://rolldown.rs/reference/InputOptions.checks#bundlertimings]8;;
| for more details.
|
o Output directory: D:/디자인시스템/HMDesign-SW/storybook-static
|
— Storybook build completed successfully
@@ -0,0 +1,422 @@
> hm-design-system-poc@0.1.0 prebuild-storybook
> npm run check:theme-defaults && npm run build:packages
> hm-design-system-poc@0.1.0 check:theme-defaults
> node scripts/theme-defaults.mjs --check
Theme defaults: 92 JSON colors / 94 contract defaults; generated outputs match
> hm-design-system-poc@0.1.0 build:packages
> npm run build:org-chart && npm run build:ui && npm run build:center-graphic && npm run build:org-chart-react && npm run build:sw
> hm-design-system-poc@0.1.0 build:org-chart
> npm run build -w @hm-design/org-chart
> @hm-design/org-chart@0.1.0 build
> node build.mjs
vite v8.3.0 building client environment for production...
transforming...
✓ 70 modules transformed.
rendering chunks...
computing gzip size...
dist/index.js 2,450.52 kB │ gzip: 1,648.92 kB
✓ built in 132ms
vite v8.3.0 building client environment for production...
transforming...
✓ 70 modules transformed.
rendering chunks...
computing gzip size...
dist/orgchart.browser.js 2,456.85 kB │ gzip: 1,649.32 kB
✓ built in 78ms
> hm-design-system-poc@0.1.0 build:ui
> npm run build -w @hm-design/ui
> @hm-design/ui@0.1.0 build
> node ../../scripts/build-package.mjs ui
vite v8.3.0 building client environment for production...
transforming...
✓ 70 modules transformed.
rendering chunks...
computing gzip size...
dist/theme/index.js 25.18 kB │ gzip: 3.98 kB
dist/index.js 120.43 kB │ gzip: 21.30 kB
✓ built in 61ms
> hm-design-system-poc@0.1.0 build:center-graphic
> npm run build -w @hm-design/center-graphic
> @hm-design/center-graphic@0.1.0 build
> node ../../scripts/build-package.mjs center-graphic
vite v8.3.0 building client environment for production...
transforming...
✓ 145 modules transformed.
rendering chunks...
computing gzip size...
dist/style.css 88.68 kB │ gzip: 20.14 kB
dist/reference.js 0.65 kB │ gzip: 0.23 kB
dist/index.js 1.86 kB │ gzip: 0.84 kB
dist/FacilityBatch-PtW_fbvn.js 1,675.84 kB │ gzip: 276.13 kB
✓ built in 145ms
> hm-design-system-poc@0.1.0 build:org-chart-react
> npm run build -w @hm-design/org-chart-react
> @hm-design/org-chart-react@0.1.0 build
> node build.mjs
vite v8.3.0 building client environment for production...
transforming...
✓ 5 modules transformed.
rendering chunks...
computing gzip size...
dist/index.js 0.09 kB │ gzip: 0.09 kB
dist/hm-dialog.js 4.39 kB │ gzip: 1.80 kB
dist/OrgChart-DZlWXlj3.js 10.50 kB │ gzip: 2.63 kB
✓ built in 29ms
> hm-design-system-poc@0.1.0 build:sw
> npm run build -w @hm-design/sw
> @hm-design/sw@0.1.0 build
> node build.mjs
vite v8.3.0 building client environment for production...
transforming...
✓ 69 modules transformed.
rendering chunks...
computing gzip size...
dist/styles.css 100.39 kB │ gzip: 23.57 kB
dist/index.js 712.25 kB │ gzip: 337.98 kB
✓ built in 286ms
> hm-design-system-poc@0.1.0 build-storybook
> storybook build -o storybook-static --disable-telemetry
T Building storybook v10.6.1
|
o Cleaning outputDir: storybook-static
|
o Loading presets
|
o Building manager..
|
• Building open services..
|
• Building preview..
|
• Copying static files: public\fonts at storybook-static\fonts
|
• Copying static files: themes at storybook-static\themes
| Vite vite v8.3.0 building client environment for production...
transforming...
Found 1 warning while optimizing generated CSS:
│ }
│ .bg-\[var\(\.\.\.\)\] {
│ background-color: var(...);
┆ ^-- Unexpected token Delim('.')
┆
│ }
│ .bg-background {
✓ 3104 modules transformed.
|
! Vite [lightningcss minify] 'host-context' is not recognized as a valid
| pseudo-class. Did you mean '::host-context' (pseudo-element) or is
| this a typo?
| 1322 | background-color: var(--hm-orgchart-dialog-close-hover);
| 1323 | }
| 1324 | :host-context(.dark) .hm-orgchart-employee-dialog-close:hover,
| | ^
| 1325 | .dark .hm-orgchart-employee-dialog-close:hover {
| 1326 | background-color: color-mix(in oklab,
| var(--hm-orgchart-dialog-close-hover) 50%, transparent);
rendering chunks...
computing gzip size...
| Vite storybook-static/assets/input-26-11656-BIXt51ww.png
| 5.09 kB
| storybook-static/iframe.html
| 19.07 kB │ gzip: 5.42 kB
| storybook-static/assets/NotoSansKR-variable-k7NQXPol.ttf
| 10,414.58 kB
| storybook-static/assets/sw-header-dropdown-BSCl7vok.css
| 0.54 kB │ gzip: 0.25 kB
| storybook-static/assets/data-table-x0avmA1M.css
| 0.89 kB │ gzip: 0.32 kB
| storybook-static/assets/department-colors-preview-C8o8mgn-.css
| 1.12 kB │ gzip: 0.39 kB
| storybook-static/assets/org-chart-stories-CVVpQeIs.css
| 1.15 kB │ gzip: 0.39 kB
| storybook-static/assets/org-chart-expanded-BQqXfdmZ.css
| 1.34 kB │ gzip: 0.43 kB
| storybook-static/assets/story-page-B9TObVPB.css
| 1.74 kB │ gzip: 0.49 kB
| storybook-static/assets/designer-theme-Bv3QXGf0.css
| 2.88 kB │ gzip: 0.85 kB
| storybook-static/assets/reference-CElszmAj.css
| 3.13 kB │ gzip: 0.87 kB
| storybook-static/assets/center-stories-MLQreMPw.css
| 6.77 kB │ gzip: 1.49 kB
| storybook-static/assets/dashboard-layout-cwHZMCdB.css
| 6.90 kB │ gzip: 1.21 kB
| storybook-static/assets/engine-DrWcIejL.css
| 15.64 kB │ gzip: 3.10 kB
| storybook-static/assets/center-shared-CBSMPY7X.css
| 55.67 kB │ gzip: 10.48 kB
| storybook-static/assets/sw-header-CUYjY3HM.css
| 73.13 kB │ gzip: 13.58 kB
| storybook-static/assets/style-BhhUui7W.css
| 93.80 kB │ gzip: 12.41 kB
| storybook-static/assets/iframe-BW1xNYqB.css
| 237.20 kB │ gzip: 36.15 kB
| storybook-static/assets/iframe-BND_ij75.js
| 0.04 kB │ gzip: 0.06 kB
| storybook-static/assets/center-stories-Cr38slYE.js
| 0.09 kB │ gzip: 0.11 kB
| storybook-static/assets/org-chart-stories-BU9b3y-N.js
| 0.09 kB │ gzip: 0.11 kB
| storybook-static/assets/chart-column-BmZwTnfz.js
| 0.41 kB │ gzip: 0.29 kB
| storybook-static/assets/sw-header-dropdown.stories-B70Obnnj.js
| 0.45 kB │ gzip: 0.32 kB
| storybook-static/assets/layout-grid-CMxoQykG.js
| 0.48 kB │ gzip: 0.28 kB
| storybook-static/assets/italic-txV71QLW.js
| 0.58 kB │ gzip: 0.35 kB
| storybook-static/assets/org-chart-full-composition.stories-CWV8lwpL.js
| 0.59 kB │ gzip: 0.39 kB
| storybook-static/assets/org-chart-p1.stories-CLN1jfvC.js
| 0.59 kB │ gzip: 0.40 kB
| storybook-static/assets/org-chart-department-colors.stories-CdJAD27-.js
| 0.60 kB │ gzip: 0.39 kB
| storybook-static/assets/settings-MWnGhGZk.js
| 0.62 kB │ gzip: 0.34 kB
| storybook-static/assets/org-chart-summary.stories-qNk87UMX.js
| 0.76 kB │ gzip: 0.39 kB
| storybook-static/assets/center-information.stories-BOTWb_cK.js
| 0.94 kB │ gzip: 0.63 kB
| storybook-static/assets/sample-users-CAqvNHXG.js
| 0.94 kB │ gzip: 0.67 kB
| storybook-static/assets/center-spatial.stories-BMTd60ec.js
| 0.97 kB │ gzip: 0.64 kB
| storybook-static/assets/rolldown-runtime-DkW27tQK.js
| 1.19 kB │ gzip: 0.67 kB
| storybook-static/assets/preload-helper-VEOc_cSF.js
| 1.33 kB │ gzip: 0.75 kB
| storybook-static/assets/center-title.stories-BhJaDLjN.js
| 1.36 kB │ gzip: 0.88 kB
| storybook-static/assets/org-chart-overview-internal.stories-DozDyomh.js
| 1.43 kB │ gzip: 0.68 kB
| storybook-static/assets/org-chart-cards.stories-DncuCRkc.js
| 1.60 kB │ gzip: 0.92 kB
| storybook-static/assets/color.stories-D-sbnsyq.js
| 1.80 kB │ gzip: 1.03 kB
| storybook-static/assets/center-facility.stories-B6UB0vOm.js
| 1.90 kB │ gzip: 1.07 kB
| storybook-static/assets/loading-screen.stories-B2hNfvjn.js
| 1.96 kB │ gzip: 1.03 kB
| storybook-static/assets/story-board-DbCnlBub.js
| 1.99 kB │ gzip: 0.89 kB
| storybook-static/assets/skeleton.stories-D0TOnXPZ.js
| 2.10 kB │ gzip: 1.00 kB
| storybook-static/assets/story-page-NviG8jVQ.js
| 2.13 kB │ gzip: 0.69 kB
| storybook-static/assets/verification-state-TLRGhnTS.js
| 2.15 kB │ gzip: 1.05 kB
| storybook-static/assets/hover-card.stories-Duxs_WfN.js
| 2.34 kB │ gzip: 1.08 kB
| storybook-static/assets/alert-dialog.stories-Bf2Yn_JE.js
| 2.48 kB │ gzip: 1.08 kB
| storybook-static/assets/separator.stories-CF-6tfX0.js
| 2.56 kB │ gzip: 1.16 kB
| storybook-static/assets/dropdown-menu.stories-DJpVX3c2.js
| 2.58 kB │ gzip: 1.28 kB
| storybook-static/assets/badge.stories-DRENhc-L.js
| 2.61 kB │ gzip: 1.23 kB
| storybook-static/assets/tooltip.stories-D2sI3-nj.js
| 2.65 kB │ gzip: 1.23 kB
| storybook-static/assets/publisher-regression.stories-BhwDJkC6.js
| 2.70 kB │ gzip: 1.14 kB
| storybook-static/assets/calendar.stories-B6L1E1ig.js
| 2.79 kB │ gzip: 1.30 kB
| storybook-static/assets/switch.stories-qrFKEVn_.js
| 2.86 kB │ gzip: 1.28 kB
| storybook-static/assets/reference-BNF4vGzV.js
| 2.88 kB │ gzip: 1.24 kB
| storybook-static/assets/context-menu.stories-D71JJUlJ.js
| 2.95 kB │ gzip: 1.47 kB
| storybook-static/assets/center-shared-vCSD7jKJ.js
| 2.96 kB │ gzip: 1.36 kB
| storybook-static/assets/scroll-area.stories-C_Zu1dz4.js
| 3.02 kB │ gzip: 1.30 kB
| storybook-static/assets/popover.stories-IP1JKf6V.js
| 3.05 kB │ gzip: 1.30 kB
| storybook-static/assets/aspect-ratio.stories-DfkJgLt5.js
| 3.06 kB │ gzip: 1.51 kB
| storybook-static/assets/typography.stories-BNi63MxZ.js
| 3.07 kB │ gzip: 1.42 kB
| storybook-static/assets/pagination.stories-DcFat-aa.js
| 3.12 kB │ gzip: 1.50 kB
| storybook-static/assets/alert.stories-UWBN2m_d.js
| 3.16 kB │ gzip: 1.29 kB
| storybook-static/assets/label.stories-DtU51tqo.js
| 3.19 kB │ gzip: 1.39 kB
| storybook-static/assets/collapsible.stories-DaoUdkEa.js
| 3.19 kB │ gzip: 1.50 kB
| storybook-static/assets/drawer.stories-sk4Px8e4.js
| 3.23 kB │ gzip: 1.47 kB
| storybook-static/assets/radio-group.stories-B7lWhHCZ.js
| 3.24 kB │ gzip: 1.47 kB
| storybook-static/assets/avatar.stories-BKgND-A1.js
| 3.30 kB │ gzip: 1.45 kB
| storybook-static/assets/page-header.stories-BHGBav5D.js
| 3.32 kB │ gzip: 1.30 kB
| storybook-static/assets/menubar.stories-BJhlGfwp.js
| 3.33 kB │ gzip: 1.39 kB
| storybook-static/assets/command.stories-DvKNhStG.js
| 3.33 kB │ gzip: 1.58 kB
| storybook-static/assets/center-overview.stories-CNJfaYjF.js
| 3.36 kB │ gzip: 1.77 kB
| storybook-static/assets/filter-bar.stories-3r8fbU61.js
| 3.43 kB │ gzip: 1.72 kB
| storybook-static/assets/sheet.stories-fvK8STyk.js
| 3.51 kB │ gzip: 1.44 kB
| storybook-static/assets/progress.stories-qlRTLJp4.js
| 3.52 kB │ gzip: 1.60 kB
| storybook-static/assets/breadcrumb.stories-CtjogBGF.js
| 3.55 kB │ gzip: 1.52 kB
| storybook-static/assets/card.stories-DTiVFkEY.js
| 3.74 kB │ gzip: 1.63 kB
| storybook-static/assets/navigation-menu.stories-B944L6Mw.js
| 3.86 kB │ gzip: 1.62 kB
| storybook-static/assets/resizable.stories-Ctx6awzP.js
| 3.96 kB │ gzip: 1.46 kB
| storybook-static/assets/specimens-CGoGpKOp.js
| 4.13 kB │ gzip: 1.36 kB
| storybook-static/assets/sonner.stories-Dd7eOQPZ.js
| 4.22 kB │ gzip: 1.83 kB
| storybook-static/assets/checkbox.stories-CSWW9qTX.js
| 4.39 kB │ gzip: 1.66 kB
| storybook-static/assets/date-picker.stories-msXZto1d.js
| 4.45 kB │ gzip: 1.68 kB
| storybook-static/assets/slider.stories-BI1THOyA.js
| 4.53 kB │ gzip: 1.86 kB
| storybook-static/assets/org-chart-page-previews-BgTYbXY2.js
| 4.70 kB │ gzip: 2.05 kB
| storybook-static/assets/carousel.stories-C59BwVbC.js
| 4.75 kB │ gzip: 1.91 kB
| storybook-static/assets/layout.stories-DP-wbrns.js
| 4.79 kB │ gzip: 1.92 kB
| storybook-static/assets/table.stories-DtTthfPY.js
| 4.86 kB │ gzip: 2.02 kB
| storybook-static/assets/combobox.stories-DACOm5TI.js
| 5.03 kB │ gzip: 2.07 kB
| storybook-static/assets/accordion.stories-D8ddzKl5.js
| 5.05 kB │ gzip: 1.82 kB
| storybook-static/assets/OrgChart-DZlWXlj3-CufYw9Gu.js
| 5.35 kB │ gzip: 1.95 kB
| storybook-static/assets/dialog.stories-ByFUJMLu.js
| 5.53 kB │ gzip: 2.13 kB
| storybook-static/assets/toggle.stories-BcrufFMD.js
| 5.81 kB │ gzip: 2.12 kB
| storybook-static/assets/data-table.stories-C1t0Gf4P.js
| 5.92 kB │ gzip: 2.51 kB
| storybook-static/assets/textarea.stories-BIz7Y6jk.js
| 5.99 kB │ gzip: 2.43 kB
| storybook-static/assets/runtime-loader.stories-Du2BNudr.js
| 6.18 kB │ gzip: 2.45 kB
| storybook-static/assets/toggle-group.stories-B3eEJmE2.js
| 6.57 kB │ gzip: 2.23 kB
| storybook-static/assets/react-Q1GcV6wX.js
| 7.87 kB │ gzip: 3.01 kB
| storybook-static/assets/input.stories-BV412_dC.js
| 8.32 kB │ gzip: 3.05 kB
| storybook-static/assets/button.stories-C7N36_Bk.js
| 9.65 kB │ gzip: 3.62 kB
| storybook-static/assets/select.stories-B0x2TD8t.js
| 10.52 kB │ gzip: 3.39 kB
| storybook-static/assets/tabs.stories-DZeCa27I.js
| 11.57 kB │ gzip: 4.13 kB
| storybook-static/assets/org-chart.stories-CrlVDUZh.js
| 12.54 kB │ gzip: 4.15 kB
| storybook-static/assets/designer-theme.stories-D55cbzRx.js
| 14.62 kB │ gzip: 5.52 kB
| storybook-static/assets/gnb.stories-DU2rsFoA.js
| 16.56 kB │ gzip: 5.83 kB
| storybook-static/assets/theme-CZw7CMzf.js
| 18.61 kB │ gzip: 3.18 kB
| storybook-static/assets/lnb.stories-Dgj80jo2.js
| 23.06 kB │ gzip: 6.43 kB
| storybook-static/assets/dashboard-layout.stories-DCly8dm7.js
| 23.84 kB │ gzip: 6.25 kB
| storybook-static/vite-inject-mocker-entry.js
| 27.84 kB │ gzip: 9.66 kB
| storybook-static/assets/reference-data-Dp4dBiCx.js
| 40.42 kB │ gzip: 9.43 kB
| storybook-static/assets/runtime-theme.stories-D_pra22q.js
| 61.92 kB │ gzip: 11.60 kB
| storybook-static/assets/org-chart-expanded.stories-BU4d2lC6.js
| 79.03 kB │ gzip: 10.07 kB
| storybook-static/assets/react-18-D2RW7xQa.js
| 207.62 kB │ gzip: 65.12 kB
| storybook-static/assets/core-component-preview-D1IaJpIz.js
| 258.40 kB │ gzip: 146.05 kB
| storybook-static/assets/sw-header.stories-DqVylvl_.js
| 754.96 kB │ gzip: 356.68 kB
| storybook-static/assets/reference-DYpK1MLp.js
| 1,644.48 kB │ gzip: 270.35 kB
| storybook-static/assets/iframe-Dd6GZeg_.js
| 1,754.32 kB │ gzip: 503.64 kB
| storybook-static/assets/style-CNeiB0x2.js
| 2,359.94 kB │ gzip: 1,631.23 kB
|
! Vite [plugin builtin:vite-reporter]
| (!) Some chunks are larger than 500 kB after minification. Consider:
| - Using dynamic import() to code-split the application
| - Use build.rolldownOptions.output.codeSplitting to improve chunking:
| ]8;;https://rolldown.rs/reference/OutputOptions.codeSplittinghttps://rolldown.rs/reference/OutputOptions.codeSplitting]8;;
| - Adjust chunk size limit for this warning via
| build.chunkSizeWarningLimit.
| Vite ✓ built in 8.85s
|
! Vite [PLUGIN_TIMINGS] JavaScript callbacks ran for 7.2s of this 8.8s
| build (82%).
| The slowest callbacks, timed inside each callback (the wait before a
| callback starts is excluded, the time it awaits is included):
| - plugin storybook:react-docgen-plugin transform (57%, 5.1s, 3104
| calls)
| Additional callback time came from the callbacks below and from
| callbacks under 1s.
| 3 callbacks are listed without a time. Their calls overlapped, so the
| time inside one call includes work from other calls. To find their
| cost, profile the build with `node --cpu-prof`:
| - plugin vite:asset load (31 calls)
| - plugin @tailwindcss/vite:generate:build transform (20 calls)
| - plugin vite:css transform (20 calls)
| See ]8;;https://rolldown.rs/reference/InputOptions.checks#bundlertimingshttps://rolldown.rs/reference/InputOptions.checks#bundlertimings]8;;
| for more details.
|
o Output directory: D:/디자인시스템/HMDesign-SW/storybook-static
|
— Storybook build completed successfully
Whitespace-only changes.
Whitespace-only changes.
@@ -0,0 +1,61 @@
{
"baseCommit": "c165753bbe24de6581c66704bde4ba3246049ec2",
"branch": "feature/sw-package",
"scope": "STORYBOOK_ONLY",
"swTypecheck": {
"command": "npm.cmd run typecheck:sw",
"exitCode": 0
},
"swBuild": {
"command": "npm.cmd run build-storybook (prebuild-storybook -> build:packages -> build:sw)",
"exitCode": 0,
"log": "storybook-build-release.txt"
},
"storybookTypecheck": {
"command": "npm.cmd exec -- tsc -p tsconfig.app.json --noEmit",
"exitCode": 0,
"log": "storybook-typecheck-release.txt"
},
"storybookBuild": {
"command": "npm.cmd run build-storybook",
"exitCode": 0,
"log": "storybook-build-release.txt"
},
"browser": {
"integration": {
"status": "PASS",
"checks": 229,
"failures": [],
"errors": []
},
"affectedFollowup": {
"status": "PASS",
"checks": 29,
"failures": [],
"errors": []
},
"overview": {
"status": "PASS",
"checks": 54,
"failures": [],
"errors": []
},
"preservation": {
"status": "PASS",
"checks": 15,
"failures": [],
"errors": []
}
},
"retainedRelativeOrderPreserved": true,
"reportLinks": {
"count": 10,
"missing": []
},
"sourceHashes": {
"src/sw/sw-header.stories.tsx": "474d1ec7eca70fe1605d2f86a4f8ab89b3b78b4c7ec9ce1dcf6edeb5cbe5beb7",
"src/sw/sw-header-dropdown.stories.tsx": "498dffa9ee330c774ec8c34448afbe4bf612f0c8cf9cb32bcf643fe08a529ca5",
"src/sw/sw-composed-controls.css": "f333c02648cedc65ecb1d2e313ae9fdaff5662082919cdfc00d7217f94bf0cd5"
},
"pushPerformed": false
}
@@ -0,0 +1,123 @@
# SW Storybook Dropdown 통합 — 2026-10-19
최종 판정: **PASS (PASS-A ~ PASS-J)**. 범위는 `STORYBOOK_ONLY`이며 제품 컴포넌트·공개 API·디자인·AI 템플릿은 변경하지 않았습니다. 신규 업무 화면 생성이 아니므로 Navigation/FilterBar 선택 및 AI 화면 생성 Guard는 적용 대상이 아닙니다.
- 작업 경로: `D:\디자인시스템\HMDesign-SW`
- 시작 브랜치: `feature/sw-package`
- 시작 HEAD: `c165753bbe24de6581c66704bde4ba3246049ec2`
- 시작 Working Tree: clean. 시작 시 기존 로컬 Commit은 upstream 대비 6개였습니다.
- 이번 요청의 경로·브랜치·로컬 Commit 지시를 적용했습니다. Push·PR·Publish·배포·다른 브랜치 수정은 수행하지 않습니다.
- 로컬 Commit SHA와 종료 Git Status는 완료 메시지에 기록합니다. Commit 자체의 SHA를 포함 파일에 기록하면 SHA가 달라지므로 이 문서에는 넣지 않습니다.
## 조사와 삭제·보존 기준
실제 소스로 `storybook index`를 생성하여 수정 전 SW Story 28개를 확보했습니다. 오래된 정적 빌드나 이름 추측을 기준으로 삭제하지 않았습니다.
실제 삭제한 4개 Story:
- Layer Dropdown — `sw-header--layer-dropdown`: 레이어 목록·선택·상태 토글·상세 Callback·긴/다량/빈 목록 시연을 통합했습니다.
- Color Dropdown — `sw-header--color-dropdown`: 기본/사용자 색상, ByLayer/ByBlock, RGB 입력·검증, Colorize·상세 Callback을 통합했습니다.
- Line Style Dropdown — `sw-header--line-style-dropdown`: 선 종류 5개, 가중치 4개, User 값 편집, 스케일·상세 Callback을 통합했습니다.
- Text · Dimension Style Dropdown — `sw-header--text-dimension-style-dropdown`: 문자스타일 2개, 치수스타일 2개와 각각의 상세 Callback을 통합했습니다.
관련 Story 중 보존한 목적:
- Composed Controls — `sw-header--composed-controls`: 기존 ID를 유지하고 내용을 실제 조합 예제로 수정했습니다.
- Detail Buttons (Shared States) — `sw-header--detail-buttons`: 5개 공유 상세 버튼의 Default/Hover/Disabled/Callback 미연결 상태 검증입니다. 기존 verification 태그도 유지했습니다.
- Document Dropdown — `sw-header--document-dropdown`: 문서 선택·닫기·New/Open과 동적 문서 목록 검증이며 6개 속성 컨트롤과 목적이 다릅니다.
- Layer Detail · Input — `sw-header--layer-detail-input`: Figma 버튼 비교와 입력 편집·Enter/Escape·ReadOnly/Disabled·외부 값 갱신 검증입니다.
- Responsive More — `sw-header--responsive-more`: Breakpoint와 More 대표 필드 전환을 검증합니다.
- Additional Hover — `sw-header--additional-hover`: 추가 Hover 정책을 검증합니다.
- Colorize — `sw-header--colorize`: Colorize 아이콘의 별도 상태 검증입니다.
- Dynamic Controls / Composition / Interactive States / Overview: 구성 API·반응형·전체 Header·호스트 상태 연결 검증이므로 보존했습니다.
- 모든 Property Bar / Property Panel Story는 그대로 보존했습니다.
## 최종 구성과 동작
메뉴는 `SW → Header → Dropdown → Composed Controls` 한 페이지입니다. 분류를 위해 별도 CSF 파일을 사용하되 `id: "sw-header"`로 **`sw-header--composed-controls`를 그대로 유지**합니다. 기존 CSF의 조합 호스트 함수는 `excludeStories`로 제외하여 중복 페이지가 생성되지 않습니다.
페이지에는 레이어·색상·선스타일·문자스타일·치수스타일·상세보기 6개 그룹을 각각 한 번 표시합니다. `SWTheme`과 공개 `SWHeaderLayerMenu`, `SWHeaderColorMenu`, `SWHeaderLineStyleMenu`, `SWHeaderTextStyleMenu`, `SWHeaderDimensionStyleMenu`, `SWHeaderProperties`를 실제 렌더링합니다. 기존 Story Fixture와 패키지 CSS/SVG를 재사용하며 디자인을 복제하지 않습니다.
5개 Dropdown은 Controlled 열림 상태를 공유하여 한 번에 하나만 열립니다. 각 값은 호스트 상태에 반영되고 다른 속성을 변경하지 않습니다. 레이어 전구·눈꽃·잠금, 색상 모드·칩·RGB, 선 종류·가중치·스케일, 문자·치수 선택의 실제 Callback을 연결했습니다. Callback 기록과 현재 선택값은 컨트롤 밖 상태 줄에서 확인할 수 있습니다.
접힌 **시연 설정**에 긴 레이어명·레이어 20개/사용자 색상 40개·빈 레이어 목록·컨트롤 Disabled·레이어 상태 표시 전용·메뉴 상세 Callback 미연결을 배치했습니다. 네이티브 설정 control은 기존 Overview와 같은 Storybook 호스트 조작 방식이며 제품 컨트롤이 아닙니다. Dropdown 컨트롤 자체에는 readOnly Prop이 없으므로 임의로 추가하지 않았습니다. 레이어 상태 Callback을 생략하면 패키지의 기존 `role=img` 표시 전용 아이콘을 사용합니다.
**상세보기**는 기존 속성Bar·속성창 토글입니다. 공개 `SWHeaderPropertyBar`/`SWHeaderPropertyPanel`과 기존 속성 Fixture를 사용하며 편집값을 공유합니다. 선가중치 모드(ByLayer/ByBlock)를 고르면 숫자 속성을 모드 문자열로 덮어쓰지 않습니다. 속성창의 숫자 편집도 상단 선스타일 값에 반영됩니다.
메뉴 하단 `레이어 상세` 등 5개 버튼은 기존처럼 호스트 Callback 후 메뉴를 닫고 Trigger로 Focus를 돌려줍니다. Callback 미연결 시 안전한 무동작을 유지합니다. 제공되지 않은 CAD 상세 팝업을 만들지 않았습니다.
Overlay는 패키지의 기존 absolute Dropdown·fixed 속성창과 위치 보정을 그대로 사용합니다. Portal/Dim이나 제품 크기 override를 추가하지 않았습니다. 조합만 flex-wrap하여 작은 폭에서 줄바꿈합니다. 속성창 초기 위치 계산 뒤 Focus를 전달하는 호스트 처리를 추가했고 닫기/Escape 시 기존 Trigger로 복귀합니다. 기존 CSS는 변경하지 않고 새 CSS의 `.sw-composed-controls` 범위에서 호스트 배치만 구성했습니다.
## 보존 결과와 Story 개수
- SW Story: **28 → 24**.
- 전체 저장소 Story: **347 → 343**. SW 외 index entry는 수정 전과 동일합니다.
- 기존 Story ID 변경: **없음**. 위 4개 삭제 외 새 ID 추가·기존 ID 교체가 없습니다.
- 나머지 23개 SW Story 선언과 공유 Fixture/함수는 시작 Commit과 동일합니다. 조합 함수·CSF meta/import만 필요한 범위에서 변경했습니다.
- Overview의 `sw-header--overview`, 16:9 Stage·Header 49px·Dropdown·속성Bar/속성창 연결을 보존했습니다.
- Window Move Motion의 「단계별 진행 (3배 확대)」, 9개 단계와 기존 모션 코드를 보존했습니다.
- `packages/sw/src`, 공개 export/types, 패키지 CSS·SVG·이미지, `packages/sw/ai`, AI 템플릿 자료, `src/sw/sw-header-overview.tsx`, 기존 `sw-stories.css`, `.storybook` 설정은 시작 Commit과 동일합니다.
최종 유지 Story 24개 (접두사 `sw-header--`):
- `overview`, `composed-controls`, `detail-buttons`, `interactive-states`, `window-move-motion`, `logo-slot`
- `document-dropdown`, `responsive-more`, `layer-detail-input`, `property-panel`, `property-panel-variants`, `k-guide`
- `additional-hover`, `property-bar`, `dynamic-controls`, `colorize`, `composition`
- `property-panel-none`, `property-panel-all`, `property-panel-circle`, `property-panel-expanded`, `property-panel-compare`, `property-shape-slot`, `property-fields`
## 통합 검증
- SW Typecheck: `npm.cmd run typecheck:sw` — PASS (exit 0).
- SW Build: `npm.cmd run build-storybook`의 `prebuild-storybook → build:packages → build:sw` — PASS (exit 0). 중복 별도 SW Build는 실행하지 않았습니다.
- Storybook Typecheck: `npm.cmd exec -- tsc -p tsconfig.app.json --noEmit` — PASS (exit 0), 최종 소스 기준.
- Storybook Build: `npm.cmd run build-storybook` — PASS (exit 0), 최종 런타임 소스 기준.
- 신규 통합 Smoke Test: **229/229 PASS**, Chrome `155.0.8059.80`, 콘솔/page 오류 0.
- 이후 선가중치 공유 상태 보정에 영향받는 범위 재검사: **29/29 PASS**, 콘솔/page 오류 0. 기존 정상 검사는 반복하지 않았습니다.
- 기존 Overview 회귀 검사: **54/54 PASS**, 브라우저 오류 0.
- 기존 Header·속성창·K 가이드·Colorize·Input 보존 검사: **15/15 PASS**, 브라우저 오류 0.
- `git diff --check` — PASS.
브라우저에서 390/768/1280/1440px의 페이지 가로 overflow 0, 필드 높이 38px와 기존 폭 234/192/284/164/164px, Hover 시 자동 열림 없음, Selected/On, Trigger 토글·Escape·외부 클릭 닫기·Focus 복귀를 확인했습니다. 각 메뉴와 하단 상세 버튼의 viewport 내 표시·실제 hit-test도 확인했습니다. 정상/오류 RGB·가중치·스케일 입력, Callback 1회, 레이어 Disabled, 다량 목록의 내부 스크롤과 상세보기 314px/28px 크기 및 값 공유도 검증했습니다.
기존 Overview 검사에서는 16:9 Stage, 실제 Storybook iframe, Header 49px, 속성Bar·속성창 값 공유·확장·하단 접근·390px 화면의 Escape/More Focus 복귀 등을 확인했습니다. 검사 항목의 상세 값은 아래 JSON 증거에 있습니다.
초기 로컬 브라우저 시도는 샌드박스의 `ERR_NETWORK_ACCESS_DENIED`로 차단되었고 localhost 접근이 허용된 실행으로 재검증했습니다. 이후 테스트 선택자·React 반영 대기 및 속성창 초기 Focus 문제를 수정했습니다. 초기 FAIL 결과와 로그도 새 증거 폴더에 남겼으며 최종 PASS로 덮어쓰지 않았습니다. 첫 Typecheck의 Callback 타입 오류도 수정한 뒤 영향을 받는 검사를 다시 실행했습니다.
Build에는 기존 생성 CSS `var(...)`, chunk 크기·bundler timing 경고가 있습니다. 해당 제품 코드와 설정은 수정하지 않았으며 Build는 성공했습니다.
Commit용 텍스트 로그는 줄 끝 공백·EOF 빈줄만 정규화했습니다. 정규화 전 원문은 같은 새 QA 폴더의 `raw-logs/*.log`에 로컬 보존했습니다(저장소의 기존 `*.log` ignore 적용). JSON 판정과 과거 증거는 변경하지 않았습니다.
## 테스트·문서 참조 변경
`detail-buttons.browser.mjs`의 삭제된 문자/치수·색상 Story 접근을 Composed Controls로 옮겼습니다. 상세 버튼 Hover·Callback·닫기·Focus 검증은 유지했습니다. 기존 Overview/정리 1단계 검증의 inventory도 승인된 삭제 ID와 새 분류를 반영하도록 수정했습니다. 테스트를 제거해 PASS로 만들지 않았으며 신규 검증은 시작 Commit 기준으로 삭제·보존 및 제품 불변 범위를 별도로 확인합니다.
현재 실행 코드에서 삭제한 Story로 이동하는 참조는 제거했습니다. 테스트의 삭제 허용 목록·과거 검증 문서·과거 index/스크린샷은 이력을 위해 보존했습니다. AI 템플릿 문서는 변경하지 않았습니다.
변경 파일:
- `src/sw/sw-header.stories.tsx` — 중복 4개 Story 및 전용 표본 제거, 조합 호스트 연결.
- `src/sw/sw-header-dropdown.stories.tsx` — 기존 ID를 유지한 단일 Dropdown CSF 등록.
- `src/sw/sw-composed-controls.css` — 조합 호스트의 줄바꿈·설정·상태 줄 배치.
- `packages/sw/tests/dropdown-consolidation.browser.mjs` — 범위 전용 회귀 검증, 필요한 후속 범위만 실행하는 followup 모드.
- `packages/sw/tests/storybook-inventory.mjs` — 승인된 삭제와 현재 SW Story 수집.
- `packages/sw/tests/detail-buttons.browser.mjs`, `overview.browser.mjs`, `storybook-cleanup-stage1.browser.mjs` — 유지할 검증의 Story 경로·목록 기준 갱신.
- 이 보고서와 `docs/sw/storybook-dropdown-consolidation-qa/`의 신규 증거 파일. 이전 QA 폴더는 변경하지 않았습니다.
증거:
- [수정 전 전체 index](storybook-dropdown-consolidation-qa/before-full-index.json)
- [통합 Smoke 결과 229개](storybook-dropdown-consolidation-qa/final/result.json)
- [최종 영향 범위 검사 29개](storybook-dropdown-consolidation-qa/release-followup/result.json)
- [기존 Overview 회귀 결과](storybook-dropdown-consolidation-qa/overview/chrome-result.json)
- [기존 보존 검사 결과](storybook-dropdown-consolidation-qa/preservation-run-02/preservation-result.json)
- [최종 Build 로그](storybook-dropdown-consolidation-qa/storybook-build-release.txt)
- [최종 Typecheck 로그](storybook-dropdown-consolidation-qa/storybook-typecheck-release.txt)
- [통합 화면](storybook-dropdown-consolidation-qa/final/composed-1440.png)
- [390px 선스타일 Overlay](storybook-dropdown-consolidation-qa/final/overlay-2-390.png)
- [390px 상세보기](storybook-dropdown-consolidation-qa/release-followup/composed-property-panel-390.png)
## NOT VERIFIED
Firefox/Safari 전체 회귀, 모든 유지 Story의 모든 상호작용, 스크린리더 전수 검증 및 Figma 원본의 신규 실시간 대조는 이번 범위에서 실행하지 않았습니다. 디자인 보존은 기존 패키지·CSS·자산 불변과 실제 Chrome 렌더링으로 확인했습니다. 실제 CAD 상세 화면·OS/파일 작업은 기존 호스트 Callback 밖의 기능이며 이번 Story 통합에 새로 구현하지 않았습니다.
기존 `detail-buttons`의 전체 baseline 비교 모드와 정리 1단계 전체 suite는 이번에 재실행하지 않았습니다. 변경된 검증 경로는 신규 Smoke에서 확인했고, 필요한 기존 `preservation` 및 Overview suite를 실행했습니다.
+9 -7
View File
@@ -2,6 +2,7 @@ import { createRequire } from 'node:module'
import { mkdir, readFile, writeFile } from 'node:fs/promises'
import path from 'node:path'
import http from 'node:http'
import { swStoryEntries, retainedInventory } from './storybook-inventory.mjs'
// Usage: node packages/sw/tests/detail-buttons.browser.mjs baseline|verify <evidence-dir> [base-url]
const mode = process.argv[2] ?? 'verify'
@@ -67,7 +68,7 @@ try {
check('preserve editable Input',await editing.isEditable()&&await editing.evaluate(e=>getComputedStyle(e).caretColor==='rgb(230, 4, 3)'))
} else {
const index = await (await fetch(`${base}/index.json`)).json()
const ids = Object.values(index.entries).filter(e => e.title === 'SW/Header' && e.type === 'story').map(e => e.id)
const ids = swStoryEntries(index).map(e => e.id)
report.storyIds = ids
if (mode === 'baseline') await writeFile(path.join(output, 'baseline-story-ids.json'), JSON.stringify(ids))
// These retained examples cover fixed-width and fluid headers after the two Args demos were retired.
@@ -82,7 +83,8 @@ try {
}
}
await page.setViewportSize({ width:1920,height:1000 })
await goto('text-dimension-style-dropdown')
await goto('composed-controls')
await page.locator('[data-composed-controls]').getByRole('button',{name:'문자스타일',exact:true}).click()
const original = page.getByRole('button',{name:'문자스타일 상세',exact:true}).first()
snapshots.textDefault = await original.evaluate(style)
if (!(await original.isDisabled())) { await original.hover(); snapshots.textHover = await original.evaluate(style) }
@@ -97,9 +99,9 @@ try {
const before=JSON.parse(await readFile(path.join(output,'baseline.json'),'utf8'))
for(const key of Object.keys(snapshots).filter(k=>!k.startsWith('text'))) check(`unchanged header ${key} (capture a current baseline for replacement fixtures)`,JSON.stringify(before[key])===JSON.stringify(snapshots[key]))
const oldIds=JSON.parse(await readFile(path.join(output,'baseline-story-ids.json'),'utf8'))
const retiredIds=['default','controls','responsive','text-stroke','dynamic-data'].map(id=>`sw-header--${id}`)
const retainedIds=oldIds.filter(id=>!retiredIds.includes(id))
check('retained stories remain; only the five approved demos are absent',ids.length===28&&retainedIds.every(id=>ids.includes(id))&&retiredIds.every(id=>!ids.includes(id)),{before:oldIds.length,after:ids.length})
const retiredIds=['default','controls','responsive','text-stroke','dynamic-data','layer-dropdown','color-dropdown','line-style-dropdown','text-dimension-style-dropdown'].map(id=>`sw-header--${id}`)
const retainedIds=retainedInventory(oldIds.map(id=>({id}))).map(e=>e.id)
check('retained stories remain; only approved retirements are absent',ids.length===24&&retainedIds.every(id=>ids.includes(id))&&retiredIds.every(id=>!ids.includes(id)),{before:oldIds.length,after:ids.length})
for(const id of ids){await goto(id.replace('sw-header--',''));check(`render ${id}`,!(await page.locator('.sb-errordisplay').isVisible()))}
await goto('composition')
const presets=['기본 전체','구성 A','구성 B (레이어·선스타일)','구성 C (로고만)','파일 목록 제거','레이어 제거','색상 제거','스타일 그룹 제거','여러 메뉴 제거','순서 변경','숨김 + 순서 변경']
@@ -117,8 +119,8 @@ try {
}
await page.setViewportSize({width:1920,height:1000})
// Real dropdown integration, separate from the shared-button specimen.
await goto('color-dropdown')
const host=page.locator('section').filter({has:page.getByRole('heading',{name:'선택 · 입력 · Callback 기록',exact:true})})
await goto('composed-controls')
const host=page.locator('.sw-composed-controls')
for(const [name,callback] of [['색상','onColorDetail'],['선스타일','onLineStyleDetail'],['문자스타일','onTextStyleDetail'],['치수스타일','onDimensionStyleDetail']]){
const trigger=host.getByRole('button',{name,exact:true});await trigger.click()
const detail=host.getByRole('button',{name:`${name} 상세`,exact:true});await detail.hover()
@@ -0,0 +1,264 @@
// Build Storybook first. Historical QA is preserved; use a new evidence directory for every run.
// Usage: node packages/sw/tests/dropdown-consolidation.browser.mjs [evidence-dir]
import { createRequire } from 'node:module'
import { readFile, writeFile, mkdir } from 'node:fs/promises'
import { execFileSync } from 'node:child_process'
import path from 'node:path'
import http from 'node:http'
import { parse } from '@babel/parser'
import { retiredDropdownIds, swStoryEntries, inventorySignature } from './storybook-inventory.mjs'
const out = path.resolve(process.argv[2] ?? 'docs/sw/storybook-dropdown-consolidation-qa')
await mkdir(out, { recursive: true })
const report = { baseCommit: 'c165753bbe24de6581c66704bde4ba3246049ec2', checks: [], errors: [], callbacks: [], geometry: [] }
const check = (name, ok, data) => { report.checks.push({ name, status: ok ? 'PASS' : 'FAIL', data }); console.log(`${ok ? 'PASS' : 'FAIL'} ${name}${ok ? '' : ` ${JSON.stringify(data)}`}`) }
const before = JSON.parse(await readFile('docs/sw/storybook-dropdown-consolidation-qa/before-full-index.json', 'utf8'))
const after = JSON.parse(await readFile('storybook-static/index.json', 'utf8'))
const beforeSW = swStoryEntries(before), afterSW = swStoryEntries(after)
await writeFile(path.join(out, 'after-full-index.json'), JSON.stringify(after, null, 2) + '\n')
await writeFile(path.join(out, 'story-inventory.json'), JSON.stringify({ before: beforeSW, after: afterSW, removed: beforeSW.filter(e => retiredDropdownIds.includes(e.id)) }, null, 2) + '\n')
check('28 -> 24 SW Stories, exactly four approved Dropdown retirements', beforeSW.length === 28 && afterSW.length === 24 &&
JSON.stringify(inventorySignature(beforeSW.filter(e => !retiredDropdownIds.includes(e.id)))) === JSON.stringify(inventorySignature(afterSW)))
check('Dropdown group has only Composed Controls with original ID', afterSW.filter(e => e.title === 'SW/Header/Dropdown').length === 1 && after.entries['sw-header--composed-controls']?.title === 'SW/Header/Dropdown')
const nonSW = index => Object.values(index.entries).filter(e => !e.title.startsWith('SW/Header'))
check('all non-SW index entries identical', JSON.stringify(nonSW(before)) === JSON.stringify(nonSW(after)))
const sourcePath = 'src/sw/sw-header.stories.tsx'
const original = execFileSync('git', ['show', `${report.baseCommit}:${sourcePath}`], { encoding: 'utf8' }).replaceAll('\r\n', '\n')
const source = (await readFile(sourcePath, 'utf8')).replaceAll('\r\n', '\n')
const declarations = text => Object.fromEntries(parse(text, { sourceType: 'module', plugins: ['typescript', 'jsx'] }).program.body.map(n => {
const d = n.type === 'ExportNamedDeclaration' ? n.declaration : n
return [d.type === 'VariableDeclaration' ? d.declarations[0].id.name : d.id?.name ?? d.type, text.slice(n.start, n.end)]
}))
const oldDeclarations = declarations(original), currentDeclarations = declarations(source)
const removed = ['LayerDropdown', 'ColorDropdown', 'LineStyleDropdown', 'TextDimensionStyleDropdown', 'ComposedControls', 'IconMatrix', 'ICON_LAYERS', 'NARROW_LAYER_WIDTHS', 'MENU_BUTTON_HOVER']
check('all retained declarations identical outside imports, meta and ComposedDemo', Object.entries(oldDeclarations).filter(([key]) => ![...removed, 'ImportDeclaration', 'meta', 'ComposedDemo'].includes(key)).every(([key, value]) => currentDeclarations[key] === value))
const untouched = ['packages/sw/src', 'packages/sw/ai', 'packages/sw/package.json', 'src/sw/sw-header-overview.tsx', 'src/sw/sw-stories.css', 'src/sw/assets', '.storybook']
check('runtime, API, AI template, Overview, existing CSS/assets and Storybook configuration untouched', !execFileSync('git', ['diff', report.baseCommit, '--', ...untouched], { encoding: 'utf8' }))
const root = path.resolve('storybook-static'), mime = { '.html': 'text/html', '.js': 'text/javascript', '.css': 'text/css', '.json': 'application/json', '.svg': 'image/svg+xml', '.ttf': 'font/ttf', '.png': 'image/png' }
const server = http.createServer(async (req, res) => {
try {
const pathname = new URL(req.url, 'http://localhost').pathname
const file = path.resolve(root, '.' + decodeURIComponent(pathname === '/' ? '/index.html' : pathname))
if (path.relative(root, file).startsWith('..')) return res.writeHead(403).end()
res.setHeader('Content-Type', mime[path.extname(file)] ?? 'application/octet-stream'); res.end(await readFile(file))
} catch { res.writeHead(404).end() }
})
await new Promise(resolve => server.listen(0, '127.0.0.1', resolve))
const base = `http://127.0.0.1:${server.address().port}`
const { chromium } = createRequire(import.meta.url)(process.env.SW_PLAYWRIGHT_PATH ?? 'C:/Users/user/.cache/codex-runtimes/codex-primary-runtime/dependencies/node/node_modules/playwright')
let browser
try {
browser = await chromium.launch({ headless: true, executablePath: process.env.SW_CHROME_PATH ?? 'C:/Program Files/Google/Chrome/Application/chrome.exe' })
report.browser = browser.version()
const page = await browser.newPage({ viewport: { width: 1440, height: 1000 } })
page.setDefaultTimeout(6000)
page.on('pageerror', e => report.errors.push(e.message))
page.on('console', m => { if (m.type() === 'error') report.errors.push(m.text()); if (m.type() === 'info' && m.text().startsWith('[SWHeader Composed] ')) report.callbacks.push(m.text().slice(20)) })
const go = async (id = 'composed-controls') => {
await page.goto(`${base}/iframe.html?id=sw-header--${id}&viewMode=story`)
await page.locator('.hm-sw-theme, .hm-sw-header').first().waitFor()
await page.evaluate(() => document.fonts.ready)
await page.mouse.move(1, 1)
}
for (const entry of process.argv[3] === 'followup' ? [] : afterSW) {
await go(entry.id.replace('sw-header--', ''))
check(`render ${entry.id}`, !await page.locator('.sb-errordisplay').isVisible())
}
await go()
const host = page.locator('[data-composed-controls]')
const field = name => host.getByRole('button', { name, exact: true })
const menu = () => page.locator('[data-composed-controls] .hm-sw-header__menu-panel, [data-composed-controls] .hm-sw-header__layer-menu')
const events = name => report.callbacks.filter(line => line.startsWith(name)).length
const once = async (name, action) => { const previous = events(name); await action(); check(`${name} callback exactly once`, events(name) === previous + 1, report.callbacks.slice(-5)) }
const labels = ['레이어', '색상', '선스타일', '문자스타일', '치수스타일']
if (process.argv[3] !== 'followup') {
check('one copy of five Dropdown fields and the details group', await host.locator('.hm-sw-header__field').count() === 5 && await host.getByRole('group', { name: '상세보기', exact: true }).count() === 1 && await field('속성Bar').count() === 1 && await field('속성창').count() === 1)
const hitTest = locator => locator.evaluate(e => {
const r = e.getBoundingClientRect()
return { x: r.x, y: r.y, w: r.width, h: r.height, right: r.right, bottom: r.bottom, hit: e.contains(document.elementFromPoint(r.x + r.width / 2, r.y + r.height / 2)) }
})
for (const width of [390, 768, 1280, 1440]) {
await page.setViewportSize({ width, height: 1000 })
const geometry = await host.evaluate(e => ({ overflow: document.documentElement.scrollWidth - document.documentElement.clientWidth,
fields: [...e.querySelectorAll('.hm-sw-header__field')].map(f => ({ width: f.getBoundingClientRect().width, height: f.getBoundingClientRect().height })) }))
report.geometry.push({ width, ...geometry })
check(`composition wraps without page overflow or scaling at ${width}`, geometry.overflow === 0 && geometry.fields.every(f => f.height === 38) && JSON.stringify(geometry.fields.map(f => f.width)) === JSON.stringify([234, 192, 284, 164, 164]), geometry)
for (const label of labels) {
const trigger = field(label)
await trigger.hover()
check(`${label} Hover does not open at ${width}`, await menu().count() === 0)
await trigger.click()
const box = await hitTest(menu())
const footer = page.getByRole('button', { name: `${label} 상세`, exact: true })
check(`${label} overlay in viewport, not clipped or covered at ${width}`, box.x >= 0 && box.right <= width && box.hit && (await hitTest(footer)).hit, box)
check(`${label} selected and expanded at ${width}`, await trigger.getAttribute('aria-expanded') === 'true' && await trigger.getAttribute('data-selected') === 'true')
if (width === 390 || width === 1440) await page.screenshot({ path: path.join(out, `overlay-${labels.indexOf(label)}-${width}.png`), fullPage: true })
await page.keyboard.press('Escape')
check(`${label} Escape closes and restores focus at ${width}`, await menu().count() === 0 && await trigger.evaluate(e => e === document.activeElement))
await trigger.click(); await trigger.click()
check(`${label} trigger toggles closed at ${width}`, await menu().count() === 0)
await trigger.click(); await page.getByRole('heading', { name: 'Composed Controls', exact: true }).click()
check(`${label} outside click closes at ${width}`, await menu().count() === 0)
}
await page.screenshot({ path: path.join(out, `composed-${width}.png`), fullPage: true })
}
await page.setViewportSize({ width: 1440, height: 1000 })
await field('레이어').focus(); await page.keyboard.press('ArrowDown')
check('keyboard opens layer menu and focuses current row', await page.locator('.hm-sw-header__layer-menu').isVisible() && await page.locator('.hm-sw-header__layer-item').first().evaluate(e => e === document.activeElement))
await page.keyboard.press('ArrowDown')
check('keyboard moves to next layer row', await page.locator('.hm-sw-header__layer-item').nth(1).evaluate(e => e === document.activeElement))
await once('onLayerSelect', () => page.keyboard.press('Enter'))
check('layer selection appears, closes and restores focus', (await field('레이어').textContent()).includes('Sample-Center') && await menu().count() === 0 && await field('레이어').evaluate(e => e === document.activeElement))
await field('레이어').click()
const active = page.locator('.hm-sw-header__layer-row[data-active]')
await active.locator('.hm-sw-header__layer-item').hover()
check('selected layer retains original row Hover background', await active.evaluate(e => getComputedStyle(e).backgroundColor === 'rgb(98, 83, 61)'))
for (const [i, name] of ['onLayerVisibilityChange', 'onLayerFreezeChange', 'onLayerLockChange'].entries()) {
const toggle = active.locator('.hm-sw-header__layer-toggle').nth(i)
const pressed = await toggle.getAttribute('aria-pressed')
await once(name, () => toggle.click())
check(`${name} toggles only its own state, menu remains open`, await toggle.getAttribute('aria-pressed') !== pressed && await menu().count() === 1)
}
const disabledLayer = page.locator('.hm-sw-header__layer-row[data-disabled]')
check('disabled layer selection and toggles blocked', await disabledLayer.locator('button:disabled').count() === 4)
await page.keyboard.press('Escape')
const beforeStyles = await page.locator('[data-style-state]').textContent()
await field('색상').click()
check('full color menu: seven palette chips, two user colors, modes, RGB and pick', await page.locator('.hm-sw-header__color-option').count() === 9 && await page.getByRole('button', { name: 'ByLayer', exact: true }).count() === 1 && await page.getByRole('textbox', { name: '색상값 (R,G,B)', exact: true }).count() === 1 && await page.getByRole('button', { name: '색상 추출', exact: true }).count() === 1)
await once('onColorSelect', () => page.locator('.hm-sw-header__color-option').nth(1).click())
check('color palette updates displayed RGB and leaves menu open', (await field('색상').textContent()).includes('241,4,4') && await menu().count() === 1)
await once('onColorModeChange', () => page.getByRole('button', { name: 'ByBlock', exact: true }).click())
check('ByBlock On and displayed mode', (await field('색상').textContent()).includes('ByBlock') && await page.getByRole('button', { name: 'ByBlock', exact: true }).getAttribute('aria-pressed') === 'true')
const rgb = page.locator('.hm-sw-header__color-input input')
await rgb.fill('255,0,0'); await once('onColorInput', () => rgb.press('Enter'))
check('RGB commit clears mode and updates chip', (await field('색상').textContent()).includes('255,0,0') && await field('색상').locator('.hm-sw-header__chip span').evaluate(e => getComputedStyle(e).backgroundColor === 'rgb(255, 0, 0)'))
const count = events('onColorInput'); await rgb.fill('256,0,0'); await rgb.press('Enter')
check('invalid RGB restores without callback', await rgb.inputValue() === '255,0,0' && events('onColorInput') === count)
await once('onColorPick', () => page.getByRole('button', { name: '색상 추출', exact: true }).click())
check('color pick closes and restores focus', await menu().count() === 0 && await field('색상').evaluate(e => e === document.activeElement))
check('color changes leave layer, line, text and dimension values intact', (await page.locator('[data-style-state]').textContent()).replace(/색상: .*? · 선:/, '색상: _ · 선:') === beforeStyles.replace(/색상: .*? · 선:/, '색상: _ · 선:'))
await field('선스타일').click()
check('all original line rows and weights retained', await page.locator('.hm-sw-header__line-column--type .hm-sw-header__menu-row').count() === 5 && await page.locator('.hm-sw-header__line-column').nth(1).locator('.hm-sw-header__menu-row').count() === 4)
await once('onLineTypeSelect', () => page.getByRole('button', { name: 'CENTER', exact: true }).click())
await page.getByRole('button', { name: 'CENTER', exact: true }).hover()
check('selected line retains original row Hover and preview', await page.locator('.hm-sw-header__line-column--type .hm-sw-header__menu-row[data-active]').evaluate(e => getComputedStyle(e).backgroundColor === 'rgb(98, 83, 61)' && !!e.querySelector('.hm-sw-header__line-preview')))
await once('onLineWeightSelect', () => page.getByRole('button', { name: /User/ }).click())
const userWeight = page.locator('.hm-sw-header__line-column').nth(1).getByRole('textbox')
await userWeight.fill('0.5'); await once('onLineWeightValueChange', () => userWeight.press('Enter'))
const scale = page.getByRole('textbox', { name: '스케일', exact: true })
await scale.fill('2'); await once('onLineScaleChange', () => scale.press('Enter'))
check('line type, editable weight and scale update independently; menu stays open', (await field('선스타일').textContent()).includes('CENTER') && (await field('선스타일').textContent()).includes('0.5') && await scale.inputValue() === '2' && await menu().count() === 1)
const scaleCount = events('onLineScaleChange'); await scale.fill('0'); await scale.press('Enter')
check('invalid scale restores, no callback', await scale.inputValue() === '2' && events('onLineScaleChange') === scaleCount)
await page.keyboard.press('Escape')
for (const [label, item, callback] of [['문자스타일', 'Dotum', 'onTextStyleSelect'], ['치수스타일', 'ISO - 25', 'onDimensionStyleSelect']]) {
await field(label).click()
check(`${label} full two-item list retained`, await menu().locator('.hm-sw-header__menu-row').count() === 2)
await once(callback, () => menu().getByRole('button', { name: new RegExp(item) }).click())
check(`${label} selection displayed, closes, focus returns`, (await field(label).textContent()).includes(item) && await menu().count() === 0 && await field(label).evaluate(e => e === document.activeElement))
}
for (const [label, callback] of labels.map((label, i) => [label, ['Layer', 'Color', 'LineStyle', 'TextStyle', 'DimensionStyle'][i]])) {
await field(label).click()
const button = page.getByRole('button', { name: `${label} 상세`, exact: true })
await button.hover()
check(`${label} detail Hover uses existing text opacity`, await button.locator('[data-detail-label]').evaluate(e => getComputedStyle(e).opacity === '0.35'))
await once(`on${callback}Detail`, () => button.click())
check(`${label} detail closes, focus returns, no fabricated popup`, await menu().count() === 0 && await field(label).evaluate(e => e === document.activeElement) && await page.getByRole('dialog').count() === 0)
}
await field('레이어').click(); await field('색상').click()
check('opening another control leaves exactly one menu and preserves selection', await menu().count() === 1 && await field('레이어').getAttribute('aria-expanded') === 'false' && (await field('레이어').textContent()).includes('Sample-Center'))
await page.keyboard.press('Escape')
await field('색상').focus(); await page.keyboard.press('Enter'); await page.keyboard.press('Tab')
check('keyboard Tab enters the open color controls', await menu().evaluate(e => e.contains(document.activeElement)))
await page.keyboard.press('Escape')
} else {
// Recheck only line-weight behavior affected by the shared property-state correction.
await field('선스타일').click()
await page.getByRole('button', { name: /User/ }).click()
const userWeight = page.locator('.hm-sw-header__line-column').nth(1).getByRole('textbox')
await userWeight.fill('0.5'); await userWeight.press('Enter')
await page.waitForFunction(() => document.querySelector('[data-composed-controls] .hm-sw-header__field--line-style')?.textContent.includes('0.5'))
check('User line weight still updates displayed numeric value', (await field('선스타일').textContent()).includes('0.5'))
await page.locator('.hm-sw-header__line-column').nth(1).getByRole('button', { name: 'ByLayer', exact: true }).click()
check('weight mode label preserves the shared numeric value', (await field('선스타일').textContent()).includes('ByLayer') && (await page.locator('[data-style-state]').textContent()).includes('/ 0.5 /'))
await page.locator('.hm-sw-header__line-column').nth(1).getByRole('button', { name: /ByDefault/ }).click()
await page.keyboard.press('Escape')
}
await field('속성Bar').click()
check('details opens existing 28px property Bar', await page.getByRole('region', { name: '속성Bar', exact: true }).evaluate(e => e.getBoundingClientRect().height === 28))
await field('속성창').click()
await page.waitForFunction(() => document.activeElement?.getAttribute('role') === 'dialog')
const panelGeometry = await page.getByRole('dialog').evaluate(e => ({ width: e.getBoundingClientRect().width, focused: e === document.activeElement, active: document.activeElement?.outerHTML }))
check('details opens existing 314px property panel with focus', panelGeometry.width === 314 && panelGeometry.focused, panelGeometry)
await page.screenshot({ path: path.join(out, 'composed-property-panel.png'), fullPage: true })
const radius = page.getByRole('dialog').getByRole('textbox', { name: '반지름', exact: true })
await radius.fill('12.5'); await radius.press('Enter')
await page.waitForFunction(() => document.querySelector('.hm-sw-property-bar [data-property-id="radius"] input')?.value === '12.5')
const barRadius = await page.getByRole('region', { name: '속성Bar', exact: true }).getByRole('textbox', { name: '반지름', exact: true }).inputValue()
check('property Bar and panel share edited state', Number(barRadius) === 12.5, barRadius)
const panelWeight = page.getByRole('dialog').getByRole('textbox', { name: '선가중치', exact: true })
await panelWeight.fill('0.75'); await panelWeight.press('Enter')
await page.waitForFunction(() => document.querySelector('[data-composed-controls] .hm-sw-header__field--line-style')?.textContent.includes('0.75'))
check('property panel weight edit appears in composed line field', (await field('선스타일').textContent()).includes('0.75'))
await page.getByRole('button', { name: '속성창 닫기', exact: true }).click()
check('property panel close returns focus', await page.getByRole('dialog').count() === 0 && await field('속성창').evaluate(e => e === document.activeElement))
await field('속성창').click(); await page.keyboard.press('Escape')
check('property panel Escape returns focus', await page.getByRole('dialog').count() === 0 && await field('속성창').evaluate(e => e === document.activeElement))
await page.setViewportSize({ width: 390, height: 844 }); await field('속성창').click()
await page.waitForFunction(() => document.activeElement?.getAttribute('role') === 'dialog')
const narrowPanel = await page.getByRole('dialog').evaluate(e => { const r = e.getBoundingClientRect(); return { width: r.width, left: r.left, right: r.right, bottom: r.bottom, overflow: document.documentElement.scrollWidth - document.documentElement.clientWidth } })
check('narrow details panel keeps natural width and fits viewport', narrowPanel.width === 314 && narrowPanel.left >= 0 && narrowPanel.right <= 390 && narrowPanel.bottom <= 844 && narrowPanel.overflow === 0, narrowPanel)
await page.screenshot({ path: path.join(out, 'composed-property-panel-390.png'), fullPage: true })
await page.keyboard.press('Escape'); await page.setViewportSize({ width: 1440, height: 1000 })
await field('속성Bar').click()
await page.getByText('시연 설정', { exact: true }).click()
await page.getByLabel('컨트롤 Disabled', { exact: true }).check()
check('all seven actionable controls Disabled', await host.locator('button:disabled').count() === 7 && await menu().count() === 0)
const disabledCount = report.callbacks.length
for (const button of await host.locator('button:disabled').all()) { const box = await button.boundingBox(); await page.mouse.click(box.x + box.width / 2, box.y + box.height / 2) }
check('Disabled controls block callbacks and overlays', report.callbacks.length === disabledCount && await menu().count() === 0 && await page.getByRole('dialog').count() === 0)
await page.getByLabel('컨트롤 Disabled', { exact: true }).uncheck()
await page.getByLabel('레이어 상태 표시 전용', { exact: true }).check(); await field('레이어').click()
check('callback-free layer icons become readonly status images', await menu().locator('button.hm-sw-header__layer-toggle').count() === 0 && await menu().getByRole('img').count() > 0)
await page.keyboard.press('Escape'); await page.getByLabel('레이어 상태 표시 전용', { exact: true }).uncheck()
await page.getByLabel('메뉴 상세 Callback 연결', { exact: true }).uncheck(); await field('색상').click()
const noDetailCount = events('onColorDetail')
await page.getByRole('button', { name: '색상 상세', exact: true }).click()
check('missing detail callback keeps safe no-op and menu open', events('onColorDetail') === noDetailCount && await menu().count() === 1)
await page.keyboard.press('Escape'); await page.getByLabel('메뉴 상세 Callback 연결', { exact: true }).check()
for (const scenario of ['long', 'many', 'empty']) {
await page.getByRole('combobox', { name: /목록 데이터/ }).selectOption(scenario); await field('레이어').click()
const rows = page.locator('.hm-sw-header__layer-row')
check(`retained ${scenario} layer scenario`, await rows.count() === ({ long: 3, many: 20, empty: 0 })[scenario])
if (scenario === 'many') check('long layer list scrolls internally', await page.locator('.hm-sw-header__layer-list').evaluate(e => e.scrollHeight > e.clientHeight))
if (scenario === 'long') {
await rows.first().getByRole('button').last().click()
check('long layer name preserved with full title', (await field('레이어').getAttribute('title'))?.includes('0123456789') || (await field('레이어').locator('[title]').first().getAttribute('title'))?.includes('0123456789'))
} else await page.keyboard.press('Escape')
if (scenario === 'many') {
await field('색상').click()
check('all 40 user colors accessible with palette scroll', await page.locator('.hm-sw-header__color-option').count() === 47 && await page.locator('.hm-sw-header__color-palette').evaluate(e => e.scrollHeight > e.clientHeight))
await page.keyboard.press('Escape')
}
}
await page.setViewportSize({ width: 1440, height: 1000 }); await go('overview')
check('Overview keeps one Header at 49px and 16:9 Stage', await page.locator('header.hm-sw-header').count() === 1 && await page.locator('[data-preview-stage]').evaluate(e => Math.abs(e.getBoundingClientRect().width / e.getBoundingClientRect().height - 16 / 9) < 0.001) && await page.locator('header.hm-sw-header').evaluate(e => e.getBoundingClientRect().height === 49))
await go('window-move-motion')
check('Window Move Motion retains only nine 3x steps', JSON.stringify(await page.locator('section > header h2').allTextContents()) === JSON.stringify(['단계별 진행 (3배 확대)']) && await page.locator('[data-motion-time]').count() === 9 && await page.locator('.sw-story-zoom').first().evaluate(e => getComputedStyle(e).zoom === '3'))
await page.goto(`${base}/?path=/story/sw-header--composed-controls`)
await page.locator('#storybook-preview-iframe').waitFor()
await page.getByRole('link', { name: 'Composed Controls', exact: true }).waitFor()
check('manager shows Dropdown group with the single Composed Controls page', await page.getByText('Dropdown', { exact: true }).isVisible() && await page.getByRole('link', { name: 'Composed Controls', exact: true }).count() === 1)
check('retired Dropdown links absent in manager', await page.locator(retiredDropdownIds.map(id => `a[href*="${id}"]`).join(',')).count() === 0)
await page.screenshot({ path: path.join(out, 'composed-manager.png'), fullPage: true })
check('no browser console or page errors', report.errors.length === 0, report.errors)
} catch (error) { check('suite completes', false, error.stack) }
finally {
if (browser) await browser.close()
await new Promise(resolve => server.close(resolve))
report.status = report.checks.every(c => c.status === 'PASS') ? 'PASS' : 'FAIL'
await writeFile(path.join(out, 'result.json'), JSON.stringify(report, null, 2) + '\n')
console.log(JSON.stringify({ status: report.status, checks: report.checks.length, errors: report.errors }))
process.exitCode = report.status === 'PASS' ? 0 : 1
}
+7 -4
View File
@@ -6,21 +6,24 @@ import { execFileSync } from 'node:child_process'
import path from 'node:path'
import http from 'node:http'
import { parse } from '@babel/parser'
import { swStoryEntries, retainedInventory, inventorySignature, retiredDropdownIds } from './storybook-inventory.mjs'
const out = path.resolve(process.argv[2] ?? 'docs/sw/storybook-overview-qa')
await mkdir(out, { recursive: true })
const report = { baseCommit: '50bf5bda8e956a4973b923d64131f2f2285bd38c', checks: [], errors: [], sizes: [] }
const check = (name, ok, data) => { report.checks.push({ name, status: ok ? 'PASS' : 'FAIL', data }); console.log(ok ? 'PASS' : 'FAIL', name) }
const before = JSON.parse(await readFile(path.join(out, 'before-index.json'), 'utf8'))
const after = Object.values(JSON.parse(await readFile('storybook-static/index.json', 'utf8')).entries).filter(e => e.type === 'story' && e.title === 'SW/Header')
const after = swStoryEntries(JSON.parse(await readFile('storybook-static/index.json', 'utf8')))
await writeFile(path.join(out, 'after-index.json'), JSON.stringify(after, null, 2) + '\n')
check('all 28 Story IDs, names, order and tags retained', after.length === 28 && JSON.stringify(before.map(e => [e.id,e.name,e.tags])) === JSON.stringify(after.map(e => [e.id,e.name,e.tags])))
check('24 retained Story IDs, names and tags; only approved Dropdown retirements', after.length === 24 && JSON.stringify(inventorySignature(retainedInventory(before))) === JSON.stringify(inventorySignature(after)))
const source = await readFile('src/sw/sw-header.stories.tsx', 'utf8')
const baseline = execFileSync('git', ['show', `${report.baseCommit}:src/sw/sw-header.stories.tsx`], { encoding: 'utf8' })
const stories = text => Object.fromEntries(parse(text, { sourceType:'module', plugins:['typescript','jsx'] }).program.body
.filter(n => n.type === 'ExportNamedDeclaration').map(n => [n.declaration.declarations[0].id.name, text.slice(n.start,n.end).replaceAll('\r\n','\n')]))
.filter(n => n.type === 'ExportNamedDeclaration' && n.declaration.type === 'VariableDeclaration').map(n => [n.declaration.declarations[0].id.name, text.slice(n.start,n.end).replaceAll('\r\n','\n')]))
const oldStories = stories(baseline), newStories = stories(source)
check('other 27 Story declarations byte-identical', Object.keys(oldStories).filter(k => k !== 'Overview').every(k => oldStories[k] === newStories[k]))
const retiredExports = ['LayerDropdown','ColorDropdown','LineStyleDropdown','TextDimensionStyleDropdown','ComposedControls']
check('retained non-Overview declarations byte-identical; relocated composition separately verified', Object.keys(oldStories).filter(k => k !== 'Overview' && !retiredExports.includes(k)).every(k => oldStories[k] === newStories[k]))
check('retired Dropdown IDs absent', retiredDropdownIds.every(id => !after.some(e => e.id === id)))
check('package production source untouched', !execFileSync('git', ['diff', report.baseCommit, '--', 'packages/sw/src'], { encoding:'utf8' }))
const root = path.resolve('storybook-static'), mime = { '.html':'text/html','.js':'text/javascript','.css':'text/css','.json':'application/json','.svg':'image/svg+xml','.ttf':'font/ttf','.png':'image/png' }
@@ -6,6 +6,7 @@ import { execFileSync } from 'node:child_process'
import path from 'node:path'
import http from 'node:http'
import { parse } from '@babel/parser'
import { swStoryEntries, retiredDropdownIds, inventorySignature } from './storybook-inventory.mjs'
const out = path.resolve(process.argv[2] ?? 'docs/sw/storybook-cleanup-stage1-qa')
await mkdir(out, { recursive: true })
@@ -14,16 +15,15 @@ const check = (name, ok, data) => {
report.checks.push({ name, status: ok ? 'PASS' : 'FAIL', data })
console.log(ok ? 'PASS' : 'FAIL', name)
}
const retired = ['responsive', 'text-stroke', 'dynamic-data', 'default', 'controls'].map(id => `sw-header--${id}`)
const retired = [...['responsive', 'text-stroke', 'dynamic-data', 'default', 'controls'].map(id => `sw-header--${id}`), ...retiredDropdownIds]
const before = JSON.parse(await readFile(path.join(out, 'before-index.json'), 'utf8'))
const after = Object.values(JSON.parse(await readFile('storybook-static/index.json', 'utf8')).entries)
.filter(e => e.type === 'story' && e.title === 'SW/Header')
const after = swStoryEntries(JSON.parse(await readFile('storybook-static/index.json', 'utf8')))
await writeFile(path.join(out, 'after-index.json'), JSON.stringify(after, null, 2) + '\n')
report.deleted = before.filter(e => !after.some(a => a.id === e.id)).map(e => ({ name: e.name, id: e.id }))
check('33 -> 28; precisely the five requested IDs removed', before.length === 33 && after.length === 28 &&
report.deleted.length === 5 && retired.every(id => report.deleted.some(e => e.id === id)), report.deleted)
check('all retained names, IDs, ordering and tags unchanged', JSON.stringify(before.filter(e => !retired.includes(e.id)).map(e => [e.id, e.name, e.tags])) ===
JSON.stringify(after.map(e => [e.id, e.name, e.tags])))
check('33 -> 24; precisely the approved stage-1 and Dropdown IDs removed', before.length === 33 && after.length === 24 &&
report.deleted.length === 9 && retired.every(id => report.deleted.some(e => e.id === id)), report.deleted)
check('all retained names, IDs and tags unchanged', JSON.stringify(inventorySignature(before.filter(e => !retired.includes(e.id)))) ===
JSON.stringify(inventorySignature(after)))
// Compare declaration text with the starting commit, including every retained fixture/helper.
const file = 'src/sw/sw-header.stories.tsx'
@@ -40,8 +40,8 @@ const declarations = text => {
})
}
const oldDeclarations = new Map(declarations(original).map(d => [d.name, d.text]))
const changed = declarations(current).filter(d => d.name !== 'WindowMoveMotion' && oldDeclarations.get(d.name) !== d.text)
check('every retained declaration unchanged except WindowMoveMotion', changed.length === 0, changed.map(d => d.name))
const changed = declarations(current).filter(d => !['WindowMoveMotion', 'ComposedDemo', 'meta', 'import:react', 'import:@hm-design/sw'].includes(d.name) && oldDeclarations.get(d.name) !== d.text)
check('retained declarations unchanged outside motion and composition integration', changed.length === 0, changed.map(d => d.name))
const section = text => text.match(/<StorySection title="단계별 진행 \(3배 확대\)"[\s\S]*?<\/StorySection>/)?.[0]
check('retained step section is byte-identical after newline normalization', !!section(original) && section(original) === section(current))
const productionDiff = execFileSync('git', ['diff', report.baseCommit, '--', 'packages/sw/src', 'src/sw/sw-stories.css', 'src/sw/assets', '.storybook'], { encoding: 'utf8' })
@@ -0,0 +1,6 @@
// Current SW inventory after the approved stage-1 and Dropdown consolidations.
export const retiredStage1Ids = ['responsive', 'text-stroke', 'dynamic-data', 'default', 'controls'].map(id => `sw-header--${id}`)
export const retiredDropdownIds = ['layer-dropdown', 'color-dropdown', 'line-style-dropdown', 'text-dimension-style-dropdown'].map(id => `sw-header--${id}`)
export const swStoryEntries = index => Object.values(index.entries).filter(entry => entry.type === 'story' && (entry.title === 'SW/Header' || entry.title === 'SW/Header/Dropdown'))
export const retainedInventory = entries => entries.filter(entry => ![...retiredStage1Ids, ...retiredDropdownIds].includes(entry.id))
export const inventorySignature = entries => entries.map(entry => [entry.id, entry.name, entry.tags]).sort((a, b) => a[0].localeCompare(b[0]))
+8
View File
@@ -0,0 +1,8 @@
/* Story-owned composition only. Public controls retain package sizes and styling. */
.sw-composed-controls .sw-story-composed { flex-wrap: wrap; }
.sw-composed-controls__settings { margin-bottom: 12px; font-size: 13px; }
.sw-composed-controls__settings summary { width: max-content; cursor: pointer; }
.sw-composed-controls__settings-content { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 16px; padding-block: 8px; }
.sw-composed-controls__settings-content label { display: inline-flex; align-items: center; gap: 4px; }
.sw-composed-controls__status { margin-top: 12px; font-size: 12px; overflow-wrap: anywhere; }
.sw-composed-controls__status output { display: block; }
+16
View File
@@ -0,0 +1,16 @@
import type { Meta, StoryObj } from "@storybook/react-vite"
import { ComposedDemo } from "./sw-header.stories"
import "./sw-composed-controls.css"
const meta = {
title: "SW/Header/Dropdown",
// Keep existing bookmarks while placing the single example under Dropdown.
id: "sw-header",
parameters: { layout: "fullscreen", controls: { disable: true } },
} satisfies Meta
export default meta
export const ComposedControls: StoryObj<typeof meta> = {
name: "Composed Controls",
render: () => <ComposedDemo />,
}
+122 -263
View File
@@ -1,7 +1,7 @@
import { useEffect, useRef, useState, type ReactNode } from "react"
import { useEffect, useId, useRef, useState, type ReactNode } from "react"
import type { Meta, StoryObj } from "@storybook/react-vite"
import {
SWHeader, SWHeaderColorControl, SWHeaderLayerControl, SWHeaderLineStyle, SWHeaderTextStyle, SWHeaderDimensionStyle,
SWHeader, SWHeaderColorMenu, SWHeaderLineStyleMenu, SWHeaderTextStyleMenu, SWHeaderDimensionStyleMenu,
SWHeaderProperties, SWHeaderWindowControls, SWTheme, SWHeaderLayerMenu, SWHeaderInput, parseSWHeaderColor, swHeaderLinePatterns, SWHeaderPropertyPanel, SWHeaderPropertyBar,
type SWHeaderColorMode, type SWHeaderColorOption, type SWHeaderColorValue, type SWHeaderDimensionStyleOption,
type SWHeaderDocument, type SWHeaderLayer, type SWHeaderLineStyleValue, type SWHeaderLineType, type SWHeaderLineWeight,
@@ -65,6 +65,7 @@ const callbacks = {
const meta = {
title: "SW/Header",
excludeStories: ["ComposedDemo"],
component: SWHeader,
parameters: { layout: "fullscreen" },
args: { ...figmaArgs, ...callbacks },
@@ -302,48 +303,126 @@ export const WindowMoveMotion: Story = {
),
}
export const ComposedControls: Story = {
name: "Composed Controls",
parameters: { controls: { disable: true } },
render: () => <ComposedDemo />,
}
function ComposedDemo() {
// ComposedDemo is exported for the Dropdown CSF file; exclude it from this file's Story index.
export function ComposedDemo() {
const panelId = useId()
const detailRef = useRef<HTMLDivElement>(null)
const [activeMenu, setActiveMenu] = useState<SWHeaderMenuId | null>(null)
const [scenario, setScenario] = useState("normal")
const [disabled, setDisabled] = useState(false)
const [layerReadOnly, setLayerReadOnly] = useState(false)
const [detailCallbacks, setDetailCallbacks] = useState(true)
const [layers, setLayers] = useState(SAMPLE_LAYERS)
const [weights, setWeights] = useState(FIGMA_LINE_WEIGHTS)
const [weightId, setWeightId] = useState("w-default")
const [colorMode, setColorMode] = useState<SWHeaderColorMode | null>(null)
const [textStyle, setTextStyle] = useState(figmaArgs.textStyle!)
const [dimensionStyle, setDimensionStyle] = useState(figmaArgs.dimensionStyle!)
const [properties, setProperties] = useState(() => propertyFixture("circle").map(item => item.id === "layer" ? { ...item, value: "0" } : item))
const [bar, setBar] = useState(false)
const [panel, setPanel] = useState(false)
return (
<StoryPage>
<StoryPageHeader kicker={KICKER} title="Composed Controls" description="공개 하위 컴포넌트만 골라 다른 SW 화면에 재사용하는 예입니다. SWTheme이 SW 토큰·글꼴·버튼 초기화 범위를 제공하므로 소비자가 hm-* class를 붙이지 않습니다. 녹색 면은 예제 배치용 Story 배경입니다." />
<StorySection title="레이어 · 색상 · 상세보기">
<SWTheme className="sw-story-composed">
<SWHeaderLayerControl value={{ name: "0_Layer_Cludmark" }} />
<SWHeaderColorControl value={{ value: "255,229,0", swatch: "#ffe500" }} selected />
<SWHeaderProperties panelOpen={panel} onPanelToggle={() => setPanel(value => !value)} />
</SWTheme>
</StorySection>
<StorySection title="선스타일 · 문자스타일 · 치수스타일" description="필드 전체 Hover 시 라벨·값·선/폰트/치수 미리보기가 #FFC600입니다. 선의 검정 border와 치수 SVG의 검정 외곽선은 유지합니다.">
<div className="sw-story-scroller">
<SWTheme className="sw-story-composed">
<SWHeaderLineStyle value={figmaArgs.lineStyle!} onClick={callbacks.onLineStyleOpen} />
<SWHeaderTextStyle value={figmaArgs.textStyle!} onClick={callbacks.onTextStyleOpen} />
<SWHeaderDimensionStyle value={figmaArgs.dimensionStyle!} onClick={callbacks.onDimensionStyleOpen} />
</SWTheme>
const [log, setLog] = useState<string[]>([])
// The overlay positions itself on mount; focus after that initial hidden layout is resolved.
useEffect(() => {
if (!panel) return
const frame = requestAnimationFrame(() => document.getElementById(panelId)?.focus())
return () => cancelAnimationFrame(frame)
}, [panel, panelId])
const record = (line: string) => { setLog(lines => [...lines.slice(-11), line]); console.info(`[SWHeader Composed] ${line}`) }
const value = (id: string) => properties.find(item => item.id === id)?.value ?? ""
const change = (id: string, next: string, event: string) => {
setProperties(items => items.map(item => item.id === id ? { ...item, value: next, mixed: false } : item))
if (id === "color") setColorMode(null)
record(`${event}(${id}, ${next})`)
}
const availableLayers = scenario === "empty" ? [] : scenario === "long" ? LONG_LAYERS : scenario === "many" ? MANY_LAYERS : layers
const currentLayer = availableLayers.find(item => item.name === value("layer"))
const currentWeight = weights.find(item => item.id === weightId)
const color = parseSWHeaderColor(value("color"))
const menuProps = (id: SWHeaderMenuId) => ({
open: activeMenu === id, disabled,
onClick: () => record(`on${id[0].toUpperCase() + id.slice(1)}Open`),
onOpenChange: (open: boolean) => {
setActiveMenu(current => open ? id : current === id ? null : current)
record(`${id}Open(${open})`)
},
})
const detail = (name: string) => detailCallbacks ? () => record(`on${name}Detail`) : undefined
const toggleLayer = (key: "visible" | "frozen" | "locked", event: string) => layerReadOnly ? undefined : (layer: SWHeaderLayer, next: boolean) => {
setLayers(items => items.map(item => item.id === layer.id || item.name === layer.id ? { ...item, [key]: next } : item))
record(`${event}(${layer.id}, ${next})`)
}
const chooseWeight = (weight: SWHeaderLineWeight) => {
setWeightId(weight.id)
if (weight.value !== undefined) change("weight", weight.value, "onLineWeightSelect")
else record(`onLineWeightSelect(${weight.id})`)
}
const changeWeight = (weight: SWHeaderLineWeight, next: string) => {
setWeights(items => items.map(item => item.id === weight.id ? { ...item, value: next } : item))
if (weightId === weight.id) change("weight", next, "onLineWeightValueChange")
else record(`onLineWeightValueChange(${weight.id}, ${next})`)
}
const closePanel = () => {
setPanel(false); record("onPropertyPanelOpenChange(false)")
detailRef.current?.querySelector<HTMLButtonElement>("[data-property-panel-trigger]")?.focus()
}
const menus: SWHeaderPropertyMenus = {
layers: availableLayers, lineTypes: PROPERTY_LINE_TYPES, lineWeights: weights, activeLineWeightId: weightId, lineScale: value("scale"),
colors: FIGMA_COLORS, userColors: scenario === "many" ? MANY_USER_COLORS : FIGMA_USER_COLORS, colorMode,
onLayerVisibilityChange: toggleLayer("visible", "onLayerVisibilityChange"), onLayerFreezeChange: toggleLayer("frozen", "onLayerFreezeChange"), onLayerLockChange: toggleLayer("locked", "onLayerLockChange"),
onLayerDetail: detail("Layer"), onLineStyleDetail: detail("LineStyle"), onColorDetail: detail("Color"),
onLineWeightSelect: chooseWeight, onLineWeightValueChange: changeWeight, onLineScaleChange: next => change("scale", next, "onLineScaleChange"),
onColorModeChange: mode => { setColorMode(mode); record(`onColorModeChange(${mode})`) }, onColorPick: () => record("onColorPick"),
}
const panelProperties = properties.map(item => ({ ...item, disabled, ...(item.id === "layer" ? { options: availableLayers.map(layer => ({ ...layer, id: layer.name })) } : {}) }))
return <StoryPage className="sw-composed-controls">
<StoryPageHeader kicker={KICKER} title="Composed Controls" description="SW Header의 레이어·색상·선스타일·문자스타일·치수스타일과 상세보기를 직접 조작합니다. 메뉴의 상세 버튼은 기존 호스트 Callback을 호출하며 CAD 상세 화면은 생성하지 않습니다." />
<details className="sw-composed-controls__settings">
<summary>시연 설정</summary>
<div className="sw-composed-controls__settings-content">
<label>목록 데이터 <select value={scenario} onChange={event => { setActiveMenu(null); setScenario(event.target.value) }}>
<option value="normal">기본</option><option value="long">긴 레이어명</option><option value="many">레이어 20개 · 사용자 색상 40개</option><option value="empty">빈 레이어 목록</option>
</select></label>
<label><input type="checkbox" checked={disabled} onChange={event => { setActiveMenu(null); setDisabled(event.target.checked) }} />컨트롤 Disabled</label>
<label><input type="checkbox" checked={layerReadOnly} onChange={event => setLayerReadOnly(event.target.checked)} />레이어 상태 표시 전용</label>
<label><input type="checkbox" checked={detailCallbacks} onChange={event => setDetailCallbacks(event.target.checked)} />메뉴 상세 Callback 연결</label>
</div>
</details>
<SWTheme>
<div className="sw-story-composed" role="group" aria-label="조합 컨트롤" data-composed-controls="">
<SWHeaderLayerMenu {...menuProps("layer")} value={{ name: value("layer") }} layers={availableLayers} activeLayerId={currentLayer?.id}
onLayerSelect={layer => change("layer", layer.name, "onLayerSelect")} onDetail={detail("Layer")}
onVisibilityChange={scenario === "normal" ? menus.onLayerVisibilityChange : undefined} onFreezeChange={scenario === "normal" ? menus.onLayerFreezeChange : undefined} onLockChange={scenario === "normal" ? menus.onLayerLockChange : undefined} />
<SWHeaderColorMenu {...menuProps("color")} value={{ value: colorMode === "byLayer" ? "ByLayer" : colorMode === "byBlock" ? "ByBlock" : value("color"), swatch: color?.hex }}
colors={FIGMA_COLORS} userColors={menus.userColors} mode={colorMode}
onColorSelect={item => change("color", item.value ?? parseSWHeaderColor(item.color)?.value ?? item.color, "onColorSelect")}
onColorInput={next => change("color", next.value, "onColorInput")} onModeChange={mode => { setColorMode(mode); record(`onColorModeChange(${mode})`) }}
onPick={() => record("onColorPick")} onDetail={detail("Color")} />
<SWHeaderLineStyleMenu {...menuProps("lineStyle")} value={{ name: value("line"), weight: currentWeight?.value === undefined ? currentWeight?.name ?? value("weight") : value("weight"), scale: value("scale") }}
lineTypes={FIGMA_LINE_TYPES} lineWeights={weights} activeLineWeightId={weightId}
onLineTypeSelect={item => change("line", item.name, "onLineTypeSelect")} onLineWeightSelect={chooseWeight} onLineWeightValueChange={changeWeight}
onScaleChange={next => change("scale", next, "onLineScaleChange")} onDetail={detail("LineStyle")} />
<SWHeaderTextStyleMenu {...menuProps("textStyle")} value={textStyle} textStyles={FIGMA_TEXT_STYLES}
onTextStyleSelect={item => { setTextStyle({ font: item.font, name: item.name }); record(`onTextStyleSelect(${item.id})`) }} onDetail={detail("TextStyle")} />
<SWHeaderDimensionStyleMenu {...menuProps("dimensionStyle")} value={dimensionStyle} dimensionStyles={FIGMA_DIMENSION_STYLES}
onDimensionStyleSelect={item => { setDimensionStyle({ name: item.name }); record(`onDimensionStyleSelect(${item.id})`) }} onDetail={detail("DimensionStyle")} />
<div ref={detailRef}>
<SWHeaderProperties disabled={disabled} barOpen={bar} panelOpen={panel} panelId={panelId}
onBarToggle={() => { setActiveMenu(null); setBar(next => !next); record(`onPropertyBarOpenChange(${!bar})`) }}
onPanelToggle={() => { setActiveMenu(null); setPanel(next => !next); record(`onPropertyPanelOpenChange(${!panel})`) }} />
</div>
</StorySection>
<StorySection title="그룹 필드 Hover (고정)" description="기존 노란 Gradient Border에 텍스트·지정 미리보기 강조만 더합니다. 색상 견본과 레이어 상태는 원래 색을 유지하며, 상세보기는 기존 텍스트 전용 Hover 그대로입니다.">
<div className="sw-story-scroller">
<PinHover selectors={[".hm-sw-header__field"]}>
<SWTheme className="sw-story-composed">
<SWHeaderLayerControl value={figmaArgs.layer!} />
<SWHeaderColorControl value={figmaArgs.color!} />
<SWHeaderLineStyle value={figmaArgs.lineStyle!} />
<SWHeaderTextStyle value={figmaArgs.textStyle!} />
<SWHeaderDimensionStyle value={figmaArgs.dimensionStyle!} />
</SWTheme>
</PinHover>
</div>
</StorySection>
</StoryPage>
)
</div>
{bar && <SWHeaderPropertyBar selection={propertySelection("circle")} properties={panelProperties.filter(item => BAR_FIXTURE.some(barItem => barItem.id === item.id))}
onPropertyChange={(property, next) => change(property.id, next, "onPropertyChange")} />}
{panel && <SWHeaderPropertyPanel id={panelId} anchorRef={detailRef} selection={propertySelection("circle")} properties={panelProperties} groups={PROPERTY_GROUPS}
menus={{ ...menus, layers: availableLayers.map(layer => ({ ...layer, id: layer.name })) }}
onPropertyChange={(property, next) => change(property.id, next, "onPropertyChange")} onClose={closePanel} />}
</SWTheme>
<div className="sw-composed-controls__status">
<output data-style-state="">레이어: {value("layer")} · 색상: {colorMode ?? value("color")} · 선: {value("line")} / {value("weight")} / {value("scale")} · 문자: {textStyle.name} · 치수: {dimensionStyle.name}</output>
<output aria-live="polite" data-callback-log="">Callback: {log.length ? log.join(" → ") : "없음"}</output>
</div>
</StoryPage>
}
/** Neutral sample logos with different ratios (no product or brand). */
@@ -558,16 +637,7 @@ const MANY_LAYERS: SWHeaderLayer[] = Array.from({ length: 20 }, (_, index) => ({
frozen: index % 5 === 2,
locked: index % 6 === 3,
}))
/**
* Icon variant matrix: rows 1-2 colored (visible, thawed, unlocked), rows 3-4 gray (hidden, frozen,
* locked); rows 2 and 4 get pinned icon hover.
*/
const ICON_LAYERS: SWHeaderLayer[] = [
{ id: "icon-on", name: "컬러 (Default)", visible: true, frozen: false, locked: false },
{ id: "icon-on-hover", name: "컬러 Hover (Variant2)", visible: true, frozen: false, locked: false },
{ id: "icon-off", name: "회색 (Variant3)", visible: false, frozen: true, locked: true },
{ id: "icon-off-hover", name: "회색 Hover (Variant4)", visible: false, frozen: true, locked: true },
]
const noop = () => {}
type LayerHostProps = Partial<SWHeaderProps> & { onLog?: (line: string) => void; showState?: boolean }
@@ -618,94 +688,6 @@ function LayerDemo({ width, ...props }: LayerHostProps & { width: number }) {
)
}
/** Standalone open layer menu: the 12 icon variants (rows 2 and 4 pin the icon hover). */
function IconMatrix() {
return (
<PinHover selectors={[".hm-sw-header__layer-row:nth-child(2) .hm-sw-header__layer-toggle", ".hm-sw-header__layer-row:nth-child(4) .hm-sw-header__layer-toggle"]}>
<div className="sw-story-zoom sw-story-layer-room">
<SWTheme className="sw-story-composed">
<SWHeaderLayerMenu
value={{ name: "아이콘 Variant" }}
layers={ICON_LAYERS}
open
onVisibilityChange={noop}
onFreezeChange={noop}
onLockChange={noop}
/>
</SWTheme>
</div>
</PinHover>
)
}
const NARROW_LAYER_WIDTHS = [1440, 1080, 900, 768, 640, 390]
export const LayerDropdown: Story = {
name: "Layer Dropdown",
parameters: { controls: { disable: true } },
render: () => (
<StoryPage>
<StoryPageHeader
kicker={KICKER}
title="Layer Dropdown"
description="레이어 필드를 클릭하면 Figma header/menu/레이어(26:10940)의 레이어 목록이 필드 아래로 겹쳐 열립니다. Hover만으로는 열리지 않습니다. 행은 header/dropdown/brown/row(26:10687), 아이콘은 icon_전구(26:10810)·icon_눈꽃(26:10855)·icon_자물쇠(26:10912)입니다. 레이어 목록과 각 상태는 호스트 데이터이며 아래 레이어명은 테스트용 예시입니다."
/>
<StorySection title="Layer Default" description="layers를 전달한 기본 상태. 필드 234 × 38, 기존 테두리·그림자, 아이콘 3개 + 라벨/레이어명. layers를 전달하지 않으면 기존 필드 버튼(onLayerOpen) 그대로입니다.">
<Frame width={1920}><LayerHeader layers={FIGMA_LAYERS} /></Frame>
</StorySection>
<StorySection title="Layer Hover (고정)" description="기존 노란 Gradient Border와 라벨·레이어명 #FFC600. 목록은 열리지 않습니다.">
<Frame width={1920}><PinHover selectors={[".hm-sw-header__field--layer"]}><LayerHeader layers={FIGMA_LAYERS} /></PinHover></Frame>
</StorySection>
<StorySection title="Layer Dropdown Open (Figma 8개 행)" description="Variant3: 라벨·레이어명 #FFC600, 필드 테두리 #081813·하단 각진 모서리, 필드+목록을 감싸는 노란 Gradient 1px 외곽선(236 × 320). 목록 234 × 280(행 30 × 8 + 하단 40), 배경 #27241D, 검정 1px, 하단 radius 3px, Shadow 0 4px 8px rgba(16,48,38,.25). 이 예제는 onLayerDetail이 없어 클릭은 무동작이며 상세 버튼의 공통 Hover는 유지합니다.">
<MenuFrame width={1920}><LayerHeader layers={FIGMA_LAYERS} layerMenuOpen onLayerDetail={undefined} /></MenuFrame>
</StorySection>
<StorySection title="Layer Row Default · Row Hover (고정)" description="두 번째 행 Hover 고정: 배경 #62533D, 레이어명 #FF5C00(26:10695). 행 크기·아이콘 위치는 그대로입니다. 다른 필드·문서 목록의 Hover 색과 무관한 이 목록 전용 색입니다.">
<MenuFrame width={1920}><PinHover selectors={[".hm-sw-header__layer-row:nth-child(2)"]}><LayerHeader layers={FIGMA_LAYERS} layerMenuOpen /></PinHover></MenuFrame>
</StorySection>
<StorySection title="전구 · 눈꽃 · 자물쇠 On / Hover / Off / Off Hover (3배 확대)" description="1행 컬러(Default: visible=true · frozen=false · locked=false) · 2행 컬러 Hover(Variant2, 고정) · 3행 회색(Variant3: visible=false · frozen=true · locked=true) · 4행 회색 Hover(Variant4, 고정). 전구 Hover는 검정 25% 배경, 눈꽃·자물쇠 Hover는 Figma Hover SVG(같은 아이콘 + 검정 25% 타일)입니다. Off → Off Hover는 Figma Smart Animate에 맞춰 300ms ease-out으로 전환됩니다.">
<IconMatrix />
</StorySection>
<StorySection title="레이어 선택 · 개별 아이콘 Toggle · Callback 기록" description="필드 클릭으로 열고, 레이어명(색상 견본 포함)을 누르면 onLayerSelect만 호출되고 필드에 그 레이어가 표시되며 목록이 닫힙니다. 전구·눈꽃·자물쇠는 각각 onLayerVisibilityChange(layer, !visible) / onLayerFreezeChange(layer, !frozen) / onLayerLockChange(layer, !locked)만 한 번 호출하고 목록은 열린 채 유지됩니다(전구 컬러 = visible=true, 눈꽃 컬러 = frozen=false 동결 해제, 자물쇠 컬러 = locked=false 잠금 해제, 회색은 반대). 위 상태표로 해당 레이어만 바뀌는 것을 확인합니다. 키보드: Enter/Space 열기, ↓↑ 행 이동(같은 열 유지), ←→ 행 안 이동, Escape 닫기, Tab으로 벗어나면 닫힘.">
<LayerDemo width={1920} activeLayerId="layer-0" />
</StorySection>
<StorySection title="여러 레이어의 서로 다른 상태 · 현재 레이어" description="현재 레이어(activeLayerId)는 Hover와 같은 갈색 배경·주황 글자이고 필드 아이콘도 그 레이어 상태를 따릅니다. Sample-Defpoints는 disabled 예시입니다.">
<MenuFrame width={1920}><LayerHeader activeLayerId="layer-5" layerMenuOpen /></MenuFrame>
</StorySection>
<StorySection title="현재 레이어 Hover (고정)" description="현재 레이어의 갈색 배경·주황 글자는 Hover 및 Mouse Leave 뒤에도 유지됩니다.">
<MenuFrame width={1920}><PinHover selectors={[".hm-sw-header__layer-row[data-active]"]}><LayerHeader activeLayerId="layer-1" layerMenuOpen /></PinHover></MenuFrame>
</StorySection>
<StorySection title="긴 레이어명" description="필드와 행 모두 말줄임으로 처리합니다. 전체 이름은 title로 확인합니다.">
<MenuFrame width={1920}><LayerHeader layers={LONG_LAYERS} activeLayerId="long-1" layerMenuOpen /></MenuFrame>
</StorySection>
<StorySection title="많은 레이어 (20개)" description="목록 부분만 세로 스크롤(최대 8행, 240px)하고 레이어 상세 영역은 고정입니다. 헤더에는 스크롤이 생기지 않습니다.">
<MenuFrame width={1920}><LayerHeader layers={MANY_LAYERS} layerMenuOpen /></MenuFrame>
</StorySection>
<StorySection title="레이어가 없는 상태" description="layers=[]이면 목록 없이 레이어 상세 영역만 표시하고 필드는 layer.name을 표시합니다.">
<MenuFrame width={1920}><LayerHeader layers={[]} layerMenuOpen /></MenuFrame>
</StorySection>
<StorySection title="레이어 상세 버튼" description="onLayerDetail을 전달하면 Callback 호출 후 목록을 닫습니다(아래 기록). 전달하지 않아도 공통 Default/Hover(텍스트 35%)를 유지하며 클릭은 안전한 무동작입니다(위 Figma 8개 행 예제). Disabled는 명시적으로 지정합니다.">
<LayerDemo width={1920} layers={FIGMA_LAYERS} />
</StorySection>
<StorySection title="상태 표시 전용(Toggle Callback 없음)" description="onLayerVisibilityChange 등을 전달하지 않으면 해당 아이콘은 버튼이 아닌 상태 표시(role=img)이며 Hover·클릭 반응이 없습니다.">
<MenuFrame width={1920}>
<SWHeader {...figmaArgs} {...callbacks} layers={SAMPLE_LAYERS} activeLayerId="layer-0" layerMenuOpen />
</MenuFrame>
</StorySection>
{NARROW_LAYER_WIDTHS.map(width => (
<StorySection
key={width}
title={`좁은 화면 (헤더 ${width}px)`}
description={width < 520
? "520 미만에서는 필드의 상태 아이콘이 숨고 레이어명이 말줄임됩니다. 목록은 234px 그대로이며 헤더 밖으로 넘치지 않도록 왼쪽으로 이동합니다(이때 노란 외곽선은 목록만 감쌉니다). 필드를 눌러 열고 조작합니다."
: "필드 위치와 헤더 49px를 유지하고 목록은 필드 왼쪽에 맞춰 열립니다."}
>
<LayerDemo width={width} activeLayerId="layer-1" layerMenuOpen={width < 520 ? undefined : true} />
</StorySection>
))}
</StoryPage>
),
}
/* ------------------------------------------------------------------------------------------------
Field dropdowns (2026-10-16): color 26:10986 / 26:11036, ByLayer 26:12666, ByBlock 26:12659,
line style 26:11104 (rows 26:10702), text style 26:11181, dimension style 26:11215.
@@ -843,127 +825,6 @@ function StyleDemo({ width, ...props }: StyleHostProps & { width: number }) {
)
}
/** Latest explicit hover exceptions: mode pair and five detail buttons. */
const MENU_BUTTON_HOVER = [".hm-sw-header__color-mode", ".hm-sw-header__color-option", ".hm-sw-header__color-pick", ".hm-sw-header__menu-detail"]
export const ColorDropdown: Story = {
name: "Color Dropdown",
parameters: { controls: { disable: true } },
render: () => (
<StoryPage>
<StoryPageHeader
kicker={KICKER}
title="Color Dropdown"
description="색상 필드를 클릭하면 Figma header/menu/색상(26:10986)의 목록이 필드 아래로 겹쳐 열립니다(Hover만으로는 열리지 않음). ByLayer/ByBlock(26:12666 / 26:12659), 22px 기본 팔레트, 사용자 색상(26:11036), 색상 추출, RGB 입력, 색상 상세 버튼으로 구성됩니다. 팔레트·사용자 색상·현재 색상은 호스트 데이터이며 아래 값은 Figma 예시입니다."
/>
<StorySection title="Default" description="colors를 전달하면 색상 필드가 Dropdown 버튼이 됩니다. 192 × 38, 견본은 현재 색상(color.swatch).">
<Frame width={1920}><StyleHeader /></Frame>
</StorySection>
<StorySection title="Hover (고정)" description="기존 노란 Gradient Border + 라벨·값 #FFC600. 색상 견본은 실제 색 그대로입니다.">
<Frame width={1920}><PinHover selectors={[".hm-sw-header__field--color"]}><StyleHeader /></PinHover></Frame>
</StorySection>
<StorySection title="Expanded (Figma 26:11005)" description="192 × 158: ByLayer/ByBlock 167 × 30 · 팔레트 168 × 22(칩 22px 7개) · 색상 추출 24 + 입력 130 · 하단 40(색상 상세). 필드 테두리 #081813·아래 모서리 각짐, 필드+목록 노란 1px 외곽선(194 × 198).">
<MenuFrame width={1920}><StyleHeader userColors={[]} colorMenuOpen /></MenuFrame>
</StorySection>
<StorySection title="사용자 추가 색상 (Figma 26:11036)" description="userColors 2개: 24px 행이 추가되어 본문 182px. 개수는 가변이며 2px 간격으로 줄바꿈합니다.">
<MenuFrame width={1920}><StyleHeader colorMenuOpen /></MenuFrame>
</StorySection>
<StorySection title="사용자 색상 40개" description="팔레트 + 사용자 색상 4행(118px)을 넘으면 팔레트 영역만 세로 스크롤합니다. 헤더 높이·다른 필드 위치는 그대로입니다.">
<MenuFrame width={1920}><StyleHeader userColors={MANY_USER_COLORS} colorMenuOpen /></MenuFrame>
</StorySection>
<StorySection title="ByLayer On (Figma on 26:12671)" description="colorMode='byLayer': #62533D 배경 + 밝은 inner shadow. 텍스트 #D4CBBD + 검정 Stroke. ByBlock은 Default(rgba(98,83,61,.3) + 어두운 inner shadow).">
<MenuFrame width={1920}><StyleHeader initialColorMode="byLayer" colorMenuOpen /></MenuFrame>
</StorySection>
<StorySection title="내부 버튼 Hover (고정) — 2026-10-16 추가 수정 정책" description="ByLayer / ByBlock 글자 #FF5C00. 선택 배경과 Inset Shadow는 유지합니다. 색상 상세는 배경 .25·radius 25·Hover 아이콘으로 변합니다. 색상 칩은 Hover가 없고, 색상 추출은 btn_colorize Hover(26:11305)입니다.">
<MenuFrame width={1920}><PinHover selectors={MENU_BUTTON_HOVER}><StyleHeader colorMenuOpen /></PinHover></MenuFrame>
</StorySection>
<StorySection title="RGB 입력 Hover (고정)" description="입력은 수정 가능함을 알리는 Figma Hover를 유지합니다(header/menu/색상/input hover: 1px rgba(197,177,158,.2)). 편집 중(Focus)에는 값 영역이 검정이 되고 커서는 #E60403입니다 — 아래 실제 예제에서 클릭해 확인합니다.">
<MenuFrame width={1920}><PinHover selectors={[".hm-sw-header__color-input", ".hm-sw-header__color-input .hm-sw-header__input"]}><StyleHeader colorMenuOpen /></PinHover></MenuFrame>
</StorySection>
<StorySection title="선택 · 입력 · Callback 기록" description="칩 → onColorSelect, ByLayer/ByBlock → onColorModeChange(서로 배타: 이 호스트는 선택한 쪽만 On), 입력(255,0,0 · #00ff00 등, Enter 또는 Focus 이동) → 유효하면 onColorInput, 잘못된 값(256,0,0 · abc)은 복원. 색상 추출 → onColorPick 후 닫힘, 색상 상세 → onColorDetail 후 닫힘. 선택·입력 후에도 목록은 열려 있고 다른 속성(레이어·선스타일 등)은 그대로입니다. Escape·바깥 클릭·Tab으로 닫힘.">
<StyleDemo width={1920} />
</StorySection>
</StoryPage>
),
}
export const LineStyleDropdown: Story = {
name: "Line Style Dropdown",
parameters: { controls: { disable: true } },
render: () => (
<StoryPage>
<StoryPageHeader
kicker={KICKER}
title="Line Style Dropdown"
description="선스타일 필드를 클릭하면 Figma header/menu/선스타일(26:11104)의 3열 목록(선 종류 182 · 가중치 142 · 스케일 142, 468 × 192)이 필드 가운데 아래로 열립니다. 선 종류 행은 header/dropdown/brown/row(26:10702). 각 열은 자기 속성만 바꾸며 목록은 열린 채 유지됩니다."
/>
<StorySection title="Default" description="284 × 38. 선 미리보기 10 × 4 × 5, 선스타일 / 가중치 / 스케일.">
<Frame width={1920}><StyleHeader /></Frame>
</StorySection>
<StorySection title="Hover (고정)" description="라벨·값 #FFC600, 선 미리보기 채움 #FFC600(검정 1px 유지), 노란 Gradient Border.">
<Frame width={1920}><PinHover selectors={[".hm-sw-header__field--line-style"]}><StyleHeader /></PinHover></Frame>
</StorySection>
<StorySection title="Expanded (Figma 26:11143)" description="필드 링(286 × 39) + 468 × 192 drop_wrap(1px 노란 링, x −92, y 37). 선 종류 5행 + 하단 40(선스타일 상세), 가중치 4행(ByDefault 0.25, User 입력), 스케일 입력. 현재 선 종류·가중치는 Hover와 같은 갈색 배경·주황 텍스트·선입니다.">
<MenuFrame width={1920}><StyleHeader lineStyleMenuOpen /></MenuFrame>
</StorySection>
<StorySection title="선 종류 행 Default · Hover (Figma 26:10703 / 26:10706, 고정)" description="1·4번째 행 Hover 고정: 배경 #62533D, 선 미리보기·텍스트 #FF5C00, 검정 Stroke 유지, 크기 182 × 30·위치 그대로. CENTER·HIDDEN은 각자의 패턴(22·7 / 33·33)을 유지합니다. 가중치 2번째 행·스케일 행도 Figma 행 Hover를 고정했습니다.">
<MenuFrame width={1920}>
<PinHover selectors={[".hm-sw-header__line-column--type .hm-sw-header__menu-row:nth-child(1)", ".hm-sw-header__line-column--type .hm-sw-header__menu-row:nth-child(4)", ".hm-sw-header__line-column:nth-child(2) .hm-sw-header__menu-row:nth-child(2)", ".hm-sw-header__line-column:nth-child(3) .hm-sw-header__menu-row"]}>
<StyleHeader lineStyleMenuOpen />
</PinHover>
</MenuFrame>
</StorySection>
<StorySection title="현재 행 Hover (고정)" description="현재 선 종류(Continuous)는 Hover 및 Mouse Leave 뒤에도 갈색 배경·주황 선·이름을 유지합니다.">
<MenuFrame width={1920}><PinHover selectors={[".hm-sw-header__menu-row[data-active]"]}><StyleHeader lineStyleMenuOpen /></PinHover></MenuFrame>
</StorySection>
<StorySection title="상세 버튼 Hover (고정)" description="2026-10-16 추가 수정 기준으로 선스타일 상세의 Figma 배경 .25·radius 25·Hover 아이콘을 적용합니다.">
<MenuFrame width={1920}><PinHover selectors={MENU_BUTTON_HOVER}><StyleHeader lineStyleMenuOpen /></PinHover></MenuFrame>
</StorySection>
<StorySection title="선 종류 · 가중치 · 스케일 선택 Callback" description="선 종류 → onLineTypeSelect(가중치·스케일 유지), 가중치 → onLineWeightSelect(선 종류·스케일 유지), User 입력 → onLineWeightValueChange(0 이상), 스케일 입력 → onLineScaleChange(0 초과). 입력은 Enter/Focus 이동으로 확정, Escape는 취소. ↓↑로 항목 이동.">
<StyleDemo width={1920} />
</StorySection>
<StorySection title="좁은 헤더 390px" description="468px 목록이 헤더보다 넓으면 3열을 세로로 쌓아(필요 시 세로 스크롤) 화면 밖 이탈·가로 스크롤 없이 모든 항목에 접근합니다. 더보기 → 선스타일로 엽니다.">
<StyleDemo width={390} />
</StorySection>
</StoryPage>
),
}
export const TextDimensionStyleDropdown: Story = {
name: "Text · Dimension Style Dropdown",
parameters: { controls: { disable: true } },
render: () => (
<StoryPage>
<StoryPageHeader
kicker={KICKER}
title="Text · Dimension Style Dropdown"
description="문자스타일(26:11181)과 치수스타일(26:11215) 필드의 목록입니다. 164px, 행 30px, 하단 40px(상세 버튼). 행을 고르면 Callback 후 닫힙니다. 목록은 호스트 데이터이며 아래 값은 Figma 예시입니다."
/>
<StorySection title="Default · Hover (고정)" description="위: Default. 아래: Hover — 라벨·값·글꼴 미리보기 #FFC600, 치수 미리보기는 Figma Hover SVG, 검정 외곽선 유지.">
<div className="sw-story-stack">
<Frame width={1920}><StyleHeader /></Frame>
<Frame width={1920}><PinHover selectors={[".hm-sw-header__field--text-style", ".hm-sw-header__field--dimension-style"]}><StyleHeader /></PinHover></Frame>
</div>
</StorySection>
<StorySection title="문자스타일 Expanded (Figma 26:11200)" description="Arial / Standard, 돋움 / Dotum. 글꼴 16px + 이름 14px(모두 검정 Stroke). 하단 '문자스타일 상세'는 Figma처럼 왼쪽 정렬(테두리 .25).">
<MenuFrame width={1920}><StyleHeader textStyleMenuOpen /></MenuFrame>
</StorySection>
<StorySection title="문자스타일 행·상세 버튼 Hover (고정)" description="두 번째 행과 현재 스타일 모두 #62533D / 글꼴·이름 #FF5C00입니다. 상세 버튼도 Figma Hover입니다.">
<MenuFrame width={1920}><PinHover selectors={[".hm-sw-header__list-menu--text-style .hm-sw-header__menu-row:nth-child(2)", ".hm-sw-header__menu-detail"]}><StyleHeader textStyleMenuOpen /></PinHover></MenuFrame>
</StorySection>
<StorySection title="치수스타일 Expanded (Figma 26:11242)" description="Standard, ISO - 25. 치수 미리보기 60 × 15(Figma 행 자산 #F6F4F2). 하단 '치수스타일 상세' 오른쪽 정렬.">
<MenuFrame width={1920} fixedDimension><StyleHeader dimensionStyleMenuOpen /></MenuFrame>
</StorySection>
<StorySection title="치수스타일 행·상세 버튼 Hover (고정)" description="두 번째 행: #62533D, 이름·치수 미리보기 #FF5C00(Figma Hover 자산). 상세 버튼 Hover는 26:10799(기본 아이콘·텍스트 100%)이며 Variant3와 혼합하지 않습니다.">
<MenuFrame width={1920} fixedDimension><PinHover selectors={[".hm-sw-header__list-menu--dimension-style .hm-sw-header__menu-row:nth-child(2)", ".hm-sw-header__menu-detail"]}><StyleHeader dimensionStyleMenuOpen /></PinHover></MenuFrame>
</StorySection>
<StorySection title="선택 Callback" description="행 → onTextStyleSelect / onDimensionStyleSelect 1회 후 닫힘, 상세 → on*Detail 1회 후 닫힘. 필드 값이 호스트 상태로 갱신됩니다.">
<StyleDemo width={1920} />
</StorySection>
</StoryPage>
),
}
const MORE_WIDTHS = [1920, 1800, 1799, 1440, 1180, 1179, 1080, 1079, 900, 899, 768, 640, 639, 520, 519, 390]
export const ResponsiveMore: Story = {
@@ -1348,8 +1209,6 @@ export const Colorize: Story = {
render: () => <StoryPage><StoryPageHeader kicker={KICKER} title="btn_colorize" description="Figma 26:11302 / 26:11305의 원본 SVG, 24px 버튼과 18px 아이콘. 클릭은 기존 onColorPick 계약입니다. 색상 돋보기 Overlay 26:11338은 호스트 연결 대상입니다." /><StyleDemo width={1920} /></StoryPage>,
}
/* 2026-10-16 composition review: every part except the logo can be removed (hiddenControls), the five
similar menus can be reordered (menuOrder). Untouched props keep the approved default header. */
const HIDEABLE_PARTS: { id: SWHeaderHideableControlId; name: string }[] = [