- dropdown-consolidation, storybook-cleanup-stage1, detail-buttons, property-panel-comparison: assert their recorded state and accept today only the approved later Story changes (storybook-inventory.mjs helpers). - header-composition.browser.mjs + fixtures/header-composition.tsx: the removed Composition Story presets, hidden controls, invalid menuOrder / hiddenControls and live changes, on a test-only page using the public API only. - storybook-unused-removal: header comment lists which older scripts run on current Stories again.
133 lines
14 KiB
JavaScript
133 lines
14 KiB
JavaScript
// 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}`)
|
|
// 2026-10-19: duplicate property panel demos; the four states live on sw-header--property-panel-compare.
|
|
export const retiredPropertyPanelIds = ['property-panel-variants', 'property-panel-none', 'property-panel-all', 'property-panel-circle', 'property-panel-expanded'].map(id => `sw-header--${id}`)
|
|
// 2026-10-19: unused SW Header demo pages; their features stay in the package and the retained Stories.
|
|
export const retiredUnusedDemoIds = ['property-fields', 'property-shape-slot', 'composition', 'colorize', 'dynamic-controls', 'property-bar', 'additional-hover', 'property-panel', 'layer-detail-input'].map(id => `sw-header--${id}`)
|
|
// Include the old title when reading historical evidence; live hierarchy is asserted separately.
|
|
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))
|
|
.map(entry => entry.id === 'sw-header--composed-controls' ? { ...entry, name: 'Dropdown', title: 'SW/Header' } : entry)
|
|
export const inventorySignature = entries => entries.map(entry => [entry.id, entry.name, entry.tags]).sort((a, b) => a[0].localeCompare(b[0]))
|
|
// 2026-10-19 SW integrated improvement (0.2.0): the only Stories added after the unused-demo removal (two under
|
|
// SW/Header next to its 10 retained Stories, the rest under SW/Tool and SW/Popup), and the only package files it changed.
|
|
// The two Header Stories sit directly under SW/Header (no separate Options menu), in src/sw/sw-header-open.stories.tsx.
|
|
export const integratedStoryIds = ['sw-header--document-open', 'sw-header--hidden-sub-controls', 'sw-tool--tool-buttons', 'sw-popup--custom-content', 'sw-popup--multiple-popups']
|
|
// 2026-10-19 (viewer worktree, user request): the SW/Tool Story menu was removed; SW/Popup (the common SWPopup
|
|
// examples) stays. SWToolButton / SWToolGroup stay public; integrated-improvement.browser.mjs opening this id is historical evidence only.
|
|
export const retiredToolIds = ["sw-tool--tool-buttons"]
|
|
// 2026-10-19 (Header home menu merge, user request): the SW/Home Menu sidebar menu was removed; its Stories moved under
|
|
// SW/Header as sw-header--home-menu (sidebar) and sw-header--home-menu-* (verification tag, reachable by URL).
|
|
export const movedHomeMenuIds = Object.fromEntries(["figma-home-on:figma", "capture-default", "capture-active", "capture-outline", "capture-recent", "header-composition", "variants", "dynamic-data", "standalone", "recent-files-panel:recent-files", "property-bar-check", "capture-property-bar", "integration", "capture-responsive"]
|
|
.map(entry => entry.split(":")).map(([from, to = from]) => [`sw-home-menu--${from}`, `sw-header--home-menu-${to}`]))
|
|
// 2026-10-20 (SW Storybook simplification, user request): Figma screenshot comparisons and duplicate Variant pages that
|
|
// no test or document used were removed; the Figma originals stay in docs/sw/figma-additional/screenshots/.
|
|
export const retiredHomeMenuCompareIds = ["figma", "capture-active", "capture-outline", "capture-recent", "variants", "recent-files"].map(id => `sw-header--home-menu-${id}`)
|
|
// 2026-10-20: Property Panel · 4개 비교 moved to SW/Popup in the sidebar; its ID is unchanged (meta id "sw-header").
|
|
export const movedToPopupIds = ["sw-header--property-panel-compare"]
|
|
// 2026-10-20 (Footer Story cleanup, user request): 기본 Footer and the States page were removed. Their screens are sections
|
|
// of sw-footer--full-footer (Figma 기본 구성, 상태); the aux Figma comparison moved to sw-footer--figma-variants.
|
|
export const retiredFooterIds = ["default", "states"].map(id => `sw-footer--${id}`)
|
|
export const integratedChangedFiles = [
|
|
'packages/sw/README.md', 'packages/sw/package.json', 'packages/sw/build.mjs',
|
|
'packages/sw/ai/AI_USAGE.md', 'packages/sw/ai/COMPONENT_CATALOG.md', 'packages/sw/ai/COMPOSITION_PATTERNS.md', 'packages/sw/ai/DESIGN_RULES.md',
|
|
'packages/sw/ai/examples/ExampleE-CustomPopup.tsx', 'packages/sw/ai/examples/ExampleF-ViewerToolbar.tsx',
|
|
'packages/sw/src/index.ts', 'packages/sw/src/theme/sw.css',
|
|
'packages/sw/src/components/sw-popup/SWPopup.tsx', 'packages/sw/src/components/sw-tool/SWTool.tsx',
|
|
'packages/sw/src/components/sw-header/SWHeader.tsx', 'packages/sw/src/components/sw-header/index.ts', 'packages/sw/src/components/sw-header/types.ts',
|
|
...['SWHeaderDocumentTitle', 'SWHeaderDropdown', 'SWHeaderFields', 'SWHeaderLayerMenu', 'SWHeaderLineStyleMenu', 'SWHeaderMore', 'SWHeaderPropertyFields', 'SWHeaderPropertyPanel'].map(name => `packages/sw/src/components/sw-header/components/${name}.tsx`),
|
|
]
|
|
// 2026-10-20 (test alignment): approved SW Story changes after the unused-demo removal that the lists above do not name.
|
|
// Each comes from a user-requested commit merged into main as 553e4df. Regressions accept exactly these changes.
|
|
// approvedMainCommit is the reviewed main merge the regressions treat as the accepted source state. overview.browser.mjs
|
|
// (both modes) and storybook-unused-removal.browser.mjs keep their old baselines (50bf5bd, c8e5fbe) for the Story
|
|
// inventory and declarations, and accept only the changes named in this file. For the source paths they guard (overview:
|
|
// packages/sw/src; unused-removal: also the SW ai/package files, the other packages, Overview, Dropdown CSF, assets and
|
|
// .storybook) they require no difference from this commit (integratedChangedFiles excepted) and report the diff from the
|
|
// old baseline as sinceBaseline only.
|
|
// Update it only after a merge into main whose Story and product source changes were all approved, in the same change
|
|
// that records that merge's approved Story additions, removals, moves and tag changes in the lists of this file.
|
|
// Never move it to make a failing check pass, and never to a commit that carries unreviewed Story or source changes.
|
|
// A new main HEAD alone is no reason to move it: no script or workflow updates it automatically; it changes only in a
|
|
// reviewed test-only commit (docs/sw/sw-test-regression-baseline-2026-10-20.md §9).
|
|
export const approvedMainCommit = '553e4df4a865aaf6514b1c2b86cb2e3e9a658e5f'
|
|
// 170a5c2: the SW/Header sidebar page of the home menu (the moved verification Stories are movedHomeMenuIds).
|
|
export const homeMenuSidebarIds = ['sw-header--home-menu']
|
|
// 6cf8854 SW Footer (current IDs after retiredFooterIds), 7f42923 viewer mode, 41e963a theme inheritance.
|
|
export const footerStoryIds = ['full-footer', 'tool-groups', 'figma-variants', 'custom-content', 'responsive', 'parts'].map(id => `sw-footer--${id}`)
|
|
export const viewerStoryIds = ['viewer-header', 'menu-groups', 'states', 'dropdowns', 'settings-panel', 'content-variants', 'variable-size', 'responsive', 'compare-with-sw-header', 'logo'].map(id => `sw-viewer--${id}`)
|
|
export const themeStoryIds = ['sw-theme--theme-inheritance']
|
|
// 2b0e1a2 sidebar simplification: ID and direct URL kept, hidden from the sidebar by the verification tag.
|
|
export const verificationTaggedIds = ['sw-header--window-move-motion', 'sw-header--k-guide']
|
|
// Every approved SW Story ID added after the unused-demo removal, as the current index lists them.
|
|
export const approvedAddedStoryIds = [...integratedStoryIds.filter(id => !retiredToolIds.includes(id)), ...homeMenuSidebarIds,
|
|
...Object.values(movedHomeMenuIds).filter(id => !retiredHomeMenuCompareIds.includes(id)), ...footerStoryIds, ...viewerStoryIds, ...themeStoryIds]
|
|
// An earlier index entry with the approved tag / Popup move applied (2b0e1a2; the moved Story has no component path).
|
|
export const withApprovedEntryChanges = entry => {
|
|
if (verificationTaggedIds.includes(entry.id)) return { ...entry, tags: [...entry.tags, 'verification'] }
|
|
if (!movedToPopupIds.includes(entry.id)) return entry
|
|
const { componentPath, ...rest } = entry
|
|
return { ...rest, title: 'SW/Popup', importPath: './src/sw/sw-property-panel.stories.tsx' }
|
|
}
|
|
// src/sw/sw-header.stories.tsx declarations changed or added by approved commits (compared with that commit's version)
|
|
// and the Popup move (compared in its new file).
|
|
export const approvedHeaderDeclarations = {
|
|
Overview: '170a5c23aed10f8fc65e5b20e9b94bd3c1ff1227', ResponsiveMore: '170a5c23aed10f8fc65e5b20e9b94bd3c1ff1227', // home menu, measured More
|
|
WindowMoveMotion: '2b0e1a2262002aedb01c29c5d18ffae1219bf3ef', KGuide: '2b0e1a2262002aedb01c29c5d18ffae1219bf3ef', // verification tag
|
|
PropertyPanelComparePage: '2b0e1a2262002aedb01c29c5d18ffae1219bf3ef', // exported for the moved Popup Story
|
|
}
|
|
export const movedHeaderDeclarations = { PropertyPanelCompare: ['src/sw/sw-property-panel.stories.tsx', '2b0e1a2262002aedb01c29c5d18ffae1219bf3ef'] }
|
|
// 2026-10-20 (legacy suite alignment): dropdown-consolidation, storybook-cleanup-stage1, property-panel-comparison and
|
|
// detail-buttons compare an earlier SW/Header inventory or source with today's through the approved changes below.
|
|
// Retired after the Dropdown consolidation and absent today (the Popup move keeps its ID: withApprovedEntryChanges).
|
|
export const laterRetiredHeaderIds = [...retiredPropertyPanelIds, ...retiredUnusedDemoIds]
|
|
// The approved additions that sit under SW/Header.
|
|
export const approvedAddedHeaderIds = approvedAddedStoryIds.filter(id => id.startsWith('sw-header--'))
|
|
// An earlier SW/Header entry list against today's index: `changed` (ID, name, title or tags differ from the earlier entry
|
|
// with the approved changes applied), `unexpected` (SW/Header Stories neither retained nor approved), `missing` (approved
|
|
// additions not under SW/Header) and `retiredPresent` (an approved retirement back in the index).
|
|
export const headerInventoryIssues = (entries, index) => {
|
|
const expected = retainedInventory(entries).filter(entry => !laterRetiredHeaderIds.includes(entry.id)).map(withApprovedEntryChanges)
|
|
const signature = entry => entry && JSON.stringify([entry.id, entry.name, entry.title, entry.tags])
|
|
const current = swStoryEntries(index)
|
|
const issues = {
|
|
actual: current.length, expected: expected.filter(entry => entry.title === 'SW/Header').length + approvedAddedHeaderIds.length,
|
|
changed: expected.filter(entry => signature(entry) !== signature(index.entries[entry.id])).map(entry => entry.id),
|
|
unexpected: current.filter(entry => !expected.some(item => item.id === entry.id) && !approvedAddedHeaderIds.includes(entry.id)).map(entry => entry.id),
|
|
missing: approvedAddedHeaderIds.filter(id => index.entries[id]?.title !== 'SW/Header'),
|
|
retiredPresent: [...retiredStage1Ids, ...retiredDropdownIds, ...laterRetiredHeaderIds].filter(id => index.entries[id]),
|
|
}
|
|
return { ...issues, ok: issues.actual === issues.expected && ['changed', 'unexpected', 'missing', 'retiredPresent'].every(key => issues[key].length === 0) }
|
|
}
|
|
// src/sw/sw-header.stories.tsx top-level declarations (Story exports, helpers, fixtures, types; imports as
|
|
// `import:<source>`) that approved commits changed, added or removed after the stage-1 baseline 92830fe, under the last
|
|
// commit that touched each. Each suite still excludes the declarations of its own change (Dropdown, motion, ComposedDemo, meta).
|
|
export const approvedHeaderSourceChanges = {
|
|
// chore(sw): improve interactive header story preview (Overview itself changed again in 170a5c2)
|
|
'bf16578226fe89e5d9a6ba904b7979bebb602661': ['import:./sw-header-overview'],
|
|
// refactor(storybook): consolidate property panel comparison layout (retiredPropertyPanelIds)
|
|
'c8e5fbeebc26fba92998fc5ddcd28c6c110e452d': ['PropertyCompare', 'PropertyPanelVariants', 'PropertyStateStory', 'PropertyPanelNone', 'PropertyPanelAll', 'PropertyPanelCircle', 'PropertyPanelExpanded'],
|
|
// refactor(storybook): remove unused SW header demo stories (retiredUnusedDemoIds and the demo code only they used)
|
|
'5faa1f1ffe89eb7aeb4aaec81ac5bb2d0f4fced9': ['StyleHostProps', 'StyleHeader', 'FIGMA_LAYERS', 'noop', 'LayerHostProps', 'describeLayers', 'LayerHeader', 'LayerDemo',
|
|
'InputDemo', 'LayerDetailInput', 'PropertyPanelDemo', 'PropertyPanel', 'RequiredColorDemo', 'AdditionalHover', 'PropertyBarDemo', 'PropertyBar', 'CONTROL_FIXTURE',
|
|
'DynamicControlsDemo', 'DynamicControls', 'Colorize', 'HIDEABLE_PARTS', 'MENU_IDS', 'COMPOSITION_PRESETS', 'CompositionDemo', 'Composition', 'SampleShapeViewer',
|
|
'SHAPE_MODES', 'SHAPE_MODE_LABELS', 'ShapeSlotDemo', 'PropertyShapeSlot', 'FIELD_NODES', 'FIELD_FIXTURE', 'FIELD_HOVER', 'FieldPanel', 'PropertyFieldsDemo', 'PropertyFields',
|
|
'import:./assets/figma-reference/btn-detail-layer-26-10767.png', 'import:./assets/figma-reference/input-26-11656.png'],
|
|
// feat(sw): integrate responsive home menu into header
|
|
'170a5c23aed10f8fc65e5b20e9b94bd3c1ff1227': ['import:@hm-design/sw', 'import:./sw-home-menu-fixture', 'OVERVIEW_HOME_MENU', 'Overview', 'MeasuredMoreDemo', 'ResponsiveMore'],
|
|
// refactor(sw): simplify storybook navigation and examples (verification tags, Popup move)
|
|
'2b0e1a2262002aedb01c29c5d18ffae1219bf3ef': ['meta', 'WindowMoveMotion', 'KGuide', 'PropertyPanelCompare', 'PropertyPanelComparePage'],
|
|
}
|
|
const approvedHeaderSourceCommit = Object.fromEntries(Object.entries(approvedHeaderSourceChanges).flatMap(([commit, names]) => names.map(name => [name, commit])))
|
|
// Declarations among `names` that differ between `base` and `current` without an approved change: none listed, or the
|
|
// current text differs from the approving commit's, or that commit did not change it. `at(ref)` returns the declaration
|
|
// map of the file at a Git ref, keyed like `base` and `current`.
|
|
export const headerSourceIssues = (names, base, current, at) => {
|
|
const cache = new Map(), version = ref => { if (!cache.has(ref)) cache.set(ref, at(ref)); return cache.get(ref) }
|
|
return names.filter(name => base[name] !== current[name]).filter(name => {
|
|
const commit = approvedHeaderSourceCommit[name]
|
|
return !commit || current[name] !== version(commit)[name] || version(`${commit}^`)[name] === version(commit)[name]
|
|
})
|
|
}
|