@ncds/ui-admin-mcp 1.0.0-alpha.13 → 1.0.0-alpha.15

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 (52) hide show
  1. package/bin/components.bundle.js +1 -1
  2. package/bin/definitions/external/editor.d.ts +50 -0
  3. package/bin/definitions/external/editor.js +53 -0
  4. package/bin/definitions/js-api.json +139 -21
  5. package/bin/server.d.ts +5 -0
  6. package/bin/server.js +21 -15
  7. package/bin/tools/external/editor.d.ts +17 -0
  8. package/bin/tools/external/editor.js +88 -0
  9. package/bin/tools/renderToHtml.d.ts +22 -7
  10. package/bin/tools/renderToHtml.js +232 -11
  11. package/bin/types.d.ts +10 -0
  12. package/data/badge-group.json +4 -4
  13. package/data/badge.json +3 -3
  14. package/data/bread-crumb.json +1 -1
  15. package/data/button-group.json +10 -0
  16. package/data/button.json +2 -2
  17. package/data/carousel-arrow.json +1 -1
  18. package/data/carousel-number-group.json +1 -1
  19. package/data/checkbox.json +1 -1
  20. package/data/combo-box.json +4 -4
  21. package/data/date-picker.json +2 -2
  22. package/data/divider.json +1 -1
  23. package/data/dot.json +1 -1
  24. package/data/dropdown.json +38 -18
  25. package/data/editor.json +85 -0
  26. package/data/empty-state.json +4 -4
  27. package/data/featured-icon.json +2 -2
  28. package/data/file-input.json +6 -1
  29. package/data/horizontal-tab.json +4 -4
  30. package/data/image-file-input.json +6 -1
  31. package/data/input-base.json +1 -1
  32. package/data/modal.json +51 -7
  33. package/data/notification.json +7 -23
  34. package/data/number-input.json +1 -1
  35. package/data/password-input.json +1 -1
  36. package/data/progress-bar.json +2 -2
  37. package/data/progress-circle.json +1 -1
  38. package/data/radio.json +1 -1
  39. package/data/range-date-picker-with-buttons.json +5 -5
  40. package/data/range-date-picker.json +5 -5
  41. package/data/select-box.json +4 -4
  42. package/data/select.json +8 -3
  43. package/data/slider.json +1 -1
  44. package/data/spinner.json +1 -1
  45. package/data/switch.json +1 -1
  46. package/data/table.json +3 -1
  47. package/data/tag.json +2 -2
  48. package/data/textarea.json +1 -1
  49. package/data/toggle.json +1 -1
  50. package/data/tooltip.json +1 -1
  51. package/data/vertical-tab.json +4 -4
  52. package/package.json +3 -2
@@ -1,7 +1,20 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.renderToHtml = void 0;
3
+ exports.renderToHtml = exports.mergeCdnDefaults = exports.stripFunctionProps = void 0;
4
+ /**
5
+ * render_to_html tool — 컴포넌트 속성을 전달하면 정확한 HTML + React 매핑을 반환 (순수 함수)
6
+ *
7
+ * DOM 환경과 React/ReactDOM은 server.ts에서 초기화하고 파라미터로 전달한다.
8
+ * 이 파일에는 fs, path, require, let이 없다.
9
+ */
10
+ // biome-ignore-all lint/complexity/noExcessiveCognitiveComplexity: 기존 spec-walk 함수 복잡도 (Story 5.8 scope 외, 별도 refactor 스토리)
11
+ // biome-ignore-all lint/style/useExportsLast: RenderToHtmlParams export interface 상단 위치 (파일 관행)
12
+ // biome-ignore-all lint/style/noNonNullAssertion: 기존 fallback 패턴 (Story 5.8 scope 외)
13
+ // biome-ignore-all lint/style/noNestedTernary: 기존 reactElementToJsx의 type 판정 로직 (Story 5.8 scope 외)
14
+ // biome-ignore-all lint/style/useTemplate: 기존 attrsPrefix 문자열 결합 (Story 5.8 scope 외)
15
+ const lodash_1 = require("lodash");
4
16
  const response_js_1 = require("../utils/response.js");
17
+ const editor_js_1 = require("./external/editor.js");
5
18
  // ── 상수 ──────────────────────────────────────────────────────────
6
19
  /** React 특수 props 차단 — injection 방지 */
7
20
  const BLOCKED_PROPS = new Set(['dangerouslySetInnerHTML', 'ref', '__self', '__source']);
@@ -19,7 +32,7 @@ const capitalize = (s) => s.charAt(0).toUpperCase() + s.slice(1);
19
32
  const resolveSimpleComponent = (name, ctx) => {
20
33
  const normalized = (0, response_js_1.normalizeName)(name);
21
34
  const childData = ctx.componentMap.get(normalized);
22
- const Component = childData?.exportName ? ctx.bundle[childData.exportName] ?? null : null;
35
+ const Component = childData?.exportName ? (ctx.bundle[childData.exportName] ?? null) : null;
23
36
  return { Component, propsSpec: childData?.props };
24
37
  };
25
38
  /** compound component resolve: "modal.header" → { Component: bundle.Modal.Header, propsSpec: subComponents["Modal.Header"].props } */
@@ -331,6 +344,180 @@ const correctMissingRequired = (userProps, propsSpec) => {
331
344
  }
332
345
  return corrected;
333
346
  };
347
+ // ── CDN init 패턴 (Story 5.8) ─────────────────────────────────────
348
+ /**
349
+ * CDN 호출 패턴은 `js-api.json`의 `cdnPattern` 필드(A/B/C)로 단일 관리한다.
350
+ * 컴포넌트 추가 시 js-api.json 한 곳에만 패턴을 명시하면 자동 인식된다.
351
+ */
352
+ /** options를 안전하게 직렬화 — script 블록 탈출 방지(`</script>` 이스케이프) */
353
+ const serializeCdnOptions = (options) => JSON.stringify(options).replace(/<\/script/gi, '<\\/script');
354
+ /** 패턴 A: `new ncua.X(wrapper, options)` */
355
+ const buildPatternA = (id, className, options) => [
356
+ `<div id="${id}"></div>`,
357
+ '<script>',
358
+ " document.addEventListener('DOMContentLoaded', function () {",
359
+ ` const wrapper = document.querySelector('#${id}');`,
360
+ ` new ncua.${className}(wrapper, ${serializeCdnOptions(options)});`,
361
+ ' });',
362
+ '</script>',
363
+ ].join('\n');
364
+ /** 패턴 B: `new ncua.X({...options, container: id})` — container 자동 주입 */
365
+ const buildPatternB = (id, className, options) => [
366
+ `<div id="${id}"></div>`,
367
+ '<script>',
368
+ " document.addEventListener('DOMContentLoaded', function () {",
369
+ ` new ncua.${className}(${serializeCdnOptions({ ...options, container: id })});`,
370
+ ' });',
371
+ '</script>',
372
+ ].join('\n');
373
+ /** 패턴 C: `new ncua.X(options)` + `getElement()` + 수동 append */
374
+ const buildPatternC = (id, className, options) => [
375
+ `<div id="${id}"></div>`,
376
+ '<script>',
377
+ " document.addEventListener('DOMContentLoaded', function () {",
378
+ ` const wrapper = document.querySelector('#${id}');`,
379
+ ` const inst = new ncua.${className}(${serializeCdnOptions(options)});`,
380
+ ' wrapper.appendChild(inst.getElement());',
381
+ ' });',
382
+ '</script>',
383
+ ].join('\n');
384
+ /**
385
+ * CDN init 스크립트 생성. 패턴은 `jsApi.cdnPattern` (A/B/C)으로 결정한다.
386
+ * 호출자는 `cdnPattern` 부재 시 isCdnInput=false로 분기하여 React renderToStaticMarkup 경로를 사용한다.
387
+ */
388
+ const buildCdnInitScript = (pattern, componentName, instanceId, className, options) => {
389
+ const id = `ncua-${componentName}-${instanceId}`;
390
+ if (pattern === 'A')
391
+ return buildPatternA(id, className, options);
392
+ if (pattern === 'B')
393
+ return buildPatternB(id, className, options);
394
+ return buildPatternC(id, className, options);
395
+ };
396
+ /** options 키 중 `jsApi.constructorParams`에 없는 키를 warning 메시지로 변환.
397
+ * constructorParams의 키는 `config.options` 같은 dot 표기 — 마지막 segment만 추출해 비교. */
398
+ const checkUnknownCdnKeys = (options, jsApi) => {
399
+ if (Object.keys(jsApi.constructorParams).length === 0)
400
+ return [];
401
+ const allowedKeys = new Set();
402
+ for (const param of Object.keys(jsApi.constructorParams)) {
403
+ const lastDot = param.lastIndexOf('.');
404
+ allowedKeys.add(lastDot >= 0 ? param.slice(lastDot + 1) : param);
405
+ }
406
+ return Object.keys(options)
407
+ .filter((key) => !allowedKeys.has(key))
408
+ .map((key) => `Unknown CDN option key '${key}' for component '${jsApi.className}'. Passed through as-is. Verify against constructorParams.`);
409
+ };
410
+ /** SelectBox/ComboBox `options` 배열 요소 키 정규화.
411
+ * 공식 docs는 `{id, label}` 또는 `{id, text}` 허용. React 매칭은 `label`만 받으므로
412
+ * 통일된 `{id, label}`로 정규화. `{value, text}`는 비표준 alias(HTML `<option>` 컨벤션
413
+ * 오용)이며 함께 변환. 정규화 발생 시 warning 기록(에이전트 학습용). */
414
+ const normalizeCdnInputProps = (componentName, cdnConfig) => {
415
+ if (componentName !== 'select-box' && componentName !== 'combo-box') {
416
+ return { normalized: cdnConfig, warnings: [] };
417
+ }
418
+ const { options } = cdnConfig;
419
+ if (!Array.isArray(options))
420
+ return { normalized: cdnConfig, warnings: [] };
421
+ const aliasesUsed = new Set();
422
+ const normalizedOptions = options.map((opt) => {
423
+ if (opt === null || typeof opt !== 'object')
424
+ return opt;
425
+ const item = { ...opt };
426
+ if (item.id === undefined && item.value !== undefined) {
427
+ item.id = item.value;
428
+ delete item.value;
429
+ aliasesUsed.add('value');
430
+ }
431
+ if (item.label === undefined && item.text !== undefined) {
432
+ item.label = item.text;
433
+ delete item.text;
434
+ aliasesUsed.add('text');
435
+ }
436
+ return item;
437
+ });
438
+ const warnings = [];
439
+ if (aliasesUsed.has('value')) {
440
+ warnings.push(`Option key 'value' normalized to 'id' for component '${componentName}'. Canonical form is {id, label}.`);
441
+ }
442
+ if (aliasesUsed.has('text')) {
443
+ warnings.push(`Option key 'text' normalized to 'label' for component '${componentName}'. Canonical form is {id, label}.`);
444
+ }
445
+ return { normalized: { ...cdnConfig, options: normalizedOptions }, warnings };
446
+ };
447
+ /** Story 5.9: 사용자 props 에서 함수 prop 재귀 제거 (JSON 직렬화·deep merge 안전).
448
+ * cdnDefaults 는 JSON 이라 함수 없음 → 사용자 props 만 정리.
449
+ * Story 5.10: 외부 분기 모듈(`tools/external/editor.ts`)에서도 재사용 → export. */
450
+ const stripFunctionProps = (obj) => {
451
+ if (typeof obj === 'function')
452
+ return undefined;
453
+ if (Array.isArray(obj)) {
454
+ return obj.map((item) => (0, exports.stripFunctionProps)(item)).filter((item) => item !== undefined);
455
+ }
456
+ if (typeof obj === 'object' && obj !== null) {
457
+ return Object.fromEntries(Object.entries(obj)
458
+ .filter(([, value]) => typeof value !== 'function')
459
+ .map(([key, value]) => [key, (0, exports.stripFunctionProps)(value)]));
460
+ }
461
+ return obj;
462
+ };
463
+ exports.stripFunctionProps = stripFunctionProps;
464
+ /** Story 5.9: cdnDefaults 와 사용자 props 를 deep merge.
465
+ * - 사용자 값 우선 (lodash merge 의 두 번째 인자가 우선)
466
+ * - 함수 prop 은 사용자 props 에서 stripFunctionProps 로 사전 제거
467
+ * - DatePicker `datePickerOptions` 배열 한정: 각 항목의 `options` 에 cdnDefaults 의 첫 항목 options 를 per-element 부분 merge
468
+ * - 다른 배열(`buttons` 등) 은 사용자 값 그대로
469
+ * 반환: { merged, defaultsApplied } — defaultsApplied 는 cdnDefaults 에 있고 사용자 props 에 없는 top-level 키 (defaultsUsed 응답용)
470
+ * Story 5.10: 외부 분기 모듈(`tools/external/editor.ts`)에서도 재사용 → export. */
471
+ const mergeCdnDefaults = (componentName, cdnDefaults, userProps) => {
472
+ if (!cdnDefaults)
473
+ return { merged: userProps, defaultsApplied: [] };
474
+ const userPropsClean = (0, exports.stripFunctionProps)(userProps);
475
+ const baseMerged = (0, lodash_1.merge)((0, lodash_1.cloneDeep)(cdnDefaults), userPropsClean);
476
+ const merged = componentName === 'date-picker' && Array.isArray(userPropsClean.datePickerOptions)
477
+ ? {
478
+ ...baseMerged,
479
+ datePickerOptions: userPropsClean.datePickerOptions.map((item) => {
480
+ const baseOptions = cdnDefaults.datePickerOptions?.[0]?.options ?? {};
481
+ return {
482
+ ...item,
483
+ options: (0, lodash_1.merge)((0, lodash_1.cloneDeep)(baseOptions), item.options ?? {}),
484
+ };
485
+ }),
486
+ }
487
+ : baseMerged;
488
+ const defaultsApplied = Object.keys(cdnDefaults).filter((key) => !(key in userPropsClean));
489
+ return { merged, defaultsApplied };
490
+ };
491
+ exports.mergeCdnDefaults = mergeCdnDefaults;
492
+ /** CDN config(에이전트 입력) → React props (buildReactOutput 입력) 번역.
493
+ * 단순 컴포넌트는 identity, 차이가 있는 컴포넌트는 별도 룰. */
494
+ const translateCdnToReactProps = (componentName, cdnConfig) => {
495
+ // SelectBox/ComboBox: options → optionItems, value(원시) → value(객체) (배열에서 매칭해 wrap)
496
+ if (componentName === 'select-box' || componentName === 'combo-box') {
497
+ const { options, value, ...rest } = cdnConfig;
498
+ const result = { ...rest };
499
+ if (options !== undefined)
500
+ result.optionItems = options;
501
+ if (value !== undefined) {
502
+ if ((typeof value === 'string' || typeof value === 'number') && Array.isArray(options)) {
503
+ const matched = options.find((opt) => typeof opt === 'object' && opt !== null && opt.id === value);
504
+ result.value = matched !== undefined ? matched : value;
505
+ }
506
+ else {
507
+ result.value = value;
508
+ }
509
+ }
510
+ return result;
511
+ }
512
+ // FileInput/ImageFileInput: container 키는 React props에 없음 → 제거
513
+ if (componentName === 'file-input' || componentName === 'image-file-input') {
514
+ const result = { ...cdnConfig };
515
+ delete result.container;
516
+ return result;
517
+ }
518
+ // 그 외: identity (Slider, DatePicker, Tooltip, Notification, ProgressBar, Tag — key 동일 가정)
519
+ return cdnConfig;
520
+ };
334
521
  // ── 응답 조립 ──────────────────────────────────────────────────────
335
522
  /** componentMap의 props 스펙에서 defaultsUsed를 자동 계산 */
336
523
  const calcDefaultsUsed = (propsSpec, userProps) => Object.fromEntries(Object.entries(propsSpec)
@@ -391,9 +578,9 @@ const reactElementToJsx = (node, ctx) => {
391
578
  const name = typeof el.type === 'string'
392
579
  ? el.type
393
580
  : typeof el.type === 'function'
394
- ? el.type.displayName
395
- || el.type.name
396
- || 'Component'
581
+ ? el.type.displayName ||
582
+ el.type.name ||
583
+ 'Component'
397
584
  : 'Component';
398
585
  const { children: childChildren, ...restProps } = el.props || {};
399
586
  const attrs = Object.entries(restProps)
@@ -464,8 +651,12 @@ const buildJsField = (componentData, jsApiMap) => {
464
651
  // ── 진입점 ────────────────────────────────────────────────────────
465
652
  /** render_to_html tool — props로 React 컴포넌트를 렌더링하여 HTML + React 매핑 반환 */
466
653
  const renderToHtml = (params) => {
467
- const { componentMap, bundle, iconBundle, cdnMeta, iconMeta, reactRuntime, jsApiMap, name, props } = params;
654
+ const { componentMap, bundle, iconBundle, cdnMeta, iconMeta, reactRuntime, jsApiMap, name, props, instanceId } = params;
468
655
  const normalized = (0, response_js_1.normalizeName)(name);
656
+ // Story 5.10: editor alias 검출 시 ui-admin 흐름 우회 — 외부 분기에서 응답 직접 조립
657
+ if ((0, editor_js_1.isEditorAlias)(normalized)) {
658
+ return (0, editor_js_1.buildEditorResponse)(props ?? {}, instanceId);
659
+ }
469
660
  const componentData = componentMap.get(normalized);
470
661
  if (!componentData)
471
662
  return (0, response_js_1.componentNotFoundResponse)(normalized);
@@ -478,29 +669,59 @@ const renderToHtml = (params) => {
478
669
  return (0, response_js_1.errorResponse)('COMPONENT_NOT_IN_BUNDLE', `'${normalized}' (${exportName}) 컴포넌트가 번들에 없습니다.`, '번들을 재빌드해주세요 (pnpm build:bundle).');
479
670
  }
480
671
  try {
481
- const safeProps = removeBlockedProps(props ?? {});
672
+ // Story 5.8: jsRequired + js-api 정의 + jsApi.cdnPattern 등록 → CDN-input 모드
673
+ const jsApi = jsApiMap.get(exportName);
674
+ const isCdnInput = componentData.jsRequired && jsApi !== undefined && jsApi.cdnPattern !== undefined;
675
+ // CDN-input은 입력이 CDN config 스키마 → 옵션 배열 키 정규화 → React 파이프라인을 위해 React props로 번역
676
+ const cdnNormalization = isCdnInput
677
+ ? normalizeCdnInputProps(normalized, props ?? {})
678
+ : { normalized: props ?? {}, warnings: [] };
679
+ const normalizedCdnProps = cdnNormalization.normalized;
680
+ // Story 5.9: cdnDefaults 와 deep merge (사용자 props 우선, 함수 prop skip, datePickerOptions per-element 부분 merge)
681
+ const cdnMergeResult = isCdnInput && jsApi
682
+ ? (0, exports.mergeCdnDefaults)(normalized, jsApi.cdnDefaults, normalizedCdnProps)
683
+ : { merged: normalizedCdnProps, defaultsApplied: [] };
684
+ const mergedCdnProps = cdnMergeResult.merged;
685
+ const reactInput = isCdnInput ? translateCdnToReactProps(normalized, mergedCdnProps) : mergedCdnProps;
686
+ const safeProps = removeBlockedProps(reactInput);
482
687
  const sanitized = componentData.props ? sanitizeProps(safeProps, componentData.props) : safeProps;
483
688
  const enumWarnings = componentData.props ? validateProps(sanitized, componentData.props) : [];
484
689
  const enumCorrected = componentData.props ? correctInvalidEnums(sanitized, componentData.props) : sanitized;
485
690
  const corrected = componentData.props ? correctMissingRequired(enumCorrected, componentData.props) : enumCorrected;
486
691
  const postWarnings = componentData.props ? validateProps(corrected, componentData.props) : [];
487
- const warnings = [...enumWarnings, ...postWarnings.filter((w) => !enumWarnings.includes(w))];
692
+ const cdnKeyWarnings = isCdnInput && jsApi ? checkUnknownCdnKeys(normalizedCdnProps, jsApi) : [];
693
+ const warnings = [
694
+ ...enumWarnings,
695
+ ...postWarnings.filter((w) => !enumWarnings.includes(w)),
696
+ ...cdnKeyWarnings,
697
+ ...cdnNormalization.warnings,
698
+ ];
488
699
  const resolvedProps = resolveIconProps(corrected, iconBundle, componentData.props);
489
700
  // children이 컴포넌트 descriptor면 React element로 변환
490
701
  if (resolvedProps.children !== undefined) {
491
702
  const ctx = { bundle, iconBundle, componentMap, reactRuntime };
492
703
  resolvedProps.children = resolveChildren(resolvedProps.children, ctx, 0);
493
704
  }
494
- const rawHtml = reactRuntime.renderToStaticMarkup(reactRuntime.createElement(Component, resolvedProps));
495
- const html = `<!-- ncua:${normalized} start -->\n${rawHtml}\n<!-- ncua:${normalized} end -->`;
705
+ // HTML 출력: CDN-input은 init script, 그 외는 React 정적 HTML (renderToStaticMarkup은 필요할 때만 호출)
706
+ const cdnInitScript = isCdnInput && jsApi?.cdnPattern
707
+ ? buildCdnInitScript(jsApi.cdnPattern, normalized, instanceId, jsApi.className, removeBlockedProps(mergedCdnProps))
708
+ : null;
709
+ const html = cdnInitScript !== null
710
+ ? cdnInitScript
711
+ : `<!-- ncua:${normalized} start -->\n${reactRuntime.renderToStaticMarkup(reactRuntime.createElement(Component, resolvedProps))}\n<!-- ncua:${normalized} end -->`;
496
712
  const hasDefaults = componentData.props ? calcDefaultsUsed(componentData.props, corrected) : {};
713
+ // Story 5.9: cdnDefaults 적용된 키도 defaultsUsed 에 노출 (에이전트 학습용)
714
+ const cdnDefaultsApplied = isCdnInput && jsApi?.cdnDefaults
715
+ ? Object.fromEntries(cdnMergeResult.defaultsApplied.map((key) => [key, jsApi.cdnDefaults?.[key]]))
716
+ : {};
717
+ const finalDefaultsUsed = { ...hasDefaults, ...cdnDefaultsApplied };
497
718
  return (0, response_js_1.successResponse)({
498
719
  html,
499
720
  component: normalized,
500
721
  exportName,
501
722
  importPath: componentData.importPath,
502
723
  appliedProps: corrected,
503
- ...(Object.keys(hasDefaults).length > 0 && { defaultsUsed: hasDefaults }),
724
+ ...(Object.keys(finalDefaultsUsed).length > 0 && { defaultsUsed: finalDefaultsUsed }),
504
725
  ...(warnings.length > 0 && { warnings }),
505
726
  js: buildJsField(componentData, jsApiMap),
506
727
  cdn: cdnMeta ?? undefined,
package/bin/types.d.ts CHANGED
@@ -85,6 +85,16 @@ export interface JsApiInfo {
85
85
  methods: string[];
86
86
  staticMethods?: string[];
87
87
  example: string;
88
+ /** Story 5.9: CDN init script 생성 시 사용자 props 와 deep merge 되는 default 옵션. JSON-serializable 만 (함수 prop 없음). */
89
+ cdnDefaults?: Record<string, unknown>;
90
+ /**
91
+ * CDN 호출 패턴.
92
+ * - A: `new ncua.X(element, options)` — element가 곧 컨테이너
93
+ * - B: `new ncua.X(options)` — options.container로 자동 append
94
+ * - C: `new ncua.X(options)` — getElement() + 수동 append
95
+ * 부재 시 React 정적 HTML 경로로 fallback.
96
+ */
97
+ cdnPattern?: 'A' | 'B' | 'C';
88
98
  }
89
99
  export interface ComplianceRuleHint {
90
100
  attr: string;
@@ -3,7 +3,7 @@
3
3
  "exportName": "BadgeGroup",
4
4
  "importPath": "@ncds/ui-admin",
5
5
  "jsRequired": false,
6
- "category": "feedback",
6
+ "category": "feedback-and-status",
7
7
  "description": "BadgeGroup은 Badge 컴포넌트를 그룹화하여 표시하는 컴포넌트입니다. 주로 Badge와 함께 추가적인 라벨과 아이콘을 표시하여 액션유도할 수 있는 아이템으로 활용할 수 있습니다.",
8
8
  "aliases": [
9
9
  "BadgeGroup",
@@ -59,7 +59,7 @@
59
59
  "groupIcon": {
60
60
  "type": "object",
61
61
  "required": false,
62
- "rawType": "import(\"/Users/nhn/Project/ncds/packages/ui-admin/src/types/side-slot\").SideSlotType | undefined",
62
+ "rawType": "import(\"/Users/nhncommerce/Desktop/project/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/nhn/Project/ncds/packages/ui-admin/src/types/side-slot\").SideSlotType | undefined",
137
+ "rawType": "import(\"/Users/nhncommerce/Desktop/project/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/nhn/Project/ncds/packages/ui-admin/src/types/side-slot\").SideSlotType | undefined",
214
+ "rawType": "import(\"/Users/nhncommerce/Desktop/project/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
@@ -3,7 +3,7 @@
3
3
  "exportName": "Badge",
4
4
  "importPath": "@ncds/ui-admin",
5
5
  "jsRequired": false,
6
- "category": "data-display",
6
+ "category": "feedback-and-status",
7
7
  "description": "Badge는 상태나 중요성 및 이벤트 강조를 나타내는 레이블이며 빠른 인식을 제공해야 합니다.",
8
8
  "aliases": [
9
9
  "Badge",
@@ -81,7 +81,7 @@
81
81
  "leadingIcon": {
82
82
  "type": "object",
83
83
  "required": false,
84
- "rawType": "import(\"/Users/nhn/Project/ncds/packages/ui-admin/src/types/side-slot\").SideSlotType | undefined",
84
+ "rawType": "import(\"/Users/nhncommerce/Desktop/project/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/nhn/Project/ncds/packages/ui-admin/src/types/side-slot\").SideSlotType | undefined",
157
+ "rawType": "import(\"/Users/nhncommerce/Desktop/project/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/nhn/Project/ncds/packages/ui-admin/src/components/bread-crumb/BreadCrumb\").BreadcrumbItemProps[]",
60
+ "rawType": "import(\"/Users/nhncommerce/Desktop/project/ncds/packages/ui-admin/src/components/navigation/bread-crumb/BreadCrumb\").BreadcrumbItemProps[]",
61
61
  "properties": {
62
62
  "href": {
63
63
  "type": "string",
@@ -89,6 +89,16 @@
89
89
  "required": false,
90
90
  "default": false
91
91
  },
92
+ "fullWidth": {
93
+ "type": "boolean",
94
+ "required": false,
95
+ "default": false
96
+ },
97
+ "hasBorder": {
98
+ "type": "boolean",
99
+ "required": false,
100
+ "default": true
101
+ },
92
102
  "icon": {
93
103
  "type": "string",
94
104
  "required": false,
package/data/button.json CHANGED
@@ -77,7 +77,7 @@
77
77
  "leadingIcon": {
78
78
  "type": "object",
79
79
  "required": false,
80
- "rawType": "import(\"/Users/nhn/Project/ncds/packages/ui-admin/src/types/side-slot\").SideSlotType | undefined",
80
+ "rawType": "import(\"/Users/nhncommerce/Desktop/project/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/nhn/Project/ncds/packages/ui-admin/src/types/side-slot\").SideSlotType | undefined",
161
+ "rawType": "import(\"/Users/nhncommerce/Desktop/project/ncds/packages/ui-admin/src/types/side-slot\").SideSlotType | undefined",
162
162
  "properties": {
163
163
  "type": {
164
164
  "type": "string",
@@ -3,7 +3,7 @@
3
3
  "exportName": "CarouselArrow",
4
4
  "importPath": "@ncds/ui-admin",
5
5
  "jsRequired": false,
6
- "category": "feedback",
6
+ "category": "feedback-and-status",
7
7
  "description": "CarouselArrow는 캐러셀의 이전/다음 페이지로 이동할 수 있는 화살표 버튼 컴포넌트입니다.",
8
8
  "aliases": [
9
9
  "CarouselArrow",
@@ -3,7 +3,7 @@
3
3
  "exportName": "CarouselNumberGroup",
4
4
  "importPath": "@ncds/ui-admin",
5
5
  "jsRequired": false,
6
- "category": "feedback",
6
+ "category": "feedback-and-status",
7
7
  "description": "CarouselNumberGroup은 캐러셀의 현재 페이지와 전체 페이지 수를 표시하는 컴포넌트입니다.",
8
8
  "aliases": [
9
9
  "CarouselNumberGroup",
@@ -3,7 +3,7 @@
3
3
  "exportName": "Checkbox",
4
4
  "importPath": "@ncds/ui-admin",
5
5
  "jsRequired": false,
6
- "category": "input",
6
+ "category": "forms-and-input",
7
7
  "description": "체크박스는 사용자가 목록에서 하나 이상의 항목을 선택하거나 옵션을 활성화/비활성화할 때 사용하는 핵심 Selection 컴포넌트입니다.",
8
8
  "aliases": [
9
9
  "체크박스",
@@ -3,7 +3,7 @@
3
3
  "exportName": "ComboBox",
4
4
  "importPath": "@ncds/ui-admin",
5
5
  "jsRequired": true,
6
- "category": "input",
6
+ "category": "forms-and-input",
7
7
  "description": "ComboBox는 여러 개의 데이터에서 검색(입력)하거나 리스트에서 옵션을 골라 빠르게 선택하는 복합 선택 컴포넌트입니다.",
8
8
  "aliases": [
9
9
  "콤보박스",
@@ -92,7 +92,7 @@
92
92
  "optionItems": {
93
93
  "type": "object",
94
94
  "required": false,
95
- "rawType": "import(\"/Users/nhn/Project/ncds/packages/ui-admin/src/types/dropdown/option\").OptionType[] | undefined",
95
+ "rawType": "import(\"/Users/nhncommerce/Desktop/project/ncds/packages/ui-admin/src/types/dropdown/option\").OptionType[] | undefined",
96
96
  "properties": {
97
97
  "id": {
98
98
  "type": "string",
@@ -119,7 +119,7 @@
119
119
  "register": {
120
120
  "type": "object",
121
121
  "required": false,
122
- "rawType": "import(\"/Users/nhn/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"
122
+ "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"
123
123
  },
124
124
  "required": {
125
125
  "type": "boolean",
@@ -148,7 +148,7 @@
148
148
  "value": {
149
149
  "type": "object",
150
150
  "required": false,
151
- "rawType": "import(\"/Users/nhn/Project/ncds/packages/ui-admin/src/types/dropdown/option\").OptionValue | undefined"
151
+ "rawType": "import(\"/Users/nhncommerce/Desktop/project/ncds/packages/ui-admin/src/types/dropdown/option\").OptionValue | undefined"
152
152
  }
153
153
  },
154
154
  "html": {},
@@ -3,7 +3,7 @@
3
3
  "exportName": "DatePicker",
4
4
  "importPath": "@ncds/ui-admin",
5
5
  "jsRequired": true,
6
- "category": "input",
6
+ "category": "forms-and-input",
7
7
  "description": "DatePicker는 등록일, 노출일, 검색 기간 등 날짜 또는 시간 설정이 필요한 경우 사용하는 선택 위젯입니다.",
8
8
  "aliases": [
9
9
  "날짜선택위젯",
@@ -62,7 +62,7 @@
62
62
  "datePickerOptions": {
63
63
  "type": "object",
64
64
  "required": false,
65
- "rawType": "Partial<import(\"/Users/nhn/Project/ncds/node_modules/.pnpm/flatpickr@4.6.13/node_modules/flatpickr/dist/types/options\").BaseOptions> | undefined"
65
+ "rawType": "Partial<import(\"/Users/nhncommerce/Desktop/project/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",
package/data/divider.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "exportName": "Divider",
4
4
  "importPath": "@ncds/ui-admin",
5
5
  "jsRequired": false,
6
- "category": "data-display",
6
+ "category": "layout",
7
7
  "description": "콘텐츠 영역을 시각적으로 구분하는 수평 또는 수직 구분선 컴포넌트입니다.",
8
8
  "aliases": [
9
9
  "Divider",
package/data/dot.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "exportName": "Dot",
4
4
  "importPath": "@ncds/ui-admin",
5
5
  "jsRequired": false,
6
- "category": "icon",
6
+ "category": "image-and-icons",
7
7
  "description": "Dot 컴포넌트는 상태나 알림을 시각적으로 표시하기 위한 작은 원형 표시기입니다",
8
8
  "aliases": [
9
9
  "Dot",