@ncds/ui-admin-mcp 1.0.0-alpha.20 → 1.0.0-alpha.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/bin/components.bundle.js +21 -8
- package/bin/definitions/instructions.md +6 -3
- package/bin/definitions/js-api.json +80 -0
- package/bin/definitions/rules.json +8 -4
- package/bin/overrides/composition.json +337 -61
- package/bin/server.js +6 -3
- package/bin/tools/renderToHtml.js +2 -1
- package/bin/types.d.ts +2 -0
- package/bin/utils/tokenValidator.js +33 -3
- package/bin/version.d.ts +1 -1
- package/bin/version.js +1 -1
- package/data/badge-group.json +8 -8
- package/data/badge.json +18 -14
- package/data/bread-crumb.json +1 -0
- package/data/combo-box.json +5 -0
- package/data/dropdown.json +2 -0
- package/data/file-input.json +4 -2
- package/data/horizontal-tab.json +3 -1
- package/data/image-file-input.json +5 -2
- package/data/notification.json +1 -0
- package/data/page-title.json +1 -0
- package/data/progress-bar.json +1 -0
- package/data/range-date-picker-with-buttons.json +3 -2
- package/data/range-date-picker.json +1 -1
- package/data/select-box.json +5 -0
- package/data/select.json +1 -0
- package/data/table.json +4 -2
- package/data/tooltip.json +4 -0
- package/data/vertical-tab.json +3 -1
- package/package.json +2 -2
- package/templates/README.md +1 -1
|
@@ -879,7 +879,7 @@
|
|
|
879
879
|
},
|
|
880
880
|
"table": {
|
|
881
881
|
"_note_required": "P7: ncua-table__required 는 NCDS Table SCSS([_table.scss:619]) 와 VanillaJS classNames 상수([classNames.ts:26])에는 정의되어 있으나 React Table.tsx 본체가 사용하지 않아 자동 추출되지 않음. Vertical Table 의 필수 라벨에 `<span class='ncua-table__required'>*</span>` 형태로 라벨 텍스트 앞에 prepend 하여 사용. validate_html 화이트리스트 통과를 위해 bemClassesExtra 에 명시 등록.",
|
|
882
|
-
"descriptionExtra": "[중요] table 컴포넌트는 두 가지 모드 지원: (1) type=horizontal — 데이터 그리드(thead+tbody, 컬럼별 헤더). (2) type=vertical — 폼 레이아웃(tbody only, 좌측 라벨-우측 값 2-cell row). 폼의 라벨-입력 쌍 구성 시 vertical 모드 사용 — 절대 BEM 수동 작성 금지. canonicalExamples 의 'vertical-form-label' / 'vertical-form-label-with-required' 시나리오 참고. ⚠️ <th class='ncua-table__header-cell'> 은 horizontal 컬럼 헤더 전용 — vertical 라벨에는 <th scope='row' class='ncua-table__cell'> 사용 (Table.Cell with isHeader=true).",
|
|
882
|
+
"descriptionExtra": "[중요] table 컴포넌트는 두 가지 모드 지원: (1) type=horizontal — 데이터 그리드(thead+tbody, 컬럼별 헤더). (2) type=vertical — 폼 레이아웃(tbody only, 좌측 라벨-우측 값 2-cell row). 폼의 라벨-입력 쌍 구성 시 vertical 모드 사용 — 절대 BEM 수동 작성 금지. canonicalExamples 의 'vertical-form-label' / 'vertical-form-label-with-required' 시나리오 참고. ⚠️ <th class='ncua-table__header-cell'> 은 horizontal 컬럼 헤더 전용 — vertical 라벨에는 <th scope='row' class='ncua-table__cell'> 사용 (Table.Cell with isHeader=true). ⚠️ 테이블 스크롤(가로/세로)은 반드시 Table 컴포넌트의 내장 props 로만 처리 — 커스텀 scroll wrapper(예: pbp-table-scroll, page-table__scroll, sgr-table-scroll 등 프로젝트 prefix div) 절대 생성 금지. 올바른 스크롤 설정: horizontalScroll=true(가로 스크롤 활성화 → ncua-table__h-scroll-container 구조 자동 생성), fixedHeader=true(헤더 고정 → ncua-table--fixed-header), maxHeight=340(세로 스크롤 최대 높이 → ncua-table__scroll-container max-height), minWidth=1140(전체 테이블 최소 너비 → --ncua-table-min-width CSS 변수 자동 주입). Table.ColGroup의 widths/minWidths 배열로 각 컬럼 너비 지정. canonicalExamples 의 'horizontal-with-scroll' 시나리오 참고. ⚠️ ncua-table 외곽 wrapper div에 border·overflow:hidden 절대 적용 금지 — (1) border: ncua-table이 자체 border: 1px solid var(--gray-100)를 보유하므로 외부에 border를 추가하면 2px 이중 테두리가 된다. (2) overflow:hidden: 테이블 셀 안의 SelectBox·DatePicker·Tooltip 등 드롭다운이 컨테이너 경계에서 잘린다. 테이블을 감싸는 div가 필요한 경우 아무 CSS 없이 빈 wrapper만 사용할 것.",
|
|
883
883
|
"aliasesExtra": [
|
|
884
884
|
"vertical-table",
|
|
885
885
|
"form-table",
|
|
@@ -898,9 +898,15 @@
|
|
|
898
898
|
"bemClassesExtra": [
|
|
899
899
|
"ncua-table--in-data-grid",
|
|
900
900
|
"ncua-table__required",
|
|
901
|
-
"ncua-
|
|
902
|
-
"ncua-
|
|
903
|
-
"ncua-
|
|
901
|
+
"ncua-table--fixed-header",
|
|
902
|
+
"ncua-table__h-scroll-container",
|
|
903
|
+
"ncua-table__h-scroll-inner",
|
|
904
|
+
"ncua-table__scroll-area",
|
|
905
|
+
"ncua-table__scroll-container",
|
|
906
|
+
"ncua-table__h-scrollbar",
|
|
907
|
+
"ncua-table__h-scrollbar-thumb",
|
|
908
|
+
"ncua-table__scrollbar",
|
|
909
|
+
"ncua-table__scrollbar-thumb"
|
|
904
910
|
],
|
|
905
911
|
"allowedChildren": {
|
|
906
912
|
"Table": ["Table.Header", "Table.Body", "Table.Footer", "Table.ColGroup", "Table.Empty"],
|
|
@@ -960,30 +966,38 @@
|
|
|
960
966
|
},
|
|
961
967
|
"canonicalExamples": {
|
|
962
968
|
"_note": "P6: NCDS Table 은 같은 <th> 태그를 두 컨텍스트로 사용한다. Horizontal=컬럼 헤더(Table.HeaderCell→ncua-table__header-cell), Vertical=행 라벨(Table.Cell with isHeader=true→<th scope='row' class='ncua-table__cell'>). 두 시나리오를 분리 등록하여 AI 가 정확히 분기 학습하도록 한다. 절대 vertical 에 Table.HeaderCell 을 사용하지 말 것.",
|
|
963
|
-
"horizontal-with-
|
|
964
|
-
"description": "
|
|
969
|
+
"horizontal-with-scroll": {
|
|
970
|
+
"description": "컬럼 수가 많아 가로 스크롤이 필요하거나 행 수가 많아 세로 스크롤이 필요한 경우 — Table 컴포넌트의 내장 props 사용. horizontalScroll=true → ncua-table__h-scroll-container 구조 자동 생성(커스텀 wrapper 불필요). fixedHeader=true → 헤더 고정(ncua-table--fixed-header). maxHeight → 세로 스크롤 높이 제한. minWidth → 전체 테이블 최소 너비(--ncua-table-min-width CSS 변수). Table.ColGroup widths/minWidths 배열로 각 컬럼 너비 명시. ⚠️ pbp-table-scroll / page-table__scroll 같은 커스텀 CSS wrapper 절대 생성 금지 — NCDS가 모든 scroll DOM을 자동 생성한다.",
|
|
965
971
|
"props": {
|
|
966
972
|
"type": "horizontal",
|
|
973
|
+
"horizontalScroll": true,
|
|
974
|
+
"fixedHeader": true,
|
|
967
975
|
"hoverable": true,
|
|
976
|
+
"maxHeight": 340,
|
|
977
|
+
"minWidth": 1140,
|
|
968
978
|
"children": [
|
|
979
|
+
{
|
|
980
|
+
"component": "table.col-group",
|
|
981
|
+
"props": {
|
|
982
|
+
"widths": [80, 160, 80, 80, 64, 80, 80, 80, 80],
|
|
983
|
+
"minWidths": [80, 160, 80, 80, 64, 80, 80, 80, 80]
|
|
984
|
+
}
|
|
985
|
+
},
|
|
969
986
|
{
|
|
970
987
|
"component": "table.header",
|
|
971
988
|
"children": [
|
|
972
989
|
{
|
|
973
990
|
"component": "table.row",
|
|
974
991
|
"children": [
|
|
975
|
-
{
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
},
|
|
979
|
-
{
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
},
|
|
983
|
-
{
|
|
984
|
-
"component": "table.header-cell",
|
|
985
|
-
"children": ["컬럼 3"]
|
|
986
|
-
}
|
|
992
|
+
{ "component": "table.header-cell", "children": ["ID"] },
|
|
993
|
+
{ "component": "table.header-cell", "children": ["상품명"] },
|
|
994
|
+
{ "component": "table.header-cell", "children": ["카테고리"] },
|
|
995
|
+
{ "component": "table.header-cell", "children": ["가격"] },
|
|
996
|
+
{ "component": "table.header-cell", "children": ["상태"] },
|
|
997
|
+
{ "component": "table.header-cell", "children": ["재고"] },
|
|
998
|
+
{ "component": "table.header-cell", "children": ["등록일"] },
|
|
999
|
+
{ "component": "table.header-cell", "children": ["담당자"] },
|
|
1000
|
+
{ "component": "table.header-cell", "children": ["메모"] }
|
|
987
1001
|
]
|
|
988
1002
|
}
|
|
989
1003
|
]
|
|
@@ -1049,7 +1063,7 @@
|
|
|
1049
1063
|
}
|
|
1050
1064
|
},
|
|
1051
1065
|
"vertical-form-label-with-required": {
|
|
1052
|
-
"description": "P7/P12: Vertical Table 필수 라벨 표기 표준.
|
|
1066
|
+
"description": "P7/P12: Vertical Table 필수 라벨 표기 표준. ncua-table__required 는 라벨 텍스트 앞에 `<span class='ncua-table__required'>*</span>` 형태로 prepend. 라벨 셀(Table.Cell with isHeader=true) 의 children 첫 자식이 raw markup string, 두 번째가 라벨 텍스트. ⚠️ component descriptor 트리로 페이지 prefix wrapper(예: page-vlabel) + raw span 을 한 번에 표현 불가 → render_to_html 출력 후 페이지 코드에서 추가하거나, 본 시나리오처럼 markup 을 children string 으로 전달. P16: 안내 Tooltip 이 필요하면 'vertical-form-label-with-tooltip' 시나리오 사용 — Table.Cell 은 tooltip prop 을 받지 않으며 라벨 셀의 children 에 합성한다.",
|
|
1053
1067
|
"props": {
|
|
1054
1068
|
"type": "vertical",
|
|
1055
1069
|
"children": [
|
|
@@ -1112,7 +1126,7 @@
|
|
|
1112
1126
|
}
|
|
1113
1127
|
},
|
|
1114
1128
|
"vertical-form-label-with-tooltip": {
|
|
1115
|
-
"description": "P16/P23: Vertical Table 라벨 + 안내 Tooltip
|
|
1129
|
+
"description": "P16/P23: Vertical Table 라벨 + 안내 Tooltip 표준 합성 패턴. Table.Cell 의 children 에 div wrapper 한 단계를 두고 그 안에 [필수 마크 span(필요 시), 라벨 텍스트, Tooltip 컴포넌트] 순으로 합성한다. NCDS Table SCSS 의 vertical 모드 룰이 Tooltip 앵커 span 을 자식으로 가진 div(셀렉터: `th:first-child > div:has(> .ncua-tooltip)`)에 한해 inline-flex 정렬을 자동 적용하므로 라벨과 합성 자식이 같은 선상에 배치된다. Tooltip 앵커 박스와 CDN JS 마운트 후 자동 생성되는 icon wrapper span(`.ncua-tooltip__icon`) 모두 SVG 크기(14px)로 수축되어 React 출력과 CDN HTML 출력 양쪽에서 동일한 박스 메트릭으로 정렬된다. spacing 은 자식별 margin 으로 관리(Required: margin-right 4px, Tooltip: margin-left 4px) — wrapper 에 flex gap 미사용. ⚠️ 사용 금지: (a) Table.Cell 에 tooltip prop 전달(시그니처에 없음). (b) ncua-table__cell--with-tooltip 모디파이어(NCDS 미정의). (c) ncua-table__cell-inner / ncua-table__cell-label 자동 wrapper(생성 안 됨). (d) 페이지 prefix wrapper(page-vlabel, sgr-tooltip-wrapper 등) 외부 배치 — 정렬 어긋남 + hallucination 주원인. ⚠️ 출력 BEM 표준은 라벨 셀이 모디파이어 없는 `<th scope='row' class='ncua-table__cell'><div>...<span class='ncua-tooltip ...'>...</span></div></th>` — th 에 추가 클래스 없음, div wrapper 가 정렬 책임. ⚠️ CDN HTML 모드의 tooltip 영역은 정적 placeholder + script — CDN JS 마운트 후 anchor span 에 `<div data-tooltip-seq data-tooltip-initialized>` wrapper + `<span class='ncua-tooltip__icon'>` SVG wrapper + inline style 자동 부착. 정적 출력을 그대로 페이지 코드로 작성하지 말고 render_to_html 출력 + CDN 스크립트 마운트 흐름을 따를 것. Tooltip 의 props 는 render_to_html 의 tooltip 컴포넌트 spec 그대로 사용(type 'short'|'long', tooltipType 'black'|'white', title, content, position 등).",
|
|
1116
1130
|
"props": {
|
|
1117
1131
|
"type": "vertical",
|
|
1118
1132
|
"children": [
|
|
@@ -1121,19 +1135,16 @@
|
|
|
1121
1135
|
"children": [
|
|
1122
1136
|
{
|
|
1123
1137
|
"component": "table.row",
|
|
1124
|
-
"_note": "필수 + 안내 tooltip 라벨. children
|
|
1138
|
+
"_note": "필수 + 안내 tooltip 라벨. Table.Cell 의 children 트리는 div wrapper 한 단계 안에 [필수 마크 span raw markup, 라벨 텍스트, Tooltip 컴포넌트] 순으로 합성. tree 표현 한계로 div 와 Tooltip 자식을 한 markup string 으로 묶고 anchor 만 placeholder 로 표시 — render_to_html 출력이 사용 환경에 맞춰 실제 Tooltip 마크업으로 채운다.",
|
|
1125
1139
|
"children": [
|
|
1126
1140
|
{
|
|
1127
1141
|
"component": "table.cell",
|
|
1128
1142
|
"props": {
|
|
1129
|
-
"isHeader": true
|
|
1130
|
-
"tooltip": {
|
|
1131
|
-
"type": "short",
|
|
1132
|
-
"tooltipType": "black",
|
|
1133
|
-
"content": "외부에 노출되는 상품명입니다. 50자 이내로 입력하세요."
|
|
1134
|
-
}
|
|
1143
|
+
"isHeader": true
|
|
1135
1144
|
},
|
|
1136
|
-
"children": [
|
|
1145
|
+
"children": [
|
|
1146
|
+
"<div><span class=\"ncua-table__required\">*</span>상품명<span class=\"ncua-tooltip ncua-tooltip--sm ncua-tooltip--short ncua-tooltip--stroke\"></span></div>"
|
|
1147
|
+
]
|
|
1137
1148
|
},
|
|
1138
1149
|
{
|
|
1139
1150
|
"component": "table.cell",
|
|
@@ -1143,20 +1154,16 @@
|
|
|
1143
1154
|
},
|
|
1144
1155
|
{
|
|
1145
1156
|
"component": "table.row",
|
|
1146
|
-
"_note": "비필수 + 안내 tooltip.
|
|
1157
|
+
"_note": "비필수 + 안내 tooltip. 필수 마크 span 없이 div wrapper 안에 [라벨 텍스트, Tooltip 컴포넌트] 합성. children 트리는 위 row 와 동일 구조에서 Required span 만 빠진 형태.",
|
|
1147
1158
|
"children": [
|
|
1148
1159
|
{
|
|
1149
1160
|
"component": "table.cell",
|
|
1150
1161
|
"props": {
|
|
1151
|
-
"isHeader": true
|
|
1152
|
-
"tooltip": {
|
|
1153
|
-
"type": "long",
|
|
1154
|
-
"tooltipType": "white",
|
|
1155
|
-
"title": "카테고리 안내",
|
|
1156
|
-
"content": "상품을 분류하는 최상위 카테고리입니다. 변경 시 검색·노출 영역에 영향."
|
|
1157
|
-
}
|
|
1162
|
+
"isHeader": true
|
|
1158
1163
|
},
|
|
1159
|
-
"children": [
|
|
1164
|
+
"children": [
|
|
1165
|
+
"<div>카테고리<span class=\"ncua-tooltip ncua-tooltip--sm ncua-tooltip--long ncua-tooltip--stroke\"></span></div>"
|
|
1166
|
+
]
|
|
1160
1167
|
},
|
|
1161
1168
|
{
|
|
1162
1169
|
"component": "table.cell",
|
|
@@ -1446,7 +1453,7 @@
|
|
|
1446
1453
|
},
|
|
1447
1454
|
"block-container": {
|
|
1448
1455
|
"_note": "P10: BlockContainer 는 페이지 블록의 외곽 컨테이너. children 으로 block-header + 본문 컴포넌트(table/data-grid/자유영역) 조합. AI 가 sgr-block / sgr-block-container 로 우회하지 않도록 다중 시나리오 등록.",
|
|
1449
|
-
"descriptionExtra": "[중요] 페이지 블록 외곽 컨테이너. 표준 자식 구조: BlockHeader + BlockContainer.Body(필수 wrapping — P14 룰). 본문은 Body 안에 table/data-grid/form 컴포넌트 배치. 직접 <section class='ncua-block-container'> 마크업 금지 — overflow:hidden / border-radius 등 CDN CSS 보호 받지 못함. 페이지 prefix wrapper
|
|
1456
|
+
"descriptionExtra": "[중요] 페이지 블록 외곽 컨테이너. 표준 자식 구조: BlockHeader + BlockContainer.Body(필수 wrapping — P14 룰). 본문은 Body 안에 table/data-grid/form 컴포넌트 배치. 직접 <section class='ncua-block-container'> 마크업 금지 — overflow:hidden / border-radius 등 CDN CSS 보호 받지 못함. ⚠️ 페이지에 필요한 모든 '섹션/박스/블록/패널' 영역은 block-container로 구현한다 — 페이지 고유 prefix를 붙인 커스텀 wrapper({page}-block / {page}-section / {page}-panel 등 어떤 이름이든)를 따로 만들지 말 것. 접을 수 있는(collapsible) 블록도 동일하게 block-container 사용.",
|
|
1450
1457
|
"aliasesExtra": [
|
|
1451
1458
|
"블록 컨테이너",
|
|
1452
1459
|
"블록",
|
|
@@ -1465,7 +1472,11 @@
|
|
|
1465
1472
|
"흰 박스",
|
|
1466
1473
|
"정보 블록",
|
|
1467
1474
|
"폼 블록",
|
|
1468
|
-
"데이터 블록"
|
|
1475
|
+
"데이터 블록",
|
|
1476
|
+
"collapsible block",
|
|
1477
|
+
"접을 수 있는 블록",
|
|
1478
|
+
"지표 블록",
|
|
1479
|
+
"kpi 블록"
|
|
1469
1480
|
],
|
|
1470
1481
|
"bemClassesExtra": [],
|
|
1471
1482
|
"allowedChildren": {
|
|
@@ -1827,7 +1838,7 @@
|
|
|
1827
1838
|
},
|
|
1828
1839
|
"page-title": {
|
|
1829
1840
|
"_note": "P7: PageTitle 은 props 기반 (subComponents 없음). breadcrumbItems / title / primaryAction / secondaryAction / guideButton / onBack / variant prop 으로 구성. AI 가 sgr-page-title 같은 페이지-prefix 로 우회하지 않도록 명시적 canonicalExamples 등록. 출력은 ncua-page-title__page-header / __title-container / __title-row / __title / __action-area 등 정밀 BEM.",
|
|
1830
|
-
"descriptionExtra": "[중요] 페이지 최상단 타이틀 영역 표준. breadcrumbItems + title + primaryAction(우측 강조 버튼) + secondaryAction(취소/목록) + guideButton + onBack + variant(default/detail/fixed). detail variant 는 onBack 으로 좌측 back button 노출. fixed variant 는 스크롤 시 상단 고정. 페이지 prefix(sgr-page-title / page-header) 우회 금지.",
|
|
1841
|
+
"descriptionExtra": "[중요] 페이지 최상단 타이틀 영역 표준. breadcrumbItems + title + primaryAction(우측 강조 버튼) + secondaryAction(취소/목록) + guideButton + onBack + variant(default/detail/fixed). detail variant 는 onBack 으로 좌측 back button 노출. fixed variant 는 스크롤 시 상단 고정. 페이지 prefix(sgr-page-title / page-header) 우회 금지. ⚠️ ReactNode props(guideButton / primaryAction / secondaryAction)는 반드시 {component: 'button', props: {...}} 형태로 전달 — {label:..., size:..., hierarchy:...} raw 객체를 직접 넘기면 React child 오류로 렌더링 전체 실패(breadcrumb 포함). canonicalExamples 의 구조를 반드시 따를 것.",
|
|
1831
1842
|
"aliasesExtra": [
|
|
1832
1843
|
"페이지 타이틀",
|
|
1833
1844
|
"페이지 제목",
|
|
@@ -1938,14 +1949,20 @@
|
|
|
1938
1949
|
"title": "상품 상세",
|
|
1939
1950
|
"onBack": "noop",
|
|
1940
1951
|
"secondaryAction": {
|
|
1941
|
-
"
|
|
1942
|
-
"
|
|
1943
|
-
|
|
1952
|
+
"component": "button",
|
|
1953
|
+
"props": {
|
|
1954
|
+
"label": "삭제",
|
|
1955
|
+
"size": "md",
|
|
1956
|
+
"hierarchy": "destructive-secondary"
|
|
1957
|
+
}
|
|
1944
1958
|
},
|
|
1945
1959
|
"primaryAction": {
|
|
1946
|
-
"
|
|
1947
|
-
"
|
|
1948
|
-
|
|
1960
|
+
"component": "button",
|
|
1961
|
+
"props": {
|
|
1962
|
+
"label": "수정",
|
|
1963
|
+
"size": "md",
|
|
1964
|
+
"hierarchy": "primary"
|
|
1965
|
+
}
|
|
1949
1966
|
}
|
|
1950
1967
|
}
|
|
1951
1968
|
},
|
|
@@ -2414,21 +2431,7 @@
|
|
|
2414
2431
|
"notification": {
|
|
2415
2432
|
"_note": "P20/P22: Notification 은 비차단 알림 컴포넌트. type ∈ {floating, full-width, message} × color ∈ {neutral, error, warning, success, info} 매트릭스 (단, floating 은 info 색상 미지원). props 기반 — subComponents 없음. ⚠️⚠️ BEM prefix 는 type 별로 분리: type='floating' → `ncua-floating-notification__*`, type='full-width' → `ncua-full-width-notification__*`, type='message' → `ncua-message-notification__*`. **generic 한 `ncua-notification__*` prefix 는 존재하지 않음** — godomall5 페이지에서 발견된 가짜 BEM. floating 은 페이지 우측 영역 자동 노출(autoClose 지원), full-width 는 화면 상단 가로 배너, message 는 인라인 메시지 박스. onHidePermanently 는 message / full-width 에서만 동작. React 컴포넌트 + CDN CSS 완비 — 반드시 render_to_html('notification', {...}) 호출해 정확한 type-prefix BEM 출력을 받아 그대로 사용.",
|
|
2416
2433
|
"descriptionExtra": "[중요] 비차단 알림 컴포넌트. type 으로 표현 형태(floating/full-width/message) 결정, color 로 상태(neutral/error/warning/success/info) 결정. ⚠️ BEM prefix 가 type 별로 다름: floating→ncua-floating-notification__*, full-width→ncua-full-width-notification__*, message→ncua-message-notification__*. generic ncua-notification__* prefix 는 존재하지 않으니 절대 직접 작성 금지 — render_to_html 출력 그대로 사용. type='floating' 은 color='info' 미지원. autoClose 는 floating 전용 (밀리초). onHidePermanently 는 message / full-width 전용. 페이지 prefix wrapper(toast-wrapper, alert-banner 등) 우회 금지.",
|
|
2417
|
-
"bemClassesExtra": [
|
|
2418
|
-
"ncua-floating-notification",
|
|
2419
|
-
"ncua-floating-notification__container",
|
|
2420
|
-
"ncua-floating-notification__content",
|
|
2421
|
-
"ncua-floating-notification__title",
|
|
2422
|
-
"ncua-floating-notification__icon",
|
|
2423
|
-
"ncua-full-width-notification",
|
|
2424
|
-
"ncua-full-width-notification__container",
|
|
2425
|
-
"ncua-full-width-notification__content",
|
|
2426
|
-
"ncua-full-width-notification__title",
|
|
2427
|
-
"ncua-message-notification",
|
|
2428
|
-
"ncua-message-notification__container",
|
|
2429
|
-
"ncua-message-notification__content",
|
|
2430
|
-
"ncua-message-notification__title"
|
|
2431
|
-
],
|
|
2434
|
+
"bemClassesExtra": ["ncua-floating-notification__icon"],
|
|
2432
2435
|
"aliasesExtra": [
|
|
2433
2436
|
"알림",
|
|
2434
2437
|
"알림창",
|
|
@@ -2496,5 +2499,278 @@
|
|
|
2496
2499
|
}
|
|
2497
2500
|
}
|
|
2498
2501
|
}
|
|
2502
|
+
},
|
|
2503
|
+
"date-picker": {
|
|
2504
|
+
"descriptionExtra": "[중요] 단일 날짜 또는 날짜+시간 입력에 사용하는 DatePicker. CDN에서는 window.ncua.DatePicker 단일 클래스로 동작한다. datePickerOptions 배열에 1개를 전달하면 single 모드, 2개를 전달하면 range 모드가 된다. ⚠️ datePickerOptions 각 요소의 options.static:true 절대 생략 금지 — 누락 시 flatpickr-wrapper div 가 생성되지 않아 flatpickr-calendar 가 input 필드 밖으로 밀려나 레이아웃이 파괴된다. options 객체는 canonicalExample 을 그대로 복사할 것: { mode:'single', static:true, dateFormat:'Y-m-d', clickOpens:true, allowInvalidPreload:true, locale:'ko' }. ⚠️ .ncua-date-picker__input 에 border·shadow·padding 을 직접 적용하는 커스텀 CSS 절대 금지 — 이 스타일들은 CDN CSS 가 .flatpickr-wrapper 에 자동 적용하며, __input 에 덮어쓰면 JS 초기화 후 이중 border 등 시각적 충돌이 발생한다. DatePicker 컨테이너는 JS 초기화 전 빈 div 이며, JS 가 .flatpickr-wrapper → .ncua-date-picker__input 구조를 동적으로 생성한다. width 조정이 필요하다면 컨테이너 div 에만 적용할 것(xs 기준 138px 은 CDN CSS 기본값). ⚠️ rangeMode 클래스는 range-date-picker(기간 범위) 전용 — 단일 DatePicker 의 flatpickr-calendar 에 rangeMode 를 참조하거나 추가 금지. JS 초기화 후 올바른 DOM 구조: .flatpickr-wrapper(input + flatpickr-calendar 래핑) 이후 .ncua-date-picker__ico label 이 flatpickr-wrapper 밖에 위치한다. ⚠️ 캘린더 아이콘 SVG 직접 작성 절대 금지 — ncua-date-picker__ico label 안의 SVG 는 컴포넌트가 stroke='currentColor' 로 자동 렌더링하며, stroke='black' 등 하드코딩하면 다크 테마/CDN 스타일 충돌 발생.",
|
|
2505
|
+
"aliasesExtra": [
|
|
2506
|
+
"날짜 선택",
|
|
2507
|
+
"단일 날짜",
|
|
2508
|
+
"date input",
|
|
2509
|
+
"flatpickr",
|
|
2510
|
+
"날짜 입력",
|
|
2511
|
+
"datepicker",
|
|
2512
|
+
"date picker",
|
|
2513
|
+
"single date",
|
|
2514
|
+
"날짜+시간",
|
|
2515
|
+
"time picker"
|
|
2516
|
+
],
|
|
2517
|
+
"bemClassesExtra": [],
|
|
2518
|
+
"notApplicableAreas": ["allowedChildren", "bemClassesExtra"],
|
|
2519
|
+
"canonicalExamples": {
|
|
2520
|
+
"single": {
|
|
2521
|
+
"description": "단일 날짜 선택 (기본)",
|
|
2522
|
+
"props": {
|
|
2523
|
+
"size": "xs",
|
|
2524
|
+
"datePickerOptions": [
|
|
2525
|
+
{
|
|
2526
|
+
"element": "date-input",
|
|
2527
|
+
"placeholder": "날짜 선택",
|
|
2528
|
+
"options": {
|
|
2529
|
+
"mode": "single",
|
|
2530
|
+
"static": true,
|
|
2531
|
+
"dateFormat": "Y-m-d",
|
|
2532
|
+
"clickOpens": true,
|
|
2533
|
+
"allowInvalidPreload": true,
|
|
2534
|
+
"locale": "ko"
|
|
2535
|
+
}
|
|
2536
|
+
}
|
|
2537
|
+
]
|
|
2538
|
+
}
|
|
2539
|
+
},
|
|
2540
|
+
"with-time": {
|
|
2541
|
+
"description": "날짜+시간 선택",
|
|
2542
|
+
"props": {
|
|
2543
|
+
"size": "xs",
|
|
2544
|
+
"datePickerOptions": [
|
|
2545
|
+
{
|
|
2546
|
+
"element": "datetime-input",
|
|
2547
|
+
"placeholder": "날짜·시간 선택",
|
|
2548
|
+
"options": {
|
|
2549
|
+
"mode": "single",
|
|
2550
|
+
"static": true,
|
|
2551
|
+
"dateFormat": "Y-m-d H:i",
|
|
2552
|
+
"enableTime": true,
|
|
2553
|
+
"clickOpens": true,
|
|
2554
|
+
"allowInvalidPreload": true,
|
|
2555
|
+
"locale": "ko"
|
|
2556
|
+
}
|
|
2557
|
+
}
|
|
2558
|
+
]
|
|
2559
|
+
}
|
|
2560
|
+
}
|
|
2561
|
+
}
|
|
2562
|
+
},
|
|
2563
|
+
"range-date-picker": {
|
|
2564
|
+
"descriptionExtra": "[중요] 시작일·종료일 기간 범위 선택. CDN에서는 window.ncua.DatePicker 에 datePickerOptions 2개를 전달해 range 모드로 동작한다. 빠른 기간 버튼이 필요하면 range-date-picker-with-buttons 를 사용한다. ⚠️ datePickerOptions 각 요소의 options.static:true 절대 생략 금지 — 누락 시 flatpickr-wrapper div 가 생성되지 않아 flatpickr-calendar 가 input 필드 밖으로 밀려나 레이아웃이 파괴된다. options 객체는 canonicalExample 을 그대로 복사할 것: { mode:'range', static:true, dateFormat:'Y-m-d', clickOpens:true, allowInvalidPreload:true, locale:'ko' }. ⚠️ .ncua-date-picker__input 에 border·shadow·padding 을 직접 적용하는 커스텀 CSS 절대 금지 — CDN CSS 가 .flatpickr-wrapper 에 자동 적용하며 __input 에 덮어쓰면 이중 border 충돌 발생. flatpickr 가 range 모드 캘린더에 rangeMode 클래스를 자동 부가 — 직접 작성 불필요. ⚠️ 캘린더 아이콘 SVG 직접 작성 절대 금지 — stroke='black' 등 하드코딩 금지, 컴포넌트가 stroke='currentColor' 로 자동 처리한다.",
|
|
2565
|
+
"aliasesExtra": [
|
|
2566
|
+
"기간 선택",
|
|
2567
|
+
"시작일 종료일",
|
|
2568
|
+
"날짜 범위",
|
|
2569
|
+
"range date",
|
|
2570
|
+
"date range",
|
|
2571
|
+
"start end date",
|
|
2572
|
+
"기간 입력",
|
|
2573
|
+
"범위 날짜"
|
|
2574
|
+
],
|
|
2575
|
+
"bemClassesExtra": [],
|
|
2576
|
+
"notApplicableAreas": ["allowedChildren", "bemClassesExtra"],
|
|
2577
|
+
"canonicalExamples": {
|
|
2578
|
+
"range": {
|
|
2579
|
+
"description": "시작일~종료일 기간 범위 선택 (xs 사이즈, 기본)",
|
|
2580
|
+
"props": {
|
|
2581
|
+
"size": "xs",
|
|
2582
|
+
"datePickerOptions": [
|
|
2583
|
+
{
|
|
2584
|
+
"element": "start-date",
|
|
2585
|
+
"placeholder": "시작일",
|
|
2586
|
+
"options": {
|
|
2587
|
+
"mode": "range",
|
|
2588
|
+
"static": true,
|
|
2589
|
+
"dateFormat": "Y-m-d",
|
|
2590
|
+
"clickOpens": true,
|
|
2591
|
+
"allowInvalidPreload": true,
|
|
2592
|
+
"locale": "ko"
|
|
2593
|
+
}
|
|
2594
|
+
},
|
|
2595
|
+
{
|
|
2596
|
+
"element": "end-date",
|
|
2597
|
+
"placeholder": "종료일",
|
|
2598
|
+
"options": {
|
|
2599
|
+
"mode": "range",
|
|
2600
|
+
"static": true,
|
|
2601
|
+
"dateFormat": "Y-m-d",
|
|
2602
|
+
"clickOpens": true,
|
|
2603
|
+
"allowInvalidPreload": true,
|
|
2604
|
+
"locale": "ko"
|
|
2605
|
+
}
|
|
2606
|
+
}
|
|
2607
|
+
]
|
|
2608
|
+
}
|
|
2609
|
+
},
|
|
2610
|
+
"range-sm": {
|
|
2611
|
+
"description": "시작일~종료일 기간 범위 선택 (sm 사이즈)",
|
|
2612
|
+
"props": {
|
|
2613
|
+
"size": "sm",
|
|
2614
|
+
"datePickerOptions": [
|
|
2615
|
+
{
|
|
2616
|
+
"element": "start-date",
|
|
2617
|
+
"placeholder": "시작일",
|
|
2618
|
+
"options": {
|
|
2619
|
+
"mode": "range",
|
|
2620
|
+
"static": true,
|
|
2621
|
+
"dateFormat": "Y-m-d",
|
|
2622
|
+
"clickOpens": true,
|
|
2623
|
+
"allowInvalidPreload": true,
|
|
2624
|
+
"locale": "ko"
|
|
2625
|
+
}
|
|
2626
|
+
},
|
|
2627
|
+
{
|
|
2628
|
+
"element": "end-date",
|
|
2629
|
+
"placeholder": "종료일",
|
|
2630
|
+
"options": {
|
|
2631
|
+
"mode": "range",
|
|
2632
|
+
"static": true,
|
|
2633
|
+
"dateFormat": "Y-m-d",
|
|
2634
|
+
"clickOpens": true,
|
|
2635
|
+
"allowInvalidPreload": true,
|
|
2636
|
+
"locale": "ko"
|
|
2637
|
+
}
|
|
2638
|
+
}
|
|
2639
|
+
]
|
|
2640
|
+
}
|
|
2641
|
+
}
|
|
2642
|
+
}
|
|
2643
|
+
},
|
|
2644
|
+
"range-date-picker-with-buttons": {
|
|
2645
|
+
"descriptionExtra": "[중요] 시작일·종료일 기간 범위 선택 + 빠른 기간 버튼 내장. CDN에서는 window.ncua.DatePicker 에 datePickerOptions 2개 + buttons 배열을 전달한다. buttons의 권장 세트: 오늘/7일/15일/1개월/3개월/1년. ENTIRE(전체) 및 1주일(unit='weeks') 은 CDN 미지원이므로 제외한다. ⚠️ datePickerOptions 각 요소의 options.static:true 절대 생략 금지 — 누락 시 flatpickr-wrapper div 가 생성되지 않아 flatpickr-calendar 가 input 필드 밖으로 밀려나 레이아웃이 파괴된다. options 객체는 canonicalExample 을 그대로 복사할 것: { mode:'range', static:true, dateFormat:'Y-m-d', clickOpens:true, allowInvalidPreload:true, locale:'ko' }. ⚠️ .ncua-date-picker__input 에 border·shadow·padding 을 직접 적용하는 커스텀 CSS 절대 금지 — CDN CSS 가 .flatpickr-wrapper 에 자동 적용하며 __input 에 덮어쓰면 이중 border 충돌 발생. flatpickr 가 range 모드 캘린더에 rangeMode 클래스를 자동 부가 — 직접 작성 불필요. ⚠️ 캘린더 아이콘 SVG 직접 작성 절대 금지 — stroke='black' 등 하드코딩 금지, 컴포넌트가 stroke='currentColor' 로 자동 처리한다.",
|
|
2646
|
+
"aliasesExtra": [
|
|
2647
|
+
"기간 선택 버튼",
|
|
2648
|
+
"빠른 기간",
|
|
2649
|
+
"기간 버튼",
|
|
2650
|
+
"date range buttons",
|
|
2651
|
+
"period buttons",
|
|
2652
|
+
"오늘 버튼",
|
|
2653
|
+
"1개월 버튼",
|
|
2654
|
+
"기간 프리셋",
|
|
2655
|
+
"date preset"
|
|
2656
|
+
],
|
|
2657
|
+
"bemClassesExtra": [],
|
|
2658
|
+
"notApplicableAreas": ["allowedChildren", "bemClassesExtra"],
|
|
2659
|
+
"canonicalExamples": {
|
|
2660
|
+
"range-with-buttons": {
|
|
2661
|
+
"description": "시작일~종료일 + 빠른 기간 버튼 (권장 세트: 오늘/7일/15일/1개월/3개월/1년)",
|
|
2662
|
+
"props": {
|
|
2663
|
+
"size": "xs",
|
|
2664
|
+
"datePickerOptions": [
|
|
2665
|
+
{
|
|
2666
|
+
"element": "start-date",
|
|
2667
|
+
"placeholder": "시작일",
|
|
2668
|
+
"options": {
|
|
2669
|
+
"mode": "range",
|
|
2670
|
+
"static": true,
|
|
2671
|
+
"dateFormat": "Y-m-d",
|
|
2672
|
+
"clickOpens": true,
|
|
2673
|
+
"allowInvalidPreload": true,
|
|
2674
|
+
"locale": "ko"
|
|
2675
|
+
}
|
|
2676
|
+
},
|
|
2677
|
+
{
|
|
2678
|
+
"element": "end-date",
|
|
2679
|
+
"placeholder": "종료일",
|
|
2680
|
+
"options": {
|
|
2681
|
+
"mode": "range",
|
|
2682
|
+
"static": true,
|
|
2683
|
+
"dateFormat": "Y-m-d",
|
|
2684
|
+
"clickOpens": true,
|
|
2685
|
+
"allowInvalidPreload": true,
|
|
2686
|
+
"locale": "ko"
|
|
2687
|
+
}
|
|
2688
|
+
}
|
|
2689
|
+
],
|
|
2690
|
+
"buttons": [
|
|
2691
|
+
{ "text": "오늘", "period": 0, "unit": "days", "isCurrent": false },
|
|
2692
|
+
{ "text": "7일", "period": 7, "unit": "days", "isCurrent": false },
|
|
2693
|
+
{ "text": "15일", "period": 15, "unit": "days", "isCurrent": false },
|
|
2694
|
+
{ "text": "1개월", "period": 1, "unit": "months", "isCurrent": false },
|
|
2695
|
+
{ "text": "3개월", "period": 3, "unit": "months", "isCurrent": false },
|
|
2696
|
+
{ "text": "1년", "period": 1, "unit": "years", "isCurrent": false }
|
|
2697
|
+
]
|
|
2698
|
+
}
|
|
2699
|
+
},
|
|
2700
|
+
"range-with-buttons-sm": {
|
|
2701
|
+
"description": "시작일~종료일 + 빠른 기간 버튼 (sm 사이즈, 최소 세트: 오늘/1개월/3개월)",
|
|
2702
|
+
"props": {
|
|
2703
|
+
"size": "sm",
|
|
2704
|
+
"datePickerOptions": [
|
|
2705
|
+
{
|
|
2706
|
+
"element": "start-date",
|
|
2707
|
+
"placeholder": "시작일",
|
|
2708
|
+
"options": {
|
|
2709
|
+
"mode": "range",
|
|
2710
|
+
"static": true,
|
|
2711
|
+
"dateFormat": "Y-m-d",
|
|
2712
|
+
"clickOpens": true,
|
|
2713
|
+
"allowInvalidPreload": true,
|
|
2714
|
+
"locale": "ko"
|
|
2715
|
+
}
|
|
2716
|
+
},
|
|
2717
|
+
{
|
|
2718
|
+
"element": "end-date",
|
|
2719
|
+
"placeholder": "종료일",
|
|
2720
|
+
"options": {
|
|
2721
|
+
"mode": "range",
|
|
2722
|
+
"static": true,
|
|
2723
|
+
"dateFormat": "Y-m-d",
|
|
2724
|
+
"clickOpens": true,
|
|
2725
|
+
"allowInvalidPreload": true,
|
|
2726
|
+
"locale": "ko"
|
|
2727
|
+
}
|
|
2728
|
+
}
|
|
2729
|
+
],
|
|
2730
|
+
"buttons": [
|
|
2731
|
+
{ "text": "오늘", "period": 0, "unit": "days", "isCurrent": true },
|
|
2732
|
+
{ "text": "1개월", "period": 1, "unit": "months", "isCurrent": false },
|
|
2733
|
+
{ "text": "3개월", "period": 3, "unit": "months", "isCurrent": false }
|
|
2734
|
+
]
|
|
2735
|
+
}
|
|
2736
|
+
}
|
|
2737
|
+
}
|
|
2738
|
+
},
|
|
2739
|
+
"bread-crumb": {
|
|
2740
|
+
"_note": "BreadCrumb 는 items 배열(label + href?) 로 동작. 첫 항목은 Home 아이콘 자동 렌더 — icon prop 불필요. 마지막 항목은 current(href 없음). page-title 의 breadcrumbItems 와 별개 — page-title 안 breadcrumb 를 BreadCrumb 로 중복 사용 금지.",
|
|
2741
|
+
"descriptionExtra": "[중요] 경로 탐색 네비게이션 컴포넌트. items 배열에 {label, href?} 전달: 첫 항목은 Home 아이콘 자동 표시(href 지정 권장), 마지막 항목은 현재 페이지(href 생략). ⚠️ guideButton / primaryAction 같은 ReactNode 슬롯 없음 — items 배열과 className만 허용. ⚠️ page-title 내부에 breadcrumbItems prop 으로 이미 breadcrumb 가 내장되므로, PageTitle 과 BreadCrumb 를 동시에 사용하면 breadcrumb 이 중복된다. 단독 nav 영역이나 page-title 없이 breadcrumb 만 필요한 경우에만 사용.",
|
|
2742
|
+
"aliasesExtra": [
|
|
2743
|
+
"브레드크럼",
|
|
2744
|
+
"브레드크럼바",
|
|
2745
|
+
"경로 탐색",
|
|
2746
|
+
"breadcrumb",
|
|
2747
|
+
"breadcrumbs",
|
|
2748
|
+
"navigation trail",
|
|
2749
|
+
"페이지 경로",
|
|
2750
|
+
"계층 탐색",
|
|
2751
|
+
"현재 위치",
|
|
2752
|
+
"홈 > 카테고리",
|
|
2753
|
+
"네비게이션 경로"
|
|
2754
|
+
],
|
|
2755
|
+
"bemClassesExtra": [],
|
|
2756
|
+
"notApplicableAreas": ["allowedChildren", "bemClassesExtra"],
|
|
2757
|
+
"canonicalExamples": {
|
|
2758
|
+
"basic": {
|
|
2759
|
+
"description": "3단계 경로. 첫 항목 Home 아이콘 자동, 중간 항목은 링크, 마지막 항목은 현재 페이지(href 없음).",
|
|
2760
|
+
"props": {
|
|
2761
|
+
"items": [
|
|
2762
|
+
{ "label": "홈", "href": "/" },
|
|
2763
|
+
{ "label": "상품 관리", "href": "/goods" },
|
|
2764
|
+
{ "label": "상품 간편 등록" }
|
|
2765
|
+
]
|
|
2766
|
+
}
|
|
2767
|
+
},
|
|
2768
|
+
"two-level": {
|
|
2769
|
+
"description": "2단계 경로. Home + 현재 페이지만 있는 최소 구성.",
|
|
2770
|
+
"props": {
|
|
2771
|
+
"items": [{ "label": "홈", "href": "/" }, { "label": "대시보드" }]
|
|
2772
|
+
}
|
|
2773
|
+
}
|
|
2774
|
+
}
|
|
2499
2775
|
}
|
|
2500
2776
|
}
|
package/bin/server.js
CHANGED
|
@@ -90,6 +90,12 @@ const main = async () => {
|
|
|
90
90
|
const instructions = (0, dataLoader_js_1.loadInstructions)(definitionsDir);
|
|
91
91
|
const complianceRules = (0, dataLoader_js_1.loadComplianceRules)(definitionsDir);
|
|
92
92
|
const jsApiMap = (0, dataLoader_js_1.loadJsApi)(definitionsDir);
|
|
93
|
+
// ── DOM + React 런타임 초기화 — 번들 로드 전에 실행해야 unifyModuleResolution 이 적용됨 ──
|
|
94
|
+
// setupDomEnvironment()가 Module._resolveFilename 을 override 하여 react / @ncds/ui-admin-icon 경로를
|
|
95
|
+
// MCP 기준으로 pin 한다. 번들 로드 이후에 실행하면 번들 내 require() 가 pin 이전 경로로 캐시되어
|
|
96
|
+
// React 인스턴스 불일치($$typeof Symbol mismatch) 가 발생한다.
|
|
97
|
+
const reactRuntime = (0, domEnvironment_js_1.setupDomEnvironment)();
|
|
98
|
+
logger_js_1.logger.info('DOM + React 런타임 초기화 완료');
|
|
93
99
|
// ── 데이터 로딩 ──
|
|
94
100
|
const { map: componentMap, compositionOverrides } = (0, dataLoader_js_1.loadComponentsFromDir)(dataLoader_js_1.DEFAULT_DATA_DIR);
|
|
95
101
|
const { cdn: cdnMeta, icon: iconMeta } = (0, dataLoader_js_1.loadMeta)(dataLoader_js_1.DEFAULT_DATA_DIR);
|
|
@@ -109,9 +115,6 @@ const main = async () => {
|
|
|
109
115
|
catch {
|
|
110
116
|
logger_js_1.logger.warn('아이콘 번들 로딩 실패 — 아이콘 resolve 비활성화');
|
|
111
117
|
}
|
|
112
|
-
// ── DOM + React 런타임 초기화 (유틸로 추출 § 3.9) ──
|
|
113
|
-
const reactRuntime = (0, domEnvironment_js_1.setupDomEnvironment)();
|
|
114
|
-
logger_js_1.logger.info('DOM + React 런타임 초기화 완료');
|
|
115
118
|
// ── 파생 데이터 사전 계산 (code-guide § 5.1 반복 계산 제거) ──
|
|
116
119
|
const rootClassMap = (0, validateHtml_js_1.buildRootClassMap)(componentMap);
|
|
117
120
|
const tokenValueMap = (0, validateHtml_js_1.buildTokenValueMap)(tokenData);
|
|
@@ -537,7 +537,8 @@ const mergeCdnDefaults = (componentName, cdnDefaults, userProps) => {
|
|
|
537
537
|
return { merged: userProps, defaultsApplied: [] };
|
|
538
538
|
const userPropsClean = (0, exports.stripFunctionProps)(userProps);
|
|
539
539
|
const baseMerged = (0, lodash_1.merge)((0, lodash_1.cloneDeep)(cdnDefaults), userPropsClean);
|
|
540
|
-
const
|
|
540
|
+
const DATE_PICKER_FAMILY = ['date-picker', 'range-date-picker', 'range-date-picker-with-buttons'];
|
|
541
|
+
const merged = DATE_PICKER_FAMILY.includes(componentName) && Array.isArray(userPropsClean.datePickerOptions)
|
|
541
542
|
? {
|
|
542
543
|
...baseMerged,
|
|
543
544
|
datePickerOptions: userPropsClean.datePickerOptions.map((item) => {
|
package/bin/types.d.ts
CHANGED
|
@@ -7,6 +7,8 @@ export interface PropSpec {
|
|
|
7
7
|
default?: unknown;
|
|
8
8
|
values?: string[];
|
|
9
9
|
rawType?: string;
|
|
10
|
+
/** 배열 타입임을 명시 — type: 'object'로 분류되어도 이 필드가 true면 반드시 배열([])로 전달해야 함 */
|
|
11
|
+
isArray?: boolean;
|
|
10
12
|
properties?: Record<string, PropSpec>;
|
|
11
13
|
/** 타입의 의미적 정체성 — 예: 'icon-component'는 SlotIconComponent 계열 아이콘 컴포넌트. renderer가 iconBundle resolve 대상 판정에 사용 */
|
|
12
14
|
semantic?: 'icon-component';
|