feat(sw): measured header compaction, gauge recolor, popup menu and story cleanups
Deploy Storybook / deploy (push) Successful in 1m12s

- SWHeader (760-1799px): pictures hide one at a time by measured room (치수 아이콘, 선 그림,
  글꼴명, 색상 칩, 레이어 상태 아이콘), then the file name narrows 310 -> 96px, then values
  ellipsize; re-fit after web fonts load. 가중치/스케일 columns grow for longer values.
- Gauge style B / property window range: Figma controll_bar_new 633:77827 colors, ring and
  shadow on the previous size (6px track, 14px thumb).
- Property window: editable text values (e.g. 하이퍼링크) get the editing face like numbers.
- SW Header › Logo: same cases, order and layout as SW Viewer › Logo (ID kept).
- Storybook inner: 80vw from 1920px. Responsive More 1920px rows use the page's usable width
  (container sw-story-page) and span 1920px when there is room.
- SW/Popup sidebar: Property Panel only; Custom Content / Multiple Popups tagged verification.
- SW Viewer Settings Popup: 축척 지정 demo popup removed, frame 620px.
- Tests: inventory / simplification sidebar expectations, Popup-only unit select check.

Verified: check:ai-docs PASS, changed test syntax, headless Chrome checks of header compaction,
Responsive 1920 rows (1920 hidden / 2560, 3840 shown), Popup sidebar, Settings Popup.
Not verified: integrated-visual baselines (not updated), full regression, changed tests not run.
This commit is contained in:
shkim4 committed 2026-10-22 20:50:39 +09:00
1 parent c1549b2b4f
commit 6d46289fc5
13 files changed
+133 -94

No files matched your search

@@ -131,7 +131,8 @@ await goto('sw-header--property-panel-compare')
const prop = await page.locator('.hm-sw-property__value > input[type="range"]').first().evaluate(e => { const r = e.getBoundingClientRect(); return [Math.round(r.width), Math.round(r.height), getComputedStyle(e).getPropertyValue('--hm-sw-range-track-paint').trim().length > 0] })
check('Slider: property window gauge keeps 86 × 16 and its paint', prop[0] === 86 && prop[1] === 16 && prop[2], prop)
// 3b. Unit select: Popup 도면 설정 = Viewer 축척 지정 (same SWSelect, same computed look in every state)
// 3b. Unit select: Popup 도면 설정 (SWSelect). 2026-10-22 (user request): the Viewer 축척 지정 demo popup was removed,
// so the Viewer side of this comparison is gone; the Popup select keeps its look and behaviour checks.
const selProps = ['appearance', 'height', 'paddingLeft', 'paddingRight', 'borderTopWidth', 'borderTopColor', 'borderTopStyle', 'borderRadius', 'backgroundColor', 'color', 'fontSize', 'fontWeight', 'lineHeight', 'outlineStyle', 'outlineColor', 'outlineWidth', 'opacity', 'cursor']
const selRead = loc => loc.evaluate((e, p) => { const s = getComputedStyle(e); return p.map(k => `${k}=${s[k]}`).join(';') + `;class=${e.className};tag=${e.tagName}` }, selProps)
const selStates = async loc => { const d = await selRead(loc); await loc.hover(); await page.waitForTimeout(80); const h = await selRead(loc); await loc.focus(); await page.keyboard.press('Shift+Tab'); await page.keyboard.press('Tab'); await page.waitForTimeout(80); const f = await selRead(loc); await page.mouse.move(2, 2); return { d, h, f } }
@@ -141,17 +142,9 @@ const ps = await selStates(popupSel)
const popupOptions = await popupSel.evaluate(e => [...e.options].map(o => o.value))
await popupSel.selectOption('m'); await page.waitForTimeout(80)
const popupPicked = [(await log()).includes('unit=m'), await popupSel.inputValue()]
await goto('sw-viewer--content-variants')
const viewerSel = page.locator('.hm-sw-viewer-panel [data-sw-select="unit"]')
const vs = await selStates(viewerSel)
const viewerOptions = await viewerSel.evaluate(e => [...e.options].map(o => o.value))
await viewerSel.selectOption('m'); await page.waitForTimeout(80)
// 2026-10-21 (user decision): the chosen value of an editable Popup select is red (#E60403) like every editable value;
// the Viewer panel keeps its own text color. Everything else of the look stays the same.
const noColor = look => look.replace(/(^|;)color=[^;]*/, '$1')
check('Select: Popup 도면 설정 단위 = Viewer 축척 지정 단위 (default · hover · focus computed look, text color apart); Popup value red', noColor(ps.d) === noColor(vs.d) && noColor(ps.h) === noColor(vs.h) && noColor(ps.f) === noColor(vs.f) && ps.d.includes('class=hm-sw-select') && ps.d.includes('color=rgb(230, 4, 3)'), { ps, vs })
check('Select: options and selection kept (Popup mm/cm/m, Viewer mm/m), change events', JSON.stringify(popupOptions) === '["mm","cm","m"]' && JSON.stringify(viewerOptions) === '["mm","m"]' && popupPicked[0] && popupPicked[1] === 'm' && await viewerSel.inputValue() === 'm', { popupOptions, viewerOptions, popupPicked })
await page.locator('.hm-sw-viewer-panel', { hasText: '축척 지정' }).screenshot({ path: path.join(out, 'viewer-scale-select.png') })
// 2026-10-21 (user decision): the chosen value of an editable Popup select is red (#E60403) like every editable value.
check('Select: Popup 도면 설정 단위 is SWSelect in default · hover · focus; value red', [ps.d, ps.h, ps.f].every(look => look.includes('class=hm-sw-select')) && ps.d.includes('color=rgb(230, 4, 3)'), { ps })
check('Select: options and selection kept (Popup mm/cm/m), change events', JSON.stringify(popupOptions) === '["mm","cm","m"]' && popupPicked[0] && popupPicked[1] === 'm', { popupOptions, popupPicked })
// 3c. Header Open hysteresis (fix A): grow 520 → 1080, Open returns once and stays; shrink: Open moves first.
await goto('sw-header--document-open')
+3 -1
View File
@@ -103,7 +103,9 @@ export const menuCleanupHiddenIds = ['sw-header--interactive-states', 'sw-header
// Second pass (same day): SW/Theme hidden as a whole; Viewer settings-panel merged into content-variants.
'sw-header--document-open', 'sw-header--composed-controls', ...themeStoryIds, ...['menu-groups', 'states', 'dropdowns', 'variable-size', 'settings-panel'].map(id => `sw-viewer--${id}`),
// 2026-10-22 (user request): SWHeader vs Viewer Header left the sidebar the same way.
'sw-viewer--compare-with-sw-header']
'sw-viewer--compare-with-sw-header',
// 2026-10-22 (user request): SW/Popup keeps only Property Panel in the sidebar.
'sw-popup--custom-content', 'sw-popup--multiple-popups']
export const renamedEntries = { 'sw-header--overview': 'SW Header', 'sw-footer--full-footer': 'SW Footer',
'sw-header--logo-slot': 'Logo', // 2026-10-22 (user request): sidebar "Logo", page title "SW Header — 로고"
'sw-header--property-panel-compare': 'Property Panel', // 2026-10-22 (user request): was "Property Panel · 4개 비교"
@@ -55,7 +55,8 @@ const hidden = ['sw-header--window-move-motion', 'sw-header--k-guide', 'sw-foote
check('verification Stories not in sidebar', rows.every(r => !hidden.includes(r[0])), rows.filter(r => hidden.includes(r[0])))
const popupRows = await m.locator('#storybook-explorer-tree [data-item-id]').evaluateAll(list => list.map(e => e.dataset.itemId))
const pi = popupRows.indexOf('sw-popup')
check('Popup children order: Custom Content, Multiple Popups, Property Panel', JSON.stringify(popupRows.slice(pi + 1, pi + 4)) === JSON.stringify(['sw-popup--custom-content', 'sw-popup--multiple-popups', 'sw-header--property-panel-compare']), popupRows.slice(pi + 1, pi + 4))
// 2026-10-22 (user request): SW/Popup shows only Property Panel; Custom Content / Multiple Popups are verification.
check('Popup children: Property Panel only', JSON.stringify(popupRows.slice(pi + 1, pi + 2)) === JSON.stringify(['sw-header--property-panel-compare']) && !popupRows.some(id => id.startsWith('sw-popup--')), popupRows.slice(pi + 1, pi + 4))
const headerIds = rows.filter(r => r[0].startsWith('sw-header--')).map(r => r[0])
check('Property Panel listed once (under Popup only)', headerIds.filter(id => id === 'sw-header--property-panel-compare').length === 1)
await m.locator('[data-item-id="sw-header--property-panel-compare"]').click(); await m.waitForTimeout(800)