@hua-labs/ui 2.1.0 → 2.2.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 (242) hide show
  1. package/README.md +55 -67
  2. package/dist/{ComponentLayout-btJq4TjA.d.mts → ComponentLayout-BhM4VSoq.d.mts} +1 -1
  3. package/dist/Section-BWzyshgX.d.mts +67 -0
  4. package/dist/advanced/dashboard.d.ts.map +1 -1
  5. package/dist/advanced-dashboard.d.mts +1 -1
  6. package/dist/advanced-dashboard.mjs +3 -3
  7. package/dist/advanced-dashboard.mjs.map +1 -1
  8. package/dist/advanced-emotion.mjs +1 -1
  9. package/dist/advanced-motion.d.mts +74 -7
  10. package/dist/advanced-motion.mjs +1 -1
  11. package/dist/advanced.d.mts +4 -4
  12. package/dist/advanced.mjs +3 -3
  13. package/dist/advanced.mjs.map +1 -1
  14. package/dist/{chunk-GLZKT7JN.mjs → chunk-5DPW7SVD.mjs} +3 -3
  15. package/dist/{chunk-GLZKT7JN.mjs.map → chunk-5DPW7SVD.mjs.map} +1 -1
  16. package/dist/{chunk-X7ZIWYRC.mjs → chunk-5L5HIPKA.mjs} +2 -2
  17. package/dist/{chunk-X7ZIWYRC.mjs.map → chunk-5L5HIPKA.mjs.map} +1 -1
  18. package/dist/chunk-A5YOVVM5.mjs +3 -0
  19. package/dist/chunk-A5YOVVM5.mjs.map +1 -0
  20. package/dist/chunk-CNW22G24.mjs +13 -0
  21. package/dist/chunk-CNW22G24.mjs.map +1 -0
  22. package/dist/chunk-CW66UBQG.mjs +3 -0
  23. package/dist/chunk-CW66UBQG.mjs.map +1 -0
  24. package/dist/chunk-EAZEI74V.mjs +3 -0
  25. package/dist/chunk-EAZEI74V.mjs.map +1 -0
  26. package/dist/{chunk-LH77I6HO.mjs → chunk-EPY3432E.mjs} +2 -2
  27. package/dist/{chunk-LH77I6HO.mjs.map → chunk-EPY3432E.mjs.map} +1 -1
  28. package/dist/{chunk-SGEP3CQE.mjs → chunk-F2M4YDDQ.mjs} +2 -2
  29. package/dist/{chunk-SGEP3CQE.mjs.map → chunk-F2M4YDDQ.mjs.map} +1 -1
  30. package/dist/chunk-FHMFDCX2.mjs +3 -0
  31. package/dist/chunk-FHMFDCX2.mjs.map +1 -0
  32. package/dist/chunk-HBIUCLFL.mjs +3 -0
  33. package/dist/chunk-HBIUCLFL.mjs.map +1 -0
  34. package/dist/{chunk-LOYAJIWO.mjs → chunk-HEBXAFRY.mjs} +2 -2
  35. package/dist/{chunk-LOYAJIWO.mjs.map → chunk-HEBXAFRY.mjs.map} +1 -1
  36. package/dist/chunk-IG47LMOD.mjs +3 -0
  37. package/dist/chunk-IG47LMOD.mjs.map +1 -0
  38. package/dist/{chunk-IFSEJVOR.mjs → chunk-J47ZEXEL.mjs} +2 -2
  39. package/dist/{chunk-IFSEJVOR.mjs.map → chunk-J47ZEXEL.mjs.map} +1 -1
  40. package/dist/{chunk-IN7RWQCJ.mjs → chunk-K2FOFIST.mjs} +2 -2
  41. package/dist/{chunk-IN7RWQCJ.mjs.map → chunk-K2FOFIST.mjs.map} +1 -1
  42. package/dist/{chunk-UWHCM3S6.mjs → chunk-LL6QPRD7.mjs} +2 -2
  43. package/dist/{chunk-UWHCM3S6.mjs.map → chunk-LL6QPRD7.mjs.map} +1 -1
  44. package/dist/{chunk-PAEKNQWW.mjs → chunk-NMJLOK6M.mjs} +2 -2
  45. package/dist/{chunk-PAEKNQWW.mjs.map → chunk-NMJLOK6M.mjs.map} +1 -1
  46. package/dist/chunk-O24K56OS.mjs +3 -0
  47. package/dist/chunk-O24K56OS.mjs.map +1 -0
  48. package/dist/chunk-OIWG3IJ7.mjs +3 -0
  49. package/dist/chunk-OIWG3IJ7.mjs.map +1 -0
  50. package/dist/{chunk-VWSBJUNI.mjs → chunk-OLLU7ZFH.mjs} +2 -2
  51. package/dist/{chunk-VWSBJUNI.mjs.map → chunk-OLLU7ZFH.mjs.map} +1 -1
  52. package/dist/chunk-Q76JW7X5.mjs +73 -0
  53. package/dist/chunk-Q76JW7X5.mjs.map +1 -0
  54. package/dist/chunk-QEMPERUK.mjs +3 -0
  55. package/dist/chunk-QEMPERUK.mjs.map +1 -0
  56. package/dist/{chunk-XV3Y7QVU.mjs → chunk-QRM66RQG.mjs} +2 -2
  57. package/dist/{chunk-XV3Y7QVU.mjs.map → chunk-QRM66RQG.mjs.map} +1 -1
  58. package/dist/{chunk-6KTHJ3EL.mjs → chunk-QRRP7TGF.mjs} +3 -3
  59. package/dist/{chunk-6KTHJ3EL.mjs.map → chunk-QRRP7TGF.mjs.map} +1 -1
  60. package/dist/chunk-SD6XGDAC.mjs +3 -0
  61. package/dist/chunk-SD6XGDAC.mjs.map +1 -0
  62. package/dist/chunk-SDFVGFXT.mjs +3 -0
  63. package/dist/chunk-SDFVGFXT.mjs.map +1 -0
  64. package/dist/{chunk-N7M6RIN4.mjs → chunk-SMLDNOV3.mjs} +3 -3
  65. package/dist/{chunk-N7M6RIN4.mjs.map → chunk-SMLDNOV3.mjs.map} +1 -1
  66. package/dist/{chunk-NBJUE7NR.mjs → chunk-TAP6MYDW.mjs} +2 -2
  67. package/dist/{chunk-NBJUE7NR.mjs.map → chunk-TAP6MYDW.mjs.map} +1 -1
  68. package/dist/{chunk-PYBYZVSL.mjs → chunk-TBZ645BI.mjs} +2 -2
  69. package/dist/{chunk-PYBYZVSL.mjs.map → chunk-TBZ645BI.mjs.map} +1 -1
  70. package/dist/{chunk-C4OACMTB.mjs → chunk-V2DNYJR6.mjs} +2 -2
  71. package/dist/{chunk-C4OACMTB.mjs.map → chunk-V2DNYJR6.mjs.map} +1 -1
  72. package/dist/chunk-VBABZXL7.mjs +3 -0
  73. package/dist/chunk-VBABZXL7.mjs.map +1 -0
  74. package/dist/{chunk-OSCMSA2Q.mjs → chunk-WYBSHTGY.mjs} +2 -2
  75. package/dist/{chunk-OSCMSA2Q.mjs.map → chunk-WYBSHTGY.mjs.map} +1 -1
  76. package/dist/chunk-ZQUMJQYV.mjs +3 -0
  77. package/dist/chunk-ZQUMJQYV.mjs.map +1 -0
  78. package/dist/chunk-ZY23NOT4.mjs +3 -0
  79. package/dist/chunk-ZY23NOT4.mjs.map +1 -0
  80. package/dist/components/Action.d.ts.map +1 -1
  81. package/dist/components/Badge.d.ts +1 -1
  82. package/dist/components/Button.d.ts.map +1 -1
  83. package/dist/components/Card.d.ts.map +1 -1
  84. package/dist/components/DatePicker.d.ts.map +1 -1
  85. package/dist/components/Dropdown.d.ts +0 -50
  86. package/dist/components/Dropdown.d.ts.map +1 -1
  87. package/dist/components/Icon/Icon.d.ts.map +1 -1
  88. package/dist/components/Modal.d.ts.map +1 -1
  89. package/dist/components/Popover.d.ts +2 -0
  90. package/dist/components/Popover.d.ts.map +1 -1
  91. package/dist/components/Progress.d.ts +3 -2
  92. package/dist/components/Progress.d.ts.map +1 -1
  93. package/dist/components/Section.d.ts +44 -0
  94. package/dist/components/Section.d.ts.map +1 -0
  95. package/dist/components/advanced/AnimatedGradient.d.ts.map +1 -1
  96. package/dist/components/advanced/Carousel.d.ts.map +1 -1
  97. package/dist/components/advanced/DotNav.d.ts +26 -0
  98. package/dist/components/advanced/DotNav.d.ts.map +1 -0
  99. package/dist/components/advanced/HorizontalScroll.d.ts +20 -0
  100. package/dist/components/advanced/HorizontalScroll.d.ts.map +1 -0
  101. package/dist/components/advanced/ImageReveal.d.ts +24 -0
  102. package/dist/components/advanced/ImageReveal.d.ts.map +1 -0
  103. package/dist/components/advanced/Parallax.d.ts +9 -6
  104. package/dist/components/advanced/Parallax.d.ts.map +1 -1
  105. package/dist/components/advanced/TextReveal.d.ts.map +1 -1
  106. package/dist/components/advanced/index.d.ts +6 -0
  107. package/dist/components/advanced/index.d.ts.map +1 -1
  108. package/dist/data.mjs +1 -1
  109. package/dist/data.mjs.map +1 -1
  110. package/dist/feedback.mjs +1 -1
  111. package/dist/form.mjs +3 -3
  112. package/dist/form.mjs.map +1 -1
  113. package/dist/{icons-Bj_nr8Ba.d.mts → icons-DcOBy9Hf.d.mts} +10 -1
  114. package/dist/iconsax-extended.mjs +2 -2
  115. package/dist/iconsax-extended.mjs.map +1 -1
  116. package/dist/index.d.mts +10 -109
  117. package/dist/index.d.ts +4 -0
  118. package/dist/index.d.ts.map +1 -1
  119. package/dist/index.mjs +14 -14
  120. package/dist/index.mjs.map +1 -1
  121. package/dist/interactive.mjs +1 -1
  122. package/dist/interactive.mjs.map +1 -1
  123. package/dist/landing/LandingAbout.d.ts +3 -0
  124. package/dist/landing/LandingAbout.d.ts.map +1 -0
  125. package/dist/landing/LandingCTA.d.ts +3 -0
  126. package/dist/landing/LandingCTA.d.ts.map +1 -0
  127. package/dist/landing/LandingContact.d.ts +3 -0
  128. package/dist/landing/LandingContact.d.ts.map +1 -0
  129. package/dist/landing/LandingExperience.d.ts +3 -0
  130. package/dist/landing/LandingExperience.d.ts.map +1 -0
  131. package/dist/landing/LandingFeatures.d.ts +3 -0
  132. package/dist/landing/LandingFeatures.d.ts.map +1 -0
  133. package/dist/landing/LandingHero.d.ts +3 -0
  134. package/dist/landing/LandingHero.d.ts.map +1 -0
  135. package/dist/landing/LandingLogoCloud.d.ts +3 -0
  136. package/dist/landing/LandingLogoCloud.d.ts.map +1 -0
  137. package/dist/landing/LandingMetrics.d.ts +3 -0
  138. package/dist/landing/LandingMetrics.d.ts.map +1 -0
  139. package/dist/landing/LandingProjects.d.ts +3 -0
  140. package/dist/landing/LandingProjects.d.ts.map +1 -0
  141. package/dist/landing/LandingProvider.d.ts +4 -0
  142. package/dist/landing/LandingProvider.d.ts.map +1 -0
  143. package/dist/landing/LandingShowcase.d.ts +3 -0
  144. package/dist/landing/LandingShowcase.d.ts.map +1 -0
  145. package/dist/landing/LandingSkills.d.ts +3 -0
  146. package/dist/landing/LandingSkills.d.ts.map +1 -0
  147. package/dist/landing/LandingStats.d.ts +3 -0
  148. package/dist/landing/LandingStats.d.ts.map +1 -0
  149. package/dist/landing/LandingTestimonials.d.ts +3 -0
  150. package/dist/landing/LandingTestimonials.d.ts.map +1 -0
  151. package/dist/landing/index.d.ts +47 -0
  152. package/dist/landing/index.d.ts.map +1 -0
  153. package/dist/landing/themes/app.d.ts +3 -0
  154. package/dist/landing/themes/app.d.ts.map +1 -0
  155. package/dist/landing/themes/corporate.d.ts +3 -0
  156. package/dist/landing/themes/corporate.d.ts.map +1 -0
  157. package/dist/landing/themes/dashboard.d.ts +3 -0
  158. package/dist/landing/themes/dashboard.d.ts.map +1 -0
  159. package/dist/landing/themes/immersive.d.ts +3 -0
  160. package/dist/landing/themes/immersive.d.ts.map +1 -0
  161. package/dist/landing/themes/index.d.ts +15 -0
  162. package/dist/landing/themes/index.d.ts.map +1 -0
  163. package/dist/landing/themes/marketing.d.ts +3 -0
  164. package/dist/landing/themes/marketing.d.ts.map +1 -0
  165. package/dist/landing/themes/portfolio.d.ts +3 -0
  166. package/dist/landing/themes/portfolio.d.ts.map +1 -0
  167. package/dist/landing/themes/product.d.ts +3 -0
  168. package/dist/landing/themes/product.d.ts.map +1 -0
  169. package/dist/landing/types.d.ts +346 -0
  170. package/dist/landing/types.d.ts.map +1 -0
  171. package/dist/landing.d.mts +417 -0
  172. package/dist/landing.mjs +31 -0
  173. package/dist/landing.mjs.map +1 -0
  174. package/dist/lib/icon-providers.d.ts +9 -25
  175. package/dist/lib/icon-providers.d.ts.map +1 -1
  176. package/dist/lib/icons.d.ts +10 -1
  177. package/dist/lib/icons.d.ts.map +1 -1
  178. package/dist/lib/utils.d.ts.map +1 -1
  179. package/dist/navigation.d.mts +1 -1
  180. package/dist/navigation.mjs +1 -1
  181. package/dist/navigation.mjs.map +1 -1
  182. package/dist/overlay.d.mts +2 -50
  183. package/dist/overlay.mjs +1 -1
  184. package/dist/overlay.mjs.map +1 -1
  185. package/dist/sdui.mjs +1 -1
  186. package/dist/sdui.mjs.map +1 -1
  187. package/dist/theme.d.mts +85 -0
  188. package/dist/theme.d.ts +14 -0
  189. package/dist/theme.d.ts.map +1 -0
  190. package/dist/theme.mjs +3 -0
  191. package/dist/theme.mjs.map +1 -0
  192. package/package.json +30 -20
  193. package/src/styles/landing.css +107 -0
  194. package/src/styles/utilities.css +58 -0
  195. package/dist/advanced-dashboard.js +0 -39
  196. package/dist/advanced-dashboard.js.map +0 -1
  197. package/dist/advanced-emotion.js +0 -2
  198. package/dist/advanced-emotion.js.map +0 -1
  199. package/dist/advanced-motion.js +0 -82
  200. package/dist/advanced-motion.js.map +0 -1
  201. package/dist/advanced.js +0 -112
  202. package/dist/advanced.js.map +0 -1
  203. package/dist/chunk-BXX2TZUB.mjs +0 -3
  204. package/dist/chunk-BXX2TZUB.mjs.map +0 -1
  205. package/dist/chunk-COR6CDMA.mjs +0 -83
  206. package/dist/chunk-COR6CDMA.mjs.map +0 -1
  207. package/dist/chunk-FFH4ZFKS.mjs +0 -3
  208. package/dist/chunk-FFH4ZFKS.mjs.map +0 -1
  209. package/dist/chunk-HN5LSP6L.mjs +0 -3
  210. package/dist/chunk-HN5LSP6L.mjs.map +0 -1
  211. package/dist/chunk-LPAG7DCA.mjs +0 -3
  212. package/dist/chunk-LPAG7DCA.mjs.map +0 -1
  213. package/dist/chunk-QQCELXFD.mjs +0 -3
  214. package/dist/chunk-QQCELXFD.mjs.map +0 -1
  215. package/dist/chunk-RPUS7G7Q.mjs +0 -3
  216. package/dist/chunk-RPUS7G7Q.mjs.map +0 -1
  217. package/dist/chunk-SDFHJ4GB.mjs +0 -3
  218. package/dist/chunk-SDFHJ4GB.mjs.map +0 -1
  219. package/dist/chunk-UUHAXGMO.mjs +0 -3
  220. package/dist/chunk-UUHAXGMO.mjs.map +0 -1
  221. package/dist/data.js +0 -3
  222. package/dist/data.js.map +0 -1
  223. package/dist/feedback.js +0 -12
  224. package/dist/feedback.js.map +0 -1
  225. package/dist/form.js +0 -8
  226. package/dist/form.js.map +0 -1
  227. package/dist/iconsax-extended.js +0 -3
  228. package/dist/iconsax-extended.js.map +0 -1
  229. package/dist/iconsax.js +0 -3
  230. package/dist/iconsax.js.map +0 -1
  231. package/dist/index.js +0 -51
  232. package/dist/index.js.map +0 -1
  233. package/dist/interactive.js +0 -2
  234. package/dist/interactive.js.map +0 -1
  235. package/dist/lib/phosphor-icons.d.ts +0 -6
  236. package/dist/lib/phosphor-icons.d.ts.map +0 -1
  237. package/dist/navigation.js +0 -12
  238. package/dist/navigation.js.map +0 -1
  239. package/dist/overlay.js +0 -3
  240. package/dist/overlay.js.map +0 -1
  241. package/dist/sdui.js +0 -9
  242. package/dist/sdui.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/Textarea.tsx","../src/components/Checkbox.tsx"],"names":["textareaVariants","cva","Textarea","React","className","variant","size","error","success","resize","props","ref","ariaInvalid","isInvalid","jsx","merge","FORM_STATE","Checkbox","label","description","id","_a","_b","generatedId","checkboxId","labelId","descriptionId","sizeClasses","iconSizes","variantClasses","stateClasses","isControlled","isChecked","needsReadOnly","jsxs","Icon"],"mappings":"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","file":"chunk-UWHCM3S6.mjs","sourcesContent":["\"use client\"\n\nimport React from \"react\"\nimport { cva } from \"class-variance-authority\"\nimport { merge } from \"../lib/utils\"\nimport { FORM_STATE } from \"../lib/styles/cva-base\"\n\nexport const textareaVariants = cva(\n \"flex w-full rounded-md border transition-all duration-200 focus:outline-none focus:ring-1 focus:ring-offset-2 hover:border-accent-foreground hover:shadow-sm disabled:cursor-not-allowed disabled:opacity-50 placeholder:text-muted-foreground\",\n {\n variants: {\n variant: {\n default: \"border-input bg-background text-foreground focus:border-ring focus:ring-ring\",\n outline: \"border-2 border-input bg-transparent text-foreground focus:border-ring focus:ring-ring\",\n filled: \"border-transparent bg-secondary/50 text-foreground focus:bg-background focus:border-ring focus:ring-ring\",\n ghost: \"border-transparent bg-transparent text-foreground focus:bg-muted focus:border-border focus:ring-muted-foreground\",\n glass: \"border-white/30 bg-white/10 backdrop-blur-sm text-white placeholder:text-white/60 focus:border-ring/50 focus:ring-ring/20 focus:bg-white/20\",\n },\n size: {\n sm: \"px-3 py-2 text-sm min-h-[80px]\",\n md: \"px-4 py-3 text-base min-h-[100px]\",\n lg: \"px-4 py-3 text-lg min-h-[120px]\",\n },\n resize: {\n none: \"resize-none\",\n vertical: \"resize-y\",\n horizontal: \"resize-x\",\n both: \"resize\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"md\",\n resize: \"vertical\",\n },\n }\n)\n\n/**\n * Textarea 컴포넌트의 props / Textarea component props\n */\nexport interface TextareaProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {\n variant?: \"default\" | \"outline\" | \"filled\" | \"ghost\" | \"glass\"\n size?: \"sm\" | \"md\" | \"lg\"\n error?: boolean\n success?: boolean\n resize?: \"none\" | \"vertical\" | \"horizontal\" | \"both\"\n}\n\n/**\n * Textarea 컴포넌트 / Textarea component\n * \n * 여러 줄 텍스트 입력을 위한 텍스트 영역 컴포넌트입니다.\n * 다양한 스타일 변형과 크기를 지원하며, 접근성 속성을 포함합니다.\n * \n * Text area component for multi-line text input.\n * Supports various style variants and sizes, includes accessibility attributes.\n * \n * @component\n * @example\n * // 기본 사용 / Basic usage\n * <Textarea placeholder=\"내용을 입력하세요\" />\n * \n * @example\n * // 에러 상태 / Error state\n * <Textarea \n * error\n * placeholder=\"에러가 발생했습니다\"\n * aria-label=\"설명 입력\"\n * />\n * \n * @example\n * // 크기 조절 비활성화 / Disable resize\n * <Textarea \n * resize=\"none\"\n * rows={5}\n * placeholder=\"고정 크기 텍스트 영역\"\n * />\n * \n * @param {TextareaProps} props - Textarea 컴포넌트의 props / Textarea component props\n * @param {React.Ref<HTMLTextAreaElement>} ref - textarea 요소 ref / textarea element ref\n * @returns {JSX.Element} Textarea 컴포넌트 / Textarea component\n * \n * @todo 접근성 개선: aria-invalid 속성 자동 추가 필요 / Accessibility improvement: auto-add aria-invalid attribute\n */\nconst Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(\n ({ \n className, \n variant = \"default\",\n size = \"md\",\n error = false,\n success = false,\n resize = \"vertical\",\n ...props \n }, ref) => {\n const ariaInvalid = props['aria-invalid' as keyof typeof props] as boolean | undefined\n const isInvalid = error || (ariaInvalid !== undefined ? ariaInvalid : false)\n\n return (\n <textarea\n className={merge(\n textareaVariants({ variant, size, resize }),\n error && FORM_STATE.error,\n success && FORM_STATE.success,\n className\n )}\n ref={ref}\n aria-invalid={isInvalid || undefined}\n {...props}\n />\n )\n }\n)\nTextarea.displayName = \"Textarea\"\n\nexport { Textarea } ","\"use client\"\n\nimport React from \"react\"\nimport { merge } from \"../lib/utils\"\nimport { Icon } from \"./Icon\"\n\n/**\n * Checkbox 컴포넌트의 props / Checkbox component props\n * @typedef {Object} CheckboxProps\n * @property {\"default\" | \"outline\" | \"filled\" | \"glass\"} [variant=\"default\"] - Checkbox 스타일 변형 / Checkbox style variant\n * @property {\"sm\" | \"md\" | \"lg\"} [size=\"md\"] - Checkbox 크기 / Checkbox size\n * @property {boolean} [error=false] - 에러 상태 표시 / Error state\n * @property {boolean} [success=false] - 성공 상태 표시 / Success state\n * @property {string} [label] - 체크박스 레이블 텍스트 / Checkbox label text\n * @property {string} [description] - 체크박스 설명 텍스트 / Checkbox description text\n * @extends {Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size'>}\n */\nexport interface CheckboxProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size'> {\n variant?: \"default\" | \"outline\" | \"filled\" | \"glass\"\n size?: \"sm\" | \"md\" | \"lg\"\n error?: boolean\n success?: boolean\n label?: string\n description?: string\n}\n\n/**\n * Checkbox 컴포넌트 / Checkbox component\n * \n * 체크박스 입력 필드를 제공하는 컴포넌트입니다.\n * ARIA 속성을 자동으로 설정하여 접근성을 지원합니다.\n * \n * Checkbox input field component.\n * Automatically sets ARIA attributes for accessibility support.\n * \n * @component\n * @example\n * // 기본 사용 / Basic usage\n * <Checkbox label=\"이용약관에 동의합니다\" />\n * \n * @example\n * // 에러 상태와 설명 / Error state with description\n * <Checkbox \n * label=\"필수 항목\"\n * description=\"이 항목은 필수입니다\"\n * error\n * />\n * \n * @example\n * // 제어 컴포넌트 / Controlled component\n * const [checked, setChecked] = useState(false)\n * <Checkbox \n * checked={checked}\n * onChange={(e) => setChecked(e.target.checked)}\n * label=\"동의\"\n * />\n * \n * @param {CheckboxProps} props - Checkbox 컴포넌트의 props / Checkbox component props\n * @param {React.Ref<HTMLInputElement>} ref - input 요소 ref / input element ref\n * @returns {JSX.Element} Checkbox 컴포넌트 / Checkbox component\n */\nconst Checkbox = React.forwardRef<HTMLInputElement, CheckboxProps>(\n ({ \n className, \n variant = \"default\",\n size = \"md\",\n error = false,\n success = false,\n label,\n description,\n id,\n ...props \n }, ref) => {\n const generatedId = React.useId()\n const checkboxId = id || generatedId\n const labelId = label ? `${checkboxId}-label` : undefined\n const descriptionId = description ? `${checkboxId}-description` : undefined\n const sizeClasses = {\n sm: \"w-4 h-4\",\n md: \"w-5 h-5\",\n lg: \"w-6 h-6\"\n }\n\n const iconSizes = {\n sm: 12,\n md: 14,\n lg: 16\n }\n\n const variantClasses = {\n default: \"border-input bg-background text-primary focus:ring-ring\",\n outline: \"border-2 border-input bg-transparent text-primary focus:ring-ring\",\n filled: \"border-transparent bg-muted text-primary focus:bg-background focus:ring-ring\",\n glass: \"border-white/30 bg-white/10 backdrop-blur-sm text-white focus:ring-ring/50 focus:bg-white/20\",\n }\n\n const stateClasses = error\n ? \"border-destructive focus:ring-destructive\"\n : success\n ? \"border-green-500 focus:ring-green-500\"\n : \"\"\n\n // Support both controlled and uncontrolled modes\n const isControlled = props.checked !== undefined;\n const isChecked = props.checked ?? props.defaultChecked ?? false;\n // Add readOnly if controlled without onChange to suppress React warning\n const needsReadOnly = isControlled && !props.onChange && !props.readOnly;\n\n return (\n <div className=\"flex items-start space-x-3\">\n <div className=\"relative\">\n <input\n type=\"checkbox\"\n id={checkboxId}\n className={merge(\n \"peer absolute inset-0 w-full h-full opacity-0 cursor-pointer z-10\",\n className\n )}\n ref={ref}\n aria-checked={isChecked}\n aria-invalid={error}\n aria-label={!label ? props['aria-label'] : undefined}\n aria-labelledby={label ? labelId : undefined}\n aria-describedby={descriptionId}\n role=\"checkbox\"\n readOnly={needsReadOnly || props.readOnly}\n {...props}\n />\n <div\n className={merge(\n \"flex items-center justify-center rounded border transition-all duration-200 cursor-pointer relative\",\n \"peer-focus:outline-none peer-focus:ring-1 peer-focus:ring-offset-2\",\n \"peer-hover:border-accent-foreground peer-hover:shadow-sm\",\n \"peer-disabled:cursor-not-allowed peer-disabled:opacity-50\",\n sizeClasses[size],\n variantClasses[variant],\n stateClasses,\n isChecked && \"bg-primary border-primary shadow-md shadow-primary/20\",\n !isChecked && \"bg-background\"\n )}\n >\n {/* 체크 아이콘으로 개선 */}\n <Icon \n name=\"check\" \n size={iconSizes[size]} \n className={merge(\n \"text-white transition-all duration-200\",\n isChecked ? \"opacity-100 scale-100\" : \"opacity-0 scale-0\"\n )}\n />\n </div>\n </div>\n {(label || description) && (\n <div className=\"flex flex-col\">\n {label && (\n <label htmlFor={checkboxId} id={labelId} className=\"text-sm font-medium text-foreground cursor-pointer\">\n {label}\n </label>\n )}\n {description && (\n <p id={descriptionId} className=\"text-sm text-muted-foreground\">\n {description}\n </p>\n )}\n </div>\n )}\n </div>\n )\n }\n)\nCheckbox.displayName = \"Checkbox\"\n\nexport { Checkbox } "]}
1
+ {"version":3,"sources":["../src/components/Textarea.tsx","../src/components/Checkbox.tsx"],"names":["textareaVariants","cva","Textarea","React","className","variant","size","error","success","resize","props","ref","ariaInvalid","isInvalid","jsx","merge","FORM_STATE","Checkbox","label","description","id","_a","_b","generatedId","checkboxId","labelId","descriptionId","sizeClasses","iconSizes","variantClasses","stateClasses","isControlled","isChecked","needsReadOnly","jsxs","Icon"],"mappings":"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","file":"chunk-LL6QPRD7.mjs","sourcesContent":["\"use client\"\n\nimport React from \"react\"\nimport { cva } from \"class-variance-authority\"\nimport { merge } from \"../lib/utils\"\nimport { FORM_STATE } from \"../lib/styles/cva-base\"\n\nexport const textareaVariants = cva(\n \"flex w-full rounded-md border transition-all duration-200 focus:outline-none focus:ring-1 focus:ring-offset-2 hover:border-accent-foreground hover:shadow-sm disabled:cursor-not-allowed disabled:opacity-50 placeholder:text-muted-foreground\",\n {\n variants: {\n variant: {\n default: \"border-input bg-background text-foreground focus:border-ring focus:ring-ring\",\n outline: \"border-2 border-input bg-transparent text-foreground focus:border-ring focus:ring-ring\",\n filled: \"border-transparent bg-secondary/50 text-foreground focus:bg-background focus:border-ring focus:ring-ring\",\n ghost: \"border-transparent bg-transparent text-foreground focus:bg-muted focus:border-border focus:ring-muted-foreground\",\n glass: \"border-white/30 bg-white/10 backdrop-blur-sm text-white placeholder:text-white/60 focus:border-ring/50 focus:ring-ring/20 focus:bg-white/20\",\n },\n size: {\n sm: \"px-3 py-2 text-sm min-h-[80px]\",\n md: \"px-4 py-3 text-base min-h-[100px]\",\n lg: \"px-4 py-3 text-lg min-h-[120px]\",\n },\n resize: {\n none: \"resize-none\",\n vertical: \"resize-y\",\n horizontal: \"resize-x\",\n both: \"resize\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"md\",\n resize: \"vertical\",\n },\n }\n)\n\n/**\n * Textarea 컴포넌트의 props / Textarea component props\n */\nexport interface TextareaProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {\n variant?: \"default\" | \"outline\" | \"filled\" | \"ghost\" | \"glass\"\n size?: \"sm\" | \"md\" | \"lg\"\n error?: boolean\n success?: boolean\n resize?: \"none\" | \"vertical\" | \"horizontal\" | \"both\"\n}\n\n/**\n * Textarea 컴포넌트 / Textarea component\n * \n * 여러 줄 텍스트 입력을 위한 텍스트 영역 컴포넌트입니다.\n * 다양한 스타일 변형과 크기를 지원하며, 접근성 속성을 포함합니다.\n * \n * Text area component for multi-line text input.\n * Supports various style variants and sizes, includes accessibility attributes.\n * \n * @component\n * @example\n * // 기본 사용 / Basic usage\n * <Textarea placeholder=\"내용을 입력하세요\" />\n * \n * @example\n * // 에러 상태 / Error state\n * <Textarea \n * error\n * placeholder=\"에러가 발생했습니다\"\n * aria-label=\"설명 입력\"\n * />\n * \n * @example\n * // 크기 조절 비활성화 / Disable resize\n * <Textarea \n * resize=\"none\"\n * rows={5}\n * placeholder=\"고정 크기 텍스트 영역\"\n * />\n * \n * @param {TextareaProps} props - Textarea 컴포넌트의 props / Textarea component props\n * @param {React.Ref<HTMLTextAreaElement>} ref - textarea 요소 ref / textarea element ref\n * @returns {JSX.Element} Textarea 컴포넌트 / Textarea component\n * \n * @todo 접근성 개선: aria-invalid 속성 자동 추가 필요 / Accessibility improvement: auto-add aria-invalid attribute\n */\nconst Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(\n ({ \n className, \n variant = \"default\",\n size = \"md\",\n error = false,\n success = false,\n resize = \"vertical\",\n ...props \n }, ref) => {\n const ariaInvalid = props['aria-invalid' as keyof typeof props] as boolean | undefined\n const isInvalid = error || (ariaInvalid !== undefined ? ariaInvalid : false)\n\n return (\n <textarea\n className={merge(\n textareaVariants({ variant, size, resize }),\n error && FORM_STATE.error,\n success && FORM_STATE.success,\n className\n )}\n ref={ref}\n aria-invalid={isInvalid || undefined}\n {...props}\n />\n )\n }\n)\nTextarea.displayName = \"Textarea\"\n\nexport { Textarea } ","\"use client\"\n\nimport React from \"react\"\nimport { merge } from \"../lib/utils\"\nimport { Icon } from \"./Icon\"\n\n/**\n * Checkbox 컴포넌트의 props / Checkbox component props\n * @typedef {Object} CheckboxProps\n * @property {\"default\" | \"outline\" | \"filled\" | \"glass\"} [variant=\"default\"] - Checkbox 스타일 변형 / Checkbox style variant\n * @property {\"sm\" | \"md\" | \"lg\"} [size=\"md\"] - Checkbox 크기 / Checkbox size\n * @property {boolean} [error=false] - 에러 상태 표시 / Error state\n * @property {boolean} [success=false] - 성공 상태 표시 / Success state\n * @property {string} [label] - 체크박스 레이블 텍스트 / Checkbox label text\n * @property {string} [description] - 체크박스 설명 텍스트 / Checkbox description text\n * @extends {Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size'>}\n */\nexport interface CheckboxProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size'> {\n variant?: \"default\" | \"outline\" | \"filled\" | \"glass\"\n size?: \"sm\" | \"md\" | \"lg\"\n error?: boolean\n success?: boolean\n label?: string\n description?: string\n}\n\n/**\n * Checkbox 컴포넌트 / Checkbox component\n * \n * 체크박스 입력 필드를 제공하는 컴포넌트입니다.\n * ARIA 속성을 자동으로 설정하여 접근성을 지원합니다.\n * \n * Checkbox input field component.\n * Automatically sets ARIA attributes for accessibility support.\n * \n * @component\n * @example\n * // 기본 사용 / Basic usage\n * <Checkbox label=\"이용약관에 동의합니다\" />\n * \n * @example\n * // 에러 상태와 설명 / Error state with description\n * <Checkbox \n * label=\"필수 항목\"\n * description=\"이 항목은 필수입니다\"\n * error\n * />\n * \n * @example\n * // 제어 컴포넌트 / Controlled component\n * const [checked, setChecked] = useState(false)\n * <Checkbox \n * checked={checked}\n * onChange={(e) => setChecked(e.target.checked)}\n * label=\"동의\"\n * />\n * \n * @param {CheckboxProps} props - Checkbox 컴포넌트의 props / Checkbox component props\n * @param {React.Ref<HTMLInputElement>} ref - input 요소 ref / input element ref\n * @returns {JSX.Element} Checkbox 컴포넌트 / Checkbox component\n */\nconst Checkbox = React.forwardRef<HTMLInputElement, CheckboxProps>(\n ({ \n className, \n variant = \"default\",\n size = \"md\",\n error = false,\n success = false,\n label,\n description,\n id,\n ...props \n }, ref) => {\n const generatedId = React.useId()\n const checkboxId = id || generatedId\n const labelId = label ? `${checkboxId}-label` : undefined\n const descriptionId = description ? `${checkboxId}-description` : undefined\n const sizeClasses = {\n sm: \"w-4 h-4\",\n md: \"w-5 h-5\",\n lg: \"w-6 h-6\"\n }\n\n const iconSizes = {\n sm: 12,\n md: 14,\n lg: 16\n }\n\n const variantClasses = {\n default: \"border-input bg-background text-primary focus:ring-ring\",\n outline: \"border-2 border-input bg-transparent text-primary focus:ring-ring\",\n filled: \"border-transparent bg-muted text-primary focus:bg-background focus:ring-ring\",\n glass: \"border-white/30 bg-white/10 backdrop-blur-sm text-white focus:ring-ring/50 focus:bg-white/20\",\n }\n\n const stateClasses = error\n ? \"border-destructive focus:ring-destructive\"\n : success\n ? \"border-green-500 focus:ring-green-500\"\n : \"\"\n\n // Support both controlled and uncontrolled modes\n const isControlled = props.checked !== undefined;\n const isChecked = props.checked ?? props.defaultChecked ?? false;\n // Add readOnly if controlled without onChange to suppress React warning\n const needsReadOnly = isControlled && !props.onChange && !props.readOnly;\n\n return (\n <div className=\"flex items-start space-x-3\">\n <div className=\"relative\">\n <input\n type=\"checkbox\"\n id={checkboxId}\n className={merge(\n \"peer absolute inset-0 w-full h-full opacity-0 cursor-pointer z-10\",\n className\n )}\n ref={ref}\n aria-checked={isChecked}\n aria-invalid={error}\n aria-label={!label ? props['aria-label'] : undefined}\n aria-labelledby={label ? labelId : undefined}\n aria-describedby={descriptionId}\n role=\"checkbox\"\n readOnly={needsReadOnly || props.readOnly}\n {...props}\n />\n <div\n className={merge(\n \"flex items-center justify-center rounded border transition-all duration-200 cursor-pointer relative\",\n \"peer-focus:outline-none peer-focus:ring-1 peer-focus:ring-offset-2\",\n \"peer-hover:border-accent-foreground peer-hover:shadow-sm\",\n \"peer-disabled:cursor-not-allowed peer-disabled:opacity-50\",\n sizeClasses[size],\n variantClasses[variant],\n stateClasses,\n isChecked && \"bg-primary border-primary shadow-md shadow-primary/20\",\n !isChecked && \"bg-background\"\n )}\n >\n {/* 체크 아이콘으로 개선 */}\n <Icon \n name=\"check\" \n size={iconSizes[size]} \n className={merge(\n \"text-white transition-all duration-200\",\n isChecked ? \"opacity-100 scale-100\" : \"opacity-0 scale-0\"\n )}\n />\n </div>\n </div>\n {(label || description) && (\n <div className=\"flex flex-col\">\n {label && (\n <label htmlFor={checkboxId} id={labelId} className=\"text-sm font-medium text-foreground cursor-pointer\">\n {label}\n </label>\n )}\n {description && (\n <p id={descriptionId} className=\"text-sm text-muted-foreground\">\n {description}\n </p>\n )}\n </div>\n )}\n </div>\n )\n }\n)\nCheckbox.displayName = \"Checkbox\"\n\nexport { Checkbox } "]}
@@ -1,3 +1,3 @@
1
1
  "use client";
2
- import {a}from'./chunk-UUHAXGMO.mjs';import o from'react';import {jsx}from'react/jsx-runtime';var b=o.forwardRef(({className:e,variant:t="default",size:a$1="md",...d},s)=>{let n=()=>{switch(t){case "bordered":return "border border-border divide-x divide-border";case "striped":return "divide-y divide-border";default:return ""}},c=()=>{switch(a$1){case "sm":return "text-sm";case "lg":return "text-base";default:return "text-sm"}};return jsx("div",{className:"w-full overflow-auto",children:jsx("table",{ref:s,className:a("w-full caption-bottom",n(),c(),e),...d})})});b.displayName="Table";var i=o.forwardRef(({className:e,...t},a$1)=>jsx("thead",{ref:a$1,className:a("[&_tr]:border-b",e),...t}));i.displayName="TableHeader";var T=o.forwardRef(({className:e,...t},a$1)=>jsx("tbody",{ref:a$1,className:a("[&_tr:last-child]:border-0",e),...t}));T.displayName="TableBody";var m=o.forwardRef(({className:e,...t},a$1)=>jsx("tfoot",{ref:a$1,className:a("border-t bg-muted/50 font-medium [&>tr]:last:border-b-0",e),...t}));m.displayName="TableFooter";var f=o.forwardRef(({className:e,variant:t="default",...a$1},d)=>jsx("tr",{ref:d,className:a("border-b transition-colors data-[state=selected]:bg-muted/50",t==="hover"?"hover:bg-muted/50":"",e),...a$1}));f.displayName="TableRow";var p=o.forwardRef(({className:e,...t},a$1)=>jsx("th",{ref:a$1,className:a("h-12 px-4 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0",e),...t}));p.displayName="TableHead";var u=o.forwardRef(({className:e,...t},a$1)=>jsx("td",{ref:a$1,className:a("p-4 align-middle [&:has([role=checkbox])]:pr-0",e),...t}));u.displayName="TableCell";var R=o.forwardRef(({className:e,...t},a$1)=>jsx("caption",{ref:a$1,className:a("mt-4 text-sm text-muted-foreground",e),...t}));R.displayName="TableCaption";export{b as a,i as b,T as c,m as d,f as e,p as f,u as g,R as h};//# sourceMappingURL=chunk-PAEKNQWW.mjs.map
3
- //# sourceMappingURL=chunk-PAEKNQWW.mjs.map
2
+ import {a}from'./chunk-QEMPERUK.mjs';import o from'react';import {jsx}from'react/jsx-runtime';var b=o.forwardRef(({className:e,variant:t="default",size:a$1="md",...d},s)=>{let n=()=>{switch(t){case "bordered":return "border border-border divide-x divide-border";case "striped":return "divide-y divide-border";default:return ""}},c=()=>{switch(a$1){case "sm":return "text-sm";case "lg":return "text-base";default:return "text-sm"}};return jsx("div",{className:"w-full overflow-auto",children:jsx("table",{ref:s,className:a("w-full caption-bottom",n(),c(),e),...d})})});b.displayName="Table";var i=o.forwardRef(({className:e,...t},a$1)=>jsx("thead",{ref:a$1,className:a("[&_tr]:border-b",e),...t}));i.displayName="TableHeader";var T=o.forwardRef(({className:e,...t},a$1)=>jsx("tbody",{ref:a$1,className:a("[&_tr:last-child]:border-0",e),...t}));T.displayName="TableBody";var m=o.forwardRef(({className:e,...t},a$1)=>jsx("tfoot",{ref:a$1,className:a("border-t bg-muted/50 font-medium [&>tr]:last:border-b-0",e),...t}));m.displayName="TableFooter";var f=o.forwardRef(({className:e,variant:t="default",...a$1},d)=>jsx("tr",{ref:d,className:a("border-b transition-colors data-[state=selected]:bg-muted/50",t==="hover"?"hover:bg-muted/50":"",e),...a$1}));f.displayName="TableRow";var p=o.forwardRef(({className:e,...t},a$1)=>jsx("th",{ref:a$1,className:a("h-12 px-4 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0",e),...t}));p.displayName="TableHead";var u=o.forwardRef(({className:e,...t},a$1)=>jsx("td",{ref:a$1,className:a("p-4 align-middle [&:has([role=checkbox])]:pr-0",e),...t}));u.displayName="TableCell";var R=o.forwardRef(({className:e,...t},a$1)=>jsx("caption",{ref:a$1,className:a("mt-4 text-sm text-muted-foreground",e),...t}));R.displayName="TableCaption";export{b as a,i as b,T as c,m as d,f as e,p as f,u as g,R as h};//# sourceMappingURL=chunk-NMJLOK6M.mjs.map
3
+ //# sourceMappingURL=chunk-NMJLOK6M.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/Table.tsx"],"names":["Table","React","className","variant","size","props","ref","getVariantClasses","getSizeClasses","jsx","merge","TableHeader","TableBody","TableFooter","TableRow","TableHead","TableCell","TableCaption"],"mappings":"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","file":"chunk-PAEKNQWW.mjs","sourcesContent":["\"use client\"\n\nimport React from \"react\"\nimport { merge } from \"../lib/utils\"\n\n/**\n * Table 컴포넌트의 props / Table component props\n * @typedef {Object} TableProps\n * @property {React.ReactNode} children - TableHeader, TableBody, TableFooter 등 / TableHeader, TableBody, TableFooter, etc.\n * @property {\"default\" | \"bordered\" | \"striped\"} [variant=\"default\"] - Table 스타일 변형 / Table style variant\n * @property {\"sm\" | \"md\" | \"lg\"} [size=\"md\"] - Table 크기 / Table size\n * @extends {React.HTMLAttributes<HTMLTableElement>}\n */\nexport interface TableProps extends React.HTMLAttributes<HTMLTableElement> {\n children: React.ReactNode\n variant?: \"default\" | \"bordered\" | \"striped\"\n size?: \"sm\" | \"md\" | \"lg\"\n}\n\n/**\n * TableHeader 컴포넌트의 props / TableHeader component props\n * @typedef {Object} TableHeaderProps\n * @property {React.ReactNode} children - TableHead 컴포넌트들 / TableHead components\n * @extends {React.HTMLAttributes<HTMLTableSectionElement>}\n */\nexport interface TableHeaderProps extends React.HTMLAttributes<HTMLTableSectionElement> {\n children: React.ReactNode\n}\n\n/**\n * TableBody 컴포넌트의 props / TableBody component props\n * @typedef {Object} TableBodyProps\n * @property {React.ReactNode} children - TableRow 컴포넌트들 / TableRow components\n * @extends {React.HTMLAttributes<HTMLTableSectionElement>}\n */\nexport interface TableBodyProps extends React.HTMLAttributes<HTMLTableSectionElement> {\n children: React.ReactNode\n}\n\n/**\n * TableFooter 컴포넌트의 props / TableFooter component props\n * @typedef {Object} TableFooterProps\n * @property {React.ReactNode} children - TableRow 컴포넌트들 / TableRow components\n * @extends {React.HTMLAttributes<HTMLTableSectionElement>}\n */\nexport interface TableFooterProps extends React.HTMLAttributes<HTMLTableSectionElement> {\n children: React.ReactNode\n}\n\n/**\n * TableRow 컴포넌트의 props / TableRow component props\n * @typedef {Object} TableRowProps\n * @property {React.ReactNode} children - TableHead 또는 TableCell 컴포넌트들 / TableHead or TableCell components\n * @property {\"default\" | \"hover\"} [variant=\"default\"] - Row 스타일 변형 / Row style variant\n * @extends {React.HTMLAttributes<HTMLTableRowElement>}\n */\nexport interface TableRowProps extends React.HTMLAttributes<HTMLTableRowElement> {\n children: React.ReactNode\n variant?: \"default\" | \"hover\"\n}\n\n/**\n * TableHead 컴포넌트의 props / TableHead component props\n * @typedef {Object} TableHeadProps\n * @property {React.ReactNode} children - 헤더 셀 내용 / Header cell content\n * @extends {React.ThHTMLAttributes<HTMLTableCellElement>}\n */\nexport interface TableHeadProps extends React.ThHTMLAttributes<HTMLTableCellElement> {\n children: React.ReactNode\n}\n\n/**\n * TableCell 컴포넌트의 props / TableCell component props\n * @typedef {Object} TableCellProps\n * @property {React.ReactNode} children - 셀 내용 / Cell content\n * @extends {React.TdHTMLAttributes<HTMLTableCellElement>}\n */\nexport interface TableCellProps extends React.TdHTMLAttributes<HTMLTableCellElement> {\n children: React.ReactNode\n}\n\n/**\n * Table 컴포넌트 / Table component\n * \n * 데이터를 표 형태로 표시하는 테이블 컴포넌트입니다.\n * TableHeader, TableBody, TableFooter, TableRow, TableHead, TableCell과 함께 사용합니다.\n * \n * Table component that displays data in tabular format.\n * Used with TableHeader, TableBody, TableFooter, TableRow, TableHead, and TableCell.\n * \n * @component\n * @example\n * // 기본 사용 / Basic usage\n * <Table>\n * <TableHeader>\n * <TableRow>\n * <TableHead>이름</TableHead>\n * <TableHead>나이</TableHead>\n * </TableRow>\n * </TableHeader>\n * <TableBody>\n * <TableRow>\n * <TableCell>홍길동</TableCell>\n * <TableCell>30</TableCell>\n * </TableRow>\n * </TableBody>\n * </Table>\n * \n * @example\n * // Bordered 스타일 / Bordered style\n * <Table variant=\"bordered\">\n * <TableHeader>\n * <TableRow>\n * <TableHead>항목</TableHead>\n * </TableRow>\n * </TableHeader>\n * <TableBody>\n * <TableRow>\n * <TableCell>값</TableCell>\n * </TableRow>\n * </TableBody>\n * </Table>\n * \n * @example\n * // Striped 스타일, 호버 효과 / Striped style with hover effect\n * <Table variant=\"striped\">\n * <TableBody>\n * <TableRow variant=\"hover\">\n * <TableCell>데이터</TableCell>\n * </TableRow>\n * </TableBody>\n * </Table>\n * \n * @param {TableProps} props - Table 컴포넌트의 props / Table component props\n * @param {React.Ref<HTMLTableElement>} ref - table 요소 ref / table element ref\n * @returns {JSX.Element} Table 컴포넌트 / Table component\n */\nconst Table = React.forwardRef<HTMLTableElement, TableProps>(\n ({ className, variant = \"default\", size = \"md\", ...props }, ref) => {\n const getVariantClasses = () => {\n switch (variant) {\n case \"bordered\":\n return \"border border-border divide-x divide-border\"\n case \"striped\":\n return \"divide-y divide-border\"\n default:\n return \"\"\n }\n }\n\n const getSizeClasses = () => {\n switch (size) {\n case \"sm\":\n return \"text-sm\"\n case \"lg\":\n return \"text-base\"\n default:\n return \"text-sm\"\n }\n }\n\n return (\n <div className=\"w-full overflow-auto\">\n <table\n ref={ref}\n className={merge(\n \"w-full caption-bottom\",\n getVariantClasses(),\n getSizeClasses(),\n className\n )}\n {...props}\n />\n </div>\n )\n }\n)\nTable.displayName = \"Table\"\n\n/**\n * TableHeader 컴포넌트 / TableHeader component\n * 테이블의 헤더 영역을 표시합니다.\n * Displays the header area of a table.\n * \n * @component\n * @param {TableHeaderProps} props - TableHeader 컴포넌트의 props / TableHeader component props\n * @param {React.Ref<HTMLTableSectionElement>} ref - thead 요소 ref / thead element ref\n * @returns {JSX.Element} TableHeader 컴포넌트 / TableHeader component\n */\nconst TableHeader = React.forwardRef<HTMLTableSectionElement, TableHeaderProps>(\n ({ className, ...props }, ref) => (\n <thead ref={ref} className={merge(\"[&_tr]:border-b\", className)} {...props} />\n )\n)\nTableHeader.displayName = \"TableHeader\"\n\n/**\n * TableBody 컴포넌트 / TableBody component\n * 테이블의 본문 영역을 표시합니다.\n * Displays the body area of a table.\n * \n * @component\n * @param {TableBodyProps} props - TableBody 컴포넌트의 props / TableBody component props\n * @param {React.Ref<HTMLTableSectionElement>} ref - tbody 요소 ref / tbody element ref\n * @returns {JSX.Element} TableBody 컴포넌트 / TableBody component\n */\nconst TableBody = React.forwardRef<HTMLTableSectionElement, TableBodyProps>(\n ({ className, ...props }, ref) => (\n <tbody\n ref={ref}\n className={merge(\"[&_tr:last-child]:border-0\", className)}\n {...props}\n />\n )\n)\nTableBody.displayName = \"TableBody\"\n\n/**\n * TableFooter 컴포넌트 / TableFooter component\n * 테이블의 푸터 영역을 표시합니다.\n * Displays the footer area of a table.\n * \n * @component\n * @param {TableFooterProps} props - TableFooter 컴포넌트의 props / TableFooter component props\n * @param {React.Ref<HTMLTableSectionElement>} ref - tfoot 요소 ref / tfoot element ref\n * @returns {JSX.Element} TableFooter 컴포넌트 / TableFooter component\n */\nconst TableFooter = React.forwardRef<HTMLTableSectionElement, TableFooterProps>(\n ({ className, ...props }, ref) => (\n <tfoot\n ref={ref}\n className={merge(\n \"border-t bg-muted/50 font-medium [&>tr]:last:border-b-0\",\n className\n )}\n {...props}\n />\n )\n)\nTableFooter.displayName = \"TableFooter\"\n\n/**\n * TableRow 컴포넌트 / TableRow component\n * 테이블의 행을 표시합니다.\n * Displays a table row.\n * \n * @component\n * @param {TableRowProps} props - TableRow 컴포넌트의 props / TableRow component props\n * @param {React.Ref<HTMLTableRowElement>} ref - tr 요소 ref / tr element ref\n * @returns {JSX.Element} TableRow 컴포넌트 / TableRow component\n */\nconst TableRow = React.forwardRef<HTMLTableRowElement, TableRowProps>(\n ({ className, variant = \"default\", ...props }, ref) => {\n const getVariantClasses = () => {\n switch (variant) {\n case \"hover\":\n return \"hover:bg-muted/50\"\n default:\n return \"\"\n }\n }\n\n return (\n <tr\n ref={ref}\n className={merge(\n \"border-b transition-colors data-[state=selected]:bg-muted/50\",\n getVariantClasses(),\n className\n )}\n {...props}\n />\n )\n }\n)\nTableRow.displayName = \"TableRow\"\n\n/**\n * TableHead 컴포넌트 / TableHead component\n * 테이블의 헤더 셀을 표시합니다.\n * Displays a table header cell.\n * \n * @component\n * @param {TableHeadProps} props - TableHead 컴포넌트의 props / TableHead component props\n * @param {React.Ref<HTMLTableCellElement>} ref - th 요소 ref / th element ref\n * @returns {JSX.Element} TableHead 컴포넌트 / TableHead component\n */\nconst TableHead = React.forwardRef<HTMLTableCellElement, TableHeadProps>(\n ({ className, ...props }, ref) => (\n <th\n ref={ref}\n className={merge(\n \"h-12 px-4 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0\",\n className\n )}\n {...props}\n />\n )\n)\nTableHead.displayName = \"TableHead\"\n\n/**\n * TableCell 컴포넌트 / TableCell component\n * 테이블의 데이터 셀을 표시합니다.\n * Displays a table data cell.\n * \n * @component\n * @param {TableCellProps} props - TableCell 컴포넌트의 props / TableCell component props\n * @param {React.Ref<HTMLTableCellElement>} ref - td 요소 ref / td element ref\n * @returns {JSX.Element} TableCell 컴포넌트 / TableCell component\n */\nconst TableCell = React.forwardRef<HTMLTableCellElement, TableCellProps>(\n ({ className, ...props }, ref) => (\n <td\n ref={ref}\n className={merge(\"p-4 align-middle [&:has([role=checkbox])]:pr-0\", className)}\n {...props}\n />\n )\n)\nTableCell.displayName = \"TableCell\"\n\n/**\n * TableCaption 컴포넌트 / TableCaption component\n * 테이블의 캡션을 표시합니다.\n * Displays a table caption.\n * \n * @component\n * @param {React.HTMLAttributes<HTMLTableCaptionElement>} props - TableCaption 컴포넌트의 props / TableCaption component props\n * @param {React.Ref<HTMLTableCaptionElement>} ref - caption 요소 ref / caption element ref\n * @returns {JSX.Element} TableCaption 컴포넌트 / TableCaption component\n */\nconst TableCaption = React.forwardRef<HTMLTableCaptionElement, React.HTMLAttributes<HTMLTableCaptionElement>>(\n ({ className, ...props }, ref) => (\n <caption\n ref={ref}\n className={merge(\"mt-4 text-sm text-muted-foreground\", className)}\n {...props}\n />\n )\n)\nTableCaption.displayName = \"TableCaption\"\n\nexport {\n Table,\n TableHeader,\n TableBody,\n TableFooter,\n TableHead,\n TableRow,\n TableCell,\n TableCaption,\n} "]}
1
+ {"version":3,"sources":["../src/components/Table.tsx"],"names":["Table","React","className","variant","size","props","ref","getVariantClasses","getSizeClasses","jsx","merge","TableHeader","TableBody","TableFooter","TableRow","TableHead","TableCell","TableCaption"],"mappings":"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","file":"chunk-NMJLOK6M.mjs","sourcesContent":["\"use client\"\n\nimport React from \"react\"\nimport { merge } from \"../lib/utils\"\n\n/**\n * Table 컴포넌트의 props / Table component props\n * @typedef {Object} TableProps\n * @property {React.ReactNode} children - TableHeader, TableBody, TableFooter 등 / TableHeader, TableBody, TableFooter, etc.\n * @property {\"default\" | \"bordered\" | \"striped\"} [variant=\"default\"] - Table 스타일 변형 / Table style variant\n * @property {\"sm\" | \"md\" | \"lg\"} [size=\"md\"] - Table 크기 / Table size\n * @extends {React.HTMLAttributes<HTMLTableElement>}\n */\nexport interface TableProps extends React.HTMLAttributes<HTMLTableElement> {\n children: React.ReactNode\n variant?: \"default\" | \"bordered\" | \"striped\"\n size?: \"sm\" | \"md\" | \"lg\"\n}\n\n/**\n * TableHeader 컴포넌트의 props / TableHeader component props\n * @typedef {Object} TableHeaderProps\n * @property {React.ReactNode} children - TableHead 컴포넌트들 / TableHead components\n * @extends {React.HTMLAttributes<HTMLTableSectionElement>}\n */\nexport interface TableHeaderProps extends React.HTMLAttributes<HTMLTableSectionElement> {\n children: React.ReactNode\n}\n\n/**\n * TableBody 컴포넌트의 props / TableBody component props\n * @typedef {Object} TableBodyProps\n * @property {React.ReactNode} children - TableRow 컴포넌트들 / TableRow components\n * @extends {React.HTMLAttributes<HTMLTableSectionElement>}\n */\nexport interface TableBodyProps extends React.HTMLAttributes<HTMLTableSectionElement> {\n children: React.ReactNode\n}\n\n/**\n * TableFooter 컴포넌트의 props / TableFooter component props\n * @typedef {Object} TableFooterProps\n * @property {React.ReactNode} children - TableRow 컴포넌트들 / TableRow components\n * @extends {React.HTMLAttributes<HTMLTableSectionElement>}\n */\nexport interface TableFooterProps extends React.HTMLAttributes<HTMLTableSectionElement> {\n children: React.ReactNode\n}\n\n/**\n * TableRow 컴포넌트의 props / TableRow component props\n * @typedef {Object} TableRowProps\n * @property {React.ReactNode} children - TableHead 또는 TableCell 컴포넌트들 / TableHead or TableCell components\n * @property {\"default\" | \"hover\"} [variant=\"default\"] - Row 스타일 변형 / Row style variant\n * @extends {React.HTMLAttributes<HTMLTableRowElement>}\n */\nexport interface TableRowProps extends React.HTMLAttributes<HTMLTableRowElement> {\n children: React.ReactNode\n variant?: \"default\" | \"hover\"\n}\n\n/**\n * TableHead 컴포넌트의 props / TableHead component props\n * @typedef {Object} TableHeadProps\n * @property {React.ReactNode} children - 헤더 셀 내용 / Header cell content\n * @extends {React.ThHTMLAttributes<HTMLTableCellElement>}\n */\nexport interface TableHeadProps extends React.ThHTMLAttributes<HTMLTableCellElement> {\n children: React.ReactNode\n}\n\n/**\n * TableCell 컴포넌트의 props / TableCell component props\n * @typedef {Object} TableCellProps\n * @property {React.ReactNode} children - 셀 내용 / Cell content\n * @extends {React.TdHTMLAttributes<HTMLTableCellElement>}\n */\nexport interface TableCellProps extends React.TdHTMLAttributes<HTMLTableCellElement> {\n children: React.ReactNode\n}\n\n/**\n * Table 컴포넌트 / Table component\n * \n * 데이터를 표 형태로 표시하는 테이블 컴포넌트입니다.\n * TableHeader, TableBody, TableFooter, TableRow, TableHead, TableCell과 함께 사용합니다.\n * \n * Table component that displays data in tabular format.\n * Used with TableHeader, TableBody, TableFooter, TableRow, TableHead, and TableCell.\n * \n * @component\n * @example\n * // 기본 사용 / Basic usage\n * <Table>\n * <TableHeader>\n * <TableRow>\n * <TableHead>이름</TableHead>\n * <TableHead>나이</TableHead>\n * </TableRow>\n * </TableHeader>\n * <TableBody>\n * <TableRow>\n * <TableCell>홍길동</TableCell>\n * <TableCell>30</TableCell>\n * </TableRow>\n * </TableBody>\n * </Table>\n * \n * @example\n * // Bordered 스타일 / Bordered style\n * <Table variant=\"bordered\">\n * <TableHeader>\n * <TableRow>\n * <TableHead>항목</TableHead>\n * </TableRow>\n * </TableHeader>\n * <TableBody>\n * <TableRow>\n * <TableCell>값</TableCell>\n * </TableRow>\n * </TableBody>\n * </Table>\n * \n * @example\n * // Striped 스타일, 호버 효과 / Striped style with hover effect\n * <Table variant=\"striped\">\n * <TableBody>\n * <TableRow variant=\"hover\">\n * <TableCell>데이터</TableCell>\n * </TableRow>\n * </TableBody>\n * </Table>\n * \n * @param {TableProps} props - Table 컴포넌트의 props / Table component props\n * @param {React.Ref<HTMLTableElement>} ref - table 요소 ref / table element ref\n * @returns {JSX.Element} Table 컴포넌트 / Table component\n */\nconst Table = React.forwardRef<HTMLTableElement, TableProps>(\n ({ className, variant = \"default\", size = \"md\", ...props }, ref) => {\n const getVariantClasses = () => {\n switch (variant) {\n case \"bordered\":\n return \"border border-border divide-x divide-border\"\n case \"striped\":\n return \"divide-y divide-border\"\n default:\n return \"\"\n }\n }\n\n const getSizeClasses = () => {\n switch (size) {\n case \"sm\":\n return \"text-sm\"\n case \"lg\":\n return \"text-base\"\n default:\n return \"text-sm\"\n }\n }\n\n return (\n <div className=\"w-full overflow-auto\">\n <table\n ref={ref}\n className={merge(\n \"w-full caption-bottom\",\n getVariantClasses(),\n getSizeClasses(),\n className\n )}\n {...props}\n />\n </div>\n )\n }\n)\nTable.displayName = \"Table\"\n\n/**\n * TableHeader 컴포넌트 / TableHeader component\n * 테이블의 헤더 영역을 표시합니다.\n * Displays the header area of a table.\n * \n * @component\n * @param {TableHeaderProps} props - TableHeader 컴포넌트의 props / TableHeader component props\n * @param {React.Ref<HTMLTableSectionElement>} ref - thead 요소 ref / thead element ref\n * @returns {JSX.Element} TableHeader 컴포넌트 / TableHeader component\n */\nconst TableHeader = React.forwardRef<HTMLTableSectionElement, TableHeaderProps>(\n ({ className, ...props }, ref) => (\n <thead ref={ref} className={merge(\"[&_tr]:border-b\", className)} {...props} />\n )\n)\nTableHeader.displayName = \"TableHeader\"\n\n/**\n * TableBody 컴포넌트 / TableBody component\n * 테이블의 본문 영역을 표시합니다.\n * Displays the body area of a table.\n * \n * @component\n * @param {TableBodyProps} props - TableBody 컴포넌트의 props / TableBody component props\n * @param {React.Ref<HTMLTableSectionElement>} ref - tbody 요소 ref / tbody element ref\n * @returns {JSX.Element} TableBody 컴포넌트 / TableBody component\n */\nconst TableBody = React.forwardRef<HTMLTableSectionElement, TableBodyProps>(\n ({ className, ...props }, ref) => (\n <tbody\n ref={ref}\n className={merge(\"[&_tr:last-child]:border-0\", className)}\n {...props}\n />\n )\n)\nTableBody.displayName = \"TableBody\"\n\n/**\n * TableFooter 컴포넌트 / TableFooter component\n * 테이블의 푸터 영역을 표시합니다.\n * Displays the footer area of a table.\n * \n * @component\n * @param {TableFooterProps} props - TableFooter 컴포넌트의 props / TableFooter component props\n * @param {React.Ref<HTMLTableSectionElement>} ref - tfoot 요소 ref / tfoot element ref\n * @returns {JSX.Element} TableFooter 컴포넌트 / TableFooter component\n */\nconst TableFooter = React.forwardRef<HTMLTableSectionElement, TableFooterProps>(\n ({ className, ...props }, ref) => (\n <tfoot\n ref={ref}\n className={merge(\n \"border-t bg-muted/50 font-medium [&>tr]:last:border-b-0\",\n className\n )}\n {...props}\n />\n )\n)\nTableFooter.displayName = \"TableFooter\"\n\n/**\n * TableRow 컴포넌트 / TableRow component\n * 테이블의 행을 표시합니다.\n * Displays a table row.\n * \n * @component\n * @param {TableRowProps} props - TableRow 컴포넌트의 props / TableRow component props\n * @param {React.Ref<HTMLTableRowElement>} ref - tr 요소 ref / tr element ref\n * @returns {JSX.Element} TableRow 컴포넌트 / TableRow component\n */\nconst TableRow = React.forwardRef<HTMLTableRowElement, TableRowProps>(\n ({ className, variant = \"default\", ...props }, ref) => {\n const getVariantClasses = () => {\n switch (variant) {\n case \"hover\":\n return \"hover:bg-muted/50\"\n default:\n return \"\"\n }\n }\n\n return (\n <tr\n ref={ref}\n className={merge(\n \"border-b transition-colors data-[state=selected]:bg-muted/50\",\n getVariantClasses(),\n className\n )}\n {...props}\n />\n )\n }\n)\nTableRow.displayName = \"TableRow\"\n\n/**\n * TableHead 컴포넌트 / TableHead component\n * 테이블의 헤더 셀을 표시합니다.\n * Displays a table header cell.\n * \n * @component\n * @param {TableHeadProps} props - TableHead 컴포넌트의 props / TableHead component props\n * @param {React.Ref<HTMLTableCellElement>} ref - th 요소 ref / th element ref\n * @returns {JSX.Element} TableHead 컴포넌트 / TableHead component\n */\nconst TableHead = React.forwardRef<HTMLTableCellElement, TableHeadProps>(\n ({ className, ...props }, ref) => (\n <th\n ref={ref}\n className={merge(\n \"h-12 px-4 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0\",\n className\n )}\n {...props}\n />\n )\n)\nTableHead.displayName = \"TableHead\"\n\n/**\n * TableCell 컴포넌트 / TableCell component\n * 테이블의 데이터 셀을 표시합니다.\n * Displays a table data cell.\n * \n * @component\n * @param {TableCellProps} props - TableCell 컴포넌트의 props / TableCell component props\n * @param {React.Ref<HTMLTableCellElement>} ref - td 요소 ref / td element ref\n * @returns {JSX.Element} TableCell 컴포넌트 / TableCell component\n */\nconst TableCell = React.forwardRef<HTMLTableCellElement, TableCellProps>(\n ({ className, ...props }, ref) => (\n <td\n ref={ref}\n className={merge(\"p-4 align-middle [&:has([role=checkbox])]:pr-0\", className)}\n {...props}\n />\n )\n)\nTableCell.displayName = \"TableCell\"\n\n/**\n * TableCaption 컴포넌트 / TableCaption component\n * 테이블의 캡션을 표시합니다.\n * Displays a table caption.\n * \n * @component\n * @param {React.HTMLAttributes<HTMLTableCaptionElement>} props - TableCaption 컴포넌트의 props / TableCaption component props\n * @param {React.Ref<HTMLTableCaptionElement>} ref - caption 요소 ref / caption element ref\n * @returns {JSX.Element} TableCaption 컴포넌트 / TableCaption component\n */\nconst TableCaption = React.forwardRef<HTMLTableCaptionElement, React.HTMLAttributes<HTMLTableCaptionElement>>(\n ({ className, ...props }, ref) => (\n <caption\n ref={ref}\n className={merge(\"mt-4 text-sm text-muted-foreground\", className)}\n {...props}\n />\n )\n)\nTableCaption.displayName = \"TableCaption\"\n\nexport {\n Table,\n TableHeader,\n TableBody,\n TableFooter,\n TableHead,\n TableRow,\n TableCell,\n TableCaption,\n} "]}
@@ -0,0 +1,3 @@
1
+ "use client";
2
+ import {a}from'./chunk-SD6XGDAC.mjs';import {a as a$1}from'./chunk-QEMPERUK.mjs';import m from'react';import {clsx}from'clsx';import {cva}from'class-variance-authority';import {jsxs,Fragment,jsx}from'react/jsx-runtime';function q(...t){return r=>{t.forEach(o=>{typeof o=="function"?o(r):o!=null&&(o.current=r);});}}function F(t,r){return o=>{t==null||t(o),o.defaultPrevented||r==null||r(o);}}function J(t,r){if(!(!t&&!r))return clsx(t,r)}function K(t,r){if(!(!t&&!r))return {...t,...r}}function Q(t,r){let o={...t};for(let e in r){let n=t[e],a=r[e];/^on[A-Z]/.test(e)?n&&a?o[e]=F(n,a):o[e]=a||n:e==="className"?o[e]=J(n,a):e==="style"?o[e]=K(n,a):o[e]=a!==void 0?a:n;}return o}function U(t){return m.isValidElement(t)}var R=m.forwardRef(({children:t,...r},o)=>{let e=m.Children.toArray(t);if(e.length!==1)return process.env.NODE_ENV!=="production"&&console.warn("[Slot] asChild\uB294 \uC815\uD655\uD788 \uD558\uB098\uC758 \uC790\uC2DD \uC694\uC18C\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4."),null;let n=e[0];if(!U(n))return process.env.NODE_ENV!=="production"&&console.warn("[Slot] \uC790\uC2DD\uC740 \uC720\uD6A8\uD55C React \uC694\uC18C\uC5EC\uC57C \uD569\uB2C8\uB2E4."),null;let a=n.props,p=n.ref,c=Q(r,a),g=q(o,p);return m.cloneElement(n,{...c,ref:g})});R.displayName="Slot";var T="[transition:transform_180ms_cubic-bezier(0.34,1.56,0.64,1),box-shadow_200ms_ease-out]",B=cva("inline-flex items-center justify-center whitespace-nowrap font-medium transition-all duration-200 disabled:pointer-events-none disabled:opacity-50 min-w-fit focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-[var(--color-ring)] focus-visible:ring-offset-2 focus-visible:ring-offset-[var(--color-background)]",{variants:{variant:{default:"bg-[var(--color-primary)] text-[var(--color-primary-foreground)] hover:opacity-90",destructive:"bg-[var(--color-destructive)] text-[var(--color-destructive-foreground)] hover:opacity-90 focus-visible:ring-[var(--color-destructive)]",outline:"border-2 border-[var(--color-border)] bg-transparent text-[var(--color-foreground)] hover:bg-[var(--color-accent)] hover:text-[var(--color-accent-foreground)] focus-visible:ring-offset-0",secondary:"bg-[var(--color-secondary)] text-[var(--color-secondary-foreground)] hover:opacity-80",ghost:"bg-transparent text-[var(--color-foreground)] hover:bg-[var(--color-accent)] hover:text-[var(--color-accent-foreground)] focus-visible:ring-offset-0",link:"bg-transparent text-[var(--color-primary)] underline hover:opacity-80 focus-visible:ring-offset-0",gradient:"bg-gradient-to-r from-[var(--btn-gradient-from,theme(colors.teal.500))] to-[var(--btn-gradient-to,theme(colors.cyan.500))] text-white hover:shadow-lg",neon:"bg-slate-900 dark:bg-slate-950 text-teal-400 border border-teal-500/50 shadow-lg shadow-[var(--btn-neon-glow,theme(colors.teal.500/20%))] hover:shadow-[var(--btn-neon-glow,theme(colors.teal.500/40%))] hover:border-teal-400",glass:"bg-white/50 dark:bg-slate-900/50 backdrop-blur-md border border-slate-200/50 dark:border-slate-700/50 text-slate-900 dark:text-slate-100 hover:bg-white/70 dark:hover:bg-slate-900/70"},size:{sm:"h-8 px-4 py-2 text-sm",md:"h-10 px-6 py-2 text-base",lg:"h-12 px-8 py-3 text-lg",xl:"h-14 px-10 py-4 text-xl",icon:"h-10 w-10 p-0"},rounded:{sm:"rounded",md:"rounded-md",lg:"rounded-lg",full:"rounded-full"},shadow:{none:"",sm:"shadow-sm",md:"shadow-md",lg:"shadow-lg",xl:"shadow-xl"},hover:{springy:`hover:scale-[1.015] hover:shadow-md active:scale-[0.985] ${T} transform-gpu`,scale:"hover:scale-[1.015] active:scale-[0.985] transition-transform duration-150 ease-out transform-gpu",glow:"hover:shadow-lg hover:shadow-primary/25 transition-shadow duration-200",slide:`hover:-translate-y-0.5 hover:shadow-md ${T} transform-gpu`,none:""},fullWidth:{true:"w-full",false:""}},defaultVariants:{variant:"default",size:"md",rounded:"md",shadow:"md",hover:"springy",fullWidth:false}}),x={blue:"from-teal-500 to-cyan-500",purple:"from-purple-500 to-pink-500",green:"from-green-500 to-emerald-500 dark:from-green-400 dark:to-emerald-400",orange:"from-orange-500 to-red-500 dark:from-orange-300 dark:to-red-300",pink:"from-pink-500 to-rose-500"};var M=m.forwardRef(function({variant:r="default",size:o="md",loading:e=false,icon:n,iconPosition:a$2="left",gradient:p="blue",customGradient:c,rounded:g="md",shadow:L="md",hover:V="springy",fullWidth:v,iconOnly:H,className:O,children:k,disabled:d,asChild:_=false,...i},b){let z=a(),D=r==="gradient"?c?`bg-gradient-to-r ${c}`:`bg-gradient-to-r ${x[p]||x.blue}`:void 0,h=a$1(B({variant:r,size:o,rounded:g,shadow:L,hover:z?"none":V,fullWidth:v!=null?v:false}),D,O),P=jsxs(Fragment,{children:[e&&jsxs("span",{role:"status","aria-live":"polite",className:"-ml-1 mr-2 inline-flex",children:[jsxs("svg",{className:"animate-spin h-4 w-4",viewBox:"0 0 24 24",fill:"none",children:[jsx("circle",{className:"opacity-25",cx:"12",cy:"12",r:"10",stroke:"currentColor",strokeWidth:"4"}),jsx("path",{className:"opacity-75",fill:"currentColor",d:"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"})]}),jsx("span",{className:"sr-only",children:"\uB85C\uB529 \uC911"})]}),!e&&n&&a$2==="left"&&jsx("span",{className:"mr-2",children:n}),k,!e&&n&&a$2==="right"&&jsx("span",{className:"ml-2",children:n})]});if(H&&!("aria-label"in i)&&process.env.NODE_ENV!=="production"&&console.warn("[Button] iconOnly \uC0AC\uC6A9 \uC2DC aria-label\uC744 \uC81C\uACF5\uD558\uC138\uC694."),_){let l={className:h,ref:b,disabled:d||e,"aria-busy":e||void 0,"aria-disabled":d||e||void 0,...i};return jsx(R,{...l,children:k})}if("href"in i&&i.href){let{onClick:l,target:S,rel:u,href:G,"aria-label":te,className:j,...A}=i,y=!!d||e,W=w=>{if(y){w.preventDefault(),w.stopPropagation();return}l==null||l(w);};return jsx("a",{ref:b,href:G,className:a$1(h,j),onClick:W,"aria-busy":e||void 0,"aria-disabled":y||void 0,tabIndex:y?-1:A.tabIndex,target:S,rel:S==="_blank"?u!=null?u:"noopener noreferrer":u,...A,children:P})}let{className:I,...$}=i,E=!!d||e;return jsx("button",{ref:b,className:a$1(h,I),type:"button",disabled:E,"aria-busy":e||void 0,"aria-disabled":E||void 0,...$,children:P})});M.displayName="Button";var me=M;export{q as a,Q as b,R as c,me as d};//# sourceMappingURL=chunk-O24K56OS.mjs.map
3
+ //# sourceMappingURL=chunk-O24K56OS.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/Slot.tsx","../src/components/Button.variants.ts","../src/components/Button.tsx"],"names":["composeRefs","refs","node","ref","composeEventHandlers","parentHandler","childHandler","event","mergeClassName","slotClassName","childClassName","clsx","mergeStyle","slotStyle","childStyle","mergeProps","slotProps","childProps","mergedProps","propName","slotValue","childValue","isSlottable","child","React","Slot","children","forwardedRef","childArray","childRef","mergedRef","springTransition","buttonVariants","cva","gradientPresets","ButtonInner","variant","size","loading","icon","iconPosition","gradient","customGradient","rounded","shadow","hover","fullWidth","iconOnly","className","disabled","asChild","rest","reduced","useReducedMotion","gradientClass","base","merge","content","jsxs","Fragment","jsx","onClick","target","rel","href","_ariaLabel","anchorClassName","anchorProps","isDisabled","handleAnchorClick","e","buttonClassName","btnProps","Button"],"mappings":"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","file":"chunk-O24K56OS.mjs","sourcesContent":["\"use client\";\n\nimport React from \"react\";\nimport { clsx } from \"clsx\";\n\n/**\n * Slot 컴포넌트\n *\n * Radix UI의 asChild 패턴을 구현합니다.\n * 자식 요소의 props와 ref를 병합하여 하나의 요소로 렌더링합니다.\n *\n * @example\n * // Button에서 asChild 사용\n * <Button asChild>\n * <Link href=\"/home\">홈으로</Link>\n * </Button>\n *\n * @see https://www.radix-ui.com/primitives/docs/utilities/slot\n */\n\ntype SlotProps = React.HTMLAttributes<HTMLElement> & {\n children?: React.ReactNode;\n};\n\n/**\n * 여러 ref를 하나로 합칩니다\n */\nfunction composeRefs<T>(\n ...refs: (React.Ref<T> | undefined)[]\n): React.RefCallback<T> {\n return (node) => {\n refs.forEach((ref) => {\n if (typeof ref === \"function\") {\n ref(node);\n } else if (ref != null) {\n (ref as React.MutableRefObject<T | null>).current = node;\n }\n });\n };\n}\n\n/**\n * 이벤트 핸들러를 합성합니다\n * \n * 부모(slot) 핸들러를 먼저 실행하고, 그 다음 자식 핸들러를 실행합니다.\n * defaultPrevented가 true이면 자식 핸들러는 실행하지 않습니다.\n */\nfunction composeEventHandlers<E>(\n parentHandler?: (event: E) => void,\n childHandler?: (event: E) => void\n): (event: E) => void {\n return (event) => {\n parentHandler?.(event);\n if (!(event as unknown as { defaultPrevented: boolean }).defaultPrevented) {\n childHandler?.(event);\n }\n };\n}\n\n/**\n * className을 병합합니다\n */\nfunction mergeClassName(\n slotClassName?: string,\n childClassName?: string\n): string | undefined {\n if (!slotClassName && !childClassName) return undefined;\n return clsx(slotClassName, childClassName);\n}\n\n/**\n * style을 병합합니다\n */\nfunction mergeStyle(\n slotStyle?: React.CSSProperties,\n childStyle?: React.CSSProperties\n): React.CSSProperties | undefined {\n if (!slotStyle && !childStyle) return undefined;\n return { ...slotStyle, ...childStyle };\n}\n\n/**\n * props를 병합합니다 (이벤트 핸들러, className, style 등)\n */\nfunction mergeProps(\n slotProps: Record<string, unknown>,\n childProps: Record<string, unknown>\n): Record<string, unknown> {\n const mergedProps: Record<string, unknown> = { ...slotProps };\n\n for (const propName in childProps) {\n const slotValue = slotProps[propName];\n const childValue = childProps[propName];\n\n // 이벤트 핸들러 병합 (부모(slot) → 자식 순서)\n if (/^on[A-Z]/.test(propName)) {\n if (slotValue && childValue) {\n mergedProps[propName] = composeEventHandlers(\n slotValue as (event: unknown) => void,\n childValue as (event: unknown) => void\n );\n } else {\n mergedProps[propName] = childValue || slotValue;\n }\n }\n // className 병합\n else if (propName === \"className\") {\n mergedProps[propName] = mergeClassName(\n slotValue as string | undefined,\n childValue as string | undefined\n );\n }\n // style 병합\n else if (propName === \"style\") {\n mergedProps[propName] = mergeStyle(\n slotValue as React.CSSProperties | undefined,\n childValue as React.CSSProperties | undefined\n );\n }\n // 그 외: 자식 값 우선\n else {\n mergedProps[propName] = childValue !== undefined ? childValue : slotValue;\n }\n }\n\n return mergedProps;\n}\n\n/**\n * 유효한 단일 React 요소인지 확인\n */\nfunction isSlottable(child: React.ReactNode): child is React.ReactElement {\n return React.isValidElement(child);\n}\n\n/**\n * Slot 컴포넌트\n *\n * 자식 요소에 부모의 props를 주입합니다.\n * asChild 패턴을 구현할 때 사용합니다.\n */\nconst Slot = React.forwardRef<HTMLElement, SlotProps>(\n ({ children, ...slotProps }, forwardedRef) => {\n const childArray = React.Children.toArray(children);\n\n // 유효한 단일 자식이 있는지 확인\n if (childArray.length !== 1) {\n if (process.env.NODE_ENV !== \"production\") {\n console.warn(\n \"[Slot] asChild는 정확히 하나의 자식 요소가 필요합니다.\"\n );\n }\n return null;\n }\n\n const child = childArray[0];\n\n if (!isSlottable(child)) {\n if (process.env.NODE_ENV !== \"production\") {\n console.warn(\"[Slot] 자식은 유효한 React 요소여야 합니다.\");\n }\n return null;\n }\n\n // 자식 요소의 props와 ref 추출\n const childProps = child.props as Record<string, unknown>;\n const childRef = (child as unknown as { ref?: React.Ref<HTMLElement> }).ref;\n\n // props와 ref 병합\n const mergedProps = mergeProps(slotProps, childProps);\n const mergedRef = composeRefs(forwardedRef, childRef);\n\n return React.cloneElement(child, {\n ...mergedProps,\n ref: mergedRef,\n } as React.Attributes);\n }\n);\n\nSlot.displayName = \"Slot\";\n\nexport { Slot, composeRefs, mergeProps };\nexport type { SlotProps };\n","import { cva } from 'class-variance-authority'\n\n/**\n * HUA Spring Easing transition — 시그니처 \"쫀득한\" 느낌\n * cubic-bezier(0.34, 1.56, 0.64, 1)\n */\nconst springTransition =\n '[transition:transform_180ms_cubic-bezier(0.34,1.56,0.64,1),box-shadow_200ms_ease-out]'\n\nexport const buttonVariants = cva(\n // ── base ──\n 'inline-flex items-center justify-center whitespace-nowrap font-medium transition-all duration-200 disabled:pointer-events-none disabled:opacity-50 min-w-fit focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-[var(--color-ring)] focus-visible:ring-offset-2 focus-visible:ring-offset-[var(--color-background)]',\n {\n variants: {\n /** 스타일 변형 */\n variant: {\n default:\n 'bg-[var(--color-primary)] text-[var(--color-primary-foreground)] hover:opacity-90',\n destructive:\n 'bg-[var(--color-destructive)] text-[var(--color-destructive-foreground)] hover:opacity-90 focus-visible:ring-[var(--color-destructive)]',\n outline:\n 'border-2 border-[var(--color-border)] bg-transparent text-[var(--color-foreground)] hover:bg-[var(--color-accent)] hover:text-[var(--color-accent-foreground)] focus-visible:ring-offset-0',\n secondary:\n 'bg-[var(--color-secondary)] text-[var(--color-secondary-foreground)] hover:opacity-80',\n ghost:\n 'bg-transparent text-[var(--color-foreground)] hover:bg-[var(--color-accent)] hover:text-[var(--color-accent-foreground)] focus-visible:ring-offset-0',\n link:\n 'bg-transparent text-[var(--color-primary)] underline hover:opacity-80 focus-visible:ring-offset-0',\n gradient:\n 'bg-gradient-to-r from-[var(--btn-gradient-from,theme(colors.teal.500))] to-[var(--btn-gradient-to,theme(colors.cyan.500))] text-white hover:shadow-lg',\n neon:\n 'bg-slate-900 dark:bg-slate-950 text-teal-400 border border-teal-500/50 shadow-lg shadow-[var(--btn-neon-glow,theme(colors.teal.500/20%))] hover:shadow-[var(--btn-neon-glow,theme(colors.teal.500/40%))] hover:border-teal-400',\n glass:\n 'bg-white/50 dark:bg-slate-900/50 backdrop-blur-md border border-slate-200/50 dark:border-slate-700/50 text-slate-900 dark:text-slate-100 hover:bg-white/70 dark:hover:bg-slate-900/70',\n },\n /** 크기 */\n size: {\n sm: 'h-8 px-4 py-2 text-sm',\n md: 'h-10 px-6 py-2 text-base',\n lg: 'h-12 px-8 py-3 text-lg',\n xl: 'h-14 px-10 py-4 text-xl',\n icon: 'h-10 w-10 p-0',\n },\n /** 모서리 둥글기 */\n rounded: {\n sm: 'rounded',\n md: 'rounded-md',\n lg: 'rounded-lg',\n full: 'rounded-full',\n },\n /** 그림자 */\n shadow: {\n none: '',\n sm: 'shadow-sm',\n md: 'shadow-md',\n lg: 'shadow-lg',\n xl: 'shadow-xl',\n },\n /** 호버 효과 — springy가 HUA-UI 시그니처 */\n hover: {\n springy: `hover:scale-[1.015] hover:shadow-md active:scale-[0.985] ${springTransition} transform-gpu`,\n scale:\n 'hover:scale-[1.015] active:scale-[0.985] transition-transform duration-150 ease-out transform-gpu',\n glow: 'hover:shadow-lg hover:shadow-primary/25 transition-shadow duration-200',\n slide: `hover:-translate-y-0.5 hover:shadow-md ${springTransition} transform-gpu`,\n none: '',\n },\n /** 전체 너비 */\n fullWidth: {\n true: 'w-full',\n false: '',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'md',\n rounded: 'md',\n shadow: 'md',\n hover: 'springy',\n fullWidth: false,\n },\n }\n)\n\n/** Gradient 프리셋 */\nexport const gradientPresets: Record<string, string> = {\n blue: 'from-teal-500 to-cyan-500',\n purple: 'from-purple-500 to-pink-500',\n green: 'from-green-500 to-emerald-500 dark:from-green-400 dark:to-emerald-400',\n orange: 'from-orange-500 to-red-500 dark:from-orange-300 dark:to-red-300',\n pink: 'from-pink-500 to-rose-500',\n}\n\nexport type { VariantProps } from 'class-variance-authority'\n","\"use client\";\n\nimport React from \"react\";\nimport { merge } from \"../lib/utils\";\nimport { buttonVariants, gradientPresets } from \"./Button.variants\";\nimport { Slot } from \"../lib/Slot\";\nimport { useReducedMotion } from \"../hooks/useReducedMotion\";\n\n/**\n * 버튼 스타일 변형 / Button style variant\n */\ntype Variant =\n | \"default\" | \"destructive\" | \"outline\" | \"secondary\"\n | \"ghost\" | \"link\" | \"gradient\" | \"neon\" | \"glass\";\n\n/**\n * 버튼 크기 / Button size\n */\ntype Size = \"sm\" | \"md\" | \"lg\" | \"xl\" | \"icon\";\n\n/**\n * 버튼 모서리 둥글기 / Button border radius\n */\ntype Rounded = \"sm\" | \"md\" | \"lg\" | \"full\";\n\n/**\n * 버튼 그림자 / Button shadow\n */\ntype Shadow = \"none\" | \"sm\" | \"md\" | \"lg\" | \"xl\";\n\n/**\n * 버튼 호버 효과 / Button hover effect\n * \"springy\"가 HUA-UI 시그니처 - 공 튕기듯 미세한 반동\n */\ntype Hover = \"springy\" | \"scale\" | \"glow\" | \"slide\" | \"none\";\n\n/**\n * 그라디언트 색상 이름 / Gradient color name\n */\ntype GradientName = \"blue\" | \"purple\" | \"green\" | \"orange\" | \"pink\" | \"custom\";\n\n/**\n * Button 컴포넌트의 공통 props / Common props for Button component\n */\ntype CommonProps = {\n variant?: Variant;\n size?: Size;\n loading?: boolean;\n icon?: React.ReactNode;\n iconPosition?: \"left\" | \"right\";\n gradient?: GradientName;\n customGradient?: string;\n rounded?: Rounded;\n shadow?: Shadow;\n hover?: Hover;\n fullWidth?: boolean;\n iconOnly?: boolean;\n \"aria-label\"?: string;\n className?: string;\n disabled?: boolean;\n asChild?: boolean;\n};\n\ntype AnchorProps = CommonProps &\n Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, \"className\"> & {\n href: string;\n };\n\ntype NativeButtonProps = CommonProps &\n Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, \"className\" | \"type\"> & {\n href?: undefined;\n };\n\n/**\n * Button 컴포넌트의 props 타입 / Button component props type\n * href가 제공되면 앵커 태그로, 그렇지 않으면 버튼 태그로 렌더링됩니다.\n */\nexport type ButtonProps = AnchorProps | NativeButtonProps;\n\ntype AnchorOrButton = HTMLAnchorElement | HTMLButtonElement;\n\n/**\n * Button 컴포넌트 / Button component\n *\n * 다양한 스타일과 크기를 지원하는 범용 버튼 컴포넌트입니다.\n * href prop을 제공하면 앵커 태그로, 그렇지 않으면 버튼 태그로 렌더링됩니다.\n *\n * @example\n * <Button onClick={() => console.log('클릭')}>클릭하세요</Button>\n * <Button variant=\"destructive\" size=\"lg\">삭제</Button>\n * <Button variant=\"gradient\" gradient=\"purple\">그라디언트</Button>\n * <Button href=\"/about\" variant=\"link\">자세히 보기</Button>\n */\nconst ButtonInner = React.forwardRef<AnchorOrButton, ButtonProps>(function ButtonInner(\n {\n variant = \"default\",\n size = \"md\",\n loading = false,\n icon,\n iconPosition = \"left\",\n gradient = \"blue\",\n customGradient,\n rounded = \"md\",\n shadow = \"md\",\n hover = \"springy\",\n fullWidth,\n iconOnly,\n className,\n children,\n disabled,\n asChild = false,\n ...rest\n },\n ref\n) {\n const reduced = useReducedMotion();\n\n // gradient variant: 커스텀 그라디언트 클래스 처리\n const gradientClass =\n variant === \"gradient\"\n ? customGradient\n ? `bg-gradient-to-r ${customGradient}`\n : `bg-gradient-to-r ${gradientPresets[gradient] || gradientPresets.blue}`\n : undefined;\n\n const base = merge(\n buttonVariants({\n variant,\n size,\n rounded,\n shadow,\n hover: reduced ? \"none\" : hover,\n fullWidth: fullWidth ?? false,\n }),\n gradientClass,\n className\n );\n\n const Spinner = (\n <span role=\"status\" aria-live=\"polite\" className=\"-ml-1 mr-2 inline-flex\">\n <svg className=\"animate-spin h-4 w-4\" viewBox=\"0 0 24 24\" fill=\"none\">\n <circle className=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" strokeWidth=\"4\" />\n <path className=\"opacity-75\" fill=\"currentColor\" d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\" />\n </svg>\n <span className=\"sr-only\">로딩 중</span>\n </span>\n );\n\n const content = (\n <>\n {loading && Spinner}\n {!loading && icon && iconPosition === \"left\" && <span className=\"mr-2\">{icon}</span>}\n {children}\n {!loading && icon && iconPosition === \"right\" && <span className=\"ml-2\">{icon}</span>}\n </>\n );\n\n if (iconOnly && !(\"aria-label\" in rest) && process.env.NODE_ENV !== \"production\") {\n console.warn(\"[Button] iconOnly 사용 시 aria-label을 제공하세요.\");\n }\n\n // asChild 모드: Slot을 사용하여 자식 요소에 props 병합\n if (asChild) {\n const slotProps = {\n className: base,\n ref,\n disabled: disabled || loading,\n \"aria-busy\": loading || undefined,\n \"aria-disabled\": (disabled || loading) || undefined,\n ...rest,\n };\n return <Slot {...slotProps}>{children}</Slot>;\n }\n\n // 앵커 모드\n if (\"href\" in rest && rest.href) {\n const { onClick, target, rel, href, \"aria-label\": _ariaLabel, className: anchorClassName, ...anchorProps } = rest as AnchorProps;\n const isDisabled = !!disabled || loading;\n\n const handleAnchorClick: React.MouseEventHandler<HTMLAnchorElement> = (e) => {\n if (isDisabled) { e.preventDefault(); e.stopPropagation(); return; }\n onClick?.(e);\n };\n\n return (\n <a\n ref={ref as React.Ref<HTMLAnchorElement>}\n href={href}\n className={merge(base, anchorClassName)}\n onClick={handleAnchorClick}\n aria-busy={loading || undefined}\n aria-disabled={isDisabled || undefined}\n tabIndex={isDisabled ? -1 : anchorProps.tabIndex}\n target={target}\n rel={target === \"_blank\" ? rel ?? \"noopener noreferrer\" : rel}\n {...anchorProps}\n >\n {content}\n </a>\n );\n }\n\n // 버튼 모드\n const { className: buttonClassName, ...btnProps } = rest as NativeButtonProps;\n const isDisabled = !!disabled || loading;\n return (\n <button\n ref={ref as React.Ref<HTMLButtonElement>}\n className={merge(base, buttonClassName)}\n type=\"button\"\n disabled={isDisabled}\n aria-busy={loading || undefined}\n aria-disabled={isDisabled || undefined}\n {...btnProps}\n >\n {content}\n </button>\n );\n});\n\nButtonInner.displayName = \"Button\";\n\nexport const Button = ButtonInner;\n"]}
@@ -0,0 +1,3 @@
1
+ "use client";
2
+ import {l}from'./chunk-ZQUMJQYV.mjs';import {a}from'./chunk-QEMPERUK.mjs';import i from'react';import {offset,flip,shift,arrow,useFloating,autoUpdate,useClick,useDismiss,useRole,useInteractions,FloatingPortal,FloatingArrow}from'@floating-ui/react';import {jsxs,jsx}from'react/jsx-runtime';function Q(t,e){return e==="center"?t:`${t}-${e}`}var C=8,X=i.forwardRef(({className:t,trigger:e,children:o,open:a$1,onOpenChange:r,placement:f="bottom",align:p="start",offset:D=8,disabled:h=false,showArrow:b=false,...P},R)=>{let[x,n]=i.useState(false),w=i.useRef(null),v=a$1!==void 0,g=v?a$1:x,L=i.useCallback(H=>{h&&H||(v||n(H),r==null||r(H));},[h,v,r]),u=Q(f,p),N=[offset(D),flip(),shift({padding:8})];b&&N.push(arrow({element:w,padding:8}));let{refs:y,floatingStyles:M,context:l}=useFloating({open:g,onOpenChange:L,placement:u,middleware:N,whileElementsMounted:autoUpdate}),E=useClick(l),S=useDismiss(l),A=useRole(l,{role:"menu"}),{getReferenceProps:I,getFloatingProps:B}=useInteractions([E,S,A]);return jsxs("div",{ref:R,className:a("relative inline-block",t),...P,children:[jsx("div",{ref:y.setReference,className:"inline-block cursor-pointer",...I(),children:e}),g&&jsx(FloatingPortal,{children:jsxs("div",{ref:y.setFloating,style:M,className:a("z-50 bg-[var(--dropdown-bg,_#fff)] dark:bg-[var(--dropdown-bg,_rgb(31,41,55))] rounded-lg shadow-lg border border-border","min-w-[var(--reference-width)] w-max py-1"),...B(),children:[b&&jsx(FloatingArrow,{ref:w,context:l,width:C*2,height:C,className:"fill-[var(--dropdown-bg,_#fff)] dark:fill-[var(--dropdown-bg,_rgb(31,41,55))] [&>path:first-of-type]:stroke-border"}),o]})})]})});X.displayName="Dropdown";var Y=i.forwardRef(({className:t,icon:e,variant:o="default",children:a$1,disabled:r,...f},p)=>jsxs("button",{ref:p,className:a("w-full flex items-center gap-2 px-3 py-2 text-sm font-medium transition-colors duration-200 ease-in-out focus-visible:outline-none focus-visible:bg-muted",(()=>{switch(o){case "destructive":return "text-destructive hover:bg-destructive/10";case "disabled":return "text-muted-foreground cursor-not-allowed";default:return "text-foreground hover:bg-muted"}})(),t),disabled:r||o==="disabled",...f,children:[e&&jsx("div",{className:"flex-shrink-0 w-4 h-4",children:e}),jsx("span",{className:"flex-1 text-left",children:a$1})]}));Y.displayName="DropdownItem";var O=i.forwardRef(({className:t,...e},o)=>jsx("div",{ref:o,className:a("h-px bg-border my-2",t),...e}));O.displayName="DropdownSeparator";var ee=i.forwardRef(({className:t,children:e,...o},a$1)=>jsx("div",{ref:a$1,className:a("px-4 py-2 text-xs font-semibold text-muted-foreground uppercase tracking-wide",t),...o,children:e}));ee.displayName="DropdownLabel";var te=i.forwardRef(({className:t,children:e,...o},a$1)=>jsx("div",{ref:a$1,className:a("py-1",t),...o,children:e}));te.displayName="DropdownMenu";var re=i.forwardRef(({className:t,children:e,...o},a$1)=>jsx("div",{ref:a$1,className:a("space-y-1",t),...o,children:e}));re.displayName="DropdownGroup";var oe=i.forwardRef(({isOpen:t,onClose:e,children:o,className:a$1,side:r="right",size:f="md",showBackdrop:p=true,backdropClassName:D,closeOnBackdropClick:h=true,closeOnEscape:b=true,closable:P=true,...R},x)=>{let n=t!=null?t:false,w=()=>{e==null||e();},[v,g]=i.useState(false),[L,u]=i.useState(false);if(i.useEffect(()=>{if(n){g(true),u(true);let l=setTimeout(()=>u(false),50);return ()=>clearTimeout(l)}else {u(true);let l=setTimeout(()=>{g(false),u(false);},300);return ()=>clearTimeout(l)}},[n]),i.useEffect(()=>{if(!b)return;let l=E=>{E.key==="Escape"&&n&&w();};return n&&(document.addEventListener("keydown",l),document.body.style.overflow="hidden"),()=>{document.removeEventListener("keydown",l),document.body.style.overflow="";}},[n,b]),!v)return null;let N={sm:r==="left"||r==="right"?"w-80":"h-64",md:r==="left"||r==="right"?"w-96":"h-96",lg:r==="left"||r==="right"?"w-[28rem]":"h-[32rem]",xl:r==="left"||r==="right"?"w-[32rem]":"h-[40rem]",full:r==="left"||r==="right"?"w-full":"h-full"},y={left:"left-0 top-0 h-full",right:"right-0 top-0 h-full",top:"top-0 left-0 w-full",bottom:"bottom-0 left-0 w-full"},M={left:n?"translate-x-0":"-translate-x-full",right:n?"translate-x-0":"translate-x-full",top:n?"translate-y-0":"-translate-y-full",bottom:n?"translate-y-0":"translate-y-full"};return jsxs("div",{className:"fixed inset-0 z-50",children:[p&&jsx("div",{className:a("absolute inset-0 bg-black/85 backdrop-blur-md transition-opacity duration-300",L?n?"opacity-100":"opacity-0":"",D),onClick:h?w:void 0}),jsx("div",{ref:x,className:a("absolute bg-background/95 backdrop-blur-xl border border-border/50 shadow-2xl transition-transform duration-300 ease-out",N[f],y[r],M[r],a$1),...R,children:o})]})});oe.displayName="Drawer";var ae=i.forwardRef(({children:t,className:e,showCloseButton:o=true,onClose:a$1,...r},f)=>jsxs("div",{ref:f,className:a("flex items-center justify-between p-6 border-b border-border/50",e),...r,children:[jsx("div",{className:"flex-1",children:t}),o&&jsx("button",{onClick:a$1,className:"p-2 rounded-lg hover:bg-muted transition-colors",children:jsx(l,{name:"close",size:20})})]}));ae.displayName="DrawerHeader";var se=i.forwardRef(({children:t,className:e,...o},a$1)=>jsx("div",{ref:a$1,className:a("flex-1 p-6 overflow-y-auto",e),...o,children:t}));se.displayName="DrawerContent";var ne=i.forwardRef(({children:t,className:e,...o},a$1)=>jsx("div",{ref:a$1,className:a("flex items-center justify-end gap-3 p-6 border-t border-border/50",e),...o,children:t}));ne.displayName="DrawerFooter";export{X as a,Y as b,O as c,ee as d,te as e,re as f,oe as g,ae as h,se as i,ne as j};//# sourceMappingURL=chunk-OIWG3IJ7.mjs.map
3
+ //# sourceMappingURL=chunk-OIWG3IJ7.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/Dropdown.tsx","../src/components/Drawer.tsx"],"names":["resolveFloatingPlacement","placement","align","ARROW_SIZE","Dropdown","React","className","trigger","children","controlledOpen","onOpenChange","offset","disabled","showArrow","props","ref","internalOpen","setInternalOpen","arrowRef","isControlled","isOpen","handleOpenChange","newOpen","floatingPlacement","middleware","offsetMiddleware","flip","shift","arrowMiddleware","refs","floatingStyles","context","useFloating","autoUpdate","click","useClick","dismiss","useDismiss","role","useRole","getReferenceProps","getFloatingProps","useInteractions","jsxs","merge","jsx","FloatingPortal","FloatingArrow","DropdownItem","icon","variant","DropdownSeparator","DropdownLabel","DropdownMenu","DropdownGroup","Drawer","onClose","side","size","showBackdrop","backdropClassName","closeOnBackdropClick","closeOnEscape","closable","_isOpen","handleClose","isVisible","setIsVisible","isAnimating","setIsAnimating","timer","handleEscapeKey","e","sizeClasses","sideClasses","transformClasses","DrawerHeader","showCloseButton","Icon","DrawerContent","DrawerFooter"],"mappings":"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","file":"chunk-OIWG3IJ7.mjs","sourcesContent":["\"use client\"\n\nimport React from \"react\"\nimport {\n useFloating,\n autoUpdate,\n offset as offsetMiddleware,\n flip,\n shift,\n arrow as arrowMiddleware,\n useClick,\n useDismiss,\n useRole,\n useInteractions,\n FloatingPortal,\n FloatingArrow,\n type Placement,\n} from \"@floating-ui/react\"\nimport { merge } from \"../lib/utils\"\n\nexport interface DropdownProps extends React.HTMLAttributes<HTMLDivElement> {\n trigger: React.ReactNode\n children: React.ReactNode\n open?: boolean\n onOpenChange?: (open: boolean) => void\n placement?: \"top\" | \"bottom\" | \"left\" | \"right\"\n align?: \"start\" | \"center\" | \"end\"\n offset?: number\n disabled?: boolean\n showArrow?: boolean\n}\n\nfunction resolveFloatingPlacement(\n placement: \"top\" | \"bottom\" | \"left\" | \"right\",\n align: \"start\" | \"center\" | \"end\"\n): Placement {\n if (align === \"center\") return placement\n return `${placement}-${align}`\n}\n\nconst ARROW_SIZE = 8\n\nconst Dropdown = React.forwardRef<HTMLDivElement, DropdownProps>(\n ({\n className,\n trigger,\n children,\n open: controlledOpen,\n onOpenChange,\n placement = \"bottom\",\n align = \"start\",\n offset = 8,\n disabled = false,\n showArrow = false,\n ...props\n }, ref) => {\n const [internalOpen, setInternalOpen] = React.useState(false)\n const arrowRef = React.useRef<SVGSVGElement>(null)\n\n const isControlled = controlledOpen !== undefined\n const isOpen = isControlled ? controlledOpen : internalOpen\n\n const handleOpenChange = React.useCallback((newOpen: boolean) => {\n if (disabled && newOpen) return\n if (!isControlled) {\n setInternalOpen(newOpen)\n }\n onOpenChange?.(newOpen)\n }, [disabled, isControlled, onOpenChange])\n\n const floatingPlacement = resolveFloatingPlacement(placement, align)\n\n const middleware = [\n offsetMiddleware(offset),\n flip(),\n shift({ padding: 8 }),\n ]\n if (showArrow) {\n middleware.push(arrowMiddleware({ element: arrowRef, padding: 8 }))\n }\n\n const { refs, floatingStyles, context } = useFloating({\n open: isOpen,\n onOpenChange: handleOpenChange,\n placement: floatingPlacement,\n middleware,\n whileElementsMounted: autoUpdate,\n })\n\n const click = useClick(context)\n const dismiss = useDismiss(context)\n const role = useRole(context, { role: \"menu\" })\n\n const { getReferenceProps, getFloatingProps } = useInteractions([\n click,\n dismiss,\n role,\n ])\n\n return (\n <div ref={ref} className={merge(\"relative inline-block\", className)} {...props}>\n {/* Trigger */}\n <div\n ref={refs.setReference}\n className=\"inline-block cursor-pointer\"\n {...getReferenceProps()}\n >\n {trigger}\n </div>\n\n {/* Dropdown via Portal */}\n {isOpen && (\n <FloatingPortal>\n <div\n ref={refs.setFloating}\n style={floatingStyles}\n className={merge(\n \"z-50 bg-[var(--dropdown-bg,_#fff)] dark:bg-[var(--dropdown-bg,_rgb(31,41,55))] rounded-lg shadow-lg border border-border\",\n \"min-w-[var(--reference-width)] w-max py-1\"\n )}\n {...getFloatingProps()}\n >\n {showArrow && (\n <FloatingArrow\n ref={arrowRef}\n context={context}\n width={ARROW_SIZE * 2}\n height={ARROW_SIZE}\n className=\"fill-[var(--dropdown-bg,_#fff)] dark:fill-[var(--dropdown-bg,_rgb(31,41,55))] [&>path:first-of-type]:stroke-border\"\n />\n )}\n {children}\n </div>\n </FloatingPortal>\n )}\n </div>\n )\n }\n)\nDropdown.displayName = \"Dropdown\"\n\n// Sub-components (unchanged)\nexport interface DropdownItemProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n icon?: React.ReactNode\n variant?: \"default\" | \"destructive\" | \"disabled\"\n}\n\nconst DropdownItem = React.forwardRef<HTMLButtonElement, DropdownItemProps>(\n ({\n className,\n icon,\n variant = \"default\",\n children,\n disabled,\n ...props\n }, ref) => {\n const getVariantClasses = () => {\n switch (variant) {\n case \"destructive\":\n return \"text-destructive hover:bg-destructive/10\"\n case \"disabled\":\n return \"text-muted-foreground cursor-not-allowed\"\n default:\n return \"text-foreground hover:bg-muted\"\n }\n }\n\n return (\n <button\n ref={ref}\n className={merge(\n \"w-full flex items-center gap-2 px-3 py-2 text-sm font-medium transition-colors duration-200 ease-in-out focus-visible:outline-none focus-visible:bg-muted\",\n getVariantClasses(),\n className\n )}\n disabled={disabled || variant === \"disabled\"}\n {...props}\n >\n {icon && (\n <div className=\"flex-shrink-0 w-4 h-4\">\n {icon}\n </div>\n )}\n <span className=\"flex-1 text-left\">{children}</span>\n </button>\n )\n }\n)\nDropdownItem.displayName = \"DropdownItem\"\n\nexport interface DropdownSeparatorProps extends React.HTMLAttributes<HTMLDivElement> {}\n\nconst DropdownSeparator = React.forwardRef<HTMLDivElement, DropdownSeparatorProps>(\n ({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={merge(\"h-px bg-border my-2\", className)}\n {...props}\n />\n )\n)\nDropdownSeparator.displayName = \"DropdownSeparator\"\n\nexport interface DropdownLabelProps extends React.HTMLAttributes<HTMLDivElement> {}\n\nconst DropdownLabel = React.forwardRef<HTMLDivElement, DropdownLabelProps>(\n ({ className, children, ...props }, ref) => (\n <div\n ref={ref}\n className={merge(\"px-4 py-2 text-xs font-semibold text-muted-foreground uppercase tracking-wide\", className)}\n {...props}\n >\n {children}\n </div>\n )\n)\nDropdownLabel.displayName = \"DropdownLabel\"\n\nconst DropdownMenu = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(\n ({ className, children, ...props }, ref) => (\n <div\n ref={ref}\n className={merge(\"py-1\", className)}\n {...props}\n >\n {children}\n </div>\n )\n)\nDropdownMenu.displayName = \"DropdownMenu\"\n\nconst DropdownGroup = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(\n ({ className, children, ...props }, ref) => (\n <div\n ref={ref}\n className={merge(\"space-y-1\", className)}\n {...props}\n >\n {children}\n </div>\n )\n)\nDropdownGroup.displayName = \"DropdownGroup\"\n\nexport { Dropdown, DropdownItem, DropdownSeparator, DropdownLabel, DropdownMenu, DropdownGroup }\n","\"use client\"\n\nimport React from \"react\"\nimport { merge } from \"../lib/utils\"\nimport { Icon } from \"./Icon\"\n\n/**\n * Drawer 컴포넌트의 props / Drawer component props\n * @typedef {Object} DrawerProps\n * @property {boolean} open - Drawer 열림/닫힘 상태 / Drawer open/close state\n * @property {(open: boolean) => void} onOpenChange - 상태 변경 콜백 / State change callback\n * @property {React.ReactNode} children - Drawer 내용 / Drawer content\n * @property {string} [className] - 추가 CSS 클래스 / Additional CSS class\n * @property {\"left\" | \"right\" | \"top\" | \"bottom\"} [side=\"right\"] - Drawer 표시 위치 / Drawer display position\n * @property {\"sm\" | \"md\" | \"lg\" | \"xl\" | \"full\"} [size=\"md\"] - Drawer 크기 / Drawer size\n * @property {boolean} [showBackdrop=true] - 배경 오버레이 표시 여부 / Show backdrop overlay\n * @property {string} [backdropClassName] - 배경 오버레이 추가 CSS 클래스 / Backdrop overlay additional CSS class\n * @property {boolean} [closeOnBackdropClick=true] - 배경 클릭 시 닫기 여부 / Close on backdrop click\n * @property {boolean} [closeOnEscape=true] - ESC 키로 닫기 여부 / Close on ESC key\n */\ninterface DrawerProps {\n /** Drawer 열림/닫힘 상태 / Drawer open/close state */\n isOpen?: boolean\n /** Drawer 닫기 콜백 / Drawer close callback */\n onClose?: () => void\n /** Drawer 내용 / Drawer content */\n children: React.ReactNode\n /** 추가 CSS 클래스 / Additional CSS class */\n className?: string\n /** Drawer 표시 위치 / Drawer display position */\n side?: \"left\" | \"right\" | \"top\" | \"bottom\"\n /** Drawer 크기 / Drawer size */\n size?: \"sm\" | \"md\" | \"lg\" | \"xl\" | \"full\"\n /** 배경 오버레이 표시 여부 / Show backdrop overlay */\n showBackdrop?: boolean\n /** 배경 오버레이 추가 CSS 클래스 / Backdrop overlay additional CSS class */\n backdropClassName?: string\n /** 배경 클릭 시 닫기 여부 / Close on backdrop click */\n closeOnBackdropClick?: boolean\n /** ESC 키로 닫기 여부 / Close on ESC key */\n closeOnEscape?: boolean\n /** 닫기 버튼 표시 여부 / Show close button */\n closable?: boolean\n}\n\n/**\n * Drawer 컴포넌트 / Drawer component\n * \n * 사이드에서 슬라이드되는 패널 컴포넌트입니다.\n * Modal과 유사하지만 특정 방향에서 슬라이드되는 애니메이션을 제공합니다.\n * ESC 키로 닫기, 배경 클릭으로 닫기 기능을 지원합니다.\n * \n * Panel component that slides from the side.\n * Similar to Modal but provides slide animation from a specific direction.\n * Supports closing with ESC key and backdrop click.\n * \n * @component\n * @example\n * // 기본 사용 / Basic usage\n * const [open, setOpen] = useState(false)\n * \n * <Drawer open={open} onOpenChange={setOpen}>\n * <DrawerHeader>제목</DrawerHeader>\n * <DrawerContent>내용</DrawerContent>\n * <DrawerFooter>\n * <Button onClick={() => setOpen(false)}>닫기</Button>\n * </DrawerFooter>\n * </Drawer>\n * \n * @example\n * // 왼쪽에서 열기 / Open from left\n * <Drawer open={open} onOpenChange={setOpen} side=\"left\" size=\"lg\">\n * <DrawerContent>사이드바 내용</DrawerContent>\n * </Drawer>\n * \n * @param {DrawerProps} props - Drawer 컴포넌트의 props / Drawer component props\n * @param {React.Ref<HTMLDivElement>} ref - Drawer 컨테이너 ref / Drawer container ref\n * @returns {JSX.Element} Drawer 컴포넌트 / Drawer component\n * \n * @todo 접근성 개선: role=\"dialog\", aria-modal=\"true\" 추가 필요 / Accessibility: Add role=\"dialog\", aria-modal=\"true\"\n * @todo 접근성 개선: aria-labelledby, aria-describedby 연결 필요 / Accessibility: Connect aria-labelledby, aria-describedby\n */\nconst Drawer = React.forwardRef<HTMLDivElement, DrawerProps>(\n ({\n isOpen,\n onClose,\n children,\n className,\n side = \"right\",\n size = \"md\",\n showBackdrop = true,\n backdropClassName,\n closeOnBackdropClick = true,\n closeOnEscape = true,\n closable = true,\n ...props\n }, ref) => {\n const _isOpen = isOpen ?? false\n const handleClose = () => {\n onClose?.()\n }\n\n const [isVisible, setIsVisible] = React.useState(false)\n const [isAnimating, setIsAnimating] = React.useState(false)\n\n React.useEffect(() => {\n if (_isOpen) {\n setIsVisible(true)\n setIsAnimating(true)\n // 애니메이션 시작을 위한 지연\n const timer = setTimeout(() => setIsAnimating(false), 50)\n return () => clearTimeout(timer)\n } else {\n setIsAnimating(true)\n const timer = setTimeout(() => {\n setIsVisible(false)\n setIsAnimating(false)\n }, 300) // 애니메이션 완료 후 숨김\n return () => clearTimeout(timer)\n }\n }, [_isOpen])\n\n React.useEffect(() => {\n if (!closeOnEscape) return\n\n const handleEscapeKey = (e: KeyboardEvent) => {\n if (e.key === \"Escape\" && _isOpen) {\n handleClose()\n }\n }\n\n if (_isOpen) {\n document.addEventListener(\"keydown\", handleEscapeKey)\n document.body.style.overflow = \"hidden\"\n }\n\n return () => {\n document.removeEventListener(\"keydown\", handleEscapeKey)\n document.body.style.overflow = \"\"\n }\n }, [_isOpen, closeOnEscape])\n\n if (!isVisible) return null\n\n const sizeClasses = {\n sm: side === \"left\" || side === \"right\" ? \"w-80\" : \"h-64\",\n md: side === \"left\" || side === \"right\" ? \"w-96\" : \"h-96\",\n lg: side === \"left\" || side === \"right\" ? \"w-[28rem]\" : \"h-[32rem]\",\n xl: side === \"left\" || side === \"right\" ? \"w-[32rem]\" : \"h-[40rem]\",\n full: side === \"left\" || side === \"right\" ? \"w-full\" : \"h-full\"\n }\n\n const sideClasses = {\n left: \"left-0 top-0 h-full\",\n right: \"right-0 top-0 h-full\",\n top: \"top-0 left-0 w-full\",\n bottom: \"bottom-0 left-0 w-full\"\n }\n\n // Transform: _isOpen=true -> visible position, _isOpen=false -> hidden position\n const transformClasses = {\n left: _isOpen ? \"translate-x-0\" : \"-translate-x-full\",\n right: _isOpen ? \"translate-x-0\" : \"translate-x-full\",\n top: _isOpen ? \"translate-y-0\" : \"-translate-y-full\",\n bottom: _isOpen ? \"translate-y-0\" : \"translate-y-full\"\n }\n\n return (\n <div className=\"fixed inset-0 z-50\">\n {/* Backdrop */}\n {showBackdrop && (\n <div\n className={merge(\n \"absolute inset-0 bg-black/85 backdrop-blur-md transition-opacity duration-300\",\n isAnimating ? (_isOpen ? \"opacity-100\" : \"opacity-0\") : \"\",\n backdropClassName\n )}\n onClick={closeOnBackdropClick ? handleClose : undefined}\n />\n )}\n\n {/* Drawer Content */}\n <div\n ref={ref}\n className={merge(\n \"absolute bg-background/95 backdrop-blur-xl border border-border/50 shadow-2xl transition-transform duration-300 ease-out\",\n sizeClasses[size],\n sideClasses[side],\n transformClasses[side],\n className\n )}\n {...props}\n >\n {children}\n </div>\n </div>\n )\n }\n)\nDrawer.displayName = \"Drawer\"\n\n/**\n * DrawerHeader 컴포넌트의 props / DrawerHeader component props\n * @typedef {Object} DrawerHeaderProps\n * @property {React.ReactNode} children - 헤더 내용 / Header content\n * @property {string} [className] - 추가 CSS 클래스 / Additional CSS class\n * @property {boolean} [showCloseButton=true] - 닫기 버튼 표시 여부 / Show close button\n * @property {() => void} [onClose] - 닫기 버튼 클릭 콜백 / Close button click callback\n */\ninterface DrawerHeaderProps {\n children: React.ReactNode\n className?: string\n showCloseButton?: boolean\n onClose?: () => void\n}\n\n/**\n * DrawerHeader 컴포넌트 / DrawerHeader component\n * Drawer의 헤더 영역을 표시합니다.\n * Displays the header area of a Drawer.\n * \n * @component\n * @param {DrawerHeaderProps} props - DrawerHeader 컴포넌트의 props / DrawerHeader component props\n * @param {React.Ref<HTMLDivElement>} ref - div 요소 ref / div element ref\n * @returns {JSX.Element} DrawerHeader 컴포넌트 / DrawerHeader component\n */\nconst DrawerHeader = React.forwardRef<HTMLDivElement, DrawerHeaderProps>(\n ({ children, className, showCloseButton = true, onClose, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={merge(\"flex items-center justify-between p-6 border-b border-border/50\", className)}\n {...props}\n >\n <div className=\"flex-1\">{children}</div>\n {showCloseButton && (\n <button\n onClick={onClose}\n className=\"p-2 rounded-lg hover:bg-muted transition-colors\"\n >\n <Icon name=\"close\" size={20} />\n </button>\n )}\n </div>\n )\n }\n)\nDrawerHeader.displayName = \"DrawerHeader\"\n\n/**\n * DrawerContent 컴포넌트의 props / DrawerContent component props\n * @typedef {Object} DrawerContentProps\n * @property {React.ReactNode} children - 콘텐츠 / Content\n * @property {string} [className] - 추가 CSS 클래스 / Additional CSS class\n */\ninterface DrawerContentProps {\n children: React.ReactNode\n className?: string\n}\n\n/**\n * DrawerContent 컴포넌트 / DrawerContent component\n * Drawer의 메인 콘텐츠 영역을 표시합니다.\n * Displays the main content area of a Drawer.\n * \n * @component\n * @param {DrawerContentProps} props - DrawerContent 컴포넌트의 props / DrawerContent component props\n * @param {React.Ref<HTMLDivElement>} ref - div 요소 ref / div element ref\n * @returns {JSX.Element} DrawerContent 컴포넌트 / DrawerContent component\n */\nconst DrawerContent = React.forwardRef<HTMLDivElement, DrawerContentProps>(\n ({ children, className, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={merge(\"flex-1 p-6 overflow-y-auto\", className)}\n {...props}\n >\n {children}\n </div>\n )\n }\n)\nDrawerContent.displayName = \"DrawerContent\"\n\n/**\n * DrawerFooter 컴포넌트의 props / DrawerFooter component props\n * @typedef {Object} DrawerFooterProps\n * @property {React.ReactNode} children - 푸터 내용 / Footer content\n * @property {string} [className] - 추가 CSS 클래스 / Additional CSS class\n */\ninterface DrawerFooterProps {\n children: React.ReactNode\n className?: string\n}\n\n/**\n * DrawerFooter 컴포넌트 / DrawerFooter component\n * Drawer의 푸터 영역을 표시합니다. 주로 액션 버튼을 배치합니다.\n * Displays the footer area of a Drawer. Typically used for action buttons.\n * \n * @component\n * @param {DrawerFooterProps} props - DrawerFooter 컴포넌트의 props / DrawerFooter component props\n * @param {React.Ref<HTMLDivElement>} ref - div 요소 ref / div element ref\n * @returns {JSX.Element} DrawerFooter 컴포넌트 / DrawerFooter component\n */\nconst DrawerFooter = React.forwardRef<HTMLDivElement, DrawerFooterProps>(\n ({ children, className, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={merge(\"flex items-center justify-end gap-3 p-6 border-t border-border/50\", className)}\n {...props}\n >\n {children}\n </div>\n )\n }\n)\nDrawerFooter.displayName = \"DrawerFooter\"\n\nexport { Drawer, DrawerHeader, DrawerContent, DrawerFooter } "]}
@@ -1,3 +1,3 @@
1
1
  "use client";
2
- import {a}from'./chunk-UUHAXGMO.mjs';import w from'react';import {jsxs,jsx}from'react/jsx-runtime';var R=w.forwardRef(({value:r,defaultValue:B=0,min:n,max:a$1,step:k=1,onChange:p,disabled:s=false,size:E="md",showButtons:N=true,buttonLayout:H="horizontal",className:y,...c},x)=>{let[V,z]=w.useState(B),f=r!==void 0,i=f?r:V,l=w.useCallback(o=>{let t=o;n!==void 0&&(t=Math.max(n,t)),a$1!==void 0&&(t=Math.min(a$1,t)),f||z(t),p==null||p(t);},[f,n,a$1,p]),v=()=>{s||l(i+k);},m=()=>{s||l(i-k);},C=o=>{let t=o.target.value;if(t===""||t==="-")return;let g=parseFloat(t);isNaN(g)||(n!==void 0&&g<n?l(n):l(g));},I=o=>{var t;n!==void 0&&i<n&&l(n),a$1!==void 0&&i>a$1&&l(a$1),(t=c.onBlur)==null||t.call(c,o);},L=o=>{o.key==="ArrowUp"?(o.preventDefault(),v()):o.key==="ArrowDown"&&(o.preventDefault(),m());},d={sm:{input:"h-8 text-sm px-2 py-1",button:"w-8 h-8 text-sm",wrapper:"gap-1"},md:{input:"h-10 text-sm px-3 py-2",button:"w-10 h-10 text-sm",wrapper:"gap-2"},lg:{input:"h-12 text-base px-4 py-2.5",button:"w-12 h-12 text-base",wrapper:"gap-2"}}[E],b=a("flex items-center justify-center rounded-md border border-input bg-background","hover:bg-secondary hover:border-primary/50 active:scale-95","transition-all duration-150","disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:bg-background","focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-2",d.button),M=n===void 0||i>n,D=a$1===void 0||i<a$1;return H==="vertical"?jsxs("div",{className:a("inline-flex items-center",d.wrapper,y),children:[jsxs("div",{className:"flex flex-col gap-0.5",children:[jsx("button",{type:"button",onClick:v,disabled:s||!D,className:a(b,"rounded-b-none h-[calc(50%-1px)]"),"aria-label":"Increase",children:jsx(K,{className:"w-3 h-3"})}),jsx("button",{type:"button",onClick:m,disabled:s||!M,className:a(b,"rounded-t-none h-[calc(50%-1px)]"),"aria-label":"Decrease",children:jsx(W,{className:"w-3 h-3"})})]}),jsx("input",{ref:x,type:"text",inputMode:"numeric",pattern:n!==void 0&&n>=0?"[0-9]*":"-?[0-9]*",value:i,onChange:C,onKeyDown:L,onBlur:I,disabled:s,className:a("w-16 text-center rounded-md border border-input bg-background","focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-2","disabled:cursor-not-allowed disabled:opacity-50","[appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none",d.input),...c})]}):jsxs("div",{className:a("inline-flex items-center",d.wrapper,y),children:[N&&jsx("button",{type:"button",onClick:m,disabled:s||!M,className:b,"aria-label":"Decrease",children:jsx(T,{className:"w-3.5 h-3.5"})}),jsx("input",{ref:x,type:"text",inputMode:"numeric",pattern:n!==void 0&&n>=0?"[0-9]*":"-?[0-9]*",value:i,onChange:C,onKeyDown:L,onBlur:I,disabled:s,className:a("w-16 text-center rounded-md border border-input bg-background","focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-2","disabled:cursor-not-allowed disabled:opacity-50","[appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none",d.input),...c}),N&&jsx("button",{type:"button",onClick:v,disabled:s||!D,className:b,"aria-label":"Increase",children:jsx(j,{className:"w-3.5 h-3.5"})})]})});R.displayName="NumberInput";function T({className:r}){return jsx("svg",{className:r,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M20 12H4"})})}function j({className:r}){return jsx("svg",{className:r,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 4v16m8-8H4"})})}function K({className:r}){return jsx("svg",{className:r,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M5 15l7-7 7 7"})})}function W({className:r}){return jsx("svg",{className:r,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M19 9l-7 7-7-7"})})}export{R as a};//# sourceMappingURL=chunk-VWSBJUNI.mjs.map
3
- //# sourceMappingURL=chunk-VWSBJUNI.mjs.map
2
+ import {a}from'./chunk-QEMPERUK.mjs';import w from'react';import {jsxs,jsx}from'react/jsx-runtime';var R=w.forwardRef(({value:r,defaultValue:B=0,min:n,max:a$1,step:k=1,onChange:p,disabled:s=false,size:E="md",showButtons:N=true,buttonLayout:H="horizontal",className:y,...c},x)=>{let[V,z]=w.useState(B),f=r!==void 0,i=f?r:V,l=w.useCallback(o=>{let t=o;n!==void 0&&(t=Math.max(n,t)),a$1!==void 0&&(t=Math.min(a$1,t)),f||z(t),p==null||p(t);},[f,n,a$1,p]),v=()=>{s||l(i+k);},m=()=>{s||l(i-k);},C=o=>{let t=o.target.value;if(t===""||t==="-")return;let g=parseFloat(t);isNaN(g)||(n!==void 0&&g<n?l(n):l(g));},I=o=>{var t;n!==void 0&&i<n&&l(n),a$1!==void 0&&i>a$1&&l(a$1),(t=c.onBlur)==null||t.call(c,o);},L=o=>{o.key==="ArrowUp"?(o.preventDefault(),v()):o.key==="ArrowDown"&&(o.preventDefault(),m());},d={sm:{input:"h-8 text-sm px-2 py-1",button:"w-8 h-8 text-sm",wrapper:"gap-1"},md:{input:"h-10 text-sm px-3 py-2",button:"w-10 h-10 text-sm",wrapper:"gap-2"},lg:{input:"h-12 text-base px-4 py-2.5",button:"w-12 h-12 text-base",wrapper:"gap-2"}}[E],b=a("flex items-center justify-center rounded-md border border-input bg-background","hover:bg-secondary hover:border-primary/50 active:scale-95","transition-all duration-150","disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:bg-background","focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-2",d.button),M=n===void 0||i>n,D=a$1===void 0||i<a$1;return H==="vertical"?jsxs("div",{className:a("inline-flex items-center",d.wrapper,y),children:[jsxs("div",{className:"flex flex-col gap-0.5",children:[jsx("button",{type:"button",onClick:v,disabled:s||!D,className:a(b,"rounded-b-none h-[calc(50%-1px)]"),"aria-label":"Increase",children:jsx(K,{className:"w-3 h-3"})}),jsx("button",{type:"button",onClick:m,disabled:s||!M,className:a(b,"rounded-t-none h-[calc(50%-1px)]"),"aria-label":"Decrease",children:jsx(W,{className:"w-3 h-3"})})]}),jsx("input",{ref:x,type:"text",inputMode:"numeric",pattern:n!==void 0&&n>=0?"[0-9]*":"-?[0-9]*",value:i,onChange:C,onKeyDown:L,onBlur:I,disabled:s,className:a("w-16 text-center rounded-md border border-input bg-background","focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-2","disabled:cursor-not-allowed disabled:opacity-50","[appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none",d.input),...c})]}):jsxs("div",{className:a("inline-flex items-center",d.wrapper,y),children:[N&&jsx("button",{type:"button",onClick:m,disabled:s||!M,className:b,"aria-label":"Decrease",children:jsx(T,{className:"w-3.5 h-3.5"})}),jsx("input",{ref:x,type:"text",inputMode:"numeric",pattern:n!==void 0&&n>=0?"[0-9]*":"-?[0-9]*",value:i,onChange:C,onKeyDown:L,onBlur:I,disabled:s,className:a("w-16 text-center rounded-md border border-input bg-background","focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-2","disabled:cursor-not-allowed disabled:opacity-50","[appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none",d.input),...c}),N&&jsx("button",{type:"button",onClick:v,disabled:s||!D,className:b,"aria-label":"Increase",children:jsx(j,{className:"w-3.5 h-3.5"})})]})});R.displayName="NumberInput";function T({className:r}){return jsx("svg",{className:r,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M20 12H4"})})}function j({className:r}){return jsx("svg",{className:r,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 4v16m8-8H4"})})}function K({className:r}){return jsx("svg",{className:r,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M5 15l7-7 7 7"})})}function W({className:r}){return jsx("svg",{className:r,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M19 9l-7 7-7-7"})})}export{R as a};//# sourceMappingURL=chunk-OLLU7ZFH.mjs.map
3
+ //# sourceMappingURL=chunk-OLLU7ZFH.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/NumberInput.tsx"],"names":["NumberInput","React","controlledValue","defaultValue","min","max","step","onChange","disabled","size","showButtons","buttonLayout","className","props","ref","internalValue","setInternalValue","isControlled","currentValue","updateValue","newValue","clampedValue","increment","decrement","handleInputChange","e","inputValue","handleBlur","_a","handleKeyDown","sizes","buttonBase","merge","canDecrement","canIncrement","jsxs","jsx","ChevronUp","ChevronDown","Minus","Plus"],"mappings":"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","file":"chunk-VWSBJUNI.mjs","sourcesContent":["\"use client\";\n\nimport React from \"react\";\nimport { merge } from \"../lib/utils\";\n\n/**\n * NumberInput 컴포넌트의 props / NumberInput component props\n * @typedef {Object} NumberInputProps\n * @property {number} [value] - 현재 값 / Current value\n * @property {number} [defaultValue=0] - 기본 값 / Default value\n * @property {number} [min] - 최소 값 / Minimum value\n * @property {number} [max] - 최대 값 / Maximum value\n * @property {number} [step=1] - 증감 단위 / Step amount\n * @property {(value: number) => void} [onChange] - 값 변경 콜백 / Value change callback\n * @property {boolean} [disabled=false] - 비활성화 / Disabled state\n * @property {\"sm\" | \"md\" | \"lg\"} [size=\"md\"] - 크기 / Size\n * @property {boolean} [showButtons=true] - +/- 버튼 표시 / Show +/- buttons\n * @property {\"horizontal\" | \"vertical\"} [buttonLayout=\"horizontal\"] - 버튼 배치 / Button layout\n * @property {string} [className] - 추가 CSS 클래스 / Additional CSS class\n */\nexport interface NumberInputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, \"onChange\" | \"value\" | \"defaultValue\" | \"size\" | \"type\"> {\n value?: number;\n defaultValue?: number;\n min?: number;\n max?: number;\n step?: number;\n onChange?: (value: number) => void;\n disabled?: boolean;\n size?: \"sm\" | \"md\" | \"lg\";\n showButtons?: boolean;\n buttonLayout?: \"horizontal\" | \"vertical\";\n}\n\n/**\n * NumberInput 컴포넌트 / NumberInput component\n *\n * 숫자 입력을 위한 컴포넌트로, 커스텀 +/- 버튼을 제공합니다.\n * 브라우저 기본 스피너 대신 스타일링된 버튼을 사용합니다.\n *\n * Number input component with custom +/- buttons.\n * Uses styled buttons instead of browser default spinners.\n *\n * @component\n * @example\n * // 기본 사용 / Basic usage\n * <NumberInput value={count} onChange={setCount} />\n *\n * @example\n * // 범위 지정 / With range\n * <NumberInput min={0} max={100} step={5} />\n *\n * @example\n * // 세로 버튼 / Vertical buttons\n * <NumberInput buttonLayout=\"vertical\" />\n */\nconst NumberInput = React.forwardRef<HTMLInputElement, NumberInputProps>(\n (\n {\n value: controlledValue,\n defaultValue = 0,\n min,\n max,\n step = 1,\n onChange,\n disabled = false,\n size = \"md\",\n showButtons = true,\n buttonLayout = \"horizontal\",\n className,\n ...props\n },\n ref\n ) => {\n const [internalValue, setInternalValue] = React.useState(defaultValue);\n const isControlled = controlledValue !== undefined;\n const currentValue = isControlled ? controlledValue : internalValue;\n\n const updateValue = React.useCallback(\n (newValue: number) => {\n // Clamp to min/max\n let clampedValue = newValue;\n if (min !== undefined) clampedValue = Math.max(min, clampedValue);\n if (max !== undefined) clampedValue = Math.min(max, clampedValue);\n\n if (!isControlled) {\n setInternalValue(clampedValue);\n }\n onChange?.(clampedValue);\n },\n [isControlled, min, max, onChange]\n );\n\n const increment = () => {\n if (disabled) return;\n updateValue(currentValue + step);\n };\n\n const decrement = () => {\n if (disabled) return;\n updateValue(currentValue - step);\n };\n\n const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const inputValue = e.target.value;\n // Allow empty string, minus sign alone (for typing negative numbers), or valid numbers\n if (inputValue === \"\" || inputValue === \"-\") {\n return;\n }\n const newValue = parseFloat(inputValue);\n if (!isNaN(newValue)) {\n // If min is set, enforce it on direct input\n if (min !== undefined && newValue < min) {\n updateValue(min);\n } else {\n updateValue(newValue);\n }\n }\n };\n\n const handleBlur = (e: React.FocusEvent<HTMLInputElement>) => {\n // On blur, ensure value is within bounds\n if (min !== undefined && currentValue < min) {\n updateValue(min);\n }\n if (max !== undefined && currentValue > max) {\n updateValue(max);\n }\n props.onBlur?.(e);\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === \"ArrowUp\") {\n e.preventDefault();\n increment();\n } else if (e.key === \"ArrowDown\") {\n e.preventDefault();\n decrement();\n }\n };\n\n // Spacing system: 4px grid\n // sm: h-8 (32px), px-2 (8px), gap-1 (4px)\n // md: h-10 (40px), px-3 (12px), gap-2 (8px)\n // lg: h-12 (48px), px-4 (16px), gap-2 (8px)\n const sizeClasses = {\n sm: {\n input: \"h-8 text-sm px-2 py-1\",\n button: \"w-8 h-8 text-sm\",\n wrapper: \"gap-1\",\n },\n md: {\n input: \"h-10 text-sm px-3 py-2\",\n button: \"w-10 h-10 text-sm\",\n wrapper: \"gap-2\",\n },\n lg: {\n input: \"h-12 text-base px-4 py-2.5\",\n button: \"w-12 h-12 text-base\",\n wrapper: \"gap-2\",\n },\n };\n\n const sizes = sizeClasses[size];\n\n const buttonBase = merge(\n \"flex items-center justify-center rounded-md border border-input bg-background\",\n \"hover:bg-secondary hover:border-primary/50 active:scale-95\",\n \"transition-all duration-150\",\n \"disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:bg-background\",\n \"focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-2\",\n sizes.button\n );\n\n const canDecrement = min === undefined || currentValue > min;\n const canIncrement = max === undefined || currentValue < max;\n\n if (buttonLayout === \"vertical\") {\n return (\n <div className={merge(\"inline-flex items-center\", sizes.wrapper, className)}>\n <div className=\"flex flex-col gap-0.5\">\n <button\n type=\"button\"\n onClick={increment}\n disabled={disabled || !canIncrement}\n className={merge(buttonBase, \"rounded-b-none h-[calc(50%-1px)]\")}\n aria-label=\"Increase\"\n >\n <ChevronUp className=\"w-3 h-3\" />\n </button>\n <button\n type=\"button\"\n onClick={decrement}\n disabled={disabled || !canDecrement}\n className={merge(buttonBase, \"rounded-t-none h-[calc(50%-1px)]\")}\n aria-label=\"Decrease\"\n >\n <ChevronDown className=\"w-3 h-3\" />\n </button>\n </div>\n <input\n ref={ref}\n type=\"text\"\n inputMode=\"numeric\"\n pattern={min !== undefined && min >= 0 ? \"[0-9]*\" : \"-?[0-9]*\"}\n value={currentValue}\n onChange={handleInputChange}\n onKeyDown={handleKeyDown}\n onBlur={handleBlur}\n disabled={disabled}\n className={merge(\n \"w-16 text-center rounded-md border border-input bg-background\",\n \"focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-2\",\n \"disabled:cursor-not-allowed disabled:opacity-50\",\n \"[appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none\",\n sizes.input\n )}\n {...props}\n />\n </div>\n );\n }\n\n return (\n <div className={merge(\"inline-flex items-center\", sizes.wrapper, className)}>\n {showButtons && (\n <button\n type=\"button\"\n onClick={decrement}\n disabled={disabled || !canDecrement}\n className={buttonBase}\n aria-label=\"Decrease\"\n >\n <Minus className=\"w-3.5 h-3.5\" />\n </button>\n )}\n <input\n ref={ref}\n type=\"text\"\n inputMode=\"numeric\"\n pattern={min !== undefined && min >= 0 ? \"[0-9]*\" : \"-?[0-9]*\"}\n value={currentValue}\n onChange={handleInputChange}\n onKeyDown={handleKeyDown}\n onBlur={handleBlur}\n disabled={disabled}\n className={merge(\n \"w-16 text-center rounded-md border border-input bg-background\",\n \"focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-2\",\n \"disabled:cursor-not-allowed disabled:opacity-50\",\n \"[appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none\",\n sizes.input\n )}\n {...props}\n />\n {showButtons && (\n <button\n type=\"button\"\n onClick={increment}\n disabled={disabled || !canIncrement}\n className={buttonBase}\n aria-label=\"Increase\"\n >\n <Plus className=\"w-3.5 h-3.5\" />\n </button>\n )}\n </div>\n );\n }\n);\n\nNumberInput.displayName = \"NumberInput\";\n\n// Simple icon components to avoid external dependency\nfunction Minus({ className }: { className?: string }) {\n return (\n <svg\n className={className}\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M20 12H4\" />\n </svg>\n );\n}\n\nfunction Plus({ className }: { className?: string }) {\n return (\n <svg\n className={className}\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M12 4v16m8-8H4\" />\n </svg>\n );\n}\n\nfunction ChevronUp({ className }: { className?: string }) {\n return (\n <svg\n className={className}\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M5 15l7-7 7 7\" />\n </svg>\n );\n}\n\nfunction ChevronDown({ className }: { className?: string }) {\n return (\n <svg\n className={className}\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M19 9l-7 7-7-7\" />\n </svg>\n );\n}\n\nexport { NumberInput };\n"]}
1
+ {"version":3,"sources":["../src/components/NumberInput.tsx"],"names":["NumberInput","React","controlledValue","defaultValue","min","max","step","onChange","disabled","size","showButtons","buttonLayout","className","props","ref","internalValue","setInternalValue","isControlled","currentValue","updateValue","newValue","clampedValue","increment","decrement","handleInputChange","e","inputValue","handleBlur","_a","handleKeyDown","sizes","buttonBase","merge","canDecrement","canIncrement","jsxs","jsx","ChevronUp","ChevronDown","Minus","Plus"],"mappings":"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","file":"chunk-OLLU7ZFH.mjs","sourcesContent":["\"use client\";\n\nimport React from \"react\";\nimport { merge } from \"../lib/utils\";\n\n/**\n * NumberInput 컴포넌트의 props / NumberInput component props\n * @typedef {Object} NumberInputProps\n * @property {number} [value] - 현재 값 / Current value\n * @property {number} [defaultValue=0] - 기본 값 / Default value\n * @property {number} [min] - 최소 값 / Minimum value\n * @property {number} [max] - 최대 값 / Maximum value\n * @property {number} [step=1] - 증감 단위 / Step amount\n * @property {(value: number) => void} [onChange] - 값 변경 콜백 / Value change callback\n * @property {boolean} [disabled=false] - 비활성화 / Disabled state\n * @property {\"sm\" | \"md\" | \"lg\"} [size=\"md\"] - 크기 / Size\n * @property {boolean} [showButtons=true] - +/- 버튼 표시 / Show +/- buttons\n * @property {\"horizontal\" | \"vertical\"} [buttonLayout=\"horizontal\"] - 버튼 배치 / Button layout\n * @property {string} [className] - 추가 CSS 클래스 / Additional CSS class\n */\nexport interface NumberInputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, \"onChange\" | \"value\" | \"defaultValue\" | \"size\" | \"type\"> {\n value?: number;\n defaultValue?: number;\n min?: number;\n max?: number;\n step?: number;\n onChange?: (value: number) => void;\n disabled?: boolean;\n size?: \"sm\" | \"md\" | \"lg\";\n showButtons?: boolean;\n buttonLayout?: \"horizontal\" | \"vertical\";\n}\n\n/**\n * NumberInput 컴포넌트 / NumberInput component\n *\n * 숫자 입력을 위한 컴포넌트로, 커스텀 +/- 버튼을 제공합니다.\n * 브라우저 기본 스피너 대신 스타일링된 버튼을 사용합니다.\n *\n * Number input component with custom +/- buttons.\n * Uses styled buttons instead of browser default spinners.\n *\n * @component\n * @example\n * // 기본 사용 / Basic usage\n * <NumberInput value={count} onChange={setCount} />\n *\n * @example\n * // 범위 지정 / With range\n * <NumberInput min={0} max={100} step={5} />\n *\n * @example\n * // 세로 버튼 / Vertical buttons\n * <NumberInput buttonLayout=\"vertical\" />\n */\nconst NumberInput = React.forwardRef<HTMLInputElement, NumberInputProps>(\n (\n {\n value: controlledValue,\n defaultValue = 0,\n min,\n max,\n step = 1,\n onChange,\n disabled = false,\n size = \"md\",\n showButtons = true,\n buttonLayout = \"horizontal\",\n className,\n ...props\n },\n ref\n ) => {\n const [internalValue, setInternalValue] = React.useState(defaultValue);\n const isControlled = controlledValue !== undefined;\n const currentValue = isControlled ? controlledValue : internalValue;\n\n const updateValue = React.useCallback(\n (newValue: number) => {\n // Clamp to min/max\n let clampedValue = newValue;\n if (min !== undefined) clampedValue = Math.max(min, clampedValue);\n if (max !== undefined) clampedValue = Math.min(max, clampedValue);\n\n if (!isControlled) {\n setInternalValue(clampedValue);\n }\n onChange?.(clampedValue);\n },\n [isControlled, min, max, onChange]\n );\n\n const increment = () => {\n if (disabled) return;\n updateValue(currentValue + step);\n };\n\n const decrement = () => {\n if (disabled) return;\n updateValue(currentValue - step);\n };\n\n const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const inputValue = e.target.value;\n // Allow empty string, minus sign alone (for typing negative numbers), or valid numbers\n if (inputValue === \"\" || inputValue === \"-\") {\n return;\n }\n const newValue = parseFloat(inputValue);\n if (!isNaN(newValue)) {\n // If min is set, enforce it on direct input\n if (min !== undefined && newValue < min) {\n updateValue(min);\n } else {\n updateValue(newValue);\n }\n }\n };\n\n const handleBlur = (e: React.FocusEvent<HTMLInputElement>) => {\n // On blur, ensure value is within bounds\n if (min !== undefined && currentValue < min) {\n updateValue(min);\n }\n if (max !== undefined && currentValue > max) {\n updateValue(max);\n }\n props.onBlur?.(e);\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === \"ArrowUp\") {\n e.preventDefault();\n increment();\n } else if (e.key === \"ArrowDown\") {\n e.preventDefault();\n decrement();\n }\n };\n\n // Spacing system: 4px grid\n // sm: h-8 (32px), px-2 (8px), gap-1 (4px)\n // md: h-10 (40px), px-3 (12px), gap-2 (8px)\n // lg: h-12 (48px), px-4 (16px), gap-2 (8px)\n const sizeClasses = {\n sm: {\n input: \"h-8 text-sm px-2 py-1\",\n button: \"w-8 h-8 text-sm\",\n wrapper: \"gap-1\",\n },\n md: {\n input: \"h-10 text-sm px-3 py-2\",\n button: \"w-10 h-10 text-sm\",\n wrapper: \"gap-2\",\n },\n lg: {\n input: \"h-12 text-base px-4 py-2.5\",\n button: \"w-12 h-12 text-base\",\n wrapper: \"gap-2\",\n },\n };\n\n const sizes = sizeClasses[size];\n\n const buttonBase = merge(\n \"flex items-center justify-center rounded-md border border-input bg-background\",\n \"hover:bg-secondary hover:border-primary/50 active:scale-95\",\n \"transition-all duration-150\",\n \"disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:bg-background\",\n \"focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-2\",\n sizes.button\n );\n\n const canDecrement = min === undefined || currentValue > min;\n const canIncrement = max === undefined || currentValue < max;\n\n if (buttonLayout === \"vertical\") {\n return (\n <div className={merge(\"inline-flex items-center\", sizes.wrapper, className)}>\n <div className=\"flex flex-col gap-0.5\">\n <button\n type=\"button\"\n onClick={increment}\n disabled={disabled || !canIncrement}\n className={merge(buttonBase, \"rounded-b-none h-[calc(50%-1px)]\")}\n aria-label=\"Increase\"\n >\n <ChevronUp className=\"w-3 h-3\" />\n </button>\n <button\n type=\"button\"\n onClick={decrement}\n disabled={disabled || !canDecrement}\n className={merge(buttonBase, \"rounded-t-none h-[calc(50%-1px)]\")}\n aria-label=\"Decrease\"\n >\n <ChevronDown className=\"w-3 h-3\" />\n </button>\n </div>\n <input\n ref={ref}\n type=\"text\"\n inputMode=\"numeric\"\n pattern={min !== undefined && min >= 0 ? \"[0-9]*\" : \"-?[0-9]*\"}\n value={currentValue}\n onChange={handleInputChange}\n onKeyDown={handleKeyDown}\n onBlur={handleBlur}\n disabled={disabled}\n className={merge(\n \"w-16 text-center rounded-md border border-input bg-background\",\n \"focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-2\",\n \"disabled:cursor-not-allowed disabled:opacity-50\",\n \"[appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none\",\n sizes.input\n )}\n {...props}\n />\n </div>\n );\n }\n\n return (\n <div className={merge(\"inline-flex items-center\", sizes.wrapper, className)}>\n {showButtons && (\n <button\n type=\"button\"\n onClick={decrement}\n disabled={disabled || !canDecrement}\n className={buttonBase}\n aria-label=\"Decrease\"\n >\n <Minus className=\"w-3.5 h-3.5\" />\n </button>\n )}\n <input\n ref={ref}\n type=\"text\"\n inputMode=\"numeric\"\n pattern={min !== undefined && min >= 0 ? \"[0-9]*\" : \"-?[0-9]*\"}\n value={currentValue}\n onChange={handleInputChange}\n onKeyDown={handleKeyDown}\n onBlur={handleBlur}\n disabled={disabled}\n className={merge(\n \"w-16 text-center rounded-md border border-input bg-background\",\n \"focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-2\",\n \"disabled:cursor-not-allowed disabled:opacity-50\",\n \"[appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none\",\n sizes.input\n )}\n {...props}\n />\n {showButtons && (\n <button\n type=\"button\"\n onClick={increment}\n disabled={disabled || !canIncrement}\n className={buttonBase}\n aria-label=\"Increase\"\n >\n <Plus className=\"w-3.5 h-3.5\" />\n </button>\n )}\n </div>\n );\n }\n);\n\nNumberInput.displayName = \"NumberInput\";\n\n// Simple icon components to avoid external dependency\nfunction Minus({ className }: { className?: string }) {\n return (\n <svg\n className={className}\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M20 12H4\" />\n </svg>\n );\n}\n\nfunction Plus({ className }: { className?: string }) {\n return (\n <svg\n className={className}\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M12 4v16m8-8H4\" />\n </svg>\n );\n}\n\nfunction ChevronUp({ className }: { className?: string }) {\n return (\n <svg\n className={className}\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M5 15l7-7 7 7\" />\n </svg>\n );\n}\n\nfunction ChevronDown({ className }: { className?: string }) {\n return (\n <svg\n className={className}\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M19 9l-7 7-7-7\" />\n </svg>\n );\n}\n\nexport { NumberInput };\n"]}
@@ -0,0 +1,73 @@
1
+ "use client";
2
+ import {a as a$1}from'./chunk-SD6XGDAC.mjs';import {a}from'./chunk-QEMPERUK.mjs';import W,{useRef,useState,useEffect,useCallback}from'react';import {jsxs,jsx,Fragment}from'react/jsx-runtime';var Me=W.forwardRef(({children:a$1,className:u,direction:t="left",speed:n=50,pauseOnHover:y=true,pauseOnClick:R=false,gap:g=16,gradient:C=true,gradientColor:w="hsl(var(--background))",gradientWidth:d=100,style:c,...m},T)=>{let v=useRef(null),[f,N]=useState(0),[E,k]=useState(0),[h,s]=useState(false),M=t==="left"||t==="right",X=t==="right"||t==="down";useEffect(()=>{let L=v.current;if(!L)return;let S=L.firstElementChild;if(!S)return;let B=()=>{M?N(S.offsetWidth):k(S.offsetHeight);};B();let P=new ResizeObserver(B);return P.observe(S),()=>P.disconnect()},[M,a$1]);let O={"--marquee-duration":`${M?f/n:E/n}s`,"--marquee-gap":`${g}px`},j=C?{"--gradient-color":w,"--gradient-width":`${d}px`}:{};return jsxs("div",{ref:T,className:a("relative overflow-hidden",C&&"marquee-gradient",u),style:{...c,...j},onMouseEnter:()=>y&&s(true),onMouseLeave:()=>y&&s(false),onClick:()=>R&&s(!h),...m,children:[jsxs("div",{ref:v,className:a("flex",M?"flex-row":"flex-col",h?"animate-pause":"",M?X?"animate-marquee-right":"animate-marquee-left":X?"animate-marquee-down":"animate-marquee-up"),style:O,children:[jsx("div",{className:a("flex shrink-0",M?"flex-row":"flex-col"),style:{gap:g},children:a$1}),jsx("div",{className:a("flex shrink-0",M?"flex-row":"flex-col"),style:{gap:g,[M?"marginLeft":"marginTop"]:g},"aria-hidden":"true",children:a$1})]}),jsx("style",{dangerouslySetInnerHTML:{__html:`
3
+ @keyframes marquee-left {
4
+ from { transform: translateX(0); }
5
+ to { transform: translateX(calc(-50% - var(--marquee-gap) / 2)); }
6
+ }
7
+ @keyframes marquee-right {
8
+ from { transform: translateX(calc(-50% - var(--marquee-gap) / 2)); }
9
+ to { transform: translateX(0); }
10
+ }
11
+ @keyframes marquee-up {
12
+ from { transform: translateY(0); }
13
+ to { transform: translateY(calc(-50% - var(--marquee-gap) / 2)); }
14
+ }
15
+ @keyframes marquee-down {
16
+ from { transform: translateY(calc(-50% - var(--marquee-gap) / 2)); }
17
+ to { transform: translateY(0); }
18
+ }
19
+ .animate-marquee-left { animation: marquee-left var(--marquee-duration) linear infinite; }
20
+ .animate-marquee-right { animation: marquee-right var(--marquee-duration) linear infinite; }
21
+ .animate-marquee-up { animation: marquee-up var(--marquee-duration) linear infinite; }
22
+ .animate-marquee-down { animation: marquee-down var(--marquee-duration) linear infinite; }
23
+ .animate-pause { animation-play-state: paused !important; }
24
+ .marquee-gradient::before, .marquee-gradient::after {
25
+ content: "";
26
+ position: absolute;
27
+ top: 0;
28
+ bottom: 0;
29
+ width: var(--gradient-width);
30
+ z-index: 10;
31
+ pointer-events: none;
32
+ }
33
+ .marquee-gradient::before {
34
+ left: 0;
35
+ background: linear-gradient(to right, var(--gradient-color), transparent);
36
+ }
37
+ .marquee-gradient::after {
38
+ right: 0;
39
+ background: linear-gradient(to left, var(--gradient-color), transparent);
40
+ }
41
+ `}})]})});Me.displayName="Marquee";var Ce=W.forwardRef(({children:a$1,className:u,glowColor:t="rgba(120, 119, 198, 0.3)",glowSize:n=400,glowOpacity:y=.6,border:R=true,borderColor:g,style:C,...w},d)=>{let c=useRef(null),[m,T]=useState({x:0,y:0}),[v,f]=useState(false),N=useCallback(h=>{if(!c.current)return;let s=c.current.getBoundingClientRect();T({x:h.clientX-s.left,y:h.clientY-s.top});},[]),E={position:"absolute",top:0,left:0,right:0,bottom:0,borderRadius:"inherit",opacity:v?y:0,background:`radial-gradient(${n}px circle at ${m.x}px ${m.y}px, ${t}, transparent 40%)`,transition:"opacity 0.3s ease",pointerEvents:"none"},k=R?{position:"absolute",top:0,left:0,right:0,bottom:0,borderRadius:"inherit",opacity:v?1:0,background:`radial-gradient(${n/2}px circle at ${m.x}px ${m.y}px, ${g||t}, transparent 40%)`,transition:"opacity 0.3s ease",pointerEvents:"none",mask:"linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0)",maskComposite:"exclude",WebkitMaskComposite:"xor",padding:"1px"}:{};return jsxs("div",{ref:Te(d,c),className:a("relative overflow-hidden rounded-xl bg-card border border-border p-6","transition-all duration-300",v&&"border-transparent",u),style:C,onMouseMove:N,onMouseEnter:()=>f(true),onMouseLeave:()=>f(false),...w,children:[jsx("div",{style:E,"aria-hidden":"true"}),R&&jsx("div",{style:k,"aria-hidden":"true"}),jsx("div",{className:"relative z-10",children:a$1})]})});Ce.displayName="GlowCard";function Te(...a){return u=>{a.forEach(t=>{typeof t=="function"?t(u):t&&typeof t=="object"&&(t.current=u);});}}var Se=W.forwardRef(({children:a$1,className:u,spotlightColor:t="rgba(255, 255, 255, 0.1)",spotlightSize:n=300,gradient:y=true,gradientFrom:R="rgba(255, 255, 255, 0.05)",gradientTo:g="transparent",style:C,...w},d)=>{let c=useRef(null),[m,T]=useState({x:0,y:0}),[v,f]=useState(false),N=useCallback(h=>{if(!c.current)return;let s=c.current.getBoundingClientRect();T({x:h.clientX-s.left,y:h.clientY-s.top});},[]),E={position:"absolute",top:0,left:0,right:0,bottom:0,borderRadius:"inherit",opacity:v?1:0,background:`radial-gradient(${n}px circle at ${m.x}px ${m.y}px, ${t}, transparent 60%)`,transition:"opacity 0.4s ease",pointerEvents:"none"},k=y?{position:"absolute",top:0,left:0,right:0,bottom:0,borderRadius:"inherit",background:`linear-gradient(135deg, ${R} 0%, ${g} 100%)`,pointerEvents:"none"}:{};return jsxs("div",{ref:Pe(d,c),className:a("relative overflow-hidden rounded-xl","bg-gray-900 border border-gray-800","transition-all duration-300",v&&"border-gray-700 shadow-2xl shadow-black/20",u),style:C,onMouseMove:N,onMouseEnter:()=>f(true),onMouseLeave:()=>f(false),...w,children:[y&&jsx("div",{style:k,"aria-hidden":"true"}),jsx("div",{style:E,"aria-hidden":"true"}),jsx("div",{className:"relative z-10",children:a$1})]})});Se.displayName="SpotlightCard";function Pe(...a){return u=>{a.forEach(t=>{typeof t=="function"?t(u):t&&typeof t=="object"&&(t.current=u);});}}var ze=["#ff0080","#7928ca","#0070f3","#00dfd8"],De=W.forwardRef(({children:a$2,className:u,colors:t=ze,speed:n=3,blur:y=true,blurAmount:R=100,type:g="mesh",animate:C=true,style:w,...d},c)=>{let[m,T]=useState(false),v=a$1(),f=C&&!v;useEffect(()=>{T(true);},[]);let N=()=>{switch(g){case "linear":return jsx("div",{className:"absolute inset-0",style:{background:`linear-gradient(
42
+ ${f?"var(--gradient-angle, 0deg)":"135deg"},
43
+ ${t.join(", ")}
44
+ )`,animation:f?`gradient-rotate ${n}s linear infinite`:void 0}});case "radial":return jsx("div",{className:"absolute inset-0",style:{background:`radial-gradient(
45
+ circle at ${f?"var(--gradient-x, 50%) var(--gradient-y, 50%)":"50% 50%"},
46
+ ${t.join(", ")}
47
+ )`,animation:f?`gradient-move ${n}s ease-in-out infinite`:void 0}});case "conic":return jsx("div",{className:"absolute inset-0",style:{background:`conic-gradient(
48
+ from ${f?"var(--gradient-angle, 0deg)":"0deg"} at 50% 50%,
49
+ ${t.join(", ")},
50
+ ${t[0]}
51
+ )`,animation:f?`gradient-spin ${n}s linear infinite`:void 0}});default:return m?jsx(Fragment,{children:t.map((E,k)=>{let h=360/t.length*k,s=n/t.length*k;return jsx("div",{className:"absolute rounded-full mix-blend-screen",style:{width:"60%",height:"60%",background:`radial-gradient(circle at center, ${E} 0%, transparent 70%)`,top:`${30+Math.sin(h*Math.PI/180)*20}%`,left:`${30+Math.cos(h*Math.PI/180)*20}%`,animation:f?`gradient-blob ${n}s ease-in-out infinite`:void 0,animationDelay:f?`${-s}s`:void 0}},k)})}):null}};return jsxs("div",{ref:c,className:a("relative overflow-hidden",u),style:w,...d,children:[jsx("div",{className:"absolute inset-0",style:{filter:y?`blur(${R}px)`:void 0},children:N()}),a$2&&jsx("div",{className:"relative z-10",children:a$2}),jsx("style",{dangerouslySetInnerHTML:{__html:`
52
+ @keyframes gradient-rotate {
53
+ 0% { --gradient-angle: 0deg; }
54
+ 100% { --gradient-angle: 360deg; }
55
+ }
56
+ @keyframes gradient-spin {
57
+ 0% { transform: rotate(0deg); }
58
+ 100% { transform: rotate(360deg); }
59
+ }
60
+ @keyframes gradient-move {
61
+ 0%, 100% { --gradient-x: 0%; --gradient-y: 0%; }
62
+ 25% { --gradient-x: 100%; --gradient-y: 0%; }
63
+ 50% { --gradient-x: 100%; --gradient-y: 100%; }
64
+ 75% { --gradient-x: 0%; --gradient-y: 100%; }
65
+ }
66
+ @keyframes gradient-blob {
67
+ 0%, 100% { transform: translate(0, 0) scale(1); }
68
+ 25% { transform: translate(20%, -20%) scale(1.1); }
69
+ 50% { transform: translate(0, 20%) scale(0.9); }
70
+ 75% { transform: translate(-20%, -10%) scale(1.05); }
71
+ }
72
+ `}})]})});De.displayName="AnimatedGradient";var je=W.forwardRef(({children:a$2,autoPlay:u=false,interval:t=5e3,loop:n=true,pauseOnHover:y=true,indicators:R="dots",indicatorPosition:g="bottom",showArrows:C=true,arrowPosition:w="inside",transition:d="slide",transitionDuration:c=500,onSlideChange:m,showPlayPause:T=false,playPausePosition:v="right",className:f,style:N,...E},k)=>{let h=()=>d==="slide"&&n?1:0,[s,M]=useState(h),[X,K]=useState(!u),[O,j]=useState(false),[L,S]=useState(false),[B,P]=useState(false),[te,re]=useState(null),[ae,ne]=useState(null),se=useRef(null),b=W.Children.count(a$2),V=a$1(),ie=useCallback(e=>d!=="slide"||!n?e:e===0?b-1:e===b+1?0:e-1,[n,b,d]),A=useCallback(e=>{if(L)return;let r=e;if(n?d!=="slide"&&(e<0?r=b-1:e>=b&&(r=0)):r=Math.max(0,Math.min(e,b-1)),r!==s){S(true),M(r);let l=n&&d==="slide"?r===0?b-1:r===b+1?0:r-1:r;m==null||m(l),setTimeout(()=>S(false),c);}},[s,b,n,L,c,d,m]);useEffect(()=>{!n||L||d!=="slide"||(s===0?setTimeout(()=>{P(true),M(b),setTimeout(()=>P(false),50);},c):s===b+1&&setTimeout(()=>{P(true),M(1),setTimeout(()=>P(false),50);},c));},[s,b,n,L,c,d]);let z=useCallback(()=>{A(s+1);},[s,A]),Y=useCallback(()=>{A(s-1);},[s,A]),ce=useCallback(()=>{j(e=>!e);},[]);useCallback(()=>{j(false);},[]);useCallback(()=>{j(true);},[]);useEffect(()=>{if(!u||X||O||V)return;let e=setInterval(z,t);return ()=>clearInterval(e)},[u,t,X,O,z,V]);let fe=e=>{re(e.targetTouches[0].clientX);},me=e=>{ne(e.targetTouches[0].clientX);},ge=()=>{if(!te||!ae)return;let e=te-ae;Math.abs(e)>=50&&(e>0?z():Y()),re(null),ne(null);};useEffect(()=>{let e=l=>{l.key==="ArrowLeft"?Y():l.key==="ArrowRight"&&z();},r=se.current;return r==null||r.addEventListener("keydown",e),()=>r==null?void 0:r.removeEventListener("keydown",e)},[z,Y]);let be=()=>{let e=V||B?0:c,r=ie(s);switch(d){case "fade":return W.Children.map(a$2,(l,p)=>jsx("div",{className:a("absolute inset-0 w-full h-full",p===r?"z-10":"z-0"),style:{opacity:p===r?1:0,transition:`opacity ${e}ms ease-in-out`},children:l},p));case "scale":return W.Children.map(a$2,(l,p)=>jsx("div",{className:a("absolute inset-0 w-full h-full",p===r?"z-10":"z-0"),style:{opacity:p===r?1:0,transform:`scale(${p===r?1:.9})`,transition:`opacity ${e}ms ease-in-out, transform ${e}ms ease-in-out`},children:l},p));default:{let l=W.Children.toArray(a$2);return (n?[l[l.length-1],...l,l[0]]:l).map((q,D)=>jsx("div",{className:"absolute inset-0 w-full h-full",style:{transform:`translateX(${(D-s)*100}%)`,transition:B?"none":`transform ${e}ms ease-in-out`},children:q},D))}}},oe=()=>{if(R==="none")return null;let e=g.includes("inside"),r=g.includes("top"),l=ie(s),p=a("flex items-center justify-center gap-2",e?a("absolute left-1/2 -translate-x-1/2 z-20",r?"top-4":"bottom-4"):a("mt-4",r&&"order-first mb-4 mt-0")),q=D=>{A(n&&d==="slide"?D+1:D);};return jsx("div",{className:p,role:"tablist",children:Array.from({length:b},(D,x)=>{let G=x===l;switch(R){case "bars":return jsx("button",{onClick:()=>q(x),className:a("h-1 rounded-full transition-all duration-300",G?"w-8 bg-white":"w-4 bg-white/50 hover:bg-white/70"),role:"tab","aria-selected":G,"aria-label":`\uC2AC\uB77C\uC774\uB4DC ${x+1}`},x);case "numbers":return jsx("button",{onClick:()=>q(x),className:a("w-8 h-8 rounded-full text-sm font-medium transition-all duration-300",G?"bg-white text-gray-900":"bg-white/30 text-white hover:bg-white/50"),role:"tab","aria-selected":G,"aria-label":`\uC2AC\uB77C\uC774\uB4DC ${x+1}`,children:x+1},x);default:return jsx("button",{onClick:()=>q(x),className:a("w-2.5 h-2.5 rounded-full transition-all duration-300",G?"bg-white scale-125":"bg-white/50 hover:bg-white/70"),role:"tab","aria-selected":G,"aria-label":`\uC2AC\uB77C\uC774\uB4DC ${x+1}`},x)}})})},ve=()=>{if(!T||!u)return null;let e=!O;return jsx("button",{onClick:ce,className:a("absolute bottom-4 z-20","w-8 h-8 rounded-full flex items-center justify-center","bg-white/80 hover:bg-white text-gray-800","transition-all duration-200","focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-white",{left:"left-4",center:"left-1/2 -translate-x-1/2",right:"right-4"}[v]),"aria-label":e?"\uC77C\uC2DC\uC815\uC9C0":"\uC7AC\uC0DD",children:e?jsx(_e,{className:"w-4 h-4"}):jsx(Ye,{className:"w-4 h-4"})})},he=()=>{if(!C||w==="hidden")return null;let e=n||s>0,r=n||s<b-1,l=a("absolute top-1/2 -translate-y-1/2 z-20","w-10 h-10 rounded-full flex items-center justify-center","bg-white/80 hover:bg-white text-gray-800","transition-all duration-200","disabled:opacity-30 disabled:cursor-not-allowed","focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-white"),p=w==="outside"?"-left-14":"left-4",q=w==="outside"?"-right-14":"right-4";return jsxs(Fragment,{children:[jsx("button",{onClick:Y,disabled:!e,className:a(l,p),"aria-label":"\uC774\uC804 \uC2AC\uB77C\uC774\uB4DC",children:jsx(Be,{className:"w-5 h-5"})}),jsx("button",{onClick:z,disabled:!r,className:a(l,q),"aria-label":"\uB2E4\uC74C \uC2AC\uB77C\uC774\uB4DC",children:jsx(We,{className:"w-5 h-5"})})]})};return jsxs("div",{ref:k,className:a("flex flex-col w-full h-full",w==="outside"&&"px-16",f),style:N,...E,children:[jsxs("div",{ref:se,className:"relative overflow-hidden w-full flex-1",onMouseEnter:()=>y&&K(true),onMouseLeave:()=>y&&K(false),onTouchStart:fe,onTouchMove:me,onTouchEnd:ge,tabIndex:0,role:"region","aria-roledescription":"carousel","aria-label":"\uC774\uBBF8\uC9C0 \uC2AC\uB77C\uC774\uB354",children:[be(),he(),ve(),g.includes("inside")&&oe()]}),!g.includes("inside")&&oe()]})});je.displayName="Carousel";function Be({className:a}){return jsx("svg",{className:a,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M15 19l-7-7 7-7"})})}function We({className:a}){return jsx("svg",{className:a,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 5l7 7-7 7"})})}function Ye({className:a}){return jsx("svg",{className:a,fill:"currentColor",viewBox:"0 0 24 24",children:jsx("path",{d:"M8 5v14l11-7z"})})}function _e({className:a}){return jsx("svg",{className:a,fill:"currentColor",viewBox:"0 0 24 24",children:jsx("path",{d:"M6 4h4v16H6V4zm8 0h4v16h-4V4z"})})}export{Me as a,Ce as b,Se as c,De as d,je as e};//# sourceMappingURL=chunk-Q76JW7X5.mjs.map
73
+ //# sourceMappingURL=chunk-Q76JW7X5.mjs.map