@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,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Story 5.10: editor 외부 분기 정의
|
|
3
|
+
*
|
|
4
|
+
* froala 기반 에디터(`@ncds/editor-html`)의 응답 메타·CDN URL·props·cdnDefaults·methods.
|
|
5
|
+
* `tools/external/editor.ts` 의 `buildEditorResponse` 가 본 정의를 읽어 응답 조립.
|
|
6
|
+
* (json 대신 ts — tsconfig `module: Node16` 환경에서 import 단순화. 빌드 시 자동 포함.)
|
|
7
|
+
*/
|
|
8
|
+
export declare const editorDefinition: {
|
|
9
|
+
readonly name: "editor";
|
|
10
|
+
readonly className: "NcdsEditor";
|
|
11
|
+
readonly category: "form";
|
|
12
|
+
readonly description: "froala 기반 WYSIWYG 에디터. textarea 를 in-place 변환.";
|
|
13
|
+
readonly cdn: {
|
|
14
|
+
readonly version: "0.0";
|
|
15
|
+
readonly css: "https://fe-sdk.cdn-nhncommerce.com/@ncds/editor/0.0/ncds-editor.css";
|
|
16
|
+
readonly js: "https://fe-sdk.cdn-nhncommerce.com/@ncds/editor/0.0/ncds-editor.js";
|
|
17
|
+
};
|
|
18
|
+
readonly props: readonly [{
|
|
19
|
+
readonly name: "heightMin";
|
|
20
|
+
readonly type: "number";
|
|
21
|
+
readonly default: 300;
|
|
22
|
+
readonly description: "최소 높이 (px)";
|
|
23
|
+
}, {
|
|
24
|
+
readonly name: "heightMax";
|
|
25
|
+
readonly type: "number";
|
|
26
|
+
readonly default: 600;
|
|
27
|
+
readonly description: "최대 높이 (px)";
|
|
28
|
+
}, {
|
|
29
|
+
readonly name: "heightResize";
|
|
30
|
+
readonly type: "boolean";
|
|
31
|
+
readonly default: false;
|
|
32
|
+
readonly description: "높이 조정 가능 여부";
|
|
33
|
+
}, {
|
|
34
|
+
readonly name: "placeholderText";
|
|
35
|
+
readonly type: "string";
|
|
36
|
+
readonly default: "내용을 입력하세요.";
|
|
37
|
+
readonly description: "플레이스홀더 텍스트";
|
|
38
|
+
}, {
|
|
39
|
+
readonly name: "imageUploadCallback";
|
|
40
|
+
readonly type: "function";
|
|
41
|
+
readonly description: "이미지 업로드 콜백 함수명 (전역 함수). 외부 분기에서 stripFunctionProps 로 자동 제외 — data-* 직렬화 대상 아님";
|
|
42
|
+
}];
|
|
43
|
+
readonly cdnDefaults: {
|
|
44
|
+
heightMin: number;
|
|
45
|
+
heightMax: number;
|
|
46
|
+
heightResize: boolean;
|
|
47
|
+
placeholderText: string;
|
|
48
|
+
};
|
|
49
|
+
readonly methods: readonly ["getHTML()", "setHTML(html)", "getText()", "focus()", "blur()", "enable()", "disable()", "destroy()", "insertImage(src, alt, link)", "insertLink(href, text)", "insertTable(rows, cols)", "on(event, handler)", "off(event)"];
|
|
50
|
+
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Story 5.10: editor 외부 분기 정의
|
|
4
|
+
*
|
|
5
|
+
* froala 기반 에디터(`@ncds/editor-html`)의 응답 메타·CDN URL·props·cdnDefaults·methods.
|
|
6
|
+
* `tools/external/editor.ts` 의 `buildEditorResponse` 가 본 정의를 읽어 응답 조립.
|
|
7
|
+
* (json 대신 ts — tsconfig `module: Node16` 환경에서 import 단순화. 빌드 시 자동 포함.)
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.editorDefinition = void 0;
|
|
11
|
+
exports.editorDefinition = {
|
|
12
|
+
name: 'editor',
|
|
13
|
+
className: 'NcdsEditor',
|
|
14
|
+
category: 'form',
|
|
15
|
+
description: 'froala 기반 WYSIWYG 에디터. textarea 를 in-place 변환.',
|
|
16
|
+
cdn: {
|
|
17
|
+
version: '0.0',
|
|
18
|
+
css: 'https://fe-sdk.cdn-nhncommerce.com/@ncds/editor/0.0/ncds-editor.css',
|
|
19
|
+
js: 'https://fe-sdk.cdn-nhncommerce.com/@ncds/editor/0.0/ncds-editor.js',
|
|
20
|
+
},
|
|
21
|
+
props: [
|
|
22
|
+
{ name: 'heightMin', type: 'number', default: 300, description: '최소 높이 (px)' },
|
|
23
|
+
{ name: 'heightMax', type: 'number', default: 600, description: '최대 높이 (px)' },
|
|
24
|
+
{ name: 'heightResize', type: 'boolean', default: false, description: '높이 조정 가능 여부' },
|
|
25
|
+
{ name: 'placeholderText', type: 'string', default: '내용을 입력하세요.', description: '플레이스홀더 텍스트' },
|
|
26
|
+
{
|
|
27
|
+
name: 'imageUploadCallback',
|
|
28
|
+
type: 'function',
|
|
29
|
+
description: '이미지 업로드 콜백 함수명 (전역 함수). 외부 분기에서 stripFunctionProps 로 자동 제외 — data-* 직렬화 대상 아님',
|
|
30
|
+
},
|
|
31
|
+
],
|
|
32
|
+
cdnDefaults: {
|
|
33
|
+
heightMin: 300,
|
|
34
|
+
heightMax: 600,
|
|
35
|
+
heightResize: false,
|
|
36
|
+
placeholderText: '내용을 입력하세요.',
|
|
37
|
+
},
|
|
38
|
+
methods: [
|
|
39
|
+
'getHTML()',
|
|
40
|
+
'setHTML(html)',
|
|
41
|
+
'getText()',
|
|
42
|
+
'focus()',
|
|
43
|
+
'blur()',
|
|
44
|
+
'enable()',
|
|
45
|
+
'disable()',
|
|
46
|
+
'destroy()',
|
|
47
|
+
'insertImage(src, alt, link)',
|
|
48
|
+
'insertLink(href, text)',
|
|
49
|
+
'insertTable(rows, cols)',
|
|
50
|
+
'on(event, handler)',
|
|
51
|
+
'off(event)',
|
|
52
|
+
],
|
|
53
|
+
};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Story 6.1: step-guide 외부 분기 정의
|
|
3
|
+
*
|
|
4
|
+
* vanilla JS 함수 기반 step-by-step 가이드 투어(`step-guide`)의 응답 메타·CDN URL·props·cdnDefaults·methods.
|
|
5
|
+
* `tools/external/step-guide.ts`의 `buildStepGuideResponse`가 본 정의를 읽어 응답 조립.
|
|
6
|
+
* 5-10 editor 패턴 답습 — 단, step-guide는 함수 호출(`window.stepGuide({el, options})`) 형식.
|
|
7
|
+
* (json 대신 ts — tsconfig `module: Node16` 환경에서 import 단순화. 빌드 시 자동 포함.)
|
|
8
|
+
*/
|
|
9
|
+
export declare const stepGuideDefinition: {
|
|
10
|
+
readonly name: "step-guide";
|
|
11
|
+
readonly exportName: "stepGuide";
|
|
12
|
+
readonly category: "overlays";
|
|
13
|
+
readonly description: "vanilla JS 함수 기반 step-by-step 가이드 투어. CDN 로드 후 window.stepGuide({el, options}) 호출.";
|
|
14
|
+
readonly cdn: {
|
|
15
|
+
readonly version: "2.0";
|
|
16
|
+
readonly css: "https://fe-sdk.cdn-nhncommerce.com/@ncds/step-guide/2.0/step-guide.min.css";
|
|
17
|
+
readonly js: "https://fe-sdk.cdn-nhncommerce.com/@ncds/step-guide/2.0/step-guide.min.js";
|
|
18
|
+
};
|
|
19
|
+
readonly props: readonly [{
|
|
20
|
+
readonly name: "steps";
|
|
21
|
+
readonly type: "Step[]";
|
|
22
|
+
readonly required: true;
|
|
23
|
+
readonly description: "단계 배열";
|
|
24
|
+
}, {
|
|
25
|
+
readonly name: "useAnimation";
|
|
26
|
+
readonly type: "boolean";
|
|
27
|
+
readonly default: true;
|
|
28
|
+
readonly description: "애니메이션 사용 여부";
|
|
29
|
+
}, {
|
|
30
|
+
readonly name: "buttonLabel";
|
|
31
|
+
readonly type: "{ prev, next, done, skip }";
|
|
32
|
+
readonly description: "버튼 라벨 (v2 default: 이전/다음/완료/나중에 하기)";
|
|
33
|
+
}, {
|
|
34
|
+
readonly name: "hideSkip";
|
|
35
|
+
readonly type: "boolean";
|
|
36
|
+
readonly default: true;
|
|
37
|
+
readonly description: "스킵 버튼 숨김 여부";
|
|
38
|
+
}, {
|
|
39
|
+
readonly name: "hideStepCount";
|
|
40
|
+
readonly type: "boolean";
|
|
41
|
+
readonly default: true;
|
|
42
|
+
readonly description: "스텝 카운트 숨김 여부";
|
|
43
|
+
}, {
|
|
44
|
+
readonly name: "hideStepPrefix";
|
|
45
|
+
readonly type: "boolean";
|
|
46
|
+
readonly default: false;
|
|
47
|
+
readonly description: "STEP N prefix 숨김 여부. 단계 1개일 때는 옵션과 무관하게 자동 생략";
|
|
48
|
+
}, {
|
|
49
|
+
readonly name: "exitOnOverlayClick";
|
|
50
|
+
readonly type: "boolean";
|
|
51
|
+
readonly default: true;
|
|
52
|
+
readonly description: "오버레이 클릭 시 종료 여부";
|
|
53
|
+
}];
|
|
54
|
+
readonly cdnDefaults: {
|
|
55
|
+
useAnimation: boolean;
|
|
56
|
+
hideSkip: boolean;
|
|
57
|
+
hideStepCount: boolean;
|
|
58
|
+
exitOnOverlayClick: boolean;
|
|
59
|
+
};
|
|
60
|
+
readonly methods: readonly ["goToStep(index)", "previousStep(e)", "nextStep(e)", "onChange(callback)", "onExit(callback)", "exit(e)"];
|
|
61
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Story 6.1: step-guide 외부 분기 정의
|
|
4
|
+
*
|
|
5
|
+
* vanilla JS 함수 기반 step-by-step 가이드 투어(`step-guide`)의 응답 메타·CDN URL·props·cdnDefaults·methods.
|
|
6
|
+
* `tools/external/step-guide.ts`의 `buildStepGuideResponse`가 본 정의를 읽어 응답 조립.
|
|
7
|
+
* 5-10 editor 패턴 답습 — 단, step-guide는 함수 호출(`window.stepGuide({el, options})`) 형식.
|
|
8
|
+
* (json 대신 ts — tsconfig `module: Node16` 환경에서 import 단순화. 빌드 시 자동 포함.)
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.stepGuideDefinition = void 0;
|
|
12
|
+
exports.stepGuideDefinition = {
|
|
13
|
+
name: 'step-guide',
|
|
14
|
+
exportName: 'stepGuide', // CDN UMD default export = 함수 (소문자, class 아님)
|
|
15
|
+
category: 'overlays',
|
|
16
|
+
description: 'vanilla JS 함수 기반 step-by-step 가이드 투어. CDN 로드 후 window.stepGuide({el, options}) 호출.',
|
|
17
|
+
cdn: {
|
|
18
|
+
version: '2.0',
|
|
19
|
+
css: 'https://fe-sdk.cdn-nhncommerce.com/@ncds/step-guide/2.0/step-guide.min.css',
|
|
20
|
+
js: 'https://fe-sdk.cdn-nhncommerce.com/@ncds/step-guide/2.0/step-guide.min.js',
|
|
21
|
+
},
|
|
22
|
+
props: [
|
|
23
|
+
{ name: 'steps', type: 'Step[]', required: true, description: '단계 배열' },
|
|
24
|
+
{ name: 'useAnimation', type: 'boolean', default: true, description: '애니메이션 사용 여부' },
|
|
25
|
+
{
|
|
26
|
+
name: 'buttonLabel',
|
|
27
|
+
type: '{ prev, next, done, skip }',
|
|
28
|
+
description: '버튼 라벨 (v2 default: 이전/다음/완료/나중에 하기)',
|
|
29
|
+
},
|
|
30
|
+
{ name: 'hideSkip', type: 'boolean', default: true, description: '스킵 버튼 숨김 여부' },
|
|
31
|
+
{ name: 'hideStepCount', type: 'boolean', default: true, description: '스텝 카운트 숨김 여부' },
|
|
32
|
+
{
|
|
33
|
+
name: 'hideStepPrefix',
|
|
34
|
+
type: 'boolean',
|
|
35
|
+
default: false,
|
|
36
|
+
description: 'STEP N prefix 숨김 여부. 단계 1개일 때는 옵션과 무관하게 자동 생략',
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
name: 'exitOnOverlayClick',
|
|
40
|
+
type: 'boolean',
|
|
41
|
+
default: true,
|
|
42
|
+
description: '오버레이 클릭 시 종료 여부',
|
|
43
|
+
},
|
|
44
|
+
],
|
|
45
|
+
cdnDefaults: {
|
|
46
|
+
useAnimation: true,
|
|
47
|
+
hideSkip: true,
|
|
48
|
+
hideStepCount: true,
|
|
49
|
+
exitOnOverlayClick: true,
|
|
50
|
+
},
|
|
51
|
+
methods: ['goToStep(index)', 'previousStep(e)', 'nextStep(e)', 'onChange(callback)', 'onExit(callback)', 'exit(e)'],
|
|
52
|
+
};
|
|
@@ -2,12 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
You are an agent that builds UI using NCUA (NCDS UI Admin) design system components from NHN Commerce.
|
|
4
4
|
|
|
5
|
-
## Absolute Rules
|
|
5
|
+
## Absolute Rules (VIOLATION = CRITICAL FAILURE)
|
|
6
6
|
|
|
7
|
-
1.
|
|
8
|
-
2.
|
|
9
|
-
3.
|
|
10
|
-
4.
|
|
7
|
+
1. Call ping ONCE at the start of every session before using any other tool. This loads version info and usage rules.
|
|
8
|
+
2. NEVER define or guess NCUA CSS variables (--ncua-\*). NCUA component styles are controlled by CDN CSS only.
|
|
9
|
+
3. NEVER write SVG icons or icon markup manually. ALL icons MUST come from search_icon or list_icons. If you write a single svg tag by hand, you have FAILED.
|
|
10
|
+
4. NEVER use emoji in generated HTML, CSS, or any output. No exceptions.
|
|
11
|
+
5. You MUST generate NCUA component HTML using render_to_html or render_to_html_batch only. Never write component HTML/CSS manually.
|
|
12
|
+
6. If an NCUA component exists for the use case, you MUST use it. Do NOT recreate it manually.
|
|
13
|
+
7. For custom areas, call get_design_tokens FIRST and prefer NCUA tokens for colors, spacing, typography, and shadows to maintain visual consistency. If no suitable token exists, you may use standard CSS values (hex, rgb, px).
|
|
11
14
|
|
|
12
15
|
## Required Workflow (follow this order strictly)
|
|
13
16
|
|
|
@@ -27,30 +30,62 @@ You are an agent that builds UI using NCUA (NCDS UI Admin) design system compone
|
|
|
27
30
|
|
|
28
31
|
### Step 1: Component Discovery
|
|
29
32
|
|
|
33
|
+
- Call **list_components** first to see all available components and their categories. This prevents reinventing components that already exist.
|
|
30
34
|
- Use **search_component** with Korean/English keywords to find the right component
|
|
31
35
|
- Example: "비밀번호" → password-input, "모달" → modal
|
|
32
36
|
- **IMPORTANT**: input is for plain text only. For passwords, always use password-input.
|
|
33
37
|
|
|
34
38
|
### Step 2: Props Check
|
|
35
39
|
|
|
36
|
-
- Use **get_component_props** to see available properties
|
|
40
|
+
- Use **get_component_props** to see available properties BEFORE calling render_to_html.
|
|
37
41
|
- Pass all required props. Choose enum values only from the allowed list.
|
|
42
|
+
- Check `type: "object"` props carefully — they often expect arrays or structured objects. Read the `rawType` field for the actual TypeScript type.
|
|
43
|
+
- For icon props (`leadingIcon`, `trailingIcon`, `icon`), pass `{ type: "icon", icon: "IconName" }` where IconName is a PascalCase name from search_icon.
|
|
38
44
|
|
|
39
45
|
### Step 3: HTML Generation
|
|
40
46
|
|
|
41
|
-
-
|
|
47
|
+
- When building a page with multiple components, use **render_to_html_batch** to render them all in one call (max 30). This is much more efficient than calling render_to_html repeatedly.
|
|
48
|
+
- For a single component, use **render_to_html**.
|
|
42
49
|
- Use the returned html as-is. Do NOT modify class names, structure, or attributes.
|
|
50
|
+
- Check the `warnings` field in the response — it reports invalid enum values and missing required props.
|
|
51
|
+
- **If render returns empty or minimal HTML**, the component likely needs data props (e.g. `menus` for HorizontalTab, `items` for BreadCrumb). Check get_component_props and retry with proper data.
|
|
52
|
+
- **Empty result recovery** (max 3 attempts):
|
|
53
|
+
1. Call get_component_props to identify required/data props
|
|
54
|
+
2. Retry render_to_html with meaningful prop values
|
|
55
|
+
3. If still empty after 3 attempts, report the issue to the user
|
|
43
56
|
|
|
44
|
-
### Step 4: CDN
|
|
57
|
+
### Step 4: CDN & JS Initialization
|
|
45
58
|
|
|
46
59
|
- Get CSS/JS URLs from the **cdn** field in the render_to_html response
|
|
47
|
-
- Include them in
|
|
48
|
-
- When **js.required is true
|
|
60
|
+
- Include them in `<head>`/`<body>` of the final HTML
|
|
61
|
+
- When **js.required is true**:
|
|
62
|
+
1. Include the CDN JS `<script>` tag — this is mandatory
|
|
63
|
+
2. Check the **js.api** field — it contains the initialization code pattern
|
|
64
|
+
3. Write a `<script>` block that initializes the component using `js.api.constructor` and `js.api.constructorParams`
|
|
65
|
+
4. Use `js.api.example` as a reference for the initialization code
|
|
66
|
+
5. Common pattern: `new window.ncua.ClassName(element, options)` — called after DOMContentLoaded
|
|
67
|
+
|
|
68
|
+
Example: DatePicker with JS initialization:
|
|
69
|
+
|
|
70
|
+
```html
|
|
71
|
+
<script>
|
|
72
|
+
document.addEventListener('DOMContentLoaded', function () {
|
|
73
|
+
// js.api.constructor: new window.ncua.DatePicker(wrapper, options)
|
|
74
|
+
// js.api.constructorParams shows required params
|
|
75
|
+
new window.ncua.DatePicker(document.getElementById('my-datepicker'), {
|
|
76
|
+
datePickerOptions: [{ element: 'start-date', options: { dateFormat: 'Y-m-d' } }],
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
</script>
|
|
80
|
+
```
|
|
49
81
|
|
|
50
82
|
### Step 5: Composition
|
|
51
83
|
|
|
52
84
|
- Combine render_to_html results to build the final page
|
|
53
85
|
- Do NOT modify NCUA component styles
|
|
86
|
+
- Apply spacing between components using NCUA design tokens: call **get_design_tokens** with category "spacing" to get available spacing values (e.g. var(--spacing-4), var(--spacing-8))
|
|
87
|
+
- When deciding component size or hierarchy, document your reasoning in an HTML comment (e.g. `<!-- size:sm chosen for compact sidebar layout -->`)
|
|
88
|
+
- If a commerce-rag MCP server is available, query it for page layout patterns and spacing guidelines specific to the project
|
|
54
89
|
|
|
55
90
|
## Building Custom Areas (not covered by NCUA)
|
|
56
91
|
|
|
@@ -86,6 +121,21 @@ After composing the final HTML, validate design system compliance:
|
|
|
86
121
|
|
|
87
122
|
**Note:** `compliance.score` is independent from `valid`. `valid=true` with `score<1.0` means BEM classes are correct but design system usage can be improved.
|
|
88
123
|
|
|
124
|
+
## Props Usage Guide
|
|
125
|
+
|
|
126
|
+
When calling `get_component_props`, the response includes:
|
|
127
|
+
|
|
128
|
+
- `props`: Full props specification with types, defaults, and allowed values
|
|
129
|
+
- `usageExamples` (if available): Ready-to-use props objects for `render_to_html`
|
|
130
|
+
|
|
131
|
+
For components with complex object/array props (e.g., dropdown, range-date-picker), always check `usageExamples` first. Copy the example and modify values as needed — this avoids required prop omission errors.
|
|
132
|
+
|
|
133
|
+
If you call `render_to_html` with missing required props:
|
|
134
|
+
|
|
135
|
+
- The server auto-fills safe defaults (empty string, empty array, etc.) to prevent crashes
|
|
136
|
+
- `warnings` field lists what was missing and what was auto-filled
|
|
137
|
+
- The rendered HTML may be incomplete — check warnings and retry with proper values
|
|
138
|
+
|
|
89
139
|
## Component Selection Guide
|
|
90
140
|
|
|
91
141
|
- Password → **password-input** (never use input)
|
|
@@ -93,4 +143,138 @@ After composing the final HTML, validate design system compliance:
|
|
|
93
143
|
- File upload → **file-input**
|
|
94
144
|
- Image upload → **image-file-input**
|
|
95
145
|
- Plain text → **input**
|
|
146
|
+
- Dropdown/Select → **select-box** (default choice for all dropdown selections). Use **select** only when native HTML select is explicitly required (e.g., react-hook-form direct binding)
|
|
147
|
+
- Searchable dropdown → **combo-box**
|
|
148
|
+
- Custom trigger dropdown → **dropdown**
|
|
149
|
+
- Date single → **date-picker**
|
|
150
|
+
- Date range → **range-date-picker**
|
|
151
|
+
- Date range with period buttons → **range-date-picker-with-buttons**
|
|
96
152
|
- Each component's description includes usage guidance and alternatives.
|
|
153
|
+
|
|
154
|
+
### Icon Usage
|
|
155
|
+
|
|
156
|
+
Icons are rendered as inline SVG by the MCP server — NOT via CDN JS or custom tags. There is NO `<ncua-icon>` tag.
|
|
157
|
+
|
|
158
|
+
- Use `search_icon` to find icon names (PascalCase, e.g., "RefreshCw01", "SearchLg", "ChevronDown")
|
|
159
|
+
- Pass icon names to component props via `render_to_html`:
|
|
160
|
+
- Button leadingIcon/trailingIcon: `{ "type": "icon", "icon": "RefreshCw01" }`
|
|
161
|
+
- FeaturedIcon icon: `"CheckCircle"` (bare string)
|
|
162
|
+
- The server resolves icon names to actual SVG at render time
|
|
163
|
+
- NEVER write `<ncua-icon>`, `<svg>`, or emoji. If you need a standalone icon, use **featured-icon** component
|
|
164
|
+
|
|
165
|
+
Example — Button with icon:
|
|
166
|
+
|
|
167
|
+
```json
|
|
168
|
+
{
|
|
169
|
+
"name": "button",
|
|
170
|
+
"props": {
|
|
171
|
+
"label": "Refresh",
|
|
172
|
+
"leadingIcon": { "type": "icon", "icon": "RefreshCw01" }
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### Children Composition
|
|
178
|
+
|
|
179
|
+
When a component needs child components (e.g., ButtonGroup with Buttons, Modal with form elements), pass children as component descriptors:
|
|
180
|
+
|
|
181
|
+
```json
|
|
182
|
+
{
|
|
183
|
+
"name": "button-group",
|
|
184
|
+
"props": {
|
|
185
|
+
"children": [
|
|
186
|
+
{ "component": "button", "props": { "label": "Save", "hierarchy": "primary" } },
|
|
187
|
+
{ "component": "button", "props": { "label": "Cancel" } }
|
|
188
|
+
]
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
This works recursively — children can contain their own children up to 5 levels deep.
|
|
194
|
+
|
|
195
|
+
### Compound Components (dot notation)
|
|
196
|
+
|
|
197
|
+
Some components have sub-components accessed via dot notation. Use `"parent.sub"` format:
|
|
198
|
+
|
|
199
|
+
- `modal.header` — Modal header with title and close button
|
|
200
|
+
- `modal.content` — Modal body content area
|
|
201
|
+
- `modal.actions` — Modal footer with action buttons
|
|
202
|
+
|
|
203
|
+
Example — Modal with full structure:
|
|
204
|
+
|
|
205
|
+
```json
|
|
206
|
+
{
|
|
207
|
+
"name": "modal",
|
|
208
|
+
"props": { "isOpen": true, "size": "md" },
|
|
209
|
+
"children": [
|
|
210
|
+
{ "component": "modal.header", "props": { "title": "Product Detail", "align": "left" } },
|
|
211
|
+
{
|
|
212
|
+
"component": "modal.content",
|
|
213
|
+
"children": [{ "component": "input-base", "props": { "placeholder": "Product name" } }]
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
"component": "modal.actions",
|
|
217
|
+
"props": { "layout": "horizontal", "align": "stretch" },
|
|
218
|
+
"children": [
|
|
219
|
+
{ "component": "button", "props": { "label": "Cancel", "hierarchy": "secondary-gray", "size": "sm" } },
|
|
220
|
+
{ "component": "button", "props": { "label": "Confirm", "hierarchy": "primary", "size": "sm" } }
|
|
221
|
+
]
|
|
222
|
+
}
|
|
223
|
+
]
|
|
224
|
+
}
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
Always check `usageExamples` in `get_component_props` for compound component patterns. You can freely omit or reorder sub-components to customize the layout.
|
|
228
|
+
|
|
229
|
+
`get_component_props` on a compound parent (e.g. `modal`, `button-group`) also returns a `subComponents` field:
|
|
230
|
+
|
|
231
|
+
```json
|
|
232
|
+
{
|
|
233
|
+
"props": { "isOpen": {...}, "size": {...}, ... },
|
|
234
|
+
"subComponents": {
|
|
235
|
+
"Modal.Header": { "props": { "title": {...}, "align": {...}, "featuredIcon": {...} } },
|
|
236
|
+
"Modal.Content": { "props": { "children": {...}, "className": {...} } },
|
|
237
|
+
"Modal.Actions": { "props": { "layout": {...}, "align": {...} } }
|
|
238
|
+
},
|
|
239
|
+
"usageExamples": { ... }
|
|
240
|
+
}
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
Use `subComponents[parent.sub].props` to learn valid props (types, enums, defaults) for each sub-component without calling `get_component_props` again. This prevents recursive tool calls when composing compound components.
|
|
244
|
+
|
|
245
|
+
## Rules Schema
|
|
246
|
+
|
|
247
|
+
The `rules` array in ping response is a flat list of strings grouped by category. Categories:
|
|
248
|
+
|
|
249
|
+
| Category | Purpose |
|
|
250
|
+
| ------------------ | -------------------------------------------------- |
|
|
251
|
+
| workflow | Required tool call order and HTML generation rules |
|
|
252
|
+
| componentSelection | Which component to use for each use case |
|
|
253
|
+
| version | MCP↔project version comparison rules |
|
|
254
|
+
| cdn | CDN CSS/JS inclusion rules |
|
|
255
|
+
| react | React-specific package and import rules |
|
|
256
|
+
| forbidden | Actions that must never be performed |
|
|
257
|
+
| customArea | Rules for building areas not covered by NCUA |
|
|
258
|
+
| compliance | validate_html self-correction loop rules |
|
|
259
|
+
| category | Component category naming standard |
|
|
260
|
+
|
|
261
|
+
## Error Response Format
|
|
262
|
+
|
|
263
|
+
All tool errors follow a consistent JSON structure:
|
|
264
|
+
|
|
265
|
+
```json
|
|
266
|
+
{ "code": "ERROR_CODE", "message": "Human-readable description", "suggestion": "What to do next" }
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
Error codes:
|
|
270
|
+
|
|
271
|
+
| Code | When |
|
|
272
|
+
| ----------------------- | -------------------------------------------------------------------- |
|
|
273
|
+
| COMPONENT_NOT_FOUND | Component name does not exist |
|
|
274
|
+
| EXPORT_NAME_MISSING | Component data is corrupted — re-extract needed |
|
|
275
|
+
| COMPONENT_NOT_IN_BUNDLE | Component exists in data but not in runtime bundle — re-build needed |
|
|
276
|
+
| RENDER_FAILED | React rendering threw an error — check props |
|
|
277
|
+
| INVALID_TOKEN_CATEGORY | get_design_tokens called with unknown category |
|
|
278
|
+
| ICON_NOT_FOUND | Icon name does not exist in the icon library |
|
|
279
|
+
| INVALID_PARAMS | Tool called with invalid or missing parameters |
|
|
280
|
+
| INTERNAL_ERROR | Unexpected server error |
|