merge(sw): integrate AI reusable component template

Merge feature/sw-ai-template (e27385e) into feature/sw-package (bf16578).
No conflicts; no runtime source, Storybook source or public API change.
Adds the integration record docs/sw/sw-ai-template-integration-2026-10-19.md
and its evidence (Overview 53/53, overlays 19/19, AI consumer 27/27).
The unverified wip/sw-header-composition-unverified branch is not included.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
shkim4andClaude Opus 5.5 committed 2026-10-19 11:33:10 +09:00
commit c165753bbe
31 files changed
+2483 -1

No files matched your search

@@ -0,0 +1,276 @@
{
"checks": [
{
"name": "1 all SVG/PNG assets decode (data URI, no external path)",
"status": "PASS",
"data": {
"count": 33,
"broken": []
}
},
{
"name": "1 styles.css loaded; SWTheme provides tokens",
"status": "PASS",
"data": {
"height": "49px",
"font": "\"Noto Sans KR\", \"Malgun Gothic\", \"Apple SD Gothic Neo\", sans-serif"
}
},
{
"name": "2 A default header 1920 geometry = Figma (49 / 0·80 / 65·310 / 377·1301 / 1680·240)",
"status": "PASS",
"data": {
"header": {
"x": 0,
"y": 0,
"w": 1920,
"h": 49
},
"home": {
"x": 0,
"y": 0,
"w": 80,
"h": 48
},
"document": {
"x": 65,
"y": 0,
"w": 310,
"h": 48
},
"object": {
"x": 377,
"y": 0,
"w": 1301,
"h": 48
},
"window": {
"x": 1680,
"y": 0,
"w": 240,
"h": 48
}
}
},
{
"name": "2 A layer dropdown select callback",
"status": "PASS",
"data": "layer:center"
},
{
"name": "2 A close callback",
"status": "PASS",
"data": "close"
},
{
"name": "3 B order Logo → File → Layer → Color → K (DOM)",
"status": "PASS",
"data": [
"뷰어 홈",
"hm-sw-header__document",
"레이어",
"색상",
"팝업 가이드"
]
},
{
"name": "3 B sizes keep SW rules (bar 49, home 80 overlapping file 15px, fields 234/192 x 38)",
"status": "PASS",
"data": {
"bar": {
"x": 0,
"y": 409,
"w": 1920,
"h": 49
},
"home": {
"x": 0,
"y": 409,
"w": 80,
"h": 48
},
"document": {
"x": 65,
"y": 409,
"w": 310,
"h": 48
},
"layer": {
"x": 382,
"y": 414,
"w": 234,
"h": 38
},
"color": {
"x": 620,
"y": 414,
"w": 192,
"h": 38
}
}
},
{
"name": "3 B document dropdown New callback",
"status": "PASS",
"data": "document:new"
},
{
"name": "3 B layer dropdown opens under the field",
"status": "PASS",
"data": "true"
},
{
"name": "3 B Escape closes and returns focus to the field",
"status": "PASS",
"data": null
},
{
"name": "3 B color chip callback (dropdown stays open)",
"status": "PASS",
"data": "color:red"
},
{
"name": "3 B K guide preview on hover (animation frame advances)",
"status": "PASS",
"data": {
"guide": true
}
},
{
"name": "3 B K click callback",
"status": "PASS",
"data": "popupGuide"
},
{
"name": "4 C order File → 선 → 문자 → 치수 → 인쇄",
"status": "PASS",
"data": [
"file",
"선스타일",
"문자스타일",
"치수스타일",
"인쇄"
]
},
{
"name": "4 C first file well has a left edge (consumer wrapper)",
"status": "PASS",
"data": "1px"
},
{
"name": "4 C line type callback + field value",
"status": "PASS",
"data": "lineType:center"
},
{
"name": "4 C text style callback + field value",
"status": "PASS",
"data": "textStyle:dotum"
},
{
"name": "4 C dimension style callback",
"status": "PASS",
"data": "dimensionStyle:iso"
},
{
"name": "4 C print callback",
"status": "PASS",
"data": "print"
},
{
"name": "5 D new search field matches the SW field surface (height/top/border/radius/background/shadow/label)",
"status": "PASS",
"data": {
"layer": {
"h": 38,
"top": 1232,
"border": "1px rgb(8, 37, 28)",
"radius": "3px",
"bg": "linear-gradient(0deg, rgba(0, 0, 0, 0.45",
"shadow": "rgba(9, 39, 30, 0.7) 0px 1px 4px 0px"
},
"search": {
"h": 38,
"top": 1232,
"border": "1px rgb(8, 37, 28)",
"radius": "3px",
"bg": "linear-gradient(0deg, rgba(0, 0, 0, 0.45",
"shadow": "rgba(9, 39, 30, 0.7) 0px 1px 4px 0px"
},
"label": "12px",
"fieldLabel": "12px"
}
},
{
"name": "5 D hover ring like existing fields (edge turns yellow, inside unchanged)",
"status": "PASS",
"data": {
"ring": "1",
"before": {
"inside": [
18,
50,
39
],
"edge": [
8,
37,
28
]
},
"after": {
"inside": [
18,
50,
39
],
"edge": [
172,
131,
3
]
}
}
},
{
"name": "5 D Enter commits through SWHeaderInput → search callback",
"status": "PASS",
"data": "search:WALL-01"
},
{
"name": "5 D search button callback uses committed value",
"status": "PASS",
"data": "search:WALL-01"
},
{
"name": "5 D Escape restores the committed value",
"status": "PASS",
"data": "WALL-01"
},
{
"name": "5 D existing color dropdown in the same bar",
"status": "PASS",
"data": "color:blue"
},
{
"name": "6 B Tab order = display order",
"status": "PASS",
"data": [
"문서: C0020101-006-평면및종단면도(06)",
"레이어",
"색상",
"팝업 가이드"
]
},
{
"name": "7 no page/console errors",
"status": "PASS",
"data": []
}
],
"errors": [],
"warnings": [
"Canvas2D: Multiple readback operations using getImageData are faster with the willReadFrequently attribute set to true. See: https://html.spec.whatwg.org/multipage/canvas.html#concept-canvas-will-read-frequently",
"Canvas2D: Multiple readback operations using getImageData are faster with the willReadFrequently attribute set to true. See: https://html.spec.whatwg.org/multipage/canvas.html#concept-canvas-will-read-frequently"
]
}
@@ -0,0 +1,104 @@
{
"baseCommit": "50bf5bda8e956a4973b923d64131f2f2285bd38c",
"checks": [
{
"name": "all 28 Story IDs, names, order and tags retained",
"status": "PASS"
},
{
"name": "other 27 Story declarations byte-identical",
"status": "PASS"
},
{
"name": "package production source untouched",
"status": "PASS"
},
{
"name": "document first row is above the property Bar and clickable",
"status": "PASS"
},
{
"name": "existing 레이어 상세 reports Callback",
"status": "PASS"
},
{
"name": "existing 색상 상세 reports Callback",
"status": "PASS"
},
{
"name": "existing 선스타일 상세 reports Callback",
"status": "PASS"
},
{
"name": "existing 문자스타일 상세 reports Callback",
"status": "PASS"
},
{
"name": "existing 치수스타일 상세 reports Callback",
"status": "PASS"
},
{
"name": "ByBlock mode immediately appears in Header without changing numeric RGB property",
"status": "PASS"
},
{
"name": "direct color selection clears Header mode label",
"status": "PASS"
},
{
"name": "small Inner layer dropdown stays in browser width",
"status": "PASS",
"data": {
"x": 141,
"y": 345.0625,
"width": 234,
"height": 250
}
},
{
"name": "small Inner lower layer row hit-test is unobstructed",
"status": "PASS"
},
{
"name": "small Inner layer selection or Escape closes only nested dropdown",
"status": "PASS"
},
{
"name": "small Inner line dropdown stays in browser width",
"status": "PASS",
"data": {
"x": 186,
"y": 39.0625,
"width": 189.1875,
"height": 342
}
},
{
"name": "small Inner line selection or Escape closes only nested dropdown",
"status": "PASS"
},
{
"name": "small Inner color dropdown stays in browser width",
"status": "PASS",
"data": {
"x": 175,
"y": 377.0625,
"width": 192,
"height": 182
}
},
{
"name": "small Inner color selection or Escape closes only nested dropdown",
"status": "PASS"
},
{
"name": "no overlay browser errors",
"status": "PASS",
"data": []
}
],
"errors": [],
"sizes": [],
"browser": "155.0.8059.80",
"status": "PASS"
}
@@ -0,0 +1,670 @@
{
"baseCommit": "50bf5bda8e956a4973b923d64131f2f2285bd38c",
"checks": [
{
"name": "all 28 Story IDs, names, order and tags retained",
"status": "PASS"
},
{
"name": "other 27 Story declarations byte-identical",
"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--composed-controls",
"sw-header--logo-slot",
"sw-header--document-dropdown",
"sw-header--layer-dropdown",
"sw-header--color-dropdown",
"sw-header--line-style-dropdown",
"sw-header--text-dimension-style-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"
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB