@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.
- package/README.md +1 -1
- package/dist/{ComponentLayout-DrZpz0yv.d.mts → ComponentLayout-BhM4VSoq.d.mts} +1 -1
- package/dist/advanced-dashboard.d.mts +1 -1
- package/dist/advanced-dashboard.mjs +3 -3
- package/dist/advanced-dashboard.mjs.map +1 -1
- package/dist/advanced-emotion.mjs +1 -1
- package/dist/advanced-motion.d.mts +9 -6
- package/dist/advanced-motion.mjs +1 -1
- package/dist/advanced.d.mts +3 -3
- package/dist/advanced.mjs +2 -2
- package/dist/advanced.mjs.map +1 -1
- package/dist/chunk-5DPW7SVD.mjs +4 -0
- package/dist/{chunk-AOSXB5JJ.mjs.map → chunk-5DPW7SVD.mjs.map} +1 -1
- package/dist/chunk-5L5HIPKA.mjs +3 -0
- package/dist/{chunk-3GAUTZXQ.mjs.map → chunk-5L5HIPKA.mjs.map} +1 -1
- package/dist/chunk-A5YOVVM5.mjs +3 -0
- package/dist/chunk-A5YOVVM5.mjs.map +1 -0
- package/dist/chunk-CNW22G24.mjs +13 -0
- package/dist/chunk-CNW22G24.mjs.map +1 -0
- package/dist/chunk-CW66UBQG.mjs +3 -0
- package/dist/{chunk-6HVJFEDA.mjs.map → chunk-CW66UBQG.mjs.map} +1 -1
- package/dist/chunk-EAZEI74V.mjs +3 -0
- package/dist/chunk-EAZEI74V.mjs.map +1 -0
- package/dist/chunk-EPY3432E.mjs +3 -0
- package/dist/{chunk-MDLCJASB.mjs.map → chunk-EPY3432E.mjs.map} +1 -1
- package/dist/chunk-F2M4YDDQ.mjs +3 -0
- package/dist/{chunk-OZNST3EZ.mjs.map → chunk-F2M4YDDQ.mjs.map} +1 -1
- package/dist/chunk-FHMFDCX2.mjs +3 -0
- package/dist/{chunk-4NJE7D6X.mjs.map → chunk-FHMFDCX2.mjs.map} +1 -1
- package/dist/chunk-HBIUCLFL.mjs +3 -0
- package/dist/chunk-HBIUCLFL.mjs.map +1 -0
- package/dist/chunk-HEBXAFRY.mjs +3 -0
- package/dist/{chunk-KJZGOL2Z.mjs.map → chunk-HEBXAFRY.mjs.map} +1 -1
- package/dist/chunk-IG47LMOD.mjs +3 -0
- package/dist/{chunk-42RGFEL2.mjs.map → chunk-IG47LMOD.mjs.map} +1 -1
- package/dist/chunk-J47ZEXEL.mjs +3 -0
- package/dist/{chunk-3CCF7U3P.mjs.map → chunk-J47ZEXEL.mjs.map} +1 -1
- package/dist/chunk-K2FOFIST.mjs +3 -0
- package/dist/{chunk-IJSYSNM5.mjs.map → chunk-K2FOFIST.mjs.map} +1 -1
- package/dist/chunk-LL6QPRD7.mjs +3 -0
- package/dist/{chunk-TZ4YSHMC.mjs.map → chunk-LL6QPRD7.mjs.map} +1 -1
- package/dist/chunk-NMJLOK6M.mjs +3 -0
- package/dist/{chunk-KYRIUUQP.mjs.map → chunk-NMJLOK6M.mjs.map} +1 -1
- package/dist/chunk-O24K56OS.mjs +3 -0
- package/dist/chunk-O24K56OS.mjs.map +1 -0
- package/dist/chunk-OIWG3IJ7.mjs +3 -0
- package/dist/chunk-OIWG3IJ7.mjs.map +1 -0
- package/dist/chunk-OLLU7ZFH.mjs +3 -0
- package/dist/{chunk-XL4KTJ4L.mjs.map → chunk-OLLU7ZFH.mjs.map} +1 -1
- package/dist/chunk-Q76JW7X5.mjs +73 -0
- package/dist/chunk-Q76JW7X5.mjs.map +1 -0
- package/dist/chunk-QEMPERUK.mjs +3 -0
- package/dist/chunk-QEMPERUK.mjs.map +1 -0
- package/dist/chunk-QRM66RQG.mjs +3 -0
- package/dist/{chunk-N56BUOCD.mjs.map → chunk-QRM66RQG.mjs.map} +1 -1
- package/dist/chunk-QRRP7TGF.mjs +13 -0
- package/dist/{chunk-RS6RKW5U.mjs.map → chunk-QRRP7TGF.mjs.map} +1 -1
- package/dist/chunk-SD6XGDAC.mjs +3 -0
- package/dist/chunk-SD6XGDAC.mjs.map +1 -0
- package/dist/chunk-SDFVGFXT.mjs +3 -0
- package/dist/{chunk-CVWWS25A.mjs.map → chunk-SDFVGFXT.mjs.map} +1 -1
- package/dist/chunk-SMLDNOV3.mjs +8 -0
- package/dist/{chunk-ZXZIHU7J.mjs.map → chunk-SMLDNOV3.mjs.map} +1 -1
- package/dist/{chunk-FX57OSYG.mjs → chunk-TAP6MYDW.mjs} +2 -2
- package/dist/{chunk-FX57OSYG.mjs.map → chunk-TAP6MYDW.mjs.map} +1 -1
- package/dist/{chunk-WP7VFE77.mjs → chunk-TBZ645BI.mjs} +2 -2
- package/dist/{chunk-WP7VFE77.mjs.map → chunk-TBZ645BI.mjs.map} +1 -1
- package/dist/{chunk-TXBZZJNR.mjs → chunk-V2DNYJR6.mjs} +2 -2
- package/dist/{chunk-TXBZZJNR.mjs.map → chunk-V2DNYJR6.mjs.map} +1 -1
- package/dist/{chunk-Z74YUUVT.mjs → chunk-VBABZXL7.mjs} +2 -2
- package/dist/{chunk-Z74YUUVT.mjs.map → chunk-VBABZXL7.mjs.map} +1 -1
- package/dist/chunk-WYBSHTGY.mjs +3 -0
- package/dist/{chunk-DYNBM24D.mjs.map → chunk-WYBSHTGY.mjs.map} +1 -1
- package/dist/chunk-ZQUMJQYV.mjs +3 -0
- package/dist/chunk-ZQUMJQYV.mjs.map +1 -0
- package/dist/chunk-ZY23NOT4.mjs +3 -0
- package/dist/chunk-ZY23NOT4.mjs.map +1 -0
- package/dist/components/Action.d.ts.map +1 -1
- package/dist/components/Badge.d.ts +1 -1
- package/dist/components/Button.d.ts.map +1 -1
- package/dist/components/DatePicker.d.ts.map +1 -1
- package/dist/components/Dropdown.d.ts +0 -50
- package/dist/components/Dropdown.d.ts.map +1 -1
- package/dist/components/Icon/Icon.d.ts.map +1 -1
- package/dist/components/Modal.d.ts.map +1 -1
- package/dist/components/Popover.d.ts.map +1 -1
- package/dist/components/Progress.d.ts +2 -2
- package/dist/components/advanced/AnimatedGradient.d.ts.map +1 -1
- package/dist/components/advanced/Carousel.d.ts.map +1 -1
- package/dist/components/advanced/ImageReveal.d.ts.map +1 -1
- package/dist/components/advanced/Parallax.d.ts +9 -6
- package/dist/components/advanced/Parallax.d.ts.map +1 -1
- package/dist/components/advanced/TextReveal.d.ts.map +1 -1
- package/dist/data.mjs +2 -2
- package/dist/data.mjs.map +1 -1
- package/dist/feedback.mjs +1 -1
- package/dist/form.mjs +4 -4
- package/dist/form.mjs.map +1 -1
- package/dist/{icons-DmhQEH_E.d.mts → icons-DcOBy9Hf.d.mts} +4 -0
- package/dist/iconsax-extended.mjs +2 -2
- package/dist/iconsax-extended.mjs.map +1 -1
- package/dist/index.d.mts +6 -87
- package/dist/index.mjs +14 -14
- package/dist/index.mjs.map +1 -1
- package/dist/interactive.mjs +1 -1
- package/dist/interactive.mjs.map +1 -1
- package/dist/landing.mjs +7 -7
- package/dist/landing.mjs.map +1 -1
- package/dist/lib/icon-providers.d.ts +9 -25
- package/dist/lib/icon-providers.d.ts.map +1 -1
- package/dist/lib/icons.d.ts +4 -0
- package/dist/lib/icons.d.ts.map +1 -1
- package/dist/lib/utils.d.ts.map +1 -1
- package/dist/navigation.d.mts +1 -1
- package/dist/navigation.mjs +1 -1
- package/dist/navigation.mjs.map +1 -1
- package/dist/overlay.d.mts +0 -50
- package/dist/overlay.mjs +1 -1
- package/dist/overlay.mjs.map +1 -1
- package/dist/sdui.mjs +1 -1
- package/dist/sdui.mjs.map +1 -1
- package/dist/theme.d.mts +85 -0
- package/dist/theme.d.ts +14 -0
- package/dist/theme.d.ts.map +1 -0
- package/dist/theme.mjs +3 -0
- package/dist/theme.mjs.map +1 -0
- package/package.json +18 -14
- package/dist/advanced-dashboard.js +0 -39
- package/dist/advanced-dashboard.js.map +0 -1
- package/dist/advanced-emotion.js +0 -2
- package/dist/advanced-emotion.js.map +0 -1
- package/dist/advanced-motion.js +0 -82
- package/dist/advanced-motion.js.map +0 -1
- package/dist/advanced.js +0 -112
- package/dist/advanced.js.map +0 -1
- package/dist/chunk-3CCF7U3P.mjs +0 -3
- package/dist/chunk-3GAUTZXQ.mjs +0 -3
- package/dist/chunk-42RGFEL2.mjs +0 -3
- package/dist/chunk-4NJE7D6X.mjs +0 -3
- package/dist/chunk-6HVJFEDA.mjs +0 -3
- package/dist/chunk-7OYT3QSY.mjs +0 -3
- package/dist/chunk-7OYT3QSY.mjs.map +0 -1
- package/dist/chunk-ANYZ56VB.mjs +0 -3
- package/dist/chunk-ANYZ56VB.mjs.map +0 -1
- package/dist/chunk-AOSXB5JJ.mjs +0 -4
- package/dist/chunk-B544MRF7.mjs +0 -3
- package/dist/chunk-B544MRF7.mjs.map +0 -1
- package/dist/chunk-CVWWS25A.mjs +0 -3
- package/dist/chunk-DYNBM24D.mjs +0 -3
- package/dist/chunk-IJSYSNM5.mjs +0 -3
- package/dist/chunk-KJZGOL2Z.mjs +0 -3
- package/dist/chunk-KYRIUUQP.mjs +0 -3
- package/dist/chunk-LSA7DU3N.mjs +0 -73
- package/dist/chunk-LSA7DU3N.mjs.map +0 -1
- package/dist/chunk-MDLCJASB.mjs +0 -3
- package/dist/chunk-N56BUOCD.mjs +0 -3
- package/dist/chunk-OFYITQXI.mjs +0 -13
- package/dist/chunk-OFYITQXI.mjs.map +0 -1
- package/dist/chunk-OZNST3EZ.mjs +0 -3
- package/dist/chunk-RS6RKW5U.mjs +0 -13
- package/dist/chunk-TZ4YSHMC.mjs +0 -3
- package/dist/chunk-U6CTBZ2U.mjs +0 -3
- package/dist/chunk-U6CTBZ2U.mjs.map +0 -1
- package/dist/chunk-XCZMLKPK.mjs +0 -3
- package/dist/chunk-XCZMLKPK.mjs.map +0 -1
- package/dist/chunk-XGHT7WMO.mjs +0 -3
- package/dist/chunk-XGHT7WMO.mjs.map +0 -1
- package/dist/chunk-XL4KTJ4L.mjs +0 -3
- package/dist/chunk-ZXZIHU7J.mjs +0 -8
- package/dist/data.js +0 -3
- package/dist/data.js.map +0 -1
- package/dist/feedback.js +0 -12
- package/dist/feedback.js.map +0 -1
- package/dist/form.js +0 -8
- package/dist/form.js.map +0 -1
- package/dist/iconsax-extended.js +0 -3
- package/dist/iconsax-extended.js.map +0 -1
- package/dist/iconsax.js +0 -3
- package/dist/iconsax.js.map +0 -1
- package/dist/index.js +0 -51
- package/dist/index.js.map +0 -1
- package/dist/interactive.js +0 -2
- package/dist/interactive.js.map +0 -1
- package/dist/landing.js +0 -100
- package/dist/landing.js.map +0 -1
- package/dist/lib/phosphor-icons.d.ts +0 -6
- package/dist/lib/phosphor-icons.d.ts.map +0 -1
- package/dist/navigation.js +0 -12
- package/dist/navigation.js.map +0 -1
- package/dist/overlay.js +0 -3
- package/dist/overlay.js.map +0 -1
- package/dist/sdui.js +0 -9
- package/dist/sdui.js.map +0 -1
package/dist/interactive.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
export{a as Accordion,d as AccordionContent,b as AccordionItem,c as AccordionTrigger,f as Tabs,k as TabsCards,e as TabsContent,g as TabsList,i as TabsPills,h as TabsTrigger,j as TabsUnderline}from'./chunk-N56BUOCD.mjs';import'./chunk-7OYT3QSY.mjs';import {b}from'./chunk-U6CTBZ2U.mjs';import l from'react';import {jsx,jsxs}from'react/jsx-runtime';var z=l.forwardRef(({className:n,children:e,variant:t="default",size:o="md",...m},d)=>{let c=()=>{switch(t){case "horizontal":return "flex items-center space-x-1";case "vertical":return "flex flex-col space-y-1";case "compact":return "flex flex-col space-y-0.5";default:return "flex flex-col space-y-1"}},p=()=>{switch(o){case "sm":return "text-sm";case "lg":return "text-base";default:return "text-sm"}};return jsx("div",{ref:d,className:b(c(),p(),n),...m,children:l.Children.map(e,f=>l.isValidElement(f)?l.cloneElement(f,{variant:t,size:o}):f)})});z.displayName="Menu";var K=l.forwardRef(({className:n,icon:e,variant:t="default",size:o="md",active:m=false,disabled:d=false,children:c,...p},f)=>{let S=()=>{switch(t){case "horizontal":return b("flex items-center gap-2 px-3 py-2 rounded-md text-sm font-medium transition-colors",m?"bg-primary/10 text-primary":"text-foreground hover:text-foreground hover:bg-muted");case "vertical":return b("flex items-center gap-3 px-4 py-3 rounded-md text-sm font-medium transition-colors",m?"bg-primary/10 text-primary":"text-foreground hover:text-foreground hover:bg-muted");case "compact":return b("flex items-center gap-2 px-2 py-1.5 rounded text-sm font-medium transition-colors",m?"bg-primary/10 text-primary":"text-foreground hover:text-foreground hover:bg-muted");default:return b("flex items-center gap-3 px-4 py-3 rounded-md text-sm font-medium transition-colors",m?"bg-primary/10 text-primary":"text-foreground hover:text-foreground hover:bg-muted")}},k=()=>{switch(o){case "sm":return "text-xs";case "lg":return "text-base";default:return "text-sm"}};return jsxs("button",{ref:f,className:b(S(),k(),d&&"opacity-50 cursor-not-allowed",n),disabled:d,...p,children:[e&&jsx("div",{className:"flex-shrink-0 w-4 h-4",children:e}),jsx("span",{className:"flex-1 text-left",children:c})]})});K.displayName="MenuItem";var _=l.forwardRef(({className:n,variant:e="default",...t},o)=>jsx("div",{ref:o,className:b(e==="horizontal"?"w-px h-4 bg-border mx-1":"h-px bg-border my-2",n),...t}));_.displayName="MenuSeparator";var q=l.forwardRef(({className:n,variant:e="default",size:t="md",children:o,...m},d)=>{let c=()=>e==="horizontal"?"px-3 py-1 text-xs font-semibold text-muted-foreground uppercase tracking-wide":"px-4 py-2 text-xs font-semibold text-muted-foreground uppercase tracking-wide",p=()=>{switch(t){case "sm":return "text-xs";case "lg":return "text-sm";default:return "text-xs"}};return jsx("div",{ref:d,className:b(c(),p(),n),...m,children:o})});q.displayName="MenuLabel";var U=l.forwardRef(({className:n,...e},t)=>jsx(z,{ref:t,variant:"horizontal",className:n,...e}));U.displayName="MenuHorizontal";var W=l.forwardRef(({className:n,...e},t)=>jsx(z,{ref:t,variant:"vertical",className:n,...e}));W.displayName="MenuVertical";var F=l.forwardRef(({className:n,...e},t)=>jsx(z,{ref:t,variant:"compact",className:n,...e}));F.displayName="MenuCompact";var X=l.forwardRef(({className:n,children:e,open:t,onOpenChange:o,trigger:m,placement:d="bottom",align:c="start",offset:p=8,disabled:f=false,...S},k)=>{let[V,B]=l.useState(false),[M,R]=l.useState({x:0,y:0}),g=l.useRef(null),T=l.useRef(null),H=t!==void 0,b$1=H?t:V,y=l.useCallback(i=>{f||(H||B(i),o==null||o(i));},[f,H,o]),C=i=>{if(i.preventDefault(),f)return;i.currentTarget.getBoundingClientRect();let D=i.clientX,r=i.clientY;R({x:D,y:r}),y(true);},L=l.useCallback(()=>{if(!T.current)return;let i=T.current.getBoundingClientRect(),w=window.innerWidth,D=window.innerHeight,r=M.x,s=M.y;r+i.width>w-8&&(r=w-i.width-8),s+i.height>D-8&&(s=D-i.height-8),r<8&&(r=8),s<8&&(s=8),R({x:r,y:s});},[M.x,M.y]);return l.useEffect(()=>{if(b$1)return L(),window.addEventListener("resize",L),window.addEventListener("scroll",L),()=>{window.removeEventListener("resize",L),window.removeEventListener("scroll",L);}},[b$1,L]),l.useEffect(()=>{let i=w=>{g.current&&T.current&&!g.current.contains(w.target)&&!T.current.contains(w.target)&&y(false);};if(b$1)return document.addEventListener("mousedown",i),()=>{document.removeEventListener("mousedown",i);}},[b$1,y]),jsxs("div",{ref:k,className:b("relative",n),...S,children:[m&&jsx("div",{ref:g,onContextMenu:C,className:"inline-block",children:m}),b$1&&jsx("div",{ref:T,className:b("fixed z-50 bg-popover text-popover-foreground rounded-lg shadow-xl backdrop-blur-sm","min-w-[200px] py-2","border-0"),style:{left:M.x,top:M.y,boxShadow:"0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)"},children:e})]})});X.displayName="ContextMenu";var Y=l.forwardRef(({className:n,icon:e,variant:t="default",children:o,disabled:m,...d},c)=>jsxs("button",{ref:c,className:b("w-full flex items-center gap-3 px-4 py-3 text-sm font-medium transition-colors duration-200 ease-in-out focus-visible:outline-none focus-visible:bg-muted",(()=>{switch(t){case "destructive":return "text-destructive hover:bg-destructive/10";case "disabled":return "text-muted-foreground cursor-not-allowed";default:return "text-foreground hover:bg-muted"}})(),n),disabled:m||t==="disabled",...d,children:[e&&jsx("div",{className:"flex-shrink-0 w-4 h-4",children:e}),jsx("span",{className:"flex-1 text-left",children:o})]}));Y.displayName="ContextMenuItem";var $=l.forwardRef(({className:n,...e},t)=>jsx("div",{ref:t,className:b("h-px bg-border my-2",n),...e}));$.displayName="ContextMenuSeparator";var J=l.forwardRef(({className:n,children:e,...t},o)=>jsx("div",{ref:o,className:b("px-4 py-2 text-xs font-semibold text-muted-foreground uppercase tracking-wide",n),...t,children:e}));J.displayName="ContextMenuLabel";var O=l.forwardRef(({className:n,children:e,...t},o)=>jsx("div",{ref:o,className:b("py-1",n),...t,children:e}));O.displayName="ContextMenuGroup";var G=l.forwardRef(({className:n,children:e,open:t,onOpenChange:o,placeholder:m="\uBA85\uB839\uC5B4\uB97C \uAC80\uC0C9\uD558\uC138\uC694...",searchValue:d,onSearchChange:c,disabled:p=false,...f},S)=>{let[k,V]=l.useState(false),[B,M]=l.useState(""),[R,g]=l.useState(0),T=l.useRef(null),H=l.useRef(null),b$1=l.useRef(null),y=t!==void 0,C=y?t:k,L=d!==void 0?d:B,i=l.useCallback(r=>{p||(y||V(r),o==null||o(r));},[p,y,o]),w=r=>{y||M(r),c==null||c(r),g(0);},D=r=>{var A;if(p)return;let s=(A=b$1.current)==null?void 0:A.querySelectorAll("[data-command-item]"),P=(s==null?void 0:s.length)||0;switch(r.key){case "ArrowDown":r.preventDefault(),g(N=>(N+1)%P);break;case "ArrowUp":r.preventDefault(),g(N=>(N-1+P)%P);break;case "Enter":{r.preventDefault();let N=s==null?void 0:s[R];N==null||N.click();break}case "Escape":r.preventDefault(),i(false);break}};return l.useEffect(()=>{var r;C&&((r=H.current)==null||r.focus(),g(0));},[C]),l.useEffect(()=>{let r=s=>{s.key==="k"&&(s.metaKey||s.ctrlKey)&&(s.preventDefault(),i(!C)),s.key==="Escape"&&C&&(s.preventDefault(),i(false));};return document.addEventListener("keydown",r),()=>{document.removeEventListener("keydown",r);}},[C,i]),l.useEffect(()=>{var s;let r=(s=b$1.current)==null?void 0:s.querySelector(`[data-command-item]:nth-child(${R+1})`);r==null||r.scrollIntoView({block:"nearest"});},[R]),jsx("div",{ref:S,className:b("relative",n),...f,children:C&&jsx("div",{ref:T,className:b("fixed inset-0 z-50 bg-black/50 backdrop-blur-sm","flex items-start justify-center pt-16"),onClick:()=>i(false),children:jsxs("div",{className:b("w-full max-w-2xl mx-4 bg-popover text-popover-foreground rounded-lg shadow-2xl","border-0 overflow-hidden"),onClick:r=>r.stopPropagation(),style:{boxShadow:"0 25px 50px -12px rgba(0, 0, 0, 0.25)"},children:[jsxs("div",{className:"p-4 border-b border-border",children:[" ",jsx("input",{ref:H,type:"text",placeholder:m,value:L,onChange:r=>w(r.target.value),onKeyDown:D,className:b("w-full bg-transparent text-lg font-medium outline-none","placeholder:text-muted-foreground","text-foreground")})]}),jsx("div",{ref:b$1,className:"max-h-96 overflow-y-auto py-2",children:l.Children.map(e,(r,s)=>l.isValidElement(r)?r.type===l.Fragment||typeof r.type=="symbol"?r:l.cloneElement(r,{selected:s===R,onSelect:()=>{var P,A;(A=(P=r.props).onSelect)==null||A.call(P),i(false);}}):r)})]})})})});G.displayName="Command";var Z=l.forwardRef(({className:n,...e},t)=>jsx("input",{ref:t,className:b("flex h-10 w-full rounded-md bg-transparent px-3 py-2 text-sm outline-none","placeholder:text-muted-foreground","disabled:cursor-not-allowed disabled:opacity-50",n),...e}));Z.displayName="CommandInput";var j=l.forwardRef(({className:n,...e},t)=>jsx("div",{ref:t,className:b("max-h-96 overflow-y-auto py-2",n),...e}));j.displayName="CommandList";var ee=l.forwardRef(({className:n,icon:e,selected:t=false,onSelect:o,children:m,...d},c)=>jsxs("button",{ref:c,"data-command-item":true,className:b("relative flex w-full items-center gap-3 rounded-sm px-4 py-3 text-sm","text-foreground","hover:bg-muted","focus:bg-muted","focus:outline-none",t&&"bg-muted","transition-colors",n),onClick:o,...d,children:[e&&jsx("div",{className:"flex-shrink-0 w-4 h-4 text-muted-foreground",children:e}),jsx("span",{className:"flex-1 text-left",children:m})]}));ee.displayName="CommandItem";var te=l.forwardRef(({className:n,heading:e,children:t,...o},m)=>jsxs("div",{ref:m,className:b("py-2",n),...o,children:[" ",e&&jsxs("div",{className:"px-4 py-2 text-xs font-semibold text-muted-foreground uppercase tracking-wide",children:[" ",e]}),jsxs("div",{className:"space-y-1",children:[" ",t]})]}));te.displayName="CommandGroup";var re=l.forwardRef(({className:n,...e},t)=>jsx("div",{ref:t,className:b("h-px bg-border my-2",n),...e}));re.displayName="CommandSeparator";var ne=l.forwardRef(({className:n,children:e="\uACB0\uACFC\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.",...t},o)=>jsx("div",{ref:o,className:b("py-8 text-center text-sm text-muted-foreground",n),...t,children:e}));ne.displayName="CommandEmpty";var oe=l.forwardRef(({className:n,...e},t)=>jsx(G,{ref:t,className:n,...e}));oe.displayName="CommandDialog";export{G as Command,oe as CommandDialog,ne as CommandEmpty,te as CommandGroup,Z as CommandInput,ee as CommandItem,j as CommandList,re as CommandSeparator,X as ContextMenu,O as ContextMenuGroup,Y as ContextMenuItem,J as ContextMenuLabel,$ as ContextMenuSeparator,z as Menu,F as MenuCompact,U as MenuHorizontal,K as MenuItem,q as MenuLabel,_ as MenuSeparator,W as MenuVertical};//# sourceMappingURL=interactive.mjs.map
|
|
2
|
+
export{a as Accordion,d as AccordionContent,b as AccordionItem,c as AccordionTrigger,f as Tabs,k as TabsCards,e as TabsContent,g as TabsList,i as TabsPills,h as TabsTrigger,j as TabsUnderline}from'./chunk-QRM66RQG.mjs';import'./chunk-ZQUMJQYV.mjs';import {a}from'./chunk-QEMPERUK.mjs';import'./chunk-EAZEI74V.mjs';import l from'react';import {jsx,jsxs}from'react/jsx-runtime';var z=l.forwardRef(({className:n,children:e,variant:t="default",size:o="md",...m},d)=>{let c=()=>{switch(t){case "horizontal":return "flex items-center space-x-1";case "vertical":return "flex flex-col space-y-1";case "compact":return "flex flex-col space-y-0.5";default:return "flex flex-col space-y-1"}},p=()=>{switch(o){case "sm":return "text-sm";case "lg":return "text-base";default:return "text-sm"}};return jsx("div",{ref:d,className:a(c(),p(),n),...m,children:l.Children.map(e,f=>l.isValidElement(f)?l.cloneElement(f,{variant:t,size:o}):f)})});z.displayName="Menu";var K=l.forwardRef(({className:n,icon:e,variant:t="default",size:o="md",active:m=false,disabled:d=false,children:c,...p},f)=>{let S=()=>{switch(t){case "horizontal":return a("flex items-center gap-2 px-3 py-2 rounded-md text-sm font-medium transition-colors",m?"bg-primary/10 text-primary":"text-foreground hover:text-foreground hover:bg-muted");case "vertical":return a("flex items-center gap-3 px-4 py-3 rounded-md text-sm font-medium transition-colors",m?"bg-primary/10 text-primary":"text-foreground hover:text-foreground hover:bg-muted");case "compact":return a("flex items-center gap-2 px-2 py-1.5 rounded text-sm font-medium transition-colors",m?"bg-primary/10 text-primary":"text-foreground hover:text-foreground hover:bg-muted");default:return a("flex items-center gap-3 px-4 py-3 rounded-md text-sm font-medium transition-colors",m?"bg-primary/10 text-primary":"text-foreground hover:text-foreground hover:bg-muted")}},k=()=>{switch(o){case "sm":return "text-xs";case "lg":return "text-base";default:return "text-sm"}};return jsxs("button",{ref:f,className:a(S(),k(),d&&"opacity-50 cursor-not-allowed",n),disabled:d,...p,children:[e&&jsx("div",{className:"flex-shrink-0 w-4 h-4",children:e}),jsx("span",{className:"flex-1 text-left",children:c})]})});K.displayName="MenuItem";var _=l.forwardRef(({className:n,variant:e="default",...t},o)=>jsx("div",{ref:o,className:a(e==="horizontal"?"w-px h-4 bg-border mx-1":"h-px bg-border my-2",n),...t}));_.displayName="MenuSeparator";var q=l.forwardRef(({className:n,variant:e="default",size:t="md",children:o,...m},d)=>{let c=()=>e==="horizontal"?"px-3 py-1 text-xs font-semibold text-muted-foreground uppercase tracking-wide":"px-4 py-2 text-xs font-semibold text-muted-foreground uppercase tracking-wide",p=()=>{switch(t){case "sm":return "text-xs";case "lg":return "text-sm";default:return "text-xs"}};return jsx("div",{ref:d,className:a(c(),p(),n),...m,children:o})});q.displayName="MenuLabel";var U=l.forwardRef(({className:n,...e},t)=>jsx(z,{ref:t,variant:"horizontal",className:n,...e}));U.displayName="MenuHorizontal";var W=l.forwardRef(({className:n,...e},t)=>jsx(z,{ref:t,variant:"vertical",className:n,...e}));W.displayName="MenuVertical";var F=l.forwardRef(({className:n,...e},t)=>jsx(z,{ref:t,variant:"compact",className:n,...e}));F.displayName="MenuCompact";var X=l.forwardRef(({className:n,children:e,open:t,onOpenChange:o,trigger:m,placement:d="bottom",align:c="start",offset:p=8,disabled:f=false,...S},k)=>{let[V,B]=l.useState(false),[M,R]=l.useState({x:0,y:0}),g=l.useRef(null),T=l.useRef(null),H=t!==void 0,b=H?t:V,y=l.useCallback(i=>{f||(H||B(i),o==null||o(i));},[f,H,o]),C=i=>{if(i.preventDefault(),f)return;i.currentTarget.getBoundingClientRect();let D=i.clientX,r=i.clientY;R({x:D,y:r}),y(true);},L=l.useCallback(()=>{if(!T.current)return;let i=T.current.getBoundingClientRect(),w=window.innerWidth,D=window.innerHeight,r=M.x,s=M.y;r+i.width>w-8&&(r=w-i.width-8),s+i.height>D-8&&(s=D-i.height-8),r<8&&(r=8),s<8&&(s=8),R({x:r,y:s});},[M.x,M.y]);return l.useEffect(()=>{if(b)return L(),window.addEventListener("resize",L),window.addEventListener("scroll",L),()=>{window.removeEventListener("resize",L),window.removeEventListener("scroll",L);}},[b,L]),l.useEffect(()=>{let i=w=>{g.current&&T.current&&!g.current.contains(w.target)&&!T.current.contains(w.target)&&y(false);};if(b)return document.addEventListener("mousedown",i),()=>{document.removeEventListener("mousedown",i);}},[b,y]),jsxs("div",{ref:k,className:a("relative",n),...S,children:[m&&jsx("div",{ref:g,onContextMenu:C,className:"inline-block",children:m}),b&&jsx("div",{ref:T,className:a("fixed z-50 bg-popover text-popover-foreground rounded-lg shadow-xl backdrop-blur-sm","min-w-[200px] py-2","border-0"),style:{left:M.x,top:M.y,boxShadow:"0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)"},children:e})]})});X.displayName="ContextMenu";var Y=l.forwardRef(({className:n,icon:e,variant:t="default",children:o,disabled:m,...d},c)=>jsxs("button",{ref:c,className:a("w-full flex items-center gap-3 px-4 py-3 text-sm font-medium transition-colors duration-200 ease-in-out focus-visible:outline-none focus-visible:bg-muted",(()=>{switch(t){case "destructive":return "text-destructive hover:bg-destructive/10";case "disabled":return "text-muted-foreground cursor-not-allowed";default:return "text-foreground hover:bg-muted"}})(),n),disabled:m||t==="disabled",...d,children:[e&&jsx("div",{className:"flex-shrink-0 w-4 h-4",children:e}),jsx("span",{className:"flex-1 text-left",children:o})]}));Y.displayName="ContextMenuItem";var $=l.forwardRef(({className:n,...e},t)=>jsx("div",{ref:t,className:a("h-px bg-border my-2",n),...e}));$.displayName="ContextMenuSeparator";var J=l.forwardRef(({className:n,children:e,...t},o)=>jsx("div",{ref:o,className:a("px-4 py-2 text-xs font-semibold text-muted-foreground uppercase tracking-wide",n),...t,children:e}));J.displayName="ContextMenuLabel";var O=l.forwardRef(({className:n,children:e,...t},o)=>jsx("div",{ref:o,className:a("py-1",n),...t,children:e}));O.displayName="ContextMenuGroup";var G=l.forwardRef(({className:n,children:e,open:t,onOpenChange:o,placeholder:m="\uBA85\uB839\uC5B4\uB97C \uAC80\uC0C9\uD558\uC138\uC694...",searchValue:d,onSearchChange:c,disabled:p=false,...f},S)=>{let[k,V]=l.useState(false),[B,M]=l.useState(""),[R,g]=l.useState(0),T=l.useRef(null),H=l.useRef(null),b=l.useRef(null),y=t!==void 0,C=y?t:k,L=d!==void 0?d:B,i=l.useCallback(r=>{p||(y||V(r),o==null||o(r));},[p,y,o]),w=r=>{y||M(r),c==null||c(r),g(0);},D=r=>{var A;if(p)return;let s=(A=b.current)==null?void 0:A.querySelectorAll("[data-command-item]"),P=(s==null?void 0:s.length)||0;switch(r.key){case "ArrowDown":r.preventDefault(),g(N=>(N+1)%P);break;case "ArrowUp":r.preventDefault(),g(N=>(N-1+P)%P);break;case "Enter":{r.preventDefault();let N=s==null?void 0:s[R];N==null||N.click();break}case "Escape":r.preventDefault(),i(false);break}};return l.useEffect(()=>{var r;C&&((r=H.current)==null||r.focus(),g(0));},[C]),l.useEffect(()=>{let r=s=>{s.key==="k"&&(s.metaKey||s.ctrlKey)&&(s.preventDefault(),i(!C)),s.key==="Escape"&&C&&(s.preventDefault(),i(false));};return document.addEventListener("keydown",r),()=>{document.removeEventListener("keydown",r);}},[C,i]),l.useEffect(()=>{var s;let r=(s=b.current)==null?void 0:s.querySelector(`[data-command-item]:nth-child(${R+1})`);r==null||r.scrollIntoView({block:"nearest"});},[R]),jsx("div",{ref:S,className:a("relative",n),...f,children:C&&jsx("div",{ref:T,className:a("fixed inset-0 z-50 bg-black/50 backdrop-blur-sm","flex items-start justify-center pt-16"),onClick:()=>i(false),children:jsxs("div",{className:a("w-full max-w-2xl mx-4 bg-popover text-popover-foreground rounded-lg shadow-2xl","border-0 overflow-hidden"),onClick:r=>r.stopPropagation(),style:{boxShadow:"0 25px 50px -12px rgba(0, 0, 0, 0.25)"},children:[jsxs("div",{className:"p-4 border-b border-border",children:[" ",jsx("input",{ref:H,type:"text",placeholder:m,value:L,onChange:r=>w(r.target.value),onKeyDown:D,className:a("w-full bg-transparent text-lg font-medium outline-none","placeholder:text-muted-foreground","text-foreground")})]}),jsx("div",{ref:b,className:"max-h-96 overflow-y-auto py-2",children:l.Children.map(e,(r,s)=>l.isValidElement(r)?r.type===l.Fragment||typeof r.type=="symbol"?r:l.cloneElement(r,{selected:s===R,onSelect:()=>{var P,A;(A=(P=r.props).onSelect)==null||A.call(P),i(false);}}):r)})]})})})});G.displayName="Command";var Z=l.forwardRef(({className:n,...e},t)=>jsx("input",{ref:t,className:a("flex h-10 w-full rounded-md bg-transparent px-3 py-2 text-sm outline-none","placeholder:text-muted-foreground","disabled:cursor-not-allowed disabled:opacity-50",n),...e}));Z.displayName="CommandInput";var j=l.forwardRef(({className:n,...e},t)=>jsx("div",{ref:t,className:a("max-h-96 overflow-y-auto py-2",n),...e}));j.displayName="CommandList";var ee=l.forwardRef(({className:n,icon:e,selected:t=false,onSelect:o,children:m,...d},c)=>jsxs("button",{ref:c,"data-command-item":true,className:a("relative flex w-full items-center gap-3 rounded-sm px-4 py-3 text-sm","text-foreground","hover:bg-muted","focus:bg-muted","focus:outline-none",t&&"bg-muted","transition-colors",n),onClick:o,...d,children:[e&&jsx("div",{className:"flex-shrink-0 w-4 h-4 text-muted-foreground",children:e}),jsx("span",{className:"flex-1 text-left",children:m})]}));ee.displayName="CommandItem";var te=l.forwardRef(({className:n,heading:e,children:t,...o},m)=>jsxs("div",{ref:m,className:a("py-2",n),...o,children:[" ",e&&jsxs("div",{className:"px-4 py-2 text-xs font-semibold text-muted-foreground uppercase tracking-wide",children:[" ",e]}),jsxs("div",{className:"space-y-1",children:[" ",t]})]}));te.displayName="CommandGroup";var re=l.forwardRef(({className:n,...e},t)=>jsx("div",{ref:t,className:a("h-px bg-border my-2",n),...e}));re.displayName="CommandSeparator";var ne=l.forwardRef(({className:n,children:e="\uACB0\uACFC\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.",...t},o)=>jsx("div",{ref:o,className:a("py-8 text-center text-sm text-muted-foreground",n),...t,children:e}));ne.displayName="CommandEmpty";var oe=l.forwardRef(({className:n,...e},t)=>jsx(G,{ref:t,className:n,...e}));oe.displayName="CommandDialog";export{G as Command,oe as CommandDialog,ne as CommandEmpty,te as CommandGroup,Z as CommandInput,ee as CommandItem,j as CommandList,re as CommandSeparator,X as ContextMenu,O as ContextMenuGroup,Y as ContextMenuItem,J as ContextMenuLabel,$ as ContextMenuSeparator,z as Menu,F as MenuCompact,U as MenuHorizontal,K as MenuItem,q as MenuLabel,_ as MenuSeparator,W as MenuVertical};//# sourceMappingURL=interactive.mjs.map
|
|
3
3
|
//# sourceMappingURL=interactive.mjs.map
|
package/dist/interactive.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/Menu.tsx","../src/components/ContextMenu.tsx","../src/components/Command.tsx"],"names":["Menu","React","className","children","variant","size","props","ref","getVariantClasses","getSizeClasses","jsx","merge","child","MenuItem","icon","active","disabled","jsxs","MenuSeparator","MenuLabel","MenuHorizontal","MenuVertical","MenuCompact","ContextMenu","controlledOpen","onOpenChange","trigger","_placement","_align","_offset","internalOpen","setInternalOpen","coords","setCoords","triggerRef","menuRef","isControlled","isOpen","handleOpenChange","newOpen","handleContextMenu","event","x","y","updatePosition","menuRect","viewportWidth","viewportHeight","handleClickOutside","ContextMenuItem","ContextMenuSeparator","ContextMenuLabel","ContextMenuGroup","Command","placeholder","controlledSearchValue","onSearchChange","internalSearchValue","setInternalSearchValue","selectedIndex","setSelectedIndex","commandRef","inputRef","listRef","searchValue","handleSearchChange","value","handleKeyDown","_a","items","itemCount","prev","selectedItem","e","index","_b","CommandInput","CommandList","CommandItem","selected","onSelect","CommandGroup","heading","CommandSeparator","CommandEmpty","CommandDialog"],"mappings":"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","file":"interactive.mjs","sourcesContent":["\"use client\"\n\nimport React from \"react\"\nimport { merge } from \"../lib/utils\"\n\n/**\n * Menu 컴포넌트의 props / Menu component props\n * @typedef {Object} MenuProps\n * @property {React.ReactNode} children - MenuItem, MenuSeparator, MenuLabel 컴포넌트들 / MenuItem, MenuSeparator, MenuLabel components\n * @property {\"default\" | \"horizontal\" | \"vertical\" | \"compact\"} [variant=\"default\"] - 메뉴 방향 및 스타일 / Menu direction and style\n * @property {\"sm\" | \"md\" | \"lg\"} [size=\"md\"] - 메뉴 아이템 크기 / Menu item size\n * @extends {React.HTMLAttributes<HTMLDivElement>}\n */\nexport interface MenuProps extends React.HTMLAttributes<HTMLDivElement> {\n children: React.ReactNode\n variant?: \"default\" | \"horizontal\" | \"vertical\" | \"compact\"\n size?: \"sm\" | \"md\" | \"lg\"\n}\n\n/**\n * Menu 컴포넌트 / Menu component\n * \n * 메뉴 리스트를 제공하는 컴포넌트입니다.\n * MenuItem, MenuSeparator, MenuLabel과 함께 사용합니다.\n * \n * Component that provides menu lists.\n * Used with MenuItem, MenuSeparator, and MenuLabel.\n * \n * @component\n * @example\n * // 기본 수직 메뉴 / Basic vertical menu\n * <Menu>\n * <MenuItem icon={<Icon name=\"home\" />}>홈</MenuItem>\n * <MenuItem icon={<Icon name=\"settings\" />}>설정</MenuItem>\n * <MenuSeparator />\n * <MenuItem>로그아웃</MenuItem>\n * </Menu>\n * \n * @example\n * // 수평 메뉴 / Horizontal menu\n * <Menu variant=\"horizontal\">\n * <MenuItem>메뉴 1</MenuItem>\n * <MenuItem>메뉴 2</MenuItem>\n * </Menu>\n * \n * @param {MenuProps} props - Menu 컴포넌트의 props / Menu component props\n * @param {React.Ref<HTMLDivElement>} ref - div 요소 ref / div element ref\n * @returns {JSX.Element} Menu 컴포넌트 / Menu component\n */\nconst Menu = React.forwardRef<HTMLDivElement, MenuProps>(\n ({ \n className, \n children,\n variant = \"default\",\n size = \"md\",\n ...props \n }, ref) => {\n const getVariantClasses = () => {\n switch (variant) {\n case \"horizontal\":\n return \"flex items-center space-x-1\" // 4px 간격\n case \"vertical\":\n return \"flex flex-col space-y-1\" // 4px 간격\n case \"compact\":\n return \"flex flex-col space-y-0.5\" // 2px 간격\n default:\n return \"flex flex-col space-y-1\" // 4px 간격\n }\n }\n\n const getSizeClasses = () => {\n switch (size) {\n case \"sm\":\n return \"text-sm\"\n case \"lg\":\n return \"text-base\"\n default:\n return \"text-sm\"\n }\n }\n\n return (\n <div\n ref={ref}\n className={merge(\n getVariantClasses(),\n getSizeClasses(),\n className\n )}\n {...props}\n >\n {React.Children.map(children, (child) => {\n if (React.isValidElement(child)) {\n return React.cloneElement(child, {\n variant,\n size\n } as Partial<MenuItemProps | MenuSeparatorProps | MenuLabelProps>)\n }\n return child\n })}\n </div>\n )\n }\n)\nMenu.displayName = \"Menu\"\n\n/**\n * MenuItem 컴포넌트의 props / MenuItem component props\n * @typedef {Object} MenuItemProps\n * @property {React.ReactNode} [icon] - 메뉴 아이템 아이콘 / Menu item icon\n * @property {\"default\" | \"horizontal\" | \"vertical\" | \"compact\"} [variant] - 메뉴 변형 (Menu에서 자동 전달) / Menu variant (auto-passed from Menu)\n * @property {\"sm\" | \"md\" | \"lg\"} [size] - 메뉴 크기 (Menu에서 자동 전달) / Menu size (auto-passed from Menu)\n * @property {boolean} [active=false] - 활성화 상태 / Active state\n * @property {boolean} [disabled=false] - 비활성화 상태 / Disabled state\n * @extends {React.ButtonHTMLAttributes<HTMLButtonElement>}\n */\nexport interface MenuItemProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n icon?: React.ReactNode\n variant?: \"default\" | \"horizontal\" | \"vertical\" | \"compact\"\n size?: \"sm\" | \"md\" | \"lg\"\n active?: boolean\n disabled?: boolean\n}\n\n/**\n * MenuItem 컴포넌트 / MenuItem component\n * 메뉴의 개별 아이템을 표시합니다.\n * Displays an individual menu item.\n * \n * @component\n * @param {MenuItemProps} props - MenuItem 컴포넌트의 props / MenuItem component props\n * @param {React.Ref<HTMLButtonElement>} ref - button 요소 ref / button element ref\n * @returns {JSX.Element} MenuItem 컴포넌트 / MenuItem component\n */\nconst MenuItem = React.forwardRef<HTMLButtonElement, MenuItemProps>(\n ({ \n className, \n icon,\n variant = \"default\",\n size = \"md\",\n active = false,\n disabled = false,\n children,\n ...props \n }, ref) => {\n const getVariantClasses = () => {\n switch (variant) {\n case \"horizontal\":\n return merge(\n \"flex items-center gap-2 px-3 py-2 rounded-md text-sm font-medium transition-colors\", // 12px, 8px 패딩\n active \n ? \"bg-primary/10 text-primary\"\n : \"text-foreground hover:text-foreground hover:bg-muted\"\n )\n case \"vertical\":\n return merge(\n \"flex items-center gap-3 px-4 py-3 rounded-md text-sm font-medium transition-colors\", // 16px, 12px 패딩\n active\n ? \"bg-primary/10 text-primary\"\n : \"text-foreground hover:text-foreground hover:bg-muted\"\n )\n case \"compact\":\n return merge(\n \"flex items-center gap-2 px-2 py-1.5 rounded text-sm font-medium transition-colors\", // 8px, 6px 패딩\n active\n ? \"bg-primary/10 text-primary\"\n : \"text-foreground hover:text-foreground hover:bg-muted\"\n )\n default:\n return merge(\n \"flex items-center gap-3 px-4 py-3 rounded-md text-sm font-medium transition-colors\", // 16px, 12px 패딩\n active\n ? \"bg-primary/10 text-primary\"\n : \"text-foreground hover:text-foreground hover:bg-muted\"\n )\n }\n }\n\n const getSizeClasses = () => {\n switch (size) {\n case \"sm\":\n return \"text-xs\"\n case \"lg\":\n return \"text-base\"\n default:\n return \"text-sm\"\n }\n }\n\n return (\n <button\n ref={ref}\n className={merge(\n getVariantClasses(),\n getSizeClasses(),\n disabled && \"opacity-50 cursor-not-allowed\",\n className\n )}\n disabled={disabled}\n {...props}\n >\n {icon && (\n <div className=\"flex-shrink-0 w-4 h-4\">\n {icon}\n </div>\n )}\n <span className=\"flex-1 text-left\">{children}</span>\n </button>\n )\n }\n)\nMenuItem.displayName = \"MenuItem\"\n\n/**\n * MenuSeparator 컴포넌트의 props / MenuSeparator component props\n * @typedef {Object} MenuSeparatorProps\n * @property {\"default\" | \"horizontal\" | \"vertical\" | \"compact\"} [variant] - 메뉴 변형 (Menu에서 자동 전달) / Menu variant (auto-passed from Menu)\n * @extends {React.HTMLAttributes<HTMLDivElement>}\n */\nexport interface MenuSeparatorProps extends React.HTMLAttributes<HTMLDivElement> {\n variant?: \"default\" | \"horizontal\" | \"vertical\" | \"compact\"\n}\n\n/**\n * MenuSeparator 컴포넌트 / MenuSeparator component\n * 메뉴 아이템들을 구분하는 구분선을 표시합니다.\n * Displays a separator line between menu items.\n * \n * @component\n * @param {MenuSeparatorProps} props - MenuSeparator 컴포넌트의 props / MenuSeparator component props\n * @param {React.Ref<HTMLDivElement>} ref - div 요소 ref / div element ref\n * @returns {JSX.Element} MenuSeparator 컴포넌트 / MenuSeparator component\n */\nconst MenuSeparator = React.forwardRef<HTMLDivElement, MenuSeparatorProps>(\n ({ className, variant = \"default\", ...props }, ref) => {\n const getVariantClasses = () => {\n switch (variant) {\n case \"horizontal\":\n return \"w-px h-4 bg-border mx-1\" // 4px 여백\n case \"vertical\":\n case \"compact\":\n default:\n return \"h-px bg-border my-2\" // 8px 여백\n }\n }\n\n return (\n <div\n ref={ref}\n className={merge(getVariantClasses(), className)}\n {...props}\n />\n )\n }\n)\nMenuSeparator.displayName = \"MenuSeparator\"\n\n/**\n * MenuLabel 컴포넌트의 props / MenuLabel component props\n * @typedef {Object} MenuLabelProps\n * @property {\"default\" | \"horizontal\" | \"vertical\" | \"compact\"} [variant] - 메뉴 변형 (Menu에서 자동 전달) / Menu variant (auto-passed from Menu)\n * @property {\"sm\" | \"md\" | \"lg\"} [size] - 메뉴 크기 (Menu에서 자동 전달) / Menu size (auto-passed from Menu)\n * @extends {React.HTMLAttributes<HTMLDivElement>}\n */\nexport interface MenuLabelProps extends React.HTMLAttributes<HTMLDivElement> {\n variant?: \"default\" | \"horizontal\" | \"vertical\" | \"compact\"\n size?: \"sm\" | \"md\" | \"lg\"\n}\n\n/**\n * MenuLabel 컴포넌트 / MenuLabel component\n * 메뉴 섹션의 레이블을 표시합니다.\n * Displays a label for a menu section.\n * \n * @component\n * @param {MenuLabelProps} props - MenuLabel 컴포넌트의 props / MenuLabel component props\n * @param {React.Ref<HTMLDivElement>} ref - div 요소 ref / div element ref\n * @returns {JSX.Element} MenuLabel 컴포넌트 / MenuLabel component\n */\nconst MenuLabel = React.forwardRef<HTMLDivElement, MenuLabelProps>(\n ({ className, variant = \"default\", size = \"md\", children, ...props }, ref) => {\n const getVariantClasses = () => {\n switch (variant) {\n case \"horizontal\":\n return \"px-3 py-1 text-xs font-semibold text-muted-foreground uppercase tracking-wide\" // 12px, 4px 패딩\n case \"vertical\":\n case \"compact\":\n default:\n return \"px-4 py-2 text-xs font-semibold text-muted-foreground uppercase tracking-wide\" // 16px, 8px 패딩\n }\n }\n\n const getSizeClasses = () => {\n switch (size) {\n case \"sm\":\n return \"text-xs\"\n case \"lg\":\n return \"text-sm\"\n default:\n return \"text-xs\"\n }\n }\n\n return (\n <div\n ref={ref}\n className={merge(\n getVariantClasses(),\n getSizeClasses(),\n className\n )}\n {...props}\n >\n {children}\n </div>\n )\n }\n)\nMenuLabel.displayName = \"MenuLabel\"\n\n// 편의 컴포넌트들\nexport const MenuHorizontal = React.forwardRef<HTMLDivElement, Omit<MenuProps, \"variant\">>(\n ({ className, ...props }, ref) => (\n <Menu ref={ref} variant=\"horizontal\" className={className} {...props} />\n )\n)\nMenuHorizontal.displayName = \"MenuHorizontal\"\n\nexport const MenuVertical = React.forwardRef<HTMLDivElement, Omit<MenuProps, \"variant\">>(\n ({ className, ...props }, ref) => (\n <Menu ref={ref} variant=\"vertical\" className={className} {...props} />\n )\n)\nMenuVertical.displayName = \"MenuVertical\"\n\nexport const MenuCompact = React.forwardRef<HTMLDivElement, Omit<MenuProps, \"variant\">>(\n ({ className, ...props }, ref) => (\n <Menu ref={ref} variant=\"compact\" className={className} {...props} />\n )\n)\nMenuCompact.displayName = \"MenuCompact\"\n\nexport { Menu, MenuItem, MenuSeparator, MenuLabel } ","\"use client\"\n\nimport React from \"react\"\nimport { merge } from \"../lib/utils\"\n\n/**\n * ContextMenu 컴포넌트의 props / ContextMenu component props\n * @typedef {Object} ContextMenuProps\n * @property {React.ReactNode} children - ContextMenu 내용 / ContextMenu content\n * @property {boolean} [open] - 제어 모드에서 열림/닫힘 상태 / Open/close state in controlled mode\n * @property {(open: boolean) => void} [onOpenChange] - 상태 변경 콜백 / State change callback\n * @property {React.ReactNode} [trigger] - ContextMenu를 열기 위한 트리거 요소 (우클릭 이벤트) / Trigger element to open context menu (right-click event)\n * @property {\"top\" | \"bottom\" | \"left\" | \"right\"} [placement=\"bottom\"] - ContextMenu 표시 위치 / ContextMenu display position\n * @property {\"start\" | \"center\" | \"end\"} [align=\"start\"] - ContextMenu 정렬 / ContextMenu alignment\n * @property {number} [offset=8] - 트리거와 ContextMenu 사이 간격 (px) / Spacing between trigger and context menu (px)\n * @property {boolean} [disabled=false] - ContextMenu 비활성화 여부 / Disable context menu\n * @extends {React.HTMLAttributes<HTMLDivElement>}\n */\nexport interface ContextMenuProps extends React.HTMLAttributes<HTMLDivElement> {\n children: React.ReactNode\n open?: boolean\n onOpenChange?: (open: boolean) => void\n trigger?: React.ReactNode\n placement?: \"top\" | \"bottom\" | \"left\" | \"right\"\n align?: \"start\" | \"center\" | \"end\"\n offset?: number\n disabled?: boolean\n}\n\n/**\n * ContextMenu 컴포넌트 / ContextMenu component\n * \n * 우클릭 시 표시되는 컨텍스트 메뉴 컴포넌트입니다.\n * 트리거 요소에 우클릭 이벤트를 자동으로 연결합니다.\n * \n * Context menu component that appears on right-click.\n * Automatically connects right-click events to the trigger element.\n * \n * @component\n * @example\n * // 기본 사용 / Basic usage\n * <ContextMenu trigger={<div>우클릭하세요</div>}>\n * <div className=\"p-2\">\n * <button>항목 1</button>\n * <button>항목 2</button>\n * </div>\n * </ContextMenu>\n * \n * @example\n * // 제어 모드 / Controlled mode\n * const [open, setOpen] = useState(false)\n * <ContextMenu \n * open={open}\n * onOpenChange={setOpen}\n * trigger={<div>우클릭</div>}\n * >\n * <Menu>\n * <MenuItem>복사</MenuItem>\n * <MenuItem>삭제</MenuItem>\n * </Menu>\n * </ContextMenu>\n * \n * @param {ContextMenuProps} props - ContextMenu 컴포넌트의 props / ContextMenu component props\n * @param {React.Ref<HTMLDivElement>} ref - div 요소 ref / div element ref\n * @returns {JSX.Element} ContextMenu 컴포넌트 / ContextMenu component\n */\nconst ContextMenu = React.forwardRef<HTMLDivElement, ContextMenuProps>(\n ({ \n className, \n children,\n open: controlledOpen,\n onOpenChange,\n trigger,\n placement: _placement = \"bottom\",\n align: _align = \"start\",\n offset: _offset = 8,\n disabled = false,\n ...props \n }, ref) => {\n const [internalOpen, setInternalOpen] = React.useState(false)\n const [coords, setCoords] = React.useState({ x: 0, y: 0 })\n const triggerRef = React.useRef<HTMLDivElement>(null)\n const menuRef = React.useRef<HTMLDivElement>(null)\n const isControlled = controlledOpen !== undefined\n const isOpen = isControlled ? controlledOpen : internalOpen\n\n const handleOpenChange = React.useCallback((newOpen: boolean) => {\n if (disabled) return\n\n if (!isControlled) {\n setInternalOpen(newOpen)\n }\n onOpenChange?.(newOpen)\n }, [disabled, isControlled, onOpenChange])\n\n const handleContextMenu = (event: React.MouseEvent) => {\n event.preventDefault()\n if (disabled) return\n\n const _rect = event.currentTarget.getBoundingClientRect()\n const x = event.clientX\n const y = event.clientY\n\n setCoords({ x, y })\n handleOpenChange(true)\n }\n\n const updatePosition = React.useCallback(() => {\n if (!menuRef.current) return\n\n const menuRect = menuRef.current.getBoundingClientRect()\n const viewportWidth = window.innerWidth\n const viewportHeight = window.innerHeight\n\n let x = coords.x\n let y = coords.y\n\n // 뷰포트 경계 확인 및 조정\n if (x + menuRect.width > viewportWidth - 8) {\n x = viewportWidth - menuRect.width - 8 // 8px 여백\n }\n if (y + menuRect.height > viewportHeight - 8) {\n y = viewportHeight - menuRect.height - 8 // 8px 여백\n }\n if (x < 8) x = 8 // 8px 여백\n if (y < 8) y = 8 // 8px 여백\n\n setCoords({ x, y })\n }, [coords.x, coords.y])\n\n React.useEffect(() => {\n if (isOpen) {\n updatePosition()\n window.addEventListener('resize', updatePosition)\n window.addEventListener('scroll', updatePosition)\n \n return () => {\n window.removeEventListener('resize', updatePosition)\n window.removeEventListener('scroll', updatePosition)\n }\n }\n }, [isOpen, updatePosition])\n\n React.useEffect(() => {\n const handleClickOutside = (event: MouseEvent) => {\n if (\n triggerRef.current &&\n menuRef.current &&\n !triggerRef.current.contains(event.target as Node) &&\n !menuRef.current.contains(event.target as Node)\n ) {\n handleOpenChange(false)\n }\n }\n\n if (isOpen) {\n document.addEventListener('mousedown', handleClickOutside)\n return () => {\n document.removeEventListener('mousedown', handleClickOutside)\n }\n }\n }, [isOpen, handleOpenChange])\n\n return (\n <div ref={ref} className={merge(\"relative\", className)} {...props}>\n {/* 트리거 */}\n {trigger && (\n <div\n ref={triggerRef}\n onContextMenu={handleContextMenu}\n className=\"inline-block\"\n >\n {trigger}\n </div>\n )}\n\n {/* 컨텍스트 메뉴 */}\n {isOpen && (\n <div\n ref={menuRef}\n className={merge(\n \"fixed z-50 bg-popover text-popover-foreground rounded-lg shadow-xl backdrop-blur-sm\", // 보더 대신 섀도우 사용\n \"min-w-[200px] py-2\", // 16px 패딩\n \"border-0\" // 보더 제거\n )}\n style={{\n left: coords.x,\n top: coords.y,\n boxShadow: \"0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)\"\n }}\n >\n {children}\n </div>\n )}\n </div>\n )\n }\n)\nContextMenu.displayName = \"ContextMenu\"\n\nexport interface ContextMenuItemProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n icon?: React.ReactNode\n variant?: \"default\" | \"destructive\" | \"disabled\"\n}\n\nconst ContextMenuItem = React.forwardRef<HTMLButtonElement, ContextMenuItemProps>(\n ({ \n className, \n icon,\n variant = \"default\",\n children,\n disabled,\n ...props \n }, ref) => {\n const getVariantClasses = () => {\n switch (variant) {\n case \"destructive\":\n return \"text-destructive hover:bg-destructive/10\"\n case \"disabled\":\n return \"text-muted-foreground cursor-not-allowed\"\n default:\n return \"text-foreground hover:bg-muted\"\n }\n }\n\n return (\n <button\n ref={ref}\n className={merge(\n \"w-full flex items-center gap-3 px-4 py-3 text-sm font-medium transition-colors duration-200 ease-in-out focus-visible:outline-none focus-visible:bg-muted\", // 16px, 12px 패딩\n getVariantClasses(),\n className\n )}\n disabled={disabled || variant === \"disabled\"}\n {...props}\n >\n {icon && (\n <div className=\"flex-shrink-0 w-4 h-4\">\n {icon}\n </div>\n )}\n <span className=\"flex-1 text-left\">{children}</span>\n </button>\n )\n }\n)\nContextMenuItem.displayName = \"ContextMenuItem\"\n\nexport interface ContextMenuSeparatorProps extends React.HTMLAttributes<HTMLDivElement> {}\n\nconst ContextMenuSeparator = React.forwardRef<HTMLDivElement, ContextMenuSeparatorProps>(\n ({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={merge(\"h-px bg-border my-2\", className)} // 8px 여백\n {...props}\n />\n )\n)\nContextMenuSeparator.displayName = \"ContextMenuSeparator\"\n\nexport interface ContextMenuLabelProps extends React.HTMLAttributes<HTMLDivElement> {}\n\nconst ContextMenuLabel = React.forwardRef<HTMLDivElement, ContextMenuLabelProps>(\n ({ className, children, ...props }, ref) => (\n <div\n ref={ref}\n className={merge(\"px-4 py-2 text-xs font-semibold text-muted-foreground uppercase tracking-wide\", className)} // 16px, 8px 패딩\n {...props}\n >\n {children}\n </div>\n )\n)\nContextMenuLabel.displayName = \"ContextMenuLabel\"\n\n// 편의 컴포넌트들\nconst ContextMenuGroup = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(\n ({ className, children, ...props }, ref) => (\n <div\n ref={ref}\n className={merge(\"py-1\", className)} // 4px 패딩\n {...props}\n >\n {children}\n </div>\n )\n)\nContextMenuGroup.displayName = \"ContextMenuGroup\"\n\nexport { ContextMenu, ContextMenuItem, ContextMenuSeparator, ContextMenuLabel, ContextMenuGroup } ","\"use client\"\n\nimport React from \"react\"\nimport { merge } from \"../lib/utils\"\n\n/**\n * Command 컴포넌트의 props / Command component props\n * @typedef {Object} CommandProps\n * @property {React.ReactNode} children - CommandList, CommandItem 등 / CommandList, CommandItem, etc.\n * @property {boolean} [open] - 제어 모드에서 열림/닫힘 상태 / Open/close state in controlled mode\n * @property {(open: boolean) => void} [onOpenChange] - 상태 변경 콜백 / State change callback\n * @property {string} [placeholder=\"명령어를 검색하세요...\"] - 검색 입력 플레이스홀더 / Search input placeholder\n * @property {string} [searchValue] - 제어 모드에서 검색 값 / Search value in controlled mode\n * @property {(value: string) => void} [onSearchChange] - 검색 값 변경 콜백 / Search value change callback\n * @property {boolean} [disabled=false] - Command 비활성화 여부 / Disable command\n * @extends {React.HTMLAttributes<HTMLDivElement>}\n */\nexport interface CommandProps extends React.HTMLAttributes<HTMLDivElement> {\n children: React.ReactNode\n open?: boolean\n onOpenChange?: (open: boolean) => void\n placeholder?: string\n searchValue?: string\n onSearchChange?: (value: string) => void\n disabled?: boolean\n}\n\n/**\n * Command 컴포넌트 / Command component\n * \n * 명령 팔레트(Command Palette) 컴포넌트입니다.\n * Cmd+K (Mac) 또는 Ctrl+K (Windows)로 열 수 있습니다.\n * 키보드 네비게이션(Arrow keys, Enter, Escape)을 지원합니다.\n * \n * Command Palette component.\n * Can be opened with Cmd+K (Mac) or Ctrl+K (Windows).\n * Supports keyboard navigation (Arrow keys, Enter, Escape).\n * \n * @component\n * @example\n * // 기본 사용 / Basic usage\n * <Command>\n * <CommandInput placeholder=\"검색...\" />\n * <CommandList>\n * <CommandItem>항목 1</CommandItem>\n * <CommandItem>항목 2</CommandItem>\n * </CommandList>\n * </Command>\n * \n * @example\n * // 제어 모드 / Controlled mode\n * const [open, setOpen] = useState(false)\n * <Command \n * open={open}\n * onOpenChange={setOpen}\n * >\n * <CommandList>\n * <CommandGroup heading=\"파일\">\n * <CommandItem>새 파일</CommandItem>\n * </CommandGroup>\n * </CommandList>\n * </Command>\n * \n * @param {CommandProps} props - Command 컴포넌트의 props / Command component props\n * @param {React.Ref<HTMLDivElement>} ref - div 요소 ref / div element ref\n * @returns {JSX.Element} Command 컴포넌트 / Command component\n */\nconst Command = React.forwardRef<HTMLDivElement, CommandProps>(\n ({ \n className, \n children,\n open: controlledOpen,\n onOpenChange,\n placeholder = \"명령어를 검색하세요...\",\n searchValue: controlledSearchValue,\n onSearchChange,\n disabled = false,\n ...props \n }, ref) => {\n const [internalOpen, setInternalOpen] = React.useState(false)\n const [internalSearchValue, setInternalSearchValue] = React.useState(\"\")\n const [selectedIndex, setSelectedIndex] = React.useState(0)\n const commandRef = React.useRef<HTMLDivElement>(null)\n const inputRef = React.useRef<HTMLInputElement>(null)\n const listRef = React.useRef<HTMLDivElement>(null)\n \n const isControlled = controlledOpen !== undefined\n const isOpen = isControlled ? controlledOpen : internalOpen\n const searchValue = controlledSearchValue !== undefined ? controlledSearchValue : internalSearchValue\n\n const handleOpenChange = React.useCallback((newOpen: boolean) => {\n if (disabled) return\n\n if (!isControlled) {\n setInternalOpen(newOpen)\n }\n onOpenChange?.(newOpen)\n }, [disabled, isControlled, onOpenChange])\n\n const handleSearchChange = (value: string) => {\n if (!isControlled) {\n setInternalSearchValue(value)\n }\n onSearchChange?.(value)\n setSelectedIndex(0)\n }\n\n const handleKeyDown = (event: React.KeyboardEvent) => {\n if (disabled) return\n\n const items = listRef.current?.querySelectorAll('[data-command-item]')\n const itemCount = items?.length || 0\n\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault()\n setSelectedIndex((prev) => (prev + 1) % itemCount)\n break\n case 'ArrowUp':\n event.preventDefault()\n setSelectedIndex((prev) => (prev - 1 + itemCount) % itemCount)\n break\n case 'Enter': {\n event.preventDefault()\n const selectedItem = items?.[selectedIndex] as HTMLElement\n selectedItem?.click()\n break\n }\n case 'Escape':\n event.preventDefault()\n handleOpenChange(false)\n break\n }\n }\n\n React.useEffect(() => {\n if (isOpen) {\n inputRef.current?.focus()\n setSelectedIndex(0)\n }\n }, [isOpen])\n\n React.useEffect(() => {\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'k' && (event.metaKey || event.ctrlKey)) {\n event.preventDefault()\n handleOpenChange(!isOpen)\n }\n // 전역 ESC 키 처리\n if (event.key === 'Escape' && isOpen) {\n event.preventDefault()\n handleOpenChange(false)\n }\n }\n\n document.addEventListener('keydown', handleKeyDown)\n return () => {\n document.removeEventListener('keydown', handleKeyDown)\n }\n }, [isOpen, handleOpenChange])\n\n React.useEffect(() => {\n const selectedItem = listRef.current?.querySelector(`[data-command-item]:nth-child(${selectedIndex + 1})`) as HTMLElement\n selectedItem?.scrollIntoView({ block: 'nearest' })\n }, [selectedIndex])\n\n return (\n <div ref={ref} className={merge(\"relative\", className)} {...props}>\n {isOpen && (\n <div\n ref={commandRef}\n className={merge(\n \"fixed inset-0 z-50 bg-black/50 backdrop-blur-sm\", // 50% 투명도\n \"flex items-start justify-center pt-16\" // 64px 상단 여백\n )}\n onClick={() => handleOpenChange(false)}\n >\n <div\n className={merge(\n \"w-full max-w-2xl mx-4 bg-popover text-popover-foreground rounded-lg shadow-2xl\", // 보더 대신 섀도우\n \"border-0 overflow-hidden\" // 보더 제거\n )}\n onClick={(e) => e.stopPropagation()}\n style={{\n boxShadow: \"0 25px 50px -12px rgba(0, 0, 0, 0.25)\"\n }}\n >\n <div className=\"p-4 border-b border-border\"> {/* 16px 패딩 */}\n <input\n ref={inputRef}\n type=\"text\"\n placeholder={placeholder}\n value={searchValue}\n onChange={(e) => handleSearchChange(e.target.value)}\n onKeyDown={handleKeyDown}\n className={merge(\n \"w-full bg-transparent text-lg font-medium outline-none\", // 18px 텍스트\n \"placeholder:text-muted-foreground\",\n \"text-foreground\"\n )}\n />\n </div>\n \n <div\n ref={listRef}\n className=\"max-h-96 overflow-y-auto py-2\" // 384px 최대 높이, 8px 패딩\n >\n {React.Children.map(children, (child, index) => {\n if (React.isValidElement<CommandItemProps>(child)) {\n // Fragment나 다른 컴포넌트에 selected prop 전달 방지\n if (child.type === React.Fragment || typeof child.type === 'symbol') {\n return child\n }\n return React.cloneElement(child, {\n selected: index === selectedIndex,\n onSelect: () => {\n child.props.onSelect?.()\n handleOpenChange(false)\n }\n })\n }\n return child\n })}\n </div>\n </div>\n </div>\n )}\n </div>\n )\n }\n)\nCommand.displayName = \"Command\"\n\n/**\n * CommandInput 컴포넌트의 props / CommandInput component props\n * @typedef {Object} CommandInputProps\n * @extends {React.InputHTMLAttributes<HTMLInputElement>}\n */\nexport interface CommandInputProps extends React.InputHTMLAttributes<HTMLInputElement> {}\n\nconst CommandInput = React.forwardRef<HTMLInputElement, CommandInputProps>(\n ({ className, ...props }, ref) => (\n <input\n ref={ref}\n className={merge(\n \"flex h-10 w-full rounded-md bg-transparent px-3 py-2 text-sm outline-none\", // 40px 높이, 12px, 8px 패딩\n \"placeholder:text-muted-foreground\",\n \"disabled:cursor-not-allowed disabled:opacity-50\",\n className\n )}\n {...props}\n />\n )\n)\nCommandInput.displayName = \"CommandInput\"\n\nexport interface CommandListProps extends React.HTMLAttributes<HTMLDivElement> {}\n\nconst CommandList = React.forwardRef<HTMLDivElement, CommandListProps>(\n ({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={merge(\"max-h-96 overflow-y-auto py-2\", className)} // 384px 최대 높이, 8px 패딩\n {...props}\n />\n )\n)\nCommandList.displayName = \"CommandList\"\n\n/**\n * CommandItem 컴포넌트의 props / CommandItem component props\n * @typedef {Object} CommandItemProps\n * @property {React.ReactNode} [icon] - 항목 아이콘 / Item icon\n * @property {boolean} [selected=false] - 선택 상태 / Selected state\n * @property {() => void} [onSelect] - 선택 시 콜백 / Selection callback\n * @extends {React.ButtonHTMLAttributes<HTMLButtonElement>}\n */\nexport interface CommandItemProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n icon?: React.ReactNode\n selected?: boolean\n onSelect?: () => void\n}\n\nconst CommandItem = React.forwardRef<HTMLButtonElement, CommandItemProps>(\n ({ \n className, \n icon,\n selected = false,\n onSelect,\n children,\n ...props \n }, ref) => {\n return (\n <button\n ref={ref}\n data-command-item\n className={merge(\n \"relative flex w-full items-center gap-3 rounded-sm px-4 py-3 text-sm\", // 16px, 12px 패딩\n \"text-foreground\",\n \"hover:bg-muted\",\n \"focus:bg-muted\",\n \"focus:outline-none\",\n selected && \"bg-muted\",\n \"transition-colors\",\n className\n )}\n onClick={onSelect}\n {...props}\n >\n {icon && (\n <div className=\"flex-shrink-0 w-4 h-4 text-muted-foreground\">\n {icon}\n </div>\n )}\n <span className=\"flex-1 text-left\">{children}</span>\n </button>\n )\n }\n)\nCommandItem.displayName = \"CommandItem\"\n\n/**\n * CommandGroup 컴포넌트의 props / CommandGroup component props\n * @typedef {Object} CommandGroupProps\n * @property {React.ReactNode} [heading] - 그룹 제목 / Group heading\n * @extends {React.HTMLAttributes<HTMLDivElement>}\n */\nexport interface CommandGroupProps extends React.HTMLAttributes<HTMLDivElement> {\n heading?: React.ReactNode\n}\n\nconst CommandGroup = React.forwardRef<HTMLDivElement, CommandGroupProps>(\n ({ className, heading, children, ...props }, ref) => (\n <div ref={ref} className={merge(\"py-2\", className)} {...props}> {/* 8px 패딩 */}\n {heading && (\n <div className=\"px-4 py-2 text-xs font-semibold text-muted-foreground uppercase tracking-wide\"> {/* 16px, 8px 패딩 */}\n {heading}\n </div>\n )}\n <div className=\"space-y-1\"> {/* 4px 간격 */}\n {children}\n </div>\n </div>\n )\n)\nCommandGroup.displayName = \"CommandGroup\"\n\n/**\n * CommandSeparator 컴포넌트의 props / CommandSeparator component props\n * @typedef {Object} CommandSeparatorProps\n * @extends {React.HTMLAttributes<HTMLDivElement>}\n */\nexport interface CommandSeparatorProps extends React.HTMLAttributes<HTMLDivElement> {}\n\nconst CommandSeparator = React.forwardRef<HTMLDivElement, CommandSeparatorProps>(\n ({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={merge(\"h-px bg-border my-2\", className)} // 8px 여백\n {...props}\n />\n )\n)\nCommandSeparator.displayName = \"CommandSeparator\"\n\n/**\n * CommandEmpty 컴포넌트의 props / CommandEmpty component props\n * @typedef {Object} CommandEmptyProps\n * @extends {React.HTMLAttributes<HTMLDivElement>}\n */\nexport interface CommandEmptyProps extends React.HTMLAttributes<HTMLDivElement> {}\n\nconst CommandEmpty = React.forwardRef<HTMLDivElement, CommandEmptyProps>(\n ({ className, children = \"결과가 없습니다.\", ...props }, ref) => (\n <div\n ref={ref}\n className={merge(\n \"py-8 text-center text-sm text-muted-foreground\", // 32px 패딩\n className\n )}\n {...props}\n >\n {children}\n </div>\n )\n)\nCommandEmpty.displayName = \"CommandEmpty\"\n\n// 편의 컴포넌트들\nexport const CommandDialog = React.forwardRef<HTMLDivElement, CommandProps>(\n ({ className, ...props }, ref) => (\n <Command ref={ref} className={className} {...props} />\n )\n)\nCommandDialog.displayName = \"CommandDialog\"\n\nexport { Command, CommandInput, CommandList, CommandItem, CommandGroup, CommandSeparator, CommandEmpty } "]}
|
|
1
|
+
{"version":3,"sources":["../src/components/Menu.tsx","../src/components/ContextMenu.tsx","../src/components/Command.tsx"],"names":["Menu","React","className","children","variant","size","props","ref","getVariantClasses","getSizeClasses","jsx","merge","child","MenuItem","icon","active","disabled","jsxs","MenuSeparator","MenuLabel","MenuHorizontal","MenuVertical","MenuCompact","ContextMenu","controlledOpen","onOpenChange","trigger","_placement","_align","_offset","internalOpen","setInternalOpen","coords","setCoords","triggerRef","menuRef","isControlled","isOpen","handleOpenChange","newOpen","handleContextMenu","event","x","y","updatePosition","menuRect","viewportWidth","viewportHeight","handleClickOutside","ContextMenuItem","ContextMenuSeparator","ContextMenuLabel","ContextMenuGroup","Command","placeholder","controlledSearchValue","onSearchChange","internalSearchValue","setInternalSearchValue","selectedIndex","setSelectedIndex","commandRef","inputRef","listRef","searchValue","handleSearchChange","value","handleKeyDown","_a","items","itemCount","prev","selectedItem","e","index","_b","CommandInput","CommandList","CommandItem","selected","onSelect","CommandGroup","heading","CommandSeparator","CommandEmpty","CommandDialog"],"mappings":"wXAiDA,IAAMA,CAAAA,CAAOC,CAAAA,CAAM,UAAA,CACjB,CAAC,CACC,SAAA,CAAAC,EACA,QAAA,CAAAC,CAAAA,CACA,QAAAC,CAAAA,CAAU,SAAA,CACV,IAAA,CAAAC,CAAAA,CAAO,IAAA,CACP,GAAGC,CACL,CAAA,CAAGC,CAAAA,GAAQ,CACT,IAAMC,CAAAA,CAAoB,IAAM,CAC9B,OAAQJ,CAAAA,EACN,KAAK,YAAA,CACH,OAAO,6BAAA,CACT,KAAK,WACH,OAAO,yBAAA,CACT,KAAK,SAAA,CACH,OAAO,2BAAA,CACT,QACE,OAAO,yBACX,CACF,CAAA,CAEMK,CAAAA,CAAiB,IAAM,CAC3B,OAAQJ,GACN,KAAK,IAAA,CACH,OAAO,SAAA,CACT,KAAK,KACH,OAAO,WAAA,CACT,QACE,OAAO,SACX,CACF,CAAA,CAEA,OACEK,GAAAA,CAAC,KAAA,CAAA,CACC,GAAA,CAAKH,CAAAA,CACL,UAAWI,CAAAA,CACTH,CAAAA,GACAC,CAAAA,EAAe,CACfP,CACF,CAAA,CACC,GAAGI,CAAAA,CAEH,QAAA,CAAAL,CAAAA,CAAM,QAAA,CAAS,IAAIE,CAAAA,CAAWS,CAAAA,EACzBX,EAAM,cAAA,CAAeW,CAAK,EACrBX,CAAAA,CAAM,YAAA,CAAaW,CAAAA,CAAO,CAC/B,OAAA,CAAAR,CAAAA,CACA,KAAAC,CACF,CAAiE,EAE5DO,CACR,CAAA,CACH,CAEJ,CACF,EACAZ,CAAAA,CAAK,WAAA,CAAc,MAAA,CA8BnB,IAAMa,EAAWZ,CAAAA,CAAM,UAAA,CACrB,CAAC,CACC,SAAA,CAAAC,EACA,IAAA,CAAAY,CAAAA,CACA,OAAA,CAAAV,CAAAA,CAAU,SAAA,CACV,IAAA,CAAAC,EAAO,IAAA,CACP,MAAA,CAAAU,EAAS,KAAA,CACT,QAAA,CAAAC,EAAW,KAAA,CACX,QAAA,CAAAb,CAAAA,CACA,GAAGG,CACL,CAAA,CAAGC,IAAQ,CACT,IAAMC,EAAoB,IAAM,CAC9B,OAAQJ,CAAAA,EACN,KAAK,YAAA,CACH,OAAOO,CAAAA,CACL,qFACAI,CAAAA,CACI,4BAAA,CACA,sDACN,CAAA,CACF,KAAK,WACH,OAAOJ,CAAAA,CACL,oFAAA,CACAI,CAAAA,CACI,4BAAA,CACA,sDACN,EACF,KAAK,SAAA,CACH,OAAOJ,CAAAA,CACL,mFAAA,CACAI,EACI,4BAAA,CACA,sDACN,CAAA,CACF,QACE,OAAOJ,CAAAA,CACL,qFACAI,CAAAA,CACI,4BAAA,CACA,sDACN,CACJ,CACF,EAEMN,CAAAA,CAAiB,IAAM,CAC3B,OAAQJ,CAAAA,EACN,KAAK,IAAA,CACH,OAAO,UACT,KAAK,IAAA,CACH,OAAO,WAAA,CACT,QACE,OAAO,SACX,CACF,CAAA,CAEA,OACEY,IAAAA,CAAC,QAAA,CAAA,CACC,IAAKV,CAAAA,CACL,SAAA,CAAWI,EACTH,CAAAA,EAAkB,CAClBC,CAAAA,EAAe,CACfO,CAAAA,EAAY,+BAAA,CACZd,CACF,CAAA,CACA,QAAA,CAAUc,EACT,GAAGV,CAAAA,CAEH,UAAAQ,CAAAA,EACCJ,GAAAA,CAAC,KAAA,CAAA,CAAI,SAAA,CAAU,uBAAA,CACZ,QAAA,CAAAI,EACH,CAAA,CAEFJ,GAAAA,CAAC,QAAK,SAAA,CAAU,kBAAA,CAAoB,SAAAP,CAAAA,CAAS,CAAA,CAAA,CAC/C,CAEJ,CACF,EACAU,CAAAA,CAAS,YAAc,UAAA,CAsBvB,IAAMK,EAAgBjB,CAAAA,CAAM,UAAA,CAC1B,CAAC,CAAE,SAAA,CAAAC,CAAAA,CAAW,OAAA,CAAAE,CAAAA,CAAU,SAAA,CAAW,GAAGE,CAAM,CAAA,CAAGC,IAa3CG,GAAAA,CAAC,KAAA,CAAA,CACC,IAAKH,CAAAA,CACL,SAAA,CAAWI,CAAAA,CAbLP,CAAAA,GACD,YAAA,CACI,yBAAA,CAIA,sBAO6BF,CAAS,CAAA,CAC9C,GAAGI,CAAAA,CACN,CAGN,EACAY,CAAAA,CAAc,WAAA,CAAc,eAAA,CAwB5B,IAAMC,CAAAA,CAAYlB,CAAAA,CAAM,WACtB,CAAC,CAAE,UAAAC,CAAAA,CAAW,OAAA,CAAAE,EAAU,SAAA,CAAW,IAAA,CAAAC,CAAAA,CAAO,IAAA,CAAM,QAAA,CAAAF,CAAAA,CAAU,GAAGG,CAAM,CAAA,CAAGC,IAAQ,CAC5E,IAAMC,EAAoB,IAChBJ,CAAAA,GACD,YAAA,CACI,+EAAA,CAIA,+EAAA,CAIPK,CAAAA,CAAiB,IAAM,CAC3B,OAAQJ,GACN,KAAK,KACH,OAAO,SAAA,CACT,KAAK,IAAA,CACH,OAAO,SAAA,CACT,QACE,OAAO,SACX,CACF,CAAA,CAEA,OACEK,IAAC,KAAA,CAAA,CACC,GAAA,CAAKH,CAAAA,CACL,SAAA,CAAWI,CAAAA,CACTH,CAAAA,GACAC,CAAAA,EAAe,CACfP,CACF,CAAA,CACC,GAAGI,EAEH,QAAA,CAAAH,CAAAA,CACH,CAEJ,CACF,EACAgB,CAAAA,CAAU,YAAc,WAAA,CAGjB,IAAMC,EAAiBnB,CAAAA,CAAM,UAAA,CAClC,CAAC,CAAE,SAAA,CAAAC,CAAAA,CAAW,GAAGI,CAAM,CAAA,CAAGC,IACxBG,GAAAA,CAACV,CAAAA,CAAA,CAAK,GAAA,CAAKO,CAAAA,CAAK,QAAQ,YAAA,CAAa,SAAA,CAAWL,CAAAA,CAAY,GAAGI,CAAAA,CAAO,CAE1E,EACAc,CAAAA,CAAe,WAAA,CAAc,iBAEtB,IAAMC,CAAAA,CAAepB,EAAM,UAAA,CAChC,CAAC,CAAE,SAAA,CAAAC,CAAAA,CAAW,GAAGI,CAAM,CAAA,CAAGC,CAAAA,GACxBG,IAACV,CAAAA,CAAA,CAAK,IAAKO,CAAAA,CAAK,OAAA,CAAQ,UAAA,CAAW,SAAA,CAAWL,CAAAA,CAAY,GAAGI,EAAO,CAExE,EACAe,CAAAA,CAAa,WAAA,CAAc,cAAA,CAEpB,IAAMC,EAAcrB,CAAAA,CAAM,UAAA,CAC/B,CAAC,CAAE,SAAA,CAAAC,CAAAA,CAAW,GAAGI,CAAM,CAAA,CAAGC,IACxBG,GAAAA,CAACV,CAAAA,CAAA,CAAK,GAAA,CAAKO,CAAAA,CAAK,OAAA,CAAQ,SAAA,CAAU,SAAA,CAAWL,CAAAA,CAAY,GAAGI,CAAAA,CAAO,CAEvE,EACAgB,CAAAA,CAAY,WAAA,CAAc,kBClRpBC,CAAAA,CAActB,CAAAA,CAAM,WACxB,CAAC,CACC,SAAA,CAAAC,CAAAA,CACA,QAAA,CAAAC,CAAAA,CACA,KAAMqB,CAAAA,CACN,YAAA,CAAAC,EACA,OAAA,CAAAC,CAAAA,CACA,UAAWC,CAAAA,CAAa,QAAA,CACxB,KAAA,CAAOC,CAAAA,CAAS,OAAA,CAChB,MAAA,CAAQC,EAAU,CAAA,CAClB,QAAA,CAAAb,EAAW,KAAA,CACX,GAAGV,CACL,CAAA,CAAGC,CAAAA,GAAQ,CACT,GAAM,CAACuB,CAAAA,CAAcC,CAAe,CAAA,CAAI9B,CAAAA,CAAM,SAAS,KAAK,CAAA,CACtD,CAAC+B,CAAAA,CAAQC,CAAS,CAAA,CAAIhC,CAAAA,CAAM,QAAA,CAAS,CAAE,EAAG,CAAA,CAAG,CAAA,CAAG,CAAE,CAAC,CAAA,CACnDiC,EAAajC,CAAAA,CAAM,MAAA,CAAuB,IAAI,CAAA,CAC9CkC,CAAAA,CAAUlC,CAAAA,CAAM,OAAuB,IAAI,CAAA,CAC3CmC,EAAeZ,CAAAA,GAAmB,MAAA,CAClCa,EAASD,CAAAA,CAAeZ,CAAAA,CAAiBM,CAAAA,CAEzCQ,CAAAA,CAAmBrC,CAAAA,CAAM,WAAA,CAAasC,GAAqB,CAC3DvB,CAAAA,GAECoB,GACHL,CAAAA,CAAgBQ,CAAO,EAEzBd,CAAAA,EAAA,IAAA,EAAAA,CAAAA,CAAec,CAAAA,CAAAA,EACjB,CAAA,CAAG,CAACvB,EAAUoB,CAAAA,CAAcX,CAAY,CAAC,CAAA,CAEnCe,CAAAA,CAAqBC,GAA4B,CAErD,GADAA,CAAAA,CAAM,cAAA,EAAe,CACjBzB,CAAAA,CAAU,OAEAyB,EAAM,aAAA,CAAc,qBAAA,OAC5BC,CAAAA,CAAID,CAAAA,CAAM,OAAA,CACVE,CAAAA,CAAIF,CAAAA,CAAM,QAEhBR,EAAU,CAAE,CAAA,CAAAS,EAAG,CAAA,CAAAC,CAAE,CAAC,CAAA,CAClBL,CAAAA,CAAiB,IAAI,EACvB,CAAA,CAEMM,CAAAA,CAAiB3C,EAAM,WAAA,CAAY,IAAM,CAC7C,GAAI,CAACkC,EAAQ,OAAA,CAAS,OAEtB,IAAMU,CAAAA,CAAWV,CAAAA,CAAQ,OAAA,CAAQ,uBAAsB,CACjDW,CAAAA,CAAgB,OAAO,UAAA,CACvBC,CAAAA,CAAiB,OAAO,WAAA,CAE1BL,CAAAA,CAAIV,CAAAA,CAAO,CAAA,CACXW,CAAAA,CAAIX,CAAAA,CAAO,EAGXU,CAAAA,CAAIG,CAAAA,CAAS,MAAQC,CAAAA,CAAgB,CAAA,GACvCJ,EAAII,CAAAA,CAAgBD,CAAAA,CAAS,KAAA,CAAQ,CAAA,CAAA,CAEnCF,CAAAA,CAAIE,CAAAA,CAAS,OAASE,CAAAA,CAAiB,CAAA,GACzCJ,CAAAA,CAAII,CAAAA,CAAiBF,CAAAA,CAAS,MAAA,CAAS,GAErCH,CAAAA,CAAI,CAAA,GAAGA,CAAAA,CAAI,CAAA,CAAA,CACXC,CAAAA,CAAI,CAAA,GAAGA,EAAI,CAAA,CAAA,CAEfV,CAAAA,CAAU,CAAE,CAAA,CAAAS,CAAAA,CAAG,EAAAC,CAAE,CAAC,EACpB,CAAA,CAAG,CAACX,CAAAA,CAAO,EAAGA,CAAAA,CAAO,CAAC,CAAC,CAAA,CAEvB,OAAA/B,EAAM,SAAA,CAAU,IAAM,CACpB,GAAIoC,CAAAA,CACF,OAAAO,GAAe,CACf,MAAA,CAAO,iBAAiB,QAAA,CAAUA,CAAc,EAChD,MAAA,CAAO,gBAAA,CAAiB,QAAA,CAAUA,CAAc,CAAA,CAEzC,IAAM,CACX,MAAA,CAAO,mBAAA,CAAoB,SAAUA,CAAc,CAAA,CACnD,OAAO,mBAAA,CAAoB,QAAA,CAAUA,CAAc,EACrD,CAEJ,CAAA,CAAG,CAACP,CAAAA,CAAQO,CAAc,CAAC,CAAA,CAE3B3C,CAAAA,CAAM,UAAU,IAAM,CACpB,IAAM+C,CAAAA,CAAsBP,CAAAA,EAAsB,CAE9CP,EAAW,OAAA,EACXC,CAAAA,CAAQ,SACR,CAACD,CAAAA,CAAW,QAAQ,QAAA,CAASO,CAAAA,CAAM,MAAc,CAAA,EACjD,CAACN,CAAAA,CAAQ,QAAQ,QAAA,CAASM,CAAAA,CAAM,MAAc,CAAA,EAE9CH,CAAAA,CAAiB,KAAK,EAE1B,CAAA,CAEA,GAAID,CAAAA,CACF,OAAA,QAAA,CAAS,gBAAA,CAAiB,YAAaW,CAAkB,CAAA,CAClD,IAAM,CACX,QAAA,CAAS,oBAAoB,WAAA,CAAaA,CAAkB,EAC9D,CAEJ,CAAA,CAAG,CAACX,EAAQC,CAAgB,CAAC,EAG3BrB,IAAAA,CAAC,KAAA,CAAA,CAAI,IAAKV,CAAAA,CAAK,SAAA,CAAWI,CAAAA,CAAM,UAAA,CAAYT,CAAS,CAAA,CAAI,GAAGI,CAAAA,CAEzD,QAAA,CAAA,CAAAoB,GACChB,GAAAA,CAAC,KAAA,CAAA,CACC,IAAKwB,CAAAA,CACL,aAAA,CAAeM,CAAAA,CACf,SAAA,CAAU,cAAA,CAET,QAAA,CAAAd,EACH,CAAA,CAIDW,CAAAA,EACC3B,IAAC,KAAA,CAAA,CACC,GAAA,CAAKyB,EACL,SAAA,CAAWxB,CAAAA,CACT,qFAAA,CACA,oBAAA,CACA,UACF,CAAA,CACA,MAAO,CACL,IAAA,CAAMqB,EAAO,CAAA,CACb,GAAA,CAAKA,EAAO,CAAA,CACZ,SAAA,CAAW,2EACb,CAAA,CAEC,QAAA,CAAA7B,CAAAA,CACH,GAEJ,CAEJ,CACF,EACAoB,CAAAA,CAAY,WAAA,CAAc,cAO1B,IAAM0B,CAAAA,CAAkBhD,CAAAA,CAAM,UAAA,CAC5B,CAAC,CACC,UAAAC,CAAAA,CACA,IAAA,CAAAY,EACA,OAAA,CAAAV,CAAAA,CAAU,UACV,QAAA,CAAAD,CAAAA,CACA,QAAA,CAAAa,CAAAA,CACA,GAAGV,CACL,EAAGC,CAAAA,GAaCU,IAAAA,CAAC,UACC,GAAA,CAAKV,CAAAA,CACL,UAAWI,CAAAA,CACT,2JAAA,CAAA,CAfoB,IAAM,CAC9B,OAAQP,CAAAA,EACN,KAAK,aAAA,CACH,OAAO,0CAAA,CACT,KAAK,UAAA,CACH,OAAO,0CAAA,CACT,QACE,OAAO,gCACX,CACF,CAAA,IAQMF,CACF,CAAA,CACA,SAAUc,CAAAA,EAAYZ,CAAAA,GAAY,WACjC,GAAGE,CAAAA,CAEH,QAAA,CAAA,CAAAQ,CAAAA,EACCJ,GAAAA,CAAC,KAAA,CAAA,CAAI,UAAU,uBAAA,CACZ,QAAA,CAAAI,EACH,CAAA,CAEFJ,GAAAA,CAAC,QAAK,SAAA,CAAU,kBAAA,CAAoB,QAAA,CAAAP,CAAAA,CAAS,CAAA,CAAA,CAC/C,CAGN,EACA8C,CAAAA,CAAgB,WAAA,CAAc,kBAI9B,IAAMC,CAAAA,CAAuBjD,EAAM,UAAA,CACjC,CAAC,CAAE,SAAA,CAAAC,CAAAA,CAAW,GAAGI,CAAM,CAAA,CAAGC,CAAAA,GACxBG,IAAC,KAAA,CAAA,CACC,GAAA,CAAKH,EACL,SAAA,CAAWI,CAAAA,CAAM,qBAAA,CAAuBT,CAAS,CAAA,CAChD,GAAGI,EACN,CAEJ,EACA4C,EAAqB,WAAA,CAAc,sBAAA,KAI7BC,CAAAA,CAAmBlD,CAAAA,CAAM,UAAA,CAC7B,CAAC,CAAE,SAAA,CAAAC,EAAW,QAAA,CAAAC,CAAAA,CAAU,GAAGG,CAAM,CAAA,CAAGC,IAClCG,GAAAA,CAAC,KAAA,CAAA,CACC,GAAA,CAAKH,CAAAA,CACL,SAAA,CAAWI,CAAAA,CAAM,gFAAiFT,CAAS,CAAA,CAC1G,GAAGI,CAAAA,CAEH,QAAA,CAAAH,EACH,CAEJ,EACAgD,CAAAA,CAAiB,WAAA,CAAc,kBAAA,CAG/B,IAAMC,EAAmBnD,CAAAA,CAAM,UAAA,CAC7B,CAAC,CAAE,SAAA,CAAAC,EAAW,QAAA,CAAAC,CAAAA,CAAU,GAAGG,CAAM,CAAA,CAAGC,CAAAA,GAClCG,IAAC,KAAA,CAAA,CACC,GAAA,CAAKH,EACL,SAAA,CAAWI,CAAAA,CAAM,OAAQT,CAAS,CAAA,CACjC,GAAGI,CAAAA,CAEH,QAAA,CAAAH,CAAAA,CACH,CAEJ,EACAiD,CAAAA,CAAiB,YAAc,kBAAA,CC7N/B,IAAMC,CAAAA,CAAUpD,EAAM,UAAA,CACpB,CAAC,CACC,SAAA,CAAAC,CAAAA,CACA,QAAA,CAAAC,CAAAA,CACA,IAAA,CAAMqB,CAAAA,CACN,aAAAC,CAAAA,CACA,WAAA,CAAA6B,EAAc,4DAAA,CACd,WAAA,CAAaC,EACb,cAAA,CAAAC,CAAAA,CACA,QAAA,CAAAxC,CAAAA,CAAW,KAAA,CACX,GAAGV,CACL,CAAA,CAAGC,CAAAA,GAAQ,CACT,GAAM,CAACuB,EAAcC,CAAe,CAAA,CAAI9B,CAAAA,CAAM,QAAA,CAAS,KAAK,CAAA,CACtD,CAACwD,CAAAA,CAAqBC,CAAsB,EAAIzD,CAAAA,CAAM,QAAA,CAAS,EAAE,CAAA,CACjE,CAAC0D,CAAAA,CAAeC,CAAgB,CAAA,CAAI3D,CAAAA,CAAM,SAAS,CAAC,CAAA,CACpD4D,EAAa5D,CAAAA,CAAM,MAAA,CAAuB,IAAI,CAAA,CAC9C6D,CAAAA,CAAW7D,CAAAA,CAAM,MAAA,CAAyB,IAAI,CAAA,CAC9C8D,EAAU9D,CAAAA,CAAM,MAAA,CAAuB,IAAI,CAAA,CAE3CmC,CAAAA,CAAeZ,IAAmB,MAAA,CAClCa,CAAAA,CAASD,CAAAA,CAAeZ,CAAAA,CAAiBM,CAAAA,CACzCkC,CAAAA,CAAcT,IAA0B,MAAA,CAAYA,CAAAA,CAAwBE,EAE5EnB,CAAAA,CAAmBrC,CAAAA,CAAM,YAAasC,CAAAA,EAAqB,CAC3DvB,CAAAA,GAECoB,CAAAA,EACHL,CAAAA,CAAgBQ,CAAO,EAEzBd,CAAAA,EAAA,IAAA,EAAAA,EAAec,CAAAA,CAAAA,EACjB,CAAA,CAAG,CAACvB,CAAAA,CAAUoB,CAAAA,CAAcX,CAAY,CAAC,CAAA,CAEnCwC,CAAAA,CAAsBC,GAAkB,CACvC9B,CAAAA,EACHsB,EAAuBQ,CAAK,CAAA,CAE9BV,GAAA,IAAA,EAAAA,CAAAA,CAAiBU,CAAAA,CAAAA,CACjBN,CAAAA,CAAiB,CAAC,EACpB,EAEMO,CAAAA,CAAiB1B,CAAAA,EAA+B,CA3G1D,IAAA2B,CAAAA,CA4GM,GAAIpD,CAAAA,CAAU,OAEd,IAAMqD,CAAAA,CAAAA,CAAQD,CAAAA,CAAAL,CAAAA,CAAQ,UAAR,IAAA,CAAA,MAAA,CAAAK,CAAAA,CAAiB,iBAAiB,qBAAA,CAAA,CAC1CE,CAAAA,CAAAA,CAAYD,GAAA,IAAA,CAAA,MAAA,CAAAA,CAAAA,CAAO,MAAA,GAAU,CAAA,CAEnC,OAAQ5B,CAAAA,CAAM,KACZ,KAAK,YACHA,CAAAA,CAAM,cAAA,GACNmB,CAAAA,CAAkBW,CAAAA,EAAAA,CAAUA,CAAAA,CAAO,CAAA,EAAKD,CAAS,CAAA,CACjD,MACF,KAAK,SAAA,CACH7B,EAAM,cAAA,EAAe,CACrBmB,EAAkBW,CAAAA,EAAAA,CAAUA,CAAAA,CAAO,CAAA,CAAID,CAAAA,EAAaA,CAAS,CAAA,CAC7D,MACF,KAAK,OAAA,CAAS,CACZ7B,CAAAA,CAAM,cAAA,GACN,IAAM+B,CAAAA,CAAeH,CAAAA,EAAA,IAAA,CAAA,MAAA,CAAAA,CAAAA,CAAQV,CAAAA,CAAAA,CAC7Ba,GAAA,IAAA,EAAAA,CAAAA,CAAc,QACd,KACF,CACA,KAAK,QAAA,CACH/B,CAAAA,CAAM,cAAA,EAAe,CACrBH,CAAAA,CAAiB,KAAK,EACtB,KACJ,CACF,EAEA,OAAArC,CAAAA,CAAM,UAAU,IAAM,CAvI1B,IAAAmE,CAAAA,CAwIU/B,CAAAA,GAAAA,CACF+B,CAAAA,CAAAN,EAAS,OAAA,GAAT,IAAA,EAAAM,EAAkB,KAAA,EAAA,CAClBR,CAAAA,CAAiB,CAAC,CAAA,EAEtB,CAAA,CAAG,CAACvB,CAAM,CAAC,CAAA,CAEXpC,EAAM,SAAA,CAAU,IAAM,CACpB,IAAMkE,CAAAA,CAAiB1B,GAAyB,CAC1CA,CAAAA,CAAM,GAAA,GAAQ,GAAA,GAAQA,CAAAA,CAAM,OAAA,EAAWA,EAAM,OAAA,CAAA,GAC/CA,CAAAA,CAAM,gBAAe,CACrBH,CAAAA,CAAiB,CAACD,CAAM,CAAA,CAAA,CAGtBI,CAAAA,CAAM,GAAA,GAAQ,QAAA,EAAYJ,CAAAA,GAC5BI,EAAM,cAAA,EAAe,CACrBH,EAAiB,KAAK,CAAA,EAE1B,EAEA,OAAA,QAAA,CAAS,gBAAA,CAAiB,SAAA,CAAW6B,CAAa,CAAA,CAC3C,IAAM,CACX,QAAA,CAAS,mBAAA,CAAoB,UAAWA,CAAa,EACvD,CACF,CAAA,CAAG,CAAC9B,CAAAA,CAAQC,CAAgB,CAAC,CAAA,CAE7BrC,EAAM,SAAA,CAAU,IAAM,CAjK1B,IAAAmE,CAAAA,CAkKM,IAAMI,GAAeJ,CAAAA,CAAAL,CAAAA,CAAQ,OAAA,GAAR,IAAA,CAAA,MAAA,CAAAK,CAAAA,CAAiB,aAAA,CAAc,iCAAiCT,CAAAA,CAAgB,CAAC,KACtGa,CAAAA,EAAA,IAAA,EAAAA,EAAc,cAAA,CAAe,CAAE,KAAA,CAAO,SAAU,CAAA,EAClD,CAAA,CAAG,CAACb,CAAa,CAAC,EAGhBjD,GAAAA,CAAC,KAAA,CAAA,CAAI,IAAKH,CAAAA,CAAK,SAAA,CAAWI,CAAAA,CAAM,UAAA,CAAYT,CAAS,CAAA,CAAI,GAAGI,CAAAA,CACzD,QAAA,CAAA+B,GACC3B,GAAAA,CAAC,KAAA,CAAA,CACC,IAAKmD,CAAAA,CACL,SAAA,CAAWlD,CAAAA,CACT,iDAAA,CACA,uCACF,CAAA,CACA,QAAS,IAAM2B,CAAAA,CAAiB,KAAK,CAAA,CAErC,QAAA,CAAArB,KAAC,KAAA,CAAA,CACC,SAAA,CAAWN,CAAAA,CACT,gFAAA,CACA,0BACF,CAAA,CACA,QAAU8D,CAAAA,EAAMA,CAAAA,CAAE,iBAAgB,CAClC,KAAA,CAAO,CACL,SAAA,CAAW,uCACb,CAAA,CAEA,QAAA,CAAA,CAAAxD,IAAAA,CAAC,KAAA,CAAA,CAAI,UAAU,4BAAA,CAA6B,QAAA,CAAA,CAAA,GAAA,CAC1CP,IAAC,OAAA,CAAA,CACC,GAAA,CAAKoD,EACL,IAAA,CAAK,MAAA,CACL,WAAA,CAAaR,CAAAA,CACb,KAAA,CAAOU,CAAAA,CACP,SAAWS,CAAAA,EAAMR,CAAAA,CAAmBQ,EAAE,MAAA,CAAO,KAAK,EAClD,SAAA,CAAWN,CAAAA,CACX,SAAA,CAAWxD,CAAAA,CACT,wDAAA,CACA,mCAAA,CACA,iBACF,CAAA,CACF,CAAA,CAAA,CACF,EAEAD,GAAAA,CAAC,KAAA,CAAA,CACC,IAAKqD,CAAAA,CACL,SAAA,CAAU,+BAAA,CAET,QAAA,CAAA9D,CAAAA,CAAM,QAAA,CAAS,IAAIE,CAAAA,CAAU,CAACS,EAAO8D,CAAAA,GAChCzE,CAAAA,CAAM,eAAiCW,CAAK,CAAA,CAE1CA,CAAAA,CAAM,IAAA,GAASX,CAAAA,CAAM,QAAA,EAAY,OAAOW,CAAAA,CAAM,IAAA,EAAS,SAClDA,CAAAA,CAEFX,CAAAA,CAAM,aAAaW,CAAAA,CAAO,CAC/B,QAAA,CAAU8D,CAAAA,GAAUf,CAAAA,CACpB,QAAA,CAAU,IAAM,CAvNtC,IAAAS,EAAAO,CAAAA,CAAAA,CAwNwBA,CAAAA,CAAAA,CAAAP,EAAAxD,CAAAA,CAAM,KAAA,EAAM,QAAA,GAAZ,IAAA,EAAA+D,CAAAA,CAAA,IAAA,CAAAP,GACA9B,CAAAA,CAAiB,KAAK,EACxB,CACF,CAAC,EAEI1B,CACR,CAAA,CACH,CAAA,CAAA,CACF,CAAA,CACF,CAAA,CAEJ,CAEJ,CACF,EACAyC,CAAAA,CAAQ,YAAc,SAAA,CAStB,IAAMuB,EAAe3E,CAAAA,CAAM,UAAA,CACzB,CAAC,CAAE,SAAA,CAAAC,CAAAA,CAAW,GAAGI,CAAM,CAAA,CAAGC,IACxBG,GAAAA,CAAC,OAAA,CAAA,CACC,IAAKH,CAAAA,CACL,SAAA,CAAWI,CAAAA,CACT,2EAAA,CACA,mCAAA,CACA,iDAAA,CACAT,CACF,CAAA,CACC,GAAGI,EACN,CAEJ,EACAsE,EAAa,WAAA,CAAc,cAAA,CAI3B,IAAMC,CAAAA,CAAc5E,CAAAA,CAAM,UAAA,CACxB,CAAC,CAAE,SAAA,CAAAC,CAAAA,CAAW,GAAGI,CAAM,CAAA,CAAGC,IACxBG,GAAAA,CAAC,KAAA,CAAA,CACC,GAAA,CAAKH,CAAAA,CACL,SAAA,CAAWI,CAAAA,CAAM,gCAAiCT,CAAS,CAAA,CAC1D,GAAGI,CAAAA,CACN,CAEJ,EACAuE,CAAAA,CAAY,WAAA,CAAc,aAAA,CAgB1B,IAAMC,EAAAA,CAAc7E,CAAAA,CAAM,WACxB,CAAC,CACC,UAAAC,CAAAA,CACA,IAAA,CAAAY,EACA,QAAA,CAAAiE,CAAAA,CAAW,KAAA,CACX,QAAA,CAAAC,CAAAA,CACA,QAAA,CAAA7E,EACA,GAAGG,CACL,EAAGC,CAAAA,GAECU,IAAAA,CAAC,UACC,GAAA,CAAKV,CAAAA,CACL,mBAAA,CAAiB,IAAA,CACjB,SAAA,CAAWI,CAAAA,CACT,uEACA,iBAAA,CACA,gBAAA,CACA,iBACA,oBAAA,CACAoE,CAAAA,EAAY,WACZ,mBAAA,CACA7E,CACF,CAAA,CACA,OAAA,CAAS8E,CAAAA,CACR,GAAG1E,EAEH,QAAA,CAAA,CAAAQ,CAAAA,EACCJ,IAAC,KAAA,CAAA,CAAI,SAAA,CAAU,8CACZ,QAAA,CAAAI,CAAAA,CACH,CAAA,CAEFJ,GAAAA,CAAC,MAAA,CAAA,CAAK,SAAA,CAAU,mBAAoB,QAAA,CAAAP,CAAAA,CAAS,GAC/C,CAGN,EACA2E,GAAY,WAAA,CAAc,aAAA,CAY1B,IAAMG,EAAAA,CAAehF,CAAAA,CAAM,UAAA,CACzB,CAAC,CAAE,SAAA,CAAAC,EAAW,OAAA,CAAAgF,CAAAA,CAAS,SAAA/E,CAAAA,CAAU,GAAGG,CAAM,CAAA,CAAGC,CAAAA,GAC3CU,IAAAA,CAAC,OAAI,GAAA,CAAKV,CAAAA,CAAK,UAAWI,CAAAA,CAAM,MAAA,CAAQT,CAAS,CAAA,CAAI,GAAGI,CAAAA,CAAO,QAAA,CAAA,CAAA,GAAA,CAC5D4E,CAAAA,EACCjE,IAAAA,CAAC,OAAI,SAAA,CAAU,+EAAA,CAAgF,cAC5FiE,CAAAA,CAAAA,CACH,CAAA,CAEFjE,KAAC,KAAA,CAAA,CAAI,SAAA,CAAU,WAAA,CAAY,QAAA,CAAA,CAAA,GAAA,CACxBd,CAAAA,CAAAA,CACH,CAAA,CAAA,CACF,CAEJ,EACA8E,EAAAA,CAAa,YAAc,cAAA,CAS3B,IAAME,GAAmBlF,CAAAA,CAAM,UAAA,CAC7B,CAAC,CAAE,SAAA,CAAAC,CAAAA,CAAW,GAAGI,CAAM,CAAA,CAAGC,IACxBG,GAAAA,CAAC,KAAA,CAAA,CACC,IAAKH,CAAAA,CACL,SAAA,CAAWI,CAAAA,CAAM,qBAAA,CAAuBT,CAAS,CAAA,CAChD,GAAGI,CAAAA,CACN,CAEJ,EACA6E,EAAAA,CAAiB,WAAA,CAAc,mBAS/B,IAAMC,EAAAA,CAAenF,CAAAA,CAAM,UAAA,CACzB,CAAC,CAAE,UAAAC,CAAAA,CAAW,QAAA,CAAAC,EAAW,8CAAA,CAAa,GAAGG,CAAM,CAAA,CAAGC,CAAAA,GAChDG,GAAAA,CAAC,KAAA,CAAA,CACC,GAAA,CAAKH,CAAAA,CACL,UAAWI,CAAAA,CACT,gDAAA,CACAT,CACF,CAAA,CACC,GAAGI,EAEH,QAAA,CAAAH,CAAAA,CACH,CAEJ,EACAiF,EAAAA,CAAa,WAAA,CAAc,eAGpB,IAAMC,EAAAA,CAAgBpF,EAAM,UAAA,CACjC,CAAC,CAAE,SAAA,CAAAC,CAAAA,CAAW,GAAGI,CAAM,CAAA,CAAGC,CAAAA,GACxBG,IAAC2C,CAAAA,CAAA,CAAQ,GAAA,CAAK9C,CAAAA,CAAK,SAAA,CAAWL,CAAAA,CAAY,GAAGI,CAAAA,CAAO,CAExD,EACA+E,EAAAA,CAAc,WAAA,CAAc,eAAA","file":"interactive.mjs","sourcesContent":["\"use client\"\n\nimport React from \"react\"\nimport { merge } from \"../lib/utils\"\n\n/**\n * Menu 컴포넌트의 props / Menu component props\n * @typedef {Object} MenuProps\n * @property {React.ReactNode} children - MenuItem, MenuSeparator, MenuLabel 컴포넌트들 / MenuItem, MenuSeparator, MenuLabel components\n * @property {\"default\" | \"horizontal\" | \"vertical\" | \"compact\"} [variant=\"default\"] - 메뉴 방향 및 스타일 / Menu direction and style\n * @property {\"sm\" | \"md\" | \"lg\"} [size=\"md\"] - 메뉴 아이템 크기 / Menu item size\n * @extends {React.HTMLAttributes<HTMLDivElement>}\n */\nexport interface MenuProps extends React.HTMLAttributes<HTMLDivElement> {\n children: React.ReactNode\n variant?: \"default\" | \"horizontal\" | \"vertical\" | \"compact\"\n size?: \"sm\" | \"md\" | \"lg\"\n}\n\n/**\n * Menu 컴포넌트 / Menu component\n * \n * 메뉴 리스트를 제공하는 컴포넌트입니다.\n * MenuItem, MenuSeparator, MenuLabel과 함께 사용합니다.\n * \n * Component that provides menu lists.\n * Used with MenuItem, MenuSeparator, and MenuLabel.\n * \n * @component\n * @example\n * // 기본 수직 메뉴 / Basic vertical menu\n * <Menu>\n * <MenuItem icon={<Icon name=\"home\" />}>홈</MenuItem>\n * <MenuItem icon={<Icon name=\"settings\" />}>설정</MenuItem>\n * <MenuSeparator />\n * <MenuItem>로그아웃</MenuItem>\n * </Menu>\n * \n * @example\n * // 수평 메뉴 / Horizontal menu\n * <Menu variant=\"horizontal\">\n * <MenuItem>메뉴 1</MenuItem>\n * <MenuItem>메뉴 2</MenuItem>\n * </Menu>\n * \n * @param {MenuProps} props - Menu 컴포넌트의 props / Menu component props\n * @param {React.Ref<HTMLDivElement>} ref - div 요소 ref / div element ref\n * @returns {JSX.Element} Menu 컴포넌트 / Menu component\n */\nconst Menu = React.forwardRef<HTMLDivElement, MenuProps>(\n ({ \n className, \n children,\n variant = \"default\",\n size = \"md\",\n ...props \n }, ref) => {\n const getVariantClasses = () => {\n switch (variant) {\n case \"horizontal\":\n return \"flex items-center space-x-1\" // 4px 간격\n case \"vertical\":\n return \"flex flex-col space-y-1\" // 4px 간격\n case \"compact\":\n return \"flex flex-col space-y-0.5\" // 2px 간격\n default:\n return \"flex flex-col space-y-1\" // 4px 간격\n }\n }\n\n const getSizeClasses = () => {\n switch (size) {\n case \"sm\":\n return \"text-sm\"\n case \"lg\":\n return \"text-base\"\n default:\n return \"text-sm\"\n }\n }\n\n return (\n <div\n ref={ref}\n className={merge(\n getVariantClasses(),\n getSizeClasses(),\n className\n )}\n {...props}\n >\n {React.Children.map(children, (child) => {\n if (React.isValidElement(child)) {\n return React.cloneElement(child, {\n variant,\n size\n } as Partial<MenuItemProps | MenuSeparatorProps | MenuLabelProps>)\n }\n return child\n })}\n </div>\n )\n }\n)\nMenu.displayName = \"Menu\"\n\n/**\n * MenuItem 컴포넌트의 props / MenuItem component props\n * @typedef {Object} MenuItemProps\n * @property {React.ReactNode} [icon] - 메뉴 아이템 아이콘 / Menu item icon\n * @property {\"default\" | \"horizontal\" | \"vertical\" | \"compact\"} [variant] - 메뉴 변형 (Menu에서 자동 전달) / Menu variant (auto-passed from Menu)\n * @property {\"sm\" | \"md\" | \"lg\"} [size] - 메뉴 크기 (Menu에서 자동 전달) / Menu size (auto-passed from Menu)\n * @property {boolean} [active=false] - 활성화 상태 / Active state\n * @property {boolean} [disabled=false] - 비활성화 상태 / Disabled state\n * @extends {React.ButtonHTMLAttributes<HTMLButtonElement>}\n */\nexport interface MenuItemProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n icon?: React.ReactNode\n variant?: \"default\" | \"horizontal\" | \"vertical\" | \"compact\"\n size?: \"sm\" | \"md\" | \"lg\"\n active?: boolean\n disabled?: boolean\n}\n\n/**\n * MenuItem 컴포넌트 / MenuItem component\n * 메뉴의 개별 아이템을 표시합니다.\n * Displays an individual menu item.\n * \n * @component\n * @param {MenuItemProps} props - MenuItem 컴포넌트의 props / MenuItem component props\n * @param {React.Ref<HTMLButtonElement>} ref - button 요소 ref / button element ref\n * @returns {JSX.Element} MenuItem 컴포넌트 / MenuItem component\n */\nconst MenuItem = React.forwardRef<HTMLButtonElement, MenuItemProps>(\n ({ \n className, \n icon,\n variant = \"default\",\n size = \"md\",\n active = false,\n disabled = false,\n children,\n ...props \n }, ref) => {\n const getVariantClasses = () => {\n switch (variant) {\n case \"horizontal\":\n return merge(\n \"flex items-center gap-2 px-3 py-2 rounded-md text-sm font-medium transition-colors\", // 12px, 8px 패딩\n active \n ? \"bg-primary/10 text-primary\"\n : \"text-foreground hover:text-foreground hover:bg-muted\"\n )\n case \"vertical\":\n return merge(\n \"flex items-center gap-3 px-4 py-3 rounded-md text-sm font-medium transition-colors\", // 16px, 12px 패딩\n active\n ? \"bg-primary/10 text-primary\"\n : \"text-foreground hover:text-foreground hover:bg-muted\"\n )\n case \"compact\":\n return merge(\n \"flex items-center gap-2 px-2 py-1.5 rounded text-sm font-medium transition-colors\", // 8px, 6px 패딩\n active\n ? \"bg-primary/10 text-primary\"\n : \"text-foreground hover:text-foreground hover:bg-muted\"\n )\n default:\n return merge(\n \"flex items-center gap-3 px-4 py-3 rounded-md text-sm font-medium transition-colors\", // 16px, 12px 패딩\n active\n ? \"bg-primary/10 text-primary\"\n : \"text-foreground hover:text-foreground hover:bg-muted\"\n )\n }\n }\n\n const getSizeClasses = () => {\n switch (size) {\n case \"sm\":\n return \"text-xs\"\n case \"lg\":\n return \"text-base\"\n default:\n return \"text-sm\"\n }\n }\n\n return (\n <button\n ref={ref}\n className={merge(\n getVariantClasses(),\n getSizeClasses(),\n disabled && \"opacity-50 cursor-not-allowed\",\n className\n )}\n disabled={disabled}\n {...props}\n >\n {icon && (\n <div className=\"flex-shrink-0 w-4 h-4\">\n {icon}\n </div>\n )}\n <span className=\"flex-1 text-left\">{children}</span>\n </button>\n )\n }\n)\nMenuItem.displayName = \"MenuItem\"\n\n/**\n * MenuSeparator 컴포넌트의 props / MenuSeparator component props\n * @typedef {Object} MenuSeparatorProps\n * @property {\"default\" | \"horizontal\" | \"vertical\" | \"compact\"} [variant] - 메뉴 변형 (Menu에서 자동 전달) / Menu variant (auto-passed from Menu)\n * @extends {React.HTMLAttributes<HTMLDivElement>}\n */\nexport interface MenuSeparatorProps extends React.HTMLAttributes<HTMLDivElement> {\n variant?: \"default\" | \"horizontal\" | \"vertical\" | \"compact\"\n}\n\n/**\n * MenuSeparator 컴포넌트 / MenuSeparator component\n * 메뉴 아이템들을 구분하는 구분선을 표시합니다.\n * Displays a separator line between menu items.\n * \n * @component\n * @param {MenuSeparatorProps} props - MenuSeparator 컴포넌트의 props / MenuSeparator component props\n * @param {React.Ref<HTMLDivElement>} ref - div 요소 ref / div element ref\n * @returns {JSX.Element} MenuSeparator 컴포넌트 / MenuSeparator component\n */\nconst MenuSeparator = React.forwardRef<HTMLDivElement, MenuSeparatorProps>(\n ({ className, variant = \"default\", ...props }, ref) => {\n const getVariantClasses = () => {\n switch (variant) {\n case \"horizontal\":\n return \"w-px h-4 bg-border mx-1\" // 4px 여백\n case \"vertical\":\n case \"compact\":\n default:\n return \"h-px bg-border my-2\" // 8px 여백\n }\n }\n\n return (\n <div\n ref={ref}\n className={merge(getVariantClasses(), className)}\n {...props}\n />\n )\n }\n)\nMenuSeparator.displayName = \"MenuSeparator\"\n\n/**\n * MenuLabel 컴포넌트의 props / MenuLabel component props\n * @typedef {Object} MenuLabelProps\n * @property {\"default\" | \"horizontal\" | \"vertical\" | \"compact\"} [variant] - 메뉴 변형 (Menu에서 자동 전달) / Menu variant (auto-passed from Menu)\n * @property {\"sm\" | \"md\" | \"lg\"} [size] - 메뉴 크기 (Menu에서 자동 전달) / Menu size (auto-passed from Menu)\n * @extends {React.HTMLAttributes<HTMLDivElement>}\n */\nexport interface MenuLabelProps extends React.HTMLAttributes<HTMLDivElement> {\n variant?: \"default\" | \"horizontal\" | \"vertical\" | \"compact\"\n size?: \"sm\" | \"md\" | \"lg\"\n}\n\n/**\n * MenuLabel 컴포넌트 / MenuLabel component\n * 메뉴 섹션의 레이블을 표시합니다.\n * Displays a label for a menu section.\n * \n * @component\n * @param {MenuLabelProps} props - MenuLabel 컴포넌트의 props / MenuLabel component props\n * @param {React.Ref<HTMLDivElement>} ref - div 요소 ref / div element ref\n * @returns {JSX.Element} MenuLabel 컴포넌트 / MenuLabel component\n */\nconst MenuLabel = React.forwardRef<HTMLDivElement, MenuLabelProps>(\n ({ className, variant = \"default\", size = \"md\", children, ...props }, ref) => {\n const getVariantClasses = () => {\n switch (variant) {\n case \"horizontal\":\n return \"px-3 py-1 text-xs font-semibold text-muted-foreground uppercase tracking-wide\" // 12px, 4px 패딩\n case \"vertical\":\n case \"compact\":\n default:\n return \"px-4 py-2 text-xs font-semibold text-muted-foreground uppercase tracking-wide\" // 16px, 8px 패딩\n }\n }\n\n const getSizeClasses = () => {\n switch (size) {\n case \"sm\":\n return \"text-xs\"\n case \"lg\":\n return \"text-sm\"\n default:\n return \"text-xs\"\n }\n }\n\n return (\n <div\n ref={ref}\n className={merge(\n getVariantClasses(),\n getSizeClasses(),\n className\n )}\n {...props}\n >\n {children}\n </div>\n )\n }\n)\nMenuLabel.displayName = \"MenuLabel\"\n\n// 편의 컴포넌트들\nexport const MenuHorizontal = React.forwardRef<HTMLDivElement, Omit<MenuProps, \"variant\">>(\n ({ className, ...props }, ref) => (\n <Menu ref={ref} variant=\"horizontal\" className={className} {...props} />\n )\n)\nMenuHorizontal.displayName = \"MenuHorizontal\"\n\nexport const MenuVertical = React.forwardRef<HTMLDivElement, Omit<MenuProps, \"variant\">>(\n ({ className, ...props }, ref) => (\n <Menu ref={ref} variant=\"vertical\" className={className} {...props} />\n )\n)\nMenuVertical.displayName = \"MenuVertical\"\n\nexport const MenuCompact = React.forwardRef<HTMLDivElement, Omit<MenuProps, \"variant\">>(\n ({ className, ...props }, ref) => (\n <Menu ref={ref} variant=\"compact\" className={className} {...props} />\n )\n)\nMenuCompact.displayName = \"MenuCompact\"\n\nexport { Menu, MenuItem, MenuSeparator, MenuLabel } ","\"use client\"\n\nimport React from \"react\"\nimport { merge } from \"../lib/utils\"\n\n/**\n * ContextMenu 컴포넌트의 props / ContextMenu component props\n * @typedef {Object} ContextMenuProps\n * @property {React.ReactNode} children - ContextMenu 내용 / ContextMenu content\n * @property {boolean} [open] - 제어 모드에서 열림/닫힘 상태 / Open/close state in controlled mode\n * @property {(open: boolean) => void} [onOpenChange] - 상태 변경 콜백 / State change callback\n * @property {React.ReactNode} [trigger] - ContextMenu를 열기 위한 트리거 요소 (우클릭 이벤트) / Trigger element to open context menu (right-click event)\n * @property {\"top\" | \"bottom\" | \"left\" | \"right\"} [placement=\"bottom\"] - ContextMenu 표시 위치 / ContextMenu display position\n * @property {\"start\" | \"center\" | \"end\"} [align=\"start\"] - ContextMenu 정렬 / ContextMenu alignment\n * @property {number} [offset=8] - 트리거와 ContextMenu 사이 간격 (px) / Spacing between trigger and context menu (px)\n * @property {boolean} [disabled=false] - ContextMenu 비활성화 여부 / Disable context menu\n * @extends {React.HTMLAttributes<HTMLDivElement>}\n */\nexport interface ContextMenuProps extends React.HTMLAttributes<HTMLDivElement> {\n children: React.ReactNode\n open?: boolean\n onOpenChange?: (open: boolean) => void\n trigger?: React.ReactNode\n placement?: \"top\" | \"bottom\" | \"left\" | \"right\"\n align?: \"start\" | \"center\" | \"end\"\n offset?: number\n disabled?: boolean\n}\n\n/**\n * ContextMenu 컴포넌트 / ContextMenu component\n * \n * 우클릭 시 표시되는 컨텍스트 메뉴 컴포넌트입니다.\n * 트리거 요소에 우클릭 이벤트를 자동으로 연결합니다.\n * \n * Context menu component that appears on right-click.\n * Automatically connects right-click events to the trigger element.\n * \n * @component\n * @example\n * // 기본 사용 / Basic usage\n * <ContextMenu trigger={<div>우클릭하세요</div>}>\n * <div className=\"p-2\">\n * <button>항목 1</button>\n * <button>항목 2</button>\n * </div>\n * </ContextMenu>\n * \n * @example\n * // 제어 모드 / Controlled mode\n * const [open, setOpen] = useState(false)\n * <ContextMenu \n * open={open}\n * onOpenChange={setOpen}\n * trigger={<div>우클릭</div>}\n * >\n * <Menu>\n * <MenuItem>복사</MenuItem>\n * <MenuItem>삭제</MenuItem>\n * </Menu>\n * </ContextMenu>\n * \n * @param {ContextMenuProps} props - ContextMenu 컴포넌트의 props / ContextMenu component props\n * @param {React.Ref<HTMLDivElement>} ref - div 요소 ref / div element ref\n * @returns {JSX.Element} ContextMenu 컴포넌트 / ContextMenu component\n */\nconst ContextMenu = React.forwardRef<HTMLDivElement, ContextMenuProps>(\n ({ \n className, \n children,\n open: controlledOpen,\n onOpenChange,\n trigger,\n placement: _placement = \"bottom\",\n align: _align = \"start\",\n offset: _offset = 8,\n disabled = false,\n ...props \n }, ref) => {\n const [internalOpen, setInternalOpen] = React.useState(false)\n const [coords, setCoords] = React.useState({ x: 0, y: 0 })\n const triggerRef = React.useRef<HTMLDivElement>(null)\n const menuRef = React.useRef<HTMLDivElement>(null)\n const isControlled = controlledOpen !== undefined\n const isOpen = isControlled ? controlledOpen : internalOpen\n\n const handleOpenChange = React.useCallback((newOpen: boolean) => {\n if (disabled) return\n\n if (!isControlled) {\n setInternalOpen(newOpen)\n }\n onOpenChange?.(newOpen)\n }, [disabled, isControlled, onOpenChange])\n\n const handleContextMenu = (event: React.MouseEvent) => {\n event.preventDefault()\n if (disabled) return\n\n const _rect = event.currentTarget.getBoundingClientRect()\n const x = event.clientX\n const y = event.clientY\n\n setCoords({ x, y })\n handleOpenChange(true)\n }\n\n const updatePosition = React.useCallback(() => {\n if (!menuRef.current) return\n\n const menuRect = menuRef.current.getBoundingClientRect()\n const viewportWidth = window.innerWidth\n const viewportHeight = window.innerHeight\n\n let x = coords.x\n let y = coords.y\n\n // 뷰포트 경계 확인 및 조정\n if (x + menuRect.width > viewportWidth - 8) {\n x = viewportWidth - menuRect.width - 8 // 8px 여백\n }\n if (y + menuRect.height > viewportHeight - 8) {\n y = viewportHeight - menuRect.height - 8 // 8px 여백\n }\n if (x < 8) x = 8 // 8px 여백\n if (y < 8) y = 8 // 8px 여백\n\n setCoords({ x, y })\n }, [coords.x, coords.y])\n\n React.useEffect(() => {\n if (isOpen) {\n updatePosition()\n window.addEventListener('resize', updatePosition)\n window.addEventListener('scroll', updatePosition)\n \n return () => {\n window.removeEventListener('resize', updatePosition)\n window.removeEventListener('scroll', updatePosition)\n }\n }\n }, [isOpen, updatePosition])\n\n React.useEffect(() => {\n const handleClickOutside = (event: MouseEvent) => {\n if (\n triggerRef.current &&\n menuRef.current &&\n !triggerRef.current.contains(event.target as Node) &&\n !menuRef.current.contains(event.target as Node)\n ) {\n handleOpenChange(false)\n }\n }\n\n if (isOpen) {\n document.addEventListener('mousedown', handleClickOutside)\n return () => {\n document.removeEventListener('mousedown', handleClickOutside)\n }\n }\n }, [isOpen, handleOpenChange])\n\n return (\n <div ref={ref} className={merge(\"relative\", className)} {...props}>\n {/* 트리거 */}\n {trigger && (\n <div\n ref={triggerRef}\n onContextMenu={handleContextMenu}\n className=\"inline-block\"\n >\n {trigger}\n </div>\n )}\n\n {/* 컨텍스트 메뉴 */}\n {isOpen && (\n <div\n ref={menuRef}\n className={merge(\n \"fixed z-50 bg-popover text-popover-foreground rounded-lg shadow-xl backdrop-blur-sm\", // 보더 대신 섀도우 사용\n \"min-w-[200px] py-2\", // 16px 패딩\n \"border-0\" // 보더 제거\n )}\n style={{\n left: coords.x,\n top: coords.y,\n boxShadow: \"0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)\"\n }}\n >\n {children}\n </div>\n )}\n </div>\n )\n }\n)\nContextMenu.displayName = \"ContextMenu\"\n\nexport interface ContextMenuItemProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n icon?: React.ReactNode\n variant?: \"default\" | \"destructive\" | \"disabled\"\n}\n\nconst ContextMenuItem = React.forwardRef<HTMLButtonElement, ContextMenuItemProps>(\n ({ \n className, \n icon,\n variant = \"default\",\n children,\n disabled,\n ...props \n }, ref) => {\n const getVariantClasses = () => {\n switch (variant) {\n case \"destructive\":\n return \"text-destructive hover:bg-destructive/10\"\n case \"disabled\":\n return \"text-muted-foreground cursor-not-allowed\"\n default:\n return \"text-foreground hover:bg-muted\"\n }\n }\n\n return (\n <button\n ref={ref}\n className={merge(\n \"w-full flex items-center gap-3 px-4 py-3 text-sm font-medium transition-colors duration-200 ease-in-out focus-visible:outline-none focus-visible:bg-muted\", // 16px, 12px 패딩\n getVariantClasses(),\n className\n )}\n disabled={disabled || variant === \"disabled\"}\n {...props}\n >\n {icon && (\n <div className=\"flex-shrink-0 w-4 h-4\">\n {icon}\n </div>\n )}\n <span className=\"flex-1 text-left\">{children}</span>\n </button>\n )\n }\n)\nContextMenuItem.displayName = \"ContextMenuItem\"\n\nexport interface ContextMenuSeparatorProps extends React.HTMLAttributes<HTMLDivElement> {}\n\nconst ContextMenuSeparator = React.forwardRef<HTMLDivElement, ContextMenuSeparatorProps>(\n ({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={merge(\"h-px bg-border my-2\", className)} // 8px 여백\n {...props}\n />\n )\n)\nContextMenuSeparator.displayName = \"ContextMenuSeparator\"\n\nexport interface ContextMenuLabelProps extends React.HTMLAttributes<HTMLDivElement> {}\n\nconst ContextMenuLabel = React.forwardRef<HTMLDivElement, ContextMenuLabelProps>(\n ({ className, children, ...props }, ref) => (\n <div\n ref={ref}\n className={merge(\"px-4 py-2 text-xs font-semibold text-muted-foreground uppercase tracking-wide\", className)} // 16px, 8px 패딩\n {...props}\n >\n {children}\n </div>\n )\n)\nContextMenuLabel.displayName = \"ContextMenuLabel\"\n\n// 편의 컴포넌트들\nconst ContextMenuGroup = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(\n ({ className, children, ...props }, ref) => (\n <div\n ref={ref}\n className={merge(\"py-1\", className)} // 4px 패딩\n {...props}\n >\n {children}\n </div>\n )\n)\nContextMenuGroup.displayName = \"ContextMenuGroup\"\n\nexport { ContextMenu, ContextMenuItem, ContextMenuSeparator, ContextMenuLabel, ContextMenuGroup } ","\"use client\"\n\nimport React from \"react\"\nimport { merge } from \"../lib/utils\"\n\n/**\n * Command 컴포넌트의 props / Command component props\n * @typedef {Object} CommandProps\n * @property {React.ReactNode} children - CommandList, CommandItem 등 / CommandList, CommandItem, etc.\n * @property {boolean} [open] - 제어 모드에서 열림/닫힘 상태 / Open/close state in controlled mode\n * @property {(open: boolean) => void} [onOpenChange] - 상태 변경 콜백 / State change callback\n * @property {string} [placeholder=\"명령어를 검색하세요...\"] - 검색 입력 플레이스홀더 / Search input placeholder\n * @property {string} [searchValue] - 제어 모드에서 검색 값 / Search value in controlled mode\n * @property {(value: string) => void} [onSearchChange] - 검색 값 변경 콜백 / Search value change callback\n * @property {boolean} [disabled=false] - Command 비활성화 여부 / Disable command\n * @extends {React.HTMLAttributes<HTMLDivElement>}\n */\nexport interface CommandProps extends React.HTMLAttributes<HTMLDivElement> {\n children: React.ReactNode\n open?: boolean\n onOpenChange?: (open: boolean) => void\n placeholder?: string\n searchValue?: string\n onSearchChange?: (value: string) => void\n disabled?: boolean\n}\n\n/**\n * Command 컴포넌트 / Command component\n * \n * 명령 팔레트(Command Palette) 컴포넌트입니다.\n * Cmd+K (Mac) 또는 Ctrl+K (Windows)로 열 수 있습니다.\n * 키보드 네비게이션(Arrow keys, Enter, Escape)을 지원합니다.\n * \n * Command Palette component.\n * Can be opened with Cmd+K (Mac) or Ctrl+K (Windows).\n * Supports keyboard navigation (Arrow keys, Enter, Escape).\n * \n * @component\n * @example\n * // 기본 사용 / Basic usage\n * <Command>\n * <CommandInput placeholder=\"검색...\" />\n * <CommandList>\n * <CommandItem>항목 1</CommandItem>\n * <CommandItem>항목 2</CommandItem>\n * </CommandList>\n * </Command>\n * \n * @example\n * // 제어 모드 / Controlled mode\n * const [open, setOpen] = useState(false)\n * <Command \n * open={open}\n * onOpenChange={setOpen}\n * >\n * <CommandList>\n * <CommandGroup heading=\"파일\">\n * <CommandItem>새 파일</CommandItem>\n * </CommandGroup>\n * </CommandList>\n * </Command>\n * \n * @param {CommandProps} props - Command 컴포넌트의 props / Command component props\n * @param {React.Ref<HTMLDivElement>} ref - div 요소 ref / div element ref\n * @returns {JSX.Element} Command 컴포넌트 / Command component\n */\nconst Command = React.forwardRef<HTMLDivElement, CommandProps>(\n ({ \n className, \n children,\n open: controlledOpen,\n onOpenChange,\n placeholder = \"명령어를 검색하세요...\",\n searchValue: controlledSearchValue,\n onSearchChange,\n disabled = false,\n ...props \n }, ref) => {\n const [internalOpen, setInternalOpen] = React.useState(false)\n const [internalSearchValue, setInternalSearchValue] = React.useState(\"\")\n const [selectedIndex, setSelectedIndex] = React.useState(0)\n const commandRef = React.useRef<HTMLDivElement>(null)\n const inputRef = React.useRef<HTMLInputElement>(null)\n const listRef = React.useRef<HTMLDivElement>(null)\n \n const isControlled = controlledOpen !== undefined\n const isOpen = isControlled ? controlledOpen : internalOpen\n const searchValue = controlledSearchValue !== undefined ? controlledSearchValue : internalSearchValue\n\n const handleOpenChange = React.useCallback((newOpen: boolean) => {\n if (disabled) return\n\n if (!isControlled) {\n setInternalOpen(newOpen)\n }\n onOpenChange?.(newOpen)\n }, [disabled, isControlled, onOpenChange])\n\n const handleSearchChange = (value: string) => {\n if (!isControlled) {\n setInternalSearchValue(value)\n }\n onSearchChange?.(value)\n setSelectedIndex(0)\n }\n\n const handleKeyDown = (event: React.KeyboardEvent) => {\n if (disabled) return\n\n const items = listRef.current?.querySelectorAll('[data-command-item]')\n const itemCount = items?.length || 0\n\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault()\n setSelectedIndex((prev) => (prev + 1) % itemCount)\n break\n case 'ArrowUp':\n event.preventDefault()\n setSelectedIndex((prev) => (prev - 1 + itemCount) % itemCount)\n break\n case 'Enter': {\n event.preventDefault()\n const selectedItem = items?.[selectedIndex] as HTMLElement\n selectedItem?.click()\n break\n }\n case 'Escape':\n event.preventDefault()\n handleOpenChange(false)\n break\n }\n }\n\n React.useEffect(() => {\n if (isOpen) {\n inputRef.current?.focus()\n setSelectedIndex(0)\n }\n }, [isOpen])\n\n React.useEffect(() => {\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'k' && (event.metaKey || event.ctrlKey)) {\n event.preventDefault()\n handleOpenChange(!isOpen)\n }\n // 전역 ESC 키 처리\n if (event.key === 'Escape' && isOpen) {\n event.preventDefault()\n handleOpenChange(false)\n }\n }\n\n document.addEventListener('keydown', handleKeyDown)\n return () => {\n document.removeEventListener('keydown', handleKeyDown)\n }\n }, [isOpen, handleOpenChange])\n\n React.useEffect(() => {\n const selectedItem = listRef.current?.querySelector(`[data-command-item]:nth-child(${selectedIndex + 1})`) as HTMLElement\n selectedItem?.scrollIntoView({ block: 'nearest' })\n }, [selectedIndex])\n\n return (\n <div ref={ref} className={merge(\"relative\", className)} {...props}>\n {isOpen && (\n <div\n ref={commandRef}\n className={merge(\n \"fixed inset-0 z-50 bg-black/50 backdrop-blur-sm\", // 50% 투명도\n \"flex items-start justify-center pt-16\" // 64px 상단 여백\n )}\n onClick={() => handleOpenChange(false)}\n >\n <div\n className={merge(\n \"w-full max-w-2xl mx-4 bg-popover text-popover-foreground rounded-lg shadow-2xl\", // 보더 대신 섀도우\n \"border-0 overflow-hidden\" // 보더 제거\n )}\n onClick={(e) => e.stopPropagation()}\n style={{\n boxShadow: \"0 25px 50px -12px rgba(0, 0, 0, 0.25)\"\n }}\n >\n <div className=\"p-4 border-b border-border\"> {/* 16px 패딩 */}\n <input\n ref={inputRef}\n type=\"text\"\n placeholder={placeholder}\n value={searchValue}\n onChange={(e) => handleSearchChange(e.target.value)}\n onKeyDown={handleKeyDown}\n className={merge(\n \"w-full bg-transparent text-lg font-medium outline-none\", // 18px 텍스트\n \"placeholder:text-muted-foreground\",\n \"text-foreground\"\n )}\n />\n </div>\n \n <div\n ref={listRef}\n className=\"max-h-96 overflow-y-auto py-2\" // 384px 최대 높이, 8px 패딩\n >\n {React.Children.map(children, (child, index) => {\n if (React.isValidElement<CommandItemProps>(child)) {\n // Fragment나 다른 컴포넌트에 selected prop 전달 방지\n if (child.type === React.Fragment || typeof child.type === 'symbol') {\n return child\n }\n return React.cloneElement(child, {\n selected: index === selectedIndex,\n onSelect: () => {\n child.props.onSelect?.()\n handleOpenChange(false)\n }\n })\n }\n return child\n })}\n </div>\n </div>\n </div>\n )}\n </div>\n )\n }\n)\nCommand.displayName = \"Command\"\n\n/**\n * CommandInput 컴포넌트의 props / CommandInput component props\n * @typedef {Object} CommandInputProps\n * @extends {React.InputHTMLAttributes<HTMLInputElement>}\n */\nexport interface CommandInputProps extends React.InputHTMLAttributes<HTMLInputElement> {}\n\nconst CommandInput = React.forwardRef<HTMLInputElement, CommandInputProps>(\n ({ className, ...props }, ref) => (\n <input\n ref={ref}\n className={merge(\n \"flex h-10 w-full rounded-md bg-transparent px-3 py-2 text-sm outline-none\", // 40px 높이, 12px, 8px 패딩\n \"placeholder:text-muted-foreground\",\n \"disabled:cursor-not-allowed disabled:opacity-50\",\n className\n )}\n {...props}\n />\n )\n)\nCommandInput.displayName = \"CommandInput\"\n\nexport interface CommandListProps extends React.HTMLAttributes<HTMLDivElement> {}\n\nconst CommandList = React.forwardRef<HTMLDivElement, CommandListProps>(\n ({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={merge(\"max-h-96 overflow-y-auto py-2\", className)} // 384px 최대 높이, 8px 패딩\n {...props}\n />\n )\n)\nCommandList.displayName = \"CommandList\"\n\n/**\n * CommandItem 컴포넌트의 props / CommandItem component props\n * @typedef {Object} CommandItemProps\n * @property {React.ReactNode} [icon] - 항목 아이콘 / Item icon\n * @property {boolean} [selected=false] - 선택 상태 / Selected state\n * @property {() => void} [onSelect] - 선택 시 콜백 / Selection callback\n * @extends {React.ButtonHTMLAttributes<HTMLButtonElement>}\n */\nexport interface CommandItemProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n icon?: React.ReactNode\n selected?: boolean\n onSelect?: () => void\n}\n\nconst CommandItem = React.forwardRef<HTMLButtonElement, CommandItemProps>(\n ({ \n className, \n icon,\n selected = false,\n onSelect,\n children,\n ...props \n }, ref) => {\n return (\n <button\n ref={ref}\n data-command-item\n className={merge(\n \"relative flex w-full items-center gap-3 rounded-sm px-4 py-3 text-sm\", // 16px, 12px 패딩\n \"text-foreground\",\n \"hover:bg-muted\",\n \"focus:bg-muted\",\n \"focus:outline-none\",\n selected && \"bg-muted\",\n \"transition-colors\",\n className\n )}\n onClick={onSelect}\n {...props}\n >\n {icon && (\n <div className=\"flex-shrink-0 w-4 h-4 text-muted-foreground\">\n {icon}\n </div>\n )}\n <span className=\"flex-1 text-left\">{children}</span>\n </button>\n )\n }\n)\nCommandItem.displayName = \"CommandItem\"\n\n/**\n * CommandGroup 컴포넌트의 props / CommandGroup component props\n * @typedef {Object} CommandGroupProps\n * @property {React.ReactNode} [heading] - 그룹 제목 / Group heading\n * @extends {React.HTMLAttributes<HTMLDivElement>}\n */\nexport interface CommandGroupProps extends React.HTMLAttributes<HTMLDivElement> {\n heading?: React.ReactNode\n}\n\nconst CommandGroup = React.forwardRef<HTMLDivElement, CommandGroupProps>(\n ({ className, heading, children, ...props }, ref) => (\n <div ref={ref} className={merge(\"py-2\", className)} {...props}> {/* 8px 패딩 */}\n {heading && (\n <div className=\"px-4 py-2 text-xs font-semibold text-muted-foreground uppercase tracking-wide\"> {/* 16px, 8px 패딩 */}\n {heading}\n </div>\n )}\n <div className=\"space-y-1\"> {/* 4px 간격 */}\n {children}\n </div>\n </div>\n )\n)\nCommandGroup.displayName = \"CommandGroup\"\n\n/**\n * CommandSeparator 컴포넌트의 props / CommandSeparator component props\n * @typedef {Object} CommandSeparatorProps\n * @extends {React.HTMLAttributes<HTMLDivElement>}\n */\nexport interface CommandSeparatorProps extends React.HTMLAttributes<HTMLDivElement> {}\n\nconst CommandSeparator = React.forwardRef<HTMLDivElement, CommandSeparatorProps>(\n ({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={merge(\"h-px bg-border my-2\", className)} // 8px 여백\n {...props}\n />\n )\n)\nCommandSeparator.displayName = \"CommandSeparator\"\n\n/**\n * CommandEmpty 컴포넌트의 props / CommandEmpty component props\n * @typedef {Object} CommandEmptyProps\n * @extends {React.HTMLAttributes<HTMLDivElement>}\n */\nexport interface CommandEmptyProps extends React.HTMLAttributes<HTMLDivElement> {}\n\nconst CommandEmpty = React.forwardRef<HTMLDivElement, CommandEmptyProps>(\n ({ className, children = \"결과가 없습니다.\", ...props }, ref) => (\n <div\n ref={ref}\n className={merge(\n \"py-8 text-center text-sm text-muted-foreground\", // 32px 패딩\n className\n )}\n {...props}\n >\n {children}\n </div>\n )\n)\nCommandEmpty.displayName = \"CommandEmpty\"\n\n// 편의 컴포넌트들\nexport const CommandDialog = React.forwardRef<HTMLDivElement, CommandProps>(\n ({ className, ...props }, ref) => (\n <Command ref={ref} className={className} {...props} />\n )\n)\nCommandDialog.displayName = \"CommandDialog\"\n\nexport { Command, CommandInput, CommandList, CommandItem, CommandGroup, CommandSeparator, CommandEmpty } "]}
|
package/dist/landing.mjs
CHANGED
|
@@ -1,29 +1,29 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import {b as b$1}from'./chunk-Z74YUUVT.mjs';import {a as a$1}from'./chunk-CVWWS25A.mjs';import {a as a$4}from'./chunk-4NJE7D6X.mjs';import {a as a$3}from'./chunk-IJSYSNM5.mjs';import {d,a as a$2,e,c,b as b$2}from'./chunk-LSA7DU3N.mjs';import {a as a$5}from'./chunk-6HVJFEDA.mjs';import {l}from'./chunk-7OYT3QSY.mjs';import {a,b}from'./chunk-U6CTBZ2U.mjs';import {createContext,useContext,useMemo,useState,useEffect,useRef,useCallback}from'react';import {jsx,jsxs}from'react/jsx-runtime';var oe={name:"corporate",colors:{background:"0 0% 100%",foreground:"222 47% 11%",muted:"210 40% 96%",mutedForeground:"215 16% 47%",primary:"217 91% 53%",primaryForeground:"0 0% 100%",secondary:"215 16% 93%",secondaryForeground:"222 47% 11%",card:"0 0% 100%",cardForeground:"222 47% 11%",border:"214 32% 91%",sectionAlt:"210 40% 98%"},hero:{background:"gradient",size:"xl",motion:{type:"fadeIn",duration:900,easing:"ease-out",delay:0}},features:{card:"spotlight",staggerDelay:150,motion:{type:"fadeIn",duration:900,easing:"ease-out",delay:0},decorator:true},stats:{numberSize:"text-4xl",countUp:false,staggerDelay:150,motion:{type:"fadeIn",duration:900,easing:"ease-out",delay:0}},cta:{background:"gradient-soft",motion:{type:"fadeIn",duration:900,easing:"ease-out",delay:0}},testimonials:{variant:"grid",staggerDelay:150,motion:{type:"fadeIn",duration:900,easing:"ease-out",delay:0}},logoCloud:{variant:"grid",speed:40},showcase:{staggerDelay:150,motion:{type:"fadeIn",duration:900,easing:"ease-out",delay:0}}};var ie={name:"marketing",colors:{background:"260 100% 4%",foreground:"0 0% 100%",muted:"270 30% 10%",mutedForeground:"240 4% 65%",primary:"258 90% 66%",primaryForeground:"0 0% 100%",secondary:"258 30% 15%",secondaryForeground:"0 0% 95%",card:"260 40% 10%",cardForeground:"0 0% 100%",border:"258 40% 20%",sectionAlt:"270 50% 6%"},hero:{background:"animated-gradient",size:"full",motion:{type:"bounceIn",duration:500,easing:"cubic-bezier(0.34, 1.56, 0.64, 1)",delay:0}},features:{card:"glow",staggerDelay:80,motion:{type:"bounceIn",duration:500,easing:"cubic-bezier(0.34, 1.56, 0.64, 1)",delay:0},decorator:false},stats:{numberSize:"text-5xl",countUp:true,staggerDelay:80,motion:{type:"bounceIn",duration:500,easing:"cubic-bezier(0.34, 1.56, 0.64, 1)",delay:0}},cta:{background:"animated-gradient",motion:{type:"bounceIn",duration:500,easing:"cubic-bezier(0.34, 1.56, 0.64, 1)",delay:0}},testimonials:{variant:"carousel",staggerDelay:80,motion:{type:"bounceIn",duration:500,easing:"cubic-bezier(0.34, 1.56, 0.64, 1)",delay:0}},logoCloud:{variant:"marquee",speed:60},showcase:{staggerDelay:80,motion:{type:"bounceIn",duration:500,easing:"cubic-bezier(0.34, 1.56, 0.64, 1)",delay:0}}};var se={name:"product",colors:{background:"240 6% 4%",foreground:"0 0% 98%",muted:"240 5% 11%",mutedForeground:"240 4% 64%",primary:"188 96% 42%",primaryForeground:"0 0% 100%",secondary:"188 20% 12%",secondaryForeground:"0 0% 98%",card:"240 5% 10%",cardForeground:"0 0% 98%",border:"240 4% 16%",sectionAlt:"240 6% 7%"},hero:{background:"dark",size:"full",motion:{type:"slideUp",duration:700,easing:"ease-in-out",delay:0}},features:{card:"feature-glass",staggerDelay:120,motion:{type:"slideUp",duration:700,easing:"ease-in-out",delay:0},decorator:false},stats:{numberSize:"text-6xl",countUp:true,staggerDelay:120,motion:{type:"slideUp",duration:700,easing:"ease-in-out",delay:0}},cta:{background:"dark",motion:{type:"slideUp",duration:700,easing:"ease-in-out",delay:0}},testimonials:{variant:"carousel",staggerDelay:120,motion:{type:"slideUp",duration:700,easing:"ease-in-out",delay:0}},logoCloud:{variant:"marquee",speed:40},showcase:{staggerDelay:120,motion:{type:"slideUp",duration:700,easing:"ease-in-out",delay:0}}};var de={name:"dashboard",colors:{background:"222 47% 11%",foreground:"214 32% 91%",muted:"222 42% 16%",mutedForeground:"215 20% 65%",primary:"217 91% 60%",primaryForeground:"0 0% 100%",secondary:"217 30% 18%",secondaryForeground:"214 32% 91%",card:"222 47% 14%",cardForeground:"214 32% 91%",border:"217 30% 22%",sectionAlt:"222 42% 14%"},hero:{background:"gradient",size:"xl",motion:{type:"fadeIn",duration:650,easing:"ease-out",delay:0}},features:{card:"feature-glass",staggerDelay:100,motion:{type:"scaleIn",duration:650,easing:"ease-out",delay:0},decorator:false},stats:{numberSize:"text-4xl",countUp:true,staggerDelay:100,motion:{type:"fadeIn",duration:650,easing:"ease-out",delay:0}},cta:{background:"gradient-soft",motion:{type:"fadeIn",duration:650,easing:"ease-out",delay:0}},testimonials:{variant:"grid",staggerDelay:100,motion:{type:"scaleIn",duration:650,easing:"ease-out",delay:0}},logoCloud:{variant:"marquee",speed:45},showcase:{staggerDelay:100,motion:{type:"scaleIn",duration:650,easing:"ease-out",delay:0}}};var le={name:"app",colors:{background:"0 0% 100%",foreground:"215 28% 17%",muted:"270 100% 96%",mutedForeground:"220 9% 46%",primary:"258 90% 66%",primaryForeground:"0 0% 100%",secondary:"258 20% 93%",secondaryForeground:"215 28% 17%",card:"0 0% 100%",cardForeground:"215 28% 17%",border:"220 13% 91%",sectionAlt:"270 100% 98%"},hero:{background:"gradient",size:"full",motion:{type:"slideUp",duration:600,easing:"cubic-bezier(0.22, 1, 0.36, 1)",delay:0}},features:{card:"feature-glass",staggerDelay:120,motion:{type:"slideUp",duration:600,easing:"cubic-bezier(0.22, 1, 0.36, 1)",delay:0},decorator:false},stats:{numberSize:"text-5xl",countUp:true,staggerDelay:120,motion:{type:"slideUp",duration:600,easing:"cubic-bezier(0.22, 1, 0.36, 1)",delay:0}},cta:{background:"gradient-soft",motion:{type:"bounceIn",duration:500,easing:"cubic-bezier(0.34, 1.56, 0.64, 1)",delay:0}},testimonials:{variant:"carousel",staggerDelay:120,motion:{type:"slideUp",duration:600,easing:"cubic-bezier(0.22, 1, 0.36, 1)",delay:0}},logoCloud:{variant:"marquee",speed:50},showcase:{staggerDelay:120,motion:{type:"slideUp",duration:600,easing:"cubic-bezier(0.22, 1, 0.36, 1)",delay:0}}};var ce={name:"immersive",colors:{background:"0 0% 0%",foreground:"0 0% 100%",muted:"0 0% 7%",mutedForeground:"0 0% 45%",primary:"252 92% 76%",primaryForeground:"0 0% 100%",secondary:"252 15% 12%",secondaryForeground:"0 0% 95%",card:"0 0% 5%",cardForeground:"0 0% 100%",border:"0 0% 10%",sectionAlt:"0 0% 4%"},hero:{background:"dark",size:"full",motion:{type:"fadeIn",duration:1200,easing:"cubic-bezier(0.16, 1, 0.3, 1)",delay:0}},features:{card:"glow",staggerDelay:200,motion:{type:"slideUp",duration:900,easing:"cubic-bezier(0.16, 1, 0.3, 1)",delay:0},decorator:false},stats:{numberSize:"text-6xl",countUp:true,staggerDelay:200,motion:{type:"fadeIn",duration:1200,easing:"cubic-bezier(0.16, 1, 0.3, 1)",delay:0}},cta:{background:"dark",motion:{type:"fadeIn",duration:1200,easing:"cubic-bezier(0.16, 1, 0.3, 1)",delay:0}},testimonials:{variant:"marquee",staggerDelay:200,motion:{type:"fadeIn",duration:1200,easing:"cubic-bezier(0.16, 1, 0.3, 1)",delay:0}},logoCloud:{variant:"marquee",speed:30},showcase:{staggerDelay:200,motion:{type:"slideUp",duration:900,easing:"cubic-bezier(0.16, 1, 0.3, 1)",delay:0}}};var me={name:"portfolio",colors:{background:"0 0% 4%",foreground:"0 0% 98%",muted:"0 0% 10%",mutedForeground:"0 0% 64%",primary:"25 95% 53%",primaryForeground:"0 0% 100%",secondary:"25 20% 12%",secondaryForeground:"0 0% 98%",card:"0 0% 8%",cardForeground:"0 0% 98%",border:"25 30% 15%",sectionAlt:"0 0% 6%"},hero:{background:"dark",size:"full",motion:{type:"slideUp",duration:800,easing:"cubic-bezier(0.22, 1, 0.36, 1)",delay:0}},features:{card:"feature-glass",staggerDelay:100,motion:{type:"slideUp",duration:700,easing:"cubic-bezier(0.22, 1, 0.36, 1)",delay:0},decorator:false},stats:{numberSize:"text-5xl",countUp:true,staggerDelay:100,motion:{type:"slideUp",duration:700,easing:"cubic-bezier(0.22, 1, 0.36, 1)",delay:0}},cta:{background:"dark",motion:{type:"slideUp",duration:700,easing:"cubic-bezier(0.22, 1, 0.36, 1)",delay:0}},testimonials:{variant:"grid",staggerDelay:100,motion:{type:"slideUp",duration:700,easing:"cubic-bezier(0.22, 1, 0.36, 1)",delay:0}},logoCloud:{variant:"grid",speed:40},showcase:{staggerDelay:100,motion:{type:"slideUp",duration:700,easing:"cubic-bezier(0.22, 1, 0.36, 1)",delay:0}}};var Ee={corporate:oe,marketing:ie,product:se,dashboard:de,app:le,immersive:ce,portfolio:me};function ue(e){return typeof e=="string"?Ee[e]:e}function Be(e,t){let n=Ee[e];return {...n,name:t.name,colors:{...n.colors,...t.colors},hero:{...n.hero,...t.hero},features:{...n.features,...t.features},stats:{...n.stats,...t.stats},cta:{...n.cta,...t.cta},testimonials:{...n.testimonials,...t.testimonials},logoCloud:{...n.logoCloud,...t.logoCloud},showcase:{...n.showcase,...t.showcase}}}var je=createContext(null);function h(){let e=useContext(je);if(!e)throw new Error("useLandingTheme must be used within <Landing.Provider>");return e}function Ke(e){return {"--color-primary":`hsl(${e.primary})`,"--color-primary-foreground":`hsl(${e.primaryForeground})`,"--color-background":`hsl(${e.background})`,"--color-foreground":`hsl(${e.foreground})`,"--color-muted":`hsl(${e.muted})`,"--color-muted-foreground":`hsl(${e.mutedForeground})`,"--color-secondary":`hsl(${e.secondary})`,"--color-secondary-foreground":`hsl(${e.secondaryForeground})`,"--color-card":`hsl(${e.card})`,"--color-card-foreground":`hsl(${e.cardForeground})`,"--color-border":`hsl(${e.border})`,"--color-input":`hsl(${e.border})`,"--color-ring":`hsl(${e.primary})`,"--primary":e.primary,"--primary-foreground":e.primaryForeground,"--background":e.background,"--foreground":e.foreground,"--muted":e.muted,"--muted-foreground":e.mutedForeground,"--secondary":e.secondary,"--secondary-foreground":e.secondaryForeground,"--card":e.card,"--card-foreground":e.cardForeground,"--border":e.border,"--input":e.border,"--ring":e.primary,"--landing-section-alt":`hsl(${e.sectionAlt})`}}function ge({theme:e,children:t}){let n=useMemo(()=>ue(e),[e]),s=useMemo(()=>({backgroundColor:`hsl(${n.colors.background})`,color:`hsl(${n.colors.foreground})`,...Ke(n.colors)}),[n.colors]);return jsx(je.Provider,{value:n,children:jsx("div",{style:s,children:t})})}function Ze(e,t){return t?{...e,...t}:e}function et(e){switch(e){case "slideUp":return "translateY(32px)";case "slideLeft":return "translateX(-32px)";case "slideRight":return "translateX(32px)";case "scaleIn":return "scale(0.95)";case "bounceIn":return "scale(0.75)";default:return "none"}}function fe({title:e,subtitle:t,description:n,primaryAction:s,secondaryAction:d$1,size:m,background:g,gradientColors:u,scrollIndicator:o=false,motion:c,className:i,...r}){let a=h(),l=m!=null?m:a.hero.size,p=g!=null?g:a.hero.background,y=Ze(a.hero.motion,c),f=useMemo(()=>({opacity:0,transform:et(y.type),animation:`landing-hero-enter ${y.duration}ms ${y.easing} ${y.delay}ms forwards`}),[y]);return jsxs("section",{className:b("relative overflow-hidden flex items-center justify-center",l==="full"?"min-h-screen":"py-28 sm:py-36",p==="dark"&&"bg-gray-950 text-white",i),...r,children:[p==="gradient"&&jsx("div",{className:"absolute inset-0 gradient-bg-soft","aria-hidden":"true"}),p==="animated-gradient"&&jsx(d,{colors:u,type:"mesh",className:"absolute inset-0 -z-0","aria-hidden":"true"}),p==="dark"&&jsx("div",{className:"absolute inset-0",style:{background:"radial-gradient(ellipse 80% 60% at 50% 40%, rgba(120, 119, 198, 0.08), transparent)"},"aria-hidden":"true"}),jsx(a$1,{size:"lg",padding:"none",centered:true,className:"relative z-10 px-6",children:jsxs("div",{style:f,className:"text-center max-w-4xl mx-auto",children:[jsx("h1",{className:"text-4xl sm:text-5xl md:text-6xl lg:text-7xl font-extrabold tracking-tight mb-6",children:e}),t&&jsx("p",{className:"text-xl sm:text-2xl text-muted-foreground mb-4",children:t}),n&&jsx("p",{className:"text-base sm:text-lg text-muted-foreground/80 max-w-2xl mx-auto mb-8",children:n}),(s||d$1)&&jsxs("div",{className:"flex flex-col sm:flex-row items-center justify-center gap-4",children:[s,d$1]})]})}),o&&jsx("div",{className:"absolute bottom-8 left-1/2 -translate-x-1/2 animate-bounce","aria-hidden":"true",children:jsx("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:"text-muted-foreground",children:jsx("path",{d:"M12 5v14M5 12l7 7 7-7"})})}),jsx("style",{dangerouslySetInnerHTML:{__html:`
|
|
2
|
+
import {b}from'./chunk-VBABZXL7.mjs';import {a as a$1}from'./chunk-SDFVGFXT.mjs';import {a as a$5}from'./chunk-FHMFDCX2.mjs';import {a as a$4}from'./chunk-K2FOFIST.mjs';import {d,a as a$3,e,c,b as b$1}from'./chunk-Q76JW7X5.mjs';import {a as a$6}from'./chunk-CW66UBQG.mjs';import'./chunk-SD6XGDAC.mjs';import {l}from'./chunk-ZQUMJQYV.mjs';import {a as a$2}from'./chunk-QEMPERUK.mjs';import {a}from'./chunk-EAZEI74V.mjs';import {createContext,useContext,useMemo,useState,useEffect,useRef,useCallback}from'react';import {jsx,jsxs}from'react/jsx-runtime';var oe={name:"corporate",colors:{background:"0 0% 100%",foreground:"222 47% 11%",muted:"210 40% 96%",mutedForeground:"215 16% 47%",primary:"217 91% 53%",primaryForeground:"0 0% 100%",secondary:"215 16% 93%",secondaryForeground:"222 47% 11%",card:"0 0% 100%",cardForeground:"222 47% 11%",border:"214 32% 91%",sectionAlt:"210 40% 98%"},hero:{background:"gradient",size:"xl",motion:{type:"fadeIn",duration:900,easing:"ease-out",delay:0}},features:{card:"spotlight",staggerDelay:150,motion:{type:"fadeIn",duration:900,easing:"ease-out",delay:0},decorator:true},stats:{numberSize:"text-4xl",countUp:false,staggerDelay:150,motion:{type:"fadeIn",duration:900,easing:"ease-out",delay:0}},cta:{background:"gradient-soft",motion:{type:"fadeIn",duration:900,easing:"ease-out",delay:0}},testimonials:{variant:"grid",staggerDelay:150,motion:{type:"fadeIn",duration:900,easing:"ease-out",delay:0}},logoCloud:{variant:"grid",speed:40},showcase:{staggerDelay:150,motion:{type:"fadeIn",duration:900,easing:"ease-out",delay:0}}};var ie={name:"marketing",colors:{background:"260 100% 4%",foreground:"0 0% 100%",muted:"270 30% 10%",mutedForeground:"240 4% 65%",primary:"258 90% 66%",primaryForeground:"0 0% 100%",secondary:"258 30% 15%",secondaryForeground:"0 0% 95%",card:"260 40% 10%",cardForeground:"0 0% 100%",border:"258 40% 20%",sectionAlt:"270 50% 6%"},hero:{background:"animated-gradient",size:"full",motion:{type:"bounceIn",duration:500,easing:"cubic-bezier(0.34, 1.56, 0.64, 1)",delay:0}},features:{card:"glow",staggerDelay:80,motion:{type:"bounceIn",duration:500,easing:"cubic-bezier(0.34, 1.56, 0.64, 1)",delay:0},decorator:false},stats:{numberSize:"text-5xl",countUp:true,staggerDelay:80,motion:{type:"bounceIn",duration:500,easing:"cubic-bezier(0.34, 1.56, 0.64, 1)",delay:0}},cta:{background:"animated-gradient",motion:{type:"bounceIn",duration:500,easing:"cubic-bezier(0.34, 1.56, 0.64, 1)",delay:0}},testimonials:{variant:"carousel",staggerDelay:80,motion:{type:"bounceIn",duration:500,easing:"cubic-bezier(0.34, 1.56, 0.64, 1)",delay:0}},logoCloud:{variant:"marquee",speed:60},showcase:{staggerDelay:80,motion:{type:"bounceIn",duration:500,easing:"cubic-bezier(0.34, 1.56, 0.64, 1)",delay:0}}};var se={name:"product",colors:{background:"240 6% 4%",foreground:"0 0% 98%",muted:"240 5% 11%",mutedForeground:"240 4% 64%",primary:"188 96% 42%",primaryForeground:"0 0% 100%",secondary:"188 20% 12%",secondaryForeground:"0 0% 98%",card:"240 5% 10%",cardForeground:"0 0% 98%",border:"240 4% 16%",sectionAlt:"240 6% 7%"},hero:{background:"dark",size:"full",motion:{type:"slideUp",duration:700,easing:"ease-in-out",delay:0}},features:{card:"feature-glass",staggerDelay:120,motion:{type:"slideUp",duration:700,easing:"ease-in-out",delay:0},decorator:false},stats:{numberSize:"text-6xl",countUp:true,staggerDelay:120,motion:{type:"slideUp",duration:700,easing:"ease-in-out",delay:0}},cta:{background:"dark",motion:{type:"slideUp",duration:700,easing:"ease-in-out",delay:0}},testimonials:{variant:"carousel",staggerDelay:120,motion:{type:"slideUp",duration:700,easing:"ease-in-out",delay:0}},logoCloud:{variant:"marquee",speed:40},showcase:{staggerDelay:120,motion:{type:"slideUp",duration:700,easing:"ease-in-out",delay:0}}};var de={name:"dashboard",colors:{background:"222 47% 11%",foreground:"214 32% 91%",muted:"222 42% 16%",mutedForeground:"215 20% 65%",primary:"217 91% 60%",primaryForeground:"0 0% 100%",secondary:"217 30% 18%",secondaryForeground:"214 32% 91%",card:"222 47% 14%",cardForeground:"214 32% 91%",border:"217 30% 22%",sectionAlt:"222 42% 14%"},hero:{background:"gradient",size:"xl",motion:{type:"fadeIn",duration:650,easing:"ease-out",delay:0}},features:{card:"feature-glass",staggerDelay:100,motion:{type:"scaleIn",duration:650,easing:"ease-out",delay:0},decorator:false},stats:{numberSize:"text-4xl",countUp:true,staggerDelay:100,motion:{type:"fadeIn",duration:650,easing:"ease-out",delay:0}},cta:{background:"gradient-soft",motion:{type:"fadeIn",duration:650,easing:"ease-out",delay:0}},testimonials:{variant:"grid",staggerDelay:100,motion:{type:"scaleIn",duration:650,easing:"ease-out",delay:0}},logoCloud:{variant:"marquee",speed:45},showcase:{staggerDelay:100,motion:{type:"scaleIn",duration:650,easing:"ease-out",delay:0}}};var le={name:"app",colors:{background:"0 0% 100%",foreground:"215 28% 17%",muted:"270 100% 96%",mutedForeground:"220 9% 46%",primary:"258 90% 66%",primaryForeground:"0 0% 100%",secondary:"258 20% 93%",secondaryForeground:"215 28% 17%",card:"0 0% 100%",cardForeground:"215 28% 17%",border:"220 13% 91%",sectionAlt:"270 100% 98%"},hero:{background:"gradient",size:"full",motion:{type:"slideUp",duration:600,easing:"cubic-bezier(0.22, 1, 0.36, 1)",delay:0}},features:{card:"feature-glass",staggerDelay:120,motion:{type:"slideUp",duration:600,easing:"cubic-bezier(0.22, 1, 0.36, 1)",delay:0},decorator:false},stats:{numberSize:"text-5xl",countUp:true,staggerDelay:120,motion:{type:"slideUp",duration:600,easing:"cubic-bezier(0.22, 1, 0.36, 1)",delay:0}},cta:{background:"gradient-soft",motion:{type:"bounceIn",duration:500,easing:"cubic-bezier(0.34, 1.56, 0.64, 1)",delay:0}},testimonials:{variant:"carousel",staggerDelay:120,motion:{type:"slideUp",duration:600,easing:"cubic-bezier(0.22, 1, 0.36, 1)",delay:0}},logoCloud:{variant:"marquee",speed:50},showcase:{staggerDelay:120,motion:{type:"slideUp",duration:600,easing:"cubic-bezier(0.22, 1, 0.36, 1)",delay:0}}};var ce={name:"immersive",colors:{background:"0 0% 0%",foreground:"0 0% 100%",muted:"0 0% 7%",mutedForeground:"0 0% 45%",primary:"252 92% 76%",primaryForeground:"0 0% 100%",secondary:"252 15% 12%",secondaryForeground:"0 0% 95%",card:"0 0% 5%",cardForeground:"0 0% 100%",border:"0 0% 10%",sectionAlt:"0 0% 4%"},hero:{background:"dark",size:"full",motion:{type:"fadeIn",duration:1200,easing:"cubic-bezier(0.16, 1, 0.3, 1)",delay:0}},features:{card:"glow",staggerDelay:200,motion:{type:"slideUp",duration:900,easing:"cubic-bezier(0.16, 1, 0.3, 1)",delay:0},decorator:false},stats:{numberSize:"text-6xl",countUp:true,staggerDelay:200,motion:{type:"fadeIn",duration:1200,easing:"cubic-bezier(0.16, 1, 0.3, 1)",delay:0}},cta:{background:"dark",motion:{type:"fadeIn",duration:1200,easing:"cubic-bezier(0.16, 1, 0.3, 1)",delay:0}},testimonials:{variant:"marquee",staggerDelay:200,motion:{type:"fadeIn",duration:1200,easing:"cubic-bezier(0.16, 1, 0.3, 1)",delay:0}},logoCloud:{variant:"marquee",speed:30},showcase:{staggerDelay:200,motion:{type:"slideUp",duration:900,easing:"cubic-bezier(0.16, 1, 0.3, 1)",delay:0}}};var me={name:"portfolio",colors:{background:"0 0% 4%",foreground:"0 0% 98%",muted:"0 0% 10%",mutedForeground:"0 0% 64%",primary:"25 95% 53%",primaryForeground:"0 0% 100%",secondary:"25 20% 12%",secondaryForeground:"0 0% 98%",card:"0 0% 8%",cardForeground:"0 0% 98%",border:"25 30% 15%",sectionAlt:"0 0% 6%"},hero:{background:"dark",size:"full",motion:{type:"slideUp",duration:800,easing:"cubic-bezier(0.22, 1, 0.36, 1)",delay:0}},features:{card:"feature-glass",staggerDelay:100,motion:{type:"slideUp",duration:700,easing:"cubic-bezier(0.22, 1, 0.36, 1)",delay:0},decorator:false},stats:{numberSize:"text-5xl",countUp:true,staggerDelay:100,motion:{type:"slideUp",duration:700,easing:"cubic-bezier(0.22, 1, 0.36, 1)",delay:0}},cta:{background:"dark",motion:{type:"slideUp",duration:700,easing:"cubic-bezier(0.22, 1, 0.36, 1)",delay:0}},testimonials:{variant:"grid",staggerDelay:100,motion:{type:"slideUp",duration:700,easing:"cubic-bezier(0.22, 1, 0.36, 1)",delay:0}},logoCloud:{variant:"grid",speed:40},showcase:{staggerDelay:100,motion:{type:"slideUp",duration:700,easing:"cubic-bezier(0.22, 1, 0.36, 1)",delay:0}}};var Ee={corporate:oe,marketing:ie,product:se,dashboard:de,app:le,immersive:ce,portfolio:me};function ue(e){return typeof e=="string"?Ee[e]:e}function Be(e,t){let n=Ee[e];return {...n,name:t.name,colors:{...n.colors,...t.colors},hero:{...n.hero,...t.hero},features:{...n.features,...t.features},stats:{...n.stats,...t.stats},cta:{...n.cta,...t.cta},testimonials:{...n.testimonials,...t.testimonials},logoCloud:{...n.logoCloud,...t.logoCloud},showcase:{...n.showcase,...t.showcase}}}var je=createContext(null);function h(){let e=useContext(je);if(!e)throw new Error("useLandingTheme must be used within <Landing.Provider>");return e}function Ke(e){return {"--color-primary":`hsl(${e.primary})`,"--color-primary-foreground":`hsl(${e.primaryForeground})`,"--color-background":`hsl(${e.background})`,"--color-foreground":`hsl(${e.foreground})`,"--color-muted":`hsl(${e.muted})`,"--color-muted-foreground":`hsl(${e.mutedForeground})`,"--color-secondary":`hsl(${e.secondary})`,"--color-secondary-foreground":`hsl(${e.secondaryForeground})`,"--color-card":`hsl(${e.card})`,"--color-card-foreground":`hsl(${e.cardForeground})`,"--color-border":`hsl(${e.border})`,"--color-input":`hsl(${e.border})`,"--color-ring":`hsl(${e.primary})`,"--primary":e.primary,"--primary-foreground":e.primaryForeground,"--background":e.background,"--foreground":e.foreground,"--muted":e.muted,"--muted-foreground":e.mutedForeground,"--secondary":e.secondary,"--secondary-foreground":e.secondaryForeground,"--card":e.card,"--card-foreground":e.cardForeground,"--border":e.border,"--input":e.border,"--ring":e.primary,"--landing-section-alt":`hsl(${e.sectionAlt})`}}function ge({theme:e,children:t}){let n=useMemo(()=>ue(e),[e]),s=useMemo(()=>({backgroundColor:`hsl(${n.colors.background})`,color:`hsl(${n.colors.foreground})`,...Ke(n.colors)}),[n.colors]);return jsx(je.Provider,{value:n,children:jsx("div",{style:s,children:t})})}function Ze(e,t){return t?{...e,...t}:e}function et(e){switch(e){case "slideUp":return "translateY(32px)";case "slideLeft":return "translateX(-32px)";case "slideRight":return "translateX(32px)";case "scaleIn":return "scale(0.95)";case "bounceIn":return "scale(0.75)";default:return "none"}}function fe({title:e,subtitle:t,description:n,primaryAction:s,secondaryAction:d$1,size:m,background:g,gradientColors:u,scrollIndicator:o=false,motion:c,className:i,...r}){let a=h(),l=m!=null?m:a.hero.size,p=g!=null?g:a.hero.background,y=Ze(a.hero.motion,c),f=useMemo(()=>({opacity:0,transform:et(y.type),animation:`landing-hero-enter ${y.duration}ms ${y.easing} ${y.delay}ms forwards`}),[y]);return jsxs("section",{className:a$2("relative overflow-hidden flex items-center justify-center",l==="full"?"min-h-screen":"py-28 sm:py-36",p==="dark"&&"bg-gray-950 text-white",i),...r,children:[p==="gradient"&&jsx("div",{className:"absolute inset-0 gradient-bg-soft","aria-hidden":"true"}),p==="animated-gradient"&&jsx(d,{colors:u,type:"mesh",className:"absolute inset-0 -z-0","aria-hidden":"true"}),p==="dark"&&jsx("div",{className:"absolute inset-0",style:{background:"radial-gradient(ellipse 80% 60% at 50% 40%, rgba(120, 119, 198, 0.08), transparent)"},"aria-hidden":"true"}),jsx(a$1,{size:"lg",padding:"none",centered:true,className:"relative z-10 px-6",children:jsxs("div",{style:f,className:"text-center max-w-4xl mx-auto",children:[jsx("h1",{className:"text-4xl sm:text-5xl md:text-6xl lg:text-7xl font-extrabold tracking-tight mb-6",children:e}),t&&jsx("p",{className:"text-xl sm:text-2xl text-muted-foreground mb-4",children:t}),n&&jsx("p",{className:"text-base sm:text-lg text-muted-foreground/80 max-w-2xl mx-auto mb-8",children:n}),(s||d$1)&&jsxs("div",{className:"flex flex-col sm:flex-row items-center justify-center gap-4",children:[s,d$1]})]})}),o&&jsx("div",{className:"absolute bottom-8 left-1/2 -translate-x-1/2 animate-bounce","aria-hidden":"true",children:jsx("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:"text-muted-foreground",children:jsx("path",{d:"M12 5v14M5 12l7 7 7-7"})})}),jsx("style",{dangerouslySetInnerHTML:{__html:`
|
|
3
3
|
@keyframes landing-hero-enter {
|
|
4
4
|
to { opacity: 1; transform: none; }
|
|
5
5
|
}
|
|
6
|
-
`}})]})}var X;try{X=a("@hua-labs/motion-core").useStagger;}catch{}var tt={2:"grid-cols-1 md:grid-cols-2",3:"grid-cols-1 md:grid-cols-2 lg:grid-cols-3",4:"grid-cols-1 md:grid-cols-2 lg:grid-cols-4"};function nt(e,t,n){switch(t){case "glow":return jsxs(b$
|
|
6
|
+
`}})]})}var X;try{X=a("@hua-labs/motion-core").useStagger;}catch{}var tt={2:"grid-cols-1 md:grid-cols-2",3:"grid-cols-1 md:grid-cols-2 lg:grid-cols-3",4:"grid-cols-1 md:grid-cols-2 lg:grid-cols-4"};function nt(e,t,n){switch(t){case "glow":return jsxs(b$1,{style:n,className:"p-6",children:[e.icon&&jsx("div",{className:"text-4xl mb-4",children:e.icon}),jsx("h3",{className:"text-xl font-bold mb-2",children:e.title}),jsx("p",{className:"text-muted-foreground text-sm",children:e.description})]});case "spotlight":return jsxs(c,{style:n,className:"p-6",children:[e.icon&&jsx("div",{className:"text-4xl mb-4",children:e.icon}),jsx("h3",{className:"text-xl font-bold mb-2",children:e.title}),jsx("p",{className:"text-muted-foreground text-sm",children:e.description})]});default:return jsx(a$5,{style:n,icon:void 0,title:e.title,description:e.description,variant:"glass",hover:"slide",children:e.icon&&jsx("div",{className:"text-4xl mb-4",children:e.icon})})}}function ye({items:e,title:t,subtitle:n,columns:s,card:d,sectionProps:m,motion:g,staggerDelay:u,decorator:o,className:c,...i}){let r=h(),a=d!=null?d:r.features.card,l=u!=null?u:r.features.staggerDelay,p=o!=null?o:r.features.decorator,y=g?{...r.features.motion,...g}:r.features.motion,f=s!=null?s:e.length<=2?2:e.length<=3?3:4,S=t||n?{title:t!=null?t:"",subtitle:n,decorator:p}:void 0,b$1=X==null?void 0:X({count:e.length,staggerDelay:l,duration:y.duration,motionType:y.type,easing:y.easing});return jsx(b,{header:S,spacing:"lg",...m,className:a$2(c),...i,children:jsx("div",{ref:b$1==null?void 0:b$1.containerRef,className:a$2("grid gap-6 lg:gap-8",tt[f]),children:e.map((L,O)=>jsx("div",{children:nt(L,a,b$1==null?void 0:b$1.styles[O])},O))})})}var Y;try{Y=a("@hua-labs/motion-core").useStagger;}catch{}function st(e){let t=e.match(/^([^0-9]*)([0-9]+(?:\.[0-9]+)?)(.*)$/);return t?{prefix:t[1],numeric:parseFloat(t[2]),suffix:t[3]}:{numeric:0,prefix:"",suffix:e}}function dt(e,t,n=1500){let[s,d]=useState(0),m=useRef(0),g=useCallback(()=>{let u=performance.now(),o=c=>{let i=c-u,r=Math.min(i/n,1),a=1-Math.pow(1-r,4);d(a*e),r<1&&(m.current=requestAnimationFrame(o));};m.current=requestAnimationFrame(o);},[e,n]);return useEffect(()=>{if(t)return g(),()=>{m.current&&cancelAnimationFrame(m.current);}},[t,g]),s}function lt({item:e,numberSize:t,countUp:n,isVisible:s,style:d}){var a,l;let{numeric:m,prefix:g,suffix:u}=st(e.value),o=dt(m,n&&s),c=(a=e.prefix)!=null?a:g,i=(l=e.suffix)!=null?l:u,r=n?`${c}${Number.isInteger(m)?Math.round(o):o.toFixed(1)}${i}`:e.value;return jsxs("div",{className:"text-center",style:d,children:[jsx("div",{className:a$2("font-extrabold stat-number",t),children:r}),jsx("div",{className:"text-muted-foreground mt-2 text-sm sm:text-base",children:e.label})]})}function be({items:e,title:t,subtitle:n,countUp:s,numberSize:d,sectionProps:m,motion:g,staggerDelay:u,className:o,...c}){let i=h(),r=s!=null?s:i.stats.countUp,a=d!=null?d:i.stats.numberSize,l=u!=null?u:i.stats.staggerDelay,p=g?{...i.stats.motion,...g}:i.stats.motion,y=t||n?{title:t!=null?t:"",subtitle:n,decorator:false}:void 0,f=Y==null?void 0:Y({count:e.length,staggerDelay:l,duration:p.duration,motionType:p.type,easing:p.easing}),S=e.length<=2?"grid-cols-1 sm:grid-cols-2":e.length<=3?"grid-cols-1 sm:grid-cols-3":"grid-cols-2 sm:grid-cols-4";return jsx(b,{header:y,spacing:"lg",...m,className:a$2(o),...c,children:jsx("div",{ref:f==null?void 0:f.containerRef,className:a$2("grid gap-8 lg:gap-12",S),children:e.map((b,L)=>{var O;return jsx(lt,{item:b,numberSize:a,countUp:r,isVisible:(O=f==null?void 0:f.isVisible)!=null?O:true,style:f==null?void 0:f.styles[L]},L)})})})}function ut(e){switch(e){case "slideUp":return "translateY(32px)";case "slideLeft":return "translateX(-32px)";case "slideRight":return "translateX(32px)";case "scaleIn":return "scale(0.95)";case "bounceIn":return "scale(0.75)";default:return "none"}}var B;try{B=a("@hua-labs/motion-core").useScrollReveal;}catch{}function he({title:e,subtitle:t,primaryAction:n,secondaryAction:s,background:d$1,gradientColors:m,motion:g,className:u,...o}){var p;let c=h(),i=d$1!=null?d$1:c.cta.background,r=g?{...c.cta.motion,...g}:c.cta.motion,a=B==null?void 0:B({motionType:r.type,duration:r.duration,delay:r.delay}),l=useMemo(()=>a?{}:{opacity:0,transform:ut(r.type),animation:`landing-cta-enter ${r.duration}ms ${r.easing} ${r.delay}ms forwards`},[a,r]);return jsxs("section",{className:a$2("relative overflow-hidden py-20 sm:py-28",i==="dark"&&"bg-gray-950 text-white",u),...o,children:[i==="gradient-soft"&&jsx("div",{className:"absolute inset-0 gradient-bg-soft","aria-hidden":"true"}),i==="animated-gradient"&&jsx(d,{colors:m,type:"mesh",className:"absolute inset-0 -z-0","aria-hidden":"true"}),i==="dark"&&jsx("div",{className:"absolute inset-0",style:{background:"radial-gradient(ellipse 80% 60% at 50% 40%, rgba(120, 119, 198, 0.08), transparent)"},"aria-hidden":"true"}),jsx(a$1,{size:"md",padding:"none",centered:true,className:"relative z-10 px-6",children:jsxs("div",{ref:a==null?void 0:a.ref,style:(p=a==null?void 0:a.style)!=null?p:l,className:"text-center",children:[jsx("h2",{className:"text-3xl sm:text-4xl md:text-5xl font-extrabold mb-4",children:e}),t&&jsx("p",{className:"text-lg text-muted-foreground max-w-2xl mx-auto mb-8",children:t}),(n||s)&&jsxs("div",{className:"flex flex-col sm:flex-row items-center justify-center gap-4",children:[n,s]})]})}),jsx("style",{dangerouslySetInnerHTML:{__html:`
|
|
7
7
|
@keyframes landing-cta-enter {
|
|
8
8
|
to { opacity: 1; transform: none; }
|
|
9
9
|
}
|
|
10
|
-
`}})]})}var W;try{W=a("@hua-labs/motion-core").useStagger;}catch{}function ve({item:e,style:t}){return jsxs("div",{className:"bg-card/50 backdrop-blur-sm border border-border/30 rounded-xl p-6 flex flex-col gap-4",style:t,children:[jsxs("blockquote",{className:"text-foreground/90 leading-relaxed flex-1",children:["\u201C",e.quote,"\u201D"]}),jsxs("div",{className:"flex items-center gap-3",children:[e.avatar&&jsx(a$
|
|
10
|
+
`}})]})}var W;try{W=a("@hua-labs/motion-core").useStagger;}catch{}function ve({item:e,style:t}){return jsxs("div",{className:"bg-card/50 backdrop-blur-sm border border-border/30 rounded-xl p-6 flex flex-col gap-4",style:t,children:[jsxs("blockquote",{className:"text-foreground/90 leading-relaxed flex-1",children:["\u201C",e.quote,"\u201D"]}),jsxs("div",{className:"flex items-center gap-3",children:[e.avatar&&jsx(a$4,{size:"sm",src:e.avatar,alt:e.author}),jsxs("div",{children:[jsx("p",{className:"font-semibold text-sm",children:e.author}),(e.role||e.company)&&jsxs("p",{className:"text-xs text-muted-foreground",children:[e.role,e.role&&e.company&&", ",e.company]})]})]})]})}var gt={2:"md:grid-cols-2",3:"md:grid-cols-2 lg:grid-cols-3"};function Le({items:e$1,title:t,subtitle:n,variant:s,columns:d,autoPlay:m=true,interval:g=5e3,motion:u,staggerDelay:o,className:c,...i}){let r=h(),a=s!=null?s:r.testimonials.variant,l=u?{...r.testimonials.motion,...u}:r.testimonials.motion,p=o!=null?o:r.testimonials.staggerDelay,y=W==null?void 0:W({count:e$1.length,staggerDelay:p,duration:l.duration,motionType:l.type,easing:l.easing}),f=t||n?{title:t!=null?t:"",subtitle:n}:void 0;if(a==="marquee")return jsx(b,{header:f,className:c,...i,children:jsx(a$3,{speed:50,pauseOnHover:true,gradient:true,children:e$1.map((b,L)=>jsx("div",{className:"w-80 shrink-0",children:jsx(ve,{item:b})},L))})});if(a==="carousel")return jsx(b,{header:f,className:c,...i,children:jsx(e,{autoPlay:m,interval:g,loop:true,transition:"fade",indicators:"dots",children:e$1.map((b,L)=>jsx("div",{className:"flex justify-center px-4",children:jsx("div",{className:"max-w-2xl w-full",children:jsx(ve,{item:b})})},L))})});let S=d!=null?d:e$1.length<=2?2:3;return jsx(b,{header:f,className:c,...i,children:jsx("div",{ref:y==null?void 0:y.containerRef,className:a$2("grid gap-6",gt[S]),children:e$1.map((b,L)=>jsx(ve,{item:b,style:y==null?void 0:y.styles[L]},L))})})}function ft(e){switch(e){case "slideUp":return "translateY(32px)";case "slideLeft":return "translateX(-32px)";case "slideRight":return "translateX(32px)";case "scaleIn":return "scale(0.95)";case "bounceIn":return "scale(0.75)";default:return "none"}}var J;try{J=a("@hua-labs/motion-core").useScrollReveal;}catch{}function Se({logos:e,title:t,variant:n,speed:s,logoHeight:d=40,motion:m,className:g,...u}){var f;let o=h(),c=n!=null?n:o.logoCloud.variant,i=s!=null?s:o.logoCloud.speed,r=m?{...o.features.motion,...m}:{type:"fadeIn",duration:800,easing:"ease-out",delay:0},a=J==null?void 0:J({motionType:r.type,duration:r.duration,delay:r.delay}),l=useMemo(()=>a?{}:{opacity:0,transform:ft(r.type),animation:`landing-logocloud-enter ${r.duration}ms ${r.easing} ${r.delay}ms forwards`},[a,r]),p=e.map((S,b)=>{let L=jsx("img",{src:S.src,alt:S.alt,className:"object-contain opacity-60 hover:opacity-100 transition-opacity grayscale hover:grayscale-0",style:{height:d,width:"auto"}},b);return S.href?jsx("a",{href:S.href,target:"_blank",rel:"noopener noreferrer",className:"inline-flex",children:L},b):L});return jsxs(b,{header:t?{title:t,subtitle:void 0}:void 0,spacing:"sm",className:a$2("py-12 sm:py-16",g),...u,children:[jsx("div",{ref:a==null?void 0:a.ref,style:(f=a==null?void 0:a.style)!=null?f:l,children:c==="marquee"?jsx(a$3,{speed:i,pauseOnHover:true,gradient:true,gap:48,children:p}):jsx("div",{className:"flex flex-wrap items-center justify-center gap-8 sm:gap-12",children:p})}),jsx("style",{dangerouslySetInnerHTML:{__html:`
|
|
11
11
|
@keyframes landing-logocloud-enter {
|
|
12
12
|
to { opacity: 1; transform: none; }
|
|
13
13
|
}
|
|
14
|
-
`}})]})}var K;try{K=a("@hua-labs/motion-core").useStagger;}catch{}function Ne({items:e,title:t,subtitle:n,motion:s,staggerDelay:d,className:m,...g}){let u=h(),o=s?{...u.showcase.motion,...s}:u.showcase.motion,c=d!=null?d:u.showcase.staggerDelay,i=K==null?void 0:K({count:e.length,staggerDelay:c,duration:o.duration,motionType:o.type,easing:o.easing}),r=t||n?{title:t!=null?t:"",subtitle:n}:void 0;return jsx(b
|
|
14
|
+
`}})]})}var K;try{K=a("@hua-labs/motion-core").useStagger;}catch{}function Ne({items:e,title:t,subtitle:n,motion:s,staggerDelay:d,className:m,...g}){let u=h(),o=s?{...u.showcase.motion,...s}:u.showcase.motion,c=d!=null?d:u.showcase.staggerDelay,i=K==null?void 0:K({count:e.length,staggerDelay:c,duration:o.duration,motionType:o.type,easing:o.easing}),r=t||n?{title:t!=null?t:"",subtitle:n}:void 0;return jsx(b,{header:r,className:m,...g,children:jsx("div",{ref:i==null?void 0:i.containerRef,className:"space-y-16 sm:space-y-24",children:e.map((a,l)=>{let p=l%2===0;return jsx(a$1,{size:"lg",padding:"none",className:"px-4",children:jsxs("div",{className:a$2("flex flex-col gap-8 items-center",p?"md:flex-row":"md:flex-row-reverse"),style:i==null?void 0:i.styles[l],children:[jsx("div",{className:"flex-1 w-full",children:jsxs("div",{className:"relative overflow-hidden rounded-xl border border-border/30 shadow-lg",children:[jsx("img",{src:a.image,alt:a.title,className:"w-full h-auto object-cover"}),jsx("div",{className:"absolute inset-0 bg-gradient-to-t from-black/20 to-transparent pointer-events-none"})]})}),jsxs("div",{className:"flex-1 w-full space-y-4",children:[jsx("h3",{className:"text-2xl sm:text-3xl font-bold",children:a.title}),jsx("p",{className:"text-muted-foreground leading-relaxed",children:a.description})]})]})},l)})})})}var Q;try{Q=a("@hua-labs/motion-core").useScrollReveal;}catch{}function ke({name:e,role:t,bio:n,avatar:s,socialLinks:d,motion:m,className:g,...u}){var a;let o=h(),c=m?{...o.hero.motion,...m}:o.hero.motion,i=Q==null?void 0:Q({motionType:c.type,duration:c.duration,delay:c.delay}),r=i?{}:{opacity:0,transform:c.type==="slideUp"?"translateY(32px)":"none",animation:`landing-about-enter ${c.duration}ms ${c.easing} ${c.delay}ms forwards`};return jsxs(b,{className:g,...u,children:[jsx(a$1,{size:"lg",padding:"none",centered:true,children:jsxs("div",{ref:i==null?void 0:i.ref,style:(a=i==null?void 0:i.style)!=null?a:r,className:"flex flex-col md:flex-row items-center gap-8 md:gap-12",children:[s&&jsx("div",{className:"flex-shrink-0",children:jsx(a$4,{size:"lg",src:s,alt:e,className:"w-32 h-32 md:w-40 md:h-40"})}),jsxs("div",{className:"flex-1 text-center md:text-left",children:[jsx("h2",{className:"text-3xl sm:text-4xl font-bold mb-2",children:e}),jsx("p",{className:"text-xl text-muted-foreground mb-4",children:t}),jsx("div",{className:"text-foreground/90 leading-relaxed mb-6",children:typeof n=="string"?jsx("p",{children:n}):n}),d&&d.length>0&&jsx("div",{className:"flex gap-4 justify-center md:justify-start",children:d.map((l$1,p)=>jsx("a",{href:l$1.href,target:"_blank",rel:"noopener noreferrer",className:"text-muted-foreground hover:text-foreground transition-colors","aria-label":l$1.label,children:jsx(l,{name:l$1.icon,size:24})},p))})]})]})}),jsx("style",{dangerouslySetInnerHTML:{__html:`
|
|
15
15
|
@keyframes landing-about-enter {
|
|
16
16
|
to { opacity: 1; transform: none; }
|
|
17
17
|
}
|
|
18
|
-
`}})]})}var Z,_e;try{let e=a("@hua-labs/motion-core");Z=e.useStagger,_e=e.TiltCard;}catch{}var xt={2:"md:grid-cols-2",3:"md:grid-cols-2 lg:grid-cols-3"};function ht({item:e,style:t}){return jsxs(_e||a$
|
|
18
|
+
`}})]})}var Z,_e;try{let e=a("@hua-labs/motion-core");Z=e.useStagger,_e=e.TiltCard;}catch{}var xt={2:"md:grid-cols-2",3:"md:grid-cols-2 lg:grid-cols-3"};function ht({item:e,style:t}){return jsxs(_e||a$6,{className:"bg-card/50 backdrop-blur-sm border border-border/30 rounded-xl overflow-hidden group hover:shadow-lg transition-shadow",style:t,children:[e.image&&jsx("div",{className:"relative overflow-hidden aspect-video",children:jsx("img",{src:e.image,alt:e.title,className:"w-full h-full object-cover group-hover:scale-105 transition-transform duration-300"})}),jsxs("div",{className:"p-6",children:[jsx("h3",{className:"text-xl font-bold mb-2",children:e.title}),jsx("p",{className:"text-muted-foreground mb-4 leading-relaxed",children:e.description}),e.tags&&e.tags.length>0&&jsx("div",{className:"flex flex-wrap gap-2 mb-4",children:e.tags.map((s,d)=>jsx("span",{className:"px-2 py-1 text-xs rounded-full bg-primary/10 text-primary",children:s},d))}),jsxs("div",{className:"flex gap-3",children:[e.href&&jsxs("a",{href:e.href,target:"_blank",rel:"noopener noreferrer",className:"text-sm text-primary hover:underline flex items-center gap-1",children:["View Project ",jsx(l,{name:"arrowRight",size:16})]}),e.github&&jsxs("a",{href:e.github,target:"_blank",rel:"noopener noreferrer",className:"text-sm text-muted-foreground hover:text-foreground flex items-center gap-1",children:[jsx(l,{name:"github",size:16})," GitHub"]})]})]})]})}function Ce({items:e,title:t,subtitle:n,columns:s=3,filter:d=false,motion:m,staggerDelay:g,className:u,...o}){let c=h(),i=m?{...c.features.motion,...m}:c.features.motion,r=g!=null?g:c.features.staggerDelay,[a,l]=useState(null),p=useMemo(()=>{let b=new Set;return e.forEach(L=>{var O;(O=L.tags)==null||O.forEach(Ye=>b.add(Ye));}),Array.from(b)},[e]),y=useMemo(()=>a?e.filter(b=>{var L;return (L=b.tags)==null?void 0:L.includes(a)}):e,[e,a]),f=Z==null?void 0:Z({count:y.length,staggerDelay:r,duration:i.duration,motionType:i.type,easing:i.easing}),S=t||n?{title:t!=null?t:"",subtitle:n}:void 0;return jsxs(b,{header:S,className:u,...o,children:[d&&p.length>0&&jsxs("div",{className:"flex flex-wrap gap-2 mb-8 justify-center",children:[jsx("button",{onClick:()=>l(null),className:a$2("px-4 py-2 rounded-full text-sm font-medium transition-colors",a?"bg-secondary text-secondary-foreground hover:bg-secondary/80":"bg-primary text-primary-foreground"),children:"All"}),p.map(b=>jsx("button",{onClick:()=>l(b),className:a$2("px-4 py-2 rounded-full text-sm font-medium transition-colors",a===b?"bg-primary text-primary-foreground":"bg-secondary text-secondary-foreground hover:bg-secondary/80"),children:b},b))]}),jsx("div",{ref:f==null?void 0:f.containerRef,className:a$2("grid gap-6",xt[s]),children:y.map((b,L)=>jsx(ht,{item:b,style:f==null?void 0:f.styles[L]},L))})]})}var ee;try{ee=a("@hua-labs/motion-core").useStagger;}catch{}function vt(e){return e>=90?"bg-green-500":e>=70?"bg-blue-500":e>=50?"bg-yellow-500":"bg-gray-500"}function we({items:e,title:t,subtitle:n,variant:s="grid",motion:d,staggerDelay:m,className:g,...u}){let o=h(),c=d?{...o.features.motion,...d}:o.features.motion,i=m!=null?m:o.features.staggerDelay,r=ee==null?void 0:ee({count:e.length,staggerDelay:i,duration:c.duration,motionType:c.type,easing:c.easing}),a=t||n?{title:t!=null?t:"",subtitle:n}:void 0;return s==="marquee"?jsx(b,{header:a,className:g,...u,children:jsx(a$3,{speed:50,pauseOnHover:true,gradient:true,children:e.map((l$1,p)=>jsxs("div",{className:"w-40 shrink-0 flex items-center gap-3 px-4 py-2",children:[l$1.icon&&jsx(l,{name:l$1.icon,size:24}),jsx("span",{className:"font-medium",children:l$1.name})]},p))})}):s==="grid"?jsx(b,{header:a,className:g,...u,children:jsx("div",{ref:r==null?void 0:r.containerRef,className:"grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-6",children:e.map((l$1,p)=>jsxs("div",{className:"flex flex-col items-center gap-3 p-6 bg-card/50 backdrop-blur-sm border border-border/30 rounded-xl hover:shadow-lg transition-shadow",style:r==null?void 0:r.styles[p],children:[l$1.icon&&jsx(l,{name:l$1.icon,size:32,variant:"primary"}),jsx("span",{className:"font-semibold text-center",children:l$1.name}),l$1.category&&jsx("span",{className:"text-xs text-muted-foreground",children:l$1.category})]},p))})}):jsxs(b,{header:a,className:g,...u,children:[jsx("div",{ref:r==null?void 0:r.containerRef,className:"space-y-6 max-w-3xl mx-auto",children:e.map((l$1,p)=>{var f;let y=(f=l$1.level)!=null?f:100;return jsxs("div",{className:"space-y-2",style:r==null?void 0:r.styles[p],children:[jsxs("div",{className:"flex justify-between items-center",children:[jsxs("div",{className:"flex items-center gap-2",children:[l$1.icon&&jsx(l,{name:l$1.icon,size:20}),jsx("span",{className:"font-semibold",children:l$1.name})]}),jsxs("span",{className:"text-sm text-muted-foreground",children:[y,"%"]})]}),jsx("div",{className:"h-2 bg-secondary rounded-full overflow-hidden",children:jsx("div",{className:a$2("h-full rounded-full transition-all duration-1000",vt(y)),style:{width:`${y}%`,animation:"skill-bar-fill 1s ease-out forwards"}})})]},p)})}),jsx("style",{dangerouslySetInnerHTML:{__html:`
|
|
19
19
|
@keyframes skill-bar-fill {
|
|
20
20
|
from { width: 0; }
|
|
21
21
|
}
|
|
22
|
-
`}})]})}var te;try{te=a("@hua-labs/motion-core").useStagger;}catch{}function Lt({item:e,style:t}){return jsxs("div",{className:"relative pl-8 pb-8 last:pb-0",style:t,children:[jsx("div",{className:
|
|
22
|
+
`}})]})}var te;try{te=a("@hua-labs/motion-core").useStagger;}catch{}function Lt({item:e,style:t}){return jsxs("div",{className:"relative pl-8 pb-8 last:pb-0",style:t,children:[jsx("div",{className:a$2("absolute left-0 top-1.5 w-3 h-3 rounded-full border-2",e.current?"bg-primary border-primary animate-pulse":"bg-background border-border")}),jsx("div",{className:"absolute left-[5px] top-4 bottom-0 w-0.5 bg-border"}),jsxs("div",{className:"space-y-1",children:[jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-1",children:[jsx("h3",{className:"text-lg font-bold",children:e.title}),jsx("span",{className:"text-sm text-muted-foreground",children:e.period})]}),jsx("p",{className:"text-base text-foreground/80 font-medium",children:e.company}),e.description&&jsx("p",{className:"text-sm text-muted-foreground leading-relaxed pt-2",children:e.description}),e.current&&jsx("span",{className:"inline-block mt-2 px-2 py-1 text-xs rounded-full bg-primary/10 text-primary",children:"Current"})]})]})}function Ie({items:e,title:t,subtitle:n,motion:s,staggerDelay:d,className:m,...g}){let u=h(),o=s?{...u.features.motion,...s}:u.features.motion,c=d!=null?d:u.features.staggerDelay,i=te==null?void 0:te({count:e.length,staggerDelay:c,duration:o.duration,motionType:o.type,easing:o.easing}),r=t||n?{title:t!=null?t:"",subtitle:n}:void 0;return jsx(b,{header:r,className:m,...g,children:jsx("div",{ref:i==null?void 0:i.containerRef,className:"max-w-3xl mx-auto",children:e.map((a,l)=>jsx(Lt,{item:a,style:i==null?void 0:i.styles[l]},l))})})}var ne;try{ne=a("@hua-labs/motion-core").useScrollReveal;}catch{}function Tt(e){return e>=90?{bar:"bg-green-500",text:"text-green-600 dark:text-green-400"}:e>=50?{bar:"bg-orange-500",text:"text-orange-600 dark:text-orange-400"}:{bar:"bg-red-500",text:"text-red-600 dark:text-red-400"}}function Nt({item:e,delay:t=0}){let[n,s]=useState(0),d=Tt(e.value);return useEffect(()=>{let m=setTimeout(()=>{s(e.value);},t);return ()=>clearTimeout(m)},[e.value,t]),jsxs("div",{className:"space-y-2",children:[jsxs("div",{className:"flex justify-between items-center",children:[jsx("span",{className:"text-sm font-medium",children:e.label}),jsx("span",{className:a$2("text-2xl font-bold",d.text),children:Math.round(n)})]}),jsx("div",{className:"h-2 bg-secondary rounded-full overflow-hidden",children:jsx("div",{className:a$2("h-full rounded-full transition-all duration-1000 ease-out",d.bar),style:{width:`${n}%`}})}),e.description&&jsx("p",{className:"text-xs text-muted-foreground",children:e.description})]})}function De({items:e,title:t,subtitle:n,tabs:s,motion:d,className:m,...g}){var y;let u=h(),o=d?{...u.stats.motion,...d}:u.stats.motion,[c,i]=useState(0),r=ne==null?void 0:ne({motionType:o.type,duration:o.duration,delay:o.delay}),a=r?{}:{opacity:0,transform:o.type==="slideUp"?"translateY(32px)":"none",animation:`landing-metrics-enter ${o.duration}ms ${o.easing} ${o.delay}ms forwards`},l=s?s[c].items:e,p=t||n?{title:t!=null?t:"",subtitle:n}:void 0;return jsxs(b,{header:p,className:m,...g,children:[jsxs("div",{ref:r==null?void 0:r.ref,style:(y=r==null?void 0:r.style)!=null?y:a,className:"max-w-3xl mx-auto",children:[s&&s.length>1&&jsx("div",{className:"flex gap-2 mb-8 justify-center",children:s.map((f,S)=>jsx("button",{onClick:()=>i(S),className:a$2("px-4 py-2 rounded-lg text-sm font-medium transition-colors",c===S?"bg-primary text-primary-foreground":"bg-secondary text-secondary-foreground hover:bg-secondary/80"),children:f.label},S))}),jsx("div",{className:"space-y-6",children:l.map((f,S)=>jsx(Nt,{item:f,delay:S*100},S))})]}),jsx("style",{dangerouslySetInnerHTML:{__html:`
|
|
23
23
|
@keyframes landing-metrics-enter {
|
|
24
24
|
to { opacity: 1; transform: none; }
|
|
25
25
|
}
|
|
26
|
-
`}})]})}var ae;try{ae=a("@hua-labs/motion-core").useScrollReveal;}catch{}function ze({title:e="Get in Touch",subtitle:t,email:n,socialLinks:s,motion:d,className:m,...g}){var a;let u=h(),o=d?{...u.cta.motion,...d}:u.cta.motion,c=ae==null?void 0:ae({motionType:o.type,duration:o.duration,delay:o.delay}),i=c?{}:{opacity:0,transform:o.type==="slideUp"?"translateY(32px)":"none",animation:`landing-contact-enter ${o.duration}ms ${o.easing} ${o.delay}ms forwards`},r=e||t?{title:e!=null?e:"",subtitle:t}:void 0;return jsxs(b
|
|
26
|
+
`}})]})}var ae;try{ae=a("@hua-labs/motion-core").useScrollReveal;}catch{}function ze({title:e="Get in Touch",subtitle:t,email:n,socialLinks:s,motion:d,className:m,...g}){var a;let u=h(),o=d?{...u.cta.motion,...d}:u.cta.motion,c=ae==null?void 0:ae({motionType:o.type,duration:o.duration,delay:o.delay}),i=c?{}:{opacity:0,transform:o.type==="slideUp"?"translateY(32px)":"none",animation:`landing-contact-enter ${o.duration}ms ${o.easing} ${o.delay}ms forwards`},r=e||t?{title:e!=null?e:"",subtitle:t}:void 0;return jsxs(b,{header:r,className:m,...g,children:[jsx(a$1,{size:"md",padding:"none",centered:true,children:jsxs("div",{ref:c==null?void 0:c.ref,style:(a=c==null?void 0:c.style)!=null?a:i,className:"text-center space-y-6",children:[n&&jsx("a",{href:`mailto:${n}`,className:"inline-block text-2xl sm:text-3xl font-bold text-primary hover:underline",children:n}),s&&s.length>0&&jsx("div",{className:"flex gap-4 justify-center",children:s.map((l$1,p)=>jsx("a",{href:l$1.href,target:"_blank",rel:"noopener noreferrer",className:"flex items-center justify-center w-12 h-12 rounded-full bg-secondary hover:bg-secondary/80 text-foreground transition-colors","aria-label":l$1.label,children:jsx(l,{name:l$1.icon,size:24})},p))})]})}),jsx("style",{dangerouslySetInnerHTML:{__html:`
|
|
27
27
|
@keyframes landing-contact-enter {
|
|
28
28
|
to { opacity: 1; transform: none; }
|
|
29
29
|
}
|