@hua-labs/ui 2.1.1 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (193) hide show
  1. package/README.md +1 -1
  2. package/dist/{ComponentLayout-DrZpz0yv.d.mts → ComponentLayout-BhM4VSoq.d.mts} +1 -1
  3. package/dist/advanced-dashboard.d.mts +1 -1
  4. package/dist/advanced-dashboard.mjs +3 -3
  5. package/dist/advanced-dashboard.mjs.map +1 -1
  6. package/dist/advanced-emotion.mjs +1 -1
  7. package/dist/advanced-motion.d.mts +9 -6
  8. package/dist/advanced-motion.mjs +1 -1
  9. package/dist/advanced.d.mts +3 -3
  10. package/dist/advanced.mjs +2 -2
  11. package/dist/advanced.mjs.map +1 -1
  12. package/dist/chunk-5DPW7SVD.mjs +4 -0
  13. package/dist/{chunk-AOSXB5JJ.mjs.map → chunk-5DPW7SVD.mjs.map} +1 -1
  14. package/dist/chunk-5L5HIPKA.mjs +3 -0
  15. package/dist/{chunk-3GAUTZXQ.mjs.map → chunk-5L5HIPKA.mjs.map} +1 -1
  16. package/dist/chunk-A5YOVVM5.mjs +3 -0
  17. package/dist/chunk-A5YOVVM5.mjs.map +1 -0
  18. package/dist/chunk-CNW22G24.mjs +13 -0
  19. package/dist/chunk-CNW22G24.mjs.map +1 -0
  20. package/dist/chunk-CW66UBQG.mjs +3 -0
  21. package/dist/{chunk-6HVJFEDA.mjs.map → chunk-CW66UBQG.mjs.map} +1 -1
  22. package/dist/chunk-EAZEI74V.mjs +3 -0
  23. package/dist/chunk-EAZEI74V.mjs.map +1 -0
  24. package/dist/chunk-EPY3432E.mjs +3 -0
  25. package/dist/{chunk-MDLCJASB.mjs.map → chunk-EPY3432E.mjs.map} +1 -1
  26. package/dist/chunk-F2M4YDDQ.mjs +3 -0
  27. package/dist/{chunk-OZNST3EZ.mjs.map → chunk-F2M4YDDQ.mjs.map} +1 -1
  28. package/dist/chunk-FHMFDCX2.mjs +3 -0
  29. package/dist/{chunk-4NJE7D6X.mjs.map → chunk-FHMFDCX2.mjs.map} +1 -1
  30. package/dist/chunk-HBIUCLFL.mjs +3 -0
  31. package/dist/chunk-HBIUCLFL.mjs.map +1 -0
  32. package/dist/chunk-HEBXAFRY.mjs +3 -0
  33. package/dist/{chunk-KJZGOL2Z.mjs.map → chunk-HEBXAFRY.mjs.map} +1 -1
  34. package/dist/chunk-IG47LMOD.mjs +3 -0
  35. package/dist/{chunk-42RGFEL2.mjs.map → chunk-IG47LMOD.mjs.map} +1 -1
  36. package/dist/chunk-J47ZEXEL.mjs +3 -0
  37. package/dist/{chunk-3CCF7U3P.mjs.map → chunk-J47ZEXEL.mjs.map} +1 -1
  38. package/dist/chunk-K2FOFIST.mjs +3 -0
  39. package/dist/{chunk-IJSYSNM5.mjs.map → chunk-K2FOFIST.mjs.map} +1 -1
  40. package/dist/chunk-LL6QPRD7.mjs +3 -0
  41. package/dist/{chunk-TZ4YSHMC.mjs.map → chunk-LL6QPRD7.mjs.map} +1 -1
  42. package/dist/chunk-NMJLOK6M.mjs +3 -0
  43. package/dist/{chunk-KYRIUUQP.mjs.map → chunk-NMJLOK6M.mjs.map} +1 -1
  44. package/dist/chunk-O24K56OS.mjs +3 -0
  45. package/dist/chunk-O24K56OS.mjs.map +1 -0
  46. package/dist/chunk-OIWG3IJ7.mjs +3 -0
  47. package/dist/chunk-OIWG3IJ7.mjs.map +1 -0
  48. package/dist/chunk-OLLU7ZFH.mjs +3 -0
  49. package/dist/{chunk-XL4KTJ4L.mjs.map → chunk-OLLU7ZFH.mjs.map} +1 -1
  50. package/dist/chunk-Q76JW7X5.mjs +73 -0
  51. package/dist/chunk-Q76JW7X5.mjs.map +1 -0
  52. package/dist/chunk-QEMPERUK.mjs +3 -0
  53. package/dist/chunk-QEMPERUK.mjs.map +1 -0
  54. package/dist/chunk-QRM66RQG.mjs +3 -0
  55. package/dist/{chunk-N56BUOCD.mjs.map → chunk-QRM66RQG.mjs.map} +1 -1
  56. package/dist/chunk-QRRP7TGF.mjs +13 -0
  57. package/dist/{chunk-RS6RKW5U.mjs.map → chunk-QRRP7TGF.mjs.map} +1 -1
  58. package/dist/chunk-SD6XGDAC.mjs +3 -0
  59. package/dist/chunk-SD6XGDAC.mjs.map +1 -0
  60. package/dist/chunk-SDFVGFXT.mjs +3 -0
  61. package/dist/{chunk-CVWWS25A.mjs.map → chunk-SDFVGFXT.mjs.map} +1 -1
  62. package/dist/chunk-SMLDNOV3.mjs +8 -0
  63. package/dist/{chunk-ZXZIHU7J.mjs.map → chunk-SMLDNOV3.mjs.map} +1 -1
  64. package/dist/{chunk-FX57OSYG.mjs → chunk-TAP6MYDW.mjs} +2 -2
  65. package/dist/{chunk-FX57OSYG.mjs.map → chunk-TAP6MYDW.mjs.map} +1 -1
  66. package/dist/{chunk-WP7VFE77.mjs → chunk-TBZ645BI.mjs} +2 -2
  67. package/dist/{chunk-WP7VFE77.mjs.map → chunk-TBZ645BI.mjs.map} +1 -1
  68. package/dist/{chunk-TXBZZJNR.mjs → chunk-V2DNYJR6.mjs} +2 -2
  69. package/dist/{chunk-TXBZZJNR.mjs.map → chunk-V2DNYJR6.mjs.map} +1 -1
  70. package/dist/{chunk-Z74YUUVT.mjs → chunk-VBABZXL7.mjs} +2 -2
  71. package/dist/{chunk-Z74YUUVT.mjs.map → chunk-VBABZXL7.mjs.map} +1 -1
  72. package/dist/chunk-WYBSHTGY.mjs +3 -0
  73. package/dist/{chunk-DYNBM24D.mjs.map → chunk-WYBSHTGY.mjs.map} +1 -1
  74. package/dist/chunk-ZQUMJQYV.mjs +3 -0
  75. package/dist/chunk-ZQUMJQYV.mjs.map +1 -0
  76. package/dist/chunk-ZY23NOT4.mjs +3 -0
  77. package/dist/chunk-ZY23NOT4.mjs.map +1 -0
  78. package/dist/components/Action.d.ts.map +1 -1
  79. package/dist/components/Badge.d.ts +1 -1
  80. package/dist/components/Button.d.ts.map +1 -1
  81. package/dist/components/DatePicker.d.ts.map +1 -1
  82. package/dist/components/Dropdown.d.ts +0 -50
  83. package/dist/components/Dropdown.d.ts.map +1 -1
  84. package/dist/components/Icon/Icon.d.ts.map +1 -1
  85. package/dist/components/Modal.d.ts.map +1 -1
  86. package/dist/components/Popover.d.ts.map +1 -1
  87. package/dist/components/Progress.d.ts +2 -2
  88. package/dist/components/advanced/AnimatedGradient.d.ts.map +1 -1
  89. package/dist/components/advanced/Carousel.d.ts.map +1 -1
  90. package/dist/components/advanced/ImageReveal.d.ts.map +1 -1
  91. package/dist/components/advanced/Parallax.d.ts +9 -6
  92. package/dist/components/advanced/Parallax.d.ts.map +1 -1
  93. package/dist/components/advanced/TextReveal.d.ts.map +1 -1
  94. package/dist/data.mjs +2 -2
  95. package/dist/data.mjs.map +1 -1
  96. package/dist/feedback.mjs +1 -1
  97. package/dist/form.mjs +4 -4
  98. package/dist/form.mjs.map +1 -1
  99. package/dist/{icons-DmhQEH_E.d.mts → icons-DcOBy9Hf.d.mts} +4 -0
  100. package/dist/iconsax-extended.mjs +2 -2
  101. package/dist/iconsax-extended.mjs.map +1 -1
  102. package/dist/index.d.mts +6 -87
  103. package/dist/index.mjs +14 -14
  104. package/dist/index.mjs.map +1 -1
  105. package/dist/interactive.mjs +1 -1
  106. package/dist/interactive.mjs.map +1 -1
  107. package/dist/landing.mjs +7 -7
  108. package/dist/landing.mjs.map +1 -1
  109. package/dist/lib/icon-providers.d.ts +9 -25
  110. package/dist/lib/icon-providers.d.ts.map +1 -1
  111. package/dist/lib/icons.d.ts +4 -0
  112. package/dist/lib/icons.d.ts.map +1 -1
  113. package/dist/lib/utils.d.ts.map +1 -1
  114. package/dist/navigation.d.mts +1 -1
  115. package/dist/navigation.mjs +1 -1
  116. package/dist/navigation.mjs.map +1 -1
  117. package/dist/overlay.d.mts +0 -50
  118. package/dist/overlay.mjs +1 -1
  119. package/dist/overlay.mjs.map +1 -1
  120. package/dist/sdui.mjs +1 -1
  121. package/dist/sdui.mjs.map +1 -1
  122. package/dist/theme.d.mts +85 -0
  123. package/dist/theme.d.ts +14 -0
  124. package/dist/theme.d.ts.map +1 -0
  125. package/dist/theme.mjs +3 -0
  126. package/dist/theme.mjs.map +1 -0
  127. package/package.json +18 -14
  128. package/dist/advanced-dashboard.js +0 -39
  129. package/dist/advanced-dashboard.js.map +0 -1
  130. package/dist/advanced-emotion.js +0 -2
  131. package/dist/advanced-emotion.js.map +0 -1
  132. package/dist/advanced-motion.js +0 -82
  133. package/dist/advanced-motion.js.map +0 -1
  134. package/dist/advanced.js +0 -112
  135. package/dist/advanced.js.map +0 -1
  136. package/dist/chunk-3CCF7U3P.mjs +0 -3
  137. package/dist/chunk-3GAUTZXQ.mjs +0 -3
  138. package/dist/chunk-42RGFEL2.mjs +0 -3
  139. package/dist/chunk-4NJE7D6X.mjs +0 -3
  140. package/dist/chunk-6HVJFEDA.mjs +0 -3
  141. package/dist/chunk-7OYT3QSY.mjs +0 -3
  142. package/dist/chunk-7OYT3QSY.mjs.map +0 -1
  143. package/dist/chunk-ANYZ56VB.mjs +0 -3
  144. package/dist/chunk-ANYZ56VB.mjs.map +0 -1
  145. package/dist/chunk-AOSXB5JJ.mjs +0 -4
  146. package/dist/chunk-B544MRF7.mjs +0 -3
  147. package/dist/chunk-B544MRF7.mjs.map +0 -1
  148. package/dist/chunk-CVWWS25A.mjs +0 -3
  149. package/dist/chunk-DYNBM24D.mjs +0 -3
  150. package/dist/chunk-IJSYSNM5.mjs +0 -3
  151. package/dist/chunk-KJZGOL2Z.mjs +0 -3
  152. package/dist/chunk-KYRIUUQP.mjs +0 -3
  153. package/dist/chunk-LSA7DU3N.mjs +0 -73
  154. package/dist/chunk-LSA7DU3N.mjs.map +0 -1
  155. package/dist/chunk-MDLCJASB.mjs +0 -3
  156. package/dist/chunk-N56BUOCD.mjs +0 -3
  157. package/dist/chunk-OFYITQXI.mjs +0 -13
  158. package/dist/chunk-OFYITQXI.mjs.map +0 -1
  159. package/dist/chunk-OZNST3EZ.mjs +0 -3
  160. package/dist/chunk-RS6RKW5U.mjs +0 -13
  161. package/dist/chunk-TZ4YSHMC.mjs +0 -3
  162. package/dist/chunk-U6CTBZ2U.mjs +0 -3
  163. package/dist/chunk-U6CTBZ2U.mjs.map +0 -1
  164. package/dist/chunk-XCZMLKPK.mjs +0 -3
  165. package/dist/chunk-XCZMLKPK.mjs.map +0 -1
  166. package/dist/chunk-XGHT7WMO.mjs +0 -3
  167. package/dist/chunk-XGHT7WMO.mjs.map +0 -1
  168. package/dist/chunk-XL4KTJ4L.mjs +0 -3
  169. package/dist/chunk-ZXZIHU7J.mjs +0 -8
  170. package/dist/data.js +0 -3
  171. package/dist/data.js.map +0 -1
  172. package/dist/feedback.js +0 -12
  173. package/dist/feedback.js.map +0 -1
  174. package/dist/form.js +0 -8
  175. package/dist/form.js.map +0 -1
  176. package/dist/iconsax-extended.js +0 -3
  177. package/dist/iconsax-extended.js.map +0 -1
  178. package/dist/iconsax.js +0 -3
  179. package/dist/iconsax.js.map +0 -1
  180. package/dist/index.js +0 -51
  181. package/dist/index.js.map +0 -1
  182. package/dist/interactive.js +0 -2
  183. package/dist/interactive.js.map +0 -1
  184. package/dist/landing.js +0 -100
  185. package/dist/landing.js.map +0 -1
  186. package/dist/lib/phosphor-icons.d.ts +0 -6
  187. package/dist/lib/phosphor-icons.d.ts.map +0 -1
  188. package/dist/navigation.js +0 -12
  189. package/dist/navigation.js.map +0 -1
  190. package/dist/overlay.js +0 -3
  191. package/dist/overlay.js.map +0 -1
  192. package/dist/sdui.js +0 -9
  193. package/dist/sdui.js.map +0 -1
@@ -0,0 +1,4 @@
1
+ "use client";
2
+ import {d}from'./chunk-O24K56OS.mjs';import {a}from'./chunk-QEMPERUK.mjs';import I,{useState,useEffect,useCallback}from'react';import {jsxs,jsx,Fragment}from'react/jsx-runtime';var U=I.forwardRef(({className:p,height:v=2,color:h="gradient",position:y="top",animated:A=true,showPercentage:w=false,...a$1},x)=>{let[u,b]=useState(0);useEffect(()=>{let d=()=>{let m=window.scrollY,n=document.documentElement.scrollHeight-window.innerHeight,k=n>0?m/n*100:0;b(k);};return d(),window.addEventListener("scroll",d,{passive:true}),window.addEventListener("resize",d,{passive:true}),()=>{window.removeEventListener("scroll",d),window.removeEventListener("resize",d);}},[]);let f={default:"bg-foreground",primary:"bg-primary",secondary:"bg-muted-foreground",gradient:"bg-gradient-to-r from-teal-600 via-cyan-500 to-teal-600"};return jsxs("div",{ref:x,className:a("fixed z-50",{top:"top-0 left-0 right-0",bottom:"bottom-0 left-0 right-0"}[y],p),style:{height:`${v}px`},...a$1,children:[jsx("div",{className:"absolute inset-0 w-full h-full bg-border/30"}),jsx("div",{className:a("absolute top-0 left-0 h-full origin-left transition-all duration-100 ease-out",f[h]||f.gradient),style:{width:`${u}%`,transformOrigin:"left"}}),w&&jsxs("div",{className:"absolute top-2 right-2 text-xs text-muted-foreground bg-card px-2 py-1 rounded border border-border",children:[Math.round(u),"%"]})]})});U.displayName="ScrollProgress";var X=I.forwardRef(({className:p,title:v,subtitle:h,description:y,primaryAction:A,secondaryAction:w,slides:a$1,autoPlay:x=false,interval:u=5e3,indicator:b="dots",showControls:f=true,pauseOnHover:N=true,background:d$1="gradient",customBackground:m,size:n="lg",fullBleed:k=false,...T},B)=>{let[g,S]=useState(0),[H,L]=useState(false),r=a$1&&a$1.length>0,c=(a$1==null?void 0:a$1.length)||0,C=useCallback(()=>{r&&S(s=>(s+1)%c);},[r,c]),$=useCallback(()=>{r&&S(s=>(s-1+c)%c);},[r,c]),E=useCallback(s=>{S(s);},[]);useEffect(()=>{if(!x||!r||H)return;let s=setInterval(C,u);return ()=>clearInterval(s)},[x,r,H,u,C]);let t=r?a$1[g]:{title:v||"",subtitle:h,description:y||"",primaryAction:A,secondaryAction:w,background:d$1},_={sm:"min-h-[400px]",md:"min-h-[500px]",lg:"min-h-[600px]",xl:"min-h-[700px]",full:"min-h-screen"},F={sm:"text-2xl sm:text-3xl md:text-4xl leading-tight",md:"text-3xl sm:text-4xl md:text-5xl leading-tight",lg:"text-3xl sm:text-4xl md:text-5xl lg:text-6xl leading-tight",xl:"text-3xl sm:text-4xl md:text-5xl lg:text-6xl leading-tight",full:"text-4xl sm:text-5xl md:text-6xl lg:text-7xl leading-tight"},G={sm:"text-base sm:text-lg md:text-xl leading-snug",md:"text-lg sm:text-xl md:text-2xl leading-snug",lg:"text-lg sm:text-xl md:text-2xl lg:text-3xl leading-snug",xl:"text-xl sm:text-2xl md:text-3xl leading-snug",full:"text-xl sm:text-2xl md:text-3xl lg:text-4xl leading-snug"},W={sm:"text-sm sm:text-base md:text-lg leading-relaxed",md:"text-base sm:text-lg md:text-xl leading-relaxed",lg:"text-base sm:text-lg md:text-xl leading-relaxed",xl:"text-base sm:text-lg md:text-xl leading-relaxed",full:"text-lg sm:text-xl md:text-2xl leading-relaxed"},D=r&&t.background||d$1,O={none:null,gradient:jsxs("div",{className:"absolute inset-0 z-0 pointer-events-none",children:[jsx("div",{className:"absolute top-0 left-0 w-80 h-80 sm:w-96 sm:h-96 md:w-[500px] md:h-[500px] -translate-x-1/3 -translate-y-1/3 rounded-full bg-gradient-to-br from-teal-400 via-cyan-500 to-teal-600 opacity-40 blur-3xl"}),jsx("div",{className:"absolute bottom-0 right-0 w-72 h-72 sm:w-80 sm:h-80 md:w-[400px] md:h-[400px] translate-x-1/4 translate-y-1/4 rounded-full bg-gradient-to-tr from-cyan-400 via-teal-500 to-emerald-500 opacity-35 blur-3xl"}),jsx("div",{className:"absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-48 h-48 sm:w-64 sm:h-64 md:w-80 md:h-80 rounded-full bg-teal-500/20 blur-2xl"})]}),particles:jsx("div",{className:"absolute inset-0 z-0 pointer-events-none",children:jsx("div",{className:"absolute inset-0 bg-gradient-to-br from-secondary/50 via-background to-secondary/30"})}),video:m?jsx("div",{className:"absolute inset-0 z-0 pointer-events-none",children:jsx("video",{autoPlay:true,loop:true,muted:true,playsInline:true,className:"absolute inset-0 w-full h-full object-cover opacity-20",children:jsx("source",{src:m,type:"video/mp4"})})}):null,image:m||r&&t.backgroundImage?jsxs("div",{className:"absolute inset-0 z-0 pointer-events-none",children:[jsx("img",{src:r&&t.backgroundImage||m,alt:"",className:"absolute inset-0 w-full h-full object-cover opacity-30"}),jsx("div",{className:"absolute inset-0 bg-gradient-to-t from-background via-background/50 to-transparent"})]}):null},Y=()=>{if(!r||b==="none")return null;switch(b){case "dots":return jsx("div",{className:"flex gap-2 justify-center mt-8",children:a$1.map((s,l)=>jsx("button",{onClick:()=>E(l),className:a("w-2.5 h-2.5 rounded-full transition-all duration-300",g===l?"bg-primary w-8":"bg-muted-foreground/30 hover:bg-muted-foreground/50"),"aria-label":`Go to slide ${l+1}`},l))});case "line":return jsx("div",{className:"flex gap-1 justify-center mt-8 max-w-xs mx-auto",children:a$1.map((s,l)=>jsx("button",{onClick:()=>E(l),className:"flex-1 h-1 rounded-full overflow-hidden bg-muted-foreground/20","aria-label":`Go to slide ${l+1}`,children:jsx("div",{className:a("h-full bg-primary transition-all duration-300",g===l?"w-full":"w-0")})},l))});case "numbers":return jsxs("div",{className:"flex items-center justify-center gap-2 mt-8 text-sm text-muted-foreground",children:[jsx("span",{className:"text-foreground font-semibold",children:g+1}),jsx("span",{children:"/"}),jsx("span",{children:c})]});default:return null}};return jsxs("section",{ref:B,className:a("relative w-full flex flex-col justify-center items-center text-center px-4 sm:px-6 lg:px-8 overflow-hidden",_[n],k&&"-mt-16 pt-16",p),onMouseEnter:()=>N&&L(true),onMouseLeave:()=>N&&L(false),...T,children:[O[D],jsxs("div",{className:"relative z-10 max-w-4xl mx-auto",children:[jsxs("div",{className:"animate-in fade-in slide-in-from-bottom-4 duration-500",children:[jsxs("h1",{className:a("font-extrabold mb-4 sm:mb-6 text-foreground",F[n]),children:[jsx("span",{className:"block gradient-text",children:t.title}),t.subtitle&&jsx("span",{className:a("block font-semibold mt-2 sm:mt-4 text-muted-foreground",G[n]),children:t.subtitle})]}),jsx("div",{className:a("text-muted-foreground mb-6 sm:mb-8 md:mb-10 max-w-2xl mx-auto",W[n]),children:t.description.split(`
3
+ `).map((s,l,q)=>jsxs(I.Fragment,{children:[s,l<q.length-1&&jsx("br",{})]},l))}),(t.primaryAction||t.secondaryAction)&&jsxs("div",{className:"flex flex-col sm:flex-row gap-4 justify-center",children:[t.primaryAction&&jsxs(d,{href:t.primaryAction.href,size:n==="xl"||n==="full"?"lg":"md",hover:"scale",className:"inline-flex items-center gap-2",children:[t.primaryAction.icon,t.primaryAction.label]}),t.secondaryAction&&jsxs(d,{href:t.secondaryAction.href,variant:"outline",size:n==="xl"||n==="full"?"lg":"md",hover:"scale",className:"inline-flex items-center gap-2",children:[t.secondaryAction.icon,t.secondaryAction.label]})]})]},r?g:0),Y()]}),r&&f&&c>1&&jsxs(Fragment,{children:[jsx("button",{onClick:$,className:"absolute left-4 top-1/2 -translate-y-1/2 z-20 p-2 rounded-full bg-card/80 backdrop-blur-sm border border-border text-foreground hover:bg-card transition-colors","aria-label":"Previous slide",children:jsx("svg",{className:"w-5 h-5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M15 19l-7-7 7-7"})})}),jsx("button",{onClick:C,className:"absolute right-4 top-1/2 -translate-y-1/2 z-20 p-2 rounded-full bg-card/80 backdrop-blur-sm border border-border text-foreground hover:bg-card transition-colors","aria-label":"Next slide",children:jsx("svg",{className:"w-5 h-5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 5l7 7-7 7"})})})]})]})});X.displayName="HeroSection";export{U as a,X as b};//# sourceMappingURL=chunk-5DPW7SVD.mjs.map
4
+ //# sourceMappingURL=chunk-5DPW7SVD.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/ScrollProgress.tsx","../src/components/HeroSection.tsx"],"names":["ScrollProgress","React","className","height","color","position","_animated","showPercentage","props","ref","progress","setProgress","useState","useEffect","updateProgress","scrollTop","docHeight","currentProgress","progressColors","jsxs","merge","jsx","HeroSection","title","subtitle","description","primaryAction","secondaryAction","slides","autoPlay","interval","indicator","showControls","pauseOnHover","background","customBackground","size","fullBleed","currentSlide","setCurrentSlide","isPaused","setIsPaused","isSlideMode","slideCount","nextSlide","useCallback","prev","prevSlide","goToSlide","index","timer","currentContent","sizeClasses","titleSizeClasses","subtitleSizeClasses","descriptionSizeClasses","currentBg","backgroundContent","renderIndicator","_","line","i","arr","Button","Fragment"],"mappings":"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","file":"chunk-AOSXB5JJ.mjs","sourcesContent":["'use client'\n\nimport React, { useState, useEffect } from 'react'\nimport { merge } from '../lib/utils'\n\n/**\n * ScrollProgress 컴포넌트의 props / ScrollProgress component props\n * @typedef {Object} ScrollProgressProps\n * @property {string} [className] - 추가 CSS 클래스 / Additional CSS class\n * @property {number} [height=2] - 진행률 바 높이 (px) / Progress bar height (px)\n * @property {'default' | 'primary' | 'secondary' | 'gradient'} [color='gradient'] - 진행률 바 색상 / Progress bar color\n * @property {'top' | 'bottom'} [position='top'] - 표시 위치 / Display position\n * @property {boolean} [animated=true] - 애니메이션 활성화 여부 / Enable animation\n * @property {boolean} [showPercentage=false] - 퍼센트 표시 여부 / Show percentage\n */\nexport interface ScrollProgressProps {\n className?: string\n height?: number\n color?: 'default' | 'primary' | 'secondary' | 'gradient'\n position?: 'top' | 'bottom'\n animated?: boolean\n showPercentage?: boolean\n}\n\n/**\n * ScrollProgress 컴포넌트 / ScrollProgress component\n * \n * 페이지 스크롤 진행률을 표시하는 컴포넌트입니다.\n * 페이지 상단 또는 하단에 고정되어 표시됩니다.\n * \n * Component that displays page scroll progress.\n * Fixed at top or bottom of the page.\n * \n * @component\n * @example\n * // 기본 사용 / Basic usage\n * <ScrollProgress />\n * \n * @example\n * // 하단에 표시, 퍼센트 포함 / Display at bottom with percentage\n * <ScrollProgress \n * position=\"bottom\"\n * color=\"primary\"\n * showPercentage\n * height={4}\n * />\n * \n * @param {ScrollProgressProps} props - ScrollProgress 컴포넌트의 props / ScrollProgress component props\n * @param {React.Ref<HTMLDivElement>} ref - div 요소 ref / div element ref\n * @returns {JSX.Element} ScrollProgress 컴포넌트 / ScrollProgress component\n */\nconst ScrollProgress = React.forwardRef<HTMLDivElement, ScrollProgressProps>(({\n className,\n height = 2,\n color = 'gradient',\n position = 'top',\n animated: _animated = true,\n showPercentage = false,\n ...props\n}, ref) => {\n const [progress, setProgress] = useState(0)\n\n useEffect(() => {\n const updateProgress = () => {\n const scrollTop = window.scrollY\n const docHeight = document.documentElement.scrollHeight - window.innerHeight\n const currentProgress = docHeight > 0 ? (scrollTop / docHeight) * 100 : 0\n setProgress(currentProgress)\n }\n\n // 초기 실행\n updateProgress()\n\n window.addEventListener('scroll', updateProgress, { passive: true })\n window.addEventListener('resize', updateProgress, { passive: true })\n \n return () => {\n window.removeEventListener('scroll', updateProgress)\n window.removeEventListener('resize', updateProgress)\n }\n }, [])\n\n // 색상 옵션 (Teal 브랜드 기반)\n const progressColors: Record<string, string> = {\n default: 'bg-foreground',\n primary: 'bg-primary',\n secondary: 'bg-muted-foreground',\n gradient: 'bg-gradient-to-r from-teal-600 via-cyan-500 to-teal-600'\n }\n\n const positionClasses = {\n top: 'top-0 left-0 right-0',\n bottom: 'bottom-0 left-0 right-0'\n }\n\n return (\n <div\n ref={ref}\n className={merge(\n 'fixed z-50',\n positionClasses[position],\n className\n )}\n style={{ height: `${height}px` }}\n {...props}\n >\n {/* 배경 바 */}\n <div className=\"absolute inset-0 w-full h-full bg-border/30\" />\n \n {/* 진행률 바 - absolute로 배경 위에 표시 */}\n <div\n className={merge(\n 'absolute top-0 left-0 h-full origin-left transition-all duration-100 ease-out',\n progressColors[color] || progressColors.gradient\n )}\n style={{\n width: `${progress}%`,\n transformOrigin: 'left'\n }}\n />\n \n {/* 퍼센트 표시 (선택사항) */}\n {showPercentage && (\n <div className=\"absolute top-2 right-2 text-xs text-muted-foreground bg-card px-2 py-1 rounded border border-border\">\n {Math.round(progress)}%\n </div>\n )}\n </div>\n )\n})\n\nScrollProgress.displayName = 'ScrollProgress'\n\nexport { ScrollProgress } ","\"use client\"\n\nimport React, { useState, useEffect, useCallback } from \"react\"\nimport { merge } from \"../lib/utils\"\nimport { Button } from \"./Button\"\n\n/**\n * 슬라이드 아이템 인터페이스\n */\nexport interface HeroSlide {\n title: string\n subtitle?: string\n description: string\n primaryAction?: {\n label: string\n href: string\n icon?: React.ReactNode\n }\n secondaryAction?: {\n label: string\n href: string\n icon?: React.ReactNode\n }\n background?: \"none\" | \"gradient\" | \"particles\" | \"image\"\n backgroundImage?: string\n}\n\n/**\n * HeroSection 컴포넌트의 props\n */\nexport interface HeroSectionProps extends React.HTMLAttributes<HTMLElement> {\n // 단일 모드 props\n title?: string\n subtitle?: string\n description?: string\n primaryAction?: {\n label: string\n href: string\n icon?: React.ReactNode\n }\n secondaryAction?: {\n label: string\n href: string\n icon?: React.ReactNode\n }\n // 슬라이드 모드 props\n slides?: HeroSlide[]\n autoPlay?: boolean\n interval?: number\n indicator?: \"dots\" | \"line\" | \"numbers\" | \"none\"\n showControls?: boolean\n pauseOnHover?: boolean\n // 공통 props\n background?: \"none\" | \"gradient\" | \"particles\" | \"video\" | \"image\"\n customBackground?: string\n /**\n * 히어로 섹션 크기\n * - sm: 400px, md: 500px, lg: 600px, xl: 700px\n * - full: 100vh (뷰포트 전체)\n */\n size?: \"sm\" | \"md\" | \"lg\" | \"xl\" | \"full\"\n /**\n * 헤더 뒤까지 확장 (fixed header가 있을 때)\n * true면 -mt-16 적용되어 헤더 뒤로 들어감\n */\n fullBleed?: boolean\n}\n\n/**\n * HeroSection 컴포넌트\n *\n * 단일 히어로 또는 슬라이드 히어로를 지원합니다.\n * slides prop이 있으면 슬라이드 모드로 동작합니다.\n */\nconst HeroSection = React.forwardRef<HTMLElement, HeroSectionProps>(\n ({\n className,\n // 단일 모드\n title,\n subtitle,\n description,\n primaryAction,\n secondaryAction,\n // 슬라이드 모드\n slides,\n autoPlay = false,\n interval = 5000,\n indicator = \"dots\",\n showControls = true,\n pauseOnHover = true,\n // 공통\n background = \"gradient\",\n customBackground,\n size = \"lg\",\n fullBleed = false,\n ...props\n }, ref) => {\n const [currentSlide, setCurrentSlide] = useState(0)\n const [isPaused, setIsPaused] = useState(false)\n\n // 슬라이드 모드 여부\n const isSlideMode = slides && slides.length > 0\n const slideCount = slides?.length || 0\n\n // 다음 슬라이드\n const nextSlide = useCallback(() => {\n if (!isSlideMode) return\n setCurrentSlide((prev) => (prev + 1) % slideCount)\n }, [isSlideMode, slideCount])\n\n // 이전 슬라이드\n const prevSlide = useCallback(() => {\n if (!isSlideMode) return\n setCurrentSlide((prev) => (prev - 1 + slideCount) % slideCount)\n }, [isSlideMode, slideCount])\n\n // 특정 슬라이드로 이동\n const goToSlide = useCallback((index: number) => {\n setCurrentSlide(index)\n }, [])\n\n // 자동 재생\n useEffect(() => {\n if (!autoPlay || !isSlideMode || isPaused) return\n\n const timer = setInterval(nextSlide, interval)\n return () => clearInterval(timer)\n }, [autoPlay, isSlideMode, isPaused, interval, nextSlide])\n\n // 현재 표시할 콘텐츠\n const currentContent = isSlideMode ? slides[currentSlide] : {\n title: title || \"\",\n subtitle,\n description: description || \"\",\n primaryAction,\n secondaryAction,\n background,\n }\n\n const sizeClasses = {\n sm: \"min-h-[400px]\",\n md: \"min-h-[500px]\",\n lg: \"min-h-[600px]\",\n xl: \"min-h-[700px]\",\n full: \"min-h-screen\"\n }\n\n const titleSizeClasses = {\n sm: \"text-2xl sm:text-3xl md:text-4xl leading-tight\",\n md: \"text-3xl sm:text-4xl md:text-5xl leading-tight\",\n lg: \"text-3xl sm:text-4xl md:text-5xl lg:text-6xl leading-tight\",\n xl: \"text-3xl sm:text-4xl md:text-5xl lg:text-6xl leading-tight\",\n full: \"text-4xl sm:text-5xl md:text-6xl lg:text-7xl leading-tight\"\n }\n\n const subtitleSizeClasses = {\n sm: \"text-base sm:text-lg md:text-xl leading-snug\",\n md: \"text-lg sm:text-xl md:text-2xl leading-snug\",\n lg: \"text-lg sm:text-xl md:text-2xl lg:text-3xl leading-snug\",\n xl: \"text-xl sm:text-2xl md:text-3xl leading-snug\",\n full: \"text-xl sm:text-2xl md:text-3xl lg:text-4xl leading-snug\"\n }\n\n const descriptionSizeClasses = {\n sm: \"text-sm sm:text-base md:text-lg leading-relaxed\",\n md: \"text-base sm:text-lg md:text-xl leading-relaxed\",\n lg: \"text-base sm:text-lg md:text-xl leading-relaxed\",\n xl: \"text-base sm:text-lg md:text-xl leading-relaxed\",\n full: \"text-lg sm:text-xl md:text-2xl leading-relaxed\"\n }\n\n const currentBg = isSlideMode ? (currentContent.background || background) : background\n\n const backgroundContent: Record<string, React.ReactNode> = {\n none: null,\n gradient: (\n <div className=\"absolute inset-0 z-0 pointer-events-none\">\n {/* 왼쪽 위 - 메인 그라데이션 */}\n <div className=\"absolute top-0 left-0 w-80 h-80 sm:w-96 sm:h-96 md:w-[500px] md:h-[500px] -translate-x-1/3 -translate-y-1/3 rounded-full bg-gradient-to-br from-teal-400 via-cyan-500 to-teal-600 opacity-40 blur-3xl\" />\n {/* 오른쪽 아래 - 보조 그라데이션 */}\n <div className=\"absolute bottom-0 right-0 w-72 h-72 sm:w-80 sm:h-80 md:w-[400px] md:h-[400px] translate-x-1/4 translate-y-1/4 rounded-full bg-gradient-to-tr from-cyan-400 via-teal-500 to-emerald-500 opacity-35 blur-3xl\" />\n {/* 중앙 액센트 */}\n <div className=\"absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-48 h-48 sm:w-64 sm:h-64 md:w-80 md:h-80 rounded-full bg-teal-500/20 blur-2xl\" />\n </div>\n ),\n particles: (\n <div className=\"absolute inset-0 z-0 pointer-events-none\">\n <div className=\"absolute inset-0 bg-gradient-to-br from-secondary/50 via-background to-secondary/30\" />\n </div>\n ),\n video: customBackground ? (\n <div className=\"absolute inset-0 z-0 pointer-events-none\">\n <video\n autoPlay\n loop\n muted\n playsInline\n className=\"absolute inset-0 w-full h-full object-cover opacity-20\"\n >\n <source src={customBackground} type=\"video/mp4\" />\n </video>\n </div>\n ) : null,\n image: (customBackground || (isSlideMode && (currentContent as HeroSlide).backgroundImage)) ? (\n <div className=\"absolute inset-0 z-0 pointer-events-none\">\n <img\n src={(isSlideMode && (currentContent as HeroSlide).backgroundImage) || customBackground}\n alt=\"\"\n className=\"absolute inset-0 w-full h-full object-cover opacity-30\"\n />\n <div className=\"absolute inset-0 bg-gradient-to-t from-background via-background/50 to-transparent\" />\n </div>\n ) : null,\n }\n\n // 인디케이터 렌더링\n const renderIndicator = () => {\n if (!isSlideMode || indicator === \"none\") return null\n\n switch (indicator) {\n case \"dots\":\n return (\n <div className=\"flex gap-2 justify-center mt-8\">\n {slides.map((_, index) => (\n <button\n key={index}\n onClick={() => goToSlide(index)}\n className={merge(\n \"w-2.5 h-2.5 rounded-full transition-all duration-300\",\n currentSlide === index\n ? \"bg-primary w-8\"\n : \"bg-muted-foreground/30 hover:bg-muted-foreground/50\"\n )}\n aria-label={`Go to slide ${index + 1}`}\n />\n ))}\n </div>\n )\n\n case \"line\":\n return (\n <div className=\"flex gap-1 justify-center mt-8 max-w-xs mx-auto\">\n {slides.map((_, index) => (\n <button\n key={index}\n onClick={() => goToSlide(index)}\n className=\"flex-1 h-1 rounded-full overflow-hidden bg-muted-foreground/20\"\n aria-label={`Go to slide ${index + 1}`}\n >\n <div\n className={merge(\n \"h-full bg-primary transition-all duration-300\",\n currentSlide === index ? \"w-full\" : \"w-0\"\n )}\n />\n </button>\n ))}\n </div>\n )\n\n case \"numbers\":\n return (\n <div className=\"flex items-center justify-center gap-2 mt-8 text-sm text-muted-foreground\">\n <span className=\"text-foreground font-semibold\">{currentSlide + 1}</span>\n <span>/</span>\n <span>{slideCount}</span>\n </div>\n )\n\n default:\n return null\n }\n }\n\n return (\n <section\n ref={ref}\n className={merge(\n \"relative w-full flex flex-col justify-center items-center text-center px-4 sm:px-6 lg:px-8 overflow-hidden\",\n sizeClasses[size],\n fullBleed && \"-mt-16 pt-16\",\n className\n )}\n onMouseEnter={() => pauseOnHover && setIsPaused(true)}\n onMouseLeave={() => pauseOnHover && setIsPaused(false)}\n {...props}\n >\n {backgroundContent[currentBg]}\n\n {/* 슬라이드 콘텐츠 */}\n <div className=\"relative z-10 max-w-4xl mx-auto\">\n <div\n key={isSlideMode ? currentSlide : 0}\n className=\"animate-in fade-in slide-in-from-bottom-4 duration-500\"\n >\n <h1 className={merge(\n \"font-extrabold mb-4 sm:mb-6 text-foreground\",\n titleSizeClasses[size]\n )}>\n <span className=\"block gradient-text\">\n {currentContent.title}\n </span>\n {currentContent.subtitle && (\n <span className={merge(\n \"block font-semibold mt-2 sm:mt-4 text-muted-foreground\",\n subtitleSizeClasses[size]\n )}>\n {currentContent.subtitle}\n </span>\n )}\n </h1>\n\n <div className={merge(\n \"text-muted-foreground mb-6 sm:mb-8 md:mb-10 max-w-2xl mx-auto\",\n descriptionSizeClasses[size]\n )}>\n {currentContent.description.split('\\n').map((line, i, arr) => (\n <React.Fragment key={i}>\n {line}\n {i < arr.length - 1 && <br />}\n </React.Fragment>\n ))}\n </div>\n\n {(currentContent.primaryAction || currentContent.secondaryAction) && (\n <div className=\"flex flex-col sm:flex-row gap-4 justify-center\">\n {currentContent.primaryAction && (\n <Button\n href={currentContent.primaryAction.href}\n size={size === \"xl\" || size === \"full\" ? \"lg\" : \"md\"}\n hover=\"scale\"\n className=\"inline-flex items-center gap-2\"\n >\n {currentContent.primaryAction.icon}\n {currentContent.primaryAction.label}\n </Button>\n )}\n\n {currentContent.secondaryAction && (\n <Button\n href={currentContent.secondaryAction.href}\n variant=\"outline\"\n size={size === \"xl\" || size === \"full\" ? \"lg\" : \"md\"}\n hover=\"scale\"\n className=\"inline-flex items-center gap-2\"\n >\n {currentContent.secondaryAction.icon}\n {currentContent.secondaryAction.label}\n </Button>\n )}\n </div>\n )}\n </div>\n\n {/* 인디케이터 */}\n {renderIndicator()}\n </div>\n\n {/* 좌우 컨트롤 */}\n {isSlideMode && showControls && slideCount > 1 && (\n <>\n <button\n onClick={prevSlide}\n className=\"absolute left-4 top-1/2 -translate-y-1/2 z-20 p-2 rounded-full bg-card/80 backdrop-blur-sm border border-border text-foreground hover:bg-card transition-colors\"\n aria-label=\"Previous slide\"\n >\n <svg className=\"w-5 h-5\" 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 </button>\n <button\n onClick={nextSlide}\n className=\"absolute right-4 top-1/2 -translate-y-1/2 z-20 p-2 rounded-full bg-card/80 backdrop-blur-sm border border-border text-foreground hover:bg-card transition-colors\"\n aria-label=\"Next slide\"\n >\n <svg className=\"w-5 h-5\" 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 </button>\n </>\n )}\n </section>\n )\n }\n)\n\nHeroSection.displayName = \"HeroSection\"\n\nexport { HeroSection }\n"]}
1
+ {"version":3,"sources":["../src/components/ScrollProgress.tsx","../src/components/HeroSection.tsx"],"names":["ScrollProgress","React","className","height","color","position","_animated","showPercentage","props","ref","progress","setProgress","useState","useEffect","updateProgress","scrollTop","docHeight","currentProgress","progressColors","jsxs","merge","jsx","HeroSection","title","subtitle","description","primaryAction","secondaryAction","slides","autoPlay","interval","indicator","showControls","pauseOnHover","background","customBackground","size","fullBleed","currentSlide","setCurrentSlide","isPaused","setIsPaused","isSlideMode","slideCount","nextSlide","useCallback","prev","prevSlide","goToSlide","index","timer","currentContent","sizeClasses","titleSizeClasses","subtitleSizeClasses","descriptionSizeClasses","currentBg","backgroundContent","renderIndicator","_","line","i","arr","Button","Fragment"],"mappings":"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","file":"chunk-5DPW7SVD.mjs","sourcesContent":["'use client'\n\nimport React, { useState, useEffect } from 'react'\nimport { merge } from '../lib/utils'\n\n/**\n * ScrollProgress 컴포넌트의 props / ScrollProgress component props\n * @typedef {Object} ScrollProgressProps\n * @property {string} [className] - 추가 CSS 클래스 / Additional CSS class\n * @property {number} [height=2] - 진행률 바 높이 (px) / Progress bar height (px)\n * @property {'default' | 'primary' | 'secondary' | 'gradient'} [color='gradient'] - 진행률 바 색상 / Progress bar color\n * @property {'top' | 'bottom'} [position='top'] - 표시 위치 / Display position\n * @property {boolean} [animated=true] - 애니메이션 활성화 여부 / Enable animation\n * @property {boolean} [showPercentage=false] - 퍼센트 표시 여부 / Show percentage\n */\nexport interface ScrollProgressProps {\n className?: string\n height?: number\n color?: 'default' | 'primary' | 'secondary' | 'gradient'\n position?: 'top' | 'bottom'\n animated?: boolean\n showPercentage?: boolean\n}\n\n/**\n * ScrollProgress 컴포넌트 / ScrollProgress component\n * \n * 페이지 스크롤 진행률을 표시하는 컴포넌트입니다.\n * 페이지 상단 또는 하단에 고정되어 표시됩니다.\n * \n * Component that displays page scroll progress.\n * Fixed at top or bottom of the page.\n * \n * @component\n * @example\n * // 기본 사용 / Basic usage\n * <ScrollProgress />\n * \n * @example\n * // 하단에 표시, 퍼센트 포함 / Display at bottom with percentage\n * <ScrollProgress \n * position=\"bottom\"\n * color=\"primary\"\n * showPercentage\n * height={4}\n * />\n * \n * @param {ScrollProgressProps} props - ScrollProgress 컴포넌트의 props / ScrollProgress component props\n * @param {React.Ref<HTMLDivElement>} ref - div 요소 ref / div element ref\n * @returns {JSX.Element} ScrollProgress 컴포넌트 / ScrollProgress component\n */\nconst ScrollProgress = React.forwardRef<HTMLDivElement, ScrollProgressProps>(({\n className,\n height = 2,\n color = 'gradient',\n position = 'top',\n animated: _animated = true,\n showPercentage = false,\n ...props\n}, ref) => {\n const [progress, setProgress] = useState(0)\n\n useEffect(() => {\n const updateProgress = () => {\n const scrollTop = window.scrollY\n const docHeight = document.documentElement.scrollHeight - window.innerHeight\n const currentProgress = docHeight > 0 ? (scrollTop / docHeight) * 100 : 0\n setProgress(currentProgress)\n }\n\n // 초기 실행\n updateProgress()\n\n window.addEventListener('scroll', updateProgress, { passive: true })\n window.addEventListener('resize', updateProgress, { passive: true })\n \n return () => {\n window.removeEventListener('scroll', updateProgress)\n window.removeEventListener('resize', updateProgress)\n }\n }, [])\n\n // 색상 옵션 (Teal 브랜드 기반)\n const progressColors: Record<string, string> = {\n default: 'bg-foreground',\n primary: 'bg-primary',\n secondary: 'bg-muted-foreground',\n gradient: 'bg-gradient-to-r from-teal-600 via-cyan-500 to-teal-600'\n }\n\n const positionClasses = {\n top: 'top-0 left-0 right-0',\n bottom: 'bottom-0 left-0 right-0'\n }\n\n return (\n <div\n ref={ref}\n className={merge(\n 'fixed z-50',\n positionClasses[position],\n className\n )}\n style={{ height: `${height}px` }}\n {...props}\n >\n {/* 배경 바 */}\n <div className=\"absolute inset-0 w-full h-full bg-border/30\" />\n \n {/* 진행률 바 - absolute로 배경 위에 표시 */}\n <div\n className={merge(\n 'absolute top-0 left-0 h-full origin-left transition-all duration-100 ease-out',\n progressColors[color] || progressColors.gradient\n )}\n style={{\n width: `${progress}%`,\n transformOrigin: 'left'\n }}\n />\n \n {/* 퍼센트 표시 (선택사항) */}\n {showPercentage && (\n <div className=\"absolute top-2 right-2 text-xs text-muted-foreground bg-card px-2 py-1 rounded border border-border\">\n {Math.round(progress)}%\n </div>\n )}\n </div>\n )\n})\n\nScrollProgress.displayName = 'ScrollProgress'\n\nexport { ScrollProgress } ","\"use client\"\n\nimport React, { useState, useEffect, useCallback } from \"react\"\nimport { merge } from \"../lib/utils\"\nimport { Button } from \"./Button\"\n\n/**\n * 슬라이드 아이템 인터페이스\n */\nexport interface HeroSlide {\n title: string\n subtitle?: string\n description: string\n primaryAction?: {\n label: string\n href: string\n icon?: React.ReactNode\n }\n secondaryAction?: {\n label: string\n href: string\n icon?: React.ReactNode\n }\n background?: \"none\" | \"gradient\" | \"particles\" | \"image\"\n backgroundImage?: string\n}\n\n/**\n * HeroSection 컴포넌트의 props\n */\nexport interface HeroSectionProps extends React.HTMLAttributes<HTMLElement> {\n // 단일 모드 props\n title?: string\n subtitle?: string\n description?: string\n primaryAction?: {\n label: string\n href: string\n icon?: React.ReactNode\n }\n secondaryAction?: {\n label: string\n href: string\n icon?: React.ReactNode\n }\n // 슬라이드 모드 props\n slides?: HeroSlide[]\n autoPlay?: boolean\n interval?: number\n indicator?: \"dots\" | \"line\" | \"numbers\" | \"none\"\n showControls?: boolean\n pauseOnHover?: boolean\n // 공통 props\n background?: \"none\" | \"gradient\" | \"particles\" | \"video\" | \"image\"\n customBackground?: string\n /**\n * 히어로 섹션 크기\n * - sm: 400px, md: 500px, lg: 600px, xl: 700px\n * - full: 100vh (뷰포트 전체)\n */\n size?: \"sm\" | \"md\" | \"lg\" | \"xl\" | \"full\"\n /**\n * 헤더 뒤까지 확장 (fixed header가 있을 때)\n * true면 -mt-16 적용되어 헤더 뒤로 들어감\n */\n fullBleed?: boolean\n}\n\n/**\n * HeroSection 컴포넌트\n *\n * 단일 히어로 또는 슬라이드 히어로를 지원합니다.\n * slides prop이 있으면 슬라이드 모드로 동작합니다.\n */\nconst HeroSection = React.forwardRef<HTMLElement, HeroSectionProps>(\n ({\n className,\n // 단일 모드\n title,\n subtitle,\n description,\n primaryAction,\n secondaryAction,\n // 슬라이드 모드\n slides,\n autoPlay = false,\n interval = 5000,\n indicator = \"dots\",\n showControls = true,\n pauseOnHover = true,\n // 공통\n background = \"gradient\",\n customBackground,\n size = \"lg\",\n fullBleed = false,\n ...props\n }, ref) => {\n const [currentSlide, setCurrentSlide] = useState(0)\n const [isPaused, setIsPaused] = useState(false)\n\n // 슬라이드 모드 여부\n const isSlideMode = slides && slides.length > 0\n const slideCount = slides?.length || 0\n\n // 다음 슬라이드\n const nextSlide = useCallback(() => {\n if (!isSlideMode) return\n setCurrentSlide((prev) => (prev + 1) % slideCount)\n }, [isSlideMode, slideCount])\n\n // 이전 슬라이드\n const prevSlide = useCallback(() => {\n if (!isSlideMode) return\n setCurrentSlide((prev) => (prev - 1 + slideCount) % slideCount)\n }, [isSlideMode, slideCount])\n\n // 특정 슬라이드로 이동\n const goToSlide = useCallback((index: number) => {\n setCurrentSlide(index)\n }, [])\n\n // 자동 재생\n useEffect(() => {\n if (!autoPlay || !isSlideMode || isPaused) return\n\n const timer = setInterval(nextSlide, interval)\n return () => clearInterval(timer)\n }, [autoPlay, isSlideMode, isPaused, interval, nextSlide])\n\n // 현재 표시할 콘텐츠\n const currentContent = isSlideMode ? slides[currentSlide] : {\n title: title || \"\",\n subtitle,\n description: description || \"\",\n primaryAction,\n secondaryAction,\n background,\n }\n\n const sizeClasses = {\n sm: \"min-h-[400px]\",\n md: \"min-h-[500px]\",\n lg: \"min-h-[600px]\",\n xl: \"min-h-[700px]\",\n full: \"min-h-screen\"\n }\n\n const titleSizeClasses = {\n sm: \"text-2xl sm:text-3xl md:text-4xl leading-tight\",\n md: \"text-3xl sm:text-4xl md:text-5xl leading-tight\",\n lg: \"text-3xl sm:text-4xl md:text-5xl lg:text-6xl leading-tight\",\n xl: \"text-3xl sm:text-4xl md:text-5xl lg:text-6xl leading-tight\",\n full: \"text-4xl sm:text-5xl md:text-6xl lg:text-7xl leading-tight\"\n }\n\n const subtitleSizeClasses = {\n sm: \"text-base sm:text-lg md:text-xl leading-snug\",\n md: \"text-lg sm:text-xl md:text-2xl leading-snug\",\n lg: \"text-lg sm:text-xl md:text-2xl lg:text-3xl leading-snug\",\n xl: \"text-xl sm:text-2xl md:text-3xl leading-snug\",\n full: \"text-xl sm:text-2xl md:text-3xl lg:text-4xl leading-snug\"\n }\n\n const descriptionSizeClasses = {\n sm: \"text-sm sm:text-base md:text-lg leading-relaxed\",\n md: \"text-base sm:text-lg md:text-xl leading-relaxed\",\n lg: \"text-base sm:text-lg md:text-xl leading-relaxed\",\n xl: \"text-base sm:text-lg md:text-xl leading-relaxed\",\n full: \"text-lg sm:text-xl md:text-2xl leading-relaxed\"\n }\n\n const currentBg = isSlideMode ? (currentContent.background || background) : background\n\n const backgroundContent: Record<string, React.ReactNode> = {\n none: null,\n gradient: (\n <div className=\"absolute inset-0 z-0 pointer-events-none\">\n {/* 왼쪽 위 - 메인 그라데이션 */}\n <div className=\"absolute top-0 left-0 w-80 h-80 sm:w-96 sm:h-96 md:w-[500px] md:h-[500px] -translate-x-1/3 -translate-y-1/3 rounded-full bg-gradient-to-br from-teal-400 via-cyan-500 to-teal-600 opacity-40 blur-3xl\" />\n {/* 오른쪽 아래 - 보조 그라데이션 */}\n <div className=\"absolute bottom-0 right-0 w-72 h-72 sm:w-80 sm:h-80 md:w-[400px] md:h-[400px] translate-x-1/4 translate-y-1/4 rounded-full bg-gradient-to-tr from-cyan-400 via-teal-500 to-emerald-500 opacity-35 blur-3xl\" />\n {/* 중앙 액센트 */}\n <div className=\"absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-48 h-48 sm:w-64 sm:h-64 md:w-80 md:h-80 rounded-full bg-teal-500/20 blur-2xl\" />\n </div>\n ),\n particles: (\n <div className=\"absolute inset-0 z-0 pointer-events-none\">\n <div className=\"absolute inset-0 bg-gradient-to-br from-secondary/50 via-background to-secondary/30\" />\n </div>\n ),\n video: customBackground ? (\n <div className=\"absolute inset-0 z-0 pointer-events-none\">\n <video\n autoPlay\n loop\n muted\n playsInline\n className=\"absolute inset-0 w-full h-full object-cover opacity-20\"\n >\n <source src={customBackground} type=\"video/mp4\" />\n </video>\n </div>\n ) : null,\n image: (customBackground || (isSlideMode && (currentContent as HeroSlide).backgroundImage)) ? (\n <div className=\"absolute inset-0 z-0 pointer-events-none\">\n <img\n src={(isSlideMode && (currentContent as HeroSlide).backgroundImage) || customBackground}\n alt=\"\"\n className=\"absolute inset-0 w-full h-full object-cover opacity-30\"\n />\n <div className=\"absolute inset-0 bg-gradient-to-t from-background via-background/50 to-transparent\" />\n </div>\n ) : null,\n }\n\n // 인디케이터 렌더링\n const renderIndicator = () => {\n if (!isSlideMode || indicator === \"none\") return null\n\n switch (indicator) {\n case \"dots\":\n return (\n <div className=\"flex gap-2 justify-center mt-8\">\n {slides.map((_, index) => (\n <button\n key={index}\n onClick={() => goToSlide(index)}\n className={merge(\n \"w-2.5 h-2.5 rounded-full transition-all duration-300\",\n currentSlide === index\n ? \"bg-primary w-8\"\n : \"bg-muted-foreground/30 hover:bg-muted-foreground/50\"\n )}\n aria-label={`Go to slide ${index + 1}`}\n />\n ))}\n </div>\n )\n\n case \"line\":\n return (\n <div className=\"flex gap-1 justify-center mt-8 max-w-xs mx-auto\">\n {slides.map((_, index) => (\n <button\n key={index}\n onClick={() => goToSlide(index)}\n className=\"flex-1 h-1 rounded-full overflow-hidden bg-muted-foreground/20\"\n aria-label={`Go to slide ${index + 1}`}\n >\n <div\n className={merge(\n \"h-full bg-primary transition-all duration-300\",\n currentSlide === index ? \"w-full\" : \"w-0\"\n )}\n />\n </button>\n ))}\n </div>\n )\n\n case \"numbers\":\n return (\n <div className=\"flex items-center justify-center gap-2 mt-8 text-sm text-muted-foreground\">\n <span className=\"text-foreground font-semibold\">{currentSlide + 1}</span>\n <span>/</span>\n <span>{slideCount}</span>\n </div>\n )\n\n default:\n return null\n }\n }\n\n return (\n <section\n ref={ref}\n className={merge(\n \"relative w-full flex flex-col justify-center items-center text-center px-4 sm:px-6 lg:px-8 overflow-hidden\",\n sizeClasses[size],\n fullBleed && \"-mt-16 pt-16\",\n className\n )}\n onMouseEnter={() => pauseOnHover && setIsPaused(true)}\n onMouseLeave={() => pauseOnHover && setIsPaused(false)}\n {...props}\n >\n {backgroundContent[currentBg]}\n\n {/* 슬라이드 콘텐츠 */}\n <div className=\"relative z-10 max-w-4xl mx-auto\">\n <div\n key={isSlideMode ? currentSlide : 0}\n className=\"animate-in fade-in slide-in-from-bottom-4 duration-500\"\n >\n <h1 className={merge(\n \"font-extrabold mb-4 sm:mb-6 text-foreground\",\n titleSizeClasses[size]\n )}>\n <span className=\"block gradient-text\">\n {currentContent.title}\n </span>\n {currentContent.subtitle && (\n <span className={merge(\n \"block font-semibold mt-2 sm:mt-4 text-muted-foreground\",\n subtitleSizeClasses[size]\n )}>\n {currentContent.subtitle}\n </span>\n )}\n </h1>\n\n <div className={merge(\n \"text-muted-foreground mb-6 sm:mb-8 md:mb-10 max-w-2xl mx-auto\",\n descriptionSizeClasses[size]\n )}>\n {currentContent.description.split('\\n').map((line, i, arr) => (\n <React.Fragment key={i}>\n {line}\n {i < arr.length - 1 && <br />}\n </React.Fragment>\n ))}\n </div>\n\n {(currentContent.primaryAction || currentContent.secondaryAction) && (\n <div className=\"flex flex-col sm:flex-row gap-4 justify-center\">\n {currentContent.primaryAction && (\n <Button\n href={currentContent.primaryAction.href}\n size={size === \"xl\" || size === \"full\" ? \"lg\" : \"md\"}\n hover=\"scale\"\n className=\"inline-flex items-center gap-2\"\n >\n {currentContent.primaryAction.icon}\n {currentContent.primaryAction.label}\n </Button>\n )}\n\n {currentContent.secondaryAction && (\n <Button\n href={currentContent.secondaryAction.href}\n variant=\"outline\"\n size={size === \"xl\" || size === \"full\" ? \"lg\" : \"md\"}\n hover=\"scale\"\n className=\"inline-flex items-center gap-2\"\n >\n {currentContent.secondaryAction.icon}\n {currentContent.secondaryAction.label}\n </Button>\n )}\n </div>\n )}\n </div>\n\n {/* 인디케이터 */}\n {renderIndicator()}\n </div>\n\n {/* 좌우 컨트롤 */}\n {isSlideMode && showControls && slideCount > 1 && (\n <>\n <button\n onClick={prevSlide}\n className=\"absolute left-4 top-1/2 -translate-y-1/2 z-20 p-2 rounded-full bg-card/80 backdrop-blur-sm border border-border text-foreground hover:bg-card transition-colors\"\n aria-label=\"Previous slide\"\n >\n <svg className=\"w-5 h-5\" 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 </button>\n <button\n onClick={nextSlide}\n className=\"absolute right-4 top-1/2 -translate-y-1/2 z-20 p-2 rounded-full bg-card/80 backdrop-blur-sm border border-border text-foreground hover:bg-card transition-colors\"\n aria-label=\"Next slide\"\n >\n <svg className=\"w-5 h-5\" 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 </button>\n </>\n )}\n </section>\n )\n }\n)\n\nHeroSection.displayName = \"HeroSection\"\n\nexport { HeroSection }\n"]}
@@ -0,0 +1,3 @@
1
+ "use client";
2
+ import {a}from'./chunk-QEMPERUK.mjs';import e from'react';import {jsxs,jsx}from'react/jsx-runtime';var c=e.forwardRef(({className:r,content:o,children:a$1,position:d="top",variant:h="default",delay:y=300,disabled:T=false,...v},w)=>{let[x,f]=e.useState(false),[p,k]=e.useState({x:0,y:0}),l=e.useRef(void 0),g=e.useRef(null),R=E=>{var b;if(T)return;let t=E.currentTarget.getBoundingClientRect();(b=g.current)==null?void 0:b.getBoundingClientRect();let s=0,n=0;switch(d){case "top":s=t.left+t.width/2,n=t.top-8;break;case "bottom":s=t.left+t.width/2,n=t.bottom+8;break;case "left":s=t.left-8,n=t.top+t.height/2;break;case "right":s=t.right+8,n=t.top+t.height/2;break}k({x:s,y:n}),l.current=window.setTimeout(()=>{f(true);},y);},L=()=>{l.current&&clearTimeout(l.current),f(false);};e.useEffect(()=>()=>{l.current&&clearTimeout(l.current);},[]);let M=()=>{switch(h){case "light":return "bg-popover text-popover-foreground border border-border shadow-lg";case "dark":return "bg-gray-900 text-white shadow-lg";default:return "bg-gray-800 text-white shadow-lg"}},N=()=>{switch(d){case "top":return "top-full left-1/2 -translate-x-1/2 border-t-gray-800 dark:border-t-gray-800";case "bottom":return "bottom-full left-1/2 -translate-x-1/2 border-b-gray-800 dark:border-b-gray-800";case "left":return "left-full top-1/2 -translate-y-1/2 border-l-gray-800 dark:border-l-gray-800";case "right":return "right-full top-1/2 -translate-y-1/2 border-r-gray-800 dark:border-r-gray-800";default:return "top-full left-1/2 -translate-x-1/2 border-t-gray-800 dark:border-t-gray-800"}};return jsxs("div",{ref:w,className:a("relative inline-block",r),onMouseEnter:R,onMouseLeave:L,...v,children:[a$1,x&&jsxs("div",{ref:g,className:a("fixed z-50 px-3 py-2 text-sm rounded-lg whitespace-nowrap pointer-events-none",M()),style:{left:`${p.x}px`,top:`${p.y}px`,transform:"translate(-50%, -50%)"},children:[o,jsx("div",{className:a("absolute w-0 h-0 border-4 border-transparent",N())})]})]})});c.displayName="Tooltip";var D=e.forwardRef(({className:r,...o},a)=>jsx(c,{ref:a,variant:"light",className:r,...o}));D.displayName="TooltipLight";var C=e.forwardRef(({className:r,...o},a)=>jsx(c,{ref:a,variant:"dark",className:r,...o}));C.displayName="TooltipDark";export{c as a,D as b,C as c};//# sourceMappingURL=chunk-5L5HIPKA.mjs.map
3
+ //# sourceMappingURL=chunk-5L5HIPKA.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/Tooltip.tsx"],"names":["Tooltip","React","className","content","children","position","variant","delay","disabled","props","ref","isVisible","setIsVisible","coords","setCoords","timeoutRef","tooltipRef","showTooltip","e","_a","rect","x","y","hideTooltip","getVariantClasses","getArrowClasses","jsxs","merge","jsx","TooltipLight","TooltipDark"],"mappings":"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","file":"chunk-3GAUTZXQ.mjs","sourcesContent":["\"use client\"\n\nimport React from \"react\"\nimport { merge } from \"../lib/utils\"\n\n/**\n * Tooltip 컴포넌트의 props / Tooltip component props\n * @typedef {Object} TooltipProps\n * @property {string} content - Tooltip 내용 / Tooltip content\n * @property {React.ReactNode} children - Tooltip이 연결될 요소 / Element to attach tooltip to\n * @property {\"top\" | \"bottom\" | \"left\" | \"right\"} [position=\"top\"] - Tooltip 표시 위치 / Tooltip display position\n * @property {\"default\" | \"light\" | \"dark\"} [variant=\"default\"] - Tooltip 스타일 변형 / Tooltip style variant\n * @property {number} [delay=300] - Tooltip 표시 지연 시간(ms) / Tooltip display delay (ms)\n * @property {boolean} [disabled=false] - Tooltip 비활성화 여부 / Disable tooltip\n * @extends {React.HTMLAttributes<HTMLDivElement>}\n */\nexport interface TooltipProps extends React.HTMLAttributes<HTMLDivElement> {\n content: string\n children: React.ReactNode\n position?: \"top\" | \"bottom\" | \"left\" | \"right\"\n variant?: \"default\" | \"light\" | \"dark\"\n delay?: number\n disabled?: boolean\n}\n\n/**\n * Tooltip 컴포넌트 / Tooltip component\n * \n * 호버 시 추가 정보를 표시하는 툴팁 컴포넌트입니다.\n * 마우스 호버 시 지연 시간 후 표시됩니다.\n * \n * Tooltip component that displays additional information on hover.\n * Appears after a delay when the mouse hovers over the element.\n * \n * @component\n * @example\n * // 기본 사용 / Basic usage\n * <Tooltip content=\"이것은 도움말입니다\">\n * <Button>호버하세요</Button>\n * </Tooltip>\n * \n * @example\n * // 다양한 위치 / Different positions\n * <Tooltip content=\"위치 변경\" position=\"bottom\">\n * <Icon name=\"info\" />\n * </Tooltip>\n * \n * @example\n * // 커스텀 스타일 / Custom styles\n * <Tooltip content=\"라이트 스타일\" variant=\"light\" delay={500}>\n * <span>호버</span>\n * </Tooltip>\n * \n * @param {TooltipProps} props - Tooltip 컴포넌트의 props / Tooltip component props\n * @param {React.Ref<HTMLDivElement>} ref - div 요소 ref / div element ref\n * @returns {JSX.Element} Tooltip 컴포넌트 / Tooltip component\n * \n * @todo 접근성 개선: role=\"tooltip\" 추가 필요 / Accessibility: Add role=\"tooltip\"\n * @todo 접근성 개선: aria-describedby 연결 필요 / Accessibility: Connect aria-describedby\n * @todo 접근성 개선: 키보드 포커스 시 Tooltip 표시 필요 / Accessibility: Show tooltip on keyboard focus\n */\nconst Tooltip = React.forwardRef<HTMLDivElement, TooltipProps>(\n ({ \n className, \n content,\n children,\n position = \"top\",\n variant = \"default\",\n delay = 300,\n disabled = false,\n ...props \n }, ref) => {\n const [isVisible, setIsVisible] = React.useState(false)\n const [coords, setCoords] = React.useState({ x: 0, y: 0 })\n const timeoutRef = React.useRef<number | undefined>(undefined)\n const tooltipRef = React.useRef<HTMLDivElement>(null)\n\n const showTooltip = (e: React.MouseEvent) => {\n if (disabled) return\n \n const rect = e.currentTarget.getBoundingClientRect()\n const _tooltipRect = tooltipRef.current?.getBoundingClientRect()\n \n let x = 0\n let y = 0\n \n switch (position) {\n case \"top\":\n x = rect.left + rect.width / 2\n y = rect.top - 8 // 8px 간격\n break\n case \"bottom\":\n x = rect.left + rect.width / 2\n y = rect.bottom + 8 // 8px 간격\n break\n case \"left\":\n x = rect.left - 8 // 8px 간격\n y = rect.top + rect.height / 2\n break\n case \"right\":\n x = rect.right + 8 // 8px 간격\n y = rect.top + rect.height / 2\n break\n }\n \n setCoords({ x, y })\n \n timeoutRef.current = window.setTimeout(() => {\n setIsVisible(true)\n }, delay)\n }\n\n const hideTooltip = () => {\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current)\n }\n setIsVisible(false)\n }\n\n React.useEffect(() => {\n return () => {\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current)\n }\n }\n }, [])\n\n const getVariantClasses = () => {\n switch (variant) {\n case \"light\":\n return \"bg-popover text-popover-foreground border border-border shadow-lg\"\n case \"dark\":\n return \"bg-gray-900 text-white shadow-lg\"\n default:\n return \"bg-gray-800 text-white shadow-lg\"\n }\n }\n\n const _getPositionClasses = () => {\n switch (position) {\n case \"top\":\n return \"bottom-full left-1/2 -translate-x-1/2 mb-2\" // 8px 간격\n case \"bottom\":\n return \"top-full left-1/2 -translate-x-1/2 mt-2\" // 8px 간격\n case \"left\":\n return \"right-full top-1/2 -translate-y-1/2 mr-2\" // 8px 간격\n case \"right\":\n return \"left-full top-1/2 -translate-y-1/2 ml-2\" // 8px 간격\n default:\n return \"bottom-full left-1/2 -translate-x-1/2 mb-2\"\n }\n }\n\n const getArrowClasses = () => {\n switch (position) {\n case \"top\":\n return \"top-full left-1/2 -translate-x-1/2 border-t-gray-800 dark:border-t-gray-800\"\n case \"bottom\":\n return \"bottom-full left-1/2 -translate-x-1/2 border-b-gray-800 dark:border-b-gray-800\"\n case \"left\":\n return \"left-full top-1/2 -translate-y-1/2 border-l-gray-800 dark:border-l-gray-800\"\n case \"right\":\n return \"right-full top-1/2 -translate-y-1/2 border-r-gray-800 dark:border-r-gray-800\"\n default:\n return \"top-full left-1/2 -translate-x-1/2 border-t-gray-800 dark:border-t-gray-800\"\n }\n }\n\n return (\n <div\n ref={ref}\n className={merge(\"relative inline-block\", className)}\n onMouseEnter={showTooltip}\n onMouseLeave={hideTooltip}\n {...props}\n >\n {children}\n \n {isVisible && (\n <div\n ref={tooltipRef}\n className={merge(\n \"fixed z-50 px-3 py-2 text-sm rounded-lg whitespace-nowrap pointer-events-none\", // 12px, 8px 패딩\n getVariantClasses()\n )}\n style={{\n left: `${coords.x}px`,\n top: `${coords.y}px`,\n transform: 'translate(-50%, -50%)'\n }}\n >\n {content}\n {/* 화살표 */}\n <div\n className={merge(\n \"absolute w-0 h-0 border-4 border-transparent\",\n getArrowClasses()\n )}\n />\n </div>\n )}\n </div>\n )\n }\n)\nTooltip.displayName = \"Tooltip\"\n\n// 편의 컴포넌트들\nexport const TooltipLight = React.forwardRef<HTMLDivElement, Omit<TooltipProps, \"variant\">>(\n ({ className, ...props }, ref) => (\n <Tooltip ref={ref} variant=\"light\" className={className} {...props} />\n )\n)\nTooltipLight.displayName = \"TooltipLight\"\n\nexport const TooltipDark = React.forwardRef<HTMLDivElement, Omit<TooltipProps, \"variant\">>(\n ({ className, ...props }, ref) => (\n <Tooltip ref={ref} variant=\"dark\" className={className} {...props} />\n )\n)\nTooltipDark.displayName = \"TooltipDark\"\n\nexport { Tooltip } "]}
1
+ {"version":3,"sources":["../src/components/Tooltip.tsx"],"names":["Tooltip","React","className","content","children","position","variant","delay","disabled","props","ref","isVisible","setIsVisible","coords","setCoords","timeoutRef","tooltipRef","showTooltip","e","_a","rect","x","y","hideTooltip","getVariantClasses","getArrowClasses","jsxs","merge","jsx","TooltipLight","TooltipDark"],"mappings":"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","file":"chunk-5L5HIPKA.mjs","sourcesContent":["\"use client\"\n\nimport React from \"react\"\nimport { merge } from \"../lib/utils\"\n\n/**\n * Tooltip 컴포넌트의 props / Tooltip component props\n * @typedef {Object} TooltipProps\n * @property {string} content - Tooltip 내용 / Tooltip content\n * @property {React.ReactNode} children - Tooltip이 연결될 요소 / Element to attach tooltip to\n * @property {\"top\" | \"bottom\" | \"left\" | \"right\"} [position=\"top\"] - Tooltip 표시 위치 / Tooltip display position\n * @property {\"default\" | \"light\" | \"dark\"} [variant=\"default\"] - Tooltip 스타일 변형 / Tooltip style variant\n * @property {number} [delay=300] - Tooltip 표시 지연 시간(ms) / Tooltip display delay (ms)\n * @property {boolean} [disabled=false] - Tooltip 비활성화 여부 / Disable tooltip\n * @extends {React.HTMLAttributes<HTMLDivElement>}\n */\nexport interface TooltipProps extends React.HTMLAttributes<HTMLDivElement> {\n content: string\n children: React.ReactNode\n position?: \"top\" | \"bottom\" | \"left\" | \"right\"\n variant?: \"default\" | \"light\" | \"dark\"\n delay?: number\n disabled?: boolean\n}\n\n/**\n * Tooltip 컴포넌트 / Tooltip component\n * \n * 호버 시 추가 정보를 표시하는 툴팁 컴포넌트입니다.\n * 마우스 호버 시 지연 시간 후 표시됩니다.\n * \n * Tooltip component that displays additional information on hover.\n * Appears after a delay when the mouse hovers over the element.\n * \n * @component\n * @example\n * // 기본 사용 / Basic usage\n * <Tooltip content=\"이것은 도움말입니다\">\n * <Button>호버하세요</Button>\n * </Tooltip>\n * \n * @example\n * // 다양한 위치 / Different positions\n * <Tooltip content=\"위치 변경\" position=\"bottom\">\n * <Icon name=\"info\" />\n * </Tooltip>\n * \n * @example\n * // 커스텀 스타일 / Custom styles\n * <Tooltip content=\"라이트 스타일\" variant=\"light\" delay={500}>\n * <span>호버</span>\n * </Tooltip>\n * \n * @param {TooltipProps} props - Tooltip 컴포넌트의 props / Tooltip component props\n * @param {React.Ref<HTMLDivElement>} ref - div 요소 ref / div element ref\n * @returns {JSX.Element} Tooltip 컴포넌트 / Tooltip component\n * \n * @todo 접근성 개선: role=\"tooltip\" 추가 필요 / Accessibility: Add role=\"tooltip\"\n * @todo 접근성 개선: aria-describedby 연결 필요 / Accessibility: Connect aria-describedby\n * @todo 접근성 개선: 키보드 포커스 시 Tooltip 표시 필요 / Accessibility: Show tooltip on keyboard focus\n */\nconst Tooltip = React.forwardRef<HTMLDivElement, TooltipProps>(\n ({ \n className, \n content,\n children,\n position = \"top\",\n variant = \"default\",\n delay = 300,\n disabled = false,\n ...props \n }, ref) => {\n const [isVisible, setIsVisible] = React.useState(false)\n const [coords, setCoords] = React.useState({ x: 0, y: 0 })\n const timeoutRef = React.useRef<number | undefined>(undefined)\n const tooltipRef = React.useRef<HTMLDivElement>(null)\n\n const showTooltip = (e: React.MouseEvent) => {\n if (disabled) return\n \n const rect = e.currentTarget.getBoundingClientRect()\n const _tooltipRect = tooltipRef.current?.getBoundingClientRect()\n \n let x = 0\n let y = 0\n \n switch (position) {\n case \"top\":\n x = rect.left + rect.width / 2\n y = rect.top - 8 // 8px 간격\n break\n case \"bottom\":\n x = rect.left + rect.width / 2\n y = rect.bottom + 8 // 8px 간격\n break\n case \"left\":\n x = rect.left - 8 // 8px 간격\n y = rect.top + rect.height / 2\n break\n case \"right\":\n x = rect.right + 8 // 8px 간격\n y = rect.top + rect.height / 2\n break\n }\n \n setCoords({ x, y })\n \n timeoutRef.current = window.setTimeout(() => {\n setIsVisible(true)\n }, delay)\n }\n\n const hideTooltip = () => {\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current)\n }\n setIsVisible(false)\n }\n\n React.useEffect(() => {\n return () => {\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current)\n }\n }\n }, [])\n\n const getVariantClasses = () => {\n switch (variant) {\n case \"light\":\n return \"bg-popover text-popover-foreground border border-border shadow-lg\"\n case \"dark\":\n return \"bg-gray-900 text-white shadow-lg\"\n default:\n return \"bg-gray-800 text-white shadow-lg\"\n }\n }\n\n const _getPositionClasses = () => {\n switch (position) {\n case \"top\":\n return \"bottom-full left-1/2 -translate-x-1/2 mb-2\" // 8px 간격\n case \"bottom\":\n return \"top-full left-1/2 -translate-x-1/2 mt-2\" // 8px 간격\n case \"left\":\n return \"right-full top-1/2 -translate-y-1/2 mr-2\" // 8px 간격\n case \"right\":\n return \"left-full top-1/2 -translate-y-1/2 ml-2\" // 8px 간격\n default:\n return \"bottom-full left-1/2 -translate-x-1/2 mb-2\"\n }\n }\n\n const getArrowClasses = () => {\n switch (position) {\n case \"top\":\n return \"top-full left-1/2 -translate-x-1/2 border-t-gray-800 dark:border-t-gray-800\"\n case \"bottom\":\n return \"bottom-full left-1/2 -translate-x-1/2 border-b-gray-800 dark:border-b-gray-800\"\n case \"left\":\n return \"left-full top-1/2 -translate-y-1/2 border-l-gray-800 dark:border-l-gray-800\"\n case \"right\":\n return \"right-full top-1/2 -translate-y-1/2 border-r-gray-800 dark:border-r-gray-800\"\n default:\n return \"top-full left-1/2 -translate-x-1/2 border-t-gray-800 dark:border-t-gray-800\"\n }\n }\n\n return (\n <div\n ref={ref}\n className={merge(\"relative inline-block\", className)}\n onMouseEnter={showTooltip}\n onMouseLeave={hideTooltip}\n {...props}\n >\n {children}\n \n {isVisible && (\n <div\n ref={tooltipRef}\n className={merge(\n \"fixed z-50 px-3 py-2 text-sm rounded-lg whitespace-nowrap pointer-events-none\", // 12px, 8px 패딩\n getVariantClasses()\n )}\n style={{\n left: `${coords.x}px`,\n top: `${coords.y}px`,\n transform: 'translate(-50%, -50%)'\n }}\n >\n {content}\n {/* 화살표 */}\n <div\n className={merge(\n \"absolute w-0 h-0 border-4 border-transparent\",\n getArrowClasses()\n )}\n />\n </div>\n )}\n </div>\n )\n }\n)\nTooltip.displayName = \"Tooltip\"\n\n// 편의 컴포넌트들\nexport const TooltipLight = React.forwardRef<HTMLDivElement, Omit<TooltipProps, \"variant\">>(\n ({ className, ...props }, ref) => (\n <Tooltip ref={ref} variant=\"light\" className={className} {...props} />\n )\n)\nTooltipLight.displayName = \"TooltipLight\"\n\nexport const TooltipDark = React.forwardRef<HTMLDivElement, Omit<TooltipProps, \"variant\">>(\n ({ className, ...props }, ref) => (\n <Tooltip ref={ref} variant=\"dark\" className={className} {...props} />\n )\n)\nTooltipDark.displayName = \"TooltipDark\"\n\nexport { Tooltip } "]}
@@ -0,0 +1,3 @@
1
+ "use client";
2
+ import {createContext,useState,useEffect,useContext}from'react';import {jsx}from'react/jsx-runtime';var p={theme:"system",setTheme:()=>null,resolvedTheme:"light",toggleTheme:()=>null},T=createContext(p);function E({children:r,defaultTheme:u="light",storageKey:s="hua-ui-theme",enableSystem:i=true,enableTransition:h=true,...g}){let[t,n]=useState(u),[a,d]=useState("light");useEffect(()=>{if(typeof window!="undefined"){let e=localStorage.getItem(s);e&&n(e);}},[s]),useEffect(()=>{let e=window.document.documentElement;if(e.classList.remove("light","dark"),t==="system"&&i){let o=window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light";e.classList.add(o),d(o);}else e.classList.add(t),d(t);h&&e.classList.add("transition-colors","duration-300");},[t,i,h]),useEffect(()=>{if(t==="system"&&i){let e=window.matchMedia("(prefers-color-scheme: dark)"),o=()=>{let c=e.matches?"dark":"light";d(c),document.documentElement.classList.remove("light","dark"),document.documentElement.classList.add(c);};return e.addEventListener("change",o),()=>e.removeEventListener("change",o)}},[t,i]);let v={theme:t,setTheme:e=>{typeof window!="undefined"&&localStorage.setItem(s,e),n(e);},resolvedTheme:a,toggleTheme:()=>{let e=a==="light"?"dark":"light";typeof window!="undefined"&&localStorage.setItem(s,e),n(e);}};return jsx(T.Provider,{...g,value:v,children:r})}var L=()=>{let r=useContext(T);if(r===void 0)throw new Error("useTheme must be used within a ThemeProvider");return r};export{E as a,L as b};//# sourceMappingURL=chunk-A5YOVVM5.mjs.map
3
+ //# sourceMappingURL=chunk-A5YOVVM5.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/ThemeProvider.tsx"],"names":["initialState","ThemeProviderContext","createContext","ThemeProvider","children","defaultTheme","storageKey","enableSystem","enableTransition","props","theme","setTheme","useState","resolvedTheme","setResolvedTheme","useEffect","savedTheme","root","systemTheme","mediaQuery","handleChange","value","newTheme","jsx","useTheme","context","useContext"],"mappings":"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","file":"chunk-A5YOVVM5.mjs","sourcesContent":["\"use client\"\n\nimport React, { createContext, useContext, useEffect, useState } from \"react\"\n\ntype Theme = \"light\" | \"dark\" | \"system\"\n\n/**\n * ThemeProvider 컴포넌트의 props / ThemeProvider component props\n * @typedef {Object} ThemeProviderProps\n * @property {React.ReactNode} children - 자식 컴포넌트 / Child components\n * @property {\"light\" | \"dark\" | \"system\"} [defaultTheme=\"light\"] - 기본 테마 / Default theme\n * @property {string} [storageKey=\"hua-ui-theme\"] - localStorage 키 / localStorage key\n * @property {boolean} [enableSystem=true] - 시스템 테마 감지 활성화 / Enable system theme detection\n * @property {boolean} [enableTransition=true] - 테마 전환 애니메이션 활성화 / Enable theme transition animation\n */\nexport interface ThemeProviderProps {\n children: React.ReactNode\n defaultTheme?: Theme\n storageKey?: string\n enableSystem?: boolean\n enableTransition?: boolean\n}\n\n/**\n * ThemeProvider의 상태 타입 / ThemeProvider state type\n * @typedef {Object} ThemeProviderState\n * @property {\"light\" | \"dark\" | \"system\"} theme - 현재 테마 / Current theme\n * @property {(theme: \"light\" | \"dark\" | \"system\") => void} setTheme - 테마 설정 함수 / Theme setter function\n * @property {\"light\" | \"dark\"} resolvedTheme - 실제 적용된 테마 (system일 경우 시스템 테마) / Actually applied theme (system theme when system is selected)\n * @property {() => void} toggleTheme - 테마 토글 함수 / Theme toggle function\n */\nexport interface ThemeProviderState {\n theme: Theme\n setTheme: (theme: Theme) => void\n resolvedTheme: \"light\" | \"dark\"\n toggleTheme: () => void\n}\n\nconst initialState: ThemeProviderState = {\n theme: \"system\",\n setTheme: () => null,\n resolvedTheme: \"light\",\n toggleTheme: () => null,\n}\n\nconst ThemeProviderContext = createContext<ThemeProviderState>(initialState)\n\n/**\n * ThemeProvider 컴포넌트 / ThemeProvider component\n * \n * 테마 관리를 위한 Context Provider 컴포넌트입니다.\n * localStorage에 테마를 저장하고, 시스템 테마를 감지할 수 있습니다.\n * useTheme 훅을 통해 테마 상태에 접근할 수 있습니다.\n * \n * Context Provider component for theme management.\n * Saves theme to localStorage and can detect system theme.\n * Access theme state through useTheme hook.\n * \n * @component\n * @example\n * // 기본 사용 / Basic usage\n * <ThemeProvider>\n * <App />\n * </ThemeProvider>\n * \n * @example\n * // 커스텀 설정 / Custom settings\n * <ThemeProvider\n * defaultTheme=\"dark\"\n * storageKey=\"my-app-theme\"\n * enableSystem={true}\n * enableTransition={true}\n * >\n * <App />\n * </ThemeProvider>\n * \n * @param {ThemeProviderProps} props - ThemeProvider 컴포넌트의 props / ThemeProvider component props\n * @returns {JSX.Element} ThemeProvider 컴포넌트 / ThemeProvider component\n */\nexport function ThemeProvider({\n children,\n defaultTheme = \"light\", // system에서 light로 변경\n storageKey = \"hua-ui-theme\",\n enableSystem = true,\n enableTransition = true,\n ...props\n}: ThemeProviderProps): React.ReactElement {\n const [theme, setTheme] = useState<Theme>(defaultTheme)\n const [resolvedTheme, setResolvedTheme] = useState<\"light\" | \"dark\">(\"light\")\n\n useEffect(() => {\n // localStorage에서 테마 가져오기 (클라이언트에서만)\n if (typeof window !== 'undefined') {\n const savedTheme = localStorage.getItem(storageKey) as Theme\n if (savedTheme) {\n setTheme(savedTheme)\n }\n }\n }, [storageKey])\n\n useEffect(() => {\n const root = window.document.documentElement\n\n root.classList.remove(\"light\", \"dark\")\n\n if (theme === \"system\" && enableSystem) {\n const systemTheme = window.matchMedia(\"(prefers-color-scheme: dark)\")\n .matches\n ? \"dark\"\n : \"light\"\n\n root.classList.add(systemTheme)\n setResolvedTheme(systemTheme)\n } else {\n root.classList.add(theme)\n setResolvedTheme(theme as \"light\" | \"dark\")\n }\n\n if (enableTransition) {\n root.classList.add(\"transition-colors\", \"duration-300\")\n }\n }, [theme, enableSystem, enableTransition])\n\n useEffect(() => {\n if (theme === \"system\" && enableSystem) {\n const mediaQuery = window.matchMedia(\"(prefers-color-scheme: dark)\")\n\n const handleChange = () => {\n const systemTheme = mediaQuery.matches ? \"dark\" : \"light\"\n setResolvedTheme(systemTheme)\n document.documentElement.classList.remove(\"light\", \"dark\")\n document.documentElement.classList.add(systemTheme)\n }\n\n mediaQuery.addEventListener(\"change\", handleChange)\n return () => mediaQuery.removeEventListener(\"change\", handleChange)\n }\n }, [theme, enableSystem])\n\n const value = {\n theme,\n setTheme: (theme: Theme) => {\n if (typeof window !== 'undefined') {\n localStorage.setItem(storageKey, theme)\n }\n setTheme(theme)\n },\n resolvedTheme,\n toggleTheme: () => {\n const newTheme = resolvedTheme === \"light\" ? \"dark\" : \"light\"\n if (typeof window !== 'undefined') {\n localStorage.setItem(storageKey, newTheme)\n }\n setTheme(newTheme)\n },\n }\n\n return (\n <ThemeProviderContext.Provider {...props} value={value}>\n {children}\n </ThemeProviderContext.Provider>\n )\n}\n\n/**\n * useTheme 훅 / useTheme hook\n * \n * ThemeProvider의 테마 상태에 접근하는 훅입니다.\n * ThemeProvider 내부에서만 사용할 수 있습니다.\n * \n * Hook to access ThemeProvider's theme state.\n * Can only be used inside ThemeProvider.\n * \n * @example\n * const { theme, setTheme, resolvedTheme, toggleTheme } = useTheme()\n * \n * @returns {ThemeProviderState} 테마 상태와 함수들 / Theme state and functions\n * @throws {Error} ThemeProvider 외부에서 사용 시 에러 발생 / Error when used outside ThemeProvider\n */\nexport const useTheme = () => {\n const context = useContext(ThemeProviderContext)\n\n if (context === undefined)\n throw new Error(\"useTheme must be used within a ThemeProvider\")\n\n return context\n} "]}
@@ -0,0 +1,13 @@
1
+ "use client";
2
+ import {a as a$1}from'./chunk-SD6XGDAC.mjs';import {l}from'./chunk-ZQUMJQYV.mjs';import {a}from'./chunk-QEMPERUK.mjs';import X,{useState,useRef,useCallback,useEffect,useMemo,createContext,useContext}from'react';import {jsxs,jsx,Fragment}from'react/jsx-runtime';var G=X.forwardRef(({children:r,className:e,type:t="fade",duration:n=500,easing:a$1="smooth",delay:i=0,autoStart:g=true,onStart:v,onComplete:u,showProgress:s=false,progressClassName:h},p)=>{let[f,c]=useState(false),[l,o]=useState(0),[y,T]=useState(false),w=useRef(null),b=useRef(null),d=k=>({linear:P=>P,"ease-in":P=>P*P,"ease-out":P=>1-Math.pow(1-P,2),"ease-in-out":P=>P<.5?2*P*P:1-Math.pow(-2*P+2,2)/2,bounce:P=>P<.36363636363636365?7.5625*P*P:P<.7272727272727273?7.5625*(P-=.5454545454545454)*P+.75:P<.9090909090909091?7.5625*(P-=.8181818181818182)*P+.9375:7.5625*(P-=.9545454545454546)*P+.984375,elastic:P=>Math.pow(2,-10*P)*Math.sin((P-.075)*(2*Math.PI)/.3)+1,smooth:P=>P*P*(3-2*P)})[k],x=useCallback(k=>{b.current||(b.current=k);let M=k-b.current,P=d(a$1),B=Math.min(M/n,1);B=P(B),o(B),c(B>.1),B<1?w.current=requestAnimationFrame(F=>x(F)):(T(false),o(1),u==null||u());},[n,a$1,u]),m=useCallback(()=>{T(true),o(0),v==null||v(),b.current=null,w.current=requestAnimationFrame(x);},[x,v]);useEffect(()=>{if(g){let k=setTimeout(()=>{m();},i);return ()=>clearTimeout(k)}},[g,i,m]),useEffect(()=>()=>{w.current&&cancelAnimationFrame(w.current);},[]);let C=(()=>{switch(t){case "fade":return {opacity:f?1:0,transform:"none"};case "slide":return {opacity:f?1:0,transform:`translateX(${(1-l)*100}%)`};case "slide-up":return {opacity:f?1:0,transform:`translateY(${(1-l)*100}%)`};case "slide-down":return {opacity:f?1:0,transform:`translateY(-${(1-l)*100}%)`};case "slide-left":return {opacity:f?1:0,transform:`translateX(-${(1-l)*100}%)`};case "slide-right":return {opacity:f?1:0,transform:`translateX(${(1-l)*100}%)`};case "scale":return {opacity:f?1:0,transform:`scale(${.8+l*.2})`};case "flip":return {opacity:f?1:0,transform:`perspective(1000px) rotateY(${(1-l)*90}deg)`};case "morph":return {opacity:f?1:0,transform:`scale(${.9+l*.1}) rotate(${(1-l)*5}deg)`};case "cube":return {opacity:f?1:0,transform:`perspective(1000px) rotateX(${(1-l)*90}deg) rotateY(${(1-l)*45}deg)`};case "zoom":return {opacity:f?1:0,transform:`scale(${.5+l*.5})`};default:return {opacity:f?1:0,transform:"none"}}})();return jsxs("div",{className:"relative",children:[s&&jsxs("div",{className:a("fixed top-4 right-4 z-50 bg-background rounded-lg px-3 py-2 shadow-lg border",h),children:[jsxs("div",{className:"text-sm font-medium text-foreground",children:["Progress: ",Math.round(l*100),"%"]}),jsx("div",{className:"w-24 h-2 bg-muted rounded-full mt-2",children:jsx("div",{className:"h-full bg-primary rounded-full transition-all duration-100",style:{width:`${l*100}%`}})})]}),jsx("div",{ref:p,className:a("transition-all duration-500 ease-out",e),style:{...C,transitionDuration:`${n}ms`,transitionTimingFunction:a$1==="smooth"?"cubic-bezier(0.4, 0, 0.2, 1)":a$1==="bounce"?"cubic-bezier(0.68, -0.55, 0.265, 1.55)":a$1==="elastic"?"cubic-bezier(0.175, 0.885, 0.32, 1.275)":a$1},children:r})]})});G.displayName="AdvancedPageTransition";var Dt=X.forwardRef((r,e)=>jsx(G,{ref:e,type:"fade",...r})),Vt=X.forwardRef((r,e)=>jsx(G,{ref:e,type:"slide",...r})),qt=X.forwardRef((r,e)=>jsx(G,{ref:e,type:"scale",...r})),Ot=X.forwardRef((r,e)=>jsx(G,{ref:e,type:"flip",...r})),_t=X.forwardRef((r,e)=>jsx(G,{ref:e,type:"morph",...r})),Ut=X.forwardRef((r,e)=>jsx(G,{ref:e,type:"cube",...r})),Yt=X.forwardRef((r,e)=>jsx(G,{ref:e,type:"zoom",...r}));Dt.displayName="FadePageTransition";Vt.displayName="SlidePageTransition";qt.displayName="ScalePageTransition";Ot.displayName="FlipPageTransition";_t.displayName="MorphPageTransition";Ut.displayName="CubePageTransition";Yt.displayName="ZoomPageTransition";var jt=(r={})=>{let[e,t]=useState({isTransitioning:false,isVisible:false,currentStep:0,progress:0}),n=useRef(null),a=useRef(null),i=useRef({type:"fade",duration:500,easing:"smooth",delay:0,stagger:0,direction:"forward",...r}),g=useCallback(c=>({linear:o=>o,"ease-in":o=>o*o,"ease-out":o=>1-Math.pow(1-o,2),"ease-in-out":o=>o<.5?2*o*o:1-Math.pow(-2*o+2,2)/2,bounce:o=>o<.36363636363636365?7.5625*o*o:o<.7272727272727273?7.5625*(o-=.5454545454545454)*o+.75:o<.9090909090909091?7.5625*(o-=.8181818181818182)*o+.9375:7.5625*(o-=.9545454545454546)*o+.984375,elastic:o=>Math.pow(2,-10*o)*Math.sin((o-.075)*(2*Math.PI)/.3)+1,smooth:o=>o*o*(3-2*o)})[c],[]),v=useCallback(c=>{var w;a.current||(a.current=c);let l=c-a.current,o=i.current,y=g(o.easing),T=Math.min(l/o.duration,1);T=y(T),t(b=>({...b,progress:T,isVisible:o.direction==="forward"?T>.1:T<.9,currentStep:Math.floor(T*10)})),T<1?n.current=requestAnimationFrame(v):(t(b=>({...b,isTransitioning:false,progress:o.direction==="forward"?1:0})),(w=o.onComplete)==null||w.call(o));},[g]),u=useCallback(async c=>new Promise(l=>{var y;c&&(i.current={...i.current,...c});let o=i.current;o.onComplete=()=>l(),t(T=>({...T,isTransitioning:true,progress:o.direction==="forward"?0:1})),a.current=null,(y=o.onStart)==null||y.call(o),o.delay?setTimeout(()=>{n.current=requestAnimationFrame(v);},o.delay):n.current=requestAnimationFrame(v);}),[v]),s=useCallback(async()=>new Promise(c=>{let l=i.current;l.direction="backward",l.onComplete=()=>c(),u();}),[u]),h=useCallback(()=>{n.current&&cancelAnimationFrame(n.current);},[]),p=useCallback(()=>{e.isTransitioning&&(n.current=requestAnimationFrame(v));},[e.isTransitioning,v]),f=useCallback(()=>{n.current&&cancelAnimationFrame(n.current),t({isTransitioning:false,isVisible:false,currentStep:0,progress:0});},[]);return useEffect(()=>()=>{n.current&&cancelAnimationFrame(n.current);},[]),[e,{start:u,reverse:s,pause:h,resume:p,reset:f}]};var Jt=(r={})=>{let{defaultType:e="fade",defaultDuration:t=500,defaultEasing:n="smooth",enableHistory:a=true,enableProgress:i=true,enableDebug:g=false}=r,[v,u]=useState({isTransitioning:false,currentTransition:null,transitionHistory:[],totalTransitions:0,averageDuration:0}),s=useRef(new Map),h=useRef(0),p=useCallback((b,d)=>{g&&console.log(`[PageTransitionManager] ${b}`,d);},[g]),f=useCallback(b=>{u(d=>{let x=a?[...d.transitionHistory,b]:d.transitionHistory,m=x.length,R=x.reduce((C,k)=>C+k.duration,0)/m;return {...d,totalTransitions:m,averageDuration:R,transitionHistory:x}});},[a]),c=useCallback(async b=>{let d=`transition_${++h.current}`,x={type:e,duration:t,easing:n,...b},m={id:d,type:x.type,duration:x.duration,easing:x.easing,timestamp:Date.now(),status:"pending"};p("Starting transition",{id:d,config:x}),u(C=>({...C,isTransitioning:true,currentTransition:m}));let R=setTimeout(()=>{var k;let C={...m,status:"completed"};u(M=>({...M,isTransitioning:false,currentTransition:null})),f(C),s.current.delete(d),p("Transition completed",{id:d}),(k=x.onComplete)==null||k.call(x);},x.duration);return s.current.set(d,{timer:R,config:x}),setTimeout(()=>{u(C=>({...C,currentTransition:{...C.currentTransition,status:"active"}}));},50),d},[e,t,n,p,f]),l=useCallback(b=>{let d=s.current.get(b);d&&(clearTimeout(d.timer),s.current.delete(b),u(x=>{var m;return {...x,isTransitioning:s.current.size>0,currentTransition:((m=x.currentTransition)==null?void 0:m.id)===b?null:x.currentTransition}}),p("Transition cancelled",{id:b}));},[p]),o=useCallback(()=>{s.current.forEach(({timer:b},d)=>{clearTimeout(b),p("Transition paused",{id:d});});},[p]),y=useCallback(()=>{s.current.forEach(({config:b},d)=>{c(b);});},[c]),T=useCallback(()=>{u(b=>({...b,transitionHistory:[],totalTransitions:0,averageDuration:0})),p("History cleared");},[p]),w=useCallback(()=>{let{transitionHistory:b}=v,d=b.reduce((m,R)=>(m[R.type]=(m[R.type]||0)+1,m),{}),x=b.reduce((m,R)=>(m[R.status]=(m[R.status]||0)+1,m),{});return {total:b.length,average:v.averageDuration,byType:d,byStatus:x}},[v]);return useEffect(()=>{let b=s.current;return ()=>{b.forEach(({timer:d})=>{clearTimeout(d);}),b.clear();}},[]),[v,{startTransition:c,cancelTransition:l,pauseAll:o,resumeAll:y,clearHistory:T,getTransitionStats:w}]};var ie=new Set,xe=false,$e=0;function er(){ie.forEach(r=>r());}function Ee(){cancelAnimationFrame($e),$e=requestAnimationFrame(er);}function tr(r){return ie.add(r),!xe&&ie.size>0&&(window.addEventListener("scroll",Ee,{passive:true}),window.addEventListener("resize",Ee,{passive:true}),xe=true),()=>{ie.delete(r),xe&&ie.size===0&&(window.removeEventListener("scroll",Ee),window.removeEventListener("resize",Ee),cancelAnimationFrame($e),xe=false);}}var yt=X.forwardRef(({children:r,className:e,speed:t=.5,direction:n="up",offset:a$2=0,disabled:i=false,scale:g=false,opacity:v=false,rotate:u=false,rotateDirection:s="cw",disableOnMobile:h=false,style:p,...f},c)=>{let l=useRef(null),o=useRef(true),y=useRef(false),T=a$1();useEffect(()=>{if(!h)return;let x=window.matchMedia("(max-width: 767px)");y.current=x.matches;let m=R=>{y.current=R.matches,R.matches&&l.current&&(l.current.style.transform="",l.current.style.opacity="");};return x.addEventListener("change",m),()=>x.removeEventListener("change",m)},[h]);let w=useCallback(()=>{if(i||T||h&&y.current||!o.current)return;let x=l.current;if(!x)return;let m=x.getBoundingClientRect(),R=window.innerHeight,C=m.top+m.height/2,M=(R/2-C)/R,P=M*t*100+a$2,B=0,F=0;switch(n){case "up":F=-P;break;case "down":F=P;break;case "left":B=-P;break;case "right":B=P;break}let O=g?1+Math.abs(M)*.1:1,A=v?Math.max(.3,1-Math.abs(M)*.5):1,D=u?M*10*(s==="cw"?1:-1):0;x.style.transform=`translate3d(${B}px, ${F}px, 0) scale(${O}) rotate(${D}deg)`,v&&(x.style.opacity=String(A));},[i,T,t,n,a$2,g,v,u,s,h]);useEffect(()=>{if(i||T)return;let x=l.current;if(!x)return;let m=new IntersectionObserver(([R])=>{o.current=R.isIntersecting;},{rootMargin:"100px"});return m.observe(x),()=>m.disconnect()},[i,T]),useEffect(()=>{if(!(i||T))return w(),tr(w)},[w,i,T]);let d={...p,willChange:!i&&!T?"transform, opacity":void 0};return jsx("div",{ref:rr(c,l),className:a("transition-none",e),style:d,...f,children:r})});yt.displayName="Parallax";function rr(...r){return e=>{r.forEach(t=>{typeof t=="function"?t(e):t&&typeof t=="object"&&(t.current=e);});}}var Tt=X.forwardRef(({text:r,className:e,revealColor:t="currentColor",hiddenColor:n="rgba(128, 128, 128, 0.3)",threshold:a$2=.5,byWord:i=false,byChar:g=false,style:v,...u},s)=>{let h=useRef(null),[p,f]=useState(0),c=a$1(),l=useCallback(()=>{if(!h.current)return;let y=h.current.getBoundingClientRect(),T=window.innerHeight,w=T*(1-a$2),b=T*a$2,d=y.top+y.height/2,x=0;d<=w&&d>=b?x=(w-d)/(w-b):d<b&&(x=1),f(Math.max(0,Math.min(1,x)));},[a$2]);useEffect(()=>{if(c){f(1);return}l();let y=()=>{requestAnimationFrame(l);};return window.addEventListener("scroll",y,{passive:true}),window.addEventListener("resize",y,{passive:true}),()=>{window.removeEventListener("scroll",y),window.removeEventListener("resize",y);}},[l,c]);let o=()=>{if(g){let y=r.split("");return y.map((T,w)=>{let b=p*y.length,d=w<b;return jsx("span",{style:{color:d?t:n,transition:"color 0.1s ease-out"},children:T},w)})}if(i){let y=r.split(" ");return y.map((T,w)=>{let b=p*y.length,d=w<b;return jsxs("span",{children:[jsx("span",{style:{color:d?t:n,transition:"color 0.15s ease-out"},children:T}),w<y.length-1&&" "]},w)})}return jsx("span",{style:{background:`linear-gradient(90deg, ${t} ${p*100}%, ${n} ${p*100}%)`,WebkitBackgroundClip:"text",WebkitTextFillColor:"transparent",backgroundClip:"text",transition:"background 0.1s ease-out"},children:r})};return jsx("div",{ref:cr(s,h),className:a("font-medium",e),style:v,...u,children:o()})});Tt.displayName="TextReveal";function cr(...r){return e=>{r.forEach(t=>{typeof t=="function"?t(e):t&&typeof t=="object"&&(t.current=e);});}}var xt=X.forwardRef(({children:r,className:e,maxTilt:t=15,perspective:n=1e3,scale:a$1=1.02,speed:i=400,glare:g=true,maxGlare:v=.3,reset:u=true,style:s,...h},p)=>{let f=useRef(null),[c,l]=useState({rotateX:0,rotateY:0,scale:1}),[o,y]=useState({x:50,y:50}),[T,w]=useState(false),b=useCallback(k=>{if(!f.current)return;let M=f.current.getBoundingClientRect(),P=M.left+M.width/2,B=M.top+M.height/2,F=k.clientX-P,O=k.clientY-B,A=F/(M.width/2)*t,D=-(O/(M.height/2))*t;l({rotateX:D,rotateY:A,scale:a$1});let Te=(k.clientX-M.left)/M.width*100,ee=(k.clientY-M.top)/M.height*100;y({x:Te,y:ee});},[t,a$1]),d=()=>{w(true);},x=()=>{w(false),u&&l({rotateX:0,rotateY:0,scale:1});},m={...s,perspective:`${n}px`},R={transform:`rotateX(${c.rotateX}deg) rotateY(${c.rotateY}deg) scale(${c.scale})`,transition:T?"none":`transform ${i}ms ease-out`,transformStyle:"preserve-3d"},C={position:"absolute",top:0,left:0,right:0,bottom:0,borderRadius:"inherit",background:`linear-gradient(
3
+ ${Math.atan2(o.y-50,o.x-50)*(180/Math.PI)+90}deg,
4
+ rgba(255, 255, 255, ${T?v:0}) 0%,
5
+ transparent 80%
6
+ )`,transition:T?"opacity 0.1s ease-out":`opacity ${i}ms ease-out`,pointerEvents:"none",opacity:T?1:0};return jsx("div",{ref:mr(p,f),className:a("relative",e),style:m,onMouseMove:b,onMouseEnter:d,onMouseLeave:x,...h,children:jsxs("div",{style:R,className:"relative",children:[r,g&&jsx("div",{style:C,"aria-hidden":"true"})]})})});xt.displayName="TiltCard";function mr(...r){return e=>{r.forEach(t=>{typeof t=="function"?t(e):t&&typeof t=="object"&&(t.current=e);});}}var wt=X.forwardRef(({src:r,type:e="native",poster:t,autoPlay:n=true,loop:a$1=true,muted:i=true,controls:g=false,objectFit:v="cover",overlay:u=true,overlayColor:s="rgba(0, 0, 0, 0.4)",gradient:h=false,gradientDirection:p="bottom",playbackRate:f=1,fadeIn:c=true,children:l,className:o,style:y,...T},w)=>{let b=useRef(null),[d,x]=useState(false),[m,R]=useState(false);useEffect(()=>{e==="native"&&b.current&&(b.current.playbackRate=f);},[f,e]);let C=()=>{x(true);},k=()=>{R(true);},M=A=>{let D=new URLSearchParams({autoplay:n?"1":"0",mute:i?"1":"0",loop:a$1?"1":"0",controls:g?"1":"0",playlist:A,modestbranding:"1",rel:"0",showinfo:"0",iv_load_policy:"3",disablekb:"1",enablejsapi:"1",playsinline:"1"});return `https://www.youtube.com/embed/${A}?${D.toString()}`},P=A=>{let D=new URLSearchParams({autoplay:n?"1":"0",muted:i?"1":"0",loop:a$1?"1":"0",controls:g?"1":"0",background:"1",quality:"auto",dnt:"1"});return `https://player.vimeo.com/video/${A}?${D.toString()}`},B=()=>{let A={cover:"object-cover",contain:"object-contain",fill:"object-fill"}[v];switch(e){case "youtube":return jsx("iframe",{src:M(r),className:a("absolute inset-0 w-full h-full pointer-events-none","scale-[1.2]"),style:{opacity:d||!c?1:0,transition:c?"opacity 0.8s ease-out":void 0},allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:true,onLoad:()=>x(true),title:"YouTube video background"});case "vimeo":return jsx("iframe",{src:P(r),className:"absolute inset-0 w-full h-full pointer-events-none",style:{opacity:d||!c?1:0,transition:c?"opacity 0.8s ease-out":void 0},allow:"autoplay; fullscreen; picture-in-picture",allowFullScreen:true,onLoad:()=>x(true),title:"Vimeo video background"});default:return jsx("video",{ref:b,src:r,poster:t,autoPlay:n,loop:a$1,muted:i,controls:g,playsInline:true,className:a("absolute inset-0 w-full h-full",A),style:{opacity:m||!c?1:0,transition:c?"opacity 0.8s ease-out":void 0},onLoadedData:C,onPlaying:k})}},F=()=>{if(!h)return null;let A=[];return (p==="top"||p==="both")&&A.push(jsx("div",{className:"absolute top-0 left-0 right-0 h-1/3",style:{background:`linear-gradient(to bottom, ${s}, transparent)`},"aria-hidden":"true"},"top")),(p==="bottom"||p==="both")&&A.push(jsx("div",{className:"absolute bottom-0 left-0 right-0 h-1/3",style:{background:`linear-gradient(to top, ${s}, transparent)`},"aria-hidden":"true"},"bottom")),jsx(Fragment,{children:A})},O=o&&/\b(fixed|absolute|sticky)\b/.test(o);return jsxs("div",{ref:w,className:a("overflow-hidden",!O&&"relative",o),style:y,...T,children:[t&&c&&!d&&!m&&jsx("div",{className:"absolute inset-0 bg-cover bg-center",style:{backgroundImage:`url(${t})`},"aria-hidden":"true"}),B(),u&&!h&&jsx("div",{className:"absolute inset-0",style:{backgroundColor:s},"aria-hidden":"true"}),F(),l&&jsx("div",{className:"relative z-10 h-full",children:l})]})});wt.displayName="VideoBackground";var Rt=X.forwardRef(({src:r,alt:e,direction:t="left",threshold:n=.3,height:a$2="400px",overlayColor:i,className:g,style:v,...u},s)=>{let h=useRef(null),[p,f]=useState(0),c=a$1(),l=useCallback(()=>{if(!h.current)return;let y=h.current.getBoundingClientRect(),T=window.innerHeight,w=T*(1-n),b=T*n,d=y.top+y.height/2,x=0;d<=w&&d>=b?x=(w-d)/(w-b):d<b&&(x=1),f(Math.max(0,Math.min(1,x)));},[n]);useEffect(()=>{if(c){f(1);return}l();let y=()=>requestAnimationFrame(l);return window.addEventListener("scroll",y,{passive:true}),window.addEventListener("resize",y,{passive:true}),()=>{window.removeEventListener("scroll",y),window.removeEventListener("resize",y);}},[l,c]);let o=kr(t,p);return jsxs("div",{ref:Mr(s,h),className:a("relative overflow-hidden",g),style:{height:a$2,...v},...u,children:[jsx("img",{src:r,alt:e,className:"absolute inset-0 w-full h-full object-cover",style:{clipPath:o,transition:"clip-path 0.1s ease-out"}}),i&&jsx("div",{className:"absolute inset-0 pointer-events-none",style:{background:i,opacity:1-p,transition:"opacity 0.3s ease-out"},"aria-hidden":"true"})]})});Rt.displayName="ImageReveal";function kr(r,e){switch(r){case "left":return `inset(0 ${100-e*100}% 0 0)`;case "right":return `inset(0 0 0 ${100-e*100}%)`;case "up":return `inset(0 0 ${100-e*100}% 0)`;case "down":return `inset(${100-e*100}% 0 0 0)`;default:return `inset(0 ${100-e*100}% 0 0)`}}function Mr(...r){return e=>{r.forEach(t=>{typeof t=="function"?t(e):t&&typeof t=="object"&&(t.current=e);});}}var Mt=X.forwardRef(({items:r,position:e="right",activeColor:t="bg-primary",inactiveColor:n="bg-muted-foreground/30",className:a$1,...i},g)=>{let[v,u]=useState(0),s=useCallback(()=>{let f=window.innerHeight,c=0,l=1/0;r.forEach((o,y)=>{let T=document.getElementById(o.id);if(!T)return;let w=T.getBoundingClientRect(),b=Math.abs(w.top-f*.3);b<l&&(l=b,c=y);}),u(c);},[r]);useEffect(()=>(s(),window.addEventListener("scroll",s,{passive:true}),()=>window.removeEventListener("scroll",s)),[s]);let h=useCallback(f=>{let c=document.getElementById(f);c&&c.scrollIntoView({behavior:"smooth",block:"start"});},[]),p=useMemo(()=>e==="left"?"left-4":"right-4",[e]);return jsx("nav",{ref:g,className:a("fixed top-1/2 -translate-y-1/2 z-40 flex flex-col gap-3",p,a$1),"aria-label":"Section navigation",...i,children:r.map((f,c)=>jsx("button",{onClick:()=>h(f.id),className:a("group relative w-3 h-3 rounded-full transition-all duration-300",c===v?`${t} scale-125`:`${n} hover:scale-110`),"aria-label":f.label||f.id,"aria-current":c===v?"true":void 0,children:f.label&&jsx("span",{className:a("absolute top-1/2 -translate-y-1/2 whitespace-nowrap px-2 py-1 text-xs rounded bg-popover text-popover-foreground shadow-md opacity-0 group-hover:opacity-100 transition-opacity pointer-events-none",e==="right"?"right-full mr-2":"left-full ml-2"),children:f.label})},f.id))})});Mt.displayName="DotNav";var Lt=X.forwardRef(({children:r,heightMultiplier:e=1,snap:t=false,onProgress:n,className:a$1,style:i,...g},v)=>{let u=useRef(null),s=useRef(null),[h,p]=useState(0),[f,c]=useState(0);useEffect(()=>{if(!s.current)return;let T=()=>{s.current&&p(s.current.scrollWidth-window.innerWidth);};T();let w=new ResizeObserver(T);return w.observe(s.current),()=>w.disconnect()},[r]);let l=useCallback(()=>{if(!u.current||h<=0)return;let T=u.current.getBoundingClientRect(),w=u.current.offsetHeight-window.innerHeight,b=-T.top,d=Math.max(0,Math.min(1,b/w));c(d),n==null||n(d);},[h,n]);useEffect(()=>(window.addEventListener("scroll",l,{passive:true}),()=>window.removeEventListener("scroll",l)),[l]);let y=`${X.Children.count(r)*e*100}vh`;return jsx("div",{ref:Ar(v,u),className:a("relative",a$1),style:{height:y,...i},...g,children:jsx("div",{className:"sticky top-0 h-screen overflow-hidden",children:jsx("div",{ref:s,className:a("flex h-full will-change-transform",t&&"scroll-snap-x"),style:{transform:`translateX(${-f*h}px)`},children:X.Children.map(r,(T,w)=>jsx("div",{className:a("flex-shrink-0 w-screen h-full",t&&"snap-start"),children:T},w))})})})});Lt.displayName="HorizontalScroll";function Ar(...r){return e=>{r.forEach(t=>{typeof t=="function"?t(e):t&&typeof t=="object"&&(t.current=e);});}}function De(r){return r.toLowerCase().replace(/[^a-z0-9가-힣ぁ-んァ-ン一-龯_.~\s-]/g,"").replace(/\s+/g,"-").replace(/-+/g,"-").replace(/^-+|-+$/g,"").trim()}function $r(r){return !r||r.length===0||r.length>200?false:/^[a-z0-9가-힣ぁ-んァ-ン一-龯_.~-]+$/.test(r)}function Ve(r){return r.toLowerCase().replace(/\s+/g,"-").replace(/[^a-z0-9가-힣ぁ-んァ-ン一-龯_.~-]/g,"").replace(/-+/g,"-").replace(/^-+|-+$/g,"")}var zr={pageTitle:"\uC0C8 \uAE00 \uC791\uC131",editTitle:"\uAE00 \uC218\uC815",preview:"\uBBF8\uB9AC\uBCF4\uAE30",editMode:"\uD3B8\uC9D1",basicInfo:"\uAE30\uBCF8 \uC815\uBCF4",slug:"\uC2AC\uB7EC\uADF8",slugPrefix:"/blog/",tags:"\uD0DC\uADF8",tagsPlaceholder:"\uAC1C\uBC1C, \uC77C\uC0C1, \uC5C5\uB370\uC774\uD2B8",coverImage:"\uCEE4\uBC84 \uC774\uBBF8\uC9C0 URL",coverImagePlaceholder:"https://example.com/image.jpg",publishDate:"\uBC1C\uD589 \uC608\uC57D\uC77C\uC2DC",publishDateHint:"\uBE44\uC6CC\uB450\uBA74 \uC989\uC2DC \uBC1C\uD589\uB428",expiresAt:"\uB9CC\uB8CC \uC77C\uC2DC",expiresAtHint:"\uBE44\uC6CC\uB450\uBA74 \uB9CC\uB8CC\uB418\uC9C0 \uC54A\uC74C",titleLabel:"\uC81C\uBAA9",titlePlaceholder:"\uC81C\uBAA9\uC744 \uC785\uB825\uD558\uC138\uC694",excerpt:"\uC694\uC57D",excerptPlaceholder:"\uCE74\uB4DC\uC5D0 \uD45C\uC2DC\uB420 \uC9E7\uC740 \uC694\uC57D",contentLabel:"\uBCF8\uBB38",contentPlaceholder:"\uB9C8\uD06C\uB2E4\uC6B4\uC73C\uB85C \uC791\uC131\uD558\uC138\uC694...",cancel:"\uCDE8\uC18C",saveDraft:"\uC784\uC2DC\uC800\uC7A5",publish:"\uBC1C\uD589",update:"\uC218\uC815 \uC644\uB8CC",saving:"\uC800\uC7A5 \uC911...",translateHint:"AI \uBC88\uC5ED \uAE30\uB2A5",translateButton:"AI \uBC88\uC5ED",translating:"\uBC88\uC5ED \uC911...",translateSuccess:"\uBC88\uC5ED \uC644\uB8CC!",requiredFields:"\uD544\uC218 \uD544\uB4DC\uB97C \uC785\uB825\uD574\uC8FC\uC138\uC694",saveError:"\uC800\uC7A5 \uC911 \uC624\uB958 \uBC1C\uC0DD",translateError:"\uBC88\uC5ED \uC911 \uC624\uB958 \uBC1C\uC0DD",noTitle:"\uC81C\uBAA9 \uC5C6\uC74C",bold:"\uAD75\uAC8C",italic:"\uAE30\uC6B8\uC784",strikethrough:"\uCDE8\uC18C\uC120",heading:"\uC81C\uBAA9",link:"\uB9C1\uD06C",image:"\uC774\uBBF8\uC9C0",code:"\uCF54\uB4DC",codeBlock:"\uCF54\uB4DC\uBE14\uB85D",quote:"\uC778\uC6A9\uBB38",list:"\uBAA9\uB85D",orderedList:"\uC21C\uC11C \uBAA9\uB85D",horizontalRule:"\uC218\uD3C9\uC120"},Dr={enableSlug:true,enableTags:true,enableCoverImage:true,enablePublishDate:true,enableExcerpt:true,enableTranslation:true,enablePreview:true,enableMarkdownToolbar:true,enableAutoSave:true,enableExpiresAt:false},Vr=[{key:"ko",label:"\uD55C\uAD6D\uC5B4",isPrimary:true,flag:"\u{1F1F0}\u{1F1F7}"},{key:"en",label:"English",flag:"\u{1F1FA}\u{1F1F8}"},{key:"ja",label:"\u65E5\u672C\u8A9E",flag:"\u{1F1EF}\u{1F1F5}"}];function Oe(r){let e={};return r.forEach(t=>{e[t.key]="";}),e}function qr(r,e){var t,n,a,i,g,v,u,s;return {slug:(t=e==null?void 0:e.slug)!=null?t:"",title:(n=e==null?void 0:e.title)!=null?n:Oe(r),excerpt:(a=e==null?void 0:e.excerpt)!=null?a:Oe(r),content:(i=e==null?void 0:e.content)!=null?i:Oe(r),tags:(g=e==null?void 0:e.tags)!=null?g:[],coverImage:(v=e==null?void 0:e.coverImage)!=null?v:"",publishedAt:(u=e==null?void 0:e.publishedAt)!=null?u:null,expiresAt:(s=e==null?void 0:e.expiresAt)!=null?s:null}}var At=createContext(null);function H(){let r=useContext(At);if(!r)throw new Error("useBlogEditor must be used within a BlogEditorProvider");return r}function _e({children:r,initialData:e,isEditMode:t=false,languages:n=Vr,defaultLanguage:a,labels:i,callbacks:g,features:v,variant:u="default",autoSaveKey:s,autoSaveInterval:h=3e3}){var it,lt,ct,dt;let p=(dt=(ct=(it=n.find(L=>L.isPrimary))==null?void 0:it.key)!=null?ct:(lt=n[0])==null?void 0:lt.key)!=null?dt:"ko",f=a!=null?a:p,c=useMemo(()=>({...zr,...i}),[i]),l=useMemo(()=>({...Dr,...v}),[v]),[o,y]=useState(()=>qr(n,e)),[T,w]=useState(f),[b,d]=useState(false),[x,m]=useState(false),[R,C]=useState(false),[k,M]=useState(false),[P,B]=useState(null),[F,O]=useState(false),[A,D]=useState(t||!!(e!=null&&e.slug)),[Te,ee]=useState("idle"),ae=useRef(null),Ze=useRef(true),Y=s||(t?null:"blog-editor-draft");useEffect(()=>{if(!(!l.enableAutoSave||!Y||t))try{let L=localStorage.getItem(Y);if(L){let z=JSON.parse(L);y(z);}}catch{}},[]),useEffect(()=>{if(!(!l.enableAutoSave||!Y)){if(Ze.current){Ze.current=false;return}return ae.current&&clearTimeout(ae.current),ee("saving"),ae.current=setTimeout(()=>{try{localStorage.setItem(Y,JSON.stringify(o)),ee("saved"),setTimeout(()=>ee("idle"),2e3);}catch{ee("idle");}},h),()=>{ae.current&&clearTimeout(ae.current);}}},[o,l.enableAutoSave,Y,h]);let Qe=useCallback(()=>{if(Y)try{localStorage.removeItem(Y);}catch{}},[Y]),et=useCallback((L,z)=>{y(K=>({...K,[L]:z}));},[]),tt=useCallback((L,z,K)=>{y(J=>({...J,[L]:{...J[L],[z]:K}}));},[]),rt=useCallback(L=>De(L),[]),ot=useCallback(async L=>{let z=o.title[p],K=o.content[p];if(!z||!K){B(c.requiredFields);return}if(l.enableSlug&&!o.slug){B(c.requiredFields);return}m(true),B(null);try{await g.onSave(o,L),Qe();}catch{B(c.saveError);}finally{m(false);}},[o,p,c,l,g,Qe]),nt=useCallback(async()=>{if(!g.onTranslate)return;let L=o.title[p],z=o.content[p],K=o.excerpt[p];if(!L||!z){B(c.requiredFields);return}C(true),B(null),O(false);try{let J=await g.onTranslate({sourceLanguage:p,title:L,content:z,excerpt:K||void 0});y(he=>{let ut={...he.title},gt={...he.content},pt={...he.excerpt};return Object.keys(J).forEach(se=>{if(se!==p){let Be=J[se];if(typeof Be=="object"&&Be!==null){let te=Be;te.title&&(ut[se]=te.title),te.content&&(gt[se]=te.content),te.excerpt&&(pt[se]=te.excerpt);}}}),{...he,title:ut,content:gt,excerpt:pt}}),O(!0),setTimeout(()=>O(!1),3e3);}catch{B(c.translateError);}finally{C(false);}},[o,p,c,g]),at=useCallback(async L=>{if(!g.onUploadImage)return null;M(true),B(null);try{return await g.onUploadImage(L)}catch{return B("\uC774\uBBF8\uC9C0 \uC5C5\uB85C\uB4DC \uC2E4\uD328"),null}finally{M(false);}},[g]),st=useCallback(()=>{var L;(L=g.onCancel)==null||L.call(g);},[g]),zt=useMemo(()=>({formData:o,activeLanguage:T,showPreview:b,submitting:x,translating:R,uploading:k,error:P,translateSuccess:F,autoSaveStatus:Te,languages:n,features:l,labels:c,variant:u,isEditMode:t,setActiveLanguage:w,setShowPreview:d,updateField:et,updateMultilingualField:tt,handleSave:ot,handleTranslate:nt,handleUploadImage:at,handleCancel:st,setError:B,generateSlug:rt,slugManuallyEdited:A,setSlugManuallyEdited:D}),[o,T,b,x,R,k,P,F,Te,n,l,c,u,t,et,tt,ot,nt,at,st,rt,A,D]);return jsx(At.Provider,{value:zt,children:r})}var le=X.forwardRef(({onBack:r,backLink:e,className:t},n)=>{let{labels:a$1,isEditMode:i,formData:g}=H();return jsx("header",{ref:n,className:a("flex items-center justify-between mb-8",t),children:jsxs("div",{className:"flex items-center gap-4",children:[e||r&&jsx("button",{type:"button",onClick:r,className:"p-2 text-muted-foreground hover:text-foreground transition-colors","aria-label":"\uB4A4\uB85C\uAC00\uAE30",children:jsx(l,{name:"chevronLeft",size:24})}),jsxs("div",{children:[jsx("h1",{className:"text-2xl font-bold text-foreground",children:i?a$1.editTitle:a$1.pageTitle}),i&&g.slug&&jsxs("p",{className:"text-sm text-muted-foreground",children:[a$1.slugPrefix,g.slug]})]})]})})});le.displayName="BlogEditorHeader";var ce=X.forwardRef(({className:r},e)=>{var d,x;let{formData:t,updateField:n,features:a$1,labels:i,variant:g,handleUploadImage:v,uploading:u,setSlugManuallyEdited:s}=H(),[h,p]=useState(""),f=useRef(null),c=a("rounded-xl p-6 space-y-4",g==="glass"?"bg-white/10 backdrop-blur-sm border border-white/20 dark:bg-background/20 dark:border-border/50":g==="minimal"?"bg-transparent":"bg-background",r),l$1="w-full px-3 py-2 border border-border rounded-lg bg-background text-foreground focus:ring-1 focus:ring-ring focus:border-transparent transition-colors",o="block text-sm font-medium text-foreground mb-1",y=useCallback(m=>{let R=m.trim();R&&!t.tags.includes(R)&&n("tags",[...t.tags,R]),p("");},[t.tags,n]),T=useCallback(m=>{n("tags",t.tags.filter(R=>R!==m));},[t.tags,n]),w=useCallback(m=>{let R=m.target.value;if(R.includes(",")){let C=R.split(",");C.forEach((k,M)=>{M<C.length-1?y(k):p(k);});}else p(R);},[y]),b=useCallback(m=>{m.key==="Enter"?(m.preventDefault(),y(h)):m.key==="Backspace"&&!h&&t.tags.length>0&&T(t.tags[t.tags.length-1]);},[h,t.tags,y,T]);return jsxs("div",{ref:e,className:c,children:[jsx("h2",{className:"font-semibold text-foreground",children:i.basicInfo}),jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[a$1.enableSlug&&jsxs("div",{children:[jsxs("label",{className:o,children:[i.slug," *"]}),jsxs("div",{className:"flex items-center",children:[jsx("span",{className:"text-muted-foreground mr-1 text-sm",children:i.slugPrefix}),jsx("input",{type:"text",value:t.slug,onChange:m=>{n("slug",Ve(m.target.value)),s(true);},className:a(l$1,"flex-1"),placeholder:"my-post-slug"})]})]}),a$1.enableTags&&jsxs("div",{children:[jsx("label",{className:o,children:i.tags}),jsxs("div",{className:a("flex flex-wrap items-center gap-2 min-h-[42px] px-3 py-2 border border-border rounded-lg bg-background focus-within:ring-1 focus-within:ring-ring focus-within:border-transparent transition-colors"),children:[t.tags.map(m=>jsxs("span",{className:"inline-flex items-center gap-1 px-2 py-0.5 bg-primary/10 text-primary text-sm rounded-md",children:[m,jsx("button",{type:"button",onClick:()=>T(m),className:"hover:text-primary transition-colors","aria-label":`${m} \uD0DC\uADF8 \uC0AD\uC81C`,children:jsx(l,{name:"x",size:14})})]},m)),jsx("input",{type:"text",value:h,onChange:w,onKeyDown:b,className:"flex-1 min-w-[100px] bg-transparent outline-none text-foreground text-sm",placeholder:t.tags.length===0?i.tagsPlaceholder:"\uD0DC\uADF8 \uCD94\uAC00..."})]}),jsx("p",{className:"mt-1 text-xs text-muted-foreground",children:"\uC27C\uD45C(,) \uB610\uB294 Enter\uB85C \uD0DC\uADF8 \uCD94\uAC00"})]})]}),a$1.enableCoverImage&&jsxs("div",{children:[jsx("label",{className:o,children:i.coverImage}),jsxs("div",{className:"space-y-3",children:[t.coverImage&&jsxs("div",{className:"relative w-full h-40 rounded-lg overflow-hidden bg-muted",children:[jsx("img",{src:t.coverImage,alt:"\uCEE4\uBC84 \uC774\uBBF8\uC9C0 \uBBF8\uB9AC\uBCF4\uAE30",className:"w-full h-full object-cover"}),jsx("button",{type:"button",onClick:()=>n("coverImage",""),className:"absolute top-2 right-2 p-1.5 bg-red-500 text-white rounded-full hover:bg-red-600 transition-colors","aria-label":"\uC774\uBBF8\uC9C0 \uC0AD\uC81C",children:jsx(l,{name:"x",size:14})})]}),jsxs("div",{className:"flex gap-2",children:[jsx("input",{type:"text",value:t.coverImage,onChange:m=>n("coverImage",m.target.value),className:a(l$1,"flex-1"),placeholder:i.coverImagePlaceholder}),jsx("input",{ref:f,type:"file",accept:"image/*",className:"hidden",onChange:async m=>{var C;let R=(C=m.target.files)==null?void 0:C[0];if(R){let k=await v(R);k&&n("coverImage",k);}m.target.value="";}}),jsx("button",{type:"button",onClick:()=>{var m;return (m=f.current)==null?void 0:m.click()},disabled:u,className:"px-3 py-2 border border-border rounded-lg hover:bg-muted disabled:opacity-50 disabled:cursor-not-allowed transition-colors",title:"\uC774\uBBF8\uC9C0 \uC5C5\uB85C\uB4DC",children:u?jsx(l,{name:"loader",size:20,spin:true}):jsx(l,{name:"upload",size:20})})]})]})]}),jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[a$1.enablePublishDate&&jsxs("div",{children:[jsx("label",{className:o,children:i.publishDate}),jsx("input",{type:"datetime-local",value:(d=t.publishedAt)!=null?d:"",onChange:m=>n("publishedAt",m.target.value||null),className:l$1}),jsx("p",{className:"mt-1 text-sm text-muted-foreground",children:i.publishDateHint})]}),a$1.enableExpiresAt&&jsxs("div",{children:[jsx("label",{className:o,children:i.expiresAt}),jsx("input",{type:"datetime-local",value:(x=t.expiresAt)!=null?x:"",onChange:m=>n("expiresAt",m.target.value||null),className:l$1}),jsx("p",{className:"mt-1 text-sm text-muted-foreground",children:i.expiresAtHint})]})]})]})});ce.displayName="BlogEditorMetadata";var de=X.forwardRef(({className:r},e)=>{let{languages:t,activeLanguage:n,setActiveLanguage:a$1,showPreview:i,setShowPreview:g,features:v,labels:u}=H();return jsxs("div",{ref:e,className:a("flex items-center border-b border-border sticky top-0 z-10 bg-background",r),role:"tablist","aria-label":"\uC5B8\uC5B4 \uC120\uD0DD",children:[jsx("div",{className:"flex flex-1",children:t.map(s=>{let h=n===s.key,p=s.isPrimary;return jsxs("button",{type:"button",role:"tab","aria-selected":h,"aria-controls":`tabpanel-${s.key}`,id:`tab-${s.key}`,onClick:()=>a$1(s.key),className:a("flex-1 px-4 py-3 text-sm font-medium transition-colors",h?"bg-primary/10 text-primary border-b-2 border-primary":"text-muted-foreground hover:bg-muted"),children:[s.flag&&jsx("span",{className:"mr-1.5",children:s.flag}),s.label,p&&" *"]},s.key)})}),v.enablePreview&&jsxs("button",{type:"button",onClick:()=>g(!i),className:"inline-flex items-center gap-1.5 px-3 py-2 mx-2 text-sm border border-border rounded-lg hover:bg-muted transition-colors shrink-0",children:[jsx(l,{name:i?"pencil":"eye",size:14}),i?u.editMode:u.preview]})]})});de.displayName="BlogEditorLanguageTabs";var pe=X.forwardRef(({className:r,textareaRef:e},t)=>{var b;let{formData:n,activeLanguage:a$1,updateMultilingualField:i,updateField:g,features:v,labels:u,languages:s,generateSlug:h,isEditMode:p,slugManuallyEdited:f}=H(),c=((b=s.find(d=>d.isPrimary))==null?void 0:b.key)===a$1,l=s.find(d=>d.key===a$1),o="w-full px-3 py-2 border border-border rounded-lg bg-background text-foreground focus:ring-1 focus:ring-ring focus:border-transparent transition-colors",y="block text-sm font-medium text-foreground mb-1",T=d=>{i("title",a$1,d),a$1==="en"&&!p&&!f&&g("slug",h(d));},w=d=>c?`${d} *`:`${d} (${(l==null?void 0:l.label)||a$1})`;return jsxs("div",{ref:t,className:a("p-6 space-y-4",r),children:[jsxs("div",{children:[jsx("label",{className:y,children:w(u.titleLabel)}),jsx("input",{type:"text",value:n.title[a$1]||"",onChange:d=>T(d.target.value),className:o,placeholder:u.titlePlaceholder})]}),v.enableExcerpt&&jsxs("div",{children:[jsx("label",{className:y,children:w(u.excerpt)}),jsx("textarea",{value:n.excerpt[a$1]||"",onChange:d=>i("excerpt",a$1,d.target.value),rows:2,className:a(o,"resize-none"),placeholder:u.excerptPlaceholder})]}),jsxs("div",{children:[jsxs("label",{className:y,children:[w(u.contentLabel)," (\uB9C8\uD06C\uB2E4\uC6B4)"]}),jsx("textarea",{ref:e,value:n.content[a$1]||"",onChange:d=>i("content",a$1,d.target.value),rows:15,className:a(o,"font-mono text-sm resize-y min-h-[300px]"),placeholder:u.contentPlaceholder})]})]})});pe.displayName="BlogEditorContent";function Wr(r){return r.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#039;")}function Ge(r){if(!r)return "";let e=r;return e=e.replace(/```(\w*)\n?([\s\S]*?)```/g,(t,n,a)=>`<pre class="bg-gray-100 dark:bg-gray-800 rounded-lg p-4 overflow-x-auto my-4"><code class="text-sm">${Wr(a.trim())}</code></pre>`),e=e.replace(/`([^`]+)`/g,'<code class="bg-gray-100 dark:bg-gray-700 px-1.5 py-0.5 rounded text-sm">$1</code>'),e=e.replace(/^######\s+(.+)$/gm,'<h6 class="text-base font-semibold mt-4 mb-2">$1</h6>'),e=e.replace(/^#####\s+(.+)$/gm,'<h5 class="text-lg font-semibold mt-4 mb-2">$1</h5>'),e=e.replace(/^####\s+(.+)$/gm,'<h4 class="text-xl font-semibold mt-5 mb-2">$1</h4>'),e=e.replace(/^###\s+(.+)$/gm,'<h3 class="text-2xl font-semibold mt-5 mb-3">$1</h3>'),e=e.replace(/^##\s+(.+)$/gm,'<h2 class="text-2xl font-bold mt-6 mb-3">$1</h2>'),e=e.replace(/^#\s+(.+)$/gm,'<h1 class="text-3xl font-bold mt-6 mb-4">$1</h1>'),e=e.replace(/^---+$/gm,'<hr class="my-6 border-gray-300 dark:border-gray-600" />'),e=e.replace(/^>\s+(.+)$/gm,'<blockquote class="border-l-4 border-gray-300 dark:border-gray-600 pl-4 my-4 italic text-gray-600 dark:text-gray-400">$1</blockquote>'),e=e.replace(/\*\*(.+?)\*\*/g,"<strong>$1</strong>"),e=e.replace(/\*(.+?)\*/g,"<em>$1</em>"),e=e.replace(/~~(.+?)~~/g,'<del class="text-gray-500">$1</del>'),e=e.replace(/\[([^\]]+)\]\(([^)]+)\)/g,'<a href="$2" class="text-cyan-600 hover:text-cyan-700 dark:text-cyan-400 dark:hover:text-cyan-300 underline" target="_blank" rel="noopener noreferrer">$1</a>'),e=e.replace(/^[-*]\s+(.+)$/gm,'<li class="ml-4">$1</li>'),e=e.replace(/(<li[^>]*>.*<\/li>\n?)+/g,t=>`<ul class="list-disc list-inside my-4 space-y-1">${t}</ul>`),e=e.replace(/\n(?!<)/g,`<br />
7
+ `),e=e.replace(/(<br \/>[\n\s]*){3,}/g,`<br /><br />
8
+ `),e}function $t(r){return r?r.replace(/```[\s\S]*?```/g,"").replace(/`[^`]+`/g,"").replace(/^#{1,6}\s+/gm,"").replace(/\*\*(.+?)\*\*/g,"$1").replace(/\*(.+?)\*/g,"$1").replace(/~~(.+?)~~/g,"$1").replace(/\[([^\]]+)\]\([^)]+\)/g,"$1").replace(/^[-*]\s+/gm,"").replace(/^>\s+/gm,"").replace(/^---+$/gm,"").replace(/\n{3,}/g,`
9
+
10
+ `).trim():""}function Kr(r,e=150){let t=$t(r);return t.length<=e?t:t.slice(0,e).trim()+"..."}function je(r,e,t,n,a){let i=r.slice(e,t),g=r.slice(0,e),v=r.slice(t),u=g+n+i+a+v,s=e+n.length+i.length+a.length;return {text:u,cursorPosition:s}}var Qr=[{icon:"bold",label:"bold",markdown:{before:"**",after:"**"},shortcut:"Ctrl+B"},{icon:"italic",label:"italic",markdown:{before:"*",after:"*"},shortcut:"Ctrl+I"},{icon:"strikethrough",label:"strikethrough",markdown:{before:"~~",after:"~~"}},{icon:"heading",label:"heading",markdown:{before:"## ",after:""}},{icon:"link",label:"link",markdown:{before:"[",after:"](url)"},shortcut:"Ctrl+K"},{icon:"image",label:"image",markdown:{before:"![alt](",after:")"}},{icon:"code",label:"code",markdown:{before:"`",after:"`"}},{icon:"fileCode",label:"codeBlock",markdown:{before:"```\n",after:"\n```"}},{icon:"quote",label:"quote",markdown:{before:"> ",after:""}},{icon:"list",label:"list",markdown:{before:"- ",after:""}},{icon:"listOrdered",label:"orderedList",markdown:{before:"1. ",after:""}},{icon:"minus",label:"horizontalRule",markdown:{before:`
11
+ ---
12
+ `,after:""}}],me=X.forwardRef(({textareaRef:r,className:e},t)=>{let{labels:n,activeLanguage:a$1,updateMultilingualField:i,formData:g,features:v}=H(),u=useCallback(s=>{let h=r.current;if(!h)return;let{selectionStart:p,selectionEnd:f}=h,c=g.content[a$1]||"",{text:l,cursorPosition:o}=je(c,p,f,s.markdown.before,s.markdown.after);i("content",a$1,l),requestAnimationFrame(()=>{h.focus(),h.setSelectionRange(o,o);});},[r,g,a$1,i]);return v.enableMarkdownToolbar?jsx("div",{ref:t,className:a("flex flex-wrap gap-1 px-4 py-2 border-b border-border bg-muted",e),role:"toolbar","aria-label":"\uB9C8\uD06C\uB2E4\uC6B4 \uC11C\uC2DD",children:Qr.map(s=>jsx("button",{type:"button",onClick:()=>u(s),className:"p-2 text-muted-foreground hover:text-foreground hover:bg-muted rounded transition-colors",title:`${n[s.label]||s.label}${s.shortcut?` (${s.shortcut})`:""}`,"aria-label":n[s.label]||s.label,children:jsx(l,{name:s.icon,size:16})},s.icon))}):null});me.displayName="BlogEditorToolbar";var fe=X.forwardRef(({renderMarkdown:r,className:e},t)=>{var p,f;let{formData:n,activeLanguage:a$1,languages:i,labels:g}=H(),v=((p=i.find(c=>c.isPrimary))==null?void 0:p.key)||((f=i[0])==null?void 0:f.key),u=n.title[a$1]||n.title[v]||g.noTitle,s=n.content[a$1]||n.content[v]||"",h=X.useMemo(()=>r?r(s):jsx("div",{dangerouslySetInnerHTML:{__html:Ge(s)}}),[s,r]);return jsxs("div",{ref:t,className:a("p-6",e),children:[jsx("h3",{className:"text-xl font-bold text-foreground mb-4",children:u}),jsx("div",{className:"prose dark:prose-invert max-w-none",children:h})]})});fe.displayName="BlogEditorPreview";var be=X.forwardRef(({cancelLink:r,className:e},t)=>{let{labels:n,submitting:a$1,handleSave:i,handleCancel:g,isEditMode:v,autoSaveStatus:u,features:s}=H();return jsxs("div",{ref:t,className:a("flex items-center justify-end gap-3",e),children:[s.enableAutoSave&&u!=="idle"&&jsxs("span",{className:"text-sm text-muted-foreground flex items-center gap-1",children:[u==="saving"&&jsxs(Fragment,{children:[jsx(l,{name:"loader",size:14,spin:true}),"\uC800\uC7A5 \uC911..."]}),u==="saved"&&jsxs(Fragment,{children:[jsx(l,{name:"check",size:14}),"\uC790\uB3D9\uC800\uC7A5\uB428"]})]}),r||jsx("button",{type:"button",onClick:g,className:"px-4 py-2 text-foreground hover:text-foreground transition-colors",children:n.cancel}),jsx("button",{type:"button",onClick:()=>i(false),disabled:a$1,className:"px-4 py-2 border border-border rounded-lg hover:bg-muted disabled:opacity-50 disabled:cursor-not-allowed transition-colors",children:n.saveDraft}),jsx("button",{type:"button",onClick:()=>i(true),disabled:a$1,className:"px-6 py-2 bg-primary text-white rounded-lg hover:bg-primary/90 disabled:opacity-50 disabled:cursor-not-allowed inline-flex items-center gap-2 transition-colors",children:a$1?jsxs(Fragment,{children:[jsx(l,{name:"loader",size:16,spin:true}),n.saving]}):jsxs(Fragment,{children:[jsx(l,{name:"check",size:16}),v?n.update:n.publish]})})]})});be.displayName="BlogEditorActions";var ye=X.forwardRef(({hint:r,className:e},t)=>{var l$1,o;let{labels:n,translating:a$1,translateSuccess:i,handleTranslate:g,formData:v,languages:u,features:s}=H();if(!s.enableTranslation)return null;let h=((l$1=u.find(y=>y.isPrimary))==null?void 0:l$1.key)||((o=u[0])==null?void 0:o.key),p=v.title[h]||"",f=v.content[h]||"",c=p&&f;return jsxs("div",{ref:t,className:a("px-6 py-3 bg-muted border-b border-border flex items-center justify-between",e),children:[jsxs("div",{className:"flex items-center gap-2 text-sm text-muted-foreground",children:[jsx(l,{name:"sparkles",size:16}),jsx("span",{children:r||n.translateHint})]}),jsx("button",{type:"button",onClick:g,disabled:a$1||!c,className:a("inline-flex items-center gap-2 px-4 py-2 text-sm font-medium rounded-lg transition-colors",i?"bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400":"bg-primary text-white hover:bg-primary/90 disabled:opacity-50 disabled:cursor-not-allowed"),children:a$1?jsxs(Fragment,{children:[jsx(l,{name:"loader",size:16,spin:true}),n.translating]}):i?jsxs(Fragment,{children:[jsx(l,{name:"check",size:16}),n.translateSuccess]}):jsxs(Fragment,{children:[jsx(l,{name:"sparkles",size:16}),n.translateButton]})})]})});ye.displayName="BlogEditorTranslate";function ao({onBack:r,backLink:e,cancelLink:t,renderMarkdown:n,translateHint:a$1,maxWidth:i="max-w-4xl",className:g,children:v}){let{showPreview:u,error:s,variant:h,features:p}=H(),f=useRef(null),c=a(h==="glass"?"bg-gradient-to-br from-gray-100 to-gray-200 dark:from-gray-900 dark:to-gray-800":h==="minimal"?"":"bg-muted"),l=a("rounded-xl overflow-hidden",h==="glass"?"bg-white/10 backdrop-blur-sm border border-white/20 dark:bg-slate-800/20 dark:border-slate-700/50":h==="minimal"?"bg-transparent border border-border":"bg-background");return v?jsx("div",{className:a(c,g),children:jsx("div",{className:a(i,"mx-auto px-4 py-8"),children:v})}):jsx("div",{className:a(c,g),children:jsxs("div",{className:a(i,"mx-auto px-4 py-8"),children:[jsx(le,{onBack:r,backLink:e}),s&&jsx("div",{className:"mb-6 p-4 bg-red-50 dark:bg-red-900/30 border border-red-200 dark:border-red-800 rounded-lg text-red-600 dark:text-red-400",children:s}),jsxs("div",{className:"space-y-6",children:[jsx(ce,{}),jsxs("div",{className:l,children:[p.enableTranslation&&jsx(ye,{hint:a$1}),jsx(de,{}),u?jsx(fe,{renderMarkdown:n}):jsxs(Fragment,{children:[p.enableMarkdownToolbar&&jsx(me,{textareaRef:f}),jsx(pe,{textareaRef:f})]})]}),jsx(be,{cancelLink:t})]})]})})}var Ft=X.forwardRef(({initialData:r,isEditMode:e,languages:t,defaultLanguage:n,labels:a,callbacks:i,features:g,variant:v,onBack:u,backLink:s,cancelLink:h,renderMarkdown:p,translateHint:f,maxWidth:c,className:l,children:o,autoSaveKey:y,autoSaveInterval:T},w)=>jsx(_e,{initialData:r,isEditMode:e,languages:t,defaultLanguage:n,labels:a,callbacks:i,features:g,variant:v,autoSaveKey:y,autoSaveInterval:T,children:jsx("div",{ref:w,children:jsx(ao,{onBack:u,backLink:s,cancelLink:h,renderMarkdown:p,translateHint:f,maxWidth:c,className:l,children:o})})}));Ft.displayName="BlogEditor";var U=Ft;U.Header=le;U.Metadata=ce;U.LanguageTabs=de;U.Content=pe;U.Toolbar=me;U.Preview=fe;U.Actions=be;U.Translate=ye;export{Ge as A,$t as B,Kr as C,je as D,me as E,fe as F,be as G,ye as H,U as I,G as a,Dt as b,Vt as c,qt as d,Ot as e,_t as f,Ut as g,Yt as h,jt as i,Jt as j,yt as k,Tt as l,xt as m,wt as n,Rt as o,Mt as p,Lt as q,De as r,$r as s,Ve as t,H as u,_e as v,le as w,ce as x,de as y,pe as z};//# sourceMappingURL=chunk-CNW22G24.mjs.map
13
+ //# sourceMappingURL=chunk-CNW22G24.mjs.map