@ncds/ui-admin-mcp 1.0.0-alpha.18 → 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.
Files changed (39) hide show
  1. package/bin/components.bundle.js +8 -8
  2. package/bin/definitions/js-api.json +39 -4
  3. package/bin/definitions/rules.json +33 -3
  4. package/bin/definitions/tool-definitions.json +8 -0
  5. package/bin/overrides/composition.json +2500 -0
  6. package/bin/server.js +6 -1
  7. package/bin/tools/getComponentProps.js +5 -0
  8. package/bin/tools/listCompositionOverrides.d.ts +61 -0
  9. package/bin/tools/listCompositionOverrides.js +156 -0
  10. package/bin/tools/renderToHtml.d.ts +14 -0
  11. package/bin/tools/renderToHtml.js +128 -24
  12. package/bin/tools/validateHtml.js +68 -0
  13. package/bin/types.d.ts +30 -0
  14. package/bin/utils/bemValidator.d.ts +7 -1
  15. package/bin/utils/dataLoader.d.ts +31 -5
  16. package/bin/utils/dataLoader.js +97 -5
  17. package/bin/version.d.ts +1 -1
  18. package/bin/version.js +1 -1
  19. package/data/badge-group.json +3 -3
  20. package/data/badge.json +2 -2
  21. package/data/bread-crumb.json +1 -1
  22. package/data/button.json +2 -2
  23. package/data/combo-box.json +11 -3
  24. package/data/date-picker.json +1 -1
  25. package/data/dropdown.json +5 -5
  26. package/data/empty-state.json +3 -3
  27. package/data/horizontal-tab.json +4 -4
  28. package/data/modal.json +1 -1
  29. package/data/notification.json +6 -1
  30. package/data/page-title.json +1 -1
  31. package/data/progress-bar.json +1 -1
  32. package/data/range-date-picker-with-buttons.json +4 -4
  33. package/data/range-date-picker.json +4 -4
  34. package/data/select-box.json +11 -3
  35. package/data/select.json +2 -2
  36. package/data/tag.json +1 -1
  37. package/data/tooltip.json +9 -0
  38. package/data/vertical-tab.json +5 -5
  39. package/package.json +2 -2
package/bin/types.d.ts CHANGED
@@ -15,6 +15,24 @@ export interface ComponentUsage {
15
15
  import: string;
16
16
  react: Record<string, string>;
17
17
  }
18
+ /** P8: allowedChildren 의 구조화 객체 형태 (P5-2).
19
+ * - required: 부모 안에 반드시 있어야 하는 자식
20
+ * - recommended: 강력히 권장 (없어도 통과)
21
+ * - optional: 선택적 (사용자 명시 요청 시만)
22
+ * - forbiddenInContext: { childKey: reason } — 이름은 valid 컴포넌트지만 이 부모 안에서는 사용 금지 + 대체 슬롯 안내 */
23
+ export interface AllowedChildrenSpec {
24
+ required?: string[];
25
+ recommended?: string[];
26
+ optional?: string[];
27
+ forbiddenInContext?: Record<string, string>;
28
+ }
29
+ /** P8: canonicalExamples 다중 시나리오 맵의 단일 항목 (P5-1). */
30
+ export interface CanonicalExampleEntry {
31
+ /** 시나리오 한 줄 설명. AI 가 어떤 시나리오를 선택할지 판단에 사용. */
32
+ description?: string;
33
+ /** render_to_html 입력으로 그대로 사용 가능한 props 트리. */
34
+ props: Record<string, unknown>;
35
+ }
18
36
  export interface ComponentData {
19
37
  name: string;
20
38
  exportName: string;
@@ -37,6 +55,18 @@ export interface ComponentData {
37
55
  subComponents?: Record<string, {
38
56
  props: Record<string, PropSpec>;
39
57
  }>;
58
+ /** P8: Composition Overrides (`src/overrides/composition.json`) 에서 병합되는 부모-자식 제약.
59
+ * 키는 컴포넌트 자체("DataGrid") 또는 서브("DataGrid.Table") PascalCase.
60
+ * 값은 단순 배열 (legacy) 또는 구조화 객체 (required/recommended/optional/forbiddenInContext) 모두 허용. */
61
+ allowedChildren?: Record<string, string[] | AllowedChildrenSpec>;
62
+ /** P8: composition overrides 에서 병합되는 허용 부모. */
63
+ allowedParents?: Record<string, string[]>;
64
+ /** P8: composition overrides 에서 병합되는 canonical 단일 시나리오 (legacy P1-6 호환). */
65
+ canonicalExample?: {
66
+ props: Record<string, unknown>;
67
+ };
68
+ /** P8: composition overrides 에서 병합되는 canonical 다중 시나리오 맵 (P5-1). 키는 시나리오 식별자. */
69
+ canonicalExamples?: Record<string, CanonicalExampleEntry>;
40
70
  html?: Record<string, string>;
41
71
  bemClasses: string[];
42
72
  usage: ComponentUsage;
@@ -7,7 +7,13 @@ import type { parse } from 'node-html-parser';
7
7
  import type { ComponentData } from '../types.js';
8
8
  import type { CdnMeta } from './dataLoader.js';
9
9
  interface ValidationError {
10
- type: 'invalid_modifier' | 'invalid_element' | 'unknown_component' | 'missing_root_class' | 'mixed_namespace' | 'missing_cdn';
10
+ type: 'invalid_modifier' | 'invalid_element' | 'unknown_component' | 'missing_root_class' | 'mixed_namespace' | 'missing_cdn'
11
+ /** P13: Vertical Table 안에서 horizontal 전용 `ncua-table__header-cell` 사용 */
12
+ | 'vertical_uses_horizontal_header_cell'
13
+ /** P13: Vertical/Horizontal Table 안 `<tr>` 에 `ncua-table__row` 클래스 누락 */
14
+ | 'missing_table_row_class'
15
+ /** P13: 페이지 prefix `*-required` 클래스로 필수 마크 자체 작성 (ncua-table__required 사용 권장) */
16
+ | 'custom_required_mark';
11
17
  class: string;
12
18
  component: string;
13
19
  message: string;
@@ -1,6 +1,29 @@
1
1
  import type { ComplianceRulesData, ComponentData, IconData, JsApiInfo, TokenData } from '../types.js';
2
2
  declare const DEFAULT_DATA_DIR: string;
3
- interface CdnMeta {
3
+ interface CompositionEntry {
4
+ bemClassesExtra?: string[];
5
+ /** P5-2: 단순 배열 (legacy) 또는 구조화 객체 모두 허용 */
6
+ allowedChildren?: Record<string, string[] | import('../types.js').AllowedChildrenSpec>;
7
+ allowedParents?: Record<string, string[]>;
8
+ /** P1-6 legacy 단일 시나리오 */
9
+ canonicalExample?: {
10
+ props: Record<string, unknown>;
11
+ };
12
+ /** P5-1 다중 시나리오 맵 */
13
+ canonicalExamples?: Record<string, import('../types.js').CanonicalExampleEntry>;
14
+ /** P13: 컴포넌트 description 끝에 append (메타 보강). list_components / search_component 응답 개선용. */
15
+ descriptionExtra?: string;
16
+ /** P13: 컴포넌트 aliases 와 union (중복 제거). search_component 별칭 보강. */
17
+ aliasesExtra?: string[];
18
+ /**
19
+ * coverageScore 분모에서 제외할 보강 영역 목록 — 구조상 채울 수 없는 영역을 선언.
20
+ * 예: extract 가 BEM 클래스를 완전히 잡는 컴포넌트는 ["bemClassesExtra"] 선언 → 분모 0.10 차감 → 달성 가능한 나머지 영역만 채우면 1.0 달성.
21
+ * compound/non-compound 구조적 제외(allowedChildren)와 union 되어 최종 notApplicable 결정.
22
+ */
23
+ notApplicableAreas?: string[];
24
+ }
25
+ declare const loadCompositionOverrides: () => Record<string, CompositionEntry>;
26
+ export interface CdnMeta {
4
27
  version: string;
5
28
  css: string;
6
29
  js: string;
@@ -9,8 +32,11 @@ interface IconMeta {
9
32
  packageName: string;
10
33
  version: string;
11
34
  }
12
- /** data/ 디렉토리의 JSON 파일을 읽어 componentMap으로 반환 */
13
- declare const loadComponentsFromDir: (dataDir: string) => Map<string, ComponentData>;
35
+ /** data/ 디렉토리의 JSON 파일을 읽어 componentMap + compositionOverrides로 반환 */
36
+ declare const loadComponentsFromDir: (dataDir: string) => {
37
+ map: Map<string, ComponentData>;
38
+ compositionOverrides: Record<string, CompositionEntry>;
39
+ };
14
40
  /** data/_icons.json을 읽어 IconData로 반환 (파일 없으면 빈 데이터) */
15
41
  declare const loadIconData: (dataDir: string) => IconData;
16
42
  /** _meta.json 파싱 결과 */
@@ -32,5 +58,5 @@ declare const loadJsApi: (definitionsDir: string) => Map<string, JsApiInfo>;
32
58
  declare const getComponent: (map: Map<string, ComponentData>, name: string) => ComponentData | undefined;
33
59
  /** componentMap의 모든 컴포넌트를 배열로 반환 */
34
60
  declare const getAllComponents: (map: Map<string, ComponentData>) => ComponentData[];
35
- export { DEFAULT_DATA_DIR, getAllComponents, getComponent, loadComplianceRules, loadComponentsFromDir, loadIconData, loadInstructions, loadJsApi, loadMeta, loadTokenData, };
36
- export type { CdnMeta, IconMeta, MetaData };
61
+ export { DEFAULT_DATA_DIR, getAllComponents, getComponent, loadComplianceRules, loadCompositionOverrides, loadComponentsFromDir, loadIconData, loadInstructions, loadJsApi, loadMeta, loadTokenData, };
62
+ export type { CompositionEntry, IconMeta, MetaData };
@@ -3,15 +3,15 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.loadTokenData = exports.loadMeta = exports.loadJsApi = exports.loadInstructions = exports.loadIconData = exports.loadComponentsFromDir = exports.loadComplianceRules = exports.getComponent = exports.getAllComponents = exports.DEFAULT_DATA_DIR = void 0;
6
+ exports.loadTokenData = exports.loadMeta = exports.loadJsApi = exports.loadInstructions = exports.loadIconData = exports.loadComponentsFromDir = exports.loadCompositionOverrides = exports.loadComplianceRules = exports.getComponent = exports.getAllComponents = exports.DEFAULT_DATA_DIR = void 0;
7
7
  /**
8
8
  * dataLoader — mcp/data/*.json + definitions/ 파일을 읽어 반환
9
9
  *
10
10
  * 함수 분류:
11
- * loadComponentsFromDir, loadIconData, loadCdnMeta, loadInstructions → 부수효과 (fs I/O)
11
+ * loadComponentsFromDir, loadCompositionOverrides, loadIconData, loadCdnMeta, loadInstructions → 부수효과 (fs I/O)
12
12
  * getComponent, getAllComponents → 순수 함수 (Map 조회)
13
13
  *
14
- * Map 소유권은 server.ts가 가진다. 이 파일은 상태를 보유하지 않는다.
14
+ * Map + 메타데이터 소유권은 server.ts가 가진다. 이 파일은 상태를 보유하지 않는다.
15
15
  */
16
16
  const fs_1 = __importDefault(require("fs"));
17
17
  const path_1 = __importDefault(require("path"));
@@ -19,13 +19,100 @@ const logger_js_1 = require("./logger.js");
19
19
  const response_js_1 = require("./response.js");
20
20
  const DEFAULT_DATA_DIR = path_1.default.resolve(__dirname, '../../data');
21
21
  exports.DEFAULT_DATA_DIR = DEFAULT_DATA_DIR;
22
+ /**
23
+ * P8: Composition Overrides 위치.
24
+ * extract-mcp-data.ts 가 만드는 data/*.json 위에 컴포넌트 디렉토리를 건드리지 않고
25
+ * allowedChildren / allowedParents / canonicalExample / canonicalExamples / bemClassesExtra 를
26
+ * 추가하는 단일 채널.
27
+ *
28
+ * 빌드 산출물(bin/) 에서는 src/overrides 가 build:server 단계에서 복사되지 않을 수 있으므로
29
+ * src 와 bin 양쪽을 fallback 으로 본다.
30
+ */
31
+ const COMPOSITION_OVERRIDES_CANDIDATES = [
32
+ path_1.default.resolve(__dirname, '../../src/overrides/composition.json'),
33
+ path_1.default.resolve(__dirname, '../overrides/composition.json'),
34
+ ];
35
+ /** composition.json 파일에서 메타 키를 제거하여 CompositionEntry 객체만 수집 */
36
+ const filterCompositionEntries = (parsed) => {
37
+ if (typeof parsed !== 'object' || !parsed)
38
+ return {};
39
+ const entries = {};
40
+ for (const [key, value] of Object.entries(parsed)) {
41
+ if (key.startsWith('_'))
42
+ continue;
43
+ if (value && typeof value === 'object' && !Array.isArray(value))
44
+ entries[key] = value;
45
+ }
46
+ return entries;
47
+ };
48
+ const loadCompositionOverrides = () => {
49
+ for (const candidate of COMPOSITION_OVERRIDES_CANDIDATES) {
50
+ try {
51
+ const raw = fs_1.default.readFileSync(candidate, 'utf-8');
52
+ const parsed = JSON.parse(raw);
53
+ const entries = filterCompositionEntries(parsed);
54
+ logger_js_1.logger.info(`composition overrides 로딩: ${Object.keys(entries).length}개 (${path_1.default.basename(candidate)})`);
55
+ return entries;
56
+ }
57
+ catch (err) {
58
+ // ENOENT: 파일 없으면 다음 후보 시도 (TOCTOU 회피)
59
+ if (err instanceof Error && 'code' in err && err.code === 'ENOENT') {
60
+ continue;
61
+ }
62
+ logger_js_1.logger.warn(`composition overrides 파싱 실패 (${candidate}): ${(0, response_js_1.toErrorMessage)(err)}`);
63
+ return {};
64
+ }
65
+ }
66
+ return {};
67
+ };
68
+ exports.loadCompositionOverrides = loadCompositionOverrides;
69
+ /** P8: `_` 접두 메타 키를 객체에서 제거 (얕은 필터). canonicalExamples 같은 중첩 맵에서 _note 누출 방지. */
70
+ const stripMetaKeys = (obj) => {
71
+ if (!obj)
72
+ return obj;
73
+ const cleaned = {};
74
+ for (const [key, value] of Object.entries(obj)) {
75
+ if (key.startsWith('_'))
76
+ continue;
77
+ cleaned[key] = value;
78
+ }
79
+ return cleaned;
80
+ };
81
+ /** ComponentData 에 composition overrides 항목을 in-place 병합 — bemClasses 는 union, 나머지는 추가 필드. */
82
+ const mergeCompositionEntry = (component, entry) => {
83
+ if (entry.bemClassesExtra && entry.bemClassesExtra.length > 0) {
84
+ const merged = new Set([...component.bemClasses, ...entry.bemClassesExtra]);
85
+ component.bemClasses = [...merged].sort();
86
+ }
87
+ if (entry.allowedChildren)
88
+ component.allowedChildren = entry.allowedChildren;
89
+ if (entry.allowedParents)
90
+ component.allowedParents = entry.allowedParents;
91
+ if (entry.canonicalExample) {
92
+ // canonicalExample 내부 _note / _comment 같은 메타 키 제거 — 응답에 누출되지 않도록
93
+ component.canonicalExample = stripMetaKeys(entry.canonicalExample);
94
+ }
95
+ if (entry.canonicalExamples) {
96
+ // canonicalExamples 내부 _note / _comment 같은 메타 키 제거 — 응답에 누출되지 않도록
97
+ component.canonicalExamples = stripMetaKeys(entry.canonicalExamples);
98
+ }
99
+ // P13: description 끝에 append — list_components 응답에서 컴포넌트 용도 명시
100
+ if (entry.descriptionExtra) {
101
+ component.description = `${component.description}\n\n${entry.descriptionExtra}`;
102
+ }
103
+ // P13: aliases union — search_component 별칭 보강 (중복 제거)
104
+ if (entry.aliasesExtra && entry.aliasesExtra.length > 0) {
105
+ const set = new Set([...(component.aliases ?? []), ...entry.aliasesExtra]);
106
+ component.aliases = [...set];
107
+ }
108
+ };
22
109
  // ── 검증 헬퍼 (§ 3.8 복잡한 조건을 의도가 드러나는 이름으로 분리) ──────────
23
110
  /** JSON.parse 결과가 name: string 필드를 가진 컴포넌트 객체인지 검증 */
24
111
  const isValidComponentJson = (data) => !!data && typeof data === 'object' && 'name' in data && typeof data.name === 'string';
25
112
  /** JSON.parse 결과가 icons 배열을 가진 아이콘 데이터인지 검증 */
26
113
  const isValidIconJson = (data) => !!data && typeof data === 'object' && 'icons' in data && Array.isArray(data.icons);
27
114
  // ── 부수효과 함수 (fs I/O) ────────────────────────────────────────────────
28
- /** data/ 디렉토리의 JSON 파일을 읽어 componentMap으로 반환 */
115
+ /** data/ 디렉토리의 JSON 파일을 읽어 componentMap + compositionOverrides로 반환 */
29
116
  const loadComponentsFromDir = (dataDir) => {
30
117
  if (!fs_1.default.existsSync(dataDir)) {
31
118
  throw new Error(`mcp/data/ 디렉토리가 없습니다: ${dataDir}`);
@@ -35,6 +122,8 @@ const loadComponentsFromDir = (dataDir) => {
35
122
  throw new Error(`mcp/data/ 디렉토리에 JSON 파일이 없습니다: ${dataDir}`);
36
123
  }
37
124
  const map = new Map();
125
+ // P8: composition overrides (composition.json) 를 한 번만 로딩해 각 컴포넌트에 병합 — 호출자에게도 반환
126
+ const compositionOverrides = loadCompositionOverrides();
38
127
  for (const file of jsonFiles) {
39
128
  const filePath = path_1.default.join(dataDir, file);
40
129
  const raw = fs_1.default.readFileSync(filePath, 'utf-8');
@@ -43,10 +132,13 @@ const loadComponentsFromDir = (dataDir) => {
43
132
  throw new Error(`JSON 파싱 실패 (${file}): name 필드가 없거나 올바르지 않습니다`);
44
133
  }
45
134
  const component = parsed;
135
+ const compositionOverridesEntry = compositionOverrides[component.name];
136
+ if (compositionOverridesEntry)
137
+ mergeCompositionEntry(component, compositionOverridesEntry);
46
138
  map.set(component.name, component);
47
139
  }
48
140
  logger_js_1.logger.info(`컴포넌트 ${map.size}개 로딩 완료`);
49
- return map;
141
+ return { map, compositionOverrides };
50
142
  };
51
143
  exports.loadComponentsFromDir = loadComponentsFromDir;
52
144
  /** data/_icons.json을 읽어 IconData로 반환 (파일 없으면 빈 데이터) */
package/bin/version.d.ts CHANGED
@@ -3,4 +3,4 @@
3
3
  * scripts/generate-version-ts.ts 가 ui-admin/package.json 의 version 으로부터 자동 생성한다.
4
4
  * 수동 편집 금지 — 빌드(`pnpm generate:version-ts` 또는 `pnpm build`) 시 덮어쓰여진다.
5
5
  */
6
- export declare const VERSION = "1.8.4";
6
+ export declare const VERSION = "1.8.7";
package/bin/version.js CHANGED
@@ -6,4 +6,4 @@ exports.VERSION = void 0;
6
6
  * scripts/generate-version-ts.ts 가 ui-admin/package.json 의 version 으로부터 자동 생성한다.
7
7
  * 수동 편집 금지 — 빌드(`pnpm generate:version-ts` 또는 `pnpm build`) 시 덮어쓰여진다.
8
8
  */
9
- exports.VERSION = '1.8.4';
9
+ exports.VERSION = '1.8.7';
@@ -59,7 +59,7 @@
59
59
  "groupIcon": {
60
60
  "type": "object",
61
61
  "required": false,
62
- "rawType": "import(\"/Users/nhncommerce/Desktop/project/ncds/packages/ui-admin/src/types/side-slot\").SideSlotType | undefined",
62
+ "rawType": "import(\"/home/runner/_work/ncds/ncds/packages/ui-admin/src/types/side-slot\").SideSlotType | undefined",
63
63
  "properties": {
64
64
  "type": {
65
65
  "type": "string",
@@ -134,7 +134,7 @@
134
134
  "leadingIcon": {
135
135
  "type": "object",
136
136
  "required": false,
137
- "rawType": "import(\"/Users/nhncommerce/Desktop/project/ncds/packages/ui-admin/src/types/side-slot\").SideSlotType | undefined",
137
+ "rawType": "import(\"/home/runner/_work/ncds/ncds/packages/ui-admin/src/types/side-slot\").SideSlotType | undefined",
138
138
  "properties": {
139
139
  "type": {
140
140
  "type": "string",
@@ -211,7 +211,7 @@
211
211
  "trailingIcon": {
212
212
  "type": "object",
213
213
  "required": false,
214
- "rawType": "import(\"/Users/nhncommerce/Desktop/project/ncds/packages/ui-admin/src/types/side-slot\").SideSlotType | undefined",
214
+ "rawType": "import(\"/home/runner/_work/ncds/ncds/packages/ui-admin/src/types/side-slot\").SideSlotType | undefined",
215
215
  "properties": {
216
216
  "type": {
217
217
  "type": "string",
package/data/badge.json CHANGED
@@ -81,7 +81,7 @@
81
81
  "leadingIcon": {
82
82
  "type": "object",
83
83
  "required": false,
84
- "rawType": "import(\"/Users/nhncommerce/Desktop/project/ncds/packages/ui-admin/src/types/side-slot\").SideSlotType | undefined",
84
+ "rawType": "import(\"/home/runner/_work/ncds/ncds/packages/ui-admin/src/types/side-slot\").SideSlotType | undefined",
85
85
  "properties": {
86
86
  "type": {
87
87
  "type": "string",
@@ -154,7 +154,7 @@
154
154
  "trailingIcon": {
155
155
  "type": "object",
156
156
  "required": false,
157
- "rawType": "import(\"/Users/nhncommerce/Desktop/project/ncds/packages/ui-admin/src/types/side-slot\").SideSlotType | undefined",
157
+ "rawType": "import(\"/home/runner/_work/ncds/ncds/packages/ui-admin/src/types/side-slot\").SideSlotType | undefined",
158
158
  "properties": {
159
159
  "type": {
160
160
  "type": "string",
@@ -57,7 +57,7 @@
57
57
  "items": {
58
58
  "type": "object",
59
59
  "required": true,
60
- "rawType": "import(\"/Users/nhncommerce/Desktop/project/ncds/packages/ui-admin/src/components/navigation/bread-crumb/BreadCrumb\").BreadcrumbItemProps[]",
60
+ "rawType": "import(\"/home/runner/_work/ncds/ncds/packages/ui-admin/src/components/navigation/bread-crumb/BreadCrumb\").BreadcrumbItemProps[]",
61
61
  "properties": {
62
62
  "href": {
63
63
  "type": "string",
package/data/button.json CHANGED
@@ -77,7 +77,7 @@
77
77
  "leadingIcon": {
78
78
  "type": "object",
79
79
  "required": false,
80
- "rawType": "import(\"/Users/nhncommerce/Desktop/project/ncds/packages/ui-admin/src/types/side-slot\").SideSlotType | undefined",
80
+ "rawType": "import(\"/home/runner/_work/ncds/ncds/packages/ui-admin/src/types/side-slot\").SideSlotType | undefined",
81
81
  "properties": {
82
82
  "type": {
83
83
  "type": "string",
@@ -158,7 +158,7 @@
158
158
  "trailingIcon": {
159
159
  "type": "object",
160
160
  "required": false,
161
- "rawType": "import(\"/Users/nhncommerce/Desktop/project/ncds/packages/ui-admin/src/types/side-slot\").SideSlotType | undefined",
161
+ "rawType": "import(\"/home/runner/_work/ncds/ncds/packages/ui-admin/src/types/side-slot\").SideSlotType | undefined",
162
162
  "properties": {
163
163
  "type": {
164
164
  "type": "string",
@@ -26,6 +26,10 @@
26
26
  "전체선택",
27
27
  "선택완료",
28
28
  "Clear",
29
+ "maxSelection",
30
+ "최대 선택 개수",
31
+ "최대선택",
32
+ "선택 제한",
29
33
  "NCDS"
30
34
  ],
31
35
  "hasChildren": true,
@@ -71,6 +75,10 @@
71
75
  "required": false,
72
76
  "default": "defaultMaxHeight"
73
77
  },
78
+ "maxSelection": {
79
+ "type": "number",
80
+ "required": false
81
+ },
74
82
  "multiple": {
75
83
  "type": "boolean",
76
84
  "required": false,
@@ -91,7 +99,7 @@
91
99
  "optionItems": {
92
100
  "type": "object",
93
101
  "required": false,
94
- "rawType": "import(\"/Users/nhncommerce/Desktop/project/ncds/packages/ui-admin/src/types/dropdown/option\").OptionType[] | undefined",
102
+ "rawType": "import(\"/home/runner/_work/ncds/ncds/packages/ui-admin/src/types/dropdown/option\").OptionType[] | undefined",
95
103
  "properties": {
96
104
  "id": {
97
105
  "type": "string",
@@ -118,7 +126,7 @@
118
126
  "register": {
119
127
  "type": "object",
120
128
  "required": false,
121
- "rawType": "import(\"/Users/nhncommerce/Desktop/project/ncds/node_modules/.pnpm/react-hook-form@7.72.0_react@18.2.0/node_modules/react-hook-form/dist/types/form\").UseFormRegisterReturn | undefined"
129
+ "rawType": "import(\"/home/runner/_work/ncds/ncds/node_modules/.pnpm/react-hook-form@7.72.0_react@18.2.0/node_modules/react-hook-form/dist/types/form\").UseFormRegisterReturn | undefined"
122
130
  },
123
131
  "required": {
124
132
  "type": "boolean",
@@ -147,7 +155,7 @@
147
155
  "value": {
148
156
  "type": "object",
149
157
  "required": false,
150
- "rawType": "import(\"/Users/nhncommerce/Desktop/project/ncds/packages/ui-admin/src/types/dropdown/option\").OptionValue | undefined"
158
+ "rawType": "import(\"/home/runner/_work/ncds/ncds/packages/ui-admin/src/types/dropdown/option\").OptionValue | undefined"
151
159
  }
152
160
  },
153
161
  "html": {},
@@ -62,7 +62,7 @@
62
62
  "datePickerOptions": {
63
63
  "type": "object",
64
64
  "required": false,
65
- "rawType": "Partial<import(\"/Users/nhncommerce/Desktop/project/ncds/node_modules/.pnpm/flatpickr@4.6.13/node_modules/flatpickr/dist/types/options\").BaseOptions> | undefined"
65
+ "rawType": "Partial<import(\"/home/runner/_work/ncds/ncds/node_modules/.pnpm/flatpickr@4.6.13/node_modules/flatpickr/dist/types/options\").BaseOptions> | undefined"
66
66
  },
67
67
  "destructive": {
68
68
  "type": "string",
@@ -2,7 +2,7 @@
2
2
  "name": "dropdown",
3
3
  "exportName": "Dropdown",
4
4
  "importPath": "@ncds/ui-admin",
5
- "jsRequired": false,
5
+ "jsRequired": true,
6
6
  "category": "overlays",
7
7
  "description": "Dropdown(메뉴형)은 버튼, 아이콘, 아바타 등 트리거 요소를 통해 숨겨진 메뉴 또는 작업(Action) 목록을 레이어 형태로 노출하는 컴포넌트입니다.",
8
8
  "aliases": [
@@ -115,12 +115,12 @@
115
115
  "groups": {
116
116
  "type": "object",
117
117
  "required": true,
118
- "rawType": "import(\"/Users/nhncommerce/Desktop/project/ncds/packages/ui-admin/src/components/overlays/dropdown/Dropdown\").DropdownGroup[]",
118
+ "rawType": "import(\"/home/runner/_work/ncds/ncds/packages/ui-admin/src/components/overlays/dropdown/Dropdown\").DropdownGroup[]",
119
119
  "properties": {
120
120
  "items": {
121
121
  "type": "object",
122
122
  "required": true,
123
- "rawType": "import(\"/Users/nhncommerce/Desktop/project/ncds/packages/ui-admin/src/components/overlays/dropdown/Dropdown\").DropdownItemType[]",
123
+ "rawType": "import(\"/home/runner/_work/ncds/ncds/packages/ui-admin/src/components/overlays/dropdown/Dropdown\").DropdownItemType[]",
124
124
  "properties": {
125
125
  "id": {
126
126
  "type": "string",
@@ -178,7 +178,7 @@
178
178
  "header": {
179
179
  "type": "object",
180
180
  "required": false,
181
- "rawType": "import(\"/Users/nhncommerce/Desktop/project/ncds/packages/ui-admin/src/components/overlays/dropdown/Dropdown\").DropdownHeaderType | undefined",
181
+ "rawType": "import(\"/home/runner/_work/ncds/ncds/packages/ui-admin/src/components/overlays/dropdown/Dropdown\").DropdownHeaderType | undefined",
182
182
  "properties": {
183
183
  "type": {
184
184
  "type": "string",
@@ -206,7 +206,7 @@
206
206
  "trigger": {
207
207
  "type": "object",
208
208
  "required": true,
209
- "rawType": "import(\"/Users/nhncommerce/Desktop/project/ncds/packages/ui-admin/src/components/overlays/dropdown/Dropdown\").AvatarTrigger | import(\"/Users/nhncommerce/Desktop/project/ncds/packages/ui-admin/src/components/overlays/dropdown/Dropdown\").ButtonTrigger | import(\"/Users/nhncommerce/Desktop/project/ncds/packages/ui-admin/src/components/overlays/dropdown/Dropdown\").IconTrigger | import(\"/Users/nhncommerce/Desktop/project/ncds/packages/ui-admin/src/components/overlays/dropdown/Dropdown\").CustomTrigger",
209
+ "rawType": "import(\"/home/runner/_work/ncds/ncds/packages/ui-admin/src/components/overlays/dropdown/Dropdown\").AvatarTrigger | import(\"/home/runner/_work/ncds/ncds/packages/ui-admin/src/components/overlays/dropdown/Dropdown\").ButtonTrigger | import(\"/home/runner/_work/ncds/ncds/packages/ui-admin/src/components/overlays/dropdown/Dropdown\").IconTrigger | import(\"/home/runner/_work/ncds/ncds/packages/ui-admin/src/components/overlays/dropdown/Dropdown\").CustomTrigger",
210
210
  "properties": {
211
211
  "type": {
212
212
  "type": "string",
@@ -37,7 +37,7 @@
37
37
  "buttons": {
38
38
  "type": "object",
39
39
  "required": false,
40
- "rawType": "import(\"/Users/nhncommerce/Desktop/project/ncds/packages/ui-admin/src/components/feedback-and-status/empty-state/EmptyState\").ButtonOptions | import(\"/Users/nhncommerce/Desktop/project/ncds/packages/ui-admin/src/components/feedback-and-status/empty-state/EmptyState\").ButtonOptions[] | undefined",
40
+ "rawType": "import(\"/home/runner/_work/ncds/ncds/packages/ui-admin/src/components/feedback-and-status/empty-state/EmptyState\").ButtonOptions | import(\"/home/runner/_work/ncds/ncds/packages/ui-admin/src/components/feedback-and-status/empty-state/EmptyState\").ButtonOptions[] | undefined",
41
41
  "properties": {
42
42
  "label": {
43
43
  "type": "string",
@@ -79,7 +79,7 @@
79
79
  "leadingIcon": {
80
80
  "type": "object",
81
81
  "required": false,
82
- "rawType": "import(\"/Users/nhncommerce/Desktop/project/ncds/packages/ui-admin/src/types/side-slot\").SideSlotType | undefined",
82
+ "rawType": "import(\"/home/runner/_work/ncds/ncds/packages/ui-admin/src/types/side-slot\").SideSlotType | undefined",
83
83
  "properties": {
84
84
  "type": {
85
85
  "type": "string",
@@ -142,7 +142,7 @@
142
142
  "trailingIcon": {
143
143
  "type": "object",
144
144
  "required": false,
145
- "rawType": "import(\"/Users/nhncommerce/Desktop/project/ncds/packages/ui-admin/src/types/side-slot\").SideSlotType | undefined",
145
+ "rawType": "import(\"/home/runner/_work/ncds/ncds/packages/ui-admin/src/types/side-slot\").SideSlotType | undefined",
146
146
  "properties": {
147
147
  "type": {
148
148
  "type": "string",
@@ -60,7 +60,7 @@
60
60
  "menus": {
61
61
  "type": "object",
62
62
  "required": false,
63
- "rawType": "import(\"/Users/nhncommerce/Desktop/project/ncds/packages/ui-admin/src/components/tab/TabButton\").TabButtonProps[] | undefined",
63
+ "rawType": "import(\"/home/runner/_work/ncds/ncds/packages/ui-admin/src/components/tab/TabButton\").TabButtonProps[] | undefined",
64
64
  "properties": {
65
65
  "id": {
66
66
  "type": "string",
@@ -97,7 +97,7 @@
97
97
  "badgeInfo": {
98
98
  "type": "object",
99
99
  "required": false,
100
- "rawType": "import(\"/Users/nhncommerce/Desktop/project/ncds/packages/ui-admin/src/components/feedback-and-status/badge/Badge\").BadgeProps | undefined",
100
+ "rawType": "import(\"/home/runner/_work/ncds/ncds/packages/ui-admin/src/components/feedback-and-status/badge/Badge\").BadgeProps | undefined",
101
101
  "properties": {
102
102
  "label": {
103
103
  "type": "string",
@@ -131,7 +131,7 @@
131
131
  "leadingIcon": {
132
132
  "type": "object",
133
133
  "required": false,
134
- "rawType": "import(\"/Users/nhncommerce/Desktop/project/ncds/packages/ui-admin/src/types/side-slot\").SideSlotType | undefined",
134
+ "rawType": "import(\"/home/runner/_work/ncds/ncds/packages/ui-admin/src/types/side-slot\").SideSlotType | undefined",
135
135
  "properties": {
136
136
  "type": {
137
137
  "type": "string",
@@ -194,7 +194,7 @@
194
194
  "trailingIcon": {
195
195
  "type": "object",
196
196
  "required": false,
197
- "rawType": "import(\"/Users/nhncommerce/Desktop/project/ncds/packages/ui-admin/src/types/side-slot\").SideSlotType | undefined",
197
+ "rawType": "import(\"/home/runner/_work/ncds/ncds/packages/ui-admin/src/types/side-slot\").SideSlotType | undefined",
198
198
  "properties": {
199
199
  "type": {
200
200
  "type": "string",
package/data/modal.json CHANGED
@@ -211,7 +211,7 @@
211
211
  "featuredIcon": {
212
212
  "type": "object",
213
213
  "required": false,
214
- "rawType": "{ icon: import(\"/Users/nhncommerce/Desktop/project/ncds/packages/ui-admin/src/types/side-slot\").SlotIconComponent; color: import(\"/Users/nhncommerce/Desktop/project/ncds/packages/ui-admin/src/components/image-and-icons/featured-icon/FeaturedIcon\").FeaturedIconColor; theme: import(\"/Users/nhncommerce/Desktop/project/ncds/packages/ui-admin/src/components/image-and-icons/featured-icon/FeaturedIcon\").FeaturedIconTheme; } | undefined",
214
+ "rawType": "{ icon: import(\"/home/runner/_work/ncds/ncds/packages/ui-admin/src/types/side-slot\").SlotIconComponent; color: import(\"/home/runner/_work/ncds/ncds/packages/ui-admin/src/components/image-and-icons/featured-icon/FeaturedIcon\").FeaturedIconColor; theme: import(\"/home/runner/_work/ncds/ncds/packages/ui-admin/src/components/image-and-icons/featured-icon/FeaturedIcon\").FeaturedIconTheme; } | undefined",
215
215
  "properties": {
216
216
  "icon": {
217
217
  "type": "function",
@@ -45,7 +45,7 @@
45
45
  "actions": {
46
46
  "type": "object",
47
47
  "required": false,
48
- "rawType": "import(\"/Users/nhncommerce/Desktop/project/ncds/packages/ui-admin/src/components/overlays/notification/Notification\").NotificationAction[] | undefined",
48
+ "rawType": "import(\"/home/runner/_work/ncds/ncds/packages/ui-admin/src/components/overlays/notification/Notification\").NotificationAction[] | undefined",
49
49
  "properties": {
50
50
  "label": {
51
51
  "type": "string",
@@ -99,6 +99,11 @@
99
99
  "type": "function",
100
100
  "required": false
101
101
  },
102
+ "portal": {
103
+ "type": "boolean",
104
+ "required": false,
105
+ "default": false
106
+ },
102
107
  "supportingText": {
103
108
  "type": "ReactNode",
104
109
  "required": false
@@ -56,7 +56,7 @@
56
56
  "breadcrumbItems": {
57
57
  "type": "object",
58
58
  "required": false,
59
- "rawType": "import(\"/Users/nhncommerce/Desktop/project/ncds/packages/ui-admin/src/components/layout/page-title/PageTitle\").PageTitleBreadcrumbItem[] | undefined",
59
+ "rawType": "import(\"/home/runner/_work/ncds/ncds/packages/ui-admin/src/components/layout/page-title/PageTitle\").PageTitleBreadcrumbItem[] | undefined",
60
60
  "properties": {
61
61
  "label": {
62
62
  "type": "string",
@@ -52,7 +52,7 @@
52
52
  "segments": {
53
53
  "type": "object",
54
54
  "required": false,
55
- "rawType": "import(\"/Users/nhncommerce/Desktop/project/ncds/packages/ui-admin/src/components/feedback-and-status/progress-bar/types\").ProgressSegment[] | undefined",
55
+ "rawType": "import(\"/home/runner/_work/ncds/ncds/packages/ui-admin/src/components/feedback-and-status/progress-bar/types\").ProgressSegment[] | undefined",
56
56
  "properties": {
57
57
  "value": {
58
58
  "type": "number",
@@ -61,7 +61,7 @@
61
61
  "endDateOptions": {
62
62
  "type": "object",
63
63
  "required": true,
64
- "rawType": "import(\"/Users/nhncommerce/Desktop/project/ncds/packages/ui-admin/src/components/forms-and-input/date-picker/DatePicker\").DatePickerProps",
64
+ "rawType": "import(\"/home/runner/_work/ncds/ncds/packages/ui-admin/src/components/forms-and-input/date-picker/DatePicker\").DatePickerProps",
65
65
  "properties": {
66
66
  "size": {
67
67
  "type": "enum",
@@ -82,7 +82,7 @@
82
82
  "datePickerOptions": {
83
83
  "type": "object",
84
84
  "required": false,
85
- "rawType": "Partial<import(\"/Users/nhncommerce/Desktop/project/ncds/node_modules/.pnpm/flatpickr@4.6.13/node_modules/flatpickr/dist/types/options\").BaseOptions> | undefined"
85
+ "rawType": "Partial<import(\"/home/runner/_work/ncds/ncds/node_modules/.pnpm/flatpickr@4.6.13/node_modules/flatpickr/dist/types/options\").BaseOptions> | undefined"
86
86
  },
87
87
  "destructive": {
88
88
  "type": "string",
@@ -144,7 +144,7 @@
144
144
  "startDateOptions": {
145
145
  "type": "object",
146
146
  "required": true,
147
- "rawType": "import(\"/Users/nhncommerce/Desktop/project/ncds/packages/ui-admin/src/components/forms-and-input/date-picker/DatePicker\").DatePickerProps",
147
+ "rawType": "import(\"/home/runner/_work/ncds/ncds/packages/ui-admin/src/components/forms-and-input/date-picker/DatePicker\").DatePickerProps",
148
148
  "properties": {
149
149
  "size": {
150
150
  "type": "enum",
@@ -165,7 +165,7 @@
165
165
  "datePickerOptions": {
166
166
  "type": "object",
167
167
  "required": false,
168
- "rawType": "Partial<import(\"/Users/nhncommerce/Desktop/project/ncds/node_modules/.pnpm/flatpickr@4.6.13/node_modules/flatpickr/dist/types/options\").BaseOptions> | undefined"
168
+ "rawType": "Partial<import(\"/home/runner/_work/ncds/ncds/node_modules/.pnpm/flatpickr@4.6.13/node_modules/flatpickr/dist/types/options\").BaseOptions> | undefined"
169
169
  },
170
170
  "destructive": {
171
171
  "type": "string",