@ncds/ui-admin-mcp 1.0.0-alpha.2 → 1.0.0-alpha.20
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/bin/components.bundle.js +15 -19
- package/bin/definitions/external/editor.d.ts +50 -0
- package/bin/definitions/external/editor.js +53 -0
- package/bin/definitions/external/step-guide.d.ts +61 -0
- package/bin/definitions/external/step-guide.js +52 -0
- package/bin/definitions/instructions.md +194 -10
- package/bin/definitions/js-api.json +352 -0
- package/bin/definitions/rules.json +36 -4
- package/bin/definitions/tool-definitions.json +33 -9
- package/bin/overrides/composition.json +2500 -0
- package/bin/server.d.ts +5 -0
- package/bin/server.js +97 -33
- package/bin/server.mjs +0 -0
- package/bin/tools/external/editor.d.ts +18 -0
- package/bin/tools/external/editor.js +88 -0
- package/bin/tools/external/step-guide.d.ts +19 -0
- package/bin/tools/external/step-guide.js +79 -0
- package/bin/tools/getComponentProps.d.ts +3 -0
- package/bin/tools/getComponentProps.js +12 -3
- package/bin/tools/listCompositionOverrides.d.ts +61 -0
- package/bin/tools/listCompositionOverrides.js +156 -0
- package/bin/tools/ping.d.ts +1 -1
- package/bin/tools/renderToHtml.d.ts +38 -7
- package/bin/tools/renderToHtml.js +785 -110
- package/bin/tools/searchComponent.d.ts +5 -0
- package/bin/tools/searchComponent.js +3 -3
- package/bin/tools/validateHtml.d.ts +8 -6
- package/bin/tools/validateHtml.js +74 -6
- package/bin/types.d.ts +60 -1
- package/bin/utils/bemValidator.d.ts +16 -8
- package/bin/utils/bemValidator.js +16 -4
- package/bin/utils/compliance.d.ts +7 -6
- package/bin/utils/compliance.js +8 -4
- package/bin/utils/dataLoader.d.ts +43 -14
- package/bin/utils/dataLoader.js +125 -22
- package/bin/utils/domEnvironment.js +51 -0
- package/bin/utils/fuzzyMatch.d.ts +4 -0
- package/bin/utils/fuzzyMatch.js +13 -3
- package/bin/utils/logger.d.ts +5 -5
- package/bin/utils/logger.js +5 -5
- package/bin/utils/response.d.ts +4 -2
- package/bin/utils/response.js +15 -4
- package/bin/utils/tokenValidator.d.ts +4 -3
- package/bin/utils/tokenValidator.js +13 -11
- package/bin/version.d.ts +4 -2
- package/bin/version.js +4 -2
- package/data/_icons.json +357 -2
- package/data/_meta.json +4 -5
- package/data/_tokens.json +8 -8
- package/data/badge-group.json +181 -4
- package/data/badge.json +146 -14
- package/data/block-container.json +95 -0
- package/data/block-header.json +208 -0
- package/data/bread-crumb.json +38 -2
- package/data/button-group.json +59 -0
- package/data/button.json +124 -1
- package/data/carousel-arrow.json +6 -11
- package/data/carousel-number-group.json +2 -12
- package/data/checkbox.json +1 -1
- package/data/combo-box.json +32 -8
- package/data/data-grid.json +240 -0
- package/data/date-picker.json +22 -2
- package/data/divider.json +1 -1
- package/data/dot.json +2 -2
- package/data/dropdown.json +187 -20
- package/data/editor.json +85 -0
- package/data/empty-state.json +168 -3
- package/data/featured-icon.json +20 -5
- package/data/file-input.json +176 -10
- package/data/horizontal-tab.json +219 -3
- package/data/image-file-input.json +176 -10
- package/data/input-base.json +165 -4
- package/data/modal.json +266 -5
- package/data/notification.json +56 -40
- package/data/number-input.json +164 -4
- package/data/page-title.json +135 -0
- package/data/pagination.json +8 -4
- package/data/password-input.json +252 -13
- package/data/progress-bar.json +28 -8
- package/data/progress-circle.json +9 -6
- package/data/radio.json +4 -3
- package/data/range-date-picker-with-buttons.json +187 -7
- package/data/range-date-picker.json +186 -6
- package/data/select-box.json +48 -16
- package/data/select.json +35 -25
- package/data/slider.json +1 -1
- package/data/spinner.json +3 -4
- package/data/step-guide.json +130 -0
- package/data/switch.json +66 -6
- package/data/table.json +293 -0
- package/data/tag.json +68 -6
- package/data/textarea.json +1 -1
- package/data/toggle.json +2 -2
- package/data/tooltip.json +16 -3
- package/data/vertical-tab.json +220 -3
- package/package.json +27 -25
- package/bin/instructions.d.ts +0 -1
- package/bin/instructions.js +0 -14
- package/bin/tools/getComponentHtml.d.ts +0 -3
- package/bin/tools/getComponentHtml.js +0 -30
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
{
|
|
2
|
+
"Modal": {
|
|
3
|
+
"className": "Modal",
|
|
4
|
+
"constructor": "new window.ncua.Modal(options?)",
|
|
5
|
+
"constructorParams": {
|
|
6
|
+
"size": "'sm' | 'md' | 'lg' (default: 'md')",
|
|
7
|
+
"closeOnBackdropClick": "boolean (default: false)",
|
|
8
|
+
"closeOnEsc": "boolean (default: true)",
|
|
9
|
+
"onClose": "() => void"
|
|
10
|
+
},
|
|
11
|
+
"methods": ["open()", "close()", "destroy()", "setContent(html: string | HTMLElement)", "isModalOpen()"],
|
|
12
|
+
"example": "const modal = new window.ncua.Modal({ size: 'sm', onClose: () => {} });\nmodal.setContent('<p>Content</p>');\nmodal.open();",
|
|
13
|
+
"cdnDefaults": {
|
|
14
|
+
"size": "md",
|
|
15
|
+
"closeOnBackdropClick": false,
|
|
16
|
+
"closeOnEsc": true
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"SelectBox": {
|
|
20
|
+
"className": "SelectBox",
|
|
21
|
+
"cdnPattern": "A",
|
|
22
|
+
"constructor": "new window.ncua.SelectBox(element, config?)",
|
|
23
|
+
"constructorParams": {
|
|
24
|
+
"element": "HTMLElement — target container",
|
|
25
|
+
"config.options": "Array<{ id: string, text: string, disabled?: boolean }>",
|
|
26
|
+
"config.placeholder": "string (default: '선택하세요')",
|
|
27
|
+
"config.value": "string | number",
|
|
28
|
+
"config.onChange": "(value) => void",
|
|
29
|
+
"config.size": "'xs' | 'sm' | 'md'",
|
|
30
|
+
"config.multiple": "boolean",
|
|
31
|
+
"config.disabled": "boolean"
|
|
32
|
+
},
|
|
33
|
+
"methods": ["getValues()", "setValues(options[])", "getSelectedCount()"],
|
|
34
|
+
"example": "const select = new window.ncua.SelectBox(document.getElementById('my-select'), {\n options: [{ id: '1', text: 'Option 1' }],\n onChange: (value) => console.log(value)\n});",
|
|
35
|
+
"cdnDefaults": {
|
|
36
|
+
"size": "md",
|
|
37
|
+
"placeholder": "선택하세요",
|
|
38
|
+
"disabled": false,
|
|
39
|
+
"multiple": false
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
"ComboBox": {
|
|
43
|
+
"className": "ComboBox",
|
|
44
|
+
"cdnPattern": "A",
|
|
45
|
+
"constructor": "new window.ncua.ComboBox(element, config?)",
|
|
46
|
+
"constructorParams": {
|
|
47
|
+
"element": "HTMLElement — target container",
|
|
48
|
+
"config.options": "Array<{ id: string, label: string, disabled?: boolean }>",
|
|
49
|
+
"config.placeholder": "string (default: '검색하고 선택하세요')",
|
|
50
|
+
"config.value": "string | number",
|
|
51
|
+
"config.onChange": "(value) => void",
|
|
52
|
+
"config.onSearch": "(searchValue: string) => void",
|
|
53
|
+
"config.size": "'xs' | 'sm'",
|
|
54
|
+
"config.multiple": "boolean"
|
|
55
|
+
},
|
|
56
|
+
"methods": ["getValues()", "setValues(options[])", "clearInput()", "getSelectedCount()"],
|
|
57
|
+
"example": "const combo = new window.ncua.ComboBox(document.getElementById('my-combo'), {\n options: [{ id: '1', label: 'React' }],\n onSearch: (q) => console.log(q)\n});",
|
|
58
|
+
"cdnDefaults": {
|
|
59
|
+
"size": "md",
|
|
60
|
+
"placeholder": "검색하고 선택하세요",
|
|
61
|
+
"disabled": false,
|
|
62
|
+
"multiple": false,
|
|
63
|
+
"showFooterButtons": false
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
"DatePicker": {
|
|
67
|
+
"className": "DatePicker",
|
|
68
|
+
"cdnPattern": "A",
|
|
69
|
+
"constructor": "new window.ncua.DatePicker(wrapper, options)",
|
|
70
|
+
"constructorParams": {
|
|
71
|
+
"wrapper": "HTMLElement — container element",
|
|
72
|
+
"options.size": "'xs' | 'sm'",
|
|
73
|
+
"options.datePickerOptions": "Array<{ element: string, attrName?: string, placeholder?: string, options: FlatpickrOptions }>",
|
|
74
|
+
"options.buttons": "Array<{ text: string, period: number, unit: 'days'|'weeks'|'months'|'years', isCurrent: boolean }>",
|
|
75
|
+
"options.onValidationError": "(error: ValidationError) => void",
|
|
76
|
+
"options.autoComplete": "'on' | 'off'"
|
|
77
|
+
},
|
|
78
|
+
"methods": ["getDates()", "setDate(dates: string[])", "setMultipleDates(dates: string[])"],
|
|
79
|
+
"example": "const dp = new window.ncua.DatePicker(document.getElementById('my-dp'), {\n size: 'xs',\n datePickerOptions: [{ element: 'date-input', placeholder: 'Select date', options: { dateFormat: 'Y-m-d' } }]\n});",
|
|
80
|
+
"cdnDefaults": {
|
|
81
|
+
"size": "xs",
|
|
82
|
+
"datePickerOptions": [
|
|
83
|
+
{
|
|
84
|
+
"options": {
|
|
85
|
+
"mode": "single",
|
|
86
|
+
"static": true,
|
|
87
|
+
"dateFormat": "Y-m-d",
|
|
88
|
+
"clickOpens": true,
|
|
89
|
+
"allowInvalidPreload": true,
|
|
90
|
+
"locale": "ko"
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
]
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
"Slider": {
|
|
97
|
+
"className": "Slider",
|
|
98
|
+
"cdnPattern": "A",
|
|
99
|
+
"constructor": "new window.ncua.Slider(element, options)",
|
|
100
|
+
"constructorParams": {
|
|
101
|
+
"element": "HTMLElement — container",
|
|
102
|
+
"options.min": "number (default: 0)",
|
|
103
|
+
"options.max": "number (default: 100)",
|
|
104
|
+
"options.step": "number (default: 1)",
|
|
105
|
+
"options.value": "number | [number, number]",
|
|
106
|
+
"options.onChange": "(value) => void",
|
|
107
|
+
"options.disabled": "boolean",
|
|
108
|
+
"options.labelPosition": "'bottom' | 'top-floating'"
|
|
109
|
+
},
|
|
110
|
+
"methods": ["getValue()", "setValue(value)", "enable()", "disable()", "destroy()"],
|
|
111
|
+
"example": "const slider = new window.ncua.Slider(document.getElementById('my-slider'), {\n min: 0, max: 100, value: 50,\n onChange: (v) => console.log(v)\n});",
|
|
112
|
+
"cdnDefaults": {
|
|
113
|
+
"min": 0,
|
|
114
|
+
"max": 100,
|
|
115
|
+
"step": 1,
|
|
116
|
+
"labelPosition": "top-floating",
|
|
117
|
+
"disabled": false,
|
|
118
|
+
"value": 0
|
|
119
|
+
}
|
|
120
|
+
},
|
|
121
|
+
"HorizontalTab": {
|
|
122
|
+
"className": "Tab",
|
|
123
|
+
"constructor": "new window.ncua.Tab(swiperEl)",
|
|
124
|
+
"constructorParams": {
|
|
125
|
+
"swiperEl": "HTMLElement — `.swiper` 클래스를 가진 element 자체. render_to_html 응답의 `.ncua-horizontal-tab` 내부에 있는 `.swiper` 를 선택해 전달해야 한다. wrapper element 를 넘기면 내부 Swiper 라이브러리가 부모 element 의 스타일을 계산하지 못해 초기화에 실패한다."
|
|
126
|
+
},
|
|
127
|
+
"methods": ["destroy()"],
|
|
128
|
+
"example": "const tab = new window.ncua.Tab(document.querySelector('#my-tab .swiper'));"
|
|
129
|
+
},
|
|
130
|
+
"Tooltip": {
|
|
131
|
+
"className": "Tooltip",
|
|
132
|
+
"cdnPattern": "C",
|
|
133
|
+
"constructor": "window.ncua.Tooltip.createShort(title, content?, options?)",
|
|
134
|
+
"constructorParams": {
|
|
135
|
+
"title": "string",
|
|
136
|
+
"content": "string (HTML supported)",
|
|
137
|
+
"options.position": "'top' | 'bottom' | 'left' | 'right' | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' | 'auto' (default: 'auto')",
|
|
138
|
+
"options.type": "'long' | 'short'",
|
|
139
|
+
"options.tooltipType": "'white' | 'black'",
|
|
140
|
+
"options.iconType": "'stroke' | 'fill'",
|
|
141
|
+
"options.size": "'sm' | 'md'",
|
|
142
|
+
"options.hideArrow": "boolean",
|
|
143
|
+
"options.zIndex": "number",
|
|
144
|
+
"options.useShadowDOM": "boolean",
|
|
145
|
+
"options.className": "string"
|
|
146
|
+
},
|
|
147
|
+
"methods": ["getElement()", "showTooltip()", "hideTooltip()", "destroy()"],
|
|
148
|
+
"example": "const tip = window.ncua.Tooltip.createShort('Help', 'Tooltip content');\ndocument.getElementById('container').appendChild(tip.getElement());",
|
|
149
|
+
"cdnDefaults": {
|
|
150
|
+
"type": "short",
|
|
151
|
+
"tooltipType": "white",
|
|
152
|
+
"iconType": "stroke",
|
|
153
|
+
"position": "auto",
|
|
154
|
+
"size": "sm",
|
|
155
|
+
"hideArrow": false
|
|
156
|
+
}
|
|
157
|
+
},
|
|
158
|
+
"Notification": {
|
|
159
|
+
"className": "Notification",
|
|
160
|
+
"cdnPattern": "C",
|
|
161
|
+
"constructor": "window.ncua.Notification.success(title, supportingText?, options?)",
|
|
162
|
+
"cdnDefaults": {
|
|
163
|
+
"type": "floating",
|
|
164
|
+
"color": "neutral",
|
|
165
|
+
"autoClose": 0
|
|
166
|
+
},
|
|
167
|
+
"constructorParams": {
|
|
168
|
+
"title": "string",
|
|
169
|
+
"supportingText": "string",
|
|
170
|
+
"options.autoClose": "number (ms, 0 = no auto-close)",
|
|
171
|
+
"options.type": "'floating' | 'message' | 'full-width'",
|
|
172
|
+
"options.color": "'neutral' | 'success' | 'error' | 'warning' | 'info'",
|
|
173
|
+
"options.actions": "Array<NotificationAction>",
|
|
174
|
+
"options.onClose": "() => void",
|
|
175
|
+
"options.className": "string",
|
|
176
|
+
"options.supportTextLink": "string — full-width 전용 supportingText 링크 URL",
|
|
177
|
+
"options.onHidePermanently": "() => void — full-width/message 다시보지 않기 핸들러"
|
|
178
|
+
},
|
|
179
|
+
"methods": ["show(parent?)", "remove()", "destroy()"],
|
|
180
|
+
"staticMethods": ["success()", "error()", "warning()", "info()", "neutral()"],
|
|
181
|
+
"example": "window.ncua.Notification.success('Saved', 'Changes saved successfully');"
|
|
182
|
+
},
|
|
183
|
+
"ProgressBar": {
|
|
184
|
+
"className": "ProgressBar",
|
|
185
|
+
"cdnPattern": "C",
|
|
186
|
+
"constructor": "new window.ncua.ProgressBar(options?)",
|
|
187
|
+
"constructorParams": {
|
|
188
|
+
"options.value": "number (0-100)",
|
|
189
|
+
"options.label": "'right' | 'bottom' | 'top-float' | 'bottom-float'",
|
|
190
|
+
"options.segments": "ProgressSegment[] — 멀티 세그먼트 진행률",
|
|
191
|
+
"options.showZeroLabel": "boolean — 0% 라벨 표시 여부",
|
|
192
|
+
"options.valueToPercent": "boolean — value 를 % 환산 표시"
|
|
193
|
+
},
|
|
194
|
+
"methods": ["getElement()", "updateOptions(newOptions)", "toHTML()"],
|
|
195
|
+
"example": "const bar = new window.ncua.ProgressBar({ value: 65, label: 'right' });\ndocument.getElementById('container').appendChild(bar.getElement());",
|
|
196
|
+
"cdnDefaults": {
|
|
197
|
+
"label": "right",
|
|
198
|
+
"showZeroLabel": false,
|
|
199
|
+
"valueToPercent": true
|
|
200
|
+
}
|
|
201
|
+
},
|
|
202
|
+
"Tag": {
|
|
203
|
+
"className": "Tag",
|
|
204
|
+
"cdnPattern": "C",
|
|
205
|
+
"constructor": "new window.ncua.Tag(options)",
|
|
206
|
+
"constructorParams": {
|
|
207
|
+
"options.text": "string",
|
|
208
|
+
"options.size": "'sm' | 'md' (default: 'sm')",
|
|
209
|
+
"options.close": "boolean — show close button",
|
|
210
|
+
"options.onButtonClick": "(event: MouseEvent) => void — close handler",
|
|
211
|
+
"options.count": "string — 카운트 표시",
|
|
212
|
+
"options.icon": "SideSlotType — 좌측 아이콘 슬롯",
|
|
213
|
+
"options.maxLength": "number — 최대 텍스트 길이 (default: 20)"
|
|
214
|
+
},
|
|
215
|
+
"methods": ["getElement()", "setText(text)", "setCount(count)", "destroy()"],
|
|
216
|
+
"example": "const tag = new window.ncua.Tag({ text: 'Label', close: true, onButtonClick: () => tag.destroy() });\ndocument.getElementById('container').appendChild(tag.getElement());",
|
|
217
|
+
"cdnDefaults": {
|
|
218
|
+
"size": "sm",
|
|
219
|
+
"maxLength": 20
|
|
220
|
+
}
|
|
221
|
+
},
|
|
222
|
+
"FileInput": {
|
|
223
|
+
"className": "FileInput",
|
|
224
|
+
"cdnPattern": "B",
|
|
225
|
+
"constructor": "new window.ncua.FileInput(options)",
|
|
226
|
+
"constructorParams": {
|
|
227
|
+
"options.container": "HTMLElement | string — auto-append target",
|
|
228
|
+
"options.onChange": "(files: File[]) => void",
|
|
229
|
+
"options.onFail": "(invalidFiles: File[]) => void",
|
|
230
|
+
"options.disabled": "boolean",
|
|
231
|
+
"options.size": "'xs' | 'sm'",
|
|
232
|
+
"options.accept": "string — e.g. '.jpg,.png' or 'image/*'",
|
|
233
|
+
"options.multiple": "boolean",
|
|
234
|
+
"options.maxFileCount": "number",
|
|
235
|
+
"options.maxFileSize": "number — bytes",
|
|
236
|
+
"options.buttonLabel": "string",
|
|
237
|
+
"options.label": "string",
|
|
238
|
+
"options.hintItems": "string[]",
|
|
239
|
+
"options.isRequired": "boolean",
|
|
240
|
+
"options.showHelpIcon": "boolean",
|
|
241
|
+
"options.hintText": "string",
|
|
242
|
+
"options.validation": "boolean",
|
|
243
|
+
"options.destructive": "boolean",
|
|
244
|
+
"options.className": "string"
|
|
245
|
+
},
|
|
246
|
+
"methods": ["getElement()", "setDisabled(boolean)", "destroy()"],
|
|
247
|
+
"example": "const fi = new window.ncua.FileInput({\n container: 'file-container',\n onChange: (files) => console.log(files)\n});",
|
|
248
|
+
"cdnDefaults": {
|
|
249
|
+
"buttonLabel": "파일 찾기",
|
|
250
|
+
"multiple": false,
|
|
251
|
+
"size": "xs"
|
|
252
|
+
}
|
|
253
|
+
},
|
|
254
|
+
"ImageFileInput": {
|
|
255
|
+
"className": "ImageFileInput",
|
|
256
|
+
"cdnPattern": "B",
|
|
257
|
+
"constructor": "new window.ncua.ImageFileInput(options)",
|
|
258
|
+
"constructorParams": {
|
|
259
|
+
"options.container": "HTMLElement | string — auto-append target",
|
|
260
|
+
"options.onChange": "(files: File[]) => void — controlled mode",
|
|
261
|
+
"options.onFileSelect": "(files: File[]) => void — uncontrolled mode",
|
|
262
|
+
"options.onFail": "(files: InvalidFile[]) => void",
|
|
263
|
+
"options.value": "File[] — initial files (controlled mode)",
|
|
264
|
+
"options.disabled": "boolean",
|
|
265
|
+
"options.size": "'xs' | 'sm'",
|
|
266
|
+
"options.accept": "string — e.g. '.jpg,.png' or 'image/*'",
|
|
267
|
+
"options.multiple": "boolean",
|
|
268
|
+
"options.maxFileCount": "number",
|
|
269
|
+
"options.maxFileSize": "number — bytes",
|
|
270
|
+
"options.buttonLabel": "string",
|
|
271
|
+
"options.imagePreviewTooltipLabel": "string",
|
|
272
|
+
"options.label": "string",
|
|
273
|
+
"options.hintItems": "string[]",
|
|
274
|
+
"options.isRequired": "boolean",
|
|
275
|
+
"options.showHelpIcon": "boolean",
|
|
276
|
+
"options.hintText": "string",
|
|
277
|
+
"options.validation": "boolean",
|
|
278
|
+
"options.destructive": "boolean",
|
|
279
|
+
"options.fileInputName": "string — name attr (PHP form 제출용)",
|
|
280
|
+
"options.className": "string"
|
|
281
|
+
},
|
|
282
|
+
"cdnDefaults": {
|
|
283
|
+
"buttonLabel": "파일 찾기",
|
|
284
|
+
"imagePreviewTooltipLabel": "이미지 업로드",
|
|
285
|
+
"multiple": false,
|
|
286
|
+
"size": "sm"
|
|
287
|
+
},
|
|
288
|
+
"methods": ["getElement()", "getFiles()", "clearFiles()", "setDisabled(boolean)", "destroy()"],
|
|
289
|
+
"example": "const img = new window.ncua.ImageFileInput({\n container: 'image-container',\n maxFileCount: 5,\n onChange: (files) => console.log(files)\n});"
|
|
290
|
+
},
|
|
291
|
+
"FeaturedIcon": {
|
|
292
|
+
"className": "FeaturedIcon",
|
|
293
|
+
"constructor": "new window.ncua.FeaturedIcon(options)",
|
|
294
|
+
"constructorParams": {
|
|
295
|
+
"options.svgString": "string — SVG content",
|
|
296
|
+
"options.theme": "'light-circle' | 'dark-circle' | 'outline-circle' | 'square-outline'",
|
|
297
|
+
"options.color": "'neutral' | 'error' | 'warning' | 'success'",
|
|
298
|
+
"options.size": "'sm' | 'md' | 'lg' | 'xl'",
|
|
299
|
+
"options.className": "string"
|
|
300
|
+
},
|
|
301
|
+
"methods": ["getElement()", "updateColor(color)", "updateSize(size)", "destroy()"],
|
|
302
|
+
"example": "const icon = new window.ncua.FeaturedIcon({ svgString: '<svg>...</svg>', color: 'success', size: 'md' });\ndocument.getElementById('container').appendChild(icon.getElement());",
|
|
303
|
+
"cdnDefaults": {
|
|
304
|
+
"theme": "light-circle",
|
|
305
|
+
"color": "neutral",
|
|
306
|
+
"size": "sm"
|
|
307
|
+
}
|
|
308
|
+
},
|
|
309
|
+
"Table": {
|
|
310
|
+
"className": "Table",
|
|
311
|
+
"constructor": "new window.ncua.Table(options)",
|
|
312
|
+
"constructorParams": {
|
|
313
|
+
"options.columns": "TableColumn[] — { key: string; label: string; width?: string; sortable?: boolean; align?: 'left'|'center'|'right'; render?: (value, row, index) => string | HTMLElement }",
|
|
314
|
+
"options.data": "Record<string, unknown>[] — row data",
|
|
315
|
+
"options.type": "'horizontal' | 'vertical' (default: 'horizontal')",
|
|
316
|
+
"options.hoverable": "boolean (default: true) — horizontal type 한정",
|
|
317
|
+
"options.selectable": "boolean (default: false)",
|
|
318
|
+
"options.fixedHeader": "boolean (default: false)",
|
|
319
|
+
"options.maxHeight": "string — fixedHeader 와 함께 사용 (예: '320px')",
|
|
320
|
+
"options.emptyText": "string (default: '등록된 게시물이 없습니다.')",
|
|
321
|
+
"options.onSort": "(key: string, direction: 'asc' | 'desc' | 'none') => void",
|
|
322
|
+
"options.onSelect": "(selectedIndices: number[]) => void"
|
|
323
|
+
},
|
|
324
|
+
"methods": ["getElement()", "setData(data: Record<string, unknown>[])", "getSelectedIndices()", "destroy()"],
|
|
325
|
+
"example": "const table = new window.ncua.Table({\n columns: [{ key: 'name', label: '이름', sortable: true }],\n data: [{ name: 'Alice' }, { name: 'Bob' }],\n selectable: true,\n onSelect: (indices) => console.log(indices),\n});\ndocument.getElementById('container').appendChild(table.getElement());",
|
|
326
|
+
"cdnDefaults": {
|
|
327
|
+
"type": "horizontal",
|
|
328
|
+
"hoverable": true,
|
|
329
|
+
"selectable": false,
|
|
330
|
+
"fixedHeader": false
|
|
331
|
+
}
|
|
332
|
+
},
|
|
333
|
+
"Dropdown": {
|
|
334
|
+
"className": "Dropdown",
|
|
335
|
+
"constructor": "new window.ncua.Dropdown(host, options)",
|
|
336
|
+
"constructorParams": {
|
|
337
|
+
"host": "HTMLElement — Dropdown 이 부착될 컨테이너 (필수, 첫 번째 인자)",
|
|
338
|
+
"options.trigger": "{ type: 'icon'|'avatar'|'button'|'custom', text?: string, iconHtml?: string, avatar?: string, html?: string } — 트리거 형태",
|
|
339
|
+
"options.groups": "DropdownGroup[] — 메뉴 항목 그룹 (각 그룹은 items: DropdownItem[], sortable?: boolean)",
|
|
340
|
+
"options.header": "{ type?: 'avatar', title?: string, subtitle?: string, avatar?: string } — 메뉴 상단 헤더 (옵션)",
|
|
341
|
+
"options.align": "'left' | 'right' — 메뉴 정렬 (default: 'left')",
|
|
342
|
+
"options.variant": "'action' | 'config' — 액션 메뉴 vs 설정 메뉴 (default: 'action')",
|
|
343
|
+
"options.closeOnClickItem": "boolean (default: true) — action variant 한정",
|
|
344
|
+
"options.closeOnClickOutside": "boolean (default: true)",
|
|
345
|
+
"options.className": "string — 추가 클래스",
|
|
346
|
+
"options.applyButtonText": "string — config variant 의 적용 버튼 텍스트 (default: '설정 완료')",
|
|
347
|
+
"options.onApply": "(items: DropdownItem[]) => void — config variant 적용 시 콜백"
|
|
348
|
+
},
|
|
349
|
+
"methods": ["toggle()", "open()", "close()", "closeAndRestoreFocus()", "destroy()"],
|
|
350
|
+
"example": "const dropdown = new window.ncua.Dropdown(document.getElementById('my-host'), {\n trigger: { type: 'button', text: '메뉴' },\n groups: [{\n items: [\n { id: 'edit', text: '수정', onClick: () => console.log('edit') },\n { id: 'delete', text: '삭제', type: 'danger', onClick: () => console.log('delete') },\n ],\n }],\n});"
|
|
351
|
+
}
|
|
352
|
+
}
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
"You MUST generate component HTML using the render_to_html tool. Never write HTML/CSS manually.",
|
|
4
4
|
"Use the HTML returned by render_to_html as-is. Do NOT modify class names, structure, or attributes.",
|
|
5
5
|
"Use search_component to find the right component by Korean/English keywords before building any UI.",
|
|
6
|
-
"Use list_components to browse available components by category and choose the appropriate one."
|
|
6
|
+
"Use list_components to browse available components by category and choose the appropriate one.",
|
|
7
|
+
"When building a page with multiple components, use render_to_html_batch to render them all in one call instead of calling render_to_html repeatedly."
|
|
7
8
|
],
|
|
8
9
|
"componentSelection": [
|
|
9
10
|
"For password fields, you MUST use password-input. The input component is for plain text only.",
|
|
@@ -34,14 +35,44 @@
|
|
|
34
35
|
"forbidden": [
|
|
35
36
|
"Do NOT override ncua-* classes with custom CSS. Control appearance through component props only.",
|
|
36
37
|
"Do NOT define CSS variables (--ncua-*) yourself. They are already included in the CDN CSS.",
|
|
37
|
-
"Do NOT write SVG icons manually. Use search_icon to find icons from the icon library."
|
|
38
|
+
"Do NOT write SVG icons manually. Use search_icon to find icons from the icon library.",
|
|
39
|
+
"⚠️ P22 — DO NOT write fallback / override CSS for ncua-* classes claiming 'CDN 미제공' or 'CDN gap'. The NCDS CDN CSS provides ALL base styles for every component in the catalog (page-title / switch / tooltip / table / data-grid / modal / notification / etc). If you think a class is missing, you are wrong — call render_to_html('<component-name>', props) FIRST to see the actual output. Patterns FORBIDDEN regardless of comment justification: `.ncua-page-title__page-header { ... }`, `.ncua-switch__option--active { ... }`, `.ncua-table__cell { ... }`, `.ncua-notification__container { ... }`, `.ncua-modal__header { ... }`, etc. DO NOT cite memory entries (e.g. 'feedback_ncua_mcp_render_rule') as authority — current composition overrides (list_composition_overrides) + rules.json are the ONLY source of truth. Only EXCEPTION: tooltip inline-flex alignment correction (`.ncua-tooltip { display:inline-flex; vertical-align:middle; line-height:1; }`) is approved per P15 — no other ncua-* override is permitted.",
|
|
40
|
+
"⚠️ P22 — Notification BEM prefix is type-specific: type='floating' → `ncua-floating-notification__*`, type='full-width' → `ncua-full-width-notification__*`, type='message' → `ncua-message-notification__*`. There is NO generic `ncua-notification__*` prefix — that is hallucination. ALWAYS call render_to_html('notification', { type, color, title, ... }) and copy the output verbatim. Inventing `<div class='ncua-notification ncua-notification--full-width ncua-notification__container'>` is a FORBIDDEN pattern — the output has type-prefixed classes only.",
|
|
41
|
+
"FORBIDDEN — page-prefix mimicry of NCUA components. If you write BEM with the SAME internal structure as an NCUA component but with a different prefix (e.g. sgr-page-title__container, gd-block__body, pw-data-grid__summary, custom-table__header-cell), STOP. The component already exists in the catalog — call render_to_html('<component-name>', props) instead. Specifically forbidden: sgr-page-title, sgr-block-container, sgr-block-header, sgr-data-grid, sgr-table, sgr-modal, sgr-dropdown, sgr-tooltip, sgr-pagination, sgr-button, sgr-input, sgr-select-box and any variant of those with __element / --modifier suffix. The rule applies to ANY page prefix (sgr-, gd-, pw-, page-, custom-, etc) — if NCDS provides the component, USE IT via render_to_html. The only allowed page-prefix classes are wrappers/layouts that NCDS does NOT provide (e.g. sgr-comb-scroll for cross-component page wrapping).",
|
|
42
|
+
"⚠️ P15 — FORBIDDEN override of NCUA root-class critical properties. Do NOT write fallback CSS that overrides core layout/positioning properties on ncua-* root classes. Concrete bans: `.ncua-block-container { overflow: visible }` (CDN uses `hidden` so block-header's white background gets clipped by the 12px radius — overriding visible breaks the corner); `.ncua-table { overflow: visible }` (the overflow:visible exception is ONLY for `.ncua-table--vertical` for tooltip overflow); any change to position / display / box-sizing / overflow on `.ncua-{component}` roots. If you need overflow:visible for a tooltip, scope it to the specific table variant (.ncua-table--vertical), NEVER the block container.",
|
|
43
|
+
"⚠️ P15 — FORBIDDEN — NCDS Switch active state with dark background. NCDS Switch follows the Apple segment-control pattern: track=gray-100, active option=base-white card with shadow-sm + gray-600 text, inactive option=gray-100 (matches track) + gray-300 text. Writing fallback like `.ncua-switch__option--active { background: var(--gray-700); color: var(--base-white) }` INVERTS the design intent. Active is NOT a 'dark highlighted button' — it is a 'raised white card on the gray track'. Do not infer active=dark from generic UI patterns."
|
|
44
|
+
],
|
|
45
|
+
"composition": [
|
|
46
|
+
"Vertical Table row labels MUST use Table.Cell with isHeader=true (renders <th scope='row' class='ncua-table__cell'>). Do NOT use Table.HeaderCell in Vertical Table — that class (ncua-table__header-cell) is exclusively for Horizontal Table column headers inside <thead>. Pick the correct scenario from canonicalExamples: 'vertical-form-label' for form layouts, 'horizontal-with-header-cell' for data lists.",
|
|
47
|
+
"For required field labels in Vertical Table, use the official NCDS element <span class='ncua-table__required'>*</span> prepended INSIDE the <th scope='row'> cell, BEFORE the label text. Do NOT invent page-prefix variants like sgr-label__required / form-required / etc. — ncua-table__required is the canonical required-mark element. See canonicalExamples key 'vertical-form-label-with-required'.",
|
|
48
|
+
"For page-level title/breadcrumb/action area, ALWAYS use the NCUA 'page-title' component (PageTitle) via render_to_html — props: breadcrumbItems, title, primaryAction, secondaryAction, guideButton, onBack, variant (default/detail/fixed). Do NOT invent page-prefix custom classes like sgr-page-title, page-header, gd-page-title — page-title is in the catalog (list_components → category=layout). Output BEM is ncua-page-title__page-header / __title-container / __title-row / __title / __action-area / __breadcrumb-item etc. Pick the right canonicalExamples scenario (default/with-guide-button/detail-with-back/fixed-on-scroll) and modify only the values, not the props shape.",
|
|
49
|
+
"For tooltips on form fields, ALWAYS use the NCUA 'tooltip' component via render_to_html('tooltip', props={...}). Do NOT invent custom classes like tooltip-custom-code, tooltip-helper, sgr-tooltip — tooltip is in the catalog and supports content/title/iconStyle/iconType/position/size/tooltipType/type props. See canonicalExamples 'icon-help-form-field' / 'with-title-and-body' / 'alert-warning'.",
|
|
50
|
+
"NCDS does NOT provide RadioGroup or CheckboxGroup wrapper components. When grouping multiple radio/checkbox items, wrap them with a PAGE-PREFIX class (e.g. <div class='sgr-radio-group'> or <div class='order-form__check-group'>) — NEVER use inline style attribute (e.g. style='display:flex;gap:16px') and NEVER reuse ncua- prefix for the wrapper. Define wrapper CSS in page-level SCSS using NCDS spacing/color tokens (var(--spacing-md), var(--gray-100)) — no hardcoded hex/px values.",
|
|
51
|
+
"⚠️ React props ≠ CDN JS options. The component's React props (in get_component_props.props) and CDN JS constructor options (in render_to_html response's js.api.constructorParams) ARE DIFFERENT. React-only props that do NOT appear in js.api.constructorParams MUST NOT be passed as CDN options. Concrete example: Tooltip.iconStyle exists as React prop ('help-circle' | 'alert-circle') but is NOT a CDN option (allowed CDN options: position / type / tooltipType / iconType / size / hideArrow / zIndex / useShadowDOM / className). When generating CDN HTML mode code, copy js.api.example AS-IS from render_to_html response — do NOT mix React props into CDN options.",
|
|
52
|
+
"⚠️ When js.api.cdnPattern is 'C' (Tooltip / Notification / Slider etc.), the component uses a STATIC FACTORY, NOT new Component(options). Use exactly the signature shown in js.api.constructor (e.g. window.ncua.Tooltip.createShort(title, content, options)). Never write `new ncua.Tooltip({title, content, ...options})` — that pattern is wrong because title/content are positional arguments, not options. Always reference render_to_html response's js.api.example and copy verbatim.",
|
|
53
|
+
"⚠️ P13 — Vertical form layouts MUST be rendered by render_to_html('table', { type: 'vertical', ... }). The same 'table' component handles BOTH horizontal (data grid) AND vertical (form layout) modes via the `type` prop. Do NOT compose vertical table HTML from scratch. Do NOT use <th class='ncua-table__header-cell'> for vertical labels — that class is horizontal-only. For vertical labels, render_to_html outputs <th scope='row' class='ncua-table__cell'> (Table.Cell with isHeader=true). The required mark in vertical is <span class='ncua-table__required'>*</span> prepended inside the <th> — NOT a page-prefix span like gp-required / sgr-required / pw-required / form-required.",
|
|
54
|
+
"For form layouts (label-value rows), ALWAYS call get_component_props('table') first and read canonicalExamples 'vertical-form-label' / 'vertical-form-label-with-required'. Search keywords that resolve to 'table' component: vertical-table, form-table, form-layout, label-value, 폼 레이아웃, 라벨-입력, 세로 테이블. Do NOT compose vertical table HTML by hand.",
|
|
55
|
+
"⚠️ P14 — BlockContainer 의 본문은 반드시 BlockContainer.Body (component descriptor: 'block-container.body') 로 wrap. 직접 <section class='ncua-block-container'> 아래에 table/data-grid 를 자식으로 넣으면 ncua-block-container__body 패딩(16px 24px) 누락 — 시각적 호흡 사라짐. 표준 구조: BlockContainer > BlockHeader + BlockContainer.Body > [실제 컨텐츠]. canonicalExamples 'form-block' / 'data-block' / 'info-block' 참고.",
|
|
56
|
+
"⚠️ P15 — horizontal-tab / carousel components are Swiper.js based. Their internal markup is `.ncua-horizontal-tab > .swiper > .swiper-wrapper > .swiper-slide.ncua-horizontal-tab__item > .ncua-tab-button`. Active tab uses `.ncua-tab-button.is-active`. NEVER hand-write markup with invented classes like `.ncua-horizontal-tab__menu` or `.ncua-horizontal-tab__menu--active` — those classes DO NOT EXIST. Always call render_to_html('horizontal-tab', { menus, activeTab, ... }) — pass menus as a data array, never as JSX children. The CDN JS auto-initializes the swiper instance.",
|
|
57
|
+
"⚠️ P15 — JS-instantiated components (those with js.required=true and a cdnPattern, e.g. image-file-input / tooltip / notification / slider / pagination) return a placeholder `<div id> + <script>` from render_to_html. The visible markup appears EMPTY until DOMContentLoaded fires and the CDN JS populates it. This is CORRECT behavior — do NOT replace the placeholder with hand-written `<div class='ncua-image-file-input'>...<button class='ncua-btn'>파일 찾기</button>...</div>` markup because it 'looks empty in the wireframe'. The hand-written version diverges from the actual CDN runtime output. Use the placeholder + script as-is.",
|
|
58
|
+
"⚠️ P16 — Vertical Table 라벨 옆 안내 아이콘은 반드시 Table.Cell 의 `tooltip` prop (TooltipProps) 으로 전달. Cell 내부에서 `ncua-table__cell-inner` / `ncua-table__cell-label` / `.ncua-tooltip` 구조로 자동 wrapping 되고 `ncua-table__cell--with-tooltip` modifier 가 부착된다. 라벨 셀 외부에 별도 Tooltip 컴포넌트를 배치하거나 페이지 prefix wrapper (예: page-vlabel, sgr-tooltip-wrapper, gd-label-with-help) 로 라벨과 아이콘을 묶지 말 것 — 정렬 어긋남 + 발명 클래스 hallucination 의 주원인. canonicalExamples 'vertical-form-label-with-tooltip' 시나리오 참고.",
|
|
59
|
+
"⚠️ P17 — JS-instantiated 컴포넌트(horizontal-tab / carousel / image-file-input / tooltip / notification / slider / pagination 등 js.required=true + cdnPattern 보유) 의 정적 출력 HTML 에 활성 상태(`.is-active` / `--active` / `aria-selected='true'`) 가 포함돼 있지 않은 것은 의도된 동작이다. 활성 탭/슬라이드는 컴포넌트 prop(`activeTab` / `defaultIndex` 등) 으로 전달해 CDN JS 가 마운트 시 적용하도록 하라. render_to_html 출력 HTML 을 후처리해 `.ncua-tab-button--active` / `.ncua-horizontal-tab__item--active` 같은 발명 modifier 를 수동 추가하지 말 것 — NCDS 표준 활성 클래스는 `.ncua-tab-button.is-active` (state class, BEM modifier 아님).",
|
|
60
|
+
"⚠️ P19 — Tooltip 의 React props 기본값과 CDN factory 기본값이 다르다. React: `tooltipType='white'` (Tooltip.tsx). CDN: `cdnDefaults.tooltipType='black'` (js-api.json). 동일 컴포넌트지만 환경별 기본 색상이 반대 — godomall5 페이지에서 발견된 색상 mismatch 의 주원인. **CDN HTML 모드에서는 반드시 options.tooltipType 을 명시**(생략 시 black 으로 fallback). 라벨 옆 인라인 배치 시 정렬 어긋남 방지: 페이지 SCSS 에 `.ncua-tooltip { display: inline-flex; vertical-align: middle; }` 추가 + 부모는 `display: inline-flex; align-items: center; gap: var(--spacing-xs);`. canonicalExamples `inline-with-label-alignment` 시나리오 참고. createShort 팩토리에 `type='long'` 옵션 전달 / createLong 에 `type='short'` 전달 같은 팩토리-옵션 충돌도 금지.",
|
|
61
|
+
"⚠️ P25 — Tooltip SVG 의 `color='var(--gray-300)'` 속성은 **NCDS 표준 base 색상 전달 메커니즘**이라 절대 제거 금지. NCDS CDN CSS 는 hover 색상만 정의(`.ncua-tooltip--stroke svg:hover { color: var(--gray-400); }`) — base 색상 SCSS 룰이 존재하지 않으므로 색상은 오직 SVG 의 color attribute 로만 적용된다. 속성 누락 시 SVG 가 부모 텍스트 색상(보통 var(--gray-700) 또는 검정) 을 상속해 의도된 회색 톤보다 너무 진해짐. render_to_html 출력의 `<svg ... color='var(--gray-300)'>` 그대로 사용 — color attribute 제거, 다른 색상으로 변경, currentColor 로 대체 모두 금지. CSS `.ncua-tooltip svg { color: ... }` override 도 금지 (P22 ncua-* override 룰 참고)."
|
|
62
|
+
],
|
|
63
|
+
"fontFamily": [
|
|
64
|
+
"⚠️ P14 — Font-family 정확한 표기는 'CommerceSans' (공백 없음, 따옴표 없어도 됨). 'Commerce Sans' (공백 포함) 는 @font-face 매칭 실패 → 시스템 폰트로 폴백되어 NCDS 표준 미적용. NCDS CDN CSS 는 자체적으로 body 에 CommerceSans 를 깔아주므로, 페이지 SCSS 에서 font-family 를 추가로 선언하지 말 것. 만약 선언이 필요하면 CSS 변수 `var(--font-families-commerce-sans)` 사용 (값: 'CommerceSans', 'Noto Sans KR', 'Apple SD Gothic Neo', sans-serif).",
|
|
65
|
+
"⚠️ P15 — DO NOT declare body { font-family: ... } in page CSS. NCDS CDN CSS already applies CommerceSans to NCUA components. Custom areas (sgr-*, raw <div>) that need explicit font inheritance should use `body { font-family: var(--font-families-commerce-sans); }` OR the inline declaration `font-family: CommerceSans, 'Noto Sans KR', 'Apple SD Gothic Neo', sans-serif` (CommerceSans is ONE token with NO quotes, NO spaces). FORBIDDEN patterns: `font-family: 'Commerce Sans', -apple-system, ...` (quoted+spaced — will NEVER match the @font-face declaration), `font-family: \"Commerce Sans\", ...` (double-quoted spaced — same issue). The @font-face declaration is `@font-face { font-family: CommerceSans; ... }` (one token, no quotes) — CSS font-family lookup is case+space sensitive.",
|
|
66
|
+
"⚠️ P24 — NCDS 페이지의 모든 텍스트는 CommerceSans 폰트를 사용해야 한다 (NCDS 표준). NCUA 컴포넌트 영역은 CDN CSS 가 자동 적용 — 추가 작업 불필요. 그러나 다음 영역에는 font-family 가 누락될 수 있어 명시적 처리 필요: (1) custom area 의 sgr-* / page-prefix 클래스, (2) raw <div> / <span> / <p> 등 NCUA 외부 요소, (3) iframe 내부 콘텐츠. 이 영역에는 **반드시** `var(--font-families-commerce-sans)` 또는 풀 스택 `CommerceSans, 'Noto Sans KR', 'Apple SD Gothic Neo', sans-serif` 사용. 인라인 style 도 동일 — `style=\"font-family: var(--font-families-commerce-sans);\"`. **금지**: 시스템 폰트 폴백만 단독 사용 (`font-family: -apple-system, BlinkMacSystemFont, ...`), 단일 따옴표 + 공백 표기 (`'Commerce Sans'`), 다른 한글 폰트로 대체 ('맑은 고딕', 'Malgun Gothic', '나눔고딕' 등). CommerceSans 부재 시 'Noto Sans KR' 로 fallback 되도록 풀 스택을 그대로 유지하라."
|
|
38
67
|
],
|
|
39
68
|
"customArea": [
|
|
40
69
|
"When building areas not covered by NCUA components, do NOT use the ncua- prefix. Use a unique BEM prefix (e.g. pw-form, order-summary).",
|
|
41
70
|
"Custom areas MUST use ONLY existing NCUA design tokens (CSS variables from CDN) for colors, fonts, spacing, and shadows. Do NOT hardcode hex values like #5B5BD6 or rgb values.",
|
|
42
71
|
"Do NOT invent token names. If no exact token exists, choose the closest available token. Never fall back to raw color/size values.",
|
|
43
72
|
"Before writing custom CSS, call get_design_tokens to see available tokens. Filter by category (color, typography, spacing, shadow) to reduce response size.",
|
|
44
|
-
"For spacing, use spacing tokens (--spacing-xs through --spacing-xxl) instead of hardcoded px values. Follow the principle: inner-block spacing < between-block spacing."
|
|
73
|
+
"For spacing, use spacing tokens (--spacing-xs through --spacing-xxl) instead of hardcoded px values. Follow the principle: inner-block spacing < between-block spacing.",
|
|
74
|
+
"Even inside inline `style=` attributes, spacing properties (gap / padding / margin / min-width / max-width / width / height) MUST use NCDS tokens via `var(--spacing-xs|sm|md|lg|xl|xxl)`. Raw px values like `gap:8px`, `padding:40px`, `min-width:280px` are forbidden in inline style as well. Pure layout properties (display:flex, flex-direction, align-items, justify-content, position) are allowed inline since they have no token equivalent. If a wrapper needs styling beyond pure layout, move it to a page-prefix CSS class in your stylesheet and reference tokens there.",
|
|
75
|
+
"⚠️ P24 — Custom area (sgr-* / page-prefix) 가 텍스트를 노출하면 font-family 도 NCDS 표준(CommerceSans) 으로 명시. CDN CSS 는 ncua-* 컴포넌트에만 폰트를 깔아주므로 custom area 는 inheritance 가 끊길 수 있다. 표준 표기: `font-family: var(--font-families-commerce-sans);` (권장) 또는 풀 스택 `CommerceSans, 'Noto Sans KR', 'Apple SD Gothic Neo', sans-serif`. 자세한 금지/허용 패턴은 fontFamily 섹션 P14/P15/P24 참고."
|
|
45
76
|
],
|
|
46
77
|
"compliance": [
|
|
47
78
|
"After generating HTML, call validate_html to check the compliance score. If compliance.score < 1.0, fix the reported errors and re-validate.",
|
|
@@ -53,5 +84,6 @@
|
|
|
53
84
|
],
|
|
54
85
|
"category": [
|
|
55
86
|
"Component categories follow the design team standard (DES INDEX): action, input, icon, overlay, navigation, feedback, data-display."
|
|
56
|
-
]
|
|
87
|
+
],
|
|
88
|
+
"pingReminder": "IMPORTANT: You have NOT called ping yet. Call ping ONCE before proceeding. Rules: (1) NEVER hardcode hex/rgb colors - use get_design_tokens. (2) NEVER write SVG icons - use search_icon. (3) Use render_to_html or render_to_html_batch for all NCUA components. (4) For custom CSS, prefer NCUA tokens. Call get_design_tokens first. (5) ⚠️ P22 — Call list_composition_overrides ONCE early to see component composition overrides coverage. NEVER claim 'CDN 미제공/gap' for any ncua-* class without first calling render_to_html to verify the actual output. NCDS CDN CSS provides ALL base styles — overriding ncua-* with fallback CSS is FORBIDDEN. DO NOT cite memory entries as authority; current composition overrides + rules.json are the only source of truth."
|
|
57
89
|
}
|
|
@@ -12,6 +12,9 @@
|
|
|
12
12
|
"list_components": {
|
|
13
13
|
"description": "List all available UI components grouped by category. Check this before building any UI to understand what components exist."
|
|
14
14
|
},
|
|
15
|
+
"list_composition_overrides": {
|
|
16
|
+
"description": "Audit NCDS Composition Overrides coverage per component — returns a table-like summary with canonicalExamples scenarios, bemClassesExtra, allowedChildren/Parents, descriptionExtra, aliasesExtra, AND a coverageScore (0.0-1.0) estimating how accurately AI can render that component without hallucination. Response includes per-metric descriptions and the scoring formula. RECOMMENDED first call on a fresh project — high-score components can be rendered with confidence via render_to_html; low-score components need extra caution. After this, dive into details with get_component_props for components you plan to use."
|
|
17
|
+
},
|
|
15
18
|
"search_component": {
|
|
16
19
|
"description": "Search components by Korean/English keyword. Returns name, category, description, aliases."
|
|
17
20
|
},
|
|
@@ -24,19 +27,40 @@
|
|
|
24
27
|
"render_to_html": {
|
|
25
28
|
"description": "Generate exact HTML for an NCUA component with given props. Returns html, appliedProps, defaultsUsed, js, cdn."
|
|
26
29
|
},
|
|
30
|
+
"render_to_html_batch": {
|
|
31
|
+
"description": "Render multiple NCUA components in a single call (max 30). Pass an array of {name, props} objects. Returns an array of render results. Use this instead of calling render_to_html repeatedly when building a page."
|
|
32
|
+
},
|
|
27
33
|
"get_design_tokens": {
|
|
28
34
|
"description": "Get available design tokens (CSS variables) for colors, typography, spacing, and shadows. Use when building custom areas to pick real tokens instead of guessing."
|
|
29
35
|
}
|
|
30
36
|
},
|
|
31
37
|
"capabilities": [
|
|
32
|
-
{ "tool": "ping", "description": "Server health check + version + capabilities/rules" },
|
|
33
|
-
{ "tool": "list_components", "description": "Browse all components by category" },
|
|
34
|
-
{
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
{ "tool": "
|
|
40
|
-
{ "tool": "
|
|
38
|
+
{ "tool": "ping", "description": "Server health check + version + capabilities/rules", "available": true },
|
|
39
|
+
{ "tool": "list_components", "description": "Browse all components by category", "available": true },
|
|
40
|
+
{
|
|
41
|
+
"tool": "list_composition_overrides",
|
|
42
|
+
"description": "Audit composition overrides per component (scenarios + counts)",
|
|
43
|
+
"available": true
|
|
44
|
+
},
|
|
45
|
+
{ "tool": "search_component", "description": "Find components by keyword", "available": true },
|
|
46
|
+
{ "tool": "list_icons", "description": "Browse all available icons", "available": true },
|
|
47
|
+
{ "tool": "search_icon", "description": "Find icons by keyword", "available": true },
|
|
48
|
+
{ "tool": "get_component_props", "description": "Get component props spec", "available": true },
|
|
49
|
+
{
|
|
50
|
+
"tool": "validate_html",
|
|
51
|
+
"description": "Validate HTML BEM classes + design system compliance score + auto-fix",
|
|
52
|
+
"available": true
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
"tool": "render_to_html",
|
|
56
|
+
"description": "Props-based dynamic HTML rendering + icon SVG resolve",
|
|
57
|
+
"available": true
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"tool": "render_to_html_batch",
|
|
61
|
+
"description": "Batch render multiple components in one call (max 30)",
|
|
62
|
+
"available": true
|
|
63
|
+
},
|
|
64
|
+
{ "tool": "get_design_tokens", "description": "Design token (CSS variable) lookup by category", "available": true }
|
|
41
65
|
]
|
|
42
66
|
}
|