@wishket/design-system 3.4.2 → 3.5.0

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 (89) hide show
  1. package/dist/Components/Base/Typography/Typography.d.ts +0 -9
  2. package/dist/Components/Base/Typography/Typography.js +2 -2
  3. package/dist/Components/DataDisplays/ImageLabel/ImageLabel.js +1 -1
  4. package/dist/Components/Feedbacks/DialogBox/DialogBox.js +6 -6
  5. package/dist/Components/Feedbacks/GlobalLoadingIndicator/GlobalLoadingIndicator.js +1 -1
  6. package/dist/Components/Feedbacks/Tooltip/Tooltip.js +3 -3
  7. package/dist/Components/Inputs/AutoCompleteList/AutoCompleteList.d.ts +2 -2
  8. package/dist/Components/Inputs/AutoCompleteList/AutoCompleteList.js +22 -7
  9. package/dist/Components/Inputs/AutoCompleteList/AutoCompleteList.types.d.ts +17 -0
  10. package/dist/Components/Inputs/Autocomplete/Autocomplete.d.ts +3 -1
  11. package/dist/Components/Inputs/Autocomplete/Autocomplete.js +28 -5
  12. package/dist/Components/Inputs/Autocomplete/Autocomplete.types.d.ts +18 -0
  13. package/dist/Components/Inputs/Checkbox/Checkbox.js +4 -4
  14. package/dist/Components/Inputs/Checkbox/Checkbox.parts.js +3 -3
  15. package/dist/Components/Inputs/Checkbox/Checkbox.types.d.ts +0 -1
  16. package/dist/Components/Inputs/CheckboxCard/CheckboxCard.js +4 -4
  17. package/dist/Components/Inputs/CheckboxCard/CheckboxCard.parts.js +4 -4
  18. package/dist/Components/Inputs/FileUploader/FileUploader.js +4 -4
  19. package/dist/Components/Inputs/IconButtonDropdown/IconButtonDropdown.js +4 -4
  20. package/dist/Components/Inputs/Input/Input.js +1 -1
  21. package/dist/Components/Inputs/Input/PasswordInput.js +3 -3
  22. package/dist/Components/Inputs/InputChip/InputChip.d.ts +16 -3
  23. package/dist/Components/Inputs/InputChip/InputChip.js +13 -4
  24. package/dist/Components/Inputs/Radio/Radio.js +5 -5
  25. package/dist/Components/Inputs/RadioCard/RadioCard.js +5 -5
  26. package/dist/Components/Inputs/RadioCard/RadioCard.parts.js +4 -4
  27. package/dist/Components/Inputs/RangeSlider/RangeSlider.js +2 -2
  28. package/dist/Components/Inputs/SearchField/SearchField.js +5 -5
  29. package/dist/Components/Inputs/TextField/TextField.js +1 -1
  30. package/dist/Components/Inputs/TextFieldDropdown/TextFieldDropdown.d.ts +24 -3
  31. package/dist/Components/Inputs/TextFieldDropdown/TextFieldDropdown.js +10 -54
  32. package/dist/Components/Inputs/TextFieldDropdown/TextFieldDropdown.parts.d.ts +9 -0
  33. package/dist/Components/Inputs/TextFieldDropdown/TextFieldDropdown.parts.js +1 -1
  34. package/dist/Components/Inputs/TextFieldTrigger/TextFieldTrigger.d.ts +73 -0
  35. package/dist/Components/Inputs/TextFieldTrigger/TextFieldTrigger.js +62 -0
  36. package/dist/Components/Inputs/TextFieldTrigger/index.d.ts +2 -0
  37. package/dist/Components/Inputs/Textarea/Textarea.js +4 -4
  38. package/dist/Components/Inputs/index.d.ts +1 -0
  39. package/dist/Components/Navigations/Drawer/Drawer.js +3 -3
  40. package/dist/Components/Navigations/Menu/MenuBase.js +3 -3
  41. package/dist/Components/Utils/BackDrop/BackDrop.js +1 -1
  42. package/dist/Components/Utils/BackDropLiftContainer/BackDropLiftContainer.js +2 -2
  43. package/dist/Components/Utils/BottomModalContainer/BottomModalContainer.js +1 -1
  44. package/dist/Components/Utils/FullModalContainer/FullModalContainer.js +1 -1
  45. package/dist/Components/Utils/Modal/Modal.js +3 -3
  46. package/dist/Components/Utils/ModalContainer/ModalContainer.js +2 -2
  47. package/dist/Components/Wrappers/WithBadge/WithBadge.js +2 -2
  48. package/dist/Components/Wrappers/WithSnackBar/WithSnackBar.js +3 -3
  49. package/dist/cjs/Components/Base/Typography/Typography.js +1 -1
  50. package/dist/cjs/Components/DataDisplays/ImageLabel/ImageLabel.js +3 -3
  51. package/dist/cjs/Components/Feedbacks/DialogBox/DialogBox.js +6 -6
  52. package/dist/cjs/Components/Feedbacks/GlobalLoadingIndicator/GlobalLoadingIndicator.js +1 -1
  53. package/dist/cjs/Components/Feedbacks/Tooltip/Tooltip.js +3 -3
  54. package/dist/cjs/Components/Inputs/AutoCompleteList/AutoCompleteList.js +22 -7
  55. package/dist/cjs/Components/Inputs/Autocomplete/Autocomplete.js +25 -4
  56. package/dist/cjs/Components/Inputs/Checkbox/Checkbox.js +4 -4
  57. package/dist/cjs/Components/Inputs/Checkbox/Checkbox.parts.js +5 -5
  58. package/dist/cjs/Components/Inputs/CheckboxCard/CheckboxCard.js +4 -4
  59. package/dist/cjs/Components/Inputs/CheckboxCard/CheckboxCard.parts.js +4 -4
  60. package/dist/cjs/Components/Inputs/FileUploader/FileUploader.js +6 -6
  61. package/dist/cjs/Components/Inputs/IconButtonDropdown/IconButtonDropdown.js +3 -3
  62. package/dist/cjs/Components/Inputs/Input/Input.js +2 -2
  63. package/dist/cjs/Components/Inputs/Input/PasswordInput.js +2 -2
  64. package/dist/cjs/Components/Inputs/InputChip/InputChip.js +36 -2
  65. package/dist/cjs/Components/Inputs/Radio/Radio.js +6 -6
  66. package/dist/cjs/Components/Inputs/RadioCard/RadioCard.js +4 -4
  67. package/dist/cjs/Components/Inputs/RadioCard/RadioCard.parts.js +4 -4
  68. package/dist/cjs/Components/Inputs/RangeSlider/RangeSlider.js +3 -3
  69. package/dist/cjs/Components/Inputs/SearchField/SearchField.js +3 -3
  70. package/dist/cjs/Components/Inputs/TextField/TextField.js +2 -2
  71. package/dist/cjs/Components/Inputs/TextFieldDropdown/TextFieldDropdown.js +10 -8
  72. package/dist/cjs/Components/Inputs/TextFieldDropdown/TextFieldDropdown.parts.js +1 -1
  73. package/dist/cjs/Components/Inputs/TextFieldTrigger/TextFieldTrigger.js +62 -0
  74. package/dist/cjs/Components/Inputs/Textarea/Textarea.js +5 -5
  75. package/dist/cjs/Components/Navigations/Drawer/Drawer.js +3 -3
  76. package/dist/cjs/Components/Navigations/Menu/MenuBase.js +3 -3
  77. package/dist/cjs/Components/Utils/BackDrop/BackDrop.js +1 -1
  78. package/dist/cjs/Components/Utils/BackDropLiftContainer/BackDropLiftContainer.js +2 -2
  79. package/dist/cjs/Components/Utils/BottomModalContainer/BottomModalContainer.js +1 -1
  80. package/dist/cjs/Components/Utils/FullModalContainer/FullModalContainer.js +1 -1
  81. package/dist/cjs/Components/Utils/Modal/Modal.js +2 -2
  82. package/dist/cjs/Components/Utils/ModalContainer/ModalContainer.js +2 -2
  83. package/dist/cjs/Components/Wrappers/WithBadge/WithBadge.js +1 -1
  84. package/dist/cjs/Components/Wrappers/WithSnackBar/WithSnackBar.js +1 -1
  85. package/dist/cjs/index.js +1 -1
  86. package/dist/index.js +1 -1
  87. package/package.json +3 -2
  88. package/scripts/codemods/add-as-link.ts +9 -5
  89. package/scripts/codemods/menu-split.ts +25 -11
@@ -1,15 +1,6 @@
1
1
  import { ComponentPropsWithRef, ElementType, ReactElement } from 'react';
2
2
  import { TypographyProps } from './Typography.types';
3
3
  type PolymorphicRef<T extends ElementType> = ComponentPropsWithRef<T>['ref'];
4
- /**
5
- * Typography
6
- * @param {Object} props
7
- * @param {React.ReactNode} props.children - Typography 내부에 들어갈 컨텐츠
8
- * @param {string} props.variant - 텍스트 스타일 variant ('title48' | 'title32' | 'title24' | 'subTitle20' | 'subTitle18' | 'contents18' | 'contents16' | 'body16' | 'body14' | 'body13' | 'caption12' | 'caption11')
9
- * @param {string} [props.className] - 추가적인 CSS 클래스
10
- * @param {keyof JSX.IntrinsicElements} [props.as='span'] - 렌더링할 HTML 요소
11
- * @param {Ref} [props.ref] - 렌더된 요소로 forward되는 ref. as에 따라 추론
12
- */
13
4
  declare const Typography: <T extends ElementType = "span">(props: TypographyProps<T> & {
14
5
  ref?: PolymorphicRef<T>;
15
6
  }) => ReactElement | null;
@@ -1,4 +1,4 @@
1
- import{jsx as t}from"react/jsx-runtime";import{twMerge as e}from"tailwind-merge";import{forwardRef as n}from"react";function r(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}function o(t,e){return e=null!=e?e:{},Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(e)):function(t){var e=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e.push.apply(e,n)}return e}(Object(e)).forEach((function(n){Object.defineProperty(t,n,Object.getOwnPropertyDescriptor(e,n))})),t}function c(t,e){if(null==t)return{};var n,r,o=function(t,e){if(null==t)return{};var n,r,o={},c=Object.keys(t);for(r=0;r<c.length;r++)n=c[r],e.indexOf(n)>=0||(o[n]=t[n]);return o}(t,e);if(Object.getOwnPropertySymbols){var c=Object.getOwnPropertySymbols(t);for(r=0;r<c.length;r++)n=c[r],e.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(t,n)&&(o[n]=t[n])}return o}const a=[{name:"title48",class:"typo-title48"},{name:"title32",class:"typo-title32"},{name:"title28",class:"typo-title28"},{name:"title24",class:"typo-title24"},{name:"subTitle20",class:"typo-subTitle20"},{name:"subTitle18",class:"typo-subTitle18"},{name:"contents18",class:"typo-contents18"},{name:"contents16",class:"typo-contents16"},{name:"body16",class:"typo-body16"},{name:"body14",class:"typo-body14"},{name:"body13",class:"typo-body13"},{name:"caption12",class:"typo-caption12"},{name:"caption11",class:"typo-caption11"}],s=/*#__PURE__*/n(((n,s)=>{var l,{children:i,variant:p,className:y,as:b}=n,u=c(n,["children","variant","className","as"]);const m=null!=b?b:"span",f=(null===(l=a.find((t=>t.name===p)))||void 0===l?void 0:l.class)||"";/*#__PURE__*/
1
+ import{jsx as t}from"react/jsx-runtime";import{twMerge as e}from"tailwind-merge";import{forwardRef as n}from"react";function r(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}function o(t,e){return e=null!=e?e:{},Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(e)):function(t){var e=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e.push.apply(e,n)}return e}(Object(e)).forEach((function(n){Object.defineProperty(t,n,Object.getOwnPropertyDescriptor(e,n))})),t}function a(t,e){if(null==t)return{};var n,r,o=function(t,e){if(null==t)return{};var n,r,o={},a=Object.keys(t);for(r=0;r<a.length;r++)n=a[r],e.indexOf(n)>=0||(o[n]=t[n]);return o}(t,e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(t);for(r=0;r<a.length;r++)n=a[r],e.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(t,n)&&(o[n]=t[n])}return o}const c=[{name:"title48",class:"typo-title48"},{name:"title32",class:"typo-title32"},{name:"title28",class:"typo-title28"},{name:"title24",class:"typo-title24"},{name:"subTitle20",class:"typo-subTitle20"},{name:"subTitle18",class:"typo-subTitle18"},{name:"contents18",class:"typo-contents18"},{name:"contents16",class:"typo-contents16"},{name:"body16",class:"typo-body16"},{name:"body14",class:"typo-body14"},{name:"body13",class:"typo-body13"},{name:"caption12",class:"typo-caption12"},{name:"caption11",class:"typo-caption11"}],s=/*#__PURE__*/n(((n,s)=>{var l,{children:i,variant:p,className:y,as:b}=n,u=a(n,["children","variant","className","as"]);const m=null!=b?b:"span",f=(null===(l=c.find((t=>t.name===p)))||void 0===l?void 0:l.class)||"";/*#__PURE__*/
2
2
  return t(m,o(function(t){for(var e=1;e<arguments.length;e++){var n=null!=arguments[e]?arguments[e]:{},o=Object.keys(n);"function"==typeof Object.getOwnPropertySymbols&&(o=o.concat(Object.getOwnPropertySymbols(n).filter((function(t){return Object.getOwnPropertyDescriptor(n,t).enumerable})))),o.forEach((function(e){r(t,e,n[e])}))}return t}({ref:s,className:e("tracking-default",f,y)},u),{children:i}))}));
3
3
  /**
4
4
  * Typography
@@ -8,4 +8,4 @@ return t(m,o(function(t){for(var e=1;e<arguments.length;e++){var n=null!=argumen
8
8
  * @param {string} [props.className] - 추가적인 CSS 클래스
9
9
  * @param {keyof JSX.IntrinsicElements} [props.as='span'] - 렌더링할 HTML 요소
10
10
  * @param {Ref} [props.ref] - 렌더된 요소로 forward되는 ref. as에 따라 추론
11
- */export{s as Typography};
11
+ */s.displayName="Typography";const l=s;export{l as Typography};
@@ -1,4 +1,4 @@
1
- import{jsx as r}from"react/jsx-runtime";import{twJoin as e}from"tailwind-merge";import"react";import{Box as t}from"../../Base/Layouts/Box/Box.js";import"../../Base/Layouts/FullBleed/FullBleed.js";import{NewCircle as s}from"./parts/NewCircle.js";import{New as a}from"./parts/New.js";import{Beta as i}from"./parts/Beta.js";import{Ai as o}from"./parts/Ai.js";
1
+ import{jsx as r}from"react/jsx-runtime";import{twJoin as e}from"tailwind-merge";import"../../Base/Typography/Typography.js";import{Box as t}from"../../Base/Layouts/Box/Box.js";import"../../Base/Layouts/FullBleed/FullBleed.js";import{NewCircle as s}from"./parts/NewCircle.js";import{New as a}from"./parts/New.js";import{Beta as i}from"./parts/Beta.js";import{Ai as o}from"./parts/Ai.js";import"react";
2
2
  /**
3
3
  * 이미지에 오버레이되는 라벨을 표시하는 컴포넌트
4
4
  * @param {('new_circle'|'new'|'beta'|'ai')} props.type - 표시할 라벨의 타입
@@ -1,6 +1,6 @@
1
- "use client";import{jsxs as e,jsx as r}from"react/jsx-runtime";import{twJoin as o}from"tailwind-merge";import{Typography as a}from"../../Base/Typography/Typography.js";import{Box as l}from"../../Base/Layouts/Box/Box.js";import"../../Base/Layouts/FullBleed/FullBleed.js";import{Button as t}from"../../Inputs/Button/Button.js";const i=({title:i,description:s,variant:n="primary",onClose:c,onConfirm:m,confirm:d,close:g="닫기",testId:p})=>{const u="caution"===n;/*#__PURE__*/
2
- return e(l,{className:"bg-w-white shadow-modal tablet:w-[400px] flex h-fit max-w-[calc(100vw-40px)] flex-col items-center gap-8 rounded-3xl p-8 font-normal not-italic","data-testid":p||"design-system--dialog-box",children:[
3
- /*#__PURE__*/e(l,{className:"flex w-full flex-col gap-6",children:[
4
- /*#__PURE__*/r(a,{variant:"subTitle18",className:"text-w-gray-900 font-medium",children:i}),
5
- /*#__PURE__*/r(a,{variant:"body16",className:"text-w-gray-800 whitespace-break-spaces",children:s})]}),
6
- /*#__PURE__*/e(l,{className:"flex w-full items-center justify-end gap-4",children:[g&&/*#__PURE__*/r(t,{role:"close",onClick:c,variant:"solid",className:"border-w-bluegray-200 bg-w-bluegray-200 hover:border-w-bluegray-300 hover:bg-w-bluegray-300",children:g}),d&&/*#__PURE__*/r(t,{role:"confirm",onClick:m,variant:"solid",className:o(u&&"border-w-orange-500 bg-w-orange-500 hover:border-w-orange-600 hover:bg-w-orange-600"),children:d})]})]})};export{i as DialogBox};
1
+ "use client";import{jsxs as e,jsx as r}from"react/jsx-runtime";import{twJoin as a}from"tailwind-merge";import{Typography as o}from"../../Base/Typography/Typography.js";import{Box as t}from"../../Base/Layouts/Box/Box.js";import"../../Base/Layouts/FullBleed/FullBleed.js";import{Button as l}from"../../Inputs/Button/Button.js";const i=({title:i,description:s,variant:n="primary",onClose:c,onConfirm:m,confirm:d,close:g="닫기",testId:p})=>{const u="caution"===n;/*#__PURE__*/
2
+ return e(t,{className:"bg-w-white shadow-modal tablet:w-[400px] flex h-fit max-w-[calc(100vw-40px)] flex-col items-center gap-8 rounded-3xl p-8 font-normal not-italic","data-testid":p||"design-system--dialog-box",children:[
3
+ /*#__PURE__*/e(t,{className:"flex w-full flex-col gap-6",children:[
4
+ /*#__PURE__*/r(o,{variant:"subTitle18",className:"text-w-gray-900 font-medium",children:i}),
5
+ /*#__PURE__*/r(o,{variant:"body16",className:"text-w-gray-800 whitespace-break-spaces",children:s})]}),
6
+ /*#__PURE__*/e(t,{className:"flex w-full items-center justify-end gap-4",children:[g&&/*#__PURE__*/r(l,{onClick:c,variant:"solid",className:"border-w-bluegray-200 bg-w-bluegray-200 hover:border-w-bluegray-300 hover:bg-w-bluegray-300",children:g}),d&&/*#__PURE__*/r(l,{onClick:m,variant:"solid",className:a(u&&"border-w-orange-500 bg-w-orange-500 hover:border-w-orange-600 hover:bg-w-orange-600"),children:d})]})]})};export{i as DialogBox};
@@ -1,4 +1,4 @@
1
- "use client";import{jsx as e}from"react/jsx-runtime";import{useId as t,useState as r,useEffect as n}from"react";import"tailwind-merge";import"@wishket/yogokit";import"../../Base/Layouts/Box/Box.js";import"../../Base/Layouts/FullBleed/FullBleed.js";import{Portal as s}from"../../Utils/Portal/Portal.js";import{LoadingIndicator as o}from"../LoadingIndicator/LoadingIndicator.js";function i(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{},n=Object.keys(r);"function"==typeof Object.getOwnPropertySymbols&&(n=n.concat(Object.getOwnPropertySymbols(r).filter((function(e){return Object.getOwnPropertyDescriptor(r,e).enumerable})))),n.forEach((function(t){i(e,t,r[t])}))}return e}class l{static getInstance(){return l.instance||(l.instance=new l),l.instance}register(e){this.loaderIds.includes(e)||this.loaderIds.push(e)}unregister(e){this.loaderIds=this.loaderIds.filter((t=>t!==e))}getIsLastIndex(e){return this.loaderIds[this.loaderIds.length-1]===e}constructor(){i(this,"loaderIds",[])}}i(l,"instance",void 0);
1
+ "use client";import{jsx as e}from"react/jsx-runtime";import{useId as t,useState as r,useEffect as n}from"react";import"tailwind-merge";import"@wishket/yogokit";import"../../Base/Typography/Typography.js";import"../../Base/Layouts/Box/Box.js";import"../../Base/Layouts/FullBleed/FullBleed.js";import{Portal as s}from"../../Utils/Portal/Portal.js";import{LoadingIndicator as o}from"../LoadingIndicator/LoadingIndicator.js";function i(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{},n=Object.keys(r);"function"==typeof Object.getOwnPropertySymbols&&(n=n.concat(Object.getOwnPropertySymbols(r).filter((function(e){return Object.getOwnPropertyDescriptor(r,e).enumerable})))),n.forEach((function(t){i(e,t,r[t])}))}return e}class l{static getInstance(){return l.instance||(l.instance=new l),l.instance}register(e){this.loaderIds.includes(e)||this.loaderIds.push(e)}unregister(e){this.loaderIds=this.loaderIds.filter((t=>t!==e))}getIsLastIndex(e){return this.loaderIds[this.loaderIds.length-1]===e}constructor(){i(this,"loaderIds",[])}}i(l,"instance",void 0);
2
2
  /**
3
3
  * 전역 로딩 인디케이터 컴포넌트입니다.
4
4
  * 화면 중앙에 로딩 스피너를 표시하며, 여러 개의 로딩 인디케이터가 동시에 존재할 경우
@@ -1,4 +1,4 @@
1
- "use client";import{jsx as i}from"react/jsx-runtime";import{twMerge as t}from"tailwind-merge";import"react";import{Box as e}from"../../Base/Layouts/Box/Box.js";import"../../Base/Layouts/FullBleed/FullBleed.js";import{PlainTooltip as o}from"./PlainTooltip/PlainTooltip.js";import{RichTooltip as l}from"./RichTooltip/RichTooltip.js";
1
+ "use client";import{jsx as i}from"react/jsx-runtime";import{twMerge as t}from"tailwind-merge";import"../../Base/Typography/Typography.js";import{Box as o}from"../../Base/Layouts/Box/Box.js";import"../../Base/Layouts/FullBleed/FullBleed.js";import{PlainTooltip as e}from"./PlainTooltip/PlainTooltip.js";import{RichTooltip as l}from"./RichTooltip/RichTooltip.js";
2
2
  /**
3
3
  * 툴팁의 루트 컴포넌트입니다.
4
4
  * CSS 기반 hover와 focus로 동작합니다.
@@ -13,7 +13,7 @@
13
13
  * </Tooltip.Trigger>
14
14
  * <Tooltip.Plain variant="up" text="간단한 툴팁" />
15
15
  * </Tooltip>
16
- */const r=({children:o,className:l})=>/*#__PURE__*/i(e,{className:t("group relative inline-block h-fit w-fit",l),"data-testid":"design-system-tooltip",children:o});
16
+ */const r=({children:e,className:l})=>/*#__PURE__*/i(o,{className:t("group relative inline-block h-fit w-fit",l),"data-testid":"design-system-tooltip",children:e});
17
17
  /**
18
18
  * 툴팁 트리거 컴포넌트입니다.
19
19
  * 데스크톱에서는 CSS hover로, 모바일에서는 터치(focus)로 툴팁을 표시합니다.
@@ -22,4 +22,4 @@
22
22
  * <Tooltip.Trigger>
23
23
  * <SystemIcon name="medium_information" />
24
24
  * </Tooltip.Trigger>
25
- */r.Trigger=({children:t})=>/*#__PURE__*/i(e,{"data-testid":"design-system-tooltip--trigger",className:"h-fit w-fit focus:outline-hidden",tabIndex:0,children:t}),r.Plain=o,r.Rich=l;export{r as Tooltip};
25
+ */r.Trigger=({children:t})=>/*#__PURE__*/i(o,{"data-testid":"design-system-tooltip--trigger",className:"h-fit w-fit focus:outline-hidden",tabIndex:0,children:t}),r.Plain=e,r.Rich=l;export{r as Tooltip};
@@ -23,8 +23,8 @@ import type { ItemProps, AutoCompleteListRootProps } from './AutoCompleteList.ty
23
23
  * ```
24
24
  */
25
25
  declare const AutoCompleteList: {
26
- Root: ({ children, className, hasIndexBar, onIndexClick, ...rest }: AutoCompleteListRootProps) => import("react/jsx-runtime").JSX.Element;
27
- Item: ({ text, count, leadingIcon, iconUrl, isInputItem, isFocused, inputValue, className, ...rest }: ItemProps) => import("react/jsx-runtime").JSX.Element;
26
+ Root: ({ children, className, hasIndexBar, onIndexClick, listboxId, ...rest }: AutoCompleteListRootProps) => import("react/jsx-runtime").JSX.Element;
27
+ Item: ({ text, count, leadingIcon, iconUrl, isInputItem, isFocused, isSelected, inputValue, className, ...rest }: ItemProps) => import("react/jsx-runtime").JSX.Element;
28
28
  Divider: () => import("react/jsx-runtime").JSX.Element;
29
29
  };
30
30
  export { AutoCompleteList };
@@ -1,10 +1,19 @@
1
- "use client";import{jsx as e,jsxs as t}from"react/jsx-runtime";import{twMerge as r}from"tailwind-merge";import{useRef as n,useState as o,useLayoutEffect as i}from"react";import"../../DataDisplays/Avatar/Avatar.js";import"../../Base/Layouts/Box/Box.js";import"../../Base/Layouts/FullBleed/FullBleed.js";import{SystemIcon as s}from"../../DataDisplays/SystemIcon/SystemIcon.js";import"../../DataDisplays/SystemIcon/SystemIcon.constants.js";import{Divider as l}from"../../DataDisplays/Divider/Divider.js";import"../../DataDisplays/Accordion/Accordion.js";import{IndexBar as a,Icon as c,TextSection as u,CountSection as m}from"./AutoCompleteList.parts.js";function p(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function d(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{},n=Object.keys(r);"function"==typeof Object.getOwnPropertySymbols&&(n=n.concat(Object.getOwnPropertySymbols(r).filter((function(e){return Object.getOwnPropertyDescriptor(r,e).enumerable})))),n.forEach((function(t){p(e,t,r[t])}))}return e}function y(e,t){return t=null!=t?t:{},Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):function(e){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t.push.apply(t,r)}return t}(Object(t)).forEach((function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(t,r))})),e}function f(e,t){if(null==e)return{};var r,n,o=function(e,t){if(null==e)return{};var r,n,o={},i=Object.keys(e);for(n=0;n<i.length;n++)r=i[n],t.indexOf(r)>=0||(o[r]=e[r]);return o}
1
+ "use client";import{jsx as e,jsxs as t}from"react/jsx-runtime";import{twMerge as r}from"tailwind-merge";import{useRef as o,useState as n,useLayoutEffect as i}from"react";import"../../DataDisplays/Avatar/Avatar.js";import"../../Base/Typography/Typography.js";import"../../Base/Layouts/Box/Box.js";import"../../Base/Layouts/FullBleed/FullBleed.js";import{SystemIcon as s}from"../../DataDisplays/SystemIcon/SystemIcon.js";import"../../DataDisplays/SystemIcon/SystemIcon.constants.js";import{Divider as l}from"../../DataDisplays/Divider/Divider.js";import"../../DataDisplays/Accordion/Accordion.js";import{IndexBar as a,Icon as c,TextSection as u,CountSection as p}from"./AutoCompleteList.parts.js";function m(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function d(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{},o=Object.keys(r);"function"==typeof Object.getOwnPropertySymbols&&(o=o.concat(Object.getOwnPropertySymbols(r).filter((function(e){return Object.getOwnPropertyDescriptor(r,e).enumerable})))),o.forEach((function(t){m(e,t,r[t])}))}return e}function y(e,t){return t=null!=t?t:{},Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):function(e){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t.push.apply(t,r)}return t}(Object(t)).forEach((function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(t,r))})),e}function f(e,t){if(null==e)return{};var r,o,n=function(e,t){if(null==e)return{};var r,o,n={},i=Object.keys(e);for(o=0;o<i.length;o++)r=i[o],t.indexOf(r)>=0||(n[r]=e[r]);return n}
2
2
  /**
3
3
  * 자동완성 목록의 Root 컴포넌트입니다.
4
4
  * 자동완성 항목들을 감싸는 컨테이너 역할을 합니다.
5
5
  *
6
+ * WAI-ARIA APG의 Combobox with List Autocomplete 패턴에 맞춰 실제 목록인
7
+ * `<ul>`에 `role="listbox"`와 `aria-multiselectable="true"`를 항상 부여합니다
8
+ * (`Autocomplete`이 다중 선택 위젯이라 옵션마다 `aria-selected`를 따로 갖습니다).
9
+ * `listboxId`를 넘기면 그 값이 이 `<ul>`의 `id`가 되므로, `Autocomplete`의
10
+ * 입력 필드가 `aria-controls`로 참조할 수 있습니다. `{...rest}`(`className` 제외)와
11
+ * `className`은 그대로 바깥 `<div>`(그림자, IndexBar를 포함하는 레이아웃 전용
12
+ * 래퍼)에 적용됩니다.
13
+ *
6
14
  * @param {Object} props
7
15
  * @param {ReactNode} props.children - 자동완성 목록에 표시될 자식 컴포넌트들 (AutoCompleteList.Item, AutoCompleteList.Divider)
16
+ * @param {string} [props.listboxId] - 실제 목록(`<ul role="listbox">`)에 부여할 id
8
17
  *
9
18
  * @example
10
19
  * ```tsx
@@ -21,11 +30,11 @@
21
30
  * />
22
31
  * </AutoCompleteList.Root>
23
32
  * ```
24
- */(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n<i.length;n++)r=i[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}const b={Root:s=>{var{children:l,className:c,hasIndexBar:u=!1,onIndexClick:m}=s,p=f(s,["children","className","hasIndexBar","onIndexClick"]);const b=n(null),[g,O]=o(!1);return i((()=>{const e=b.current;if(!e)return;const{scrollHeight:t,clientHeight:r}=e;O(t>r)}),[l]),/*#__PURE__*/t("div",y(d({className:r("shadow-graymedium flex max-h-[436px] w-full rounded-xl",c)},p),{children:[u&&/*#__PURE__*/e(a,{onIndexClick:m}),
25
- /*#__PURE__*/e("ul",{ref:b,"data-testid":"design-system-autoCompleteList",className:r("bg-w-white flex w-full flex-col py-2 pr-2","scrollbar-list overflow-y-auto",u?"rounded-r-xl":"rounded-xl",g&&"pr-0"),children:l})]}))},Item:n=>{var{text:o,count:i,leadingIcon:l,iconUrl:a,isInputItem:p=!1,isFocused:b=!1,inputValue:g,className:O}=n,j=f(n,["text","count","leadingIcon","iconUrl","isInputItem","isFocused","inputValue","className"]);/*#__PURE__*/
26
- return t("li",y(d({className:r("bg-w-white hover:bg-primary-10 visible ml-2 flex cursor-pointer items-center gap-2 rounded-xl px-4 py-3 select-none",b&&"bg-primary-10",O)},j),{"data-testid":"design-system-list-item",children:[l&&/*#__PURE__*/e(s,{name:l,className:"text-w-gray-600",testId:"design-system-list-item-leading-icon"}),a&&/*#__PURE__*/e(c,{iconUrl:a}),
27
- /*#__PURE__*/e(u,{text:o,isInputItem:p,inputValue:g}),
28
- /*#__PURE__*/e(m,{count:i})]}))},Divider:()=>/*#__PURE__*/e(l,{className:"my-2"})};
33
+ */(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o<i.length;o++)r=i[o],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}const b={Root:s=>{var{children:l,className:c,hasIndexBar:u=!1,onIndexClick:p,listboxId:m}=s,b=f(s,["children","className","hasIndexBar","onIndexClick","listboxId"]);const g=o(null),[O,x]=n(!1);return i((()=>{const e=g.current;if(!e)return;const{scrollHeight:t,clientHeight:r}=e;x(t>r)}),[l]),/*#__PURE__*/t("div",y(d({className:r("shadow-graymedium flex max-h-[436px] w-full rounded-xl",c)},b),{children:[u&&/*#__PURE__*/e(a,{onIndexClick:p}),
34
+ /*#__PURE__*/e("ul",{ref:g,id:m,role:"listbox","aria-multiselectable":"true",className:r("bg-w-white flex w-full flex-col py-2 pr-2","scrollbar-list overflow-y-auto",u?"rounded-r-xl":"rounded-xl",O&&"pr-0"),"data-testid":"design-system-autoCompleteList",children:l})]}))},Item:o=>{var{text:n,count:i,leadingIcon:l,iconUrl:a,isInputItem:m=!1,isFocused:b=!1,isSelected:g=!1,inputValue:O,className:x}=o,j=f(o,["text","count","leadingIcon","iconUrl","isInputItem","isFocused","isSelected","inputValue","className"]);/*#__PURE__*/
35
+ return t("li",y(d({className:r("bg-w-white hover:bg-primary-10 visible ml-2 flex cursor-pointer items-center gap-2 rounded-xl px-4 py-3 select-none",b&&"bg-primary-10",x)},j),{role:"option","aria-selected":g,"data-testid":"design-system-list-item",children:[l&&/*#__PURE__*/e(s,{name:l,className:"text-w-gray-600",testId:"design-system-list-item-leading-icon"}),a&&/*#__PURE__*/e(c,{iconUrl:a}),
36
+ /*#__PURE__*/e(u,{text:n,isInputItem:m,inputValue:O}),
37
+ /*#__PURE__*/e(p,{count:i})]}))},Divider:()=>/*#__PURE__*/e(l,{className:"my-2"})};
29
38
  /**
30
39
  * 자동완성 목록의 개별 항목 컴포넌트입니다.
31
40
  * @param {Object} props
@@ -34,7 +43,13 @@ return t("li",y(d({className:r("bg-w-white hover:bg-primary-10 visible ml-2 flex
34
43
  * @param {SystemIconName} [props.leadingIcon] - 항목 앞에 표시될 시스템 아이콘
35
44
  * @param {string} [props.iconUrl] - 항목 앞에 표시될 커스텀 아이콘 URL
36
45
  * @param {boolean} [props.isInputItem=false] - 입력 항목 여부
37
- * @param {boolean} [props.isFocused=false] - 포커스 상태 여부
46
+ * @param {boolean} [props.isFocused=false] - 키보드 커서(활성 옵션) 여부. 시각 하이라이트(`bg-primary-10`)에만 반영되며 `aria-selected`와는 무관합니다.
47
+ * @param {boolean} [props.isSelected=false] - 실제로 선택된 항목인지 여부. `aria-selected`에 그대로 반영됩니다.
38
48
  * @param {string} [props.inputValue] - 입력값 (isInputItem이 true인 경우 사용)
39
49
  * @param {string} [props.className] - 추가적인 CSS 클래스
50
+ *
51
+ * `role="option"`이 항상 부여되며, `aria-selected`는 `isSelected`를 그대로 반영합니다.
52
+ * (`isFocused`는 시각 하이라이트 전용이며, `Autocomplete`처럼 다중 선택이 가능한
53
+ * 위젯에서는 커서 위치와 실제 선택 여부가 다르므로 분리했습니다.)
54
+ * `aria-activedescendant`가 가리킬 수 있도록 `id`를 넘겨야 합니다.
40
55
  */export{b as AutoCompleteList};
@@ -3,6 +3,12 @@ import { SystemIconName } from '../../DataDisplays';
3
3
  export interface AutoCompleteListRootProps extends PropsWithChildren<ComponentProps<'div'>> {
4
4
  hasIndexBar?: boolean;
5
5
  onIndexClick?: (index: string) => void;
6
+ /**
7
+ * 실제 목록인 `<ul role="listbox">`에 부여할 `id`입니다.
8
+ * `Autocomplete`의 입력 필드가 `aria-controls`로 이 값을 참조합니다.
9
+ * (그 외 `className` 등은 그대로 바깥 레이아웃용 `<div>`에 적용됩니다.)
10
+ */
11
+ listboxId?: string;
6
12
  }
7
13
  export interface ItemProps extends ComponentProps<'li'> {
8
14
  text: string;
@@ -10,6 +16,17 @@ export interface ItemProps extends ComponentProps<'li'> {
10
16
  leadingIcon?: SystemIconName;
11
17
  iconUrl?: string;
12
18
  isInputItem?: boolean;
19
+ /**
20
+ * 키보드 커서(활성 옵션) 여부. 시각 하이라이트(`bg-primary-10`)에만
21
+ * 반영되며 `aria-selected`와는 무관합니다. 실제 선택 여부는 `isSelected`로
22
+ * 전달하세요.
23
+ */
13
24
  isFocused?: boolean;
25
+ /**
26
+ * 실제로 선택된 항목인지 여부. `aria-selected`에 그대로 반영됩니다.
27
+ * `Autocomplete`은 다중 선택 위젯이므로 커서 위치(`isFocused`)와는
28
+ * 별개로 관리됩니다.
29
+ */
30
+ isSelected?: boolean;
14
31
  inputValue?: string;
15
32
  }
@@ -18,6 +18,8 @@ import { AutocompleteProps } from './Autocomplete.types';
18
18
  * @param {boolean} [props.isError] - 오류 상태 여부
19
19
  * @param {string} [props.errorMessage] - 오류 메시지
20
20
  * @param {ReactNode} [props.leadingIcon] - 항목 앞에 표시될 아이콘
21
+ * @param {string} [props.label] - 입력 필드의 접근 가능한 이름(스크린리더용). 화면에는 보이지 않는(sr-only) 텍스트를 렌더링하고, 입력 필드에 `aria-labelledby`로 그 텍스트만 연결합니다. `label`/`ariaLabel`이 모두 없으면 HTML-AAM 이름 계산 순서(aria-labelledby → aria-label → `<label>` → title → placeholder)의 마지막 폴백인 `placeholder`가 접근 가능한 이름이 됩니다(선택된 칩을 감싸는 컨테이너가 `<label>`이 아닌 `<div>`이므로 칩 텍스트는 더 이상 섞이지 않습니다). placeholder는 컨트롤의 정체를 온전히 설명하지 못하므로, 접근성을 신경 쓰는 화면이라면 `label` 또는 `ariaLabel`을 지정하는 것을 권장합니다.
22
+ * @param {string} [props.ariaLabel] - 입력 필드의 `aria-label`. `label`과 동시에 주어지면 `aria-label`이 우선합니다(둘 다 설정되면 `aria-labelledby`를 생성하지 않습니다).
21
23
  *
22
24
  * @example
23
25
  * ```tsx
@@ -38,5 +40,5 @@ import { AutocompleteProps } from './Autocomplete.types';
38
40
  * />
39
41
  * ```
40
42
  */
41
- declare const Autocomplete: ({ skillItems, legacySkillItems, selectedItems, onChipDelete, value, onValueChange, placeholder, onSkillItemClick, onLegacySkillItemClick, onInputItemClick, supportingText, hasIndexBar, isError, errorMessage, leadingIcon, }: AutocompleteProps) => import("react/jsx-runtime").JSX.Element;
43
+ declare const Autocomplete: ({ skillItems, legacySkillItems, selectedItems, onChipDelete, value, onValueChange, placeholder, onSkillItemClick, onLegacySkillItemClick, onInputItemClick, supportingText, hasIndexBar, isError, errorMessage, leadingIcon, label, ariaLabel, }: AutocompleteProps) => import("react/jsx-runtime").JSX.Element;
42
44
  export { Autocomplete };
@@ -1,4 +1,4 @@
1
- "use client";import{jsxs as e,jsx as t,Fragment as l}from"react/jsx-runtime";import{useState as r,useRef as o,useEffect as n}from"react";import{useClickOutside as i}from"@wishket/yogokit";import{AutoCompleteList as s}from"../AutoCompleteList/AutoCompleteList.js";import{TextFieldContainer as a}from"../TextFieldContainer/TextFieldContainer.js";import"tailwind-merge";import{Box as c}from"../../Base/Layouts/Box/Box.js";import"../../Base/Layouts/FullBleed/FullBleed.js";import{Input as u}from"../Input/Input.js";import"../Input/PasswordInput.js";import"../Input/LabelInput.js";import"../Input/InputTypeSelector.js";import{InputChip as p}from"../InputChip/InputChip.js";import{SupportTextContainer as m}from"../SupportTextContainer/SupportTextContainer.js";import{WithDivider as d}from"./Autocomplete.parts.js";import{getSortedSkillItems as f}from"./Autocomplete.utils.js";
1
+ "use client";import{jsxs as e,jsx as t,Fragment as l}from"react/jsx-runtime";import{useState as n,useRef as r,useId as o,useCallback as i,useEffect as a}from"react";import{useClickOutside as s}from"@wishket/yogokit";import{AutoCompleteList as c}from"../AutoCompleteList/AutoCompleteList.js";import{TextFieldContainer as u}from"../TextFieldContainer/TextFieldContainer.js";import"../../Base/Typography/Typography.js";import{Box as p}from"../../Base/Layouts/Box/Box.js";import"tailwind-merge";import"../../Base/Layouts/FullBleed/FullBleed.js";import{Input as m}from"../Input/Input.js";import"../Input/PasswordInput.js";import"../Input/LabelInput.js";import"../Input/InputTypeSelector.js";import{InputChip as d}from"../InputChip/InputChip.js";import{SupportTextContainer as h}from"../SupportTextContainer/SupportTextContainer.js";import{WithDivider as f}from"./Autocomplete.parts.js";import{getSortedSkillItems as v}from"./Autocomplete.utils.js";
2
2
  /**
3
3
  * 자동완성 입력 컴포넌트
4
4
  *
@@ -18,6 +18,8 @@
18
18
  * @param {boolean} [props.isError] - 오류 상태 여부
19
19
  * @param {string} [props.errorMessage] - 오류 메시지
20
20
  * @param {ReactNode} [props.leadingIcon] - 항목 앞에 표시될 아이콘
21
+ * @param {string} [props.label] - 입력 필드의 접근 가능한 이름(스크린리더용). 화면에는 보이지 않는(sr-only) 텍스트를 렌더링하고, 입력 필드에 `aria-labelledby`로 그 텍스트만 연결합니다. `label`/`ariaLabel`이 모두 없으면 HTML-AAM 이름 계산 순서(aria-labelledby → aria-label → `<label>` → title → placeholder)의 마지막 폴백인 `placeholder`가 접근 가능한 이름이 됩니다(선택된 칩을 감싸는 컨테이너가 `<label>`이 아닌 `<div>`이므로 칩 텍스트는 더 이상 섞이지 않습니다). placeholder는 컨트롤의 정체를 온전히 설명하지 못하므로, 접근성을 신경 쓰는 화면이라면 `label` 또는 `ariaLabel`을 지정하는 것을 권장합니다.
22
+ * @param {string} [props.ariaLabel] - 입력 필드의 `aria-label`. `label`과 동시에 주어지면 `aria-label`이 우선합니다(둘 다 설정되면 `aria-labelledby`를 생성하지 않습니다).
21
23
  *
22
24
  * @example
23
25
  * ```tsx
@@ -37,7 +39,28 @@
37
39
  * placeholder="기술을 입력하세요"
38
40
  * />
39
41
  * ```
40
- */const g=({skillItems:g,legacySkillItems:h,selectedItems:I,onChipDelete:k,value:v,onValueChange:y,placeholder:C,onSkillItemClick:x,onLegacySkillItemClick:w,onInputItemClick:j,supportingText:b,hasIndexBar:B=!1,isError:A,errorMessage:D,leadingIcon:F})=>{const[S,L]=r(!1),T=o(null),V=o(null),E=o(null),M=o(null),[U,$]=r(54),[_,q]=r([]),[N,R]=r(-1),z=f(g),K=f(h),O=()=>{L(!1)};n((()=>{if(!V.current)return;const e=new ResizeObserver((e=>{for(const t of e)t.target===V.current&&$(t.contentRect.height+4)}));return e.observe(V.current),()=>{e.disconnect()}}),[]),i(T,O);const P=[...z.map((e=>({type:"static_skill",item:e}))),...K.map((e=>({type:"legacy",item:e}))),...v?[{type:"input",item:v}]:[]],W=e=>{x(e),q([..._,e])},G=e=>{w(e),q([..._,e])},H=()=>{""!==v.trim()&&(j(v.trim()),y(""),q([..._,v]))};/*#__PURE__*/
41
- return e("div",{"data-testid":"design-system-autocomplete-root",className:"relative flex w-full flex-col gap-3",ref:T,onKeyDown:e=>{if(!e.nativeEvent.isComposing&&S)switch(e.key){case"ArrowDown":e.preventDefault(),R((e=>{const t=e<P.length-1?e+1:e,l=M.current;if(l){const e=l.querySelectorAll("li")[t];null==e||e.scrollIntoView({block:"nearest"})}return t}));break;case"ArrowUp":e.preventDefault(),R((e=>{const t=e>0?e-1:e,l=M.current;if(l){const e=l.querySelectorAll("li")[t];null==e||e.scrollIntoView({block:"nearest"})}return t}));break;case"Enter":if(e.preventDefault(),N>=0&&N<P.length){const{type:e,item:t}=P[N];"static_skill"===e?W(t):"legacy"===e?G(t):"input"===e&&H()}else v.trim()&&H();break;case"Backspace":v||(e.preventDefault(),k(I[I.length-1]));break;case"Escape":e.preventDefault(),O()}},children:[
42
- /*#__PURE__*/t("label",{ref:V,children:/*#__PURE__*/e(a,{isError:A,isFocused:S,testId:"design-system--selectBox",isAutoComplete:!0,children:[I.map((e=>/*#__PURE__*/t(p,{onDelete:()=>k(e),children:e},e))),
43
- /*#__PURE__*/t(u,{value:v,onChange:e=>{y(e.target.value)},placeholder:C,onFocus:()=>{S||L(!S)},className:"w-fit flex-auto"})]})}),(b||D)&&/*#__PURE__*/t(m,{supportMessage:b,errorMessage:D}),S&&/*#__PURE__*/t(c,{"data-testid":"design-system-autocomplete-list",ref:E,className:"absolute z-40 w-full",style:{top:U},onMouseLeave:()=>{_.length>0&&(O(),q([]))},children:/*#__PURE__*/t(s.Root,{hasIndexBar:B,onIndexClick:e=>{const t=z.find((t=>t.value.toUpperCase().startsWith(e)));if(t&&E.current){const e=E.current.querySelector(`[id="item-${t.value.replace(/ /g,"_")}"]`);e&&e.scrollIntoView()}},children:/*#__PURE__*/t("ul",{ref:M,children:/*#__PURE__*/e(d,{children:[g.length>0&&/*#__PURE__*/t(l,{children:z.map(((e,l)=>/*#__PURE__*/t(s.Item,{id:`item-${e.value.replace(/ /g,"_")}`,leadingIcon:F,iconUrl:e.iconUrl,text:e.value,onClick:()=>W(e),isFocused:N===l,inputValue:v},e.value)))}),h.length>0&&/*#__PURE__*/t(l,{children:K.map(((e,l)=>/*#__PURE__*/t(s.Item,{text:e.value,count:e.count,onClick:()=>G(e),isFocused:N===z.length+l,inputValue:v},`${e.value}-${l}`)))}),""!==v.trim()&&/*#__PURE__*/t(s.Item,{text:v,isInputItem:!0,onClick:()=>H(),isFocused:N===P.length-1})]})})})})]})};export{g as Autocomplete};
42
+ */const g=({skillItems:g,legacySkillItems:I,selectedItems:y,onChipDelete:k,value:x,onValueChange:b,placeholder:C,onSkillItemClick:w,onLegacySkillItemClick:B,onInputItemClick:D,supportingText:j,hasIndexBar:E=!1,isError:F,errorMessage:A,leadingIcon:L,label:M,ariaLabel:S})=>{const[T,$]=n(!1),V=r(null),N=r(null),R=r(null),[U,z]=n(54),[P,_]=n([]),[H,K]=n(-1),O=o(),W=e=>`${O}-option-${e}`,q=i((e=>`${O}-chip-${e}`),[O]),[G,J]=n(0),Q=r(null),X=`${O}-label`,Y=v(g),Z=v(I),ee=()=>{$(!1)};a((()=>{if(!N.current)return;const e=new ResizeObserver((e=>{for(const t of e)t.target===N.current&&z(t.contentRect.height+4)}));return e.observe(N.current),()=>{e.disconnect()}}),[]),s(V,ee),
43
+ // 칩이 줄어들면 activeChipIndex가 범위를 벗어날 있다.
44
+ a((()=>{J((e=>Math.min(e,Math.max(y.length-1,0))))}),[y.length]),
45
+ // 키보드 삭제 포커스 이동: 같은 자리의 → 없으면 마지막 칩 →
46
+ // 칩이 하나도 남지 않으면 입력 필드. 포커스가 body로 유실되지 않게 한다.
47
+ a((()=>{var e;const t=Q.current;if(null===t)return;var l;if(Q.current=null,0===y.length)return void(null===(l=R.current)||void 0===l||l.focus());const n=Math.min(t,y.length-1);J(n),null===(e=document.getElementById(q(n)))||void 0===e||e.focus()}),[y,q]);const te=[...Y.map((e=>({type:"static_skill",item:e}))),...Z.map((e=>({type:"legacy",item:e}))),...x?[{type:"input",item:x}]:[]],le=e=>{var t;J(e),null===(t=document.getElementById(q(e)))||void 0===t||t.focus()},ne=e=>{const t=y.length-1;if(!(t<0))switch(e.key){case"ArrowRight":e.preventDefault(),le(Math.min(G+1,t));break;case"ArrowLeft":e.preventDefault(),le(Math.max(G-1,0));break;case"Home":e.preventDefault(),le(0);break;case"End":e.preventDefault(),le(t);break;case"Delete":case"Backspace":case"Enter":case" ":e.preventDefault(),(e=>{
48
+ // activeChipIndex는 clamp effect와 삭제 버튼의 onFocus로 범위 안에 유지되지만,
49
+ // 소비자 콜백에 undefined를 넘기는 일은 어떤 경우에도 없어야 하므로 확인한다.
50
+ const t=y[e];void 0!==t&&(
51
+ // 다음 렌더에서 포커스를 옮기기 위해 위치를 기록해 둔다.
52
+ Q.current=e,k(t))})(G)}},re=e=>{w(e),_([...P,e])},oe=e=>{B(e),_([...P,e])},ie=()=>{""!==x.trim()&&(D(x.trim()),b(""),_([...P,x]))};/*#__PURE__*/
53
+ return e("div",{"data-testid":"design-system-autocomplete-root",className:"relative flex w-full flex-col gap-3",ref:V,onKeyDown:e=>{if(!e.nativeEvent.isComposing){
54
+ // Escape는 위젯 안 어디에 포커스가 있든 목록을 닫아야 한다(APG combobox).
55
+ // 칩 삭제 버튼에 포커스를 둔 키보드 사용자가 목록을 닫을 방법이 없어지면
56
+ // 안 되므로, 아래 "입력 필드 한정" 가드보다 먼저 처리한다.
57
+ if("Escape"===e.key){if(!T)return;return e.preventDefault(),void ee()}
58
+ // 그 밖의 콤보박스 키 조작은 입력 필드에 포커스가 있을 때만 처리한다.
59
+ // 이 핸들러는 루트 <div>에 붙어 있어, 컨테이너 안의 다른 포커스 가능한
60
+ // 요소(칩의 삭제 버튼)에서 올라온 키 이벤트까지 그대로 받는다. 그대로 두면
61
+ // Enter의 preventDefault가 버튼의 기본 활성화를 막아 삭제가 아예 동작하지
62
+ // 않고, Backspace는 포커스된 칩이 아니라 항상 마지막 칩을 지운다.
63
+ if(e.target===R.current){if(T)switch(e.key){case"ArrowDown":e.preventDefault(),K((e=>{var t;const l=e<te.length-1?e+1:e;return null===(t=document.getElementById(W(l)))||void 0===t||t.scrollIntoView({block:"nearest"}),l}));break;case"ArrowUp":e.preventDefault(),K((e=>{var t;const l=e>0?e-1:e;return null===(t=document.getElementById(W(l)))||void 0===t||t.scrollIntoView({block:"nearest"}),l}));break;case"Enter":if(e.preventDefault(),H>=0&&H<te.length){const{type:e,item:t}=te[H];"static_skill"===e?re(t):"legacy"===e?oe(t):"input"===e&&ie()}else x.trim()&&ie();break;case"Backspace":x||(e.preventDefault(),k(y[y.length-1]))}}else ne(e)}},children:[
64
+ /*#__PURE__*/e("div",{ref:N,onClick:()=>{var e;null===(e=R.current)||void 0===e||e.focus()},className:"cursor-text",children:[M&&/*#__PURE__*/t("span",{id:X,className:"sr-only",children:M}),
65
+ /*#__PURE__*/e(u,{isError:F,isFocused:T,testId:"design-system--selectBox",isAutoComplete:!0,children:[y.map(((e,l)=>/*#__PURE__*/t(d,{onDelete:()=>k(e),deleteButtonProps:{id:q(l),tabIndex:l===G?0:-1,onFocus:()=>J(l)},children:e},e))),
66
+ /*#__PURE__*/t(m,{ref:R,value:x,onChange:e=>{b(e.target.value)},placeholder:C,onFocus:()=>{T||$(!T)},className:"w-fit flex-auto",role:"combobox","aria-label":S,"aria-labelledby":!S&&M?X:void 0,"aria-expanded":T,"aria-controls":O,"aria-autocomplete":"list","aria-activedescendant":H>=0?W(H):void 0})]})]}),(j||A)&&/*#__PURE__*/t(h,{supportMessage:j,errorMessage:A}),T&&/*#__PURE__*/t(p,{"data-testid":"design-system-autocomplete-list",className:"absolute z-40 w-full",style:{top:U},onMouseLeave:()=>{P.length>0&&(ee(),_([]))},children:/*#__PURE__*/t(c.Root,{listboxId:O,hasIndexBar:E,onIndexClick:e=>{var t;const l=Y.findIndex((t=>t.value.toUpperCase().startsWith(e)));-1!==l&&(null===(t=document.getElementById(W(l)))||void 0===t||t.scrollIntoView())},children:/*#__PURE__*/e(f,{children:[g.length>0&&/*#__PURE__*/t(l,{children:Y.map(((e,l)=>/*#__PURE__*/t(c.Item,{id:W(l),leadingIcon:L,iconUrl:e.iconUrl,text:e.value,onClick:()=>re(e),isFocused:H===l,isSelected:y.includes(e.value),inputValue:x},e.value)))}),I.length>0&&/*#__PURE__*/t(l,{children:Z.map(((e,l)=>/*#__PURE__*/t(c.Item,{id:W(Y.length+l),text:e.value,count:e.count,onClick:()=>oe(e),isFocused:H===Y.length+l,isSelected:y.includes(e.value),inputValue:x},`${e.value}-${l}`)))}),""!==x.trim()&&/*#__PURE__*/t(c.Item,{id:W(te.length-1),text:x,isInputItem:!0,onClick:()=>ie(),isFocused:H===te.length-1,isSelected:y.includes(x.trim())})]})})})]})};export{g as Autocomplete};
@@ -23,4 +23,22 @@ export interface AutocompleteProps {
23
23
  errorMessage?: string;
24
24
  isError?: boolean;
25
25
  leadingIcon?: MediumSystemIconName;
26
+ /**
27
+ * 입력 필드의 접근 가능한 이름(스크린리더용). 화면에는 보이지 않는(sr-only)
28
+ * 텍스트로 렌더링되고, 입력 필드의 `aria-labelledby`가 그 텍스트만
29
+ * 참조합니다. 선택된 항목(`InputChip`)을 감싸는 컨테이너는 `<label>`이
30
+ * 아닌 `<div>`이므로 암묵적 라벨 연결이 발생하지 않아 칩 텍스트가 이름에
31
+ * 섞이지 않습니다. `label`과 `ariaLabel`이 모두 없으면 HTML-AAM 이름
32
+ * 계산 순서(aria-labelledby → aria-label → `<label>` → title →
33
+ * placeholder)의 마지막 폴백인 `placeholder`가 접근 가능한 이름이
34
+ * 됩니다("이름이 없는 상태"가 되는 게 아닙니다). placeholder는 컨트롤의
35
+ * 정체를 온전히 설명하지 못하므로, 접근성을 신경 쓰는 화면이라면 `label`
36
+ * 또는 `ariaLabel`을 지정하는 것을 권장합니다.
37
+ */
38
+ label?: string;
39
+ /**
40
+ * 입력 필드의 `aria-label`. `label`과 동시에 주어지면 `aria-label`이
41
+ * 우선합니다(이 경우 `aria-labelledby`는 생성되지 않습니다).
42
+ */
43
+ ariaLabel?: string;
26
44
  }
@@ -1,4 +1,4 @@
1
- "use client";import{jsxs as e,jsx as r}from"react/jsx-runtime";import{forwardRef as t,useCallback as o}from"react";import"tailwind-merge";import{Box as n}from"../../Base/Layouts/Box/Box.js";import"../../Base/Layouts/FullBleed/FullBleed.js";import{CheckboxButton as c}from"./Checkbox.parts.js";function a(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function i(e){for(var r=1;r<arguments.length;r++){var t=null!=arguments[r]?arguments[r]:{},o=Object.keys(t);"function"==typeof Object.getOwnPropertySymbols&&(o=o.concat(Object.getOwnPropertySymbols(t).filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable})))),o.forEach((function(r){a(e,r,t[r])}))}return e}function l(e,r){if(null==e)return{};var t,o,n=function(e,r){if(null==e)return{};var t,o,n={},c=Object.keys(e);for(o=0;o<c.length;o++)t=c[o],r.indexOf(t)>=0||(n[t]=e[t]);return n}
1
+ "use client";import{jsxs as e,jsx as r}from"react/jsx-runtime";import{forwardRef as t,useCallback as o}from"react";import"../../Base/Typography/Typography.js";import{Box as n}from"../../Base/Layouts/Box/Box.js";import"tailwind-merge";import"../../Base/Layouts/FullBleed/FullBleed.js";import{CheckboxButton as a}from"./Checkbox.parts.js";function c(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function s(e){for(var r=1;r<arguments.length;r++){var t=null!=arguments[r]?arguments[r]:{},o=Object.keys(t);"function"==typeof Object.getOwnPropertySymbols&&(o=o.concat(Object.getOwnPropertySymbols(t).filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable})))),o.forEach((function(r){c(e,r,t[r])}))}return e}function i(e,r){if(null==e)return{};var t,o,n=function(e,r){if(null==e)return{};var t,o,n={},a=Object.keys(e);for(o=0;o<a.length;o++)t=a[o],r.indexOf(t)>=0||(n[t]=e[t]);return n}
2
2
  /**
3
3
  * @component
4
4
  * @param {Object} props - 체크박스 컴포넌트 프로퍼티
@@ -27,7 +27,7 @@
27
27
  * console.log('체크박스 상태:', e.target.checked);
28
28
  * };
29
29
  * <Checkbox onChange={handleChange} />
30
- */(e,r);if(Object.getOwnPropertySymbols){var c=Object.getOwnPropertySymbols(e);for(o=0;o<c.length;o++)t=c[o],r.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(n[t]=e[t])}return n}const s=/*#__PURE__*/t(((t,a)=>{var{checked:s=!1,onChange:u,disabled:p=!1,isError:b=!1,type:f="box",className:m}=t,y=l(t,["checked","onChange","disabled","isError","type","className"]);const d=o((e=>{p||null==u||u(e)}),[u,p]);/*#__PURE__*/
30
+ */(e,r);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(o=0;o<a.length;o++)t=a[o],r.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(n[t]=e[t])}return n}const l=/*#__PURE__*/t(((t,c)=>{var{checked:l=!1,onChange:p,disabled:u=!1,isError:b=!1,type:y="box",className:f}=t,m=i(t,["checked","onChange","disabled","isError","type","className"]);const d=o((e=>{u||null==p||p(e)}),[p,u]);/*#__PURE__*/
31
31
  return e(n,{"data-testid":"design-system-checkbox",className:"group relative flex size-fit",children:[
32
- /*#__PURE__*/r("input",i({ref:a,className:"absolute inset-0 z-10 cursor-pointer opacity-0",type:"checkbox",checked:s,onChange:d,disabled:p},y)),
33
- /*#__PURE__*/r(c,{checked:s,disabled:p,isError:b,type:f,className:m})]})}));s.displayName="Checkbox";export{s as Checkbox};
32
+ /*#__PURE__*/r("input",s({ref:c,className:"absolute inset-0 z-10 cursor-pointer opacity-0",type:"checkbox",checked:l,onChange:d,disabled:u},m)),
33
+ /*#__PURE__*/r(a,{checked:l,disabled:u,isError:b,type:y,className:f})]})}));l.displayName="Checkbox";export{l as Checkbox};
@@ -1,8 +1,8 @@
1
- import{jsx as r,jsxs as e}from"react/jsx-runtime";import{twMerge as t}from"tailwind-merge";const o="text-w-white group-hover:text-w-white",s="text-w-gray-200 group-hover:text-w-gray-200",a="stroke-dasharray-[16] stroke-dashoffset-[16] animate-checkbox-check",i=({type:o="box",disabled:s,checked:a=!1,isError:i,className:n})=>{const h="circle"===o?"rounded-full":"rounded";return"sub"===o?/*#__PURE__*/r(l,{role:"checkbox-button",className:n,checked:a,disabled:s,isError:i}):/*#__PURE__*/e("div",{className:t("group relative box-border cursor-pointer border",!s&&!i&&"group-focus-within:border-primary-500",!s&&!i&&!a&&"group-focus-within:bg-w-white",{box:"size-4 m-px",circle:"size-[18px]"}[o],h,
1
+ import{jsx as r,jsxs as e}from"react/jsx-runtime";import{twMerge as t}from"tailwind-merge";const o="text-w-white group-hover:text-w-white",s="text-w-gray-200 group-hover:text-w-gray-200",a="stroke-dasharray-[16] stroke-dashoffset-[16] animate-checkbox-check",i=({type:o="box",disabled:s,checked:a=!1,isError:i,className:l})=>{const h="circle"===o?"rounded-full":"rounded";return"sub"===o?/*#__PURE__*/r(c,{className:l,checked:a,disabled:s,isError:i}):/*#__PURE__*/e("div",{className:t("group relative box-border cursor-pointer border",!s&&!i&&"group-focus-within:border-primary-500",!s&&!i&&!a&&"group-focus-within:bg-w-white",{box:"size-4 m-px",circle:"size-[18px]"}[o],h,
2
2
  // 비활성화 상태
3
3
  s?a?i?"bg-w-gray-50 border-w-gray-200 cursor-not-allowed":"bg-primary-100 border-primary-100 cursor-not-allowed":"border-w-gray-200 bg-w-gray-50 cursor-not-allowed":
4
4
  // 에러 상태
5
5
  i?a?"border-w-red-500 bg-w-red-500":"border-w-red-500 bg-w-white":
6
6
  // 정상 상태
7
- a?"bg-primary-500 border-primary-500":"group-hover:border-primary-500 border-w-gray-200 bg-white",n),role:"checkbox-button",children:["box"===o&&/*#__PURE__*/r(d,{checked:a,isError:i,disabled:s}),"circle"===o&&/*#__PURE__*/r(c,{checked:a,isError:i,disabled:s})]})},d=({checked:e,isError:i,disabled:d})=>/*#__PURE__*/r("svg",{width:"10",height:"8",viewBox:"0 0 10 8",fill:"none",xmlns:"http://www.w3.org/2000/svg",className:t("absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2",e&&o,i&&d&&s,!e&&"text-transparent",d&&(!i&&e?o:"text-transparent")),style:{strokeDasharray:e?"16":"0",strokeDashoffset:e?"16":"0"},children:/*#__PURE__*/r("path",{d:"M1 3.8L4 7L9 1",stroke:"currentColor",strokeWidth:"1.6",strokeLinecap:"round",strokeLinejoin:"round",className:e?a:""})}),c=({checked:e,isError:i,disabled:d})=>/*#__PURE__*/r("svg",{width:"10",height:"8",viewBox:"0 0 10 8",fill:"none",xmlns:"http://www.w3.org/2000/svg",className:t("absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2",e&&o,i&&d&&s,!e&&"text-w-gray-200 group-hover:text-w-primary",i&&!e&&"text-w-red-500 group-hover:text-w-red-500",d&&(!i&&e?o:s)),style:{strokeDasharray:e?"16":"0",strokeDashoffset:e?"16":"0"},children:/*#__PURE__*/r("path",{d:"M1 3.8L4 7L9 1",stroke:"currentColor",strokeWidth:"1.6",strokeLinecap:"round",strokeLinejoin:"round",className:e?a:""})}),l=({role:e,className:o,checked:s,disabled:a,isError:i})=>{const d="text-w-gray-100";/*#__PURE__*/
8
- return r("svg",{width:"18",height:"18",viewBox:"0 0 18 18",fill:"none",xmlns:"http://www.w3.org/2000/svg",role:e,className:t("cursor-pointer",a&&"cursor-not-allowed",i?a?d:"text-w-red-500":a?s?"text-primary-100":d:s?"text-primary":"text-w-gray-200",o),"data-testid":"design-system--sub-checkbox",children:/*#__PURE__*/r("path",{d:"M4 8.76667L7.75004 12.5L14.0001 5.5",stroke:"currentColor",strokeWidth:"1.4",strokeLinecap:"round",strokeLinejoin:"round"})})};export{i as CheckboxButton};
7
+ a?"bg-primary-500 border-primary-500":"group-hover:border-primary-500 border-w-gray-200 bg-white",l),"data-testid":"design-system--checkbox-button",children:["box"===o&&/*#__PURE__*/r(d,{checked:a,isError:i,disabled:s}),"circle"===o&&/*#__PURE__*/r(n,{checked:a,isError:i,disabled:s})]})},d=({checked:e,isError:i,disabled:d})=>/*#__PURE__*/r("svg",{width:"10",height:"8",viewBox:"0 0 10 8",fill:"none",xmlns:"http://www.w3.org/2000/svg",className:t("absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2",e&&o,i&&d&&s,!e&&"text-transparent",d&&(!i&&e?o:"text-transparent")),style:{strokeDasharray:e?"16":"0",strokeDashoffset:e?"16":"0"},children:/*#__PURE__*/r("path",{d:"M1 3.8L4 7L9 1",stroke:"currentColor",strokeWidth:"1.6",strokeLinecap:"round",strokeLinejoin:"round",className:e?a:""})}),n=({checked:e,isError:i,disabled:d})=>/*#__PURE__*/r("svg",{width:"10",height:"8",viewBox:"0 0 10 8",fill:"none",xmlns:"http://www.w3.org/2000/svg",className:t("absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2",e&&o,i&&d&&s,!e&&"text-w-gray-200 group-hover:text-w-primary",i&&!e&&"text-w-red-500 group-hover:text-w-red-500",d&&(!i&&e?o:s)),style:{strokeDasharray:e?"16":"0",strokeDashoffset:e?"16":"0"},children:/*#__PURE__*/r("path",{d:"M1 3.8L4 7L9 1",stroke:"currentColor",strokeWidth:"1.6",strokeLinecap:"round",strokeLinejoin:"round",className:e?a:""})}),c=({className:e,checked:o,disabled:s,isError:a})=>{const i="text-w-gray-100";/*#__PURE__*/
8
+ return r("svg",{width:"18",height:"18",viewBox:"0 0 18 18",fill:"none",xmlns:"http://www.w3.org/2000/svg",className:t("cursor-pointer",s&&"cursor-not-allowed",a?s?i:"text-w-red-500":s?o?"text-primary-100":i:o?"text-primary":"text-w-gray-200",e),"data-testid":"design-system--sub-checkbox",children:/*#__PURE__*/r("path",{d:"M4 8.76667L7.75004 12.5L14.0001 5.5",stroke:"currentColor",strokeWidth:"1.4",strokeLinecap:"round",strokeLinejoin:"round"})})};export{i as CheckboxButton};
@@ -12,7 +12,6 @@ export interface CheckMarkProps {
12
12
  }
13
13
  export type CheckboxProps = CheckboxButtonProps & ComponentPropsWithRef<'input'>;
14
14
  export interface SubCheckboxProps {
15
- role?: string;
16
15
  className?: string;
17
16
  checked?: boolean;
18
17
  disabled?: boolean;
@@ -1,8 +1,8 @@
1
- "use client";import{jsx as e,jsxs as t}from"react/jsx-runtime";import{twMerge as a}from"tailwind-merge";import{Typography as r}from"../../Base/Typography/Typography.js";import"../../Base/Layouts/Box/Box.js";import"../../Base/Layouts/FullBleed/FullBleed.js";import{CheckboxCardContainer as s,StyledCheckbox as i,CheckboxCardIcon as d,TitleContainer as o}from"./CheckboxCard.parts.js";const c=c=>{const{disabled:n=!1,checked:l=!1,isError:m=!1,onChange:h,isWide:x=!1,containerClassName:p,className:y,iconName:g,title:b,description:u,testId:k,name:C,value:f}=c,B=null!=g?g:x?void 0:"receipt";/*#__PURE__*/
2
- return e("label",{"data-testid":k,role:"checkbox-card",className:a("group",p),children:/*#__PURE__*/t(s,{"data-testid":"design-system-checkboxCard--container",checked:l,isError:m,isWide:x,disabled:n,className:y,children:[
3
- /*#__PURE__*/e(i,{isWide:x,checked:l,onChange:h,isError:m,disabled:n,name:C,value:f}),B&&/*#__PURE__*/e(d,{isError:m,checked:l,iconName:B,disabled:n}),
1
+ "use client";import{jsx as e,jsxs as t}from"react/jsx-runtime";import{twMerge as a}from"tailwind-merge";import{Typography as s}from"../../Base/Typography/Typography.js";import"../../Base/Layouts/Box/Box.js";import"../../Base/Layouts/FullBleed/FullBleed.js";import{CheckboxCardContainer as i,StyledCheckbox as r,CheckboxCardIcon as d,TitleContainer as o}from"./CheckboxCard.parts.js";const c=c=>{const{disabled:n=!1,checked:l=!1,isError:m=!1,onChange:h,isWide:x=!1,containerClassName:y,className:p,iconName:g,title:b,description:u,testId:k,name:C,value:f}=c,B=null!=g?g:x?void 0:"receipt";/*#__PURE__*/
2
+ return e("label",{"data-testid":k||"design-system-checkboxCard",className:a("group",y),children:/*#__PURE__*/t(i,{"data-testid":"design-system-checkboxCard--container",checked:l,isError:m,isWide:x,disabled:n,className:p,children:[
3
+ /*#__PURE__*/e(r,{isWide:x,checked:l,onChange:h,isError:m,disabled:n,name:C,value:f}),B&&/*#__PURE__*/e(d,{isError:m,checked:l,iconName:B,disabled:n}),
4
4
  /*#__PURE__*/t(o,{isWide:x,"data-testid":"design-system-checkboxCard--titleBox",children:[
5
- /*#__PURE__*/e(r,{"data-testid":"design-system-checkboxCard--title",variant:"body16",className:a("font-medium",x?"text-left":"text-center",n?"text-w-gray-300":"text-w-gray-900"),children:b}),u&&/*#__PURE__*/e(r,{variant:"body14",className:a("font-normal",x?"text-left":"text-center",n?"text-w-gray-300":"text-w-gray-600"),"data-testid":"design-system-checkboxCard--description",children:u})]})]})})};
5
+ /*#__PURE__*/e(s,{"data-testid":"design-system-checkboxCard--title",variant:"body16",className:a("font-medium",x?"text-left":"text-center",n?"text-w-gray-300":"text-w-gray-900"),children:b}),u&&/*#__PURE__*/e(s,{variant:"body14",className:a("font-normal",x?"text-left":"text-center",n?"text-w-gray-300":"text-w-gray-600"),"data-testid":"design-system-checkboxCard--description",children:u})]})]})})};
6
6
  /**
7
7
  * 체크박스와 함께 아이콘, 제목, 설명을 포함하는 카드 형태의 선택 컴포넌트입니다.
8
8
  *
@@ -1,4 +1,4 @@
1
- import{jsx as e}from"react/jsx-runtime";import{twMerge as r,twJoin as t}from"tailwind-merge";import"../../DataDisplays/Avatar/Avatar.js";import"react";import{Box as o}from"../../Base/Layouts/Box/Box.js";import"../../Base/Layouts/FullBleed/FullBleed.js";import"../../DataDisplays/SystemIcon/SystemIcon.constants.js";import{ProductIcon as i}from"../../DataDisplays/ProductIcon/ProductIcon.js";import"../../DataDisplays/Accordion/Accordion.js";import{Checkbox as n}from"../Checkbox/Checkbox.js";function c(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function s(e){for(var r=1;r<arguments.length;r++){var t=null!=arguments[r]?arguments[r]:{},o=Object.keys(t);"function"==typeof Object.getOwnPropertySymbols&&(o=o.concat(Object.getOwnPropertySymbols(t).filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable})))),o.forEach((function(r){c(e,r,t[r])}))}return e}function a(e,r){return r=null!=r?r:{},Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):function(e){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);r.push.apply(r,t)}return r}(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))})),e}function l(e,r){if(null==e)return{};var t,o,i=function(e,r){if(null==e)return{};var t,o,i={},n=Object.keys(e);for(o=0;o<n.length;o++)t=n[o],r.indexOf(t)>=0||(i[t]=e[t]);return i}(e,r);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);for(o=0;o<n.length;o++)t=n[o],r.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}const p=t=>{var{children:o,isWide:i,checked:n,isError:c,disabled:p,className:d}=t,b=l(t,["children","isWide","checked","isError","disabled","className"]);/*#__PURE__*/
2
- return e("div",a(s({className:r("relative flex h-auto cursor-pointer items-center gap-2 rounded-xl border",i?"min-h-[94px] w-[298px] flex-row gap-3 px-5 py-4":"min-h-fit w-[224px] flex-col justify-center px-4 pt-4 pb-6",!p&&!c&&"group-focus-within:border-primary-500",p?r("cursor-not-allowed",n&&!c?"border-primary-100":"border-w-gray-200"):c?"border-w-red-500":n?"border-primary-500":"border-w-gray-200 group-hover:border-primary",p?n&&!c?"bg-primary-10":"bg-w-gray-10":n?c?"bg-w-red-10":"bg-primary-10":"bg-w-white",d)},b),{children:o}))},d=({isWide:t,children:o})=>/*#__PURE__*/e("div",{className:r("flex h-auto w-full flex-col justify-between gap-0.5",t?"items-start":"items-center"),children:o}),b=i=>{var{isWide:c,className:a}=i,p=l(i,["isWide","className"]);const d=!c;/*#__PURE__*/
3
- return e(o,{className:t(d&&"absolute top-[17px] left-[17px]"),children:/*#__PURE__*/e(n,s({className:r(d&&"group-hover:border-primary-500",a)},p))})},m=({iconName:t,disabled:o,checked:n,isError:c})=>{const s=c||!n;/*#__PURE__*/
4
- return e("div",{className:r("flex size-[60px] shrink-0 items-center justify-center",o&&"opacity-30"),"data-testid":"design-system-checkboxCard--icon",children:/*#__PURE__*/e(i,{name:t,disabled:s})})};export{p as CheckboxCardContainer,m as CheckboxCardIcon,b as StyledCheckbox,d as TitleContainer};
1
+ import{jsx as e}from"react/jsx-runtime";import{twMerge as r,twJoin as t}from"tailwind-merge";import"../../DataDisplays/Avatar/Avatar.js";import"../../Base/Typography/Typography.js";import{Box as o}from"../../Base/Layouts/Box/Box.js";import"../../Base/Layouts/FullBleed/FullBleed.js";import"react";import"../../DataDisplays/SystemIcon/SystemIcon.constants.js";import{ProductIcon as i}from"../../DataDisplays/ProductIcon/ProductIcon.js";import"../../DataDisplays/Accordion/Accordion.js";import{Checkbox as n}from"../Checkbox/Checkbox.js";function s(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function a(e){for(var r=1;r<arguments.length;r++){var t=null!=arguments[r]?arguments[r]:{},o=Object.keys(t);"function"==typeof Object.getOwnPropertySymbols&&(o=o.concat(Object.getOwnPropertySymbols(t).filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable})))),o.forEach((function(r){s(e,r,t[r])}))}return e}function c(e,r){return r=null!=r?r:{},Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):function(e){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);r.push.apply(r,t)}return r}(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))})),e}function l(e,r){if(null==e)return{};var t,o,i=function(e,r){if(null==e)return{};var t,o,i={},n=Object.keys(e);for(o=0;o<n.length;o++)t=n[o],r.indexOf(t)>=0||(i[t]=e[t]);return i}(e,r);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);for(o=0;o<n.length;o++)t=n[o],r.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}const p=t=>{var{children:o,isWide:i,checked:n,isError:s,disabled:p,className:d}=t,m=l(t,["children","isWide","checked","isError","disabled","className"]);/*#__PURE__*/
2
+ return e("div",c(a({className:r("relative flex h-auto cursor-pointer items-center gap-2 rounded-xl border",i?"min-h-[94px] w-[298px] flex-row gap-3 px-5 py-4":"min-h-fit w-[224px] flex-col justify-center px-4 pt-4 pb-6",!p&&!s&&"group-focus-within:border-primary-500",p?r("cursor-not-allowed",n&&!s?"border-primary-100":"border-w-gray-200"):s?"border-w-red-500":n?"border-primary-500":"border-w-gray-200 group-hover:border-primary",p?n&&!s?"bg-primary-10":"bg-w-gray-10":n?s?"bg-w-red-10":"bg-primary-10":"bg-w-white",d)},m),{children:o}))},d=({isWide:t,children:o})=>/*#__PURE__*/e("div",{className:r("flex h-auto w-full flex-col justify-between gap-0.5",t?"items-start":"items-center"),children:o}),m=i=>{var{isWide:s,className:c}=i,p=l(i,["isWide","className"]);const d=!s;/*#__PURE__*/
3
+ return e(o,{className:t(d&&"absolute top-[17px] left-[17px]"),children:/*#__PURE__*/e(n,a({className:r(d&&"group-hover:border-primary-500",c)},p))})},b=({iconName:t,disabled:o,checked:n,isError:s})=>{const a=s||!n;/*#__PURE__*/
4
+ return e("div",{className:r("flex size-[60px] shrink-0 items-center justify-center",o&&"opacity-30"),"data-testid":"design-system-checkboxCard--icon",children:/*#__PURE__*/e(i,{name:t,disabled:a})})};export{p as CheckboxCardContainer,b as CheckboxCardIcon,m as StyledCheckbox,d as TitleContainer};
@@ -1,4 +1,4 @@
1
- import{jsxs as e,jsx as r}from"react/jsx-runtime";import{twMerge as l}from"tailwind-merge";import{useMemo as a}from"react";import{Box as o}from"../../Base/Layouts/Box/Box.js";import"../../Base/Layouts/FullBleed/FullBleed.js";import{SupportTextContainer as i}from"../SupportTextContainer/SupportTextContainer.js";import{FileItem as t,FileUploadArea as s}from"./FileUploader.parts.js";import{useFileUploader as d}from"./FileUploader.hooks.js";import{generateAcceptDescription as n}from"./FileUploader.utils.js";
1
+ import{jsxs as e,jsx as r}from"react/jsx-runtime";import{twMerge as l}from"tailwind-merge";import{useMemo as a}from"react";import"../../Base/Typography/Typography.js";import{Box as o}from"../../Base/Layouts/Box/Box.js";import"../../Base/Layouts/FullBleed/FullBleed.js";import{SupportTextContainer as i}from"../SupportTextContainer/SupportTextContainer.js";import{FileItem as t,FileUploadArea as s}from"./FileUploader.parts.js";import{useFileUploader as d}from"./FileUploader.hooks.js";import{generateAcceptDescription as n}from"./FileUploader.utils.js";
2
2
  /**
3
3
  * 파일 업로드를 위한 컴포넌트입니다.
4
4
  *
@@ -40,9 +40,9 @@ import{jsxs as e,jsx as r}from"react/jsx-runtime";import{twMerge as l}from"tailw
40
40
  * isSmall={true}
41
41
  * text="파일 첨부하기"
42
42
  * />
43
- */const p=({files:p=[],onChange:m,accept:c,multiple:u=!0,maxFileSize:f,disabled:g=!1,isError:x=!1,errorMessage:h,supportMessage:b,text:F,isSmall:w=!1,onFileSizeExceeded:y})=>{const{inputRef:S,isDragOver:j,handleInputChange:v,handleButtonClick:C,handleRemoveFile:D,handleDragOver:z,handleDragLeave:B,handleDrop:N}=d({files:p,onChange:m,maxFileSize:f,disabled:g,onFileSizeExceeded:y}),L=a((()=>p.reduce(((e,r)=>e+r.size),0)),[p]),M=n(c);/*#__PURE__*/
43
+ */const p=({files:p=[],onChange:m,accept:c,multiple:u=!0,maxFileSize:f,disabled:g=!1,isError:x=!1,errorMessage:h,supportMessage:b,text:y,isSmall:F=!1,onFileSizeExceeded:w})=>{const{inputRef:S,isDragOver:j,handleInputChange:v,handleButtonClick:B,handleRemoveFile:C,handleDragOver:D,handleDragLeave:z,handleDrop:N}=d({files:p,onChange:m,maxFileSize:f,disabled:g,onFileSizeExceeded:w}),L=a((()=>p.reduce(((e,r)=>e+r.size),0)),[p]),M=n(c);/*#__PURE__*/
44
44
  return e(o,{className:"flex w-full flex-col gap-6",children:[
45
- /*#__PURE__*/r("input",{ref:S,type:"file",className:"hidden",accept:c,multiple:u,onChange:v,disabled:g,"data-testid":"file-uploader-input"}),p.length>0&&/*#__PURE__*/r(o,{className:"flex flex-col gap-2",children:p.map(((e,l)=>/*#__PURE__*/r(t,{file:e,onRemove:()=>D(l),disabled:g},`${e.name}-${l}`)))}),
45
+ /*#__PURE__*/r("input",{ref:S,type:"file",className:"hidden",accept:c,multiple:u,onChange:v,disabled:g,"data-testid":"file-uploader-input"}),p.length>0&&/*#__PURE__*/r(o,{className:"flex flex-col gap-2",children:p.map(((e,l)=>/*#__PURE__*/r(t,{file:e,onRemove:()=>C(l),disabled:g},`${e.name}-${l}`)))}),
46
46
  /*#__PURE__*/e(o,{className:"flex flex-col gap-2",children:[
47
- /*#__PURE__*/r("button",{type:"button",className:l("border-w-gray-200 bg-w-gray-10 text-w-gray-600 flex w-full items-center justify-center gap-3 rounded-xl border border-dashed px-6 py-8",w?"flex-row":"flex-col",g&&"cursor-not-allowed",x&&"border-w-red-500",!g&&!x&&"hover:border-w-gray-400",j&&!g&&!x&&"border-w-gray-400"),disabled:g,onClick:C,onDragOver:z,onDragLeave:B,onDrop:N,children:/*#__PURE__*/r(s,{disabled:g,isSmall:w,text:F,acceptDescription:M})}),
47
+ /*#__PURE__*/r("button",{type:"button",className:l("border-w-gray-200 bg-w-gray-10 text-w-gray-600 flex w-full items-center justify-center gap-3 rounded-xl border border-dashed px-6 py-8",F?"flex-row":"flex-col",g&&"cursor-not-allowed",x&&"border-w-red-500",!g&&!x&&"hover:border-w-gray-400",j&&!g&&!x&&"border-w-gray-400"),disabled:g,onClick:B,onDragOver:D,onDragLeave:z,onDrop:N,children:/*#__PURE__*/r(s,{disabled:g,isSmall:F,text:y,acceptDescription:M})}),
48
48
  /*#__PURE__*/r(i,{errorMessage:h,supportMessage:b,currentFileSize:L,maxFileSize:f})]})]})};export{p as FileUploader};
@@ -1,4 +1,4 @@
1
- "use client";import{jsxs as t,jsx as e}from"react/jsx-runtime";import{twJoin as o}from"tailwind-merge";import"../../DataDisplays/Avatar/Avatar.js";import"react";import"../../Base/Layouts/Box/Box.js";import"../../Base/Layouts/FullBleed/FullBleed.js";import{SystemIcon as s}from"../../DataDisplays/SystemIcon/SystemIcon.js";import"../../DataDisplays/SystemIcon/SystemIcon.constants.js";import"../../DataDisplays/Accordion/Accordion.js";import{IconButton as i}from"../IconButton/IconButton.js";import{List as n}from"../List/List.js";import{useDropdown as a}from"../../../hooks/useDropdown.js";
1
+ "use client";import{jsxs as t,jsx as e}from"react/jsx-runtime";import{twJoin as o}from"tailwind-merge";import"../../DataDisplays/Avatar/Avatar.js";import"../../Base/Typography/Typography.js";import"../../Base/Layouts/Box/Box.js";import"../../Base/Layouts/FullBleed/FullBleed.js";import"react";import{SystemIcon as s}from"../../DataDisplays/SystemIcon/SystemIcon.js";import"../../DataDisplays/SystemIcon/SystemIcon.constants.js";import"../../DataDisplays/Accordion/Accordion.js";import{IconButton as i}from"../IconButton/IconButton.js";import{List as n}from"../List/List.js";import{useDropdown as a}from"../../../hooks/useDropdown.js";
2
2
  /**
3
3
  * 아이콘 버튼과 드롭다운 목록을 결합한 컴포넌트입니다.
4
4
  * 버튼 클릭 시 드롭다운 목록이 표시되며, 키보드 탐색이 가능합니다.
@@ -30,6 +30,6 @@
30
30
  * align="right"
31
31
  * />
32
32
  * ```
33
- */const l=({icon:l,items:r,selectedItem:m,onItemClick:d,size:c="sm",align:p="left",disabled:u=!1})=>{const{isListOpen:y,ref:f,focusedIndex:I,handleItemClick:h,toggleListOpen:g,handleKeyDown:D}=a({items:r,onItemClick:d});/*#__PURE__*/
34
- return t("div",{"data-testid":"design-system-icon-button-dropdown",className:"relative w-fit outline-hidden",ref:f,onKeyDown:D,tabIndex:0,children:[
35
- /*#__PURE__*/e(i,{onClick:g,size:c,className:"outline-hidden",disabled:u,children:/*#__PURE__*/e(s,{name:l,className:o(u&&"text-w-gray-300")})}),y&&/*#__PURE__*/e("div",{"data-testid":"design-system-icon-button-dropdown--list-container",className:o("absolute -bottom-2 z-40 translate-y-full transform transition-all","right"===p?"right-0":"left-0"),children:/*#__PURE__*/e(n.Root,{className:"max-h-full min-w-40 overflow-y-visible",children:r.map(((t,o)=>/*#__PURE__*/e(n.Item,{text:t.value,leadingIcon:t.leadingIcon,onClick:()=>h(t),selected:t.key===(null==m?void 0:m.key),isFocused:o===I},t.key)))})})]})};export{l as IconButtonDropdown};
33
+ */const l=({icon:l,items:r,selectedItem:m,onItemClick:d,size:c="sm",align:p="left",disabled:y=!1})=>{const{isListOpen:u,ref:f,focusedIndex:I,handleItemClick:h,toggleListOpen:g,handleKeyDown:j}=a({items:r,onItemClick:d});/*#__PURE__*/
34
+ return t("div",{"data-testid":"design-system-icon-button-dropdown",className:"relative w-fit outline-hidden",ref:f,onKeyDown:j,tabIndex:0,children:[
35
+ /*#__PURE__*/e(i,{onClick:g,size:c,className:"outline-hidden",disabled:y,children:/*#__PURE__*/e(s,{name:l,className:o(y&&"text-w-gray-300")})}),u&&/*#__PURE__*/e("div",{"data-testid":"design-system-icon-button-dropdown--list-container",className:o("absolute -bottom-2 z-40 translate-y-full transform transition-all","right"===p?"right-0":"left-0"),children:/*#__PURE__*/e(n.Root,{className:"max-h-full min-w-40 overflow-y-visible",children:r.map(((t,o)=>/*#__PURE__*/e(n.Item,{text:t.value,leadingIcon:t.leadingIcon,onClick:()=>h(t),selected:t.key===(null==m?void 0:m.key),isFocused:o===I},t.key)))})})]})};export{l as IconButtonDropdown};
@@ -24,4 +24,4 @@ import{jsx as e}from"react/jsx-runtime";import{forwardRef as r}from"react";impor
24
24
  * // 에러 상태
25
25
  * <Input isError placeholder="에러 상태" />
26
26
  */(e,r);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(o=0;o<l.length;o++)t=l[o],r.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(n[t]=e[t])}return n}const l=/*#__PURE__*/r(((r,l)=>{var{disabled:a,className:i,isError:c,isFocused:u}=r,s=n(r,["disabled","className","isError","isFocused"]);/*#__PURE__*/
27
- return e("input",function(e){for(var r=1;r<arguments.length;r++){var t=null!=arguments[r]?arguments[r]:{},n=Object.keys(t);"function"==typeof Object.getOwnPropertySymbols&&(n=n.concat(Object.getOwnPropertySymbols(t).filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable})))),n.forEach((function(r){o(e,r,t[r])}))}return e}({role:"text-input",ref:l,className:t("typo-body16 placeholder:typo-body16 tracking-default placeholder:tracking-default text-w-gray-600 placeholder:text-w-gray-300 disabled:bg-w-gray-10 w-full outline-hidden",a&&"placeholder:typo-body16 text-w-gray-300 placeholder:text-w-gray-200 cursor-not-allowed",i),"data-testid":"design-system--input",disabled:a},s))}));l.displayName="Input";export{l as Input};
27
+ return e("input",function(e){for(var r=1;r<arguments.length;r++){var t=null!=arguments[r]?arguments[r]:{},n=Object.keys(t);"function"==typeof Object.getOwnPropertySymbols&&(n=n.concat(Object.getOwnPropertySymbols(t).filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable})))),n.forEach((function(r){o(e,r,t[r])}))}return e}({ref:l,className:t("typo-body16 placeholder:typo-body16 tracking-default placeholder:tracking-default text-w-gray-600 placeholder:text-w-gray-300 disabled:bg-w-gray-10 w-full outline-hidden",a&&"placeholder:typo-body16 text-w-gray-300 placeholder:text-w-gray-200 cursor-not-allowed",i),"data-testid":"design-system--input",disabled:a},s))}));l.displayName="Input";export{l as Input};
@@ -1,4 +1,4 @@
1
- "use client";import{jsxs as e,jsx as t}from"react/jsx-runtime";import{forwardRef as r,useState as o}from"react";import"../../DataDisplays/Avatar/Avatar.js";import"tailwind-merge";import{Box as n}from"../../Base/Layouts/Box/Box.js";import"../../Base/Layouts/FullBleed/FullBleed.js";import{SystemIcon as s}from"../../DataDisplays/SystemIcon/SystemIcon.js";import"../../DataDisplays/SystemIcon/SystemIcon.constants.js";import"../../DataDisplays/Accordion/Accordion.js";import{Input as a}from"./Input.js";function i(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function c(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{},o=Object.keys(r);"function"==typeof Object.getOwnPropertySymbols&&(o=o.concat(Object.getOwnPropertySymbols(r).filter((function(e){return Object.getOwnPropertyDescriptor(r,e).enumerable})))),o.forEach((function(t){i(e,t,r[t])}))}return e}function l(e,t){return t=null!=t?t:{},Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):function(e){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t.push.apply(t,r)}return t}(Object(t)).forEach((function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(t,r))})),e}function p(e,t){if(null==e)return{};var r,o,n=function(e,t){if(null==e)return{};var r,o,n={},s=Object.keys(e);for(o=0;o<s.length;o++)r=s[o],t.indexOf(r)>=0||(n[r]=e[r]);return n}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(o=0;o<s.length;o++)r=s[o],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}const u=/*#__PURE__*/r(((r,i)=>{var{type:u,disabled:y}=r,m=p(r,["type","disabled"]);const[f,b]=o(!1);/*#__PURE__*/
1
+ "use client";import{jsxs as e,jsx as t}from"react/jsx-runtime";import{forwardRef as r,useState as o}from"react";import"../../DataDisplays/Avatar/Avatar.js";import"tailwind-merge";import"../../Base/Typography/Typography.js";import{Box as n}from"../../Base/Layouts/Box/Box.js";import"../../Base/Layouts/FullBleed/FullBleed.js";import{SystemIcon as s}from"../../DataDisplays/SystemIcon/SystemIcon.js";import"../../DataDisplays/SystemIcon/SystemIcon.constants.js";import"../../DataDisplays/Accordion/Accordion.js";import{Input as a}from"./Input.js";function i(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function c(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{},o=Object.keys(r);"function"==typeof Object.getOwnPropertySymbols&&(o=o.concat(Object.getOwnPropertySymbols(r).filter((function(e){return Object.getOwnPropertyDescriptor(r,e).enumerable})))),o.forEach((function(t){i(e,t,r[t])}))}return e}function p(e,t){return t=null!=t?t:{},Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):function(e){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t.push.apply(t,r)}return t}(Object(t)).forEach((function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(t,r))})),e}function l(e,t){if(null==e)return{};var r,o,n=function(e,t){if(null==e)return{};var r,o,n={},s=Object.keys(e);for(o=0;o<s.length;o++)r=s[o],t.indexOf(r)>=0||(n[r]=e[r]);return n}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(o=0;o<s.length;o++)r=s[o],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}const y=/*#__PURE__*/r(((r,i)=>{var{type:y,disabled:u}=r,m=l(r,["type","disabled"]);const[f,b]=o(!1);/*#__PURE__*/
2
2
  return e(n,{className:"flex w-full items-center gap-2","data-testid":"design-system--password-input",children:[
3
- /*#__PURE__*/t(a,l(c({type:f?"text":"password",ref:i},m),{disabled:y})),
4
- /*#__PURE__*/t("button",{onClick:e=>{e.preventDefault(),b((e=>!e))},disabled:y,className:y?"cursor-not-allowed":"cursor-pointer",type:"button",children:/*#__PURE__*/t(s,{name:f?"medium_eye_slash":"medium_eye",className:"text-w-gray-400"})})]})}));u.displayName="PasswordInput";export{u as PasswordInput};
3
+ /*#__PURE__*/t(a,p(c({type:f?"text":"password",ref:i},m),{disabled:u})),
4
+ /*#__PURE__*/t("button",{onClick:e=>{e.preventDefault(),b((e=>!e))},disabled:u,className:u?"cursor-not-allowed":"cursor-pointer",type:"button",children:/*#__PURE__*/t(s,{name:f?"medium_eye_slash":"medium_eye",className:"text-w-gray-400"})})]})}));y.displayName="PasswordInput";export{y as PasswordInput};
@@ -1,7 +1,18 @@
1
- import { PropsWithChildren } from 'react';
1
+ import { ComponentPropsWithoutRef, PropsWithChildren } from 'react';
2
2
  export interface InputChipProps extends PropsWithChildren {
3
3
  onDelete?: () => void;
4
4
  className?: string;
5
+ /**
6
+ * 삭제 버튼의 접근 가능한 이름. 지정하지 않으면 `children`이 문자열일 때
7
+ * `"{children} 삭제"`, 그 외에는 `"삭제"`가 사용됩니다.
8
+ */
9
+ deleteLabel?: string;
10
+ /**
11
+ * 삭제 버튼(`<button>`)에 직접 전달할 속성. 칩을 여러 개 렌더하는 컴포넌트가
12
+ * roving tabindex(묶음 전체를 탭 스톱 1개로 두고 방향키로 이동)를 구현할 때
13
+ * 사용합니다. 단독 사용 시에는 지정할 필요가 없습니다.
14
+ */
15
+ deleteButtonProps?: Pick<ComponentPropsWithoutRef<'button'>, 'id' | 'tabIndex' | 'onFocus'>;
5
16
  }
6
17
  /**
7
18
  * 삭제 가능한 칩(chip) 형태의 입력 컴포넌트입니다.
@@ -9,8 +20,10 @@ export interface InputChipProps extends PropsWithChildren {
9
20
  * @component
10
21
  * @param {Object} props
11
22
  * @param {React.ReactNode} props.children - 칩 내부에 표시될 콘텐츠
12
- * @param {() => void} [props.onDelete] - 삭제 버튼 클릭 시 실행될 콜백 함수
23
+ * @param {() => void} [props.onDelete] - 삭제 버튼 클릭 시 실행될 콜백 함수. 삭제 버튼은 `<button type="button">`으로 렌더되어 클릭뿐 아니라 키보드(Tab 포커스 + Enter/Space)로도 동작합니다.
13
24
  * @param {string} [props.className] - 추가적인 CSS 클래스
25
+ * @param {string} [props.deleteLabel] - 삭제 버튼의 접근 가능한 이름. 미지정 시 `children`이 문자열이면 `"{children} 삭제"`, 아니면 `"삭제"`
26
+ * @param {Object} [props.deleteButtonProps] - 삭제 버튼에 직접 전달할 `id` / `tabIndex` / `onFocus`. 칩 묶음의 roving tabindex 구현용이며 단독 사용 시에는 불필요합니다.
14
27
  *
15
28
  * @example
16
29
  * ```tsx
@@ -28,5 +41,5 @@ export interface InputChipProps extends PropsWithChildren {
28
41
  * </InputChip>
29
42
  * ```
30
43
  */
31
- declare const InputChip: ({ children, onDelete, className }: InputChipProps) => import("react/jsx-runtime").JSX.Element;
44
+ declare const InputChip: ({ children, onDelete, className, deleteLabel, deleteButtonProps, }: InputChipProps) => import("react/jsx-runtime").JSX.Element;
32
45
  export { InputChip };