@hua-labs/ui 2.0.2 → 2.1.1

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 (214) hide show
  1. package/README.md +34 -161
  2. package/dist/{ComponentLayout-btJq4TjA.d.mts → ComponentLayout-DrZpz0yv.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.js +4 -4
  7. package/dist/advanced-dashboard.js.map +1 -1
  8. package/dist/advanced-dashboard.mjs +3 -3
  9. package/dist/advanced-dashboard.mjs.map +1 -1
  10. package/dist/advanced-emotion.mjs +1 -1
  11. package/dist/advanced-motion.d.mts +65 -1
  12. package/dist/advanced-motion.js +14 -14
  13. package/dist/advanced-motion.js.map +1 -1
  14. package/dist/advanced-motion.mjs +1 -1
  15. package/dist/advanced.d.mts +4 -4
  16. package/dist/advanced.js +16 -16
  17. package/dist/advanced.js.map +1 -1
  18. package/dist/advanced.mjs +3 -3
  19. package/dist/advanced.mjs.map +1 -1
  20. package/dist/chunk-3CCF7U3P.mjs +3 -0
  21. package/dist/{chunk-IFSEJVOR.mjs.map → chunk-3CCF7U3P.mjs.map} +1 -1
  22. package/dist/chunk-3GAUTZXQ.mjs +3 -0
  23. package/dist/{chunk-X7ZIWYRC.mjs.map → chunk-3GAUTZXQ.mjs.map} +1 -1
  24. package/dist/chunk-42RGFEL2.mjs +3 -0
  25. package/dist/chunk-42RGFEL2.mjs.map +1 -0
  26. package/dist/chunk-4NJE7D6X.mjs +3 -0
  27. package/dist/chunk-4NJE7D6X.mjs.map +1 -0
  28. package/dist/chunk-6HVJFEDA.mjs +3 -0
  29. package/dist/{chunk-FSL373O6.mjs.map → chunk-6HVJFEDA.mjs.map} +1 -1
  30. package/dist/chunk-7OYT3QSY.mjs +3 -0
  31. package/dist/chunk-7OYT3QSY.mjs.map +1 -0
  32. package/dist/chunk-ANYZ56VB.mjs +3 -0
  33. package/dist/{chunk-QQCELXFD.mjs.map → chunk-ANYZ56VB.mjs.map} +1 -1
  34. package/dist/chunk-AOSXB5JJ.mjs +4 -0
  35. package/dist/{chunk-GLZKT7JN.mjs.map → chunk-AOSXB5JJ.mjs.map} +1 -1
  36. package/dist/chunk-B544MRF7.mjs +3 -0
  37. package/dist/{chunk-SDFHJ4GB.mjs.map → chunk-B544MRF7.mjs.map} +1 -1
  38. package/dist/chunk-CVWWS25A.mjs +3 -0
  39. package/dist/chunk-CVWWS25A.mjs.map +1 -0
  40. package/dist/chunk-DYNBM24D.mjs +3 -0
  41. package/dist/{chunk-OSCMSA2Q.mjs.map → chunk-DYNBM24D.mjs.map} +1 -1
  42. package/dist/{chunk-NBJUE7NR.mjs → chunk-FX57OSYG.mjs} +2 -2
  43. package/dist/{chunk-NBJUE7NR.mjs.map → chunk-FX57OSYG.mjs.map} +1 -1
  44. package/dist/chunk-IJSYSNM5.mjs +3 -0
  45. package/dist/{chunk-IN7RWQCJ.mjs.map → chunk-IJSYSNM5.mjs.map} +1 -1
  46. package/dist/chunk-KJZGOL2Z.mjs +3 -0
  47. package/dist/{chunk-LOYAJIWO.mjs.map → chunk-KJZGOL2Z.mjs.map} +1 -1
  48. package/dist/chunk-KYRIUUQP.mjs +3 -0
  49. package/dist/{chunk-PAEKNQWW.mjs.map → chunk-KYRIUUQP.mjs.map} +1 -1
  50. package/dist/chunk-LSA7DU3N.mjs +73 -0
  51. package/dist/chunk-LSA7DU3N.mjs.map +1 -0
  52. package/dist/chunk-MDLCJASB.mjs +3 -0
  53. package/dist/{chunk-LH77I6HO.mjs.map → chunk-MDLCJASB.mjs.map} +1 -1
  54. package/dist/chunk-N56BUOCD.mjs +3 -0
  55. package/dist/{chunk-XV3Y7QVU.mjs.map → chunk-N56BUOCD.mjs.map} +1 -1
  56. package/dist/chunk-OFYITQXI.mjs +13 -0
  57. package/dist/chunk-OFYITQXI.mjs.map +1 -0
  58. package/dist/chunk-OZNST3EZ.mjs +3 -0
  59. package/dist/{chunk-SGEP3CQE.mjs.map → chunk-OZNST3EZ.mjs.map} +1 -1
  60. package/dist/chunk-RS6RKW5U.mjs +13 -0
  61. package/dist/{chunk-6KTHJ3EL.mjs.map → chunk-RS6RKW5U.mjs.map} +1 -1
  62. package/dist/{chunk-C4OACMTB.mjs → chunk-TXBZZJNR.mjs} +2 -2
  63. package/dist/{chunk-C4OACMTB.mjs.map → chunk-TXBZZJNR.mjs.map} +1 -1
  64. package/dist/chunk-TZ4YSHMC.mjs +3 -0
  65. package/dist/{chunk-UWHCM3S6.mjs.map → chunk-TZ4YSHMC.mjs.map} +1 -1
  66. package/dist/chunk-U6CTBZ2U.mjs +3 -0
  67. package/dist/chunk-U6CTBZ2U.mjs.map +1 -0
  68. package/dist/{chunk-5BMH7223.mjs → chunk-WP7VFE77.mjs} +2 -2
  69. package/dist/{chunk-5BMH7223.mjs.map → chunk-WP7VFE77.mjs.map} +1 -1
  70. package/dist/{chunk-FFH4ZFKS.mjs → chunk-XCZMLKPK.mjs} +2 -2
  71. package/dist/{chunk-FFH4ZFKS.mjs.map → chunk-XCZMLKPK.mjs.map} +1 -1
  72. package/dist/chunk-XGHT7WMO.mjs +3 -0
  73. package/dist/chunk-XGHT7WMO.mjs.map +1 -0
  74. package/dist/chunk-XL4KTJ4L.mjs +3 -0
  75. package/dist/{chunk-VWSBJUNI.mjs.map → chunk-XL4KTJ4L.mjs.map} +1 -1
  76. package/dist/chunk-Z74YUUVT.mjs +3 -0
  77. package/dist/chunk-Z74YUUVT.mjs.map +1 -0
  78. package/dist/chunk-ZXZIHU7J.mjs +8 -0
  79. package/dist/{chunk-N7M6RIN4.mjs.map → chunk-ZXZIHU7J.mjs.map} +1 -1
  80. package/dist/components/DatePicker.d.ts.map +1 -1
  81. package/dist/components/Modal.d.ts.map +1 -1
  82. package/dist/components/Popover.d.ts +2 -0
  83. package/dist/components/Popover.d.ts.map +1 -1
  84. package/dist/components/Progress.d.ts +1 -0
  85. package/dist/components/Progress.d.ts.map +1 -1
  86. package/dist/components/Section.d.ts +44 -0
  87. package/dist/components/Section.d.ts.map +1 -0
  88. package/dist/components/advanced/AnimatedGradient.d.ts.map +1 -1
  89. package/dist/components/advanced/DotNav.d.ts +26 -0
  90. package/dist/components/advanced/DotNav.d.ts.map +1 -0
  91. package/dist/components/advanced/HorizontalScroll.d.ts +20 -0
  92. package/dist/components/advanced/HorizontalScroll.d.ts.map +1 -0
  93. package/dist/components/advanced/ImageReveal.d.ts +24 -0
  94. package/dist/components/advanced/ImageReveal.d.ts.map +1 -0
  95. package/dist/components/advanced/index.d.ts +6 -0
  96. package/dist/components/advanced/index.d.ts.map +1 -1
  97. package/dist/data.mjs +2 -2
  98. package/dist/data.mjs.map +1 -1
  99. package/dist/feedback.mjs +1 -1
  100. package/dist/form.js +3 -3
  101. package/dist/form.js.map +1 -1
  102. package/dist/form.mjs +4 -4
  103. package/dist/form.mjs.map +1 -1
  104. package/dist/{icons-Bj_nr8Ba.d.mts → icons-DmhQEH_E.d.mts} +6 -1
  105. package/dist/index.d.mts +9 -27
  106. package/dist/index.d.ts +4 -0
  107. package/dist/index.d.ts.map +1 -1
  108. package/dist/index.js +6 -6
  109. package/dist/index.js.map +1 -1
  110. package/dist/index.mjs +2 -2
  111. package/dist/index.mjs.map +1 -1
  112. package/dist/interactive.js +1 -1
  113. package/dist/interactive.js.map +1 -1
  114. package/dist/interactive.mjs +1 -1
  115. package/dist/interactive.mjs.map +1 -1
  116. package/dist/landing/LandingAbout.d.ts +3 -0
  117. package/dist/landing/LandingAbout.d.ts.map +1 -0
  118. package/dist/landing/LandingCTA.d.ts +3 -0
  119. package/dist/landing/LandingCTA.d.ts.map +1 -0
  120. package/dist/landing/LandingContact.d.ts +3 -0
  121. package/dist/landing/LandingContact.d.ts.map +1 -0
  122. package/dist/landing/LandingExperience.d.ts +3 -0
  123. package/dist/landing/LandingExperience.d.ts.map +1 -0
  124. package/dist/landing/LandingFeatures.d.ts +3 -0
  125. package/dist/landing/LandingFeatures.d.ts.map +1 -0
  126. package/dist/landing/LandingHero.d.ts +3 -0
  127. package/dist/landing/LandingHero.d.ts.map +1 -0
  128. package/dist/landing/LandingLogoCloud.d.ts +3 -0
  129. package/dist/landing/LandingLogoCloud.d.ts.map +1 -0
  130. package/dist/landing/LandingMetrics.d.ts +3 -0
  131. package/dist/landing/LandingMetrics.d.ts.map +1 -0
  132. package/dist/landing/LandingProjects.d.ts +3 -0
  133. package/dist/landing/LandingProjects.d.ts.map +1 -0
  134. package/dist/landing/LandingProvider.d.ts +4 -0
  135. package/dist/landing/LandingProvider.d.ts.map +1 -0
  136. package/dist/landing/LandingShowcase.d.ts +3 -0
  137. package/dist/landing/LandingShowcase.d.ts.map +1 -0
  138. package/dist/landing/LandingSkills.d.ts +3 -0
  139. package/dist/landing/LandingSkills.d.ts.map +1 -0
  140. package/dist/landing/LandingStats.d.ts +3 -0
  141. package/dist/landing/LandingStats.d.ts.map +1 -0
  142. package/dist/landing/LandingTestimonials.d.ts +3 -0
  143. package/dist/landing/LandingTestimonials.d.ts.map +1 -0
  144. package/dist/landing/index.d.ts +47 -0
  145. package/dist/landing/index.d.ts.map +1 -0
  146. package/dist/landing/themes/app.d.ts +3 -0
  147. package/dist/landing/themes/app.d.ts.map +1 -0
  148. package/dist/landing/themes/corporate.d.ts +3 -0
  149. package/dist/landing/themes/corporate.d.ts.map +1 -0
  150. package/dist/landing/themes/dashboard.d.ts +3 -0
  151. package/dist/landing/themes/dashboard.d.ts.map +1 -0
  152. package/dist/landing/themes/immersive.d.ts +3 -0
  153. package/dist/landing/themes/immersive.d.ts.map +1 -0
  154. package/dist/landing/themes/index.d.ts +15 -0
  155. package/dist/landing/themes/index.d.ts.map +1 -0
  156. package/dist/landing/themes/marketing.d.ts +3 -0
  157. package/dist/landing/themes/marketing.d.ts.map +1 -0
  158. package/dist/landing/themes/portfolio.d.ts +3 -0
  159. package/dist/landing/themes/portfolio.d.ts.map +1 -0
  160. package/dist/landing/themes/product.d.ts +3 -0
  161. package/dist/landing/themes/product.d.ts.map +1 -0
  162. package/dist/landing/types.d.ts +346 -0
  163. package/dist/landing/types.d.ts.map +1 -0
  164. package/dist/landing.d.mts +417 -0
  165. package/dist/landing.js +100 -0
  166. package/dist/landing.js.map +1 -0
  167. package/dist/landing.mjs +31 -0
  168. package/dist/landing.mjs.map +1 -0
  169. package/dist/lib/icons.d.ts +6 -1
  170. package/dist/lib/icons.d.ts.map +1 -1
  171. package/dist/navigation.d.mts +1 -1
  172. package/dist/navigation.js +2 -2
  173. package/dist/navigation.js.map +1 -1
  174. package/dist/navigation.mjs +1 -1
  175. package/dist/navigation.mjs.map +1 -1
  176. package/dist/overlay.d.mts +2 -0
  177. package/dist/overlay.js +1 -1
  178. package/dist/overlay.js.map +1 -1
  179. package/dist/overlay.mjs +1 -1
  180. package/dist/overlay.mjs.map +1 -1
  181. package/dist/sdui.js +4 -4
  182. package/dist/sdui.js.map +1 -1
  183. package/dist/sdui.mjs +1 -1
  184. package/dist/sdui.mjs.map +1 -1
  185. package/package.json +18 -7
  186. package/src/styles/landing.css +107 -0
  187. package/src/styles/utilities.css +58 -0
  188. package/dist/chunk-6KTHJ3EL.mjs +0 -13
  189. package/dist/chunk-COR6CDMA.mjs +0 -83
  190. package/dist/chunk-COR6CDMA.mjs.map +0 -1
  191. package/dist/chunk-FSL373O6.mjs +0 -3
  192. package/dist/chunk-GLZKT7JN.mjs +0 -4
  193. package/dist/chunk-HN5LSP6L.mjs +0 -3
  194. package/dist/chunk-HN5LSP6L.mjs.map +0 -1
  195. package/dist/chunk-IFSEJVOR.mjs +0 -3
  196. package/dist/chunk-IN7RWQCJ.mjs +0 -3
  197. package/dist/chunk-LH77I6HO.mjs +0 -3
  198. package/dist/chunk-LOYAJIWO.mjs +0 -3
  199. package/dist/chunk-LPAG7DCA.mjs +0 -3
  200. package/dist/chunk-LPAG7DCA.mjs.map +0 -1
  201. package/dist/chunk-N7M6RIN4.mjs +0 -8
  202. package/dist/chunk-OSCMSA2Q.mjs +0 -3
  203. package/dist/chunk-PAEKNQWW.mjs +0 -3
  204. package/dist/chunk-QQCELXFD.mjs +0 -3
  205. package/dist/chunk-RPUS7G7Q.mjs +0 -3
  206. package/dist/chunk-RPUS7G7Q.mjs.map +0 -1
  207. package/dist/chunk-SDFHJ4GB.mjs +0 -3
  208. package/dist/chunk-SGEP3CQE.mjs +0 -3
  209. package/dist/chunk-UUHAXGMO.mjs +0 -3
  210. package/dist/chunk-UUHAXGMO.mjs.map +0 -1
  211. package/dist/chunk-UWHCM3S6.mjs +0 -3
  212. package/dist/chunk-VWSBJUNI.mjs +0 -3
  213. package/dist/chunk-X7ZIWYRC.mjs +0 -3
  214. package/dist/chunk-XV3Y7QVU.mjs +0 -3
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/advanced/Marquee.tsx","../src/components/advanced/GlowCard.tsx","../src/components/advanced/SpotlightCard.tsx","../src/components/advanced/AnimatedGradient.tsx","../src/components/advanced/Carousel.tsx"],"names":["Marquee","React","children","className","direction","speed","pauseOnHover","pauseOnClick","gap","gradient","gradientColor","gradientWidth","style","props","ref","containerRef","useRef","contentWidth","setContentWidth","useState","contentHeight","setContentHeight","isPaused","setIsPaused","isHorizontal","isReverse","useEffect","container","firstChild","updateSize","resizeObserver","animationStyle","gradientStyle","jsxs","merge","jsx","GlowCard","glowColor","glowSize","glowOpacity","border","borderColor","cardRef","mousePosition","setMousePosition","isHovered","setIsHovered","handleMouseMove","useCallback","e","rect","glowStyle","borderStyle","mergeRefs","refs","value","SpotlightCard","spotlightColor","spotlightSize","gradientFrom","gradientTo","spotlightStyle","gradientOverlayStyle","defaultColors","AnimatedGradient","colors","blur","blurAmount","type","animate","mounted","setMounted","prefersReducedMotion","useReducedMotion","shouldAnimate","renderGradient","Fragment","color","index","angle","delay","setPrefersReducedMotion","mediaQuery","handleChange","Carousel","autoPlay","interval","loop","indicators","indicatorPosition","showArrows","arrowPosition","transition","transitionDuration","onSlideChange","showPlayPause","playPausePosition","getInitialIndex","currentIndex","setCurrentIndex","isManuallyPaused","setIsManuallyPaused","isTransitioning","setIsTransitioning","noTransition","setNoTransition","touchStart","setTouchStart","touchEnd","setTouchEnd","slideCount","getActualIndex","goToSlide","newIndex","actualIndex","nextSlide","prevSlide","togglePlayPause","prev","timer","handleTouchStart","handleTouchMove","handleTouchEnd","distance","handleKeyDown","renderSlides","duration","child","childArray","renderIndicators","isInside","isTop","indicatorContainerClass","handleIndicatorClick","_","isActive","renderPlayPause","isPlaying","PauseIcon","PlayIcon","renderArrows","canGoPrev","canGoNext","arrowBaseClass","prevPosition","nextPosition","ChevronLeft","ChevronRight"],"mappings":"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","file":"chunk-LSA7DU3N.mjs","sourcesContent":["\"use client\";\n\nimport React, { useRef, useEffect, useState } from \"react\";\nimport { merge } from \"../../lib/utils\";\n\n/**\n * Marquee 컴포넌트의 props / Marquee component props\n * @property {\"left\" | \"right\" | \"up\" | \"down\"} [direction=\"left\"] - 이동 방향 / Movement direction\n * @property {number} [speed=50] - 속도 (px/s) / Speed in pixels per second\n * @property {boolean} [pauseOnHover=true] - 호버시 일시정지 / Pause on hover\n * @property {boolean} [pauseOnClick=false] - 클릭시 일시정지 / Pause on click\n * @property {number} [gap=16] - 아이템 간격 (px) / Gap between items in pixels\n * @property {boolean} [gradient=true] - 양쪽 페이드 그라디언트 / Fade gradient on edges\n * @property {string} [gradientColor=\"hsl(var(--background))\"] - 그라디언트 색상 / Gradient color\n * @property {number} [gradientWidth=100] - 그라디언트 너비 (px) / Gradient width in pixels\n */\nexport interface MarqueeProps extends React.HTMLAttributes<HTMLDivElement> {\n direction?: \"left\" | \"right\" | \"up\" | \"down\";\n speed?: number;\n pauseOnHover?: boolean;\n pauseOnClick?: boolean;\n gap?: number;\n gradient?: boolean;\n gradientColor?: string;\n gradientWidth?: number;\n}\n\n/**\n * Marquee 컴포넌트 / Marquee component\n *\n * 무한 스크롤 애니메이션을 제공하는 컴포넌트입니다.\n * 로고, 텍스트, 이미지 등을 자동으로 흐르게 표시합니다.\n *\n * Component that provides infinite scroll animation.\n * Displays logos, text, images, etc. with automatic scrolling.\n *\n * @component\n * @example\n * // 기본 사용 / Basic usage\n * <Marquee>\n * <span>Item 1</span>\n * <span>Item 2</span>\n * <span>Item 3</span>\n * </Marquee>\n *\n * @example\n * // 로고 캐러셀 / Logo carousel\n * <Marquee speed={30} pauseOnHover gradient>\n * {logos.map(logo => <img key={logo.id} src={logo.src} />)}\n * </Marquee>\n */\nconst Marquee = React.forwardRef<HTMLDivElement, MarqueeProps>(\n (\n {\n children,\n className,\n direction = \"left\",\n speed = 50,\n pauseOnHover = true,\n pauseOnClick = false,\n gap = 16,\n gradient = true,\n gradientColor = \"hsl(var(--background))\",\n gradientWidth = 100,\n style,\n ...props\n },\n ref\n ) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const [contentWidth, setContentWidth] = useState(0);\n const [contentHeight, setContentHeight] = useState(0);\n const [isPaused, setIsPaused] = useState(false);\n\n const isHorizontal = direction === \"left\" || direction === \"right\";\n const isReverse = direction === \"right\" || direction === \"down\";\n\n // Measure content size\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n\n const firstChild = container.firstElementChild as HTMLElement;\n if (!firstChild) return;\n\n const updateSize = () => {\n if (isHorizontal) {\n setContentWidth(firstChild.offsetWidth);\n } else {\n setContentHeight(firstChild.offsetHeight);\n }\n };\n\n updateSize();\n\n const resizeObserver = new ResizeObserver(updateSize);\n resizeObserver.observe(firstChild);\n\n return () => resizeObserver.disconnect();\n }, [isHorizontal, children]);\n\n // Calculate animation duration\n const duration = isHorizontal\n ? contentWidth / speed\n : contentHeight / speed;\n\n const animationStyle: React.CSSProperties = {\n [\"--marquee-duration\" as string]: `${duration}s`,\n [\"--marquee-gap\" as string]: `${gap}px`,\n };\n\n // Gradient styles\n const gradientStyle = gradient\n ? {\n [\"--gradient-color\" as string]: gradientColor,\n [\"--gradient-width\" as string]: `${gradientWidth}px`,\n }\n : {};\n\n return (\n <div\n ref={ref}\n className={merge(\n \"relative overflow-hidden\",\n gradient && \"marquee-gradient\",\n className\n )}\n style={{ ...style, ...gradientStyle }}\n onMouseEnter={() => pauseOnHover && setIsPaused(true)}\n onMouseLeave={() => pauseOnHover && setIsPaused(false)}\n onClick={() => pauseOnClick && setIsPaused(!isPaused)}\n {...props}\n >\n <div\n ref={containerRef}\n className={merge(\n \"flex\",\n isHorizontal ? \"flex-row\" : \"flex-col\",\n isPaused ? \"animate-pause\" : \"\",\n isHorizontal\n ? isReverse\n ? \"animate-marquee-right\"\n : \"animate-marquee-left\"\n : isReverse\n ? \"animate-marquee-down\"\n : \"animate-marquee-up\"\n )}\n style={animationStyle}\n >\n {/* Original content */}\n <div\n className={merge(\n \"flex shrink-0\",\n isHorizontal ? \"flex-row\" : \"flex-col\"\n )}\n style={{ gap }}\n >\n {children}\n </div>\n {/* Duplicated content for seamless loop */}\n <div\n className={merge(\n \"flex shrink-0\",\n isHorizontal ? \"flex-row\" : \"flex-col\"\n )}\n style={{ gap, [isHorizontal ? \"marginLeft\" : \"marginTop\"]: gap }}\n aria-hidden=\"true\"\n >\n {children}\n </div>\n </div>\n\n {/* CSS for animations - injected as style element */}\n <style dangerouslySetInnerHTML={{ __html: `\n @keyframes marquee-left {\n from { transform: translateX(0); }\n to { transform: translateX(calc(-50% - var(--marquee-gap) / 2)); }\n }\n @keyframes marquee-right {\n from { transform: translateX(calc(-50% - var(--marquee-gap) / 2)); }\n to { transform: translateX(0); }\n }\n @keyframes marquee-up {\n from { transform: translateY(0); }\n to { transform: translateY(calc(-50% - var(--marquee-gap) / 2)); }\n }\n @keyframes marquee-down {\n from { transform: translateY(calc(-50% - var(--marquee-gap) / 2)); }\n to { transform: translateY(0); }\n }\n .animate-marquee-left { animation: marquee-left var(--marquee-duration) linear infinite; }\n .animate-marquee-right { animation: marquee-right var(--marquee-duration) linear infinite; }\n .animate-marquee-up { animation: marquee-up var(--marquee-duration) linear infinite; }\n .animate-marquee-down { animation: marquee-down var(--marquee-duration) linear infinite; }\n .animate-pause { animation-play-state: paused !important; }\n .marquee-gradient::before, .marquee-gradient::after {\n content: \"\";\n position: absolute;\n top: 0;\n bottom: 0;\n width: var(--gradient-width);\n z-index: 10;\n pointer-events: none;\n }\n .marquee-gradient::before {\n left: 0;\n background: linear-gradient(to right, var(--gradient-color), transparent);\n }\n .marquee-gradient::after {\n right: 0;\n background: linear-gradient(to left, var(--gradient-color), transparent);\n }\n `}} />\n </div>\n );\n }\n);\n\nMarquee.displayName = \"Marquee\";\n\nexport { Marquee };\n","\"use client\";\n\nimport React, { useRef, useState, useCallback } from \"react\";\nimport { merge } from \"../../lib/utils\";\n\n/**\n * GlowCard 컴포넌트의 props / GlowCard component props\n * @property {string} [glowColor=\"rgba(120, 119, 198, 0.3)\"] - 글로우 색상 / Glow color\n * @property {number} [glowSize=400] - 글로우 크기 (px) / Glow size in pixels\n * @property {number} [glowOpacity=0.6] - 글로우 투명도 / Glow opacity\n * @property {boolean} [border=true] - 글로우 보더 표시 / Show glow border\n * @property {string} [borderColor] - 보더 색상 (기본: glowColor) / Border color (default: glowColor)\n */\nexport interface GlowCardProps extends React.HTMLAttributes<HTMLDivElement> {\n glowColor?: string;\n glowSize?: number;\n glowOpacity?: number;\n border?: boolean;\n borderColor?: string;\n}\n\n/**\n * GlowCard 컴포넌트 / GlowCard component\n *\n * 마우스를 따라다니는 글로우 효과가 있는 카드 컴포넌트입니다.\n * SaaS 랜딩 페이지, 프리미엄 UI에 적합합니다.\n *\n * Card component with mouse-following glow effect.\n * Perfect for SaaS landing pages and premium UI.\n *\n * @component\n * @example\n * <GlowCard glowColor=\"rgba(59, 130, 246, 0.4)\">\n * <h3>Premium Feature</h3>\n * <p>This is a premium feature card</p>\n * </GlowCard>\n */\nconst GlowCard = React.forwardRef<HTMLDivElement, GlowCardProps>(\n (\n {\n children,\n className,\n glowColor = \"rgba(120, 119, 198, 0.3)\",\n glowSize = 400,\n glowOpacity = 0.6,\n border = true,\n borderColor,\n style,\n ...props\n },\n ref\n ) => {\n const cardRef = useRef<HTMLDivElement>(null);\n const [mousePosition, setMousePosition] = useState({ x: 0, y: 0 });\n const [isHovered, setIsHovered] = useState(false);\n\n const handleMouseMove = useCallback(\n (e: React.MouseEvent<HTMLDivElement>) => {\n if (!cardRef.current) return;\n const rect = cardRef.current.getBoundingClientRect();\n setMousePosition({\n x: e.clientX - rect.left,\n y: e.clientY - rect.top,\n });\n },\n []\n );\n\n const glowStyle: React.CSSProperties = {\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n borderRadius: \"inherit\",\n opacity: isHovered ? glowOpacity : 0,\n background: `radial-gradient(${glowSize}px circle at ${mousePosition.x}px ${mousePosition.y}px, ${glowColor}, transparent 40%)`,\n transition: \"opacity 0.3s ease\",\n pointerEvents: \"none\",\n };\n\n const borderStyle: React.CSSProperties = border\n ? {\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n borderRadius: \"inherit\",\n opacity: isHovered ? 1 : 0,\n background: `radial-gradient(${glowSize / 2}px circle at ${mousePosition.x}px ${mousePosition.y}px, ${borderColor || glowColor}, transparent 40%)`,\n transition: \"opacity 0.3s ease\",\n pointerEvents: \"none\",\n mask: \"linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0)\",\n maskComposite: \"exclude\",\n WebkitMaskComposite: \"xor\",\n padding: \"1px\",\n }\n : {};\n\n return (\n <div\n ref={mergeRefs(ref, cardRef)}\n className={merge(\n \"relative overflow-hidden rounded-xl bg-card border border-border p-6\",\n \"transition-all duration-300\",\n isHovered && \"border-transparent\",\n className\n )}\n style={style}\n onMouseMove={handleMouseMove}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n {...props}\n >\n {/* Glow effect */}\n <div style={glowStyle} aria-hidden=\"true\" />\n\n {/* Border glow */}\n {border && <div style={borderStyle as React.CSSProperties} aria-hidden=\"true\" />}\n\n {/* Content */}\n <div className=\"relative z-10\">{children}</div>\n </div>\n );\n }\n);\n\nGlowCard.displayName = \"GlowCard\";\n\n// Utility to merge refs\nfunction mergeRefs<T>(...refs: (React.Ref<T> | undefined)[]): React.RefCallback<T> {\n return (value) => {\n refs.forEach((ref) => {\n if (typeof ref === \"function\") {\n ref(value);\n } else if (ref && typeof ref === \"object\") {\n (ref as React.MutableRefObject<T | null>).current = value;\n }\n });\n };\n}\n\nexport { GlowCard };\n","\"use client\";\n\nimport React, { useRef, useState, useCallback } from \"react\";\nimport { merge } from \"../../lib/utils\";\n\n/**\n * SpotlightCard 컴포넌트의 props / SpotlightCard component props\n * @property {string} [spotlightColor=\"rgba(255, 255, 255, 0.1)\"] - 스포트라이트 색상 / Spotlight color\n * @property {number} [spotlightSize=300] - 스포트라이트 크기 (px) / Spotlight size in pixels\n * @property {boolean} [gradient=true] - 그라디언트 배경 효과 / Gradient background effect\n * @property {string} [gradientFrom=\"rgba(255, 255, 255, 0.05)\"] - 그라디언트 시작 색상 / Gradient start color\n * @property {string} [gradientTo=\"transparent\"] - 그라디언트 끝 색상 / Gradient end color\n */\nexport interface SpotlightCardProps extends React.HTMLAttributes<HTMLDivElement> {\n spotlightColor?: string;\n spotlightSize?: number;\n gradient?: boolean;\n gradientFrom?: string;\n gradientTo?: string;\n}\n\n/**\n * SpotlightCard 컴포넌트 / SpotlightCard component\n *\n * 마우스 위치에 스포트라이트 효과를 표시하는 프리미엄 카드 컴포넌트입니다.\n * 다크 테마 랜딩 페이지, 프리미엄 UI에 적합합니다.\n *\n * Premium card component that displays a spotlight effect at mouse position.\n * Perfect for dark theme landing pages and premium UI.\n *\n * @component\n * @example\n * <SpotlightCard className=\"bg-gray-900 text-white p-8\">\n * <h3>Premium Feature</h3>\n * <p>Discover our exclusive features</p>\n * </SpotlightCard>\n */\nconst SpotlightCard = React.forwardRef<HTMLDivElement, SpotlightCardProps>(\n (\n {\n children,\n className,\n spotlightColor = \"rgba(255, 255, 255, 0.1)\",\n spotlightSize = 300,\n gradient = true,\n gradientFrom = \"rgba(255, 255, 255, 0.05)\",\n gradientTo = \"transparent\",\n style,\n ...props\n },\n ref\n ) => {\n const cardRef = useRef<HTMLDivElement>(null);\n const [mousePosition, setMousePosition] = useState({ x: 0, y: 0 });\n const [isHovered, setIsHovered] = useState(false);\n\n const handleMouseMove = useCallback(\n (e: React.MouseEvent<HTMLDivElement>) => {\n if (!cardRef.current) return;\n const rect = cardRef.current.getBoundingClientRect();\n setMousePosition({\n x: e.clientX - rect.left,\n y: e.clientY - rect.top,\n });\n },\n []\n );\n\n const spotlightStyle: React.CSSProperties = {\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n borderRadius: \"inherit\",\n opacity: isHovered ? 1 : 0,\n background: `radial-gradient(${spotlightSize}px circle at ${mousePosition.x}px ${mousePosition.y}px, ${spotlightColor}, transparent 60%)`,\n transition: \"opacity 0.4s ease\",\n pointerEvents: \"none\",\n };\n\n const gradientOverlayStyle: React.CSSProperties = gradient\n ? {\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n borderRadius: \"inherit\",\n background: `linear-gradient(135deg, ${gradientFrom} 0%, ${gradientTo} 100%)`,\n pointerEvents: \"none\",\n }\n : {};\n\n return (\n <div\n ref={mergeRefs(ref, cardRef)}\n className={merge(\n \"relative overflow-hidden rounded-xl\",\n \"bg-gray-900 border border-gray-800\",\n \"transition-all duration-300\",\n isHovered && \"border-gray-700 shadow-2xl shadow-black/20\",\n className\n )}\n style={style}\n onMouseMove={handleMouseMove}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n {...props}\n >\n {/* Gradient overlay */}\n {gradient && <div style={gradientOverlayStyle} aria-hidden=\"true\" />}\n\n {/* Spotlight effect */}\n <div style={spotlightStyle} aria-hidden=\"true\" />\n\n {/* Content */}\n <div className=\"relative z-10\">{children}</div>\n </div>\n );\n }\n);\n\nSpotlightCard.displayName = \"SpotlightCard\";\n\n// Utility to merge refs\nfunction mergeRefs<T>(...refs: (React.Ref<T> | undefined)[]): React.RefCallback<T> {\n return (value) => {\n refs.forEach((ref) => {\n if (typeof ref === \"function\") {\n ref(value);\n } else if (ref && typeof ref === \"object\") {\n (ref as React.MutableRefObject<T | null>).current = value;\n }\n });\n };\n}\n\nexport { SpotlightCard };\n","\"use client\";\n\nimport React, { useEffect, useState } from \"react\";\nimport { merge } from \"../../lib/utils\";\n\n/**\n * AnimatedGradient 컴포넌트의 props / AnimatedGradient component props\n * @property {string[]} [colors] - 그라디언트 색상 배열 / Array of gradient colors\n * @property {number} [speed=3] - 애니메이션 속도 (초) / Animation speed in seconds\n * @property {boolean} [blur=true] - 블러 효과 / Blur effect\n * @property {number} [blurAmount=100] - 블러 양 (px) / Blur amount in pixels\n * @property {\"linear\" | \"radial\" | \"conic\" | \"mesh\"} [type=\"mesh\"] - 그라디언트 타입 / Gradient type\n * @property {boolean} [animate=true] - 애니메이션 활성화 / Enable animation\n */\nexport interface AnimatedGradientProps extends React.HTMLAttributes<HTMLDivElement> {\n colors?: string[];\n speed?: number;\n blur?: boolean;\n blurAmount?: number;\n type?: \"linear\" | \"radial\" | \"conic\" | \"mesh\";\n animate?: boolean;\n}\n\nconst defaultColors = [\n \"#ff0080\",\n \"#7928ca\",\n \"#0070f3\",\n \"#00dfd8\",\n];\n\n/**\n * AnimatedGradient 컴포넌트 / AnimatedGradient component\n *\n * 아름다운 애니메이션 그라디언트 배경을 제공합니다.\n * 히어로 섹션, 배경, 오버레이에 적합합니다.\n *\n * Provides beautiful animated gradient backgrounds.\n * Perfect for hero sections, backgrounds, and overlays.\n *\n * @component\n * @example\n * // 메쉬 그라디언트 / Mesh gradient\n * <AnimatedGradient type=\"mesh\" className=\"absolute inset-0 -z-10\" />\n *\n * @example\n * // 커스텀 색상 / Custom colors\n * <AnimatedGradient\n * colors={[\"#667eea\", \"#764ba2\", \"#f093fb\"]}\n * speed={5}\n * type=\"conic\"\n * />\n */\nconst AnimatedGradient = React.forwardRef<HTMLDivElement, AnimatedGradientProps>(\n (\n {\n children,\n className,\n colors = defaultColors,\n speed = 3,\n blur = true,\n blurAmount = 100,\n type = \"mesh\",\n animate = true,\n style,\n ...props\n },\n ref\n ) => {\n const [mounted, setMounted] = useState(false);\n const prefersReducedMotion = useReducedMotion();\n const shouldAnimate = animate && !prefersReducedMotion;\n\n useEffect(() => {\n setMounted(true);\n }, []);\n\n const renderGradient = () => {\n switch (type) {\n case \"linear\":\n return (\n <div\n className=\"absolute inset-0\"\n style={{\n background: `linear-gradient(\n ${shouldAnimate ? \"var(--gradient-angle, 0deg)\" : \"135deg\"},\n ${colors.join(\", \")}\n )`,\n animation: shouldAnimate ? `gradient-rotate ${speed}s linear infinite` : undefined,\n }}\n />\n );\n\n case \"radial\":\n return (\n <div\n className=\"absolute inset-0\"\n style={{\n background: `radial-gradient(\n circle at ${shouldAnimate ? \"var(--gradient-x, 50%) var(--gradient-y, 50%)\" : \"50% 50%\"},\n ${colors.join(\", \")}\n )`,\n animation: shouldAnimate ? `gradient-move ${speed}s ease-in-out infinite` : undefined,\n }}\n />\n );\n\n case \"conic\":\n return (\n <div\n className=\"absolute inset-0\"\n style={{\n background: `conic-gradient(\n from ${shouldAnimate ? \"var(--gradient-angle, 0deg)\" : \"0deg\"} at 50% 50%,\n ${colors.join(\", \")},\n ${colors[0]}\n )`,\n animation: shouldAnimate ? `gradient-spin ${speed}s linear infinite` : undefined,\n }}\n />\n );\n\n case \"mesh\":\n default:\n // Render blobs only after mount to prevent SSR hydration mismatch\n // (Math.sin/cos produce floating-point values that differ between server and client)\n if (!mounted) return null;\n return (\n <>\n {colors.map((color, index) => {\n const angle = (360 / colors.length) * index;\n const delay = (speed / colors.length) * index;\n return (\n <div\n key={index}\n className=\"absolute rounded-full mix-blend-screen\"\n style={{\n width: \"60%\",\n height: \"60%\",\n background: `radial-gradient(circle at center, ${color} 0%, transparent 70%)`,\n top: `${30 + Math.sin((angle * Math.PI) / 180) * 20}%`,\n left: `${30 + Math.cos((angle * Math.PI) / 180) * 20}%`,\n animation: shouldAnimate\n ? `gradient-blob ${speed}s ease-in-out infinite`\n : undefined,\n animationDelay: shouldAnimate ? `${-delay}s` : undefined,\n }}\n />\n );\n })}\n </>\n );\n }\n };\n\n return (\n <div\n ref={ref}\n className={merge(\n \"relative overflow-hidden\",\n className\n )}\n style={style}\n {...props}\n >\n {/* Gradient layer */}\n <div\n className=\"absolute inset-0\"\n style={{\n filter: blur ? `blur(${blurAmount}px)` : undefined,\n }}\n >\n {renderGradient()}\n </div>\n\n {/* Content */}\n {children && <div className=\"relative z-10\">{children}</div>}\n\n {/* Animation keyframes - injected as style element */}\n <style dangerouslySetInnerHTML={{ __html: `\n @keyframes gradient-rotate {\n 0% { --gradient-angle: 0deg; }\n 100% { --gradient-angle: 360deg; }\n }\n @keyframes gradient-spin {\n 0% { transform: rotate(0deg); }\n 100% { transform: rotate(360deg); }\n }\n @keyframes gradient-move {\n 0%, 100% { --gradient-x: 0%; --gradient-y: 0%; }\n 25% { --gradient-x: 100%; --gradient-y: 0%; }\n 50% { --gradient-x: 100%; --gradient-y: 100%; }\n 75% { --gradient-x: 0%; --gradient-y: 100%; }\n }\n @keyframes gradient-blob {\n 0%, 100% { transform: translate(0, 0) scale(1); }\n 25% { transform: translate(20%, -20%) scale(1.1); }\n 50% { transform: translate(0, 20%) scale(0.9); }\n 75% { transform: translate(-20%, -10%) scale(1.05); }\n }\n `}} />\n </div>\n );\n }\n);\n\nAnimatedGradient.displayName = \"AnimatedGradient\";\n\n// Hook to check for reduced motion preference\nfunction useReducedMotion(): boolean {\n const [prefersReducedMotion, setPrefersReducedMotion] = useState(false);\n\n useEffect(() => {\n const mediaQuery = window.matchMedia(\"(prefers-reduced-motion: reduce)\");\n setPrefersReducedMotion(mediaQuery.matches);\n\n const handleChange = (e: MediaQueryListEvent) => {\n setPrefersReducedMotion(e.matches);\n };\n\n mediaQuery.addEventListener(\"change\", handleChange);\n return () => mediaQuery.removeEventListener(\"change\", handleChange);\n }, []);\n\n return prefersReducedMotion;\n}\n\nexport { AnimatedGradient };\n","\"use client\";\n\nimport React, { useRef, useState, useCallback, useEffect } from \"react\";\nimport { merge } from \"../../lib/utils\";\n\n/**\n * Carousel 컴포넌트의 props / Carousel component props\n * @property {boolean} [autoPlay=false] - 자동 재생 / Auto play\n * @property {number} [interval=5000] - 자동 재생 간격 (ms) / Auto play interval\n * @property {boolean} [loop=true] - 무한 루프 / Infinite loop\n * @property {boolean} [pauseOnHover=true] - 호버시 일시정지 / Pause on hover\n * @property {\"dots\" | \"bars\" | \"numbers\" | \"none\"} [indicators=\"dots\"] - 인디케이터 타입 / Indicator type\n * @property {\"bottom\" | \"top\" | \"inside-bottom\" | \"inside-top\"} [indicatorPosition=\"bottom\"] - 인디케이터 위치 / Indicator position\n * @property {boolean} [showArrows=true] - 화살표 버튼 표시 / Show arrow buttons\n * @property {\"inside\" | \"outside\" | \"hidden\"} [arrowPosition=\"inside\"] - 화살표 위치 / Arrow position\n * @property {\"slide\" | \"fade\" | \"scale\"} [transition=\"slide\"] - 전환 효과 / Transition effect\n * @property {number} [transitionDuration=500] - 전환 시간 (ms) / Transition duration\n * @property {(index: number) => void} [onSlideChange] - 슬라이드 변경 콜백 / Slide change callback\n * @property {boolean} [showPlayPause=false] - 재생/일시정지 버튼 표시 / Show play/pause button\n * @property {\"left\" | \"right\" | \"center\"} [playPausePosition=\"right\"] - 재생/일시정지 버튼 위치 / Play/pause button position\n */\nexport interface CarouselProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'children'> {\n children: React.ReactNode[];\n autoPlay?: boolean;\n interval?: number;\n loop?: boolean;\n pauseOnHover?: boolean;\n indicators?: \"dots\" | \"bars\" | \"numbers\" | \"none\";\n indicatorPosition?: \"bottom\" | \"top\" | \"inside-bottom\" | \"inside-top\";\n showArrows?: boolean;\n arrowPosition?: \"inside\" | \"outside\" | \"hidden\";\n transition?: \"slide\" | \"fade\" | \"scale\";\n transitionDuration?: number;\n onSlideChange?: (index: number) => void;\n showPlayPause?: boolean;\n playPausePosition?: \"left\" | \"right\" | \"center\";\n}\n\n/**\n * Carousel 컴포넌트 / Carousel component\n *\n * 슬라이드 캐러셀 컴포넌트입니다.\n * 다양한 인디케이터, 화살표, 전환 효과를 지원합니다.\n *\n * Slide carousel component.\n * Supports various indicators, arrows, and transition effects.\n *\n * @component\n * @example\n * <Carousel autoPlay interval={3000} indicators=\"bars\">\n * <img src=\"/slide1.jpg\" alt=\"Slide 1\" />\n * <img src=\"/slide2.jpg\" alt=\"Slide 2\" />\n * <img src=\"/slide3.jpg\" alt=\"Slide 3\" />\n * </Carousel>\n */\nconst Carousel = React.forwardRef<HTMLDivElement, CarouselProps>(\n (\n {\n children,\n autoPlay = false,\n interval = 5000,\n loop = true,\n pauseOnHover = true,\n indicators = \"dots\",\n indicatorPosition = \"bottom\",\n showArrows = true,\n arrowPosition = \"inside\",\n transition = \"slide\",\n transitionDuration = 500,\n onSlideChange,\n showPlayPause = false,\n playPausePosition = \"right\",\n className,\n style,\n ...props\n },\n ref\n ) => {\n // For slide transition with loop: start at 1 (account for cloned first slide)\n // For fade/scale: always start at 0 (no cloned slides)\n const getInitialIndex = () => {\n if (transition === \"slide\" && loop) return 1;\n return 0;\n };\n const [currentIndex, setCurrentIndex] = useState(getInitialIndex);\n const [isPaused, setIsPaused] = useState(!autoPlay);\n const [isManuallyPaused, setIsManuallyPaused] = useState(false);\n const [isTransitioning, setIsTransitioning] = useState(false);\n const [noTransition, setNoTransition] = useState(false);\n const [touchStart, setTouchStart] = useState<number | null>(null);\n const [touchEnd, setTouchEnd] = useState<number | null>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n const slideCount = React.Children.count(children);\n\n // Check for reduced motion preference\n const prefersReducedMotion = useReducedMotion();\n\n // Get actual slide index for display (accounting for cloned slides in loop mode for slide transition)\n const getActualIndex = useCallback((index: number) => {\n // For fade/scale transitions, currentIndex is the actual index\n if (transition !== \"slide\") return index;\n // For slide transition without loop, index is actual\n if (!loop) return index;\n // For slide transition with loop, account for cloned slides\n if (index === 0) return slideCount - 1;\n if (index === slideCount + 1) return 0;\n return index - 1;\n }, [loop, slideCount, transition]);\n\n // Go to specific slide\n const goToSlide = useCallback(\n (index: number) => {\n if (isTransitioning) return;\n\n let newIndex = index;\n if (!loop) {\n newIndex = Math.max(0, Math.min(index, slideCount - 1));\n } else if (transition !== \"slide\") {\n // For fade/scale with loop, wrap around without cloned slides\n if (index < 0) {\n newIndex = slideCount - 1;\n } else if (index >= slideCount) {\n newIndex = 0;\n }\n }\n\n if (newIndex !== currentIndex) {\n setIsTransitioning(true);\n setCurrentIndex(newIndex);\n const actualIndex = loop && transition === \"slide\"\n ? (newIndex === 0 ? slideCount - 1 : newIndex === slideCount + 1 ? 0 : newIndex - 1)\n : newIndex;\n onSlideChange?.(actualIndex);\n setTimeout(() => setIsTransitioning(false), transitionDuration);\n }\n },\n [currentIndex, slideCount, loop, isTransitioning, transitionDuration, transition, onSlideChange]\n );\n\n // Handle infinite loop jump (when reaching cloned slides)\n useEffect(() => {\n if (!loop || isTransitioning || transition !== \"slide\") return;\n\n // Jump to real slide without animation when on cloned slides\n if (currentIndex === 0) {\n // At cloned last slide -> jump to real last slide\n setTimeout(() => {\n setNoTransition(true);\n setCurrentIndex(slideCount);\n setTimeout(() => setNoTransition(false), 50);\n }, transitionDuration);\n } else if (currentIndex === slideCount + 1) {\n // At cloned first slide -> jump to real first slide\n setTimeout(() => {\n setNoTransition(true);\n setCurrentIndex(1);\n setTimeout(() => setNoTransition(false), 50);\n }, transitionDuration);\n }\n }, [currentIndex, slideCount, loop, isTransitioning, transitionDuration, transition]);\n\n // Next slide\n const nextSlide = useCallback(() => {\n goToSlide(currentIndex + 1);\n }, [currentIndex, goToSlide]);\n\n // Previous slide\n const prevSlide = useCallback(() => {\n goToSlide(currentIndex - 1);\n }, [currentIndex, goToSlide]);\n\n // Toggle play/pause manually\n const togglePlayPause = useCallback(() => {\n setIsManuallyPaused(prev => !prev);\n }, []);\n\n // Play function\n const play = useCallback(() => {\n setIsManuallyPaused(false);\n }, []);\n\n // Pause function\n const pause = useCallback(() => {\n setIsManuallyPaused(true);\n }, []);\n\n // Auto play\n useEffect(() => {\n if (!autoPlay || isPaused || isManuallyPaused || prefersReducedMotion) return;\n\n const timer = setInterval(nextSlide, interval);\n return () => clearInterval(timer);\n }, [autoPlay, interval, isPaused, isManuallyPaused, nextSlide, prefersReducedMotion]);\n\n // Touch handlers for swipe\n const handleTouchStart = (e: React.TouchEvent) => {\n setTouchStart(e.targetTouches[0].clientX);\n };\n\n const handleTouchMove = (e: React.TouchEvent) => {\n setTouchEnd(e.targetTouches[0].clientX);\n };\n\n const handleTouchEnd = () => {\n if (!touchStart || !touchEnd) return;\n\n const distance = touchStart - touchEnd;\n const minSwipeDistance = 50;\n\n if (Math.abs(distance) >= minSwipeDistance) {\n if (distance > 0) {\n nextSlide();\n } else {\n prevSlide();\n }\n }\n\n setTouchStart(null);\n setTouchEnd(null);\n };\n\n // Keyboard navigation\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === \"ArrowLeft\") {\n prevSlide();\n } else if (e.key === \"ArrowRight\") {\n nextSlide();\n }\n };\n\n const container = containerRef.current;\n container?.addEventListener(\"keydown\", handleKeyDown);\n return () => container?.removeEventListener(\"keydown\", handleKeyDown);\n }, [nextSlide, prevSlide]);\n\n // Render slides with transition\n const renderSlides = () => {\n const duration = prefersReducedMotion || noTransition ? 0 : transitionDuration;\n const actualIndex = getActualIndex(currentIndex);\n\n switch (transition) {\n case \"fade\":\n return React.Children.map(children, (child, index) => (\n <div\n key={index}\n className={merge(\n \"absolute inset-0 w-full h-full\",\n index === actualIndex ? \"z-10\" : \"z-0\"\n )}\n style={{\n opacity: index === actualIndex ? 1 : 0,\n transition: `opacity ${duration}ms ease-in-out`,\n }}\n >\n {child}\n </div>\n ));\n\n case \"scale\":\n return React.Children.map(children, (child, index) => (\n <div\n key={index}\n className={merge(\n \"absolute inset-0 w-full h-full\",\n index === actualIndex ? \"z-10\" : \"z-0\"\n )}\n style={{\n opacity: index === actualIndex ? 1 : 0,\n transform: `scale(${index === actualIndex ? 1 : 0.9})`,\n transition: `opacity ${duration}ms ease-in-out, transform ${duration}ms ease-in-out`,\n }}\n >\n {child}\n </div>\n ));\n\n case \"slide\":\n default: {\n const childArray = React.Children.toArray(children);\n // For infinite loop: clone last slide at beginning and first slide at end\n const slides = loop\n ? [childArray[childArray.length - 1], ...childArray, childArray[0]]\n : childArray;\n\n // 각 슬라이드를 fade/scale처럼 absolute로 배치하고 translateX로 위치 조정\n return slides.map((child, index) => (\n <div\n key={index}\n className=\"absolute inset-0 w-full h-full\"\n style={{\n transform: `translateX(${(index - currentIndex) * 100}%)`,\n transition: noTransition ? 'none' : `transform ${duration}ms ease-in-out`,\n }}\n >\n {child}\n </div>\n ));\n }\n }\n };\n\n // Render indicators\n const renderIndicators = () => {\n if (indicators === \"none\") return null;\n\n const isInside = indicatorPosition.includes(\"inside\");\n const isTop = indicatorPosition.includes(\"top\");\n const actualIndex = getActualIndex(currentIndex);\n\n const indicatorContainerClass = merge(\n \"flex items-center justify-center gap-2\",\n isInside\n ? merge(\n \"absolute left-1/2 -translate-x-1/2 z-20\",\n isTop ? \"top-4\" : \"bottom-4\"\n )\n : merge(\n \"mt-4\",\n isTop && \"order-first mb-4 mt-0\"\n )\n );\n\n // Handle indicator click - go to the correct index accounting for loop mode\n const handleIndicatorClick = (index: number) => {\n if (loop && transition === \"slide\") {\n goToSlide(index + 1); // +1 because of cloned first slide (only for slide transition)\n } else {\n goToSlide(index);\n }\n };\n\n return (\n <div className={indicatorContainerClass} role=\"tablist\">\n {Array.from({ length: slideCount }, (_, index) => {\n const isActive = index === actualIndex;\n\n switch (indicators) {\n case \"bars\":\n return (\n <button\n key={index}\n onClick={() => handleIndicatorClick(index)}\n className={merge(\n \"h-1 rounded-full transition-all duration-300\",\n isActive\n ? \"w-8 bg-white\"\n : \"w-4 bg-white/50 hover:bg-white/70\"\n )}\n role=\"tab\"\n aria-selected={isActive}\n aria-label={`슬라이드 ${index + 1}`}\n />\n );\n\n case \"numbers\":\n return (\n <button\n key={index}\n onClick={() => handleIndicatorClick(index)}\n className={merge(\n \"w-8 h-8 rounded-full text-sm font-medium transition-all duration-300\",\n isActive\n ? \"bg-white text-gray-900\"\n : \"bg-white/30 text-white hover:bg-white/50\"\n )}\n role=\"tab\"\n aria-selected={isActive}\n aria-label={`슬라이드 ${index + 1}`}\n >\n {index + 1}\n </button>\n );\n\n case \"dots\":\n default:\n return (\n <button\n key={index}\n onClick={() => handleIndicatorClick(index)}\n className={merge(\n \"w-2.5 h-2.5 rounded-full transition-all duration-300\",\n isActive\n ? \"bg-white scale-125\"\n : \"bg-white/50 hover:bg-white/70\"\n )}\n role=\"tab\"\n aria-selected={isActive}\n aria-label={`슬라이드 ${index + 1}`}\n />\n );\n }\n })}\n </div>\n );\n };\n\n // Render play/pause button\n const renderPlayPause = () => {\n if (!showPlayPause || !autoPlay) return null;\n\n const isPlaying = !isManuallyPaused;\n const positionClasses = {\n left: \"left-4\",\n center: \"left-1/2 -translate-x-1/2\",\n right: \"right-4\"\n };\n\n return (\n <button\n onClick={togglePlayPause}\n className={merge(\n \"absolute bottom-4 z-20\",\n \"w-8 h-8 rounded-full flex items-center justify-center\",\n \"bg-white/80 hover:bg-white text-gray-800\",\n \"transition-all duration-200\",\n \"focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-white\",\n positionClasses[playPausePosition]\n )}\n aria-label={isPlaying ? \"일시정지\" : \"재생\"}\n >\n {isPlaying ? <PauseIcon className=\"w-4 h-4\" /> : <PlayIcon className=\"w-4 h-4\" />}\n </button>\n );\n };\n\n // Render arrows\n const renderArrows = () => {\n if (!showArrows || arrowPosition === \"hidden\") return null;\n\n const canGoPrev = loop || currentIndex > 0;\n const canGoNext = loop || currentIndex < slideCount - 1;\n\n const arrowBaseClass = merge(\n \"absolute top-1/2 -translate-y-1/2 z-20\",\n \"w-10 h-10 rounded-full flex items-center justify-center\",\n \"bg-white/80 hover:bg-white text-gray-800\",\n \"transition-all duration-200\",\n \"disabled:opacity-30 disabled:cursor-not-allowed\",\n \"focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-white\"\n );\n\n const prevPosition = arrowPosition === \"outside\" ? \"-left-14\" : \"left-4\";\n const nextPosition = arrowPosition === \"outside\" ? \"-right-14\" : \"right-4\";\n\n return (\n <>\n <button\n onClick={prevSlide}\n disabled={!canGoPrev}\n className={merge(arrowBaseClass, prevPosition)}\n aria-label=\"이전 슬라이드\"\n >\n <ChevronLeft className=\"w-5 h-5\" />\n </button>\n <button\n onClick={nextSlide}\n disabled={!canGoNext}\n className={merge(arrowBaseClass, nextPosition)}\n aria-label=\"다음 슬라이드\"\n >\n <ChevronRight className=\"w-5 h-5\" />\n </button>\n </>\n );\n };\n\n return (\n <div\n ref={ref}\n className={merge(\n \"flex flex-col w-full h-full\",\n arrowPosition === \"outside\" && \"px-16\",\n className\n )}\n style={style}\n {...props}\n >\n <div\n ref={containerRef}\n className=\"relative overflow-hidden w-full flex-1\"\n onMouseEnter={() => pauseOnHover && setIsPaused(true)}\n onMouseLeave={() => pauseOnHover && setIsPaused(false)}\n onTouchStart={handleTouchStart}\n onTouchMove={handleTouchMove}\n onTouchEnd={handleTouchEnd}\n tabIndex={0}\n role=\"region\"\n aria-roledescription=\"carousel\"\n aria-label=\"이미지 슬라이더\"\n >\n {renderSlides()}\n {renderArrows()}\n {renderPlayPause()}\n {indicatorPosition.includes(\"inside\") && renderIndicators()}\n </div>\n {!indicatorPosition.includes(\"inside\") && renderIndicators()}\n </div>\n );\n }\n);\n\nCarousel.displayName = \"Carousel\";\n\n// Hook to check for reduced motion preference\nfunction useReducedMotion(): boolean {\n const [prefersReducedMotion, setPrefersReducedMotion] = useState(false);\n\n useEffect(() => {\n const mediaQuery = window.matchMedia(\"(prefers-reduced-motion: reduce)\");\n setPrefersReducedMotion(mediaQuery.matches);\n\n const handleChange = (e: MediaQueryListEvent) => {\n setPrefersReducedMotion(e.matches);\n };\n\n mediaQuery.addEventListener(\"change\", handleChange);\n return () => mediaQuery.removeEventListener(\"change\", handleChange);\n }, []);\n\n return prefersReducedMotion;\n}\n\n// Simple icon components\nfunction ChevronLeft({ className }: { className?: string }) {\n return (\n <svg className={className} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M15 19l-7-7 7-7\" />\n </svg>\n );\n}\n\nfunction ChevronRight({ className }: { className?: string }) {\n return (\n <svg className={className} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M9 5l7 7-7 7\" />\n </svg>\n );\n}\n\nfunction PlayIcon({ className }: { className?: string }) {\n return (\n <svg className={className} fill=\"currentColor\" viewBox=\"0 0 24 24\">\n <path d=\"M8 5v14l11-7z\" />\n </svg>\n );\n}\n\nfunction PauseIcon({ className }: { className?: string }) {\n return (\n <svg className={className} fill=\"currentColor\" viewBox=\"0 0 24 24\">\n <path d=\"M6 4h4v16H6V4zm8 0h4v16h-4V4z\" />\n </svg>\n );\n}\n\nexport { Carousel };\n"]}
@@ -0,0 +1,3 @@
1
+ "use client";
2
+ import {b}from'./chunk-U6CTBZ2U.mjs';var K={50:"50",100:"100",200:"200",300:"300",400:"400",500:"500",600:"600",700:"700",800:"800",900:"900"};function o(t,r,e=""){return `${e}${t}-${K[r]}`}function d(t,r){return `${t} dark:${r}`}var n={default:{border:{light:200,dark:700},background:{light:50,dark:900,opacity:"50"}},outline:{border:{light:300,dark:600},background:"transparent",text:{light:600,dark:400}},elevated:{border:{light:200,dark:700},background:{light:"white",dark:"gray-800"},shadow:"lg"},icon:{background:{light:100,dark:900,opacity:"30"},text:{light:600,dark:400}},badge:{background:{light:50,dark:900,opacity:"30"},text:{light:700,dark:300}}},U={from:500,to:600,border:{light:400,dark:500}};function j(t,r){var g,s,u,c,b$1,h,k,p,x,S,y,C,f,$,m;let e={default:(r==null?void 0:r.default)||n.default,gradient:(r==null?void 0:r.gradient)||U,outline:(r==null?void 0:r.outline)||n.outline,elevated:(r==null?void 0:r.elevated)||n.elevated,icon:(r==null?void 0:r.icon)||n.icon,badge:(r==null?void 0:r.badge)||n.badge},l=(g=e.default)!=null&&g.border?d(`border-${o(t,e.default.border.light)}`,`border-${o(t,e.default.border.dark||e.default.border.light)}`):"",v=(s=e.default)!=null&&s.background?d(`bg-${o(t,e.default.background.light)}${e.default.background.opacity?`/${e.default.background.opacity}`:""}`,`bg-${o(t,e.default.background.dark||e.default.background.light)}${e.default.background.opacity?`/${e.default.background.opacity}`:""}`):"",w=b(l,v),z=(u=e.gradient)!=null&&u.from?`from-${o(t,e.gradient.from)}`:"",B=(c=e.gradient)!=null&&c.to?`to-${o(t,e.gradient.to)}`:"",M=(b$1=e.gradient)!=null&&b$1.border?d(`border-${o(t,e.gradient.border.light)}`,`border-${o(t,e.gradient.border.dark||e.gradient.border.light)}`):"",R=b("bg-gradient-to-br",z,B,M),E=(h=e.outline)!=null&&h.border?`border-2 ${d(`border-${o(t,e.outline.border.light)}`,`border-${o(t,e.outline.border.dark||e.outline.border.light)}`)}`:"",_=((k=e.outline)==null?void 0:k.background)||"bg-transparent",H=(p=e.outline)!=null&&p.text?d(`text-${o(t,e.outline.text.light)}`,`text-${o(t,e.outline.text.dark||e.outline.text.light)}`):"",T=b(E,_,H),N=(x=e.elevated)!=null&&x.border?d(`border-${o(t,e.elevated.border.light)}`,`border-${o(t,e.elevated.border.dark||e.elevated.border.light)}`):"",P=(S=e.elevated)!=null&&S.background?d(`bg-${e.elevated.background.light}`,`bg-${e.elevated.background.dark}`):"",V=(y=e.elevated)!=null&&y.shadow?`shadow-${e.elevated.shadow}`:"",A=b(N,P,V),G=(C=e.icon)!=null&&C.background?d(`bg-${o(t,e.icon.background.light)}${e.icon.background.opacity?`/${e.icon.background.opacity}`:""}`,`bg-${o(t,e.icon.background.dark||e.icon.background.light)}${e.icon.background.opacity?`/${e.icon.background.opacity}`:""}`):"",I=(f=e.icon)!=null&&f.text?d(`text-${o(t,e.icon.text.light)}`,`text-${o(t,e.icon.text.dark||e.icon.text.light)}`):"",O=b(G,I),D=($=e.badge)!=null&&$.background?d(`bg-${o(t,e.badge.background.light)}${e.badge.background.opacity?`/${e.badge.background.opacity}`:""}`,`bg-${o(t,e.badge.background.dark||e.badge.background.light)}${e.badge.background.opacity?`/${e.badge.background.opacity}`:""}`):"",F=(m=e.badge)!=null&&m.text?d(`text-${o(t,e.badge.text.light)}`,`text-${o(t,e.badge.text.dark||e.badge.text.light)}`):"",J=b(D,F);return {default:w,gradient:R,outline:T,elevated:A,icon:O,badge:J}}var i=new Map;function L(t,r){let e=`${t}-${JSON.stringify(r||{})}`;return i.has(e)||i.set(e,j(t,r)),i.get(e)}function X(t,r){let e="rounded-2xl border transition-all duration-200";switch(t){case "default":return b(e,r.default);case "gradient":return b(e,"text-white",r.gradient);case "outline":return b(e,r.outline);case "elevated":return b(e,r.elevated);default:return e}}function Y(t="md"){return {sm:{container:"p-4",icon:"h-4 w-4",iconContainer:"w-8 h-8",text:"text-xs",title:"text-xs",description:"text-xs"},md:{container:"p-6",icon:"h-6 w-6",iconContainer:"w-12 h-12",text:"text-base",title:"text-sm",description:"text-sm"},lg:{container:"p-8",icon:"h-8 w-8",iconContainer:"w-16 h-16",text:"text-lg",title:"text-base",description:"text-base"},xl:{container:"p-10",icon:"h-10 w-10",iconContainer:"w-20 h-20",text:"text-xl",title:"text-lg",description:"text-lg"}}[t]}function Z(t="md"){return {sm:"rounded",md:"rounded-md",lg:"rounded-lg",xl:"rounded-xl",full:"rounded-full",none:"rounded-none"}[t]}function ee(t="md"){return t==="none"?"":`shadow-${t}`}var te="cubic-bezier(0.34, 1.56, 0.64, 1)";function re(t="springy",r=false){if(r||t==="none")return "";let e="[transition:transform_180ms_cubic-bezier(0.34,1.56,0.64,1),box-shadow_200ms_ease-out]";return {springy:`hover:scale-[1.015] hover:shadow-md active:scale-[0.985] ${e} 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 ${e} transform-gpu`,none:""}[t]}export{j as a,L as b,X as c,Y as d,Z as e,ee as f,te as g,re as h};//# sourceMappingURL=chunk-MDLCJASB.mjs.map
3
+ //# sourceMappingURL=chunk-MDLCJASB.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/lib/styles/colors.ts","../src/lib/styles/variants.ts"],"names":["colorShades","colorClass","color","shade","prefix","withDarkMode","lightClass","darkClass","defaultColorConfig","gradientConfig","createColorStyles","config","_a","_b","_c","_d","_e","_f","_g","_h","_i","_j","_k","_l","_m","_n","_o","finalConfig","defaultBorder","defaultBg","defaultStyle","merge","gradientFrom","gradientTo","gradientBorder","gradientStyle","outlineBorder","outlineBg","outlineText","outlineStyle","elevatedBorder","elevatedBg","elevatedShadow","elevatedStyle","iconBg","iconText","iconStyle","badgeBg","badgeText","badgeStyle","colorStylesCache","useColorStyles","cacheKey","createVariantStyles","variant","colorStyles","baseClasses","createSizeStyles","size","createRoundedStyles","rounded","createShadowStyles","shadow","HUA_SPRING_EASING","createHoverStyles","hover","reducedMotion","springTransition"],"mappings":"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","file":"chunk-LH77I6HO.mjs","sourcesContent":["/**\n * HUA UI 공통 색상 시스템\n * 중앙화된 색상 팔레트와 스타일 생성 유틸리티\n */\n\nimport type { Color } from \"../types/common\";\nimport { merge } from \"../utils\";\n\n/**\n * Tailwind CSS 색상 클래스 매핑\n * 각 색상의 50-900 단계를 정의합니다.\n */\nconst colorShades = {\n 50: \"50\",\n 100: \"100\",\n 200: \"200\",\n 300: \"300\",\n 400: \"400\",\n 500: \"500\",\n 600: \"600\",\n 700: \"700\",\n 800: \"800\",\n 900: \"900\",\n} as const;\n\ntype ColorShade = keyof typeof colorShades;\n\n/**\n * 색상별 클래스 생성 헬퍼\n */\nfunction colorClass(color: Color, shade: ColorShade, prefix: string = \"\"): string {\n return `${prefix}${color}-${colorShades[shade]}`;\n}\n\n/**\n * 다크 모드 지원 클래스 생성\n */\nfunction withDarkMode(lightClass: string, darkClass: string): string {\n return `${lightClass} dark:${darkClass}`;\n}\n\n/**\n * 색상 스타일 설정 인터페이스\n */\nexport interface ColorStyleConfig {\n /** 기본 variant 스타일 */\n default?: {\n border?: { light: ColorShade; dark?: ColorShade };\n background?: { light: ColorShade; dark?: ColorShade; opacity?: string };\n };\n /** 그라데이션 variant 스타일 */\n gradient?: {\n from?: ColorShade;\n to?: ColorShade;\n border?: { light: ColorShade; dark?: ColorShade };\n };\n /** 아웃라인 variant 스타일 */\n outline?: {\n border?: { light: ColorShade; dark?: ColorShade };\n background?: string;\n text?: { light: ColorShade; dark?: ColorShade };\n };\n /** Elevated variant 스타일 */\n elevated?: {\n border?: { light: ColorShade; dark?: ColorShade };\n background?: { light: string; dark: string };\n shadow?: string;\n };\n /** 아이콘 스타일 */\n icon?: {\n background?: { light: ColorShade; dark?: ColorShade; opacity?: string };\n text?: { light: ColorShade; dark?: ColorShade };\n };\n /** 배지 스타일 */\n badge?: {\n background?: { light: ColorShade; dark?: ColorShade; opacity?: string };\n text?: { light: ColorShade; dark?: ColorShade };\n };\n}\n\n/**\n * 생성된 색상 스타일 인터페이스\n */\nexport interface ColorStyles {\n default: string;\n gradient: string;\n outline: string;\n elevated: string;\n icon: string;\n badge: string;\n}\n\n/**\n * 기본 색상 스타일 설정\n * 각 색상에 대한 기본 스타일 템플릿\n */\nconst defaultColorConfig: Omit<ColorStyleConfig, \"gradient\"> = {\n default: {\n border: { light: 200, dark: 700 },\n background: { light: 50, dark: 900, opacity: \"50\" },\n },\n outline: {\n border: { light: 300, dark: 600 },\n background: \"transparent\",\n text: { light: 600, dark: 400 },\n },\n elevated: {\n border: { light: 200, dark: 700 },\n background: { light: \"white\", dark: \"gray-800\" },\n shadow: \"lg\",\n },\n icon: {\n background: { light: 100, dark: 900, opacity: \"30\" },\n text: { light: 600, dark: 400 },\n },\n badge: {\n background: { light: 50, dark: 900, opacity: \"30\" },\n text: { light: 700, dark: 300 },\n },\n};\n\n/**\n * 그라데이션 스타일 설정\n */\nconst gradientConfig: ColorStyleConfig[\"gradient\"] = {\n from: 500,\n to: 600,\n border: { light: 400, dark: 500 },\n};\n\n/**\n * 색상 스타일 생성 함수\n * \n * @param color - 색상 이름\n * @param config - 커스텀 스타일 설정 (선택사항)\n * @returns 생성된 색상 스타일 객체\n * \n * @example\n * ```tsx\n * const styles = createColorStyles(\"blue\");\n * // styles.default, styles.gradient, styles.outline 등 사용 가능\n * ```\n */\nexport function createColorStyles(\n color: Color,\n config?: Partial<ColorStyleConfig>\n): ColorStyles {\n const finalConfig: ColorStyleConfig = {\n default: config?.default || defaultColorConfig.default,\n gradient: config?.gradient || gradientConfig,\n outline: config?.outline || defaultColorConfig.outline,\n elevated: config?.elevated || defaultColorConfig.elevated,\n icon: config?.icon || defaultColorConfig.icon,\n badge: config?.badge || defaultColorConfig.badge,\n };\n\n // Default variant\n const defaultBorder = finalConfig.default?.border\n ? withDarkMode(\n `border-${colorClass(color, finalConfig.default.border.light)}`,\n `border-${colorClass(color, finalConfig.default.border.dark || finalConfig.default.border.light)}`\n )\n : \"\";\n \n const defaultBg = finalConfig.default?.background\n ? withDarkMode(\n `bg-${colorClass(color, finalConfig.default.background.light)}${finalConfig.default.background.opacity ? `/${finalConfig.default.background.opacity}` : \"\"}`,\n `bg-${colorClass(color, finalConfig.default.background.dark || finalConfig.default.background.light)}${finalConfig.default.background.opacity ? `/${finalConfig.default.background.opacity}` : \"\"}`\n )\n : \"\";\n\n const defaultStyle = merge(defaultBorder, defaultBg);\n\n // Gradient variant\n const gradientFrom = finalConfig.gradient?.from\n ? `from-${colorClass(color, finalConfig.gradient.from)}`\n : \"\";\n const gradientTo = finalConfig.gradient?.to\n ? `to-${colorClass(color, finalConfig.gradient.to)}`\n : \"\";\n const gradientBorder = finalConfig.gradient?.border\n ? withDarkMode(\n `border-${colorClass(color, finalConfig.gradient.border.light)}`,\n `border-${colorClass(color, finalConfig.gradient.border.dark || finalConfig.gradient.border.light)}`\n )\n : \"\";\n \n const gradientStyle = merge(\n \"bg-gradient-to-br\",\n gradientFrom,\n gradientTo,\n gradientBorder\n );\n\n // Outline variant\n const outlineBorder = finalConfig.outline?.border\n ? `border-2 ${withDarkMode(\n `border-${colorClass(color, finalConfig.outline.border.light)}`,\n `border-${colorClass(color, finalConfig.outline.border.dark || finalConfig.outline.border.light)}`\n )}`\n : \"\";\n const outlineBg = finalConfig.outline?.background || \"bg-transparent\";\n const outlineText = finalConfig.outline?.text\n ? withDarkMode(\n `text-${colorClass(color, finalConfig.outline.text.light)}`,\n `text-${colorClass(color, finalConfig.outline.text.dark || finalConfig.outline.text.light)}`\n )\n : \"\";\n \n const outlineStyle = merge(outlineBorder, outlineBg, outlineText);\n\n // Elevated variant\n const elevatedBorder = finalConfig.elevated?.border\n ? withDarkMode(\n `border-${colorClass(color, finalConfig.elevated.border.light)}`,\n `border-${colorClass(color, finalConfig.elevated.border.dark || finalConfig.elevated.border.light)}`\n )\n : \"\";\n const elevatedBg = finalConfig.elevated?.background\n ? withDarkMode(\n `bg-${finalConfig.elevated.background.light}`,\n `bg-${finalConfig.elevated.background.dark}`\n )\n : \"\";\n const elevatedShadow = finalConfig.elevated?.shadow\n ? `shadow-${finalConfig.elevated.shadow}`\n : \"\";\n \n const elevatedStyle = merge(elevatedBorder, elevatedBg, elevatedShadow);\n\n // Icon style\n const iconBg = finalConfig.icon?.background\n ? withDarkMode(\n `bg-${colorClass(color, finalConfig.icon.background.light)}${finalConfig.icon.background.opacity ? `/${finalConfig.icon.background.opacity}` : \"\"}`,\n `bg-${colorClass(color, finalConfig.icon.background.dark || finalConfig.icon.background.light)}${finalConfig.icon.background.opacity ? `/${finalConfig.icon.background.opacity}` : \"\"}`\n )\n : \"\";\n const iconText = finalConfig.icon?.text\n ? withDarkMode(\n `text-${colorClass(color, finalConfig.icon.text.light)}`,\n `text-${colorClass(color, finalConfig.icon.text.dark || finalConfig.icon.text.light)}`\n )\n : \"\";\n \n const iconStyle = merge(iconBg, iconText);\n\n // Badge style\n const badgeBg = finalConfig.badge?.background\n ? withDarkMode(\n `bg-${colorClass(color, finalConfig.badge.background.light)}${finalConfig.badge.background.opacity ? `/${finalConfig.badge.background.opacity}` : \"\"}`,\n `bg-${colorClass(color, finalConfig.badge.background.dark || finalConfig.badge.background.light)}${finalConfig.badge.background.opacity ? `/${finalConfig.badge.background.opacity}` : \"\"}`\n )\n : \"\";\n const badgeText = finalConfig.badge?.text\n ? withDarkMode(\n `text-${colorClass(color, finalConfig.badge.text.light)}`,\n `text-${colorClass(color, finalConfig.badge.text.dark || finalConfig.badge.text.light)}`\n )\n : \"\";\n \n const badgeStyle = merge(badgeBg, badgeText);\n\n return {\n default: defaultStyle,\n gradient: gradientStyle,\n outline: outlineStyle,\n elevated: elevatedStyle,\n icon: iconStyle,\n badge: badgeStyle,\n };\n}\n\n/**\n * 색상 스타일 캐시\n * 동일한 색상과 설정에 대해 재사용하여 성능 최적화\n */\nconst colorStylesCache = new Map<string, ColorStyles>();\n\n/**\n * 메모이제이션된 색상 스타일 생성 함수\n * \n * @param color - 색상 이름\n * @param config - 커스텀 스타일 설정 (선택사항)\n * @returns 생성된 색상 스타일 객체\n */\nexport function useColorStyles(\n color: Color,\n config?: Partial<ColorStyleConfig>\n): ColorStyles {\n const cacheKey = `${color}-${JSON.stringify(config || {})}`;\n \n if (!colorStylesCache.has(cacheKey)) {\n colorStylesCache.set(cacheKey, createColorStyles(color, config));\n }\n \n return colorStylesCache.get(cacheKey)!;\n}\n\n","/**\n * HUA UI 공통 Variant 시스템\n * 컴포넌트 variant 스타일 생성 유틸리티\n */\n\nimport type { ExtendedVariant, Size } from \"../types/common\";\nimport type { ColorStyles } from \"./colors\";\nimport { merge } from \"../utils\";\n\n/**\n * Variant 스타일 생성 함수\n * \n * @param variant - Variant 타입\n * @param colorStyles - 색상 스타일 객체\n * @returns 생성된 variant 클래스 문자열\n * \n * @example\n * ```tsx\n * const colorStyles = useColorStyles(\"blue\");\n * const variantClass = createVariantStyles(\"elevated\", colorStyles);\n * ```\n */\nexport function createVariantStyles(\n variant: ExtendedVariant,\n colorStyles: ColorStyles\n): string {\n const baseClasses = \"rounded-2xl border transition-all duration-200\";\n \n switch (variant) {\n case \"default\":\n return merge(baseClasses, colorStyles.default);\n \n case \"gradient\":\n return merge(baseClasses, \"text-white\", colorStyles.gradient);\n \n case \"outline\":\n return merge(baseClasses, colorStyles.outline);\n \n case \"elevated\":\n return merge(baseClasses, colorStyles.elevated);\n \n default:\n return baseClasses;\n }\n}\n\n/**\n * Size 스타일 설정 인터페이스\n */\nexport interface SizeStyles {\n container: string;\n icon: string;\n iconContainer: string;\n text: string;\n title: string;\n description: string;\n}\n\n/**\n * Size 스타일 생성 함수\n * \n * @param size - 크기 타입\n * @returns 생성된 size 스타일 객체\n * \n * @example\n * ```tsx\n * const sizeStyles = createSizeStyles(\"md\");\n * // sizeStyles.container, sizeStyles.icon 등 사용 가능\n * ```\n */\nexport function createSizeStyles(size: Size = \"md\"): SizeStyles {\n const sizeMap: Record<Size, SizeStyles> = {\n sm: {\n container: \"p-4\",\n icon: \"h-4 w-4\",\n iconContainer: \"w-8 h-8\",\n text: \"text-xs\",\n title: \"text-xs\",\n description: \"text-xs\",\n },\n md: {\n container: \"p-6\",\n icon: \"h-6 w-6\",\n iconContainer: \"w-12 h-12\",\n text: \"text-base\",\n title: \"text-sm\",\n description: \"text-sm\",\n },\n lg: {\n container: \"p-8\",\n icon: \"h-8 w-8\",\n iconContainer: \"w-16 h-16\",\n text: \"text-lg\",\n title: \"text-base\",\n description: \"text-base\",\n },\n xl: {\n container: \"p-10\",\n icon: \"h-10 w-10\",\n iconContainer: \"w-20 h-20\",\n text: \"text-xl\",\n title: \"text-lg\",\n description: \"text-lg\",\n },\n };\n \n return sizeMap[size];\n}\n\n/**\n * Rounded 스타일 타입\n */\nexport type Rounded = \"sm\" | \"md\" | \"lg\" | \"xl\" | \"full\" | \"none\";\n\n/**\n * Rounded 스타일 생성 함수\n * \n * @param rounded - Rounded 타입\n * @returns 생성된 rounded 클래스 문자열\n */\nexport function createRoundedStyles(rounded: Rounded = \"md\"): string {\n const roundedMap: Record<Rounded, string> = {\n sm: \"rounded\",\n md: \"rounded-md\",\n lg: \"rounded-lg\",\n xl: \"rounded-xl\",\n full: \"rounded-full\",\n none: \"rounded-none\",\n };\n \n return roundedMap[rounded];\n}\n\n/**\n * Shadow 스타일 타입\n */\nexport type Shadow = \"none\" | \"sm\" | \"md\" | \"lg\" | \"xl\" | \"2xl\";\n\n/**\n * Shadow 스타일 생성 함수\n * \n * @param shadow - Shadow 타입\n * @returns 생성된 shadow 클래스 문자열\n */\nexport function createShadowStyles(shadow: Shadow = \"md\"): string {\n if (shadow === \"none\") return \"\";\n \n return `shadow-${shadow}`;\n}\n\n/**\n * Hover 효과 타입\n */\nexport type HoverEffect = \"scale\" | \"glow\" | \"slide\" | \"springy\" | \"none\";\n\n/**\n * HUA-UI 스프링 이징\n * 공 튕기듯 아주 미세한 반동 - cubic-bezier(0.34, 1.56, 0.64, 1)\n */\nexport const HUA_SPRING_EASING = \"cubic-bezier(0.34, 1.56, 0.64, 1)\";\n\n/**\n * Hover 효과 스타일 생성 함수\n *\n * @param hover - Hover 효과 타입\n * @param reducedMotion - 애니메이션 축소 설정 여부\n * @returns 생성된 hover 클래스 문자열\n *\n * @description\n * HUA-UI 시그니처: \"스륵 부드럽고 아주 미세하게 쫀득\"\n * - 스프링 이징으로 미세한 반동 효과\n * - 1.5% 스케일 변화로 자연스러운 피드백\n */\nexport function createHoverStyles(\n hover: HoverEffect = \"springy\",\n reducedMotion: boolean = false\n): string {\n if (reducedMotion || hover === \"none\") return \"\";\n\n // 스프링 이징 스타일 (Tailwind arbitrary value)\n // HUA-UI 시그니처: 아주 미세한 스프링 반동 (쫀득한 느낌)\n const springTransition = \"[transition:transform_180ms_cubic-bezier(0.34,1.56,0.64,1),box-shadow_200ms_ease-out]\";\n\n const hoverMap: Record<HoverEffect, string> = {\n // HUA-UI 시그니처 스프링 효과 (기본값)\n // scale 1.5% + 미세한 shadow 추가로 입체감\n springy: `hover:scale-[1.015] hover:shadow-md active:scale-[0.985] ${springTransition} transform-gpu`,\n // scale만 (스프링 없음)\n scale: \"hover:scale-[1.015] active:scale-[0.985] transition-transform duration-150 ease-out transform-gpu\",\n // 글로우 효과 - shadow 강화\n glow: \"hover:shadow-lg hover:shadow-primary/25 transition-shadow duration-200\",\n // 슬라이드 효과 - 위로 살짝 뜨는 느낌 + shadow\n slide: `hover:-translate-y-0.5 hover:shadow-md ${springTransition} transform-gpu`,\n none: \"\",\n };\n\n return hoverMap[hover];\n}\n\n"]}
1
+ {"version":3,"sources":["../src/lib/styles/colors.ts","../src/lib/styles/variants.ts"],"names":["colorShades","colorClass","color","shade","prefix","withDarkMode","lightClass","darkClass","defaultColorConfig","gradientConfig","createColorStyles","config","_a","_b","_c","_d","_e","_f","_g","_h","_i","_j","_k","_l","_m","_n","_o","finalConfig","defaultBorder","defaultBg","defaultStyle","merge","gradientFrom","gradientTo","gradientBorder","gradientStyle","outlineBorder","outlineBg","outlineText","outlineStyle","elevatedBorder","elevatedBg","elevatedShadow","elevatedStyle","iconBg","iconText","iconStyle","badgeBg","badgeText","badgeStyle","colorStylesCache","useColorStyles","cacheKey","createVariantStyles","variant","colorStyles","baseClasses","createSizeStyles","size","createRoundedStyles","rounded","createShadowStyles","shadow","HUA_SPRING_EASING","createHoverStyles","hover","reducedMotion","springTransition"],"mappings":"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","file":"chunk-MDLCJASB.mjs","sourcesContent":["/**\n * HUA UI 공통 색상 시스템\n * 중앙화된 색상 팔레트와 스타일 생성 유틸리티\n */\n\nimport type { Color } from \"../types/common\";\nimport { merge } from \"../utils\";\n\n/**\n * Tailwind CSS 색상 클래스 매핑\n * 각 색상의 50-900 단계를 정의합니다.\n */\nconst colorShades = {\n 50: \"50\",\n 100: \"100\",\n 200: \"200\",\n 300: \"300\",\n 400: \"400\",\n 500: \"500\",\n 600: \"600\",\n 700: \"700\",\n 800: \"800\",\n 900: \"900\",\n} as const;\n\ntype ColorShade = keyof typeof colorShades;\n\n/**\n * 색상별 클래스 생성 헬퍼\n */\nfunction colorClass(color: Color, shade: ColorShade, prefix: string = \"\"): string {\n return `${prefix}${color}-${colorShades[shade]}`;\n}\n\n/**\n * 다크 모드 지원 클래스 생성\n */\nfunction withDarkMode(lightClass: string, darkClass: string): string {\n return `${lightClass} dark:${darkClass}`;\n}\n\n/**\n * 색상 스타일 설정 인터페이스\n */\nexport interface ColorStyleConfig {\n /** 기본 variant 스타일 */\n default?: {\n border?: { light: ColorShade; dark?: ColorShade };\n background?: { light: ColorShade; dark?: ColorShade; opacity?: string };\n };\n /** 그라데이션 variant 스타일 */\n gradient?: {\n from?: ColorShade;\n to?: ColorShade;\n border?: { light: ColorShade; dark?: ColorShade };\n };\n /** 아웃라인 variant 스타일 */\n outline?: {\n border?: { light: ColorShade; dark?: ColorShade };\n background?: string;\n text?: { light: ColorShade; dark?: ColorShade };\n };\n /** Elevated variant 스타일 */\n elevated?: {\n border?: { light: ColorShade; dark?: ColorShade };\n background?: { light: string; dark: string };\n shadow?: string;\n };\n /** 아이콘 스타일 */\n icon?: {\n background?: { light: ColorShade; dark?: ColorShade; opacity?: string };\n text?: { light: ColorShade; dark?: ColorShade };\n };\n /** 배지 스타일 */\n badge?: {\n background?: { light: ColorShade; dark?: ColorShade; opacity?: string };\n text?: { light: ColorShade; dark?: ColorShade };\n };\n}\n\n/**\n * 생성된 색상 스타일 인터페이스\n */\nexport interface ColorStyles {\n default: string;\n gradient: string;\n outline: string;\n elevated: string;\n icon: string;\n badge: string;\n}\n\n/**\n * 기본 색상 스타일 설정\n * 각 색상에 대한 기본 스타일 템플릿\n */\nconst defaultColorConfig: Omit<ColorStyleConfig, \"gradient\"> = {\n default: {\n border: { light: 200, dark: 700 },\n background: { light: 50, dark: 900, opacity: \"50\" },\n },\n outline: {\n border: { light: 300, dark: 600 },\n background: \"transparent\",\n text: { light: 600, dark: 400 },\n },\n elevated: {\n border: { light: 200, dark: 700 },\n background: { light: \"white\", dark: \"gray-800\" },\n shadow: \"lg\",\n },\n icon: {\n background: { light: 100, dark: 900, opacity: \"30\" },\n text: { light: 600, dark: 400 },\n },\n badge: {\n background: { light: 50, dark: 900, opacity: \"30\" },\n text: { light: 700, dark: 300 },\n },\n};\n\n/**\n * 그라데이션 스타일 설정\n */\nconst gradientConfig: ColorStyleConfig[\"gradient\"] = {\n from: 500,\n to: 600,\n border: { light: 400, dark: 500 },\n};\n\n/**\n * 색상 스타일 생성 함수\n * \n * @param color - 색상 이름\n * @param config - 커스텀 스타일 설정 (선택사항)\n * @returns 생성된 색상 스타일 객체\n * \n * @example\n * ```tsx\n * const styles = createColorStyles(\"blue\");\n * // styles.default, styles.gradient, styles.outline 등 사용 가능\n * ```\n */\nexport function createColorStyles(\n color: Color,\n config?: Partial<ColorStyleConfig>\n): ColorStyles {\n const finalConfig: ColorStyleConfig = {\n default: config?.default || defaultColorConfig.default,\n gradient: config?.gradient || gradientConfig,\n outline: config?.outline || defaultColorConfig.outline,\n elevated: config?.elevated || defaultColorConfig.elevated,\n icon: config?.icon || defaultColorConfig.icon,\n badge: config?.badge || defaultColorConfig.badge,\n };\n\n // Default variant\n const defaultBorder = finalConfig.default?.border\n ? withDarkMode(\n `border-${colorClass(color, finalConfig.default.border.light)}`,\n `border-${colorClass(color, finalConfig.default.border.dark || finalConfig.default.border.light)}`\n )\n : \"\";\n \n const defaultBg = finalConfig.default?.background\n ? withDarkMode(\n `bg-${colorClass(color, finalConfig.default.background.light)}${finalConfig.default.background.opacity ? `/${finalConfig.default.background.opacity}` : \"\"}`,\n `bg-${colorClass(color, finalConfig.default.background.dark || finalConfig.default.background.light)}${finalConfig.default.background.opacity ? `/${finalConfig.default.background.opacity}` : \"\"}`\n )\n : \"\";\n\n const defaultStyle = merge(defaultBorder, defaultBg);\n\n // Gradient variant\n const gradientFrom = finalConfig.gradient?.from\n ? `from-${colorClass(color, finalConfig.gradient.from)}`\n : \"\";\n const gradientTo = finalConfig.gradient?.to\n ? `to-${colorClass(color, finalConfig.gradient.to)}`\n : \"\";\n const gradientBorder = finalConfig.gradient?.border\n ? withDarkMode(\n `border-${colorClass(color, finalConfig.gradient.border.light)}`,\n `border-${colorClass(color, finalConfig.gradient.border.dark || finalConfig.gradient.border.light)}`\n )\n : \"\";\n \n const gradientStyle = merge(\n \"bg-gradient-to-br\",\n gradientFrom,\n gradientTo,\n gradientBorder\n );\n\n // Outline variant\n const outlineBorder = finalConfig.outline?.border\n ? `border-2 ${withDarkMode(\n `border-${colorClass(color, finalConfig.outline.border.light)}`,\n `border-${colorClass(color, finalConfig.outline.border.dark || finalConfig.outline.border.light)}`\n )}`\n : \"\";\n const outlineBg = finalConfig.outline?.background || \"bg-transparent\";\n const outlineText = finalConfig.outline?.text\n ? withDarkMode(\n `text-${colorClass(color, finalConfig.outline.text.light)}`,\n `text-${colorClass(color, finalConfig.outline.text.dark || finalConfig.outline.text.light)}`\n )\n : \"\";\n \n const outlineStyle = merge(outlineBorder, outlineBg, outlineText);\n\n // Elevated variant\n const elevatedBorder = finalConfig.elevated?.border\n ? withDarkMode(\n `border-${colorClass(color, finalConfig.elevated.border.light)}`,\n `border-${colorClass(color, finalConfig.elevated.border.dark || finalConfig.elevated.border.light)}`\n )\n : \"\";\n const elevatedBg = finalConfig.elevated?.background\n ? withDarkMode(\n `bg-${finalConfig.elevated.background.light}`,\n `bg-${finalConfig.elevated.background.dark}`\n )\n : \"\";\n const elevatedShadow = finalConfig.elevated?.shadow\n ? `shadow-${finalConfig.elevated.shadow}`\n : \"\";\n \n const elevatedStyle = merge(elevatedBorder, elevatedBg, elevatedShadow);\n\n // Icon style\n const iconBg = finalConfig.icon?.background\n ? withDarkMode(\n `bg-${colorClass(color, finalConfig.icon.background.light)}${finalConfig.icon.background.opacity ? `/${finalConfig.icon.background.opacity}` : \"\"}`,\n `bg-${colorClass(color, finalConfig.icon.background.dark || finalConfig.icon.background.light)}${finalConfig.icon.background.opacity ? `/${finalConfig.icon.background.opacity}` : \"\"}`\n )\n : \"\";\n const iconText = finalConfig.icon?.text\n ? withDarkMode(\n `text-${colorClass(color, finalConfig.icon.text.light)}`,\n `text-${colorClass(color, finalConfig.icon.text.dark || finalConfig.icon.text.light)}`\n )\n : \"\";\n \n const iconStyle = merge(iconBg, iconText);\n\n // Badge style\n const badgeBg = finalConfig.badge?.background\n ? withDarkMode(\n `bg-${colorClass(color, finalConfig.badge.background.light)}${finalConfig.badge.background.opacity ? `/${finalConfig.badge.background.opacity}` : \"\"}`,\n `bg-${colorClass(color, finalConfig.badge.background.dark || finalConfig.badge.background.light)}${finalConfig.badge.background.opacity ? `/${finalConfig.badge.background.opacity}` : \"\"}`\n )\n : \"\";\n const badgeText = finalConfig.badge?.text\n ? withDarkMode(\n `text-${colorClass(color, finalConfig.badge.text.light)}`,\n `text-${colorClass(color, finalConfig.badge.text.dark || finalConfig.badge.text.light)}`\n )\n : \"\";\n \n const badgeStyle = merge(badgeBg, badgeText);\n\n return {\n default: defaultStyle,\n gradient: gradientStyle,\n outline: outlineStyle,\n elevated: elevatedStyle,\n icon: iconStyle,\n badge: badgeStyle,\n };\n}\n\n/**\n * 색상 스타일 캐시\n * 동일한 색상과 설정에 대해 재사용하여 성능 최적화\n */\nconst colorStylesCache = new Map<string, ColorStyles>();\n\n/**\n * 메모이제이션된 색상 스타일 생성 함수\n * \n * @param color - 색상 이름\n * @param config - 커스텀 스타일 설정 (선택사항)\n * @returns 생성된 색상 스타일 객체\n */\nexport function useColorStyles(\n color: Color,\n config?: Partial<ColorStyleConfig>\n): ColorStyles {\n const cacheKey = `${color}-${JSON.stringify(config || {})}`;\n \n if (!colorStylesCache.has(cacheKey)) {\n colorStylesCache.set(cacheKey, createColorStyles(color, config));\n }\n \n return colorStylesCache.get(cacheKey)!;\n}\n\n","/**\n * HUA UI 공통 Variant 시스템\n * 컴포넌트 variant 스타일 생성 유틸리티\n */\n\nimport type { ExtendedVariant, Size } from \"../types/common\";\nimport type { ColorStyles } from \"./colors\";\nimport { merge } from \"../utils\";\n\n/**\n * Variant 스타일 생성 함수\n * \n * @param variant - Variant 타입\n * @param colorStyles - 색상 스타일 객체\n * @returns 생성된 variant 클래스 문자열\n * \n * @example\n * ```tsx\n * const colorStyles = useColorStyles(\"blue\");\n * const variantClass = createVariantStyles(\"elevated\", colorStyles);\n * ```\n */\nexport function createVariantStyles(\n variant: ExtendedVariant,\n colorStyles: ColorStyles\n): string {\n const baseClasses = \"rounded-2xl border transition-all duration-200\";\n \n switch (variant) {\n case \"default\":\n return merge(baseClasses, colorStyles.default);\n \n case \"gradient\":\n return merge(baseClasses, \"text-white\", colorStyles.gradient);\n \n case \"outline\":\n return merge(baseClasses, colorStyles.outline);\n \n case \"elevated\":\n return merge(baseClasses, colorStyles.elevated);\n \n default:\n return baseClasses;\n }\n}\n\n/**\n * Size 스타일 설정 인터페이스\n */\nexport interface SizeStyles {\n container: string;\n icon: string;\n iconContainer: string;\n text: string;\n title: string;\n description: string;\n}\n\n/**\n * Size 스타일 생성 함수\n * \n * @param size - 크기 타입\n * @returns 생성된 size 스타일 객체\n * \n * @example\n * ```tsx\n * const sizeStyles = createSizeStyles(\"md\");\n * // sizeStyles.container, sizeStyles.icon 등 사용 가능\n * ```\n */\nexport function createSizeStyles(size: Size = \"md\"): SizeStyles {\n const sizeMap: Record<Size, SizeStyles> = {\n sm: {\n container: \"p-4\",\n icon: \"h-4 w-4\",\n iconContainer: \"w-8 h-8\",\n text: \"text-xs\",\n title: \"text-xs\",\n description: \"text-xs\",\n },\n md: {\n container: \"p-6\",\n icon: \"h-6 w-6\",\n iconContainer: \"w-12 h-12\",\n text: \"text-base\",\n title: \"text-sm\",\n description: \"text-sm\",\n },\n lg: {\n container: \"p-8\",\n icon: \"h-8 w-8\",\n iconContainer: \"w-16 h-16\",\n text: \"text-lg\",\n title: \"text-base\",\n description: \"text-base\",\n },\n xl: {\n container: \"p-10\",\n icon: \"h-10 w-10\",\n iconContainer: \"w-20 h-20\",\n text: \"text-xl\",\n title: \"text-lg\",\n description: \"text-lg\",\n },\n };\n \n return sizeMap[size];\n}\n\n/**\n * Rounded 스타일 타입\n */\nexport type Rounded = \"sm\" | \"md\" | \"lg\" | \"xl\" | \"full\" | \"none\";\n\n/**\n * Rounded 스타일 생성 함수\n * \n * @param rounded - Rounded 타입\n * @returns 생성된 rounded 클래스 문자열\n */\nexport function createRoundedStyles(rounded: Rounded = \"md\"): string {\n const roundedMap: Record<Rounded, string> = {\n sm: \"rounded\",\n md: \"rounded-md\",\n lg: \"rounded-lg\",\n xl: \"rounded-xl\",\n full: \"rounded-full\",\n none: \"rounded-none\",\n };\n \n return roundedMap[rounded];\n}\n\n/**\n * Shadow 스타일 타입\n */\nexport type Shadow = \"none\" | \"sm\" | \"md\" | \"lg\" | \"xl\" | \"2xl\";\n\n/**\n * Shadow 스타일 생성 함수\n * \n * @param shadow - Shadow 타입\n * @returns 생성된 shadow 클래스 문자열\n */\nexport function createShadowStyles(shadow: Shadow = \"md\"): string {\n if (shadow === \"none\") return \"\";\n \n return `shadow-${shadow}`;\n}\n\n/**\n * Hover 효과 타입\n */\nexport type HoverEffect = \"scale\" | \"glow\" | \"slide\" | \"springy\" | \"none\";\n\n/**\n * HUA-UI 스프링 이징\n * 공 튕기듯 아주 미세한 반동 - cubic-bezier(0.34, 1.56, 0.64, 1)\n */\nexport const HUA_SPRING_EASING = \"cubic-bezier(0.34, 1.56, 0.64, 1)\";\n\n/**\n * Hover 효과 스타일 생성 함수\n *\n * @param hover - Hover 효과 타입\n * @param reducedMotion - 애니메이션 축소 설정 여부\n * @returns 생성된 hover 클래스 문자열\n *\n * @description\n * HUA-UI 시그니처: \"스륵 부드럽고 아주 미세하게 쫀득\"\n * - 스프링 이징으로 미세한 반동 효과\n * - 1.5% 스케일 변화로 자연스러운 피드백\n */\nexport function createHoverStyles(\n hover: HoverEffect = \"springy\",\n reducedMotion: boolean = false\n): string {\n if (reducedMotion || hover === \"none\") return \"\";\n\n // 스프링 이징 스타일 (Tailwind arbitrary value)\n // HUA-UI 시그니처: 아주 미세한 스프링 반동 (쫀득한 느낌)\n const springTransition = \"[transition:transform_180ms_cubic-bezier(0.34,1.56,0.64,1),box-shadow_200ms_ease-out]\";\n\n const hoverMap: Record<HoverEffect, string> = {\n // HUA-UI 시그니처 스프링 효과 (기본값)\n // scale 1.5% + 미세한 shadow 추가로 입체감\n springy: `hover:scale-[1.015] hover:shadow-md active:scale-[0.985] ${springTransition} transform-gpu`,\n // scale만 (스프링 없음)\n scale: \"hover:scale-[1.015] active:scale-[0.985] transition-transform duration-150 ease-out transform-gpu\",\n // 글로우 효과 - shadow 강화\n glow: \"hover:shadow-lg hover:shadow-primary/25 transition-shadow duration-200\",\n // 슬라이드 효과 - 위로 살짝 뜨는 느낌 + shadow\n slide: `hover:-translate-y-0.5 hover:shadow-md ${springTransition} transform-gpu`,\n none: \"\",\n };\n\n return hoverMap[hover];\n}\n\n"]}
@@ -0,0 +1,3 @@
1
+ "use client";
2
+ import {l}from'./chunk-7OYT3QSY.mjs';import {b}from'./chunk-U6CTBZ2U.mjs';import f from'react';import {jsx,jsxs}from'react/jsx-runtime';var M=f.forwardRef(({children:s,className:r,type:o="single",defaultValue:a,value:n,onValueChange:c,collapsible:u=false,...v},m)=>{let[l,d]=f.useState(n?Array.isArray(n)?n:[n]:a?Array.isArray(a)?a:[a]:[]);f.useEffect(()=>{n!==void 0&&d(Array.isArray(n)?n:[n]);},[n]);let y=e=>{let t;o==="single"?l.includes(e)?t=u?[]:l:t=[e]:l.includes(e)?t=l.filter(i=>i!==e):t=[...l,e],d(t),c==null||c(o==="single"?t[0]||"":t);},p=f.useMemo(()=>{let e=[];return f.Children.forEach(s,t=>{if(f.isValidElement(t)){let i=t.props;i.value&&e.push(i.value);}}),e},[s]),h=e=>{var D;let t=e.target;if(!t.hasAttribute("data-accordion-trigger"))return;let i=t.getAttribute("data-accordion-value");if(!i)return;let x=p.indexOf(i);if(x===-1)return;let T=x;if(e.key==="ArrowDown"?(e.preventDefault(),T=x<p.length-1?x+1:0):e.key==="ArrowUp"?(e.preventDefault(),T=x>0?x-1:p.length-1):e.key==="Home"?(e.preventDefault(),T=0):e.key==="End"&&(e.preventDefault(),T=p.length-1),T!==x&&p[T]){let P=(D=t.closest("[data-accordion-item]"))==null?void 0:D.querySelector(`[data-accordion-value="${p[T]}"]`);P==null||P.focus();}};return jsx("div",{ref:m,className:b("space-y-2",r),onKeyDown:h,...v,children:f.Children.map(s,e=>f.isValidElement(e)?f.cloneElement(e,{openItems:l,onToggle:y}):e)})});M.displayName="Accordion";var k=f.forwardRef(({value:s,children:r,className:o,disabled:a=false,openItems:n=[],onToggle:c,...u},v)=>{let m=n.includes(s);return jsx("div",{ref:v,"data-accordion-item":true,className:b("border border-border/50 rounded-lg overflow-hidden",a&&"opacity-50 pointer-events-none",o),...u,children:f.Children.map(r,l=>f.isValidElement(l)?f.cloneElement(l,{value:s,isOpen:m,disabled:a,onToggle:()=>c==null?void 0:c(s),"data-accordion-value":s}):l)})});k.displayName="AccordionItem";var I=f.forwardRef(({children:s,className:r,icon:o,iconPosition:a="right",value:n,isOpen:c=false,disabled:u=false,onToggle:v,...m},l$1)=>{let d=jsx(l,{name:"chevronDown",size:20,className:b("transition-transform duration-300 ease-out text-muted-foreground",c&&"rotate-180")}),y=`accordion-content-${n}`,p=`accordion-trigger-${n}`;return jsxs("button",{ref:l$1,id:p,"data-accordion-trigger":true,"data-accordion-value":n,"aria-expanded":c,"aria-controls":y,onClick:v,disabled:u,className:b("flex w-full items-center justify-between px-6 py-4 text-left font-medium transition-all hover:bg-muted/80 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring/50 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",r),...m,children:[jsxs("div",{className:"flex items-center gap-3 flex-1",children:[a==="left"&&(o||d),jsx("span",{className:"flex-1",children:s})]}),a==="right"&&(o||d)]})});I.displayName="AccordionTrigger";var C=f.forwardRef(({children:s,className:r,isOpen:o=false,value:a,"data-accordion-value":n,...c},u)=>{let[v,m]=f.useState(0),l=f.useRef(null),d=a||n||"unknown";f.useEffect(()=>{l.current&&m(o?l.current.scrollHeight:0);},[o,s]);let y=`accordion-trigger-${d}`,p=`accordion-content-${d}`;return jsx("div",{ref:u,id:p,role:"region","aria-labelledby":y,hidden:!o,className:"overflow-hidden transition-all duration-300 ease-out",style:{height:`${v}px`},...c,children:jsx("div",{ref:l,className:b("px-6 pt-2 pb-4",r),children:s})})});C.displayName="AccordionContent";var L=f.forwardRef(({className:s,value:r,active:o,children:a,...n},c)=>o===false?null:jsx("div",{ref:c,role:"tabpanel",id:`tabpanel-${r}`,"aria-labelledby":`tab-${r}`,hidden:!o,className:b("mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-2",s),...n,children:a}));L.displayName="TabsContent";var A=f.forwardRef(({className:s,value:r,defaultValue:o,onValueChange:a,orientation:n="horizontal",variant:c="default",size:u="md",children:v,...m},l)=>{let[d,y]=f.useState(r||o||""),p=r!==void 0,h=p?r:d,e=t=>{p||y(t),a==null||a(t);};return f.useEffect(()=>{r!==void 0&&y(r);},[r]),jsx("div",{ref:l,className:b("w-full",n==="vertical"&&"flex",s),...m,children:f.Children.map(v,t=>{if(f.isValidElement(t)){if(t.type===L){let i=t.props;return f.cloneElement(t,{active:i.value===h})}if(t.type===N)return f.cloneElement(t,{value:h,onValueChange:e,orientation:n,variant:c,size:u});if(typeof t.type!="string")return f.cloneElement(t,{value:h,onValueChange:e,orientation:n,variant:c,size:u})}return t})})});A.displayName="Tabs";var N=f.forwardRef(({className:s,value:r,onValueChange:o,orientation:a="horizontal",variant:n="default",size:c="md",children:u,...v},m)=>{let l=f.useRef(null);f.useImperativeHandle(m,()=>l.current);let d=f.useMemo(()=>{let e=[];return f.Children.forEach(u,t=>{if(f.isValidElement(t)){let i=t.props;i.value&&e.push(i.value);}}),e},[u]),y=e=>{var x;if(!r||d.length===0)return;let t=d.indexOf(r);if(t===-1)return;let i=t;if(a==="horizontal"?e.key==="ArrowLeft"?(e.preventDefault(),i=t>0?t-1:d.length-1):e.key==="ArrowRight"?(e.preventDefault(),i=t<d.length-1?t+1:0):e.key==="Home"?(e.preventDefault(),i=0):e.key==="End"&&(e.preventDefault(),i=d.length-1):e.key==="ArrowUp"?(e.preventDefault(),i=t>0?t-1:d.length-1):e.key==="ArrowDown"?(e.preventDefault(),i=t<d.length-1?t+1:0):e.key==="Home"?(e.preventDefault(),i=0):e.key==="End"&&(e.preventDefault(),i=d.length-1),i!==t&&d[i]){o==null||o(d[i]);let T=(x=l.current)==null?void 0:x.querySelector(`[data-tab-value="${d[i]}"]`);T==null||T.focus();}},p=()=>{switch(n){case "pills":return "bg-muted p-3 rounded-xl border border-border/50";case "underline":return "border-b border-border";case "cards":return "bg-muted/80 p-3 rounded-xl border border-border/50";default:return "bg-muted p-3 rounded-xl border border-border/50"}},h=()=>{switch(c){case "sm":return "h-12";case "lg":return "h-16";default:return "h-14"}};return jsx("div",{ref:l,role:"tablist","aria-orientation":a,onKeyDown:y,className:b("flex items-center justify-center",a==="vertical"&&"flex-col",p(),h(),s),...v,children:f.Children.map(u,e=>{if(f.isValidElement(e)){if(typeof e.type=="string")return e;let t=e.props;return f.cloneElement(e,{onValueChange:o,orientation:a,variant:n,size:c,active:t.value===r})}return e})})});N.displayName="TabsList";var z=f.forwardRef(({className:s,value:r,onValueChange:o,orientation:a="horizontal",variant:n="default",size:c="md",active:u=false,children:v,...m},l)=>{let d=()=>{switch(n){case "pills":return b("inline-flex items-center justify-center whitespace-nowrap rounded-lg px-4 py-2.5 text-sm font-medium ring-offset-background transition-all duration-200 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",u?"bg-background text-foreground shadow-md":"text-muted-foreground hover:text-foreground hover:bg-muted");case "underline":return b("inline-flex items-center justify-center whitespace-nowrap border-b-2 px-4 py-2.5 text-sm font-medium ring-offset-background transition-all duration-200 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",u?"border-primary text-primary":"border-transparent text-muted-foreground hover:text-foreground");case "cards":return b("inline-flex items-center justify-center whitespace-nowrap rounded-lg px-4 py-2.5 text-sm font-medium ring-offset-background transition-all duration-200 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",u?"bg-background text-foreground shadow-md":"text-muted-foreground hover:text-foreground hover:bg-muted");default:return b("inline-flex items-center justify-center whitespace-nowrap rounded-lg px-4 py-2.5 text-sm font-medium ring-offset-background transition-all duration-200 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",u?"bg-background text-foreground shadow-md":"text-muted-foreground hover:text-foreground hover:bg-muted")}},y=()=>{switch(c){case "sm":return "h-10 px-4 py-2 text-xs";case "lg":return "h-14 px-6 py-3 text-base";default:return "h-12 px-5 py-2.5 text-sm"}},p=()=>{o&&o(r);};return jsx("button",{ref:l,role:"tab","aria-selected":u,"aria-controls":`tabpanel-${r}`,id:`tab-${r}`,"data-tab-value":r,tabIndex:u?0:-1,className:b(d(),y(),s),onClick:p,type:"button",...m,children:v})});z.displayName="TabsTrigger";var $=f.forwardRef((s,r)=>jsx(A,{ref:r,variant:"pills",...s}));$.displayName="TabsPills";var S=f.forwardRef((s,r)=>jsx(A,{ref:r,variant:"underline",...s}));S.displayName="TabsUnderline";var K=f.forwardRef((s,r)=>jsx(A,{ref:r,variant:"cards",...s}));K.displayName="TabsCards";export{M as a,k as b,I as c,C as d,L as e,A as f,N as g,z as h,$ as i,S as j,K as k};//# sourceMappingURL=chunk-N56BUOCD.mjs.map
3
+ //# sourceMappingURL=chunk-N56BUOCD.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/Accordion.tsx","../src/components/Tabs.tsx"],"names":["Accordion","React","children","className","type","defaultValue","value","onValueChange","collapsible","props","ref","openItems","setOpenItems","handleItemToggle","itemValue","newOpenItems","item","itemValues","values","child","childProps","handleKeyDown","_a","target","currentValue","currentIndex","newIndex","triggerElement","jsx","merge","AccordionItem","disabled","onToggle","isOpen","AccordionTrigger","icon","iconPosition","defaultIcon","Icon","contentId","triggerId","jsxs","AccordionContent","dataValue","height","setHeight","contentRef","TabsContent","active","Tabs","orientation","variant","size","activeTab","setActiveTab","isControlled","handleTabChange","newValue","TabsList","listRef","tabValues","getVariantClasses","getSizeClasses","TabsTrigger","_orientation","handleClick","TabsPills","TabsUnderline","TabsCards"],"mappings":"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","file":"chunk-XV3Y7QVU.mjs","sourcesContent":["\"use client\"\n\nimport React from \"react\"\nimport { merge } from \"../lib/utils\"\nimport { Icon } from \"./Icon\"\n\n/**\n * Accordion 컴포넌트의 props / Accordion component props\n * @typedef {Object} AccordionProps\n * @property {React.ReactNode} children - AccordionItem 컴포넌트들 / AccordionItem components\n * @property {string} [className] - 추가 CSS 클래스 / Additional CSS class\n * @property {\"single\" | \"multiple\"} [type=\"single\"] - 단일 또는 다중 아이템 열기 허용 / Allow single or multiple items to be open\n * @property {string | string[]} [defaultValue] - 초기 열린 아이템 값 (비제어 컴포넌트) / Initial open item value (uncontrolled component)\n * @property {string | string[]} [value] - 현재 열린 아이템 값 (제어 컴포넌트) / Current open item value (controlled component)\n * @property {(value: string | string[]) => void} [onValueChange] - 아이템 열림/닫힘 콜백 / Item open/close callback\n * @property {boolean} [collapsible=false] - 단일 모드에서 열린 아이템을 닫을 수 있는지 여부 / Whether open item can be closed in single mode\n */\ninterface AccordionProps {\n children: React.ReactNode\n className?: string\n type?: \"single\" | \"multiple\"\n defaultValue?: string | string[]\n value?: string | string[]\n onValueChange?: (value: string | string[]) => void\n collapsible?: boolean\n}\n\n/**\n * Accordion 컴포넌트 / Accordion component\n * \n * 접을 수 있는 콘텐츠 섹션을 제공하는 컴포넌트입니다.\n * 키보드 네비게이션(Arrow keys, Home/End)을 지원하며, ARIA 속성을 자동으로 설정합니다.\n * \n * Component that provides collapsible content sections.\n * Supports keyboard navigation (Arrow keys, Home/End) and automatically sets ARIA attributes.\n * \n * @component\n * @example\n * // 기본 사용 (단일 열기) / Basic usage (single open)\n * <Accordion type=\"single\">\n * <AccordionItem value=\"item1\">\n * <AccordionTrigger>제목 1</AccordionTrigger>\n * <AccordionContent>내용 1</AccordionContent>\n * </AccordionItem>\n * <AccordionItem value=\"item2\">\n * <AccordionTrigger>제목 2</AccordionTrigger>\n * <AccordionContent>내용 2</AccordionContent>\n * </AccordionItem>\n * </Accordion>\n * \n * @example\n * // 다중 열기 / Multiple open\n * <Accordion type=\"multiple\" defaultValue={[\"item1\", \"item2\"]}>\n * <AccordionItem value=\"item1\">\n * <AccordionTrigger>제목 1</AccordionTrigger>\n * <AccordionContent>내용 1</AccordionContent>\n * </AccordionItem>\n * </Accordion>\n * \n * @example\n * // 제어 컴포넌트 / Controlled component\n * const [openItems, setOpenItems] = useState<string[]>([])\n * <Accordion type=\"multiple\" value={openItems} onValueChange={setOpenItems}>\n * <AccordionItem value=\"item1\">\n * <AccordionTrigger>제목</AccordionTrigger>\n * <AccordionContent>내용</AccordionContent>\n * </AccordionItem>\n * </Accordion>\n * \n * @param {AccordionProps} props - Accordion 컴포넌트의 props / Accordion component props\n * @param {React.Ref<HTMLDivElement>} ref - div 요소 ref / div element ref\n * @returns {JSX.Element} Accordion 컴포넌트 / Accordion component\n */\nconst Accordion = React.forwardRef<HTMLDivElement, AccordionProps>(\n ({ \n children, \n className,\n type = \"single\",\n defaultValue,\n value,\n onValueChange,\n collapsible = false,\n ...props \n }, ref) => {\n const [openItems, setOpenItems] = React.useState<string[]>(\n value ? (Array.isArray(value) ? value : [value]) : \n defaultValue ? (Array.isArray(defaultValue) ? defaultValue : [defaultValue]) : []\n )\n\n React.useEffect(() => {\n if (value !== undefined) {\n setOpenItems(Array.isArray(value) ? value : [value])\n }\n }, [value])\n\n const handleItemToggle = (itemValue: string) => {\n let newOpenItems: string[]\n\n if (type === \"single\") {\n if (openItems.includes(itemValue)) {\n newOpenItems = collapsible ? [] : openItems\n } else {\n newOpenItems = [itemValue]\n }\n } else {\n if (openItems.includes(itemValue)) {\n newOpenItems = openItems.filter(item => item !== itemValue)\n } else {\n newOpenItems = [...openItems, itemValue]\n }\n }\n\n setOpenItems(newOpenItems)\n onValueChange?.(type === \"single\" ? newOpenItems[0] || \"\" : newOpenItems)\n }\n\n // 모든 아이템의 value를 수집\n const itemValues = React.useMemo(() => {\n const values: string[] = []\n React.Children.forEach(children, (child) => {\n if (React.isValidElement(child)) {\n const childProps = child.props as { value?: string }\n if (childProps.value) {\n values.push(childProps.value)\n }\n }\n })\n return values\n }, [children])\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {\n const target = e.target as HTMLElement\n if (!target.hasAttribute('data-accordion-trigger')) return\n\n const currentValue = target.getAttribute('data-accordion-value')\n if (!currentValue) return\n\n const currentIndex = itemValues.indexOf(currentValue)\n if (currentIndex === -1) return\n\n let newIndex = currentIndex\n\n if (e.key === \"ArrowDown\") {\n e.preventDefault()\n newIndex = currentIndex < itemValues.length - 1 ? currentIndex + 1 : 0\n } else if (e.key === \"ArrowUp\") {\n e.preventDefault()\n newIndex = currentIndex > 0 ? currentIndex - 1 : itemValues.length - 1\n } else if (e.key === \"Home\") {\n e.preventDefault()\n newIndex = 0\n } else if (e.key === \"End\") {\n e.preventDefault()\n newIndex = itemValues.length - 1\n }\n\n if (newIndex !== currentIndex && itemValues[newIndex]) {\n const triggerElement = target.closest('[data-accordion-item]')?.querySelector(\n `[data-accordion-value=\"${itemValues[newIndex]}\"]`\n ) as HTMLElement\n triggerElement?.focus()\n }\n }\n\n return (\n <div\n ref={ref}\n className={merge(\"space-y-2\", className)}\n onKeyDown={handleKeyDown}\n {...props}\n >\n {React.Children.map(children, (child) => {\n if (React.isValidElement(child)) {\n return React.cloneElement(child, {\n openItems,\n onToggle: handleItemToggle\n } as Partial<AccordionItemProps>)\n }\n return child\n })}\n </div>\n )\n }\n)\nAccordion.displayName = \"Accordion\"\n\n/**\n * AccordionItem 컴포넌트의 props / AccordionItem component props\n * @typedef {Object} AccordionItemProps\n * @property {string} value - 아이템의 고유 값 / Item unique value\n * @property {React.ReactNode} children - AccordionTrigger와 AccordionContent / AccordionTrigger and AccordionContent\n * @property {string} [className] - 추가 CSS 클래스 / Additional CSS class\n * @property {boolean} [disabled=false] - 아이템 비활성화 여부 / Item disabled state\n * @property {string[]} [openItems] - 열린 아이템 목록 (Accordion에서 자동 전달) / Open items list (auto-passed from Accordion)\n * @property {(value: string) => void} [onToggle] - 토글 콜백 (Accordion에서 자동 전달) / Toggle callback (auto-passed from Accordion)\n */\ninterface AccordionItemProps {\n value: string\n children: React.ReactNode\n className?: string\n disabled?: boolean\n openItems?: string[]\n onToggle?: (value: string) => void\n}\n\n/**\n * AccordionItem 컴포넌트 / AccordionItem component\n * 아코디언의 개별 아이템을 감싸는 컨테이너입니다.\n * Container that wraps an individual accordion item.\n * \n * @component\n * @param {AccordionItemProps} props - AccordionItem 컴포넌트의 props / AccordionItem component props\n * @param {React.Ref<HTMLDivElement>} ref - div 요소 ref / div element ref\n * @returns {JSX.Element} AccordionItem 컴포넌트 / AccordionItem component\n */\nconst AccordionItem = React.forwardRef<HTMLDivElement, AccordionItemProps>(\n ({ \n value, \n children, \n className,\n disabled = false,\n openItems = [],\n onToggle,\n ...props \n }, ref) => {\n const isOpen = openItems.includes(value)\n\n return (\n <div\n ref={ref}\n data-accordion-item\n className={merge(\n \"border border-border/50 rounded-lg overflow-hidden\",\n disabled && \"opacity-50 pointer-events-none\",\n className\n )}\n {...props}\n >\n {React.Children.map(children, (child) => {\n if (React.isValidElement(child)) {\n return React.cloneElement(child, {\n value,\n isOpen,\n disabled,\n onToggle: () => onToggle?.(value),\n 'data-accordion-value': value\n } as Partial<AccordionTriggerProps | AccordionContentProps>)\n }\n return child\n })}\n </div>\n )\n }\n)\nAccordionItem.displayName = \"AccordionItem\"\n\ninterface AccordionTriggerProps {\n children: React.ReactNode\n className?: string\n icon?: React.ReactNode\n iconPosition?: \"left\" | \"right\"\n value?: string // Optional: AccordionItem에서 자동으로 전달됨 / Optional: Auto-passed from AccordionItem\n isOpen?: boolean\n disabled?: boolean\n onToggle?: () => void\n}\n\nconst AccordionTrigger = React.forwardRef<HTMLButtonElement, AccordionTriggerProps>(\n ({ \n children, \n className,\n icon,\n iconPosition = \"right\",\n value,\n isOpen = false,\n disabled = false,\n onToggle,\n ...props \n }, ref) => {\n const defaultIcon = (\n <Icon \n name=\"chevronDown\" \n size={20} \n className={merge(\n \"transition-transform duration-300 ease-out text-muted-foreground\",\n isOpen && \"rotate-180\"\n )} \n />\n )\n\n const contentId = `accordion-content-${value}`\n const triggerId = `accordion-trigger-${value}`\n\n return (\n <button\n ref={ref}\n id={triggerId}\n data-accordion-trigger\n data-accordion-value={value}\n aria-expanded={isOpen}\n aria-controls={contentId}\n onClick={onToggle}\n disabled={disabled}\n className={merge(\n \"flex w-full items-center justify-between px-6 py-4 text-left font-medium transition-all hover:bg-muted/80 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring/50 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50\",\n className\n )}\n {...props}\n >\n <div className=\"flex items-center gap-3 flex-1\">\n {iconPosition === \"left\" && (icon || defaultIcon)}\n <span className=\"flex-1\">{children}</span>\n </div>\n {iconPosition === \"right\" && (icon || defaultIcon)}\n </button>\n )\n }\n)\nAccordionTrigger.displayName = \"AccordionTrigger\"\n\n/**\n * AccordionTrigger 컴포넌트 / AccordionTrigger component\n * 아코디언 아이템을 열고 닫는 트리거 버튼입니다.\n * Button that opens and closes an accordion item.\n * \n * @component\n * @param {AccordionTriggerProps} props - AccordionTrigger 컴포넌트의 props / AccordionTrigger component props\n * @param {React.Ref<HTMLButtonElement>} ref - button 요소 ref / button element ref\n * @returns {JSX.Element} AccordionTrigger 컴포넌트 / AccordionTrigger component\n */\n\n/**\n * AccordionContent 컴포넌트의 props\n * @typedef {Object} AccordionContentProps\n * @property {React.ReactNode} children - 콘텐츠\n * @property {string} [className] - 추가 CSS 클래스\n * @property {boolean} [isOpen] - 열림 상태 (AccordionItem에서 자동 전달)\n * @property {string} [value] - 아이템 값 (AccordionItem에서 자동 전달)\n * @property {string} ['data-accordion-value'] - 아이템 값 (내부 사용)\n */\ninterface AccordionContentProps {\n children: React.ReactNode\n className?: string\n isOpen?: boolean\n value?: string\n 'data-accordion-value'?: string\n}\n\n/**\n * AccordionContent 컴포넌트 / AccordionContent component\n * 아코디언 아이템의 콘텐츠를 표시합니다.\n * Displays the content of an accordion item.\n * \n * @component\n * @param {AccordionContentProps} props - AccordionContent 컴포넌트의 props / AccordionContent component props\n * @param {React.Ref<HTMLDivElement>} ref - div 요소 ref / div element ref\n * @returns {JSX.Element} AccordionContent 컴포넌트 / AccordionContent component\n */\nconst AccordionContent = React.forwardRef<HTMLDivElement, AccordionContentProps>(\n ({ children, className, isOpen = false, value, 'data-accordion-value': dataValue, ...props }, ref) => {\n const [height, setHeight] = React.useState(0)\n const contentRef = React.useRef<HTMLDivElement>(null)\n const itemValue = value || dataValue || 'unknown'\n\n React.useEffect(() => {\n if (contentRef.current) {\n if (isOpen) {\n setHeight(contentRef.current.scrollHeight)\n } else {\n setHeight(0)\n }\n }\n }, [isOpen, children])\n\n const triggerId = `accordion-trigger-${itemValue}`\n const contentId = `accordion-content-${itemValue}`\n\n return (\n <div\n ref={ref}\n id={contentId}\n role=\"region\"\n aria-labelledby={triggerId}\n hidden={!isOpen}\n className=\"overflow-hidden transition-all duration-300 ease-out\"\n style={{ height: `${height}px` }}\n {...props}\n >\n <div\n ref={contentRef}\n className={merge(\"px-6 pt-2 pb-4\", className)}\n >\n {children}\n </div>\n </div>\n )\n }\n)\nAccordionContent.displayName = \"AccordionContent\"\n\nexport { Accordion, AccordionItem, AccordionTrigger, AccordionContent } ","\"use client\"\n\nimport React from 'react'\nimport { merge } from '../lib/utils'\n\n/**\n * TabsContent 컴포넌트의 props / TabsContent component props\n * @typedef {Object} TabsContentProps\n * @property {string} value - 탭 패널의 고유 값 (TabsTrigger의 value와 일치해야 함) / Unique value for tab panel (must match TabsTrigger value)\n * @property {boolean} [active] - 탭 패널 활성화 상태 (자동 설정됨) / Tab panel active state (auto-set)\n * @extends {React.HTMLAttributes<HTMLDivElement>}\n */\nexport interface TabsContentProps extends React.HTMLAttributes<HTMLDivElement> {\n value: string\n active?: boolean\n}\n\n/**\n * TabsContent 컴포넌트 / TabsContent component\n * 탭의 콘텐츠 패널을 표시합니다. Tabs 컴포넌트 내부에서 사용됩니다.\n * Displays the tab content panel. Used inside Tabs component.\n * \n * @component\n * @param {TabsContentProps} props - TabsContent 컴포넌트의 props / TabsContent component props\n * @param {React.Ref<HTMLDivElement>} ref - div 요소 ref / div element ref\n * @returns {JSX.Element} TabsContent 컴포넌트 / TabsContent component\n */\nconst TabsContent = React.forwardRef<HTMLDivElement, TabsContentProps>(\n ({ className, value, active, children, ...props }, ref) => {\n // active prop이 명시적으로 false로 설정된 경우에만 숨김\n if (active === false) return null\n\n return (\n <div\n ref={ref}\n role=\"tabpanel\"\n id={`tabpanel-${value}`}\n aria-labelledby={`tab-${value}`}\n hidden={!active}\n className={merge(\n \"mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-2\",\n className\n )}\n {...props}\n >\n {children}\n </div>\n )\n }\n)\nTabsContent.displayName = \"TabsContent\"\n\n/**\n * Tabs 컴포넌트의 props / Tabs component props\n * @typedef {Object} TabsProps\n * @property {string} [value] - 현재 활성화된 탭 값 (제어 컴포넌트) / Currently active tab value (controlled component)\n * @property {string} [defaultValue] - 초기 활성화된 탭 값 (비제어 컴포넌트) / Initial active tab value (uncontrolled component)\n * @property {(value: string) => void} [onValueChange] - 탭 변경 시 호출되는 콜백 / Callback when tab changes\n * @property {\"horizontal\" | \"vertical\"} [orientation=\"horizontal\"] - 탭 방향 / Tab orientation\n * @property {\"default\" | \"pills\" | \"underline\" | \"cards\"} [variant=\"default\"] - 탭 스타일 변형 / Tab style variant\n * @property {\"sm\" | \"md\" | \"lg\"} [size=\"md\"] - 탭 크기 / Tab size\n * @extends {React.HTMLAttributes<HTMLDivElement>}\n */\nexport interface TabsProps extends React.HTMLAttributes<HTMLDivElement> {\n value?: string\n defaultValue?: string\n onValueChange?: (value: string) => void\n orientation?: \"horizontal\" | \"vertical\"\n variant?: \"default\" | \"pills\" | \"underline\" | \"cards\"\n size?: \"sm\" | \"md\" | \"lg\"\n}\n\n/**\n * Tabs 컴포넌트 / Tabs component\n * \n * 탭 네비게이션을 제공하는 컴포넌트입니다.\n * 키보드 네비게이션(Arrow keys, Home/End)을 지원하며, ARIA 속성을 자동으로 설정합니다.\n * \n * Component that provides tab navigation.\n * Supports keyboard navigation (Arrow keys, Home/End) and automatically sets ARIA attributes.\n * \n * @component\n * @example\n * // 기본 사용 / Basic usage\n * <Tabs defaultValue=\"tab1\">\n * <TabsList>\n * <TabsTrigger value=\"tab1\">탭 1</TabsTrigger>\n * <TabsTrigger value=\"tab2\">탭 2</TabsTrigger>\n * </TabsList>\n * <TabsContent value=\"tab1\">탭 1 내용</TabsContent>\n * <TabsContent value=\"tab2\">탭 2 내용</TabsContent>\n * </Tabs>\n * \n * @example\n * // 제어 컴포넌트 / Controlled component\n * const [activeTab, setActiveTab] = useState(\"tab1\")\n * <Tabs value={activeTab} onValueChange={setActiveTab}>\n * <TabsList>\n * <TabsTrigger value=\"tab1\">탭 1</TabsTrigger>\n * </TabsList>\n * <TabsContent value=\"tab1\">내용</TabsContent>\n * </Tabs>\n * \n * @example\n * // 다양한 변형 / Various variants\n * <Tabs variant=\"pills\" size=\"lg\">\n * <TabsList>\n * <TabsTrigger value=\"tab1\">Pills 스타일</TabsTrigger>\n * </TabsList>\n * </Tabs>\n * \n * @param {TabsProps} props - Tabs 컴포넌트의 props / Tabs component props\n * @param {React.Ref<HTMLDivElement>} ref - div 요소 ref / div element ref\n * @returns {JSX.Element} Tabs 컴포넌트 / Tabs component\n */\nconst Tabs = React.forwardRef<HTMLDivElement, TabsProps>(\n ({ \n className, \n value,\n defaultValue,\n onValueChange,\n orientation = \"horizontal\",\n variant = \"default\",\n size = \"md\",\n children,\n ...props \n }, ref) => {\n const [activeTab, setActiveTab] = React.useState(value || defaultValue || \"\")\n const isControlled = value !== undefined\n const currentValue = isControlled ? value : activeTab\n\n const handleTabChange = (newValue: string) => {\n if (!isControlled) {\n setActiveTab(newValue)\n }\n onValueChange?.(newValue)\n }\n\n React.useEffect(() => {\n if (value !== undefined) {\n setActiveTab(value)\n }\n }, [value])\n\n return (\n <div\n ref={ref}\n className={merge(\n \"w-full\",\n orientation === \"vertical\" && \"flex\",\n className\n )}\n {...props}\n >\n {React.Children.map(children, (child) => {\n if (React.isValidElement(child)) {\n // TabsContent인 경우 active prop만 설정 (value는 원래 값 유지)\n if (child.type === TabsContent) {\n const childProps = child.props as TabsContentProps\n return React.cloneElement(child, {\n active: childProps.value === currentValue\n } as Partial<TabsContentProps>)\n }\n // TabsList인 경우에만 onValueChange 전달\n if (child.type === TabsList) {\n return React.cloneElement(child, {\n value: currentValue,\n onValueChange: handleTabChange,\n orientation,\n variant,\n size\n } as Partial<TabsListProps>)\n }\n // 다른 React 컴포넌트들 (다른 custom wrapper 등)\n // HTML 요소가 아닌 경우에만 props 전달\n if (typeof child.type !== 'string') {\n return React.cloneElement(child, {\n value: currentValue,\n onValueChange: handleTabChange,\n orientation,\n variant,\n size\n } as Record<string, unknown>)\n }\n }\n return child\n })}\n </div>\n )\n }\n)\nTabs.displayName = \"Tabs\"\n\n/**\n * TabsList 컴포넌트의 props / TabsList component props\n * @typedef {Object} TabsListProps\n * @property {string} [value] - 현재 활성화된 탭 값 (Tabs에서 자동 전달) / Currently active tab value (auto-passed from Tabs)\n * @property {(value: string) => void} [onValueChange] - 탭 변경 콜백 (Tabs에서 자동 전달) / Tab change callback (auto-passed from Tabs)\n * @property {\"horizontal\" | \"vertical\"} [orientation] - 탭 방향 (Tabs에서 자동 전달) / Tab orientation (auto-passed from Tabs)\n * @property {\"default\" | \"pills\" | \"underline\" | \"cards\"} [variant] - 탭 스타일 (Tabs에서 자동 전달) / Tab style (auto-passed from Tabs)\n * @property {\"sm\" | \"md\" | \"lg\"} [size] - 탭 크기 (Tabs에서 자동 전달) / Tab size (auto-passed from Tabs)\n * @extends {React.HTMLAttributes<HTMLDivElement>}\n */\nexport interface TabsListProps extends React.HTMLAttributes<HTMLDivElement> {\n value?: string\n onValueChange?: (value: string) => void\n orientation?: \"horizontal\" | \"vertical\"\n variant?: \"default\" | \"pills\" | \"underline\" | \"cards\"\n size?: \"sm\" | \"md\" | \"lg\"\n}\n\n/**\n * TabsList 컴포넌트 / TabsList component\n * 탭 트리거 목록을 표시합니다. Tabs 컴포넌트 내부에서 사용됩니다.\n * Displays the list of tab triggers. Used inside Tabs component.\n * \n * @component\n * @param {TabsListProps} props - TabsList 컴포넌트의 props / TabsList component props\n * @param {React.Ref<HTMLDivElement>} ref - div 요소 ref / div element ref\n * @returns {JSX.Element} TabsList 컴포넌트 / TabsList component\n */\nconst TabsList = React.forwardRef<HTMLDivElement, TabsListProps>(\n ({ \n className, \n value,\n onValueChange,\n orientation = \"horizontal\",\n variant = \"default\",\n size = \"md\",\n children,\n ...props \n }, ref) => {\n const listRef = React.useRef<HTMLDivElement>(null)\n React.useImperativeHandle(ref, () => listRef.current as HTMLDivElement)\n \n // 모든 탭 트리거의 value를 수집\n const tabValues = React.useMemo(() => {\n const values: string[] = []\n React.Children.forEach(children, (child) => {\n if (React.isValidElement(child)) {\n const childProps = child.props as { value?: string }\n if (childProps.value) {\n values.push(childProps.value)\n }\n }\n })\n return values\n }, [children])\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {\n if (!value || tabValues.length === 0) return\n\n const currentIndex = tabValues.indexOf(value)\n if (currentIndex === -1) return\n\n let newIndex = currentIndex\n\n if (orientation === \"horizontal\") {\n if (e.key === \"ArrowLeft\") {\n e.preventDefault()\n newIndex = currentIndex > 0 ? currentIndex - 1 : tabValues.length - 1\n } else if (e.key === \"ArrowRight\") {\n e.preventDefault()\n newIndex = currentIndex < tabValues.length - 1 ? currentIndex + 1 : 0\n } else if (e.key === \"Home\") {\n e.preventDefault()\n newIndex = 0\n } else if (e.key === \"End\") {\n e.preventDefault()\n newIndex = tabValues.length - 1\n }\n } else {\n if (e.key === \"ArrowUp\") {\n e.preventDefault()\n newIndex = currentIndex > 0 ? currentIndex - 1 : tabValues.length - 1\n } else if (e.key === \"ArrowDown\") {\n e.preventDefault()\n newIndex = currentIndex < tabValues.length - 1 ? currentIndex + 1 : 0\n } else if (e.key === \"Home\") {\n e.preventDefault()\n newIndex = 0\n } else if (e.key === \"End\") {\n e.preventDefault()\n newIndex = tabValues.length - 1\n }\n }\n\n if (newIndex !== currentIndex && tabValues[newIndex]) {\n onValueChange?.(tabValues[newIndex])\n // 포커스 이동\n const triggerElement = listRef.current?.querySelector(\n `[data-tab-value=\"${tabValues[newIndex]}\"]`\n ) as HTMLElement\n triggerElement?.focus()\n }\n }\n const getVariantClasses = () => {\n switch (variant) {\n case \"pills\":\n return \"bg-muted p-3 rounded-xl border border-border/50\"\n case \"underline\":\n return \"border-b border-border\"\n case \"cards\":\n return \"bg-muted/80 p-3 rounded-xl border border-border/50\"\n default:\n return \"bg-muted p-3 rounded-xl border border-border/50\"\n }\n }\n\n const getSizeClasses = () => {\n switch (size) {\n case \"sm\":\n return \"h-12\"\n case \"lg\":\n return \"h-16\"\n default:\n return \"h-14\"\n }\n }\n\n return (\n <div\n ref={listRef}\n role=\"tablist\"\n aria-orientation={orientation}\n onKeyDown={handleKeyDown}\n className={merge(\n \"flex items-center justify-center\",\n orientation === \"vertical\" && \"flex-col\",\n getVariantClasses(),\n getSizeClasses(),\n className\n )}\n {...props}\n >\n {React.Children.map(children, (child) => {\n if (React.isValidElement(child)) {\n // Only pass tab props to non-HTML elements (React components)\n if (typeof child.type === 'string') {\n return child\n }\n const childProps = child.props as { value?: string }\n return React.cloneElement(child, {\n onValueChange,\n orientation,\n variant,\n size,\n active: childProps.value === value\n } as Partial<TabsTriggerProps>)\n }\n return child\n })}\n </div>\n )\n }\n)\nTabsList.displayName = \"TabsList\"\n\n/**\n * TabsTrigger 컴포넌트의 props\n * @typedef {Object} TabsTriggerProps\n * @property {string} value - 탭 트리거의 고유 값 (TabsContent의 value와 일치해야 함)\n * @property {(value: string) => void} [onValueChange] - 탭 변경 콜백 (TabsList에서 자동 전달)\n * @property {\"horizontal\" | \"vertical\"} [orientation] - 탭 방향 (TabsList에서 자동 전달)\n * @property {\"default\" | \"pills\" | \"underline\" | \"cards\"} [variant] - 탭 스타일 (TabsList에서 자동 전달)\n * @property {\"sm\" | \"md\" | \"lg\"} [size] - 탭 크기 (TabsList에서 자동 전달)\n * @property {boolean} [active] - 탭 활성화 상태 (자동 설정됨)\n * @extends {React.ButtonHTMLAttributes<HTMLButtonElement>}\n */\nexport interface TabsTriggerProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n value: string\n onValueChange?: (value: string) => void\n orientation?: \"horizontal\" | \"vertical\"\n variant?: \"default\" | \"pills\" | \"underline\" | \"cards\"\n size?: \"sm\" | \"md\" | \"lg\"\n active?: boolean\n}\n\n/**\n * TabsTrigger 컴포넌트 / TabsTrigger component\n * 탭을 활성화하는 버튼입니다. TabsList 컴포넌트 내부에서 사용됩니다.\n * Button that activates a tab. Used inside TabsList component.\n * \n * @component\n * @param {TabsTriggerProps} props - TabsTrigger 컴포넌트의 props / TabsTrigger component props\n * @param {React.Ref<HTMLButtonElement>} ref - button 요소 ref / button element ref\n * @returns {JSX.Element} TabsTrigger 컴포넌트 / TabsTrigger component\n */\nconst TabsTrigger = React.forwardRef<HTMLButtonElement, TabsTriggerProps>(\n ({ \n className,\n value,\n onValueChange,\n orientation: _orientation = \"horizontal\",\n variant = \"default\",\n size = \"md\",\n active = false,\n children,\n ...props\n }, ref) => {\n const getVariantClasses = () => {\n switch (variant) {\n case \"pills\":\n return merge(\n \"inline-flex items-center justify-center whitespace-nowrap rounded-lg px-4 py-2.5 text-sm font-medium ring-offset-background transition-all duration-200 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50\",\n active\n ? \"bg-background text-foreground shadow-md\"\n : \"text-muted-foreground hover:text-foreground hover:bg-muted\"\n )\n case \"underline\":\n return merge(\n \"inline-flex items-center justify-center whitespace-nowrap border-b-2 px-4 py-2.5 text-sm font-medium ring-offset-background transition-all duration-200 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50\",\n active\n ? \"border-primary text-primary\"\n : \"border-transparent text-muted-foreground hover:text-foreground\"\n )\n case \"cards\":\n return merge(\n \"inline-flex items-center justify-center whitespace-nowrap rounded-lg px-4 py-2.5 text-sm font-medium ring-offset-background transition-all duration-200 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50\",\n active\n ? \"bg-background text-foreground shadow-md\"\n : \"text-muted-foreground hover:text-foreground hover:bg-muted\"\n )\n default:\n return merge(\n \"inline-flex items-center justify-center whitespace-nowrap rounded-lg px-4 py-2.5 text-sm font-medium ring-offset-background transition-all duration-200 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50\",\n active\n ? \"bg-background text-foreground shadow-md\"\n : \"text-muted-foreground hover:text-foreground hover:bg-muted\"\n )\n }\n }\n\n const getSizeClasses = () => {\n switch (size) {\n case \"sm\":\n return \"h-10 px-4 py-2 text-xs\"\n case \"lg\":\n return \"h-14 px-6 py-3 text-base\"\n default:\n return \"h-12 px-5 py-2.5 text-sm\"\n }\n }\n\n const handleClick = () => {\n if (onValueChange) {\n onValueChange(value)\n }\n }\n\n return (\n <button\n ref={ref}\n role=\"tab\"\n aria-selected={active}\n aria-controls={`tabpanel-${value}`}\n id={`tab-${value}`}\n data-tab-value={value}\n tabIndex={active ? 0 : -1}\n className={merge(\n getVariantClasses(),\n getSizeClasses(),\n className\n )}\n onClick={handleClick}\n type=\"button\"\n {...props}\n >\n {children}\n </button>\n )\n }\n)\nTabsTrigger.displayName = \"TabsTrigger\"\n\n// 편의 컴포넌트들\nconst TabsPills = React.forwardRef<HTMLDivElement, TabsProps>(\n (props, ref) => <Tabs ref={ref} variant=\"pills\" {...props} />\n)\nTabsPills.displayName = \"TabsPills\"\n\nconst TabsUnderline = React.forwardRef<HTMLDivElement, TabsProps>(\n (props, ref) => <Tabs ref={ref} variant=\"underline\" {...props} />\n)\nTabsUnderline.displayName = \"TabsUnderline\"\n\nconst TabsCards = React.forwardRef<HTMLDivElement, TabsProps>(\n (props, ref) => <Tabs ref={ref} variant=\"cards\" {...props} />\n)\nTabsCards.displayName = \"TabsCards\"\n\nexport { Tabs, TabsList, TabsTrigger, TabsContent, TabsPills, TabsUnderline, TabsCards } "]}
1
+ {"version":3,"sources":["../src/components/Accordion.tsx","../src/components/Tabs.tsx"],"names":["Accordion","React","children","className","type","defaultValue","value","onValueChange","collapsible","props","ref","openItems","setOpenItems","handleItemToggle","itemValue","newOpenItems","item","itemValues","values","child","childProps","handleKeyDown","_a","target","currentValue","currentIndex","newIndex","triggerElement","jsx","merge","AccordionItem","disabled","onToggle","isOpen","AccordionTrigger","icon","iconPosition","defaultIcon","Icon","contentId","triggerId","jsxs","AccordionContent","dataValue","height","setHeight","contentRef","TabsContent","active","Tabs","orientation","variant","size","activeTab","setActiveTab","isControlled","handleTabChange","newValue","TabsList","listRef","tabValues","getVariantClasses","getSizeClasses","TabsTrigger","_orientation","handleClick","TabsPills","TabsUnderline","TabsCards"],"mappings":"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","file":"chunk-N56BUOCD.mjs","sourcesContent":["\"use client\"\n\nimport React from \"react\"\nimport { merge } from \"../lib/utils\"\nimport { Icon } from \"./Icon\"\n\n/**\n * Accordion 컴포넌트의 props / Accordion component props\n * @typedef {Object} AccordionProps\n * @property {React.ReactNode} children - AccordionItem 컴포넌트들 / AccordionItem components\n * @property {string} [className] - 추가 CSS 클래스 / Additional CSS class\n * @property {\"single\" | \"multiple\"} [type=\"single\"] - 단일 또는 다중 아이템 열기 허용 / Allow single or multiple items to be open\n * @property {string | string[]} [defaultValue] - 초기 열린 아이템 값 (비제어 컴포넌트) / Initial open item value (uncontrolled component)\n * @property {string | string[]} [value] - 현재 열린 아이템 값 (제어 컴포넌트) / Current open item value (controlled component)\n * @property {(value: string | string[]) => void} [onValueChange] - 아이템 열림/닫힘 콜백 / Item open/close callback\n * @property {boolean} [collapsible=false] - 단일 모드에서 열린 아이템을 닫을 수 있는지 여부 / Whether open item can be closed in single mode\n */\ninterface AccordionProps {\n children: React.ReactNode\n className?: string\n type?: \"single\" | \"multiple\"\n defaultValue?: string | string[]\n value?: string | string[]\n onValueChange?: (value: string | string[]) => void\n collapsible?: boolean\n}\n\n/**\n * Accordion 컴포넌트 / Accordion component\n * \n * 접을 수 있는 콘텐츠 섹션을 제공하는 컴포넌트입니다.\n * 키보드 네비게이션(Arrow keys, Home/End)을 지원하며, ARIA 속성을 자동으로 설정합니다.\n * \n * Component that provides collapsible content sections.\n * Supports keyboard navigation (Arrow keys, Home/End) and automatically sets ARIA attributes.\n * \n * @component\n * @example\n * // 기본 사용 (단일 열기) / Basic usage (single open)\n * <Accordion type=\"single\">\n * <AccordionItem value=\"item1\">\n * <AccordionTrigger>제목 1</AccordionTrigger>\n * <AccordionContent>내용 1</AccordionContent>\n * </AccordionItem>\n * <AccordionItem value=\"item2\">\n * <AccordionTrigger>제목 2</AccordionTrigger>\n * <AccordionContent>내용 2</AccordionContent>\n * </AccordionItem>\n * </Accordion>\n * \n * @example\n * // 다중 열기 / Multiple open\n * <Accordion type=\"multiple\" defaultValue={[\"item1\", \"item2\"]}>\n * <AccordionItem value=\"item1\">\n * <AccordionTrigger>제목 1</AccordionTrigger>\n * <AccordionContent>내용 1</AccordionContent>\n * </AccordionItem>\n * </Accordion>\n * \n * @example\n * // 제어 컴포넌트 / Controlled component\n * const [openItems, setOpenItems] = useState<string[]>([])\n * <Accordion type=\"multiple\" value={openItems} onValueChange={setOpenItems}>\n * <AccordionItem value=\"item1\">\n * <AccordionTrigger>제목</AccordionTrigger>\n * <AccordionContent>내용</AccordionContent>\n * </AccordionItem>\n * </Accordion>\n * \n * @param {AccordionProps} props - Accordion 컴포넌트의 props / Accordion component props\n * @param {React.Ref<HTMLDivElement>} ref - div 요소 ref / div element ref\n * @returns {JSX.Element} Accordion 컴포넌트 / Accordion component\n */\nconst Accordion = React.forwardRef<HTMLDivElement, AccordionProps>(\n ({ \n children, \n className,\n type = \"single\",\n defaultValue,\n value,\n onValueChange,\n collapsible = false,\n ...props \n }, ref) => {\n const [openItems, setOpenItems] = React.useState<string[]>(\n value ? (Array.isArray(value) ? value : [value]) : \n defaultValue ? (Array.isArray(defaultValue) ? defaultValue : [defaultValue]) : []\n )\n\n React.useEffect(() => {\n if (value !== undefined) {\n setOpenItems(Array.isArray(value) ? value : [value])\n }\n }, [value])\n\n const handleItemToggle = (itemValue: string) => {\n let newOpenItems: string[]\n\n if (type === \"single\") {\n if (openItems.includes(itemValue)) {\n newOpenItems = collapsible ? [] : openItems\n } else {\n newOpenItems = [itemValue]\n }\n } else {\n if (openItems.includes(itemValue)) {\n newOpenItems = openItems.filter(item => item !== itemValue)\n } else {\n newOpenItems = [...openItems, itemValue]\n }\n }\n\n setOpenItems(newOpenItems)\n onValueChange?.(type === \"single\" ? newOpenItems[0] || \"\" : newOpenItems)\n }\n\n // 모든 아이템의 value를 수집\n const itemValues = React.useMemo(() => {\n const values: string[] = []\n React.Children.forEach(children, (child) => {\n if (React.isValidElement(child)) {\n const childProps = child.props as { value?: string }\n if (childProps.value) {\n values.push(childProps.value)\n }\n }\n })\n return values\n }, [children])\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {\n const target = e.target as HTMLElement\n if (!target.hasAttribute('data-accordion-trigger')) return\n\n const currentValue = target.getAttribute('data-accordion-value')\n if (!currentValue) return\n\n const currentIndex = itemValues.indexOf(currentValue)\n if (currentIndex === -1) return\n\n let newIndex = currentIndex\n\n if (e.key === \"ArrowDown\") {\n e.preventDefault()\n newIndex = currentIndex < itemValues.length - 1 ? currentIndex + 1 : 0\n } else if (e.key === \"ArrowUp\") {\n e.preventDefault()\n newIndex = currentIndex > 0 ? currentIndex - 1 : itemValues.length - 1\n } else if (e.key === \"Home\") {\n e.preventDefault()\n newIndex = 0\n } else if (e.key === \"End\") {\n e.preventDefault()\n newIndex = itemValues.length - 1\n }\n\n if (newIndex !== currentIndex && itemValues[newIndex]) {\n const triggerElement = target.closest('[data-accordion-item]')?.querySelector(\n `[data-accordion-value=\"${itemValues[newIndex]}\"]`\n ) as HTMLElement\n triggerElement?.focus()\n }\n }\n\n return (\n <div\n ref={ref}\n className={merge(\"space-y-2\", className)}\n onKeyDown={handleKeyDown}\n {...props}\n >\n {React.Children.map(children, (child) => {\n if (React.isValidElement(child)) {\n return React.cloneElement(child, {\n openItems,\n onToggle: handleItemToggle\n } as Partial<AccordionItemProps>)\n }\n return child\n })}\n </div>\n )\n }\n)\nAccordion.displayName = \"Accordion\"\n\n/**\n * AccordionItem 컴포넌트의 props / AccordionItem component props\n * @typedef {Object} AccordionItemProps\n * @property {string} value - 아이템의 고유 값 / Item unique value\n * @property {React.ReactNode} children - AccordionTrigger와 AccordionContent / AccordionTrigger and AccordionContent\n * @property {string} [className] - 추가 CSS 클래스 / Additional CSS class\n * @property {boolean} [disabled=false] - 아이템 비활성화 여부 / Item disabled state\n * @property {string[]} [openItems] - 열린 아이템 목록 (Accordion에서 자동 전달) / Open items list (auto-passed from Accordion)\n * @property {(value: string) => void} [onToggle] - 토글 콜백 (Accordion에서 자동 전달) / Toggle callback (auto-passed from Accordion)\n */\ninterface AccordionItemProps {\n value: string\n children: React.ReactNode\n className?: string\n disabled?: boolean\n openItems?: string[]\n onToggle?: (value: string) => void\n}\n\n/**\n * AccordionItem 컴포넌트 / AccordionItem component\n * 아코디언의 개별 아이템을 감싸는 컨테이너입니다.\n * Container that wraps an individual accordion item.\n * \n * @component\n * @param {AccordionItemProps} props - AccordionItem 컴포넌트의 props / AccordionItem component props\n * @param {React.Ref<HTMLDivElement>} ref - div 요소 ref / div element ref\n * @returns {JSX.Element} AccordionItem 컴포넌트 / AccordionItem component\n */\nconst AccordionItem = React.forwardRef<HTMLDivElement, AccordionItemProps>(\n ({ \n value, \n children, \n className,\n disabled = false,\n openItems = [],\n onToggle,\n ...props \n }, ref) => {\n const isOpen = openItems.includes(value)\n\n return (\n <div\n ref={ref}\n data-accordion-item\n className={merge(\n \"border border-border/50 rounded-lg overflow-hidden\",\n disabled && \"opacity-50 pointer-events-none\",\n className\n )}\n {...props}\n >\n {React.Children.map(children, (child) => {\n if (React.isValidElement(child)) {\n return React.cloneElement(child, {\n value,\n isOpen,\n disabled,\n onToggle: () => onToggle?.(value),\n 'data-accordion-value': value\n } as Partial<AccordionTriggerProps | AccordionContentProps>)\n }\n return child\n })}\n </div>\n )\n }\n)\nAccordionItem.displayName = \"AccordionItem\"\n\ninterface AccordionTriggerProps {\n children: React.ReactNode\n className?: string\n icon?: React.ReactNode\n iconPosition?: \"left\" | \"right\"\n value?: string // Optional: AccordionItem에서 자동으로 전달됨 / Optional: Auto-passed from AccordionItem\n isOpen?: boolean\n disabled?: boolean\n onToggle?: () => void\n}\n\nconst AccordionTrigger = React.forwardRef<HTMLButtonElement, AccordionTriggerProps>(\n ({ \n children, \n className,\n icon,\n iconPosition = \"right\",\n value,\n isOpen = false,\n disabled = false,\n onToggle,\n ...props \n }, ref) => {\n const defaultIcon = (\n <Icon \n name=\"chevronDown\" \n size={20} \n className={merge(\n \"transition-transform duration-300 ease-out text-muted-foreground\",\n isOpen && \"rotate-180\"\n )} \n />\n )\n\n const contentId = `accordion-content-${value}`\n const triggerId = `accordion-trigger-${value}`\n\n return (\n <button\n ref={ref}\n id={triggerId}\n data-accordion-trigger\n data-accordion-value={value}\n aria-expanded={isOpen}\n aria-controls={contentId}\n onClick={onToggle}\n disabled={disabled}\n className={merge(\n \"flex w-full items-center justify-between px-6 py-4 text-left font-medium transition-all hover:bg-muted/80 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring/50 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50\",\n className\n )}\n {...props}\n >\n <div className=\"flex items-center gap-3 flex-1\">\n {iconPosition === \"left\" && (icon || defaultIcon)}\n <span className=\"flex-1\">{children}</span>\n </div>\n {iconPosition === \"right\" && (icon || defaultIcon)}\n </button>\n )\n }\n)\nAccordionTrigger.displayName = \"AccordionTrigger\"\n\n/**\n * AccordionTrigger 컴포넌트 / AccordionTrigger component\n * 아코디언 아이템을 열고 닫는 트리거 버튼입니다.\n * Button that opens and closes an accordion item.\n * \n * @component\n * @param {AccordionTriggerProps} props - AccordionTrigger 컴포넌트의 props / AccordionTrigger component props\n * @param {React.Ref<HTMLButtonElement>} ref - button 요소 ref / button element ref\n * @returns {JSX.Element} AccordionTrigger 컴포넌트 / AccordionTrigger component\n */\n\n/**\n * AccordionContent 컴포넌트의 props\n * @typedef {Object} AccordionContentProps\n * @property {React.ReactNode} children - 콘텐츠\n * @property {string} [className] - 추가 CSS 클래스\n * @property {boolean} [isOpen] - 열림 상태 (AccordionItem에서 자동 전달)\n * @property {string} [value] - 아이템 값 (AccordionItem에서 자동 전달)\n * @property {string} ['data-accordion-value'] - 아이템 값 (내부 사용)\n */\ninterface AccordionContentProps {\n children: React.ReactNode\n className?: string\n isOpen?: boolean\n value?: string\n 'data-accordion-value'?: string\n}\n\n/**\n * AccordionContent 컴포넌트 / AccordionContent component\n * 아코디언 아이템의 콘텐츠를 표시합니다.\n * Displays the content of an accordion item.\n * \n * @component\n * @param {AccordionContentProps} props - AccordionContent 컴포넌트의 props / AccordionContent component props\n * @param {React.Ref<HTMLDivElement>} ref - div 요소 ref / div element ref\n * @returns {JSX.Element} AccordionContent 컴포넌트 / AccordionContent component\n */\nconst AccordionContent = React.forwardRef<HTMLDivElement, AccordionContentProps>(\n ({ children, className, isOpen = false, value, 'data-accordion-value': dataValue, ...props }, ref) => {\n const [height, setHeight] = React.useState(0)\n const contentRef = React.useRef<HTMLDivElement>(null)\n const itemValue = value || dataValue || 'unknown'\n\n React.useEffect(() => {\n if (contentRef.current) {\n if (isOpen) {\n setHeight(contentRef.current.scrollHeight)\n } else {\n setHeight(0)\n }\n }\n }, [isOpen, children])\n\n const triggerId = `accordion-trigger-${itemValue}`\n const contentId = `accordion-content-${itemValue}`\n\n return (\n <div\n ref={ref}\n id={contentId}\n role=\"region\"\n aria-labelledby={triggerId}\n hidden={!isOpen}\n className=\"overflow-hidden transition-all duration-300 ease-out\"\n style={{ height: `${height}px` }}\n {...props}\n >\n <div\n ref={contentRef}\n className={merge(\"px-6 pt-2 pb-4\", className)}\n >\n {children}\n </div>\n </div>\n )\n }\n)\nAccordionContent.displayName = \"AccordionContent\"\n\nexport { Accordion, AccordionItem, AccordionTrigger, AccordionContent } ","\"use client\"\n\nimport React from 'react'\nimport { merge } from '../lib/utils'\n\n/**\n * TabsContent 컴포넌트의 props / TabsContent component props\n * @typedef {Object} TabsContentProps\n * @property {string} value - 탭 패널의 고유 값 (TabsTrigger의 value와 일치해야 함) / Unique value for tab panel (must match TabsTrigger value)\n * @property {boolean} [active] - 탭 패널 활성화 상태 (자동 설정됨) / Tab panel active state (auto-set)\n * @extends {React.HTMLAttributes<HTMLDivElement>}\n */\nexport interface TabsContentProps extends React.HTMLAttributes<HTMLDivElement> {\n value: string\n active?: boolean\n}\n\n/**\n * TabsContent 컴포넌트 / TabsContent component\n * 탭의 콘텐츠 패널을 표시합니다. Tabs 컴포넌트 내부에서 사용됩니다.\n * Displays the tab content panel. Used inside Tabs component.\n * \n * @component\n * @param {TabsContentProps} props - TabsContent 컴포넌트의 props / TabsContent component props\n * @param {React.Ref<HTMLDivElement>} ref - div 요소 ref / div element ref\n * @returns {JSX.Element} TabsContent 컴포넌트 / TabsContent component\n */\nconst TabsContent = React.forwardRef<HTMLDivElement, TabsContentProps>(\n ({ className, value, active, children, ...props }, ref) => {\n // active prop이 명시적으로 false로 설정된 경우에만 숨김\n if (active === false) return null\n\n return (\n <div\n ref={ref}\n role=\"tabpanel\"\n id={`tabpanel-${value}`}\n aria-labelledby={`tab-${value}`}\n hidden={!active}\n className={merge(\n \"mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-2\",\n className\n )}\n {...props}\n >\n {children}\n </div>\n )\n }\n)\nTabsContent.displayName = \"TabsContent\"\n\n/**\n * Tabs 컴포넌트의 props / Tabs component props\n * @typedef {Object} TabsProps\n * @property {string} [value] - 현재 활성화된 탭 값 (제어 컴포넌트) / Currently active tab value (controlled component)\n * @property {string} [defaultValue] - 초기 활성화된 탭 값 (비제어 컴포넌트) / Initial active tab value (uncontrolled component)\n * @property {(value: string) => void} [onValueChange] - 탭 변경 시 호출되는 콜백 / Callback when tab changes\n * @property {\"horizontal\" | \"vertical\"} [orientation=\"horizontal\"] - 탭 방향 / Tab orientation\n * @property {\"default\" | \"pills\" | \"underline\" | \"cards\"} [variant=\"default\"] - 탭 스타일 변형 / Tab style variant\n * @property {\"sm\" | \"md\" | \"lg\"} [size=\"md\"] - 탭 크기 / Tab size\n * @extends {React.HTMLAttributes<HTMLDivElement>}\n */\nexport interface TabsProps extends React.HTMLAttributes<HTMLDivElement> {\n value?: string\n defaultValue?: string\n onValueChange?: (value: string) => void\n orientation?: \"horizontal\" | \"vertical\"\n variant?: \"default\" | \"pills\" | \"underline\" | \"cards\"\n size?: \"sm\" | \"md\" | \"lg\"\n}\n\n/**\n * Tabs 컴포넌트 / Tabs component\n * \n * 탭 네비게이션을 제공하는 컴포넌트입니다.\n * 키보드 네비게이션(Arrow keys, Home/End)을 지원하며, ARIA 속성을 자동으로 설정합니다.\n * \n * Component that provides tab navigation.\n * Supports keyboard navigation (Arrow keys, Home/End) and automatically sets ARIA attributes.\n * \n * @component\n * @example\n * // 기본 사용 / Basic usage\n * <Tabs defaultValue=\"tab1\">\n * <TabsList>\n * <TabsTrigger value=\"tab1\">탭 1</TabsTrigger>\n * <TabsTrigger value=\"tab2\">탭 2</TabsTrigger>\n * </TabsList>\n * <TabsContent value=\"tab1\">탭 1 내용</TabsContent>\n * <TabsContent value=\"tab2\">탭 2 내용</TabsContent>\n * </Tabs>\n * \n * @example\n * // 제어 컴포넌트 / Controlled component\n * const [activeTab, setActiveTab] = useState(\"tab1\")\n * <Tabs value={activeTab} onValueChange={setActiveTab}>\n * <TabsList>\n * <TabsTrigger value=\"tab1\">탭 1</TabsTrigger>\n * </TabsList>\n * <TabsContent value=\"tab1\">내용</TabsContent>\n * </Tabs>\n * \n * @example\n * // 다양한 변형 / Various variants\n * <Tabs variant=\"pills\" size=\"lg\">\n * <TabsList>\n * <TabsTrigger value=\"tab1\">Pills 스타일</TabsTrigger>\n * </TabsList>\n * </Tabs>\n * \n * @param {TabsProps} props - Tabs 컴포넌트의 props / Tabs component props\n * @param {React.Ref<HTMLDivElement>} ref - div 요소 ref / div element ref\n * @returns {JSX.Element} Tabs 컴포넌트 / Tabs component\n */\nconst Tabs = React.forwardRef<HTMLDivElement, TabsProps>(\n ({ \n className, \n value,\n defaultValue,\n onValueChange,\n orientation = \"horizontal\",\n variant = \"default\",\n size = \"md\",\n children,\n ...props \n }, ref) => {\n const [activeTab, setActiveTab] = React.useState(value || defaultValue || \"\")\n const isControlled = value !== undefined\n const currentValue = isControlled ? value : activeTab\n\n const handleTabChange = (newValue: string) => {\n if (!isControlled) {\n setActiveTab(newValue)\n }\n onValueChange?.(newValue)\n }\n\n React.useEffect(() => {\n if (value !== undefined) {\n setActiveTab(value)\n }\n }, [value])\n\n return (\n <div\n ref={ref}\n className={merge(\n \"w-full\",\n orientation === \"vertical\" && \"flex\",\n className\n )}\n {...props}\n >\n {React.Children.map(children, (child) => {\n if (React.isValidElement(child)) {\n // TabsContent인 경우 active prop만 설정 (value는 원래 값 유지)\n if (child.type === TabsContent) {\n const childProps = child.props as TabsContentProps\n return React.cloneElement(child, {\n active: childProps.value === currentValue\n } as Partial<TabsContentProps>)\n }\n // TabsList인 경우에만 onValueChange 전달\n if (child.type === TabsList) {\n return React.cloneElement(child, {\n value: currentValue,\n onValueChange: handleTabChange,\n orientation,\n variant,\n size\n } as Partial<TabsListProps>)\n }\n // 다른 React 컴포넌트들 (다른 custom wrapper 등)\n // HTML 요소가 아닌 경우에만 props 전달\n if (typeof child.type !== 'string') {\n return React.cloneElement(child, {\n value: currentValue,\n onValueChange: handleTabChange,\n orientation,\n variant,\n size\n } as Record<string, unknown>)\n }\n }\n return child\n })}\n </div>\n )\n }\n)\nTabs.displayName = \"Tabs\"\n\n/**\n * TabsList 컴포넌트의 props / TabsList component props\n * @typedef {Object} TabsListProps\n * @property {string} [value] - 현재 활성화된 탭 값 (Tabs에서 자동 전달) / Currently active tab value (auto-passed from Tabs)\n * @property {(value: string) => void} [onValueChange] - 탭 변경 콜백 (Tabs에서 자동 전달) / Tab change callback (auto-passed from Tabs)\n * @property {\"horizontal\" | \"vertical\"} [orientation] - 탭 방향 (Tabs에서 자동 전달) / Tab orientation (auto-passed from Tabs)\n * @property {\"default\" | \"pills\" | \"underline\" | \"cards\"} [variant] - 탭 스타일 (Tabs에서 자동 전달) / Tab style (auto-passed from Tabs)\n * @property {\"sm\" | \"md\" | \"lg\"} [size] - 탭 크기 (Tabs에서 자동 전달) / Tab size (auto-passed from Tabs)\n * @extends {React.HTMLAttributes<HTMLDivElement>}\n */\nexport interface TabsListProps extends React.HTMLAttributes<HTMLDivElement> {\n value?: string\n onValueChange?: (value: string) => void\n orientation?: \"horizontal\" | \"vertical\"\n variant?: \"default\" | \"pills\" | \"underline\" | \"cards\"\n size?: \"sm\" | \"md\" | \"lg\"\n}\n\n/**\n * TabsList 컴포넌트 / TabsList component\n * 탭 트리거 목록을 표시합니다. Tabs 컴포넌트 내부에서 사용됩니다.\n * Displays the list of tab triggers. Used inside Tabs component.\n * \n * @component\n * @param {TabsListProps} props - TabsList 컴포넌트의 props / TabsList component props\n * @param {React.Ref<HTMLDivElement>} ref - div 요소 ref / div element ref\n * @returns {JSX.Element} TabsList 컴포넌트 / TabsList component\n */\nconst TabsList = React.forwardRef<HTMLDivElement, TabsListProps>(\n ({ \n className, \n value,\n onValueChange,\n orientation = \"horizontal\",\n variant = \"default\",\n size = \"md\",\n children,\n ...props \n }, ref) => {\n const listRef = React.useRef<HTMLDivElement>(null)\n React.useImperativeHandle(ref, () => listRef.current as HTMLDivElement)\n \n // 모든 탭 트리거의 value를 수집\n const tabValues = React.useMemo(() => {\n const values: string[] = []\n React.Children.forEach(children, (child) => {\n if (React.isValidElement(child)) {\n const childProps = child.props as { value?: string }\n if (childProps.value) {\n values.push(childProps.value)\n }\n }\n })\n return values\n }, [children])\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {\n if (!value || tabValues.length === 0) return\n\n const currentIndex = tabValues.indexOf(value)\n if (currentIndex === -1) return\n\n let newIndex = currentIndex\n\n if (orientation === \"horizontal\") {\n if (e.key === \"ArrowLeft\") {\n e.preventDefault()\n newIndex = currentIndex > 0 ? currentIndex - 1 : tabValues.length - 1\n } else if (e.key === \"ArrowRight\") {\n e.preventDefault()\n newIndex = currentIndex < tabValues.length - 1 ? currentIndex + 1 : 0\n } else if (e.key === \"Home\") {\n e.preventDefault()\n newIndex = 0\n } else if (e.key === \"End\") {\n e.preventDefault()\n newIndex = tabValues.length - 1\n }\n } else {\n if (e.key === \"ArrowUp\") {\n e.preventDefault()\n newIndex = currentIndex > 0 ? currentIndex - 1 : tabValues.length - 1\n } else if (e.key === \"ArrowDown\") {\n e.preventDefault()\n newIndex = currentIndex < tabValues.length - 1 ? currentIndex + 1 : 0\n } else if (e.key === \"Home\") {\n e.preventDefault()\n newIndex = 0\n } else if (e.key === \"End\") {\n e.preventDefault()\n newIndex = tabValues.length - 1\n }\n }\n\n if (newIndex !== currentIndex && tabValues[newIndex]) {\n onValueChange?.(tabValues[newIndex])\n // 포커스 이동\n const triggerElement = listRef.current?.querySelector(\n `[data-tab-value=\"${tabValues[newIndex]}\"]`\n ) as HTMLElement\n triggerElement?.focus()\n }\n }\n const getVariantClasses = () => {\n switch (variant) {\n case \"pills\":\n return \"bg-muted p-3 rounded-xl border border-border/50\"\n case \"underline\":\n return \"border-b border-border\"\n case \"cards\":\n return \"bg-muted/80 p-3 rounded-xl border border-border/50\"\n default:\n return \"bg-muted p-3 rounded-xl border border-border/50\"\n }\n }\n\n const getSizeClasses = () => {\n switch (size) {\n case \"sm\":\n return \"h-12\"\n case \"lg\":\n return \"h-16\"\n default:\n return \"h-14\"\n }\n }\n\n return (\n <div\n ref={listRef}\n role=\"tablist\"\n aria-orientation={orientation}\n onKeyDown={handleKeyDown}\n className={merge(\n \"flex items-center justify-center\",\n orientation === \"vertical\" && \"flex-col\",\n getVariantClasses(),\n getSizeClasses(),\n className\n )}\n {...props}\n >\n {React.Children.map(children, (child) => {\n if (React.isValidElement(child)) {\n // Only pass tab props to non-HTML elements (React components)\n if (typeof child.type === 'string') {\n return child\n }\n const childProps = child.props as { value?: string }\n return React.cloneElement(child, {\n onValueChange,\n orientation,\n variant,\n size,\n active: childProps.value === value\n } as Partial<TabsTriggerProps>)\n }\n return child\n })}\n </div>\n )\n }\n)\nTabsList.displayName = \"TabsList\"\n\n/**\n * TabsTrigger 컴포넌트의 props\n * @typedef {Object} TabsTriggerProps\n * @property {string} value - 탭 트리거의 고유 값 (TabsContent의 value와 일치해야 함)\n * @property {(value: string) => void} [onValueChange] - 탭 변경 콜백 (TabsList에서 자동 전달)\n * @property {\"horizontal\" | \"vertical\"} [orientation] - 탭 방향 (TabsList에서 자동 전달)\n * @property {\"default\" | \"pills\" | \"underline\" | \"cards\"} [variant] - 탭 스타일 (TabsList에서 자동 전달)\n * @property {\"sm\" | \"md\" | \"lg\"} [size] - 탭 크기 (TabsList에서 자동 전달)\n * @property {boolean} [active] - 탭 활성화 상태 (자동 설정됨)\n * @extends {React.ButtonHTMLAttributes<HTMLButtonElement>}\n */\nexport interface TabsTriggerProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n value: string\n onValueChange?: (value: string) => void\n orientation?: \"horizontal\" | \"vertical\"\n variant?: \"default\" | \"pills\" | \"underline\" | \"cards\"\n size?: \"sm\" | \"md\" | \"lg\"\n active?: boolean\n}\n\n/**\n * TabsTrigger 컴포넌트 / TabsTrigger component\n * 탭을 활성화하는 버튼입니다. TabsList 컴포넌트 내부에서 사용됩니다.\n * Button that activates a tab. Used inside TabsList component.\n * \n * @component\n * @param {TabsTriggerProps} props - TabsTrigger 컴포넌트의 props / TabsTrigger component props\n * @param {React.Ref<HTMLButtonElement>} ref - button 요소 ref / button element ref\n * @returns {JSX.Element} TabsTrigger 컴포넌트 / TabsTrigger component\n */\nconst TabsTrigger = React.forwardRef<HTMLButtonElement, TabsTriggerProps>(\n ({ \n className,\n value,\n onValueChange,\n orientation: _orientation = \"horizontal\",\n variant = \"default\",\n size = \"md\",\n active = false,\n children,\n ...props\n }, ref) => {\n const getVariantClasses = () => {\n switch (variant) {\n case \"pills\":\n return merge(\n \"inline-flex items-center justify-center whitespace-nowrap rounded-lg px-4 py-2.5 text-sm font-medium ring-offset-background transition-all duration-200 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50\",\n active\n ? \"bg-background text-foreground shadow-md\"\n : \"text-muted-foreground hover:text-foreground hover:bg-muted\"\n )\n case \"underline\":\n return merge(\n \"inline-flex items-center justify-center whitespace-nowrap border-b-2 px-4 py-2.5 text-sm font-medium ring-offset-background transition-all duration-200 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50\",\n active\n ? \"border-primary text-primary\"\n : \"border-transparent text-muted-foreground hover:text-foreground\"\n )\n case \"cards\":\n return merge(\n \"inline-flex items-center justify-center whitespace-nowrap rounded-lg px-4 py-2.5 text-sm font-medium ring-offset-background transition-all duration-200 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50\",\n active\n ? \"bg-background text-foreground shadow-md\"\n : \"text-muted-foreground hover:text-foreground hover:bg-muted\"\n )\n default:\n return merge(\n \"inline-flex items-center justify-center whitespace-nowrap rounded-lg px-4 py-2.5 text-sm font-medium ring-offset-background transition-all duration-200 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50\",\n active\n ? \"bg-background text-foreground shadow-md\"\n : \"text-muted-foreground hover:text-foreground hover:bg-muted\"\n )\n }\n }\n\n const getSizeClasses = () => {\n switch (size) {\n case \"sm\":\n return \"h-10 px-4 py-2 text-xs\"\n case \"lg\":\n return \"h-14 px-6 py-3 text-base\"\n default:\n return \"h-12 px-5 py-2.5 text-sm\"\n }\n }\n\n const handleClick = () => {\n if (onValueChange) {\n onValueChange(value)\n }\n }\n\n return (\n <button\n ref={ref}\n role=\"tab\"\n aria-selected={active}\n aria-controls={`tabpanel-${value}`}\n id={`tab-${value}`}\n data-tab-value={value}\n tabIndex={active ? 0 : -1}\n className={merge(\n getVariantClasses(),\n getSizeClasses(),\n className\n )}\n onClick={handleClick}\n type=\"button\"\n {...props}\n >\n {children}\n </button>\n )\n }\n)\nTabsTrigger.displayName = \"TabsTrigger\"\n\n// 편의 컴포넌트들\nconst TabsPills = React.forwardRef<HTMLDivElement, TabsProps>(\n (props, ref) => <Tabs ref={ref} variant=\"pills\" {...props} />\n)\nTabsPills.displayName = \"TabsPills\"\n\nconst TabsUnderline = React.forwardRef<HTMLDivElement, TabsProps>(\n (props, ref) => <Tabs ref={ref} variant=\"underline\" {...props} />\n)\nTabsUnderline.displayName = \"TabsUnderline\"\n\nconst TabsCards = React.forwardRef<HTMLDivElement, TabsProps>(\n (props, ref) => <Tabs ref={ref} variant=\"cards\" {...props} />\n)\nTabsCards.displayName = \"TabsCards\"\n\nexport { Tabs, TabsList, TabsTrigger, TabsContent, TabsPills, TabsUnderline, TabsCards } "]}