@vmscloud/moz-ui-components-react 0.1.46 → 0.1.48

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.
@@ -3,6 +3,7 @@ import { ButtonProps as CoreButtonProps } from '@vmscloud/moz-ui-components-core
3
3
  export { useToast } from '@vmscloud/moz-ui-components-core';
4
4
  export type { ToastOptions, ToastInstance, ToastProps, ToastType, ToastPosition } from '@vmscloud/moz-ui-components-core';
5
5
  export type { BadgeProps, BadgeTone, BadgeAppearance, BadgeSize } from '@vmscloud/moz-ui-components-core';
6
+ export type { ChipProps, ChipTone, ChipAppearance, ChipSize } from '@vmscloud/moz-ui-components-core';
6
7
  /**
7
8
  * 각 컴포넌트는 공용 브릿지 + 코어 스펙으로 1줄 정의.
8
9
  * 사용 예:
@@ -20,6 +21,9 @@ export declare const Label: import('react').ForwardRefExoticComponent<Omit<Recor
20
21
  export declare const Badge: import('react').ForwardRefExoticComponent<Omit<Record<string, any>, "ref"> & import('react').RefAttributes<{
21
22
  readonly el: HTMLElement | null;
22
23
  }>>;
24
+ export declare const Chip: import('react').ForwardRefExoticComponent<Omit<Record<string, any>, "ref"> & import('react').RefAttributes<{
25
+ readonly el: HTMLElement | null;
26
+ }>>;
23
27
  export declare const Toggle: import('react').ForwardRefExoticComponent<Omit<Record<string, any>, "ref"> & import('react').RefAttributes<{
24
28
  readonly el: HTMLElement | null;
25
29
  }>>;
package/dist/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";var Ce=Object.defineProperty;var Ee=(o,e,n)=>e in o?Ce(o,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):o[e]=n;var K=(o,e,n)=>Ee(o,typeof e!="symbol"?e+"":e,n);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("react"),Pe=require("react-dom"),me=require("react-dom/client"),i=require("@vmscloud/moz-ui-components-core"),O=require("react/jsx-runtime"),W=new Set;let F=null;function H(o){W.add(o),F==null&&(F=setTimeout(()=>{F=null;const e=Array.from(W);W.clear();for(const n of e)n.unmount()},0))}class Q{constructor(){K(this,"contextWrapper",null);K(this,"roots",new Set)}setContextWrapper(e){this.contextWrapper=e}mountInstance(e,n,s){const r=me.createRoot(e);this.roots.add(r);const l=c=>{const u=t.createElement(n,c);r.render(this.contextWrapper?this.contextWrapper(u):u)};return l(s),{update:c=>l(c),destroy:()=>{this.roots.delete(r),H(r)}}}unmountAll(){for(const e of this.roots)H(e);this.roots.clear()}get size(){return this.roots.size}}const q=t.createContext(i.koKR),G=t.createContext(null);function be({locale:o=i.koKR,contextWrapper:e,children:n}){return t.createElement(q.Provider,{value:o},t.createElement(G.Provider,{value:e??null},n))}function Z(){return t.useContext(q)}function ee(){return t.useContext(G)}const D=t.createContext(null);function Se({children:o}){const e=t.useRef();e.current||(e.current=i.createValidator());const n={validate:e.current.validate,initValidator:e.current.initValidator};return t.createElement(D.Provider,{value:e.current},typeof o=="function"?o(n):o)}function Te(){return t.useContext(D)}function U(o){return o.startsWith("update:")?"on"+o.slice(7).charAt(0).toUpperCase()+o.slice(8)+"Change":"on"+o.charAt(0).toUpperCase()+o.slice(1)}function ye(o,e){if(Object.is(o,e))return!0;if(typeof o!="object"||typeof e!="object"||o===null||e===null)return!1;const n=Object.keys(o),s=Object.keys(e);return n.length!==s.length?!1:n.every(r=>Object.is(o[r],e[r]))}function X(o,e){const n=Object.keys(o),s=Object.keys(e);if(n.length!==s.length)return!1;for(const r of n)if(!Object.prototype.hasOwnProperty.call(e,r)||!Object.is(o[r],e[r]))return!1;return!0}function d(o){const e=o.models??{},n=new Set([...o.props,...Object.keys(e),...Object.values(e).map(r=>r.prop),...(o.slots??[]).map(r=>r==="default"?"children":r),...(o.emits??[]).map(U),...Object.keys(e).map(r=>U(`update:${r}`)),...Object.values(e).map(r=>U(r.event)),"children","className","style","id","key","ref","slots"]),s=t.forwardRef((r,l)=>{const c=t.useRef(null),u=t.useRef(void 0),C=t.useRef(void 0),[S,T]=t.useState(()=>new Map);if(!C.current){const m={};Object.defineProperty(m,"el",{get:()=>{var f;return((f=u.current)==null?void 0:f.el)??null},enumerable:!0}),C.current=m}const a=t.useRef();a.current||(a.current=new Q);const E=ee();a.current.setContextWrapper(E);const p=Z(),y=t.useContext(D),x=t.useRef(r);x.current=r;const g=((m,...f)=>{const v=U(String(m)),R=x.current[v];typeof R=="function"&&R(...f)}),P=()=>{const m=x.current,f={};for(const v of Object.keys(m))n.has(v)||(f[v]=m[v]);for(const v of o.props)f[v]=m[v];for(const v of Object.keys(e))f[e[v].prop]=m[v];return m.className!=null&&(f.class=m.className),m.style!=null&&(f.style=m.style),m.id!=null&&(f.id=m.id),f};t.useLayoutEffect(()=>{const m=a.current,f={};for(const b of o.slots??[]){const M=b==="default"?"children":b;x.current[M]!=null&&(f[b]=(h,z)=>{const I=({scope:L})=>{const w=x.current[M];return(typeof w=="function"?w(L):w)??null},_=m.mountInstance(h,I,{scope:z});return{update:L=>_.update({scope:L}),dispose:_.destroy}})}const v=b=>{const M=x.current.slots;if(!(M==null||M[b]==null))return(h,z)=>{const I=h.getAttribute("data-moz-slot-id")??b;return T(_=>new Map(_).set(I,{name:b,el:h,scope:z})),{update:_=>T(L=>{const w=L.get(I);return!w||ye(w.scope,_)?L:new Map(L).set(I,{...w,scope:_})}),dispose:()=>T(_=>{if(!_.has(I))return _;const L=new Map(_);return L.delete(I),L})}}};u.current=o.core(c.current,P(),g,{slots:f,slotResolver:v,locale:p,validator:y??void 0,providedKeys:Object.keys(x.current)});const R=u.current.api;if(R)for(const b of Object.keys(R))b!=="el"&&(C.current[b]=R[b]);return()=>{var b;(b=u.current)==null||b.destroy(),m.unmountAll(),u.current=void 0}},[]);const A=()=>{const m=x.current,f={};for(const R of o.slots??[]){const b=R==="default"?"children":R;f[b]=m[b]}const v=m.slots;return f.__dynamicSlotKeys=v?Object.keys(v).sort().join("\0"):"",f},k=t.useRef(null);t.useEffect(()=>{const m=u.current;if(!m)return;const f=P(),v=A(),R=k.current;R&&R.locale===p&&X(R.props,f)&&X(R.slots,v)||(k.current={props:f,slots:v,locale:p},(!R||R.locale!==p)&&m.setLocale(p),m.update(f,{replace:!0,sync:o.syncUpdate}))}),t.useImperativeHandle(l,()=>C.current,[]);const j=r.slots,B=Array.from(S,([m,f])=>{const v=j==null?void 0:j[f.name],R=(typeof v=="function"?v(f.scope):v)??null;return Pe.createPortal(R,f.el,m)});return t.createElement(t.Fragment,null,t.createElement("div",{ref:c,style:{display:"contents"}}),...B)});return s.displayName=o.name,s}const ve=d(i.SPLITPANE_SPEC),te=o=>null,xe=({horizontal:o,children:e})=>{const n=t.Children.toArray(e).filter(l=>t.isValidElement(l)&&l.type===te),s=n.map(l=>({size:l.props.size,minSize:l.props.minSize,maxSize:l.props.maxSize,hidden:l.props.hidden})),r={};return n.forEach((l,c)=>{r[`pane-${c}`]=l.props.children}),O.jsx(ve,{panes:s,horizontal:o,...r})},ge=d(i.TOOLTIP_SPEC),$=new Set,oe=200,Re=100,ne=t.createContext({delayDuration:oe,disableHoverableContent:!1});function he({delayDuration:o=oe,disableHoverableContent:e=!1,children:n}){const s=t.useMemo(()=>({delayDuration:o,disableHoverableContent:e}),[o,e]);return O.jsx(ne.Provider,{value:s,children:n})}const re=t.createContext(null);function se(o){const e=t.useContext(re);if(!e)throw new Error(`${o} 는 <Tooltip> 안에서만 쓸 수 있습니다.`);return e}function Ae({open:o,defaultOpen:e=!1,onOpenChange:n,delayDuration:s,disableHoverableContent:r,children:l}){const c=t.useContext(ne),u=s??c.delayDuration,C=!(r??c.disableHoverableContent),[S,T]=t.useState(e),a=o!==void 0,E=a?!!o:S,[p,y]=t.useState(null),x=`moz-tooltip-${t.useId()}`,g=t.useRef(null),P=t.useRef(null),A=t.useRef(n);A.current=n;const k=t.useCallback(()=>{g.current&&clearTimeout(g.current),P.current&&clearTimeout(P.current),g.current=null,P.current=null},[]),j=t.useCallback(h=>{var z;a||T(h),(z=A.current)==null||z.call(A,h)},[a]),B=t.useCallback(()=>{k(),j(!0)},[k,j]),m=t.useCallback(()=>{if(P.current&&(clearTimeout(P.current),P.current=null),!g.current){if(u<=0){j(!0);return}g.current=setTimeout(()=>{g.current=null,j(!0)},u)}},[u,j]),f=t.useCallback(()=>{k(),j(!1)},[k,j]),v=t.useCallback(()=>{if(g.current&&(clearTimeout(g.current),g.current=null),!C){j(!1);return}P.current||(P.current=setTimeout(()=>{P.current=null,j(!1)},Re))},[C,j]),R=t.useCallback(()=>{P.current&&(clearTimeout(P.current),P.current=null)},[]);t.useEffect(()=>k,[k]);const b=t.useRef(f);b.current=f,t.useEffect(()=>{if(!E)return;const h=()=>b.current();for(const I of Array.from($))I();$.add(h);const z=I=>{I.key==="Escape"&&b.current()};return document.addEventListener("keydown",z),()=>{$.delete(h),document.removeEventListener("keydown",z)}},[E]);const M=t.useMemo(()=>({open:E,contentId:x,anchor:p,setAnchor:y,hoverable:C,openNow:B,openDelayed:m,closeNow:f,closeSoon:v,cancelClose:R}),[E,x,p,C,B,m,f,v,R]);return O.jsx(re.Provider,{value:M,children:l})}function N(o,e){return n=>{typeof o=="function"&&o(n),e()}}function J(o,e){o&&(typeof o=="function"?o(e):o.current=e)}function ke({asChild:o=!1,children:e}){const n=se("TooltipTrigger"),{open:s,contentId:r,setAnchor:l,openNow:c,openDelayed:u,closeNow:C,closeSoon:S}=n,T=t.isValidElement(e)?e:null,a=(T==null?void 0:T.props)??{},E=T==null?void 0:T.ref,p=t.useRef(E);p.current=E;const y=t.useRef(null),x=t.useCallback(A=>{y.current=A,l(A),J(p.current,A)},[l]),g=t.useRef(E);t.useLayoutEffect(()=>{g.current!==E&&(g.current=E,J(E,y.current))});const P={ref:x,onPointerMove:N(a.onPointerMove,u),onMouseEnter:N(a.onMouseEnter,u),onPointerLeave:N(a.onPointerLeave,S),onMouseLeave:N(a.onMouseLeave,S),onPointerDown:N(a.onPointerDown,C),onFocus:N(a.onFocus,c),onBlur:N(a.onBlur,C),"aria-describedby":s?r:a["aria-describedby"],"data-state":s?"open":"closed"};return o&&T?t.cloneElement(T,P):O.jsx("span",{...P,children:e})}function Me({side:o="top",align:e="center",sideOffset:n=8,collisionPadding:s=8,arrow:r=!0,className:l,style:c,children:u,...C}){const S=se("TooltipContent"),{open:T,anchor:a,contentId:E,hoverable:p,cancelClose:y,closeSoon:x}=S,g=t.useRef({cancelClose:y,closeSoon:x});g.current={cancelClose:y,closeSoon:x};const P=t.useCallback(()=>g.current.cancelClose(),[]),A=t.useCallback(()=>g.current.closeSoon(),[]),k=t.useMemo(()=>({content:u}),[u]);return O.jsx(ge,{open:T,anchor:a,side:o,align:e,sideOffset:n,collisionPadding:s,arrow:r,tooltipId:E,className:l,style:c,slots:k,"data-hoverable":p?"true":void 0,onPointerEnter:p?P:void 0,onPointerLeave:p?A:void 0,...C})}const je=d(i.POPOVER_SPEC),ce=t.createContext(null);function V(o){const e=t.useContext(ce);if(!e)throw new Error(`${o} 는 <Popover> 안에서만 쓸 수 있습니다.`);return e}function le(...o){return e=>{for(const n of o)n&&(typeof n=="function"?n(e):n.current=e)}}function ue(o,e){return n=>{typeof o=="function"&&o(n),e(n)}}function Oe({open:o,defaultOpen:e=!1,onOpenChange:n,children:s}){const[r,l]=t.useState(e),c=o!==void 0,u=c?!!o:r,[C,S]=t.useState(null),[T,a]=t.useState(null),E=`moz-popover-${t.useId()}`,p=t.useRef(n);p.current=n;const y=t.useCallback(g=>{var P;c||l(g),(P=p.current)==null||P.call(p,g)},[c]),x=t.useMemo(()=>({open:u,setOpen:y,contentId:E,triggerEl:C,anchorEl:T,setTriggerEl:S,setAnchorEl:a}),[u,y,E,C,T]);return O.jsx(ce.Provider,{value:x,children:s})}function Ie({asChild:o=!1,children:e}){const{open:n,setOpen:s,contentId:r,setTriggerEl:l}=V("PopoverTrigger"),c=t.isValidElement(e)?e:null,u=(c==null?void 0:c.props)??{},S={ref:t.useMemo(()=>le(l,c==null?void 0:c.ref),[l,c]),onClick:ue(u.onClick,()=>s(!n)),"aria-haspopup":"dialog","aria-expanded":n,"aria-controls":n?r:void 0,"data-state":n?"open":"closed"};return o&&c?t.cloneElement(c,S):O.jsx("span",{...S,children:e})}function _e({asChild:o=!1,children:e}){const{setAnchorEl:n}=V("PopoverAnchor"),s=t.isValidElement(e)?e:null,r=t.useMemo(()=>le(n,s==null?void 0:s.ref),[n,s]);return o&&s?t.cloneElement(s,{ref:r}):O.jsx("span",{ref:r,children:e})}function Le({asChild:o=!1,children:e}){const{setOpen:n}=V("PopoverClose"),s=t.isValidElement(e)?e:null,r=(s==null?void 0:s.props)??{},l={onClick:ue(r.onClick,()=>n(!1))};return o&&s?t.cloneElement(s,l):O.jsx("button",{type:"button",...l,children:e})}function ze({side:o="bottom",align:e="start",sideOffset:n=4,collisionPadding:s=8,matchTriggerWidth:r=!1,trapFocus:l=!0,className:c,style:u,onOpenAutoFocus:C,onCloseAutoFocus:S,onEscapeKeyDown:T,onInteractOutside:a,children:E,...p}){const{open:y,setOpen:x,contentId:g,triggerEl:P,anchorEl:A}=V("PopoverContent"),k=t.useRef({setOpen:x,triggerEl:P,anchorEl:A,onOpenAutoFocus:C,onCloseAutoFocus:S,onEscapeKeyDown:T,onInteractOutside:a});k.current={setOpen:x,triggerEl:P,anchorEl:A,onOpenAutoFocus:C,onCloseAutoFocus:S,onEscapeKeyDown:T,onInteractOutside:a};const j=t.useCallback(b=>{k.current.setOpen(!1)},[]),B=t.useCallback(b=>{var M,h;(h=(M=k.current).onEscapeKeyDown)==null||h.call(M,b)},[]),m=t.useCallback(b=>{var I,_,L,w;const M=(_=(I=b.detail)==null?void 0:I.originalEvent)==null?void 0:_.target,{triggerEl:h,anchorEl:z}=k.current;if(M&&(h&&h.contains(M)||z&&z.contains(M))){b.preventDefault();return}(w=(L=k.current).onInteractOutside)==null||w.call(L,b)},[]),f=t.useCallback(b=>{var M,h;(h=(M=k.current).onOpenAutoFocus)==null||h.call(M,b)},[]),v=t.useCallback(b=>{var M,h;(h=(M=k.current).onCloseAutoFocus)==null||h.call(M,b)},[]),R=t.useMemo(()=>({content:E}),[E]);return O.jsx(je,{open:y,anchor:A??P,side:o,align:e,sideOffset:n,collisionPadding:s,matchTriggerWidth:r,trapFocus:l,popoverId:g,className:c,style:u,slots:R,onRequestClose:j,onEscapeKeyDown:B,onInteractOutside:m,onOpenAutoFocus:f,onCloseAutoFocus:v,...p})}const we=d(i.COLLAPSIBLE_SPEC),ae=t.createContext(null);function ie(o){const e=t.useContext(ae);if(!e)throw new Error(`${o} 는 <Collapsible> 안에서만 쓸 수 있습니다.`);return e}function Be(...o){return e=>{for(const n of o)n&&(typeof n=="function"?n(e):n.current=e)}}function Y(o,e){return n=>{typeof o=="function"&&o(n),e(n)}}function pe(o,e){const n=[o,e].filter(s=>typeof s=="string"&&s.length>0).join(" ");return n.length>0?n:void 0}function Ne({open:o,defaultOpen:e=!1,onOpenChange:n,disabled:s=!1,asChild:r=!1,className:l,style:c,children:u,...C}){const[S,T]=t.useState(e),a=o!==void 0,E=a?!!o:S,p=`moz-collapsible-${t.useId()}`,y=t.useRef(n);y.current=n;const x=t.useCallback(j=>{var B;a||T(j),(B=y.current)==null||B.call(y,j)},[a]),g=t.useMemo(()=>({open:E,setOpen:x,contentId:p,disabled:s}),[E,x,p,s]),P={"data-state":E?"open":"closed","data-disabled":s?"":void 0,...C},A=t.isValidElement(u)?u:null,k=r&&A?t.cloneElement(A,{...P,className:pe(A.props.className,l),style:c??A.props.style}):O.jsx("div",{...P,className:l,style:c,children:u});return O.jsx(ae.Provider,{value:g,children:k})}function Ue({asChild:o=!1,disabled:e,className:n,style:s,onClick:r,children:l,...c}){const{open:u,setOpen:C,contentId:S,disabled:T}=ie("CollapsibleTrigger"),a=e??T,E=t.useCallback(()=>{a||C(!u)},[a,u,C]),p=t.isValidElement(l)?l:null,y=(p==null?void 0:p.props)??{},x={"aria-expanded":u,"aria-controls":S,"data-state":u?"open":"closed","data-disabled":a?"":void 0,...c};if(o&&p){const g=Be(p.ref);return t.cloneElement(p,{...x,ref:g,className:pe(y.className,n),style:s??y.style,onClick:Y(y.onClick,P=>{r==null||r(P),E()}),disabled:a||void 0})}return O.jsx("button",{type:"button",...x,className:n,style:s,disabled:a||void 0,onClick:Y(r,E),children:l})}function De({forceMount:o=!1,className:e,style:n,onHeightChange:s,children:r,...l}){const{open:c,contentId:u,disabled:C}=ie("CollapsibleContent"),S=t.useRef({onHeightChange:s});S.current={onHeightChange:s};const T=t.useCallback(E=>{var p,y;(y=(p=S.current).onHeightChange)==null||y.call(p,E)},[]),a=t.useMemo(()=>({content:r}),[r]);return O.jsx(we,{open:c,forceMount:o,contentId:u,disabled:C,className:e,style:n,slots:a,onHeightChange:T,...l})}const Ve=d(i.AVATAR_SPEC);function fe(o){return null}function de(o){return null}function Ke({className:o,style:e,onLoadingStatusChange:n,children:s,...r}){let l,c;t.Children.forEach(s,S=>{t.isValidElement(S)&&(S.type===fe?l=S.props:S.type===de&&(c=S.props))});const u=c==null?void 0:c.children,C=t.useMemo(()=>({fallback:u}),[u]);return O.jsx(Ve,{src:l==null?void 0:l.src,alt:l==null?void 0:l.alt,imageClass:l==null?void 0:l.className,fallbackClass:c==null?void 0:c.className,delayMs:c==null?void 0:c.delayMs,className:o,style:e,slots:C,onLoadingStatusChange:n,...r})}const We=d(i.SCROLLAREA_SPEC);function Fe({orientation:o="vertical",scrollbarVisibility:e="always",className:n,viewportClassName:s,scrollbarClassName:r,thumbClassName:l,viewportRef:c,style:u,onScroll:C,children:S,...T}){const[a,E]=t.useState(null),p=t.useCallback(y=>{E(y),typeof c=="function"?c(y):c&&(c.current=y)},[c]);return O.jsxs("div",{className:["moz-scroll-area",n].filter(Boolean).join(" "),style:u,...T,children:[O.jsx("div",{ref:p,className:["moz-scroll-area-viewport",s].filter(Boolean).join(" "),"data-moz-scroll-area-viewport":"",children:S}),O.jsx(We,{viewport:a,interactionRoot:a==null?void 0:a.parentElement,scrollbarVisibility:e,orientation:o,scrollbarClass:r,thumbClass:l,onScroll:C})]})}const $e=d(i.BUTTON_SPEC),qe=d(i.LABEL_SPEC),Ge=d(i.BADGE_SPEC),He=d(i.TOGGLE_SPEC),Xe=d(i.BREADCRUMB_SPEC),Je=d(i.EMPTYSTATE_SPEC),Ye=d(i.CHECKBOX_SPEC),Qe=d(i.RADIO_SPEC),Ze=d(i.INPUT_SPEC),et=d(i.PASSWORDINPUT_SPEC),tt=d(i.TEXTAREA_SPEC),ot=d(i.NUMBERINPUT_SPEC),nt=d(i.TAB_SPEC),rt=d(i.SLIDER_SPEC),st=d(i.CALENDAR_SPEC),ct=d(i.DATEINPUT_SPEC),lt=d(i.POPUP_SPEC),ut=d(i.SELECT_SPEC),at=d(i.MULTISELECT_SPEC),it=d(i.TIMEPICKER_SPEC),pt=d(i.TAGINPUT_SPEC),ft=d(i.CONTEXTMENU_SPEC),dt=d(i.TABLESELECT_SPEC),Ct=d(i.TREESELECT_SPEC),Et=d(i.CONTROLLER_SPEC),Pt=d(i.TOAST_SPEC);Object.defineProperty(exports,"createValidator",{enumerable:!0,get:()=>i.createValidator});Object.defineProperty(exports,"enUS",{enumerable:!0,get:()=>i.enUS});Object.defineProperty(exports,"jaJP",{enumerable:!0,get:()=>i.jaJP});Object.defineProperty(exports,"koKR",{enumerable:!0,get:()=>i.koKR});Object.defineProperty(exports,"useToast",{enumerable:!0,get:()=>i.useToast});Object.defineProperty(exports,"zhCN",{enumerable:!0,get:()=>i.zhCN});exports.Avatar=Ke;exports.AvatarFallback=de;exports.AvatarImage=fe;exports.Badge=Ge;exports.BreadCrumb=Xe;exports.Button=$e;exports.Calendar=st;exports.CheckBox=Ye;exports.Collapsible=Ne;exports.CollapsibleContent=De;exports.CollapsibleTrigger=Ue;exports.ContextMenu=ft;exports.Controller=Et;exports.DateInput=ct;exports.EmptyState=Je;exports.Input=Ze;exports.Label=qe;exports.MozConfigProvider=be;exports.MozContextWrapperContext=G;exports.MozLocaleContext=q;exports.MultiSelect=at;exports.NumberInput=ot;exports.Pane=te;exports.PasswordInput=et;exports.Popover=Oe;exports.PopoverAnchor=_e;exports.PopoverClose=Le;exports.PopoverContent=ze;exports.PopoverTrigger=Ie;exports.Popup=lt;exports.Radio=Qe;exports.ReactRenderer=Q;exports.ScrollArea=Fe;exports.Select=ut;exports.Slider=rt;exports.SplitPane=xe;exports.Tab=nt;exports.TableSelect=dt;exports.TagInput=pt;exports.TextArea=tt;exports.TimePicker=it;exports.Toast=Pt;exports.Toggle=He;exports.Tooltip=Ae;exports.TooltipContent=Me;exports.TooltipProvider=he;exports.TooltipTrigger=ke;exports.TreeSelect=Ct;exports.Validator=Se;exports.ValidatorReactContext=D;exports.createMozComponent=d;exports.useMozContextWrapper=ee;exports.useMozLocale=Z;exports.useValidatorContext=Te;
1
+ "use strict";var Ce=Object.defineProperty;var Ee=(o,e,n)=>e in o?Ce(o,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):o[e]=n;var K=(o,e,n)=>Ee(o,typeof e!="symbol"?e+"":e,n);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("react"),Pe=require("react-dom"),me=require("react-dom/client"),a=require("@vmscloud/moz-ui-components-core"),O=require("react/jsx-runtime"),W=new Set;let F=null;function G(o){W.add(o),F==null&&(F=setTimeout(()=>{F=null;const e=Array.from(W);W.clear();for(const n of e)n.unmount()},0))}class Q{constructor(){K(this,"contextWrapper",null);K(this,"roots",new Set)}setContextWrapper(e){this.contextWrapper=e}mountInstance(e,n,s){const r=me.createRoot(e);this.roots.add(r);const l=c=>{const u=t.createElement(n,c);r.render(this.contextWrapper?this.contextWrapper(u):u)};return l(s),{update:c=>l(c),destroy:()=>{this.roots.delete(r),G(r)}}}unmountAll(){for(const e of this.roots)G(e);this.roots.clear()}get size(){return this.roots.size}}const q=t.createContext(a.koKR),H=t.createContext(null);function be({locale:o=a.koKR,contextWrapper:e,children:n}){return t.createElement(q.Provider,{value:o},t.createElement(H.Provider,{value:e??null},n))}function Z(){return t.useContext(q)}function ee(){return t.useContext(H)}const D=t.createContext(null);function Se({children:o}){const e=t.useRef();e.current||(e.current=a.createValidator());const n={validate:e.current.validate,initValidator:e.current.initValidator};return t.createElement(D.Provider,{value:e.current},typeof o=="function"?o(n):o)}function Te(){return t.useContext(D)}function U(o){return o.startsWith("update:")?"on"+o.slice(7).charAt(0).toUpperCase()+o.slice(8)+"Change":"on"+o.charAt(0).toUpperCase()+o.slice(1)}function ye(o,e){if(Object.is(o,e))return!0;if(typeof o!="object"||typeof e!="object"||o===null||e===null)return!1;const n=Object.keys(o),s=Object.keys(e);return n.length!==s.length?!1:n.every(r=>Object.is(o[r],e[r]))}function X(o,e){const n=Object.keys(o),s=Object.keys(e);if(n.length!==s.length)return!1;for(const r of n)if(!Object.prototype.hasOwnProperty.call(e,r)||!Object.is(o[r],e[r]))return!1;return!0}function d(o){const e=o.models??{},n=new Set([...o.props,...Object.keys(e),...Object.values(e).map(r=>r.prop),...(o.slots??[]).map(r=>r==="default"?"children":r),...(o.emits??[]).map(U),...Object.keys(e).map(r=>U(`update:${r}`)),...Object.values(e).map(r=>U(r.event)),"children","className","style","id","key","ref","slots"]),s=t.forwardRef((r,l)=>{const c=t.useRef(null),u=t.useRef(void 0),C=t.useRef(void 0),[S,T]=t.useState(()=>new Map);if(!C.current){const m={};Object.defineProperty(m,"el",{get:()=>{var f;return((f=u.current)==null?void 0:f.el)??null},enumerable:!0}),C.current=m}const i=t.useRef();i.current||(i.current=new Q);const E=ee();i.current.setContextWrapper(E);const p=Z(),y=t.useContext(D),x=t.useRef(r);x.current=r;const g=((m,...f)=>{const v=U(String(m)),R=x.current[v];typeof R=="function"&&R(...f)}),P=()=>{const m=x.current,f={};for(const v of Object.keys(m))n.has(v)||(f[v]=m[v]);for(const v of o.props)f[v]=m[v];for(const v of Object.keys(e))f[e[v].prop]=m[v];return m.className!=null&&(f.class=m.className),m.style!=null&&(f.style=m.style),m.id!=null&&(f.id=m.id),f};t.useLayoutEffect(()=>{const m=i.current,f={};for(const b of o.slots??[]){const M=b==="default"?"children":b;x.current[M]!=null&&(f[b]=(h,z)=>{const I=({scope:L})=>{const w=x.current[M];return(typeof w=="function"?w(L):w)??null},_=m.mountInstance(h,I,{scope:z});return{update:L=>_.update({scope:L}),dispose:_.destroy}})}const v=b=>{const M=x.current.slots;if(!(M==null||M[b]==null))return(h,z)=>{const I=h.getAttribute("data-moz-slot-id")??b;return T(_=>new Map(_).set(I,{name:b,el:h,scope:z})),{update:_=>T(L=>{const w=L.get(I);return!w||ye(w.scope,_)?L:new Map(L).set(I,{...w,scope:_})}),dispose:()=>T(_=>{if(!_.has(I))return _;const L=new Map(_);return L.delete(I),L})}}};u.current=o.core(c.current,P(),g,{slots:f,slotResolver:v,locale:p,validator:y??void 0,providedKeys:Object.keys(x.current)});const R=u.current.api;if(R)for(const b of Object.keys(R))b!=="el"&&(C.current[b]=R[b]);return()=>{var b;(b=u.current)==null||b.destroy(),m.unmountAll(),u.current=void 0}},[]);const A=()=>{const m=x.current,f={};for(const R of o.slots??[]){const b=R==="default"?"children":R;f[b]=m[b]}const v=m.slots;return f.__dynamicSlotKeys=v?Object.keys(v).sort().join("\0"):"",f},k=t.useRef(null);t.useEffect(()=>{const m=u.current;if(!m)return;const f=P(),v=A(),R=k.current;R&&R.locale===p&&X(R.props,f)&&X(R.slots,v)||(k.current={props:f,slots:v,locale:p},(!R||R.locale!==p)&&m.setLocale(p),m.update(f,{replace:!0,sync:o.syncUpdate}))}),t.useImperativeHandle(l,()=>C.current,[]);const j=r.slots,B=Array.from(S,([m,f])=>{const v=j==null?void 0:j[f.name],R=(typeof v=="function"?v(f.scope):v)??null;return Pe.createPortal(R,f.el,m)});return t.createElement(t.Fragment,null,t.createElement("div",{ref:c,style:{display:"contents"}}),...B)});return s.displayName=o.name,s}const ve=d(a.SPLITPANE_SPEC),te=o=>null,xe=({horizontal:o,children:e})=>{const n=t.Children.toArray(e).filter(l=>t.isValidElement(l)&&l.type===te),s=n.map(l=>({size:l.props.size,minSize:l.props.minSize,maxSize:l.props.maxSize,hidden:l.props.hidden})),r={};return n.forEach((l,c)=>{r[`pane-${c}`]=l.props.children}),O.jsx(ve,{panes:s,horizontal:o,...r})},ge=d(a.TOOLTIP_SPEC),$=new Set,oe=200,Re=100,ne=t.createContext({delayDuration:oe,disableHoverableContent:!1});function he({delayDuration:o=oe,disableHoverableContent:e=!1,children:n}){const s=t.useMemo(()=>({delayDuration:o,disableHoverableContent:e}),[o,e]);return O.jsx(ne.Provider,{value:s,children:n})}const re=t.createContext(null);function se(o){const e=t.useContext(re);if(!e)throw new Error(`${o} 는 <Tooltip> 안에서만 쓸 수 있습니다.`);return e}function Ae({open:o,defaultOpen:e=!1,onOpenChange:n,delayDuration:s,disableHoverableContent:r,children:l}){const c=t.useContext(ne),u=s??c.delayDuration,C=!(r??c.disableHoverableContent),[S,T]=t.useState(e),i=o!==void 0,E=i?!!o:S,[p,y]=t.useState(null),x=`moz-tooltip-${t.useId()}`,g=t.useRef(null),P=t.useRef(null),A=t.useRef(n);A.current=n;const k=t.useCallback(()=>{g.current&&clearTimeout(g.current),P.current&&clearTimeout(P.current),g.current=null,P.current=null},[]),j=t.useCallback(h=>{var z;i||T(h),(z=A.current)==null||z.call(A,h)},[i]),B=t.useCallback(()=>{k(),j(!0)},[k,j]),m=t.useCallback(()=>{if(P.current&&(clearTimeout(P.current),P.current=null),!g.current){if(u<=0){j(!0);return}g.current=setTimeout(()=>{g.current=null,j(!0)},u)}},[u,j]),f=t.useCallback(()=>{k(),j(!1)},[k,j]),v=t.useCallback(()=>{if(g.current&&(clearTimeout(g.current),g.current=null),!C){j(!1);return}P.current||(P.current=setTimeout(()=>{P.current=null,j(!1)},Re))},[C,j]),R=t.useCallback(()=>{P.current&&(clearTimeout(P.current),P.current=null)},[]);t.useEffect(()=>k,[k]);const b=t.useRef(f);b.current=f,t.useEffect(()=>{if(!E)return;const h=()=>b.current();for(const I of Array.from($))I();$.add(h);const z=I=>{I.key==="Escape"&&b.current()};return document.addEventListener("keydown",z),()=>{$.delete(h),document.removeEventListener("keydown",z)}},[E]);const M=t.useMemo(()=>({open:E,contentId:x,anchor:p,setAnchor:y,hoverable:C,openNow:B,openDelayed:m,closeNow:f,closeSoon:v,cancelClose:R}),[E,x,p,C,B,m,f,v,R]);return O.jsx(re.Provider,{value:M,children:l})}function N(o,e){return n=>{typeof o=="function"&&o(n),e()}}function J(o,e){o&&(typeof o=="function"?o(e):o.current=e)}function ke({asChild:o=!1,children:e}){const n=se("TooltipTrigger"),{open:s,contentId:r,setAnchor:l,openNow:c,openDelayed:u,closeNow:C,closeSoon:S}=n,T=t.isValidElement(e)?e:null,i=(T==null?void 0:T.props)??{},E=T==null?void 0:T.ref,p=t.useRef(E);p.current=E;const y=t.useRef(null),x=t.useCallback(A=>{y.current=A,l(A),J(p.current,A)},[l]),g=t.useRef(E);t.useLayoutEffect(()=>{g.current!==E&&(g.current=E,J(E,y.current))});const P={ref:x,onPointerMove:N(i.onPointerMove,u),onMouseEnter:N(i.onMouseEnter,u),onPointerLeave:N(i.onPointerLeave,S),onMouseLeave:N(i.onMouseLeave,S),onPointerDown:N(i.onPointerDown,C),onFocus:N(i.onFocus,c),onBlur:N(i.onBlur,C),"aria-describedby":s?r:i["aria-describedby"],"data-state":s?"open":"closed"};return o&&T?t.cloneElement(T,P):O.jsx("span",{...P,children:e})}function Me({side:o="top",align:e="center",sideOffset:n=8,collisionPadding:s=8,arrow:r=!0,className:l,style:c,children:u,...C}){const S=se("TooltipContent"),{open:T,anchor:i,contentId:E,hoverable:p,cancelClose:y,closeSoon:x}=S,g=t.useRef({cancelClose:y,closeSoon:x});g.current={cancelClose:y,closeSoon:x};const P=t.useCallback(()=>g.current.cancelClose(),[]),A=t.useCallback(()=>g.current.closeSoon(),[]),k=t.useMemo(()=>({content:u}),[u]);return O.jsx(ge,{open:T,anchor:i,side:o,align:e,sideOffset:n,collisionPadding:s,arrow:r,tooltipId:E,className:l,style:c,slots:k,"data-hoverable":p?"true":void 0,onPointerEnter:p?P:void 0,onPointerLeave:p?A:void 0,...C})}const je=d(a.POPOVER_SPEC),ce=t.createContext(null);function V(o){const e=t.useContext(ce);if(!e)throw new Error(`${o} 는 <Popover> 안에서만 쓸 수 있습니다.`);return e}function le(...o){return e=>{for(const n of o)n&&(typeof n=="function"?n(e):n.current=e)}}function ue(o,e){return n=>{typeof o=="function"&&o(n),e(n)}}function Oe({open:o,defaultOpen:e=!1,onOpenChange:n,children:s}){const[r,l]=t.useState(e),c=o!==void 0,u=c?!!o:r,[C,S]=t.useState(null),[T,i]=t.useState(null),E=`moz-popover-${t.useId()}`,p=t.useRef(n);p.current=n;const y=t.useCallback(g=>{var P;c||l(g),(P=p.current)==null||P.call(p,g)},[c]),x=t.useMemo(()=>({open:u,setOpen:y,contentId:E,triggerEl:C,anchorEl:T,setTriggerEl:S,setAnchorEl:i}),[u,y,E,C,T]);return O.jsx(ce.Provider,{value:x,children:s})}function Ie({asChild:o=!1,children:e}){const{open:n,setOpen:s,contentId:r,setTriggerEl:l}=V("PopoverTrigger"),c=t.isValidElement(e)?e:null,u=(c==null?void 0:c.props)??{},S={ref:t.useMemo(()=>le(l,c==null?void 0:c.ref),[l,c]),onClick:ue(u.onClick,()=>s(!n)),"aria-haspopup":"dialog","aria-expanded":n,"aria-controls":n?r:void 0,"data-state":n?"open":"closed"};return o&&c?t.cloneElement(c,S):O.jsx("span",{...S,children:e})}function _e({asChild:o=!1,children:e}){const{setAnchorEl:n}=V("PopoverAnchor"),s=t.isValidElement(e)?e:null,r=t.useMemo(()=>le(n,s==null?void 0:s.ref),[n,s]);return o&&s?t.cloneElement(s,{ref:r}):O.jsx("span",{ref:r,children:e})}function Le({asChild:o=!1,children:e}){const{setOpen:n}=V("PopoverClose"),s=t.isValidElement(e)?e:null,r=(s==null?void 0:s.props)??{},l={onClick:ue(r.onClick,()=>n(!1))};return o&&s?t.cloneElement(s,l):O.jsx("button",{type:"button",...l,children:e})}function ze({side:o="bottom",align:e="start",sideOffset:n=4,collisionPadding:s=8,matchTriggerWidth:r=!1,trapFocus:l=!0,className:c,style:u,onOpenAutoFocus:C,onCloseAutoFocus:S,onEscapeKeyDown:T,onInteractOutside:i,children:E,...p}){const{open:y,setOpen:x,contentId:g,triggerEl:P,anchorEl:A}=V("PopoverContent"),k=t.useRef({setOpen:x,triggerEl:P,anchorEl:A,onOpenAutoFocus:C,onCloseAutoFocus:S,onEscapeKeyDown:T,onInteractOutside:i});k.current={setOpen:x,triggerEl:P,anchorEl:A,onOpenAutoFocus:C,onCloseAutoFocus:S,onEscapeKeyDown:T,onInteractOutside:i};const j=t.useCallback(b=>{k.current.setOpen(!1)},[]),B=t.useCallback(b=>{var M,h;(h=(M=k.current).onEscapeKeyDown)==null||h.call(M,b)},[]),m=t.useCallback(b=>{var I,_,L,w;const M=(_=(I=b.detail)==null?void 0:I.originalEvent)==null?void 0:_.target,{triggerEl:h,anchorEl:z}=k.current;if(M&&(h&&h.contains(M)||z&&z.contains(M))){b.preventDefault();return}(w=(L=k.current).onInteractOutside)==null||w.call(L,b)},[]),f=t.useCallback(b=>{var M,h;(h=(M=k.current).onOpenAutoFocus)==null||h.call(M,b)},[]),v=t.useCallback(b=>{var M,h;(h=(M=k.current).onCloseAutoFocus)==null||h.call(M,b)},[]),R=t.useMemo(()=>({content:E}),[E]);return O.jsx(je,{open:y,anchor:A??P,side:o,align:e,sideOffset:n,collisionPadding:s,matchTriggerWidth:r,trapFocus:l,popoverId:g,className:c,style:u,slots:R,onRequestClose:j,onEscapeKeyDown:B,onInteractOutside:m,onOpenAutoFocus:f,onCloseAutoFocus:v,...p})}const we=d(a.COLLAPSIBLE_SPEC),ae=t.createContext(null);function ie(o){const e=t.useContext(ae);if(!e)throw new Error(`${o} 는 <Collapsible> 안에서만 쓸 수 있습니다.`);return e}function Be(...o){return e=>{for(const n of o)n&&(typeof n=="function"?n(e):n.current=e)}}function Y(o,e){return n=>{typeof o=="function"&&o(n),e(n)}}function pe(o,e){const n=[o,e].filter(s=>typeof s=="string"&&s.length>0).join(" ");return n.length>0?n:void 0}function Ne({open:o,defaultOpen:e=!1,onOpenChange:n,disabled:s=!1,asChild:r=!1,className:l,style:c,children:u,...C}){const[S,T]=t.useState(e),i=o!==void 0,E=i?!!o:S,p=`moz-collapsible-${t.useId()}`,y=t.useRef(n);y.current=n;const x=t.useCallback(j=>{var B;i||T(j),(B=y.current)==null||B.call(y,j)},[i]),g=t.useMemo(()=>({open:E,setOpen:x,contentId:p,disabled:s}),[E,x,p,s]),P={"data-state":E?"open":"closed","data-disabled":s?"":void 0,...C},A=t.isValidElement(u)?u:null,k=r&&A?t.cloneElement(A,{...P,className:pe(A.props.className,l),style:c??A.props.style}):O.jsx("div",{...P,className:l,style:c,children:u});return O.jsx(ae.Provider,{value:g,children:k})}function Ue({asChild:o=!1,disabled:e,className:n,style:s,onClick:r,children:l,...c}){const{open:u,setOpen:C,contentId:S,disabled:T}=ie("CollapsibleTrigger"),i=e??T,E=t.useCallback(()=>{i||C(!u)},[i,u,C]),p=t.isValidElement(l)?l:null,y=(p==null?void 0:p.props)??{},x={"aria-expanded":u,"aria-controls":S,"data-state":u?"open":"closed","data-disabled":i?"":void 0,...c};if(o&&p){const g=Be(p.ref);return t.cloneElement(p,{...x,ref:g,className:pe(y.className,n),style:s??y.style,onClick:Y(y.onClick,P=>{r==null||r(P),E()}),disabled:i||void 0})}return O.jsx("button",{type:"button",...x,className:n,style:s,disabled:i||void 0,onClick:Y(r,E),children:l})}function De({forceMount:o=!1,className:e,style:n,onHeightChange:s,children:r,...l}){const{open:c,contentId:u,disabled:C}=ie("CollapsibleContent"),S=t.useRef({onHeightChange:s});S.current={onHeightChange:s};const T=t.useCallback(E=>{var p,y;(y=(p=S.current).onHeightChange)==null||y.call(p,E)},[]),i=t.useMemo(()=>({content:r}),[r]);return O.jsx(we,{open:c,forceMount:o,contentId:u,disabled:C,className:e,style:n,slots:i,onHeightChange:T,...l})}const Ve=d(a.AVATAR_SPEC);function fe(o){return null}function de(o){return null}function Ke({className:o,style:e,onLoadingStatusChange:n,children:s,...r}){let l,c;t.Children.forEach(s,S=>{t.isValidElement(S)&&(S.type===fe?l=S.props:S.type===de&&(c=S.props))});const u=c==null?void 0:c.children,C=t.useMemo(()=>({fallback:u}),[u]);return O.jsx(Ve,{src:l==null?void 0:l.src,alt:l==null?void 0:l.alt,imageClass:l==null?void 0:l.className,fallbackClass:c==null?void 0:c.className,delayMs:c==null?void 0:c.delayMs,className:o,style:e,slots:C,onLoadingStatusChange:n,...r})}const We=d(a.SCROLLAREA_SPEC);function Fe({orientation:o="vertical",scrollbarVisibility:e="always",className:n,viewportClassName:s,scrollbarClassName:r,thumbClassName:l,viewportRef:c,style:u,onScroll:C,children:S,...T}){const[i,E]=t.useState(null),p=t.useCallback(y=>{E(y),typeof c=="function"?c(y):c&&(c.current=y)},[c]);return O.jsxs("div",{className:["moz-scroll-area",n].filter(Boolean).join(" "),style:u,...T,children:[O.jsx("div",{ref:p,className:["moz-scroll-area-viewport",s].filter(Boolean).join(" "),"data-moz-scroll-area-viewport":"",children:S}),O.jsx(We,{viewport:i,interactionRoot:i==null?void 0:i.parentElement,scrollbarVisibility:e,orientation:o,scrollbarClass:r,thumbClass:l,onScroll:C})]})}const $e=d(a.BUTTON_SPEC),qe=d(a.LABEL_SPEC),He=d(a.BADGE_SPEC),Ge=d(a.CHIP_SPEC),Xe=d(a.TOGGLE_SPEC),Je=d(a.BREADCRUMB_SPEC),Ye=d(a.EMPTYSTATE_SPEC),Qe=d(a.CHECKBOX_SPEC),Ze=d(a.RADIO_SPEC),et=d(a.INPUT_SPEC),tt=d(a.PASSWORDINPUT_SPEC),ot=d(a.TEXTAREA_SPEC),nt=d(a.NUMBERINPUT_SPEC),rt=d(a.TAB_SPEC),st=d(a.SLIDER_SPEC),ct=d(a.CALENDAR_SPEC),lt=d(a.DATEINPUT_SPEC),ut=d(a.POPUP_SPEC),at=d(a.SELECT_SPEC),it=d(a.MULTISELECT_SPEC),pt=d(a.TIMEPICKER_SPEC),ft=d(a.TAGINPUT_SPEC),dt=d(a.CONTEXTMENU_SPEC),Ct=d(a.TABLESELECT_SPEC),Et=d(a.TREESELECT_SPEC),Pt=d(a.CONTROLLER_SPEC),mt=d(a.TOAST_SPEC);Object.defineProperty(exports,"createValidator",{enumerable:!0,get:()=>a.createValidator});Object.defineProperty(exports,"enUS",{enumerable:!0,get:()=>a.enUS});Object.defineProperty(exports,"jaJP",{enumerable:!0,get:()=>a.jaJP});Object.defineProperty(exports,"koKR",{enumerable:!0,get:()=>a.koKR});Object.defineProperty(exports,"useToast",{enumerable:!0,get:()=>a.useToast});Object.defineProperty(exports,"zhCN",{enumerable:!0,get:()=>a.zhCN});exports.Avatar=Ke;exports.AvatarFallback=de;exports.AvatarImage=fe;exports.Badge=He;exports.BreadCrumb=Je;exports.Button=$e;exports.Calendar=ct;exports.CheckBox=Qe;exports.Chip=Ge;exports.Collapsible=Ne;exports.CollapsibleContent=De;exports.CollapsibleTrigger=Ue;exports.ContextMenu=dt;exports.Controller=Pt;exports.DateInput=lt;exports.EmptyState=Ye;exports.Input=et;exports.Label=qe;exports.MozConfigProvider=be;exports.MozContextWrapperContext=H;exports.MozLocaleContext=q;exports.MultiSelect=it;exports.NumberInput=nt;exports.Pane=te;exports.PasswordInput=tt;exports.Popover=Oe;exports.PopoverAnchor=_e;exports.PopoverClose=Le;exports.PopoverContent=ze;exports.PopoverTrigger=Ie;exports.Popup=ut;exports.Radio=Ze;exports.ReactRenderer=Q;exports.ScrollArea=Fe;exports.Select=at;exports.Slider=st;exports.SplitPane=xe;exports.Tab=rt;exports.TableSelect=Ct;exports.TagInput=ft;exports.TextArea=ot;exports.TimePicker=pt;exports.Toast=mt;exports.Toggle=Xe;exports.Tooltip=Ae;exports.TooltipContent=Me;exports.TooltipProvider=he;exports.TooltipTrigger=ke;exports.TreeSelect=Et;exports.Validator=Se;exports.ValidatorReactContext=D;exports.createMozComponent=d;exports.useMozContextWrapper=ee;exports.useMozLocale=Z;exports.useValidatorContext=Te;
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../src/bridge/ReactRenderer.tsx","../src/locale/MozLocaleContext.tsx","../src/validator/ValidatorContext.tsx","../src/createMozComponent.tsx","../src/split-pane.tsx","../src/tooltip.tsx","../src/popover.tsx","../src/collapsible.tsx","../src/avatar.tsx","../src/scroll-area.tsx","../src/components.ts"],"sourcesContent":["import { createElement, type ComponentType, type ReactNode } from 'react';\nimport { createRoot, type Root } from 'react-dom/client';\n\n/**\n * React ↔ DOM 브릿지 (moz-ui-grid-react 의 ReactRenderer 패턴 복사 — grid 패키지 의존 없음).\n *\n * 헤드리스 코어가 slot outlet(빈 컨테이너)을 만들면, 이 브릿지가 소비자의 React 콘텐츠를\n * 그 컨테이너에 마운트/갱신/정리한다.\n *\n * - contextWrapper 옵션으로 외부 Provider 트리(Locale 등)를 각 root 에 주입\n * - unmountAll() 로 일괄 정리 (메모리 누수 방지)\n */\nexport type ContextWrapper = (children: ReactNode) => ReactNode;\n\n/**\n * slot root 의 unmount 는 **매크로태스크**로 미룬다 (mozart-cloud issue 915).\n *\n * `root.unmount()` 는 내부적으로 `flushSync` 다. 예전처럼 마이크로태스크에서 부르면 메인 root 에\n * 대기 중인 sync 업데이트(트리거 리렌더의 ref 재호출, 슬롯 재fill 의 setState 등)를 그 자리에서\n * 커밋시키고, 그 커밋이 다시 슬롯을 갈아엎어 또 unmount 를 예약한다 — root 가 둘이라 React 의\n * 중첩 업데이트 가드(50회)가 root 마다 리셋되어 한 task 안에서 끝없이 핑퐁한다(실측 커밋 4만 회).\n * `setTimeout(0)` 이면 React 스케줄러가 대기 업데이트를 먼저 정상 경로로 비운 뒤 unmount 하므로\n * 커플링이 끊긴다. 컨테이너 element 는 코어가 이미 떼어 냈으므로 화면에는 차이가 없다.\n * (commit 단계 내부의 동기 unmount 경고 회피라는 원래 목적도 그대로 충족한다.)\n */\nconst pendingUnmounts = new Set<Root>();\nlet unmountTimer: ReturnType<typeof setTimeout> | null = null;\n\nfunction deferUnmount(root: Root): void {\n pendingUnmounts.add(root);\n if (unmountTimer != null) return;\n unmountTimer = setTimeout(() => {\n unmountTimer = null;\n const batch = Array.from(pendingUnmounts);\n pendingUnmounts.clear();\n for (const r of batch) r.unmount();\n }, 0);\n}\n\nexport class ReactRenderer {\n private contextWrapper: ContextWrapper | null = null;\n private roots = new Set<Root>();\n\n /** 외부 Provider 트리를 캡처 */\n setContextWrapper(wrapper: ContextWrapper | null): void {\n this.contextWrapper = wrapper;\n }\n\n /**\n * 컨테이너 단위 인스턴스 마운트.\n * component(props) 를 컨테이너에 렌더하고, update(props) 로 갱신, destroy() 로 정리한다.\n */\n mountInstance(\n container: HTMLElement,\n component: ComponentType<any>,\n initialProps: Record<string, unknown>,\n ): { update: (props: Record<string, unknown>) => void; destroy: () => void } {\n const root = createRoot(container);\n this.roots.add(root);\n\n const renderProps = (props: Record<string, unknown>): void => {\n const element = createElement(component, props);\n root.render(this.contextWrapper ? this.contextWrapper(element) : element);\n };\n renderProps(initialProps);\n\n return {\n update: (props) => renderProps(props),\n destroy: () => {\n this.roots.delete(root);\n deferUnmount(root);\n },\n };\n }\n\n /** 전체 인스턴스 언마운트 */\n unmountAll(): void {\n for (const root of this.roots) deferUnmount(root);\n this.roots.clear();\n }\n\n get size(): number {\n return this.roots.size;\n }\n}\n","import { createContext, createElement, useContext, type ReactNode } from 'react';\nimport { koKR, type MozLocaleMessages } from '@vmscloud/moz-ui-components-core';\nimport type { ContextWrapper } from '../bridge/ReactRenderer';\n\n/**\n * React 로케일 — Vue 의 provide/inject 대응(context). Provider 없으면 koKR 기본값. per-subtree override.\n */\nexport const MozLocaleContext = createContext<MozLocaleMessages>(koKR);\n\n/**\n * slot 이 렌더될 때 감쌀 소비자 Provider 트리 (ITSM-2026-002233).\n *\n * slot 콘텐츠는 `ReactRenderer.mountInstance` 가 만드는 **독립 root** 에 렌더되므로\n * 소비자 앱의 React context 가 닿지 않는다. 소비자가 여기에 wrapper 를 주면 각 slot\n * root 가 그 트리 안에서 렌더돼 context 를 되찾는다. Provider 없으면 `null`(기존 동작).\n */\nexport const MozContextWrapperContext = createContext<ContextWrapper | null>(null);\n\nexport function MozConfigProvider({\n locale = koKR,\n contextWrapper,\n children,\n}: {\n locale?: MozLocaleMessages;\n /**\n * slot root 를 감쌀 함수. 소비자의 Provider 트리를 그대로 넘긴다.\n *\n * ```tsx\n * <MozConfigProvider contextWrapper={(node) => <QueryClientProvider client={qc}>{node}</QueryClientProvider>}>\n * ```\n *\n * **참조 동일성을 유지하세요** — 매 렌더 새 함수를 주면 마운트된 slot 이 매번 다시\n * 렌더된다. `useCallback` 이나 모듈 상수로 고정하는 것을 권장한다.\n */\n contextWrapper?: ContextWrapper;\n children?: ReactNode;\n}) {\n return createElement(\n MozLocaleContext.Provider,\n { value: locale },\n createElement(\n MozContextWrapperContext.Provider,\n { value: contextWrapper ?? null },\n children,\n ),\n );\n}\n\nexport function useMozLocale(): MozLocaleMessages {\n return useContext(MozLocaleContext);\n}\n\n/** 현재 트리에 설정된 slot context wrapper (없으면 `null`). */\nexport function useMozContextWrapper(): ContextWrapper | null {\n return useContext(MozContextWrapperContext);\n}\n","import { createContext, createElement, useContext, useRef, type ReactNode } from 'react';\nimport { createValidator, type RuleEventTarget, type ValidatorContext } from '@vmscloud/moz-ui-components-core';\n\n/** Vue 의 provide/inject('validateInput') 대응 (context) */\nexport const ValidatorReactContext = createContext<ValidatorContext | null>(null);\n\ninterface ValidatorApi {\n validate: (eventTarget?: RuleEventTarget) => Promise<boolean>;\n initValidator: () => void;\n}\n\n/**\n * Validator — 폼 컨텍스트 provider. children 은 노드 또는 render-prop({validate, initValidator}).\n */\nexport function Validator({\n children,\n}: {\n children?: ReactNode | ((api: ValidatorApi) => ReactNode);\n}) {\n const ref = useRef<ValidatorContext>();\n if (!ref.current) ref.current = createValidator();\n const api: ValidatorApi = { validate: ref.current.validate, initValidator: ref.current.initValidator };\n return createElement(\n ValidatorReactContext.Provider,\n { value: ref.current },\n typeof children === 'function' ? (children as (a: ValidatorApi) => ReactNode)(api) : children,\n );\n}\n\nexport function useValidatorContext(): ValidatorContext | null {\n return useContext(ValidatorReactContext);\n}\n","import {\n Fragment,\n createElement,\n forwardRef,\n useContext,\n useEffect,\n useImperativeHandle,\n useLayoutEffect,\n useRef,\n useState,\n} from 'react';\nimport { createPortal } from 'react-dom';\nimport type { CoreInstance, MozSpec, SlotRenderer } from '@vmscloud/moz-ui-components-core';\nimport { ReactRenderer } from './bridge/ReactRenderer';\nimport { useMozContextWrapper, useMozLocale } from './locale';\nimport { ValidatorReactContext } from './validator';\n\n/**\n * createMozComponent — 하나의 공용 React 브릿지.\n *\n * 헤드리스 코어(MozSpec)를 받아 React 컴포넌트를 만든다. props → 코어 props,\n * onXxx → 코어 emit, children/render-prop → slot 주입(ReactRenderer)을 이 파일 하나가 담당하고,\n * 각 컴포넌트는 스펙 1줄로 정의된다.\n *\n * NOTE(pilot): slot 은 ReactRenderer.mountInstance(독립 root)로 마운트한다. 소비자의 React\n * context/Suspense 를 그대로 유지하려면 createPortal 로 바꾸는 것이 다음 개선 (Decision Fork 2).\n * slot 콘텐츠의 최신 props 반영도 그 단계에서 강화한다.\n */\n/** Vue `update:x` / 코어 emit 이름 → React 관례 핸들러 prop 이름. emitFn 의 매핑과 1:1. */\nfunction handlerKeyOf(emitName: string): string {\n return emitName.startsWith('update:')\n ? 'on' + emitName.slice(7).charAt(0).toUpperCase() + emitName.slice(8) + 'Change'\n : 'on' + emitName.charAt(0).toUpperCase() + emitName.slice(1);\n}\n\n/**\n * 브릿지가 `ref` 로 노출하는 핸들 — 코어의 명령형 API + 코어가 그린 루트 element.\n *\n * `el` 이 필요한 이유: 브릿지는 위치 앵커로 `display:contents` 호스트 div 를 하나 렌더하고\n * 코어의 시맨틱 루트(`<button>`/`<input>` …)는 그 안에 그려진다. 소비자 어댑터가 루트에\n * 닿으려면 지금까지는 호스트 아래를 DOM 으로 훑어 추측해야 했고, 마크업이 바뀌면 조용히\n * 깨졌다. `el` 이 그 추측을 없앤다.\n */\nexport type MozHandle<API> = (API extends void ? unknown : API) & {\n readonly el: HTMLElement | null;\n};\n\n/** slot scope 의 얕은 동등 비교 — 코어는 렌더마다 새 객체를 만들지만 값은 대개 같다. */\nfunction sameScope(a: unknown, b: unknown): boolean {\n if (Object.is(a, b)) return true;\n if (typeof a !== 'object' || typeof b !== 'object' || a === null || b === null) return false;\n const ka = Object.keys(a as Record<string, unknown>);\n const kb = Object.keys(b as Record<string, unknown>);\n if (ka.length !== kb.length) return false;\n return ka.every((k) => Object.is((a as Record<string, unknown>)[k], (b as Record<string, unknown>)[k]));\n}\n\n/** 키 집합과 값(Object.is)이 모두 같으면 true — `replace` 갱신이라 키 소멸도 변경으로 본다. */\nfunction shallowEqualProps(a: Record<string, unknown>, b: Record<string, unknown>): boolean {\n const ka = Object.keys(a);\n const kb = Object.keys(b);\n if (ka.length !== kb.length) return false;\n for (const k of ka) {\n if (!Object.prototype.hasOwnProperty.call(b, k) || !Object.is(a[k], b[k])) return false;\n }\n return true;\n}\n\nexport function createMozComponent<P extends object, E, API>(spec: MozSpec<P, E, API>) {\n const models = (spec.models ?? {}) as Record<string, { prop: string; event: string }>;\n\n /**\n * rest 패스스루에서 제외할 키 — 스펙이 이미 소비하는 것들이다.\n *\n * 빠뜨리면 슬롯 콘텐츠(React 노드/함수)가 attribute 로 나가거나, emit 핸들러가 엉뚱한\n * DOM 이벤트 리스너로 등록된다(`spread` 는 `onXxx` 함수를 addEventListener 로 처리한다).\n */\n const reservedKeys = new Set<string>([\n ...spec.props,\n ...Object.keys(models),\n ...Object.values(models).map((m) => m.prop),\n ...(spec.slots ?? []).map((name) => (name === 'default' ? 'children' : name)),\n ...(spec.emits ?? []).map(handlerKeyOf),\n ...Object.keys(models).map((model) => handlerKeyOf(`update:${model}`)),\n ...Object.values(models).map((m) => handlerKeyOf(m.event)),\n 'children',\n 'className',\n 'style',\n 'id',\n 'key',\n 'ref',\n // 동적 slot 묶음 — `slots={{ 'a-tab': (scope) => …, a: <Panel/> }}`. Vue 브릿지는 소비자\n // slots 를 전부 등록하지만 React 는 스펙의 정적 목록만 알았다. 이름이 데이터에서 파생되는\n // 코어(Tab)는 이 통로 없이는 React 에서 콘텐츠를 받을 수 없었다.\n 'slots',\n ]);\n const Comp = forwardRef<MozHandle<API>, Record<string, any>>((props, ref) => {\n const host = useRef<HTMLDivElement>(null);\n const core = useRef<CoreInstance<P, API> | undefined>(undefined);\n /**\n * ref 로 노출할 **안정 핸들** — Vue 브릿지의 `expose(apiProxy)` 와 같은 방식이다.\n * 코어는 마운트 effect 에서야 생기므로, 객체를 먼저 만들어 두고 API 를 나중에 얹는다.\n *\n * `el` 은 브릿지 예약 키다. 코어 API 가 같은 이름을 쓰면 루트 접근이 조용히 가려지므로\n * 아래 병합에서 건너뛰고, `rootElementRef.test.tsx` 가 코어 쪽 `el` 사용을 막는다.\n */\n const handle = useRef<MozHandle<API> | undefined>(undefined);\n /**\n * 동적 slot(`slots` prop)의 outlet 들. 코어가 outlet 을 만들어 fill 을 요청하면 여기 기록하고,\n * 브릿지가 **자기 React 트리 안에서** `createPortal` 로 콘텐츠를 그린다. 독립 root 로 마운트\n * (정적 slot 의 방식)하면 Router·QueryClient 같은 소비자 context 가 끊겨, 페이지 서브트리를\n * 담는 패널(Tab)은 첫 훅에서 죽는다(소비처 실측: `useNavigate() … <Router>`). 포털은 context·\n * Suspense·act 를 소비자 트리 그대로 잇는다 — 코어 주석의 \"Decision Fork 2\" 가 이것이다.\n * 키는 코어가 outlet 마다 붙이는 `data-moz-slot-id`(반복 slot 도 고유).\n */\n const [portalSlots, setPortalSlots] = useState<\n Map<string, { name: string; el: HTMLElement; scope: unknown }>\n >(() => new Map());\n if (!handle.current) {\n const h = {} as MozHandle<API>;\n Object.defineProperty(h, 'el', {\n get: () => core.current?.el ?? null,\n enumerable: true,\n });\n handle.current = h;\n }\n const rendererRef = useRef<ReactRenderer>();\n if (!rendererRef.current) rendererRef.current = new ReactRenderer();\n\n // slot context wrapper: slot 은 독립 root 라 소비자 context 가 닿지 않는다\n // (ITSM-2026-002233). Provider 가 준 wrapper 를 renderer 에 넘겨 각 root 를 감싼다.\n // **렌더 중에 설정한다** — slot mount 는 아래 useLayoutEffect 에서 일어나므로\n // effect 로 미루면 첫 마운트가 wrapper 없이 렌더된다.\n const contextWrapper = useMozContextWrapper();\n rendererRef.current.setContextWrapper(contextWrapper);\n\n // 로케일: context 로 해석 (Provider 없으면 koKR). 코어엔 setLocale 채널로 전달.\n const locale = useMozLocale();\n // Validator: 부모 <Validator> context (없으면 null → standalone)\n const validatorCtx = useContext(ValidatorReactContext);\n\n // emit/slot 클로저가 항상 최신 props 를 참조하도록 ref 로 보관\n const propsRef = useRef(props);\n propsRef.current = props;\n\n const emitFn = ((name: any, ...args: any[]) => {\n // Vue 의 `update:X` (v-model) 는 React 관례 `onXChange` 로 매핑. 그 외는 `onX`.\n // `reservedKeys` 도 같은 함수를 쓴다 — 매핑이 갈라지면 emit 핸들러가 rest 로 새어\n // DOM 리스너로 등록되므로 반드시 한 곳에서 계산한다.\n const key = handlerKeyOf(String(name));\n const handler = propsRef.current[key];\n if (typeof handler === 'function') handler(...args);\n }) as any;\n\n const buildProps = (): P => {\n const src = propsRef.current;\n const p: Record<string, any> = {};\n // rest 를 먼저 깔고 명시 prop 이 덮어쓴다 — Vue 브릿지(`defineMozComponent`)의\n // `{ ...attrs }` 와 같은 순서다. 코어는 자신이 아는 키를 뺀 나머지를 `spread(rest)` 로\n // 루트 엘리먼트에 뿌리므로(runtime/spread.ts), 이 한 줄이 aria-*/data-*/title/role/\n // native type/rows 같은 임의 속성과 onXxx 리스너의 패스스루 경로가 된다.\n for (const k of Object.keys(src)) {\n if (reservedKeys.has(k)) continue;\n p[k] = src[k];\n }\n for (const k of spec.props) p[k] = src[k];\n for (const model of Object.keys(models)) p[models[model].prop] = src[model];\n // className/style/id 패스스루\n if (src.className != null) p.class = src.className;\n if (src.style != null) p.style = src.style;\n if (src.id != null) p.id = src.id;\n return p as P;\n };\n\n useLayoutEffect(() => {\n const R = rendererRef.current!;\n const slotMap: Record<string, SlotRenderer> = {};\n for (const name of spec.slots ?? []) {\n const key = name === 'default' ? 'children' : name;\n if (propsRef.current[key] == null) continue;\n slotMap[name] = (el, scope) => {\n const SlotComp = ({ scope: s }: { scope: unknown }) => {\n const content = propsRef.current[key];\n return (typeof content === 'function' ? content(s) : content) ?? null;\n };\n const handle = R.mountInstance(el, SlotComp as any, { scope });\n return { update: (s) => handle.update({ scope: s }), dispose: handle.destroy };\n };\n }\n // 동적 slot: 코어가 이름을 요청하는 시점에 propsRef 를 읽는다 — 마운트 뒤에 생긴 이름도 잡힌다.\n // 콘텐츠는 독립 root 가 아니라 포털로 그린다(위 portalSlots 주석).\n const slotResolver = (name: string): SlotRenderer | undefined => {\n const bag = propsRef.current.slots as Record<string, unknown> | undefined;\n if (bag == null || bag[name] == null) return undefined;\n return (el, scope) => {\n const key = el.getAttribute('data-moz-slot-id') ?? name;\n setPortalSlots((prev) => new Map(prev).set(key, { name, el, scope }));\n return {\n // scope 가 값까지 같으면 state 를 건드리지 않는다. 코어는 렌더마다 scope 객체를 새로\n // 만들어 fill 하므로, 무조건 setState 하면 브릿지 재렌더 → core.update → 다시 fill →\n // setState … 로 끝나지 않는 비동기 루프가 된다(소비처 실측: 페이지 테스트 타임아웃).\n update: (s) =>\n setPortalSlots((prev) => {\n const cur = prev.get(key);\n if (!cur || sameScope(cur.scope, s)) return prev;\n return new Map(prev).set(key, { ...cur, scope: s });\n }),\n dispose: () =>\n setPortalSlots((prev) => {\n if (!prev.has(key)) return prev;\n const next = new Map(prev);\n next.delete(key);\n return next;\n }),\n };\n };\n };\n core.current = spec.core(host.current as HTMLElement, buildProps(), emitFn, {\n slots: slotMap,\n slotResolver,\n locale,\n validator: validatorCtx ?? undefined,\n // 소비자가 실제로 넘긴 prop 키 (controlled 판별)\n providedKeys: Object.keys(propsRef.current),\n });\n // 코어 API 를 안정 핸들에 얹는다 (`el` 은 예약 키라 건너뛴다).\n const api = core.current.api as Record<string, unknown> | undefined;\n if (api) {\n for (const k of Object.keys(api)) {\n if (k === 'el') continue;\n (handle.current as unknown as Record<string, unknown>)[k] = api[k];\n }\n }\n return () => {\n core.current?.destroy();\n R.unmountAll();\n core.current = undefined;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n // 매 렌더 최신 props/로케일 을 코어로 반영 — 단, **바뀐 것이 없으면 건너뛴다**.\n // 소비처 트리의 무관한 리렌더(예: 툴팁 anchor 상태 변경)마다 코어를 update 하면 코어가\n // 템플릿을 다시 그리며 slot 을 재fill 하고, 그 재fill 이 브릿지 상태를 건드려 다시 리렌더되는\n // 루프의 한 축이 됐다(mozart-cloud issue 915). 마지막으로 보낸 props 와 얕은 비교한다.\n // slot 콘텐츠는 buildProps 에 들어가지 않지만(reservedKeys) 코어 update 가 slot 을 재fill 해야\n // 새 콘텐츠가 그려지므로, 정적 slot 값(문자열은 값·엘리먼트는 identity)과 동적 slot 이름 집합도\n // 비교 대상에 넣는다 — 라벨 문자열이 같은 리렌더는 건너뛰고, 바뀌면 예전처럼 update 한다.\n const slotSignature = (): Record<string, unknown> => {\n const src = propsRef.current;\n const sig: Record<string, unknown> = {};\n for (const name of spec.slots ?? []) {\n const key = name === 'default' ? 'children' : name;\n sig[key] = src[key];\n }\n const bag = src.slots as Record<string, unknown> | undefined;\n sig.__dynamicSlotKeys = bag ? Object.keys(bag).sort().join('\u0000') : '';\n return sig;\n };\n const lastSentRef = useRef<{\n props: Record<string, unknown>;\n slots: Record<string, unknown>;\n locale: typeof locale;\n } | null>(null);\n useEffect(() => {\n const c = core.current;\n if (!c) return;\n const next = buildProps() as Record<string, unknown>;\n const slots = slotSignature();\n const last = lastSentRef.current;\n if (\n last &&\n last.locale === locale &&\n shallowEqualProps(last.props, next) &&\n shallowEqualProps(last.slots, slots)\n )\n return;\n lastSentRef.current = { props: next, slots, locale };\n if (!last || last.locale !== locale) c.setLocale(locale);\n // 매 렌더 전체 prop 을 넘기므로 replace 로 갱신한다 — 병합하면 소비처가 조건부로\n // 뺀 prop(`aria-label` 등)이 지워지지 않고 DOM 에 남는다.\n c.update(next as P, { replace: true, sync: spec.syncUpdate });\n });\n\n useImperativeHandle(ref, () => handle.current as MozHandle<API>, []);\n\n const bag = props.slots as Record<string, unknown> | undefined;\n const portals = Array.from(portalSlots, ([key, p]) => {\n const content = bag?.[p.name];\n const node = (typeof content === 'function' ? content(p.scope) : content) ?? null;\n return createPortal(node, p.el, key);\n });\n return createElement(\n Fragment,\n null,\n createElement('div', { ref: host, style: { display: 'contents' } }),\n ...portals,\n );\n });\n Comp.displayName = spec.name;\n return Comp;\n}\n","import { Children, isValidElement, type ReactElement, type ReactNode } from 'react';\nimport { SPLITPANE_SPEC, type PaneConfig } from '@vmscloud/moz-ui-components-core';\nimport { createMozComponent } from './createMozComponent';\n\n// 코어 구동 컴포넌트(panes 배열 + pane-N 프롭) — 커스텀 래퍼가 내부적으로 사용.\nconst MozSplitPane = createMozComponent(SPLITPANE_SPEC);\n\nexport interface PaneProps {\n size?: number | string;\n minSize?: number | string;\n maxSize?: number | string;\n hidden?: boolean;\n children?: ReactNode;\n}\n\n/**\n * Pane — SplitPane 자식 마커. 직접 렌더되지 않고(반환 null) 부모 SplitPane 이 props/children 을 읽는다.\n */\nexport const Pane = (_props: PaneProps): null => null;\n\nexport interface SplitPaneProps {\n horizontal?: boolean;\n children?: ReactNode;\n}\n\n/**\n * SplitPane — 원본 사용법 그대로: `<SplitPane><Pane size=\"..\">A</Pane>…</SplitPane>`.\n *\n * 자식 `<Pane>` 엘리먼트를 읽어 코어의 `panes` 배열 + `pane-N` 슬롯(프롭)으로 변환한다.\n * React.Children introspection 은 React 전용이라 코어가 아닌 이 래퍼가 담당. (최대 8 패널 — 코어 spec.slots.)\n */\nexport const SplitPane = ({ horizontal, children }: SplitPaneProps) => {\n const paneEls = Children.toArray(children).filter(\n (c): c is ReactElement<PaneProps> => isValidElement(c) && c.type === Pane,\n );\n\n const panes: PaneConfig[] = paneEls.map((c) => ({\n size: c.props.size,\n minSize: c.props.minSize,\n maxSize: c.props.maxSize,\n hidden: c.props.hidden,\n }));\n\n const paneProps: Record<string, ReactNode> = {};\n paneEls.forEach((c, i) => {\n paneProps[`pane-${i}`] = c.props.children;\n });\n\n return <MozSplitPane panes={panes} horizontal={horizontal} {...paneProps} />;\n};\n","import {\n cloneElement,\n createContext,\n isValidElement,\n useCallback,\n useContext,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n type CSSProperties,\n type FocusEvent as ReactFocusEvent,\n type MouseEvent as ReactMouseEvent,\n type PointerEvent as ReactPointerEvent,\n type ReactElement,\n type ReactNode,\n type Ref,\n useLayoutEffect,\n} from 'react';\nimport { TOOLTIP_SPEC, type TooltipAlign, type TooltipSide } from '@vmscloud/moz-ui-components-core';\nimport { createMozComponent } from './createMozComponent';\n\n/**\n * Tooltip — 코어 버블 위의 React 전용 컴파운드 래퍼.\n *\n * 다른 컴포넌트처럼 `createMozComponent(SPEC)` 한 줄로 끝나지 않는 이유는 SplitPane 과 같다:\n * 툴팁의 **트리거는 소비처가 이미 렌더한 React 엘리먼트**이고, 그 엘리먼트에 ref·포인터·포커스\n * 핸들러·`aria-describedby` 를 얹는 일은 React 에서만 할 수 있다. 코어는 앵커 element 를 받아\n * 버블만 그리고, 지연·hover 판단·전역 단일화는 여기서 한다.\n *\n * 콘텐츠는 브릿지의 **동적 slot 경로**(`slots={{ content: … }}`)로 넘긴다. 그 경로는 브릿지가\n * 자기 React 트리 안에서 `createPortal` 로 그리므로 소비자 context(Router·QueryClient·테마)가\n * 그대로 이어진다 — 정적 slot 은 독립 root 로 마운트돼 context 가 끊긴다.\n *\n * 열림 경로는 셋이다: 트리거 위 `pointermove` / `mouseenter`(지연 후), 트리거로 버블링된\n * `focus`(지연 없이 즉시 — 키보드 사용자는 기다릴 이유가 없다). 닫힘은 `pointerleave`·`blur`·\n * `pointerdown`·ESC 이며, **즉시 언마운트**한다(닫힘 애니메이션 없음).\n */\n\nconst MozTooltipCore = createMozComponent(TOOLTIP_SPEC);\n\n/** 열려 있는 툴팁의 닫기 함수들 — 하나가 열리면 나머지를 닫는다(전역 단일화) */\nconst openTooltips = new Set<() => void>();\n\nconst DEFAULT_DELAY = 200;\n/** hoverable 콘텐츠로 포인터가 건너갈 여유 */\nconst CLOSE_GRACE_MS = 100;\n\ninterface TooltipProviderValue {\n delayDuration: number;\n disableHoverableContent: boolean;\n}\n\nconst TooltipProviderContext = createContext<TooltipProviderValue>({\n delayDuration: DEFAULT_DELAY,\n disableHoverableContent: false,\n});\n\nexport interface TooltipProviderProps {\n /** 포인터로 열릴 때까지의 지연(ms). 포커스는 이 값과 무관하게 즉시 연다 */\n delayDuration?: number;\n /** true 면 트리거를 벗어나는 즉시 닫는다(콘텐츠 위 hover 유지 안 함) */\n disableHoverableContent?: boolean;\n children?: ReactNode;\n}\n\nexport function TooltipProvider({\n delayDuration = DEFAULT_DELAY,\n disableHoverableContent = false,\n children,\n}: TooltipProviderProps) {\n const value = useMemo(\n () => ({ delayDuration, disableHoverableContent }),\n [delayDuration, disableHoverableContent],\n );\n return <TooltipProviderContext.Provider value={value}>{children}</TooltipProviderContext.Provider>;\n}\n\ninterface TooltipRootValue {\n open: boolean;\n contentId: string;\n anchor: HTMLElement | null;\n setAnchor: (el: HTMLElement | null) => void;\n hoverable: boolean;\n openNow: () => void;\n openDelayed: () => void;\n closeNow: () => void;\n closeSoon: () => void;\n cancelClose: () => void;\n}\n\nconst TooltipRootContext = createContext<TooltipRootValue | null>(null);\n\nfunction useTooltipRoot(component: string): TooltipRootValue {\n const ctx = useContext(TooltipRootContext);\n if (!ctx) throw new Error(`${component} 는 <Tooltip> 안에서만 쓸 수 있습니다.`);\n return ctx;\n}\n\nexport interface TooltipProps {\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n /** Provider 값을 이 툴팁에 한해 덮어쓴다 */\n delayDuration?: number;\n disableHoverableContent?: boolean;\n children?: ReactNode;\n}\n\nexport function Tooltip({\n open: openProp,\n defaultOpen = false,\n onOpenChange,\n delayDuration,\n disableHoverableContent,\n children,\n}: TooltipProps) {\n const provider = useContext(TooltipProviderContext);\n const delay = delayDuration ?? provider.delayDuration;\n const hoverable = !(disableHoverableContent ?? provider.disableHoverableContent);\n\n const [uncontrolled, setUncontrolled] = useState(defaultOpen);\n const controlled = openProp !== undefined;\n const open = controlled ? Boolean(openProp) : uncontrolled;\n\n const [anchor, setAnchor] = useState<HTMLElement | null>(null);\n const contentId = `moz-tooltip-${useId()}`;\n\n const openTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n const closeTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const onOpenChangeRef = useRef(onOpenChange);\n onOpenChangeRef.current = onOpenChange;\n\n const clearTimers = useCallback(() => {\n if (openTimer.current) clearTimeout(openTimer.current);\n if (closeTimer.current) clearTimeout(closeTimer.current);\n openTimer.current = null;\n closeTimer.current = null;\n }, []);\n\n const setOpen = useCallback(\n (next: boolean) => {\n if (!controlled) setUncontrolled(next);\n onOpenChangeRef.current?.(next);\n },\n [controlled],\n );\n\n const openNow = useCallback(() => {\n clearTimers();\n setOpen(true);\n }, [clearTimers, setOpen]);\n\n const openDelayed = useCallback(() => {\n if (closeTimer.current) {\n clearTimeout(closeTimer.current);\n closeTimer.current = null;\n }\n if (openTimer.current) return;\n if (delay <= 0) {\n setOpen(true);\n return;\n }\n openTimer.current = setTimeout(() => {\n openTimer.current = null;\n setOpen(true);\n }, delay);\n }, [delay, setOpen]);\n\n const closeNow = useCallback(() => {\n clearTimers();\n setOpen(false);\n }, [clearTimers, setOpen]);\n\n const closeSoon = useCallback(() => {\n if (openTimer.current) {\n clearTimeout(openTimer.current);\n openTimer.current = null;\n }\n // 콘텐츠 위 hover 를 유지하지 않는다면 유예 없이 바로 닫는다.\n if (!hoverable) {\n setOpen(false);\n return;\n }\n if (closeTimer.current) return;\n closeTimer.current = setTimeout(() => {\n closeTimer.current = null;\n setOpen(false);\n }, CLOSE_GRACE_MS);\n }, [hoverable, setOpen]);\n\n const cancelClose = useCallback(() => {\n if (closeTimer.current) {\n clearTimeout(closeTimer.current);\n closeTimer.current = null;\n }\n }, []);\n\n // 언마운트 시 타이머 정리\n useEffect(() => clearTimers, [clearTimers]);\n\n // 전역 단일화 + ESC — 열려 있는 동안에만 건다.\n const closeRef = useRef(closeNow);\n closeRef.current = closeNow;\n useEffect(() => {\n if (!open) return undefined;\n const self = () => closeRef.current();\n for (const other of Array.from(openTooltips)) other();\n openTooltips.add(self);\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape') closeRef.current();\n };\n document.addEventListener('keydown', onKeyDown);\n return () => {\n openTooltips.delete(self);\n document.removeEventListener('keydown', onKeyDown);\n };\n }, [open]);\n\n const value = useMemo<TooltipRootValue>(\n () => ({\n open,\n contentId,\n anchor,\n setAnchor,\n hoverable,\n openNow,\n openDelayed,\n closeNow,\n closeSoon,\n cancelClose,\n }),\n [open, contentId, anchor, hoverable, openNow, openDelayed, closeNow, closeSoon, cancelClose],\n );\n\n return <TooltipRootContext.Provider value={value}>{children}</TooltipRootContext.Provider>;\n}\n\n/** 소비처 핸들러를 먼저 실행하고 툴팁 핸들러를 잇는다 (소비처 동작을 가리지 않는다) */\nfunction chain<E>(theirs: unknown, ours: () => void) {\n return (event: E) => {\n if (typeof theirs === 'function') (theirs as (e: E) => void)(event);\n ours();\n };\n}\n\nfunction applyRef<T>(ref: Ref<T> | undefined, node: T | null): void {\n if (!ref) return;\n if (typeof ref === 'function') ref(node);\n else (ref as { current: T | null }).current = node;\n}\n\nexport interface TooltipTriggerProps {\n /** true 면 래퍼 없이 children 을 그대로 트리거로 쓴다(말줄임·레이아웃 보존) */\n asChild?: boolean;\n children?: ReactNode;\n}\n\nexport function TooltipTrigger({ asChild = false, children }: TooltipTriggerProps) {\n const ctx = useTooltipRoot('TooltipTrigger');\n const { open, contentId, setAnchor, openNow, openDelayed, closeNow, closeSoon } = ctx;\n\n const child = isValidElement(children) ? (children as ReactElement<Record<string, unknown>>) : null;\n const childProps = (child?.props ?? {}) as Record<string, unknown>;\n\n // ref 콜백의 identity 를 고정한다(mozart-cloud issue 915). 예전에는 `child` 를 deps 로 두어\n // 트리거가 리렌더될 때마다 새 콜백이 만들어졌고, React 는 콜백이 바뀌면 이전 콜백에 null,\n // 새 콜백에 node 를 다시 호출하므로 `setAnchor(null)`→`setAnchor(node)` 가 매 리렌더마다\n // 재발생했다. 툴팁이 열린 채 트리거가 리렌더되는 조합(클릭으로 className 이 바뀌는 MozButton)\n // 에서는 그 상태 변경이 콘텐츠를 내리고 다시 올리며, 슬롯 root 의 unmount(flushSync) 와 메인\n // root 커밋이 동기로 핑퐁해 렌더러가 멈췄다. 소비처 child 의 ref 는 최신 값을 ref 로 읽어 잇는다.\n const childRef = (child as { ref?: Ref<HTMLElement> } | null)?.ref;\n const childRefRef = useRef<Ref<HTMLElement> | undefined>(childRef);\n childRefRef.current = childRef;\n const anchorNodeRef = useRef<HTMLElement | null>(null);\n const setRef = useCallback(\n (node: HTMLElement | null) => {\n anchorNodeRef.current = node;\n setAnchor(node);\n applyRef(childRefRef.current, node);\n },\n [setAnchor],\n );\n // child 의 ref 가 다른 객체/콜백으로 바뀌면(리렌더마다 새 인라인 콜백 등) 현재 anchor 를 새 ref\n // 에도 전달한다 — React 가 ref 교체 시 하던 일 중 \"새 ref 에 node\" 만 남기고 \"이전 ref 에 null\" 은\n // 하지 않는다(anchor 상태를 흔들지 않기 위해).\n const appliedChildRef = useRef<Ref<HTMLElement> | undefined>(childRef);\n useLayoutEffect(() => {\n if (appliedChildRef.current === childRef) return;\n appliedChildRef.current = childRef;\n applyRef(childRef, anchorNodeRef.current);\n });\n\n const handlers = {\n ref: setRef,\n // pointermove·mouseenter 둘 다 받는다 — 포인터 종류·테스트 도구에 따라 어느 하나만 오는\n // 경우가 있어(예: fireEvent.pointerMove / fireEvent.mouseOver) 한쪽만 걸면 조용히 안 열린다.\n onPointerMove: chain<ReactPointerEvent<HTMLElement>>(childProps.onPointerMove, openDelayed),\n onMouseEnter: chain<ReactMouseEvent<HTMLElement>>(childProps.onMouseEnter, openDelayed),\n onPointerLeave: chain<ReactPointerEvent<HTMLElement>>(childProps.onPointerLeave, closeSoon),\n onMouseLeave: chain<ReactMouseEvent<HTMLElement>>(childProps.onMouseLeave, closeSoon),\n // 클릭하러 온 것이므로 즉시 치운다(누른 순간 가려지지 않게).\n onPointerDown: chain<ReactPointerEvent<HTMLElement>>(childProps.onPointerDown, closeNow),\n // 포커스는 지연 없이 — 버블링된 focus 도 받는다(트리거가 감싼 span 인 경우).\n onFocus: chain<ReactFocusEvent<HTMLElement>>(childProps.onFocus, openNow),\n onBlur: chain<ReactFocusEvent<HTMLElement>>(childProps.onBlur, closeNow),\n 'aria-describedby': open ? contentId : (childProps['aria-describedby'] as string | undefined),\n // 트리거는 열림 상태를 attribute 로도 노출한다 — 소비처가 열려 있는 동안의 트리거 스타일을\n // CSS 만으로 걸 수 있고(`[data-state='open']`), \"툴팁이 배선됐는가\" 를 DOM 에서 확인할 수 있다.\n 'data-state': open ? 'open' : 'closed',\n };\n\n if (asChild && child) return cloneElement(child, handlers);\n return <span {...handlers}>{children}</span>;\n}\n\nexport interface TooltipContentProps {\n side?: TooltipSide;\n align?: TooltipAlign;\n sideOffset?: number;\n collisionPadding?: number;\n /** 화살표 렌더 (기본 true) */\n arrow?: boolean;\n className?: string;\n style?: CSSProperties;\n children?: ReactNode;\n [attr: string]: unknown;\n}\n\nexport function TooltipContent({\n side = 'top',\n align = 'center',\n sideOffset = 8,\n collisionPadding = 8,\n arrow = true,\n className,\n style,\n children,\n ...rest\n}: TooltipContentProps) {\n const ctx = useTooltipRoot('TooltipContent');\n const { open, anchor, contentId, hoverable, cancelClose, closeSoon } = ctx;\n\n // 코어는 이 핸들러를 addEventListener 로 **붙일 당시의 함수**로 등록한다(ITSM-2026-002299).\n // identity 를 고정하고 최신 콜백은 ref 로 읽는다.\n const hoverRef = useRef({ cancelClose, closeSoon });\n hoverRef.current = { cancelClose, closeSoon };\n const onBubbleEnter = useCallback(() => hoverRef.current.cancelClose(), []);\n const onBubbleLeave = useCallback(() => hoverRef.current.closeSoon(), []);\n\n const slots = useMemo(() => ({ content: children }), [children]);\n\n return (\n <MozTooltipCore\n open={open}\n anchor={anchor}\n side={side}\n align={align}\n sideOffset={sideOffset}\n collisionPadding={collisionPadding}\n arrow={arrow}\n tooltipId={contentId}\n className={className}\n style={style}\n slots={slots}\n data-hoverable={hoverable ? 'true' : undefined}\n onPointerEnter={hoverable ? onBubbleEnter : undefined}\n onPointerLeave={hoverable ? onBubbleLeave : undefined}\n {...rest}\n />\n );\n}\n","import {\n cloneElement,\n createContext,\n isValidElement,\n useCallback,\n useContext,\n useId,\n useMemo,\n useRef,\n useState,\n type CSSProperties,\n type MouseEvent as ReactMouseEvent,\n type ReactElement,\n type ReactNode,\n type Ref,\n} from 'react';\nimport {\n POPOVER_SPEC,\n type PopoverAlign,\n type PopoverCloseReason,\n type PopoverSide,\n} from '@vmscloud/moz-ui-components-core';\nimport { createMozComponent } from './createMozComponent';\n\n/**\n * Popover — 코어 패널 위의 React 전용 컴파운드 래퍼.\n *\n * Tooltip 과 같은 이유의 전용 래퍼다: 트리거·앵커가 **소비처가 이미 렌더한 React 엘리먼트**\n * 이고, 거기에 ref·클릭 토글·`aria-expanded`/`aria-controls` 를 얹는 일은 React 에서만 할 수\n * 있다. 코어는 앵커 element 를 받아 패널만 그리고, 상태·이벤트 배선은 여기서 한다.\n *\n * 콘텐츠는 브릿지의 **동적 slot 경로**(`slots={{ content: … }}`)로 넘긴다 — 소비자 React 트리\n * 안에서 `createPortal` 로 그려지므로 Router·QueryClient·테마 context 가 그대로 이어진다.\n *\n * 닫힘 계약은 코어의 `DismissStack` 이 담당한다. ESC 는 `window` capture 에서 **최상위 레이어**\n * 에만 전달되고 전파가 끊기므로, 다른 라이브러리의 모달 안에 이 팝오버가 있어도 바깥 레이어가\n * 함께 닫히지 않는다. 반대로 팝오버 위에 다른 라이브러리 모달이 열리면 소비 앱이\n * `registerForeignLayer()` 로 알려 이쪽이 ESC 에 손대지 않는다.\n */\n\nconst MozPopoverCore = createMozComponent(POPOVER_SPEC);\n\ninterface PopoverContextValue {\n open: boolean;\n setOpen: (next: boolean) => void;\n contentId: string;\n triggerEl: HTMLElement | null;\n anchorEl: HTMLElement | null;\n setTriggerEl: (el: HTMLElement | null) => void;\n setAnchorEl: (el: HTMLElement | null) => void;\n}\n\nconst PopoverContext = createContext<PopoverContextValue | null>(null);\n\nfunction usePopover(component: string): PopoverContextValue {\n const ctx = useContext(PopoverContext);\n if (!ctx) throw new Error(`${component} 는 <Popover> 안에서만 쓸 수 있습니다.`);\n return ctx;\n}\n\nfunction composeRefs<T>(...refs: Array<Ref<T> | undefined>) {\n return (node: T | null) => {\n for (const r of refs) {\n if (!r) continue;\n if (typeof r === 'function') r(node);\n else (r as { current: T | null }).current = node;\n }\n };\n}\n\nfunction chain<E>(theirs: unknown, ours: (event: E) => void) {\n return (event: E) => {\n if (typeof theirs === 'function') (theirs as (e: E) => void)(event);\n ours(event);\n };\n}\n\nexport interface PopoverProps {\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n children?: ReactNode;\n}\n\nexport function Popover({ open: openProp, defaultOpen = false, onOpenChange, children }: PopoverProps) {\n const [uncontrolled, setUncontrolled] = useState(defaultOpen);\n const controlled = openProp !== undefined;\n const open = controlled ? Boolean(openProp) : uncontrolled;\n\n const [triggerEl, setTriggerEl] = useState<HTMLElement | null>(null);\n const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null);\n const contentId = `moz-popover-${useId()}`;\n\n const onOpenChangeRef = useRef(onOpenChange);\n onOpenChangeRef.current = onOpenChange;\n\n const setOpen = useCallback(\n (next: boolean) => {\n if (!controlled) setUncontrolled(next);\n onOpenChangeRef.current?.(next);\n },\n [controlled],\n );\n\n const value = useMemo<PopoverContextValue>(\n () => ({ open, setOpen, contentId, triggerEl, anchorEl, setTriggerEl, setAnchorEl }),\n [open, setOpen, contentId, triggerEl, anchorEl],\n );\n\n return <PopoverContext.Provider value={value}>{children}</PopoverContext.Provider>;\n}\n\nexport interface PopoverTriggerProps {\n /** true 면 래퍼 없이 children 을 그대로 트리거로 쓴다 */\n asChild?: boolean;\n children?: ReactNode;\n}\n\nexport function PopoverTrigger({ asChild = false, children }: PopoverTriggerProps) {\n const { open, setOpen, contentId, setTriggerEl } = usePopover('PopoverTrigger');\n const child = isValidElement(children) ? (children as ReactElement<Record<string, unknown>>) : null;\n const childProps = (child?.props ?? {}) as Record<string, unknown>;\n\n const setRef = useMemo(\n () => composeRefs<HTMLElement>(setTriggerEl, (child as { ref?: Ref<HTMLElement> } | null)?.ref),\n [setTriggerEl, child],\n );\n\n const props = {\n ref: setRef,\n onClick: chain<ReactMouseEvent<HTMLElement>>(childProps.onClick, () => setOpen(!open)),\n 'aria-haspopup': 'dialog' as const,\n 'aria-expanded': open,\n 'aria-controls': open ? contentId : undefined,\n 'data-state': open ? 'open' : 'closed',\n };\n\n if (asChild && child) return cloneElement(child, props);\n return <span {...props}>{children}</span>;\n}\n\nexport interface PopoverAnchorProps {\n /** true 면 래퍼 없이 children 을 그대로 위치 기준으로 쓴다 */\n asChild?: boolean;\n children?: ReactNode;\n}\n\n/** 트리거와 위치 기준을 분리하고 싶을 때 쓴다. 클릭 토글·aria 는 붙지 않는다. */\nexport function PopoverAnchor({ asChild = false, children }: PopoverAnchorProps) {\n const { setAnchorEl } = usePopover('PopoverAnchor');\n const child = isValidElement(children) ? (children as ReactElement<Record<string, unknown>>) : null;\n\n const setRef = useMemo(\n () => composeRefs<HTMLElement>(setAnchorEl, (child as { ref?: Ref<HTMLElement> } | null)?.ref),\n [setAnchorEl, child],\n );\n\n if (asChild && child) return cloneElement(child, { ref: setRef });\n return <span ref={setRef}>{children}</span>;\n}\n\nexport interface PopoverCloseProps {\n asChild?: boolean;\n children?: ReactNode;\n}\n\nexport function PopoverClose({ asChild = false, children }: PopoverCloseProps) {\n const { setOpen } = usePopover('PopoverClose');\n const child = isValidElement(children) ? (children as ReactElement<Record<string, unknown>>) : null;\n const childProps = (child?.props ?? {}) as Record<string, unknown>;\n const props = {\n onClick: chain<ReactMouseEvent<HTMLElement>>(childProps.onClick, () => setOpen(false)),\n };\n if (asChild && child) return cloneElement(child, props);\n return <button type=\"button\" {...props}>{children}</button>;\n}\n\nexport interface PopoverContentProps {\n side?: PopoverSide;\n align?: PopoverAlign;\n sideOffset?: number;\n collisionPadding?: number;\n /** 패널 폭을 트리거 폭에 맞춘다. `--moz-popover-trigger-width` 는 값과 무관하게 항상 실린다 */\n matchTriggerWidth?: boolean;\n /** 열린 동안 Tab 을 패널 안에서 순환시킨다 (기본 true) */\n trapFocus?: boolean;\n className?: string;\n style?: CSSProperties;\n /** 열린 직후 자동 포커스 전 — `preventDefault()` 로 막는다 */\n onOpenAutoFocus?: (event: CustomEvent) => void;\n /** 닫힌 직후 포커스 복원 전 — `preventDefault()` 로 막는다 */\n onCloseAutoFocus?: (event: CustomEvent) => void;\n /** 최상위일 때의 ESC — `preventDefault()` 로 닫힘을 막는다 */\n onEscapeKeyDown?: (event: KeyboardEvent) => void;\n /** 패널 바깥 포인터 다운 — `preventDefault()` 로 닫힘을 막는다. 트리거·앵커 위는 제외된다 */\n onInteractOutside?: (event: CustomEvent<{ originalEvent: Event }>) => void;\n children?: ReactNode;\n [attr: string]: unknown;\n}\n\nexport function PopoverContent({\n side = 'bottom',\n align = 'start',\n sideOffset = 4,\n collisionPadding = 8,\n matchTriggerWidth = false,\n trapFocus = true,\n className,\n style,\n onOpenAutoFocus,\n onCloseAutoFocus,\n onEscapeKeyDown,\n onInteractOutside,\n children,\n ...rest\n}: PopoverContentProps) {\n const { open, setOpen, contentId, triggerEl, anchorEl } = usePopover('PopoverContent');\n\n // 코어는 이 핸들러들을 붙일 당시의 함수로 기억할 수 있다(ITSM-2026-002299) — identity 를\n // 고정하고 최신 콜백은 ref 로 읽는다.\n const latest = useRef({ setOpen, triggerEl, anchorEl, onOpenAutoFocus, onCloseAutoFocus, onEscapeKeyDown, onInteractOutside });\n latest.current = { setOpen, triggerEl, anchorEl, onOpenAutoFocus, onCloseAutoFocus, onEscapeKeyDown, onInteractOutside };\n\n const handleRequestClose = useCallback((_reason: PopoverCloseReason) => {\n latest.current.setOpen(false);\n }, []);\n\n const handleEscapeKeyDown = useCallback((event: KeyboardEvent) => {\n latest.current.onEscapeKeyDown?.(event);\n }, []);\n\n const handleInteractOutside = useCallback((event: CustomEvent<{ originalEvent: Event }>) => {\n // 트리거·앵커 위의 포인터 다운은 \"바깥\" 이 아니다. 트리거는 자기 클릭으로 토글하고,\n // 앵커는 입력창을 품는 경우가 있어(검색형 팝오버) 닫으면 안 된다.\n const target = event.detail?.originalEvent?.target as Node | null;\n const { triggerEl: trigger, anchorEl: anchor } = latest.current;\n if (target && ((trigger && trigger.contains(target)) || (anchor && anchor.contains(target)))) {\n event.preventDefault();\n return;\n }\n latest.current.onInteractOutside?.(event);\n }, []);\n\n const handleOpenAutoFocus = useCallback((event: CustomEvent) => {\n latest.current.onOpenAutoFocus?.(event);\n }, []);\n\n const handleCloseAutoFocus = useCallback((event: CustomEvent) => {\n latest.current.onCloseAutoFocus?.(event);\n }, []);\n\n const slots = useMemo(() => ({ content: children }), [children]);\n\n return (\n <MozPopoverCore\n open={open}\n anchor={anchorEl ?? triggerEl}\n side={side}\n align={align}\n sideOffset={sideOffset}\n collisionPadding={collisionPadding}\n matchTriggerWidth={matchTriggerWidth}\n trapFocus={trapFocus}\n popoverId={contentId}\n className={className}\n style={style}\n slots={slots}\n onRequestClose={handleRequestClose}\n onEscapeKeyDown={handleEscapeKeyDown}\n onInteractOutside={handleInteractOutside}\n onOpenAutoFocus={handleOpenAutoFocus}\n onCloseAutoFocus={handleCloseAutoFocus}\n {...rest}\n />\n );\n}\n","import {\n cloneElement,\n createContext,\n isValidElement,\n useCallback,\n useContext,\n useId,\n useMemo,\n useRef,\n useState,\n type CSSProperties,\n type MouseEvent as ReactMouseEvent,\n type ReactElement,\n type ReactNode,\n type Ref,\n} from 'react';\nimport { COLLAPSIBLE_SPEC } from '@vmscloud/moz-ui-components-core';\nimport { createMozComponent } from './createMozComponent';\n\n/**\n * Collapsible — 코어 콘텐츠 패널 위의 React 전용 컴파운드 래퍼.\n *\n * Tooltip·Popover 와 같은 이유의 전용 래퍼다: 트리거가 **소비처가 이미 렌더한 React 엘리먼트**\n * (버튼·행 헤더·아이콘 조합)이고, 거기에 클릭 토글·`aria-expanded`/`aria-controls` 를 얹는 일은\n * React 에서만 할 수 있다. 코어는 패널만 그리고, 상태·이벤트 배선은 여기서 한다.\n *\n * 콘텐츠는 브릿지의 **동적 slot 경로**(`slots={{ content: … }}`)로 넘긴다 — 소비자 React 트리\n * 안에서 `createPortal` 로 그려지므로 Router·QueryClient·테마 context 가 그대로 이어진다.\n *\n * 열림 상태는 controlled(`open`)/uncontrolled(`defaultOpen`) 둘 다 지원한다. controlled 에서는\n * 클릭이 내부 상태를 바꾸지 않고 `onOpenChange` 만 호출한다.\n */\n\nconst MozCollapsibleCore = createMozComponent(COLLAPSIBLE_SPEC);\n\ninterface CollapsibleContextValue {\n open: boolean;\n setOpen: (next: boolean) => void;\n contentId: string;\n disabled: boolean;\n}\n\nconst CollapsibleContext = createContext<CollapsibleContextValue | null>(null);\n\nfunction useCollapsible(component: string): CollapsibleContextValue {\n const ctx = useContext(CollapsibleContext);\n if (!ctx) throw new Error(`${component} 는 <Collapsible> 안에서만 쓸 수 있습니다.`);\n return ctx;\n}\n\nfunction composeRefs<T>(...refs: Array<Ref<T> | undefined>) {\n return (node: T | null) => {\n for (const r of refs) {\n if (!r) continue;\n if (typeof r === 'function') r(node);\n else (r as { current: T | null }).current = node;\n }\n };\n}\n\nfunction chain<E>(theirs: unknown, ours: (event: E) => void) {\n return (event: E) => {\n if (typeof theirs === 'function') (theirs as (e: E) => void)(event);\n ours(event);\n };\n}\n\n/** `asChild` 로 합칠 때 소비처 className 을 지우지 않는다. */\nfunction mergeClassName(theirs: unknown, ours: string | undefined): string | undefined {\n const merged = [theirs, ours].filter((v) => typeof v === 'string' && v.length > 0).join(' ');\n return merged.length > 0 ? merged : undefined;\n}\n\nexport interface CollapsibleProps {\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n disabled?: boolean;\n /** true 면 래퍼 div 없이 children 을 그대로 루트로 쓴다 */\n asChild?: boolean;\n className?: string;\n style?: CSSProperties;\n children?: ReactNode;\n [attr: string]: unknown;\n}\n\nexport function Collapsible({\n open: openProp,\n defaultOpen = false,\n onOpenChange,\n disabled = false,\n asChild = false,\n className,\n style,\n children,\n ...rest\n}: CollapsibleProps) {\n const [uncontrolled, setUncontrolled] = useState(defaultOpen);\n const controlled = openProp !== undefined;\n const open = controlled ? Boolean(openProp) : uncontrolled;\n\n const contentId = `moz-collapsible-${useId()}`;\n\n const onOpenChangeRef = useRef(onOpenChange);\n onOpenChangeRef.current = onOpenChange;\n\n const setOpen = useCallback(\n (next: boolean) => {\n if (!controlled) setUncontrolled(next);\n onOpenChangeRef.current?.(next);\n },\n [controlled],\n );\n\n const value = useMemo<CollapsibleContextValue>(\n () => ({ open, setOpen, contentId, disabled }),\n [open, setOpen, contentId, disabled],\n );\n\n const rootProps: Record<string, unknown> = {\n 'data-state': open ? 'open' : 'closed',\n 'data-disabled': disabled ? '' : undefined,\n ...rest,\n };\n\n const child = isValidElement(children) ? (children as ReactElement<Record<string, unknown>>) : null;\n const body =\n asChild && child ? (\n cloneElement(child, {\n ...rootProps,\n className: mergeClassName(child.props.className, className),\n style: (style ?? child.props.style) as CSSProperties | undefined,\n })\n ) : (\n <div {...rootProps} className={className} style={style}>\n {children}\n </div>\n );\n\n return <CollapsibleContext.Provider value={value}>{body}</CollapsibleContext.Provider>;\n}\n\nexport interface CollapsibleTriggerProps {\n /** true 면 래퍼 없이 children 을 그대로 트리거로 쓴다 */\n asChild?: boolean;\n disabled?: boolean;\n className?: string;\n style?: CSSProperties;\n onClick?: (event: ReactMouseEvent<HTMLElement>) => void;\n children?: ReactNode;\n [attr: string]: unknown;\n}\n\nexport function CollapsibleTrigger({\n asChild = false,\n disabled: disabledProp,\n className,\n style,\n onClick,\n children,\n ...rest\n}: CollapsibleTriggerProps) {\n const { open, setOpen, contentId, disabled: rootDisabled } = useCollapsible('CollapsibleTrigger');\n const disabled = disabledProp ?? rootDisabled;\n\n const toggle = useCallback(() => {\n if (disabled) return;\n setOpen(!open);\n }, [disabled, open, setOpen]);\n\n const child = isValidElement(children) ? (children as ReactElement<Record<string, unknown>>) : null;\n const childProps = (child?.props ?? {}) as Record<string, unknown>;\n\n const shared: Record<string, unknown> = {\n 'aria-expanded': open,\n 'aria-controls': contentId,\n 'data-state': open ? 'open' : 'closed',\n 'data-disabled': disabled ? '' : undefined,\n ...rest,\n };\n\n if (asChild && child) {\n const setRef = composeRefs<HTMLElement>((child as { ref?: Ref<HTMLElement> }).ref);\n return cloneElement(child, {\n ...shared,\n ref: setRef,\n className: mergeClassName(childProps.className, className),\n style: (style ?? childProps.style) as CSSProperties | undefined,\n // 소비처 onClick 을 먼저 돌리고 토글한다 — 소비처가 stopPropagation 을 걸어도\n // 토글 의미는 유지된다(Radix 와 같은 순서).\n onClick: chain<ReactMouseEvent<HTMLElement>>(childProps.onClick, (event) => {\n onClick?.(event);\n toggle();\n }),\n disabled: disabled || undefined,\n });\n }\n\n return (\n <button\n type=\"button\"\n {...shared}\n className={className}\n style={style}\n disabled={disabled || undefined}\n onClick={chain<ReactMouseEvent<HTMLElement>>(onClick, toggle)}\n >\n {children}\n </button>\n );\n}\n\nexport interface CollapsibleContentProps {\n /** 닫혀도 DOM 에 남긴다(`hidden`). 기본은 Radix Presence 와 같이 언마운트다. */\n forceMount?: boolean;\n className?: string;\n style?: CSSProperties;\n /** 패널 자연 높이(px) 변화 — 소비처 애니메이션·가상 스크롤 보정용 */\n onHeightChange?: (height: number) => void;\n children?: ReactNode;\n [attr: string]: unknown;\n}\n\nexport function CollapsibleContent({\n forceMount = false,\n className,\n style,\n onHeightChange,\n children,\n ...rest\n}: CollapsibleContentProps) {\n const { open, contentId, disabled } = useCollapsible('CollapsibleContent');\n\n // 코어는 핸들러를 붙일 당시의 함수로 기억할 수 있다(ITSM-2026-002299) — identity 를 고정하고\n // 최신 콜백은 ref 로 읽는다.\n const latest = useRef({ onHeightChange });\n latest.current = { onHeightChange };\n const handleHeightChange = useCallback((height: number) => {\n latest.current.onHeightChange?.(height);\n }, []);\n\n const slots = useMemo(() => ({ content: children }), [children]);\n\n return (\n <MozCollapsibleCore\n open={open}\n forceMount={forceMount}\n contentId={contentId}\n disabled={disabled}\n className={className}\n style={style}\n slots={slots}\n onHeightChange={handleHeightChange}\n {...rest}\n />\n );\n}\n","import { Children, isValidElement, useMemo, type CSSProperties, type ReactElement, type ReactNode } from 'react';\nimport { AVATAR_SPEC, type AvatarLoadingStatus } from '@vmscloud/moz-ui-components-core';\nimport { createMozComponent } from './createMozComponent';\n\n/**\n * Avatar — 코어 로드 상태 기계 위의 React 컴파운드 래퍼.\n *\n * 사용법은 흔한 컴파운드 형태 그대로다:\n *\n * <Avatar className=\"h-9 w-9\">\n * <AvatarImage src={user.avatarUrl} alt={user.name} />\n * <AvatarFallback>{initial}</AvatarFallback>\n * </Avatar>\n *\n * 다만 `AvatarImage`·`AvatarFallback` 은 **스스로 DOM 을 그리지 않는다.** 이미지와 대체 표시는\n * 서로 배타적이고 그 전환을 결정하는 것은 코어의 로드 상태이므로, 두 자식은 \"설정\"만 담고\n * 루트가 코어 하나를 그린다. SplitPane 의 `<Pane>` introspection 과 같은 방식이다.\n *\n * 이 형태를 고른 이유는 소비처 호환이다 — 컴파운드 사용법을 유지하면 기존 호출부를 한 줄도\n * 고치지 않고 구현만 갈아 끼울 수 있다.\n */\n\nconst MozAvatarCore = createMozComponent(AVATAR_SPEC);\n\nexport interface AvatarImageProps {\n src?: string;\n alt?: string;\n className?: string;\n}\n\n/** 설정 전용 — 실제 `<img>` 는 코어가 로드 성공 시에만 그린다. */\nexport function AvatarImage(_props: AvatarImageProps): null {\n return null;\n}\n\nexport interface AvatarFallbackProps {\n /** 이 시간(ms)이 지나기 전에는 대체 표시를 그리지 않는다 (캐시 이미지 깜빡임 방지) */\n delayMs?: number;\n className?: string;\n children?: ReactNode;\n}\n\n/** 설정 전용 — 대체 표시는 코어의 `fallback` slot 으로 넘어간다. */\nexport function AvatarFallback(_props: AvatarFallbackProps): null {\n return null;\n}\n\nexport interface AvatarProps {\n className?: string;\n style?: CSSProperties;\n /** 로드 상태 변화 통지 (`idle`/`loading`/`loaded`/`error`) */\n onLoadingStatusChange?: (status: AvatarLoadingStatus) => void;\n children?: ReactNode;\n [attr: string]: unknown;\n}\n\nexport function Avatar({ className, style, onLoadingStatusChange, children, ...rest }: AvatarProps) {\n let image: AvatarImageProps | undefined;\n let fallback: AvatarFallbackProps | undefined;\n\n Children.forEach(children, (child) => {\n if (!isValidElement(child)) return;\n if (child.type === AvatarImage) image = (child as ReactElement<AvatarImageProps>).props;\n else if (child.type === AvatarFallback) fallback = (child as ReactElement<AvatarFallbackProps>).props;\n });\n\n const fallbackChildren = fallback?.children;\n const slots = useMemo(() => ({ fallback: fallbackChildren }), [fallbackChildren]);\n\n return (\n <MozAvatarCore\n src={image?.src}\n alt={image?.alt}\n imageClass={image?.className}\n fallbackClass={fallback?.className}\n delayMs={fallback?.delayMs}\n className={className}\n style={style}\n slots={slots}\n onLoadingStatusChange={onLoadingStatusChange}\n {...rest}\n />\n );\n}\n","import {\n useCallback,\n useState,\n type CSSProperties,\n type MutableRefObject,\n type ReactNode,\n type Ref,\n} from 'react';\nimport { SCROLLAREA_SPEC, type ScrollAreaOrientation, type ScrollbarVisibility } from '@vmscloud/moz-ui-components-core';\nimport { createMozComponent } from './createMozComponent';\n\n/**\n * ScrollArea — 네이티브 스크롤 뷰포트 + 코어가 그리는 커스텀 스크롤바.\n *\n * **뷰포트는 이 래퍼가 자기 React 트리에 직접 렌더한다.** 코어 slot 으로 끌어오지 않는 이유는\n * 타이밍이다 — slot 콘텐츠는 코어가 마운트된 뒤 포털로 그려지므로 소비자 트리보다 한 커밋\n * 늦게 마운트되고, 그러면 \"자식 layout effect 가 부모보다 먼저 돈다\" 는 React 불변식에 기대는\n * 소비처 로직이 조용히 깨진다(소비 앱 실측: 사이드바 초기 활성 항목 중앙 정렬 소실).\n * children 이 평범한 React 자식이면 그 문제가 애초에 생기지 않고 context 도 당연히 이어진다.\n *\n * 코어는 뷰포트 element 를 `viewport` prop 으로 받아 스크롤·리사이즈를 관찰하고 thumb 만\n * 그린다 — Tooltip 이 트리거를 그리지 않고 `anchor` 를 받는 것과 같은 형태다.\n *\n * 루트·뷰포트가 평범한 React element 이므로 `style` 에 숫자를 줘도 React 가 px 를 붙이고,\n * `onMouseLeave` 같은 핸들러도 합성 이벤트로 그대로 동작한다.\n */\n\nconst MozScrollAreaBars = createMozComponent(SCROLLAREA_SPEC);\n\nexport interface ScrollAreaProps {\n /** 어느 방향 스크롤바를 그릴지. 기본 `vertical` */\n orientation?: ScrollAreaOrientation;\n /** 기본 `always`. `hover` 는 영역 hover·내부 focus·thumb drag 동안만 표시한다 */\n scrollbarVisibility?: ScrollbarVisibility;\n className?: string;\n viewportClassName?: string;\n scrollbarClassName?: string;\n thumbClassName?: string;\n /** 실제 스크롤 컨테이너(뷰포트) element 를 받는다 */\n viewportRef?: Ref<HTMLDivElement | null>;\n style?: CSSProperties;\n onScroll?: (position: { scrollTop: number; scrollLeft: number }) => void;\n children?: ReactNode;\n [attr: string]: unknown;\n}\n\nexport function ScrollArea({\n orientation = 'vertical',\n scrollbarVisibility = 'always',\n className,\n viewportClassName,\n scrollbarClassName,\n thumbClassName,\n viewportRef,\n style,\n onScroll,\n children,\n ...rest\n}: ScrollAreaProps) {\n // 코어에 넘길 뷰포트는 state 여야 한다 — ref 로만 잡으면 값이 생겨도 재렌더가 없어\n // 코어가 영원히 null 을 본다.\n const [viewport, setViewport] = useState<HTMLDivElement | null>(null);\n\n const setRef = useCallback(\n (node: HTMLDivElement | null) => {\n setViewport(node);\n if (typeof viewportRef === 'function') viewportRef(node);\n else if (viewportRef) (viewportRef as MutableRefObject<HTMLDivElement | null>).current = node;\n },\n [viewportRef],\n );\n\n return (\n <div className={['moz-scroll-area', className].filter(Boolean).join(' ')} style={style} {...rest}>\n <div\n ref={setRef}\n className={['moz-scroll-area-viewport', viewportClassName].filter(Boolean).join(' ')}\n data-moz-scroll-area-viewport=\"\"\n >\n {children}\n </div>\n <MozScrollAreaBars\n viewport={viewport}\n interactionRoot={viewport?.parentElement}\n scrollbarVisibility={scrollbarVisibility}\n orientation={orientation}\n scrollbarClass={scrollbarClassName}\n thumbClass={thumbClassName}\n onScroll={onScroll}\n />\n </div>\n );\n}\n","import type { ButtonProps as CoreButtonProps } from '@vmscloud/moz-ui-components-core';\nimport {\n BADGE_SPEC,\n BREADCRUMB_SPEC,\n BUTTON_SPEC,\n CALENDAR_SPEC,\n CHECKBOX_SPEC,\n CONTEXTMENU_SPEC,\n CONTROLLER_SPEC,\n DATEINPUT_SPEC,\n EMPTYSTATE_SPEC,\n INPUT_SPEC,\n LABEL_SPEC,\n MULTISELECT_SPEC,\n NUMBERINPUT_SPEC,\n PASSWORDINPUT_SPEC,\n POPUP_SPEC,\n RADIO_SPEC,\n SELECT_SPEC,\n SLIDER_SPEC,\n TABLESELECT_SPEC,\n TAB_SPEC,\n TAGINPUT_SPEC,\n TEXTAREA_SPEC,\n TIMEPICKER_SPEC,\n TOAST_SPEC,\n TREESELECT_SPEC,\n TOGGLE_SPEC,\n} from '@vmscloud/moz-ui-components-core';\nimport { createMozComponent } from './createMozComponent';\n\nexport { useToast } from '@vmscloud/moz-ui-components-core';\nexport type { ToastOptions, ToastInstance, ToastProps, ToastType, ToastPosition } from '@vmscloud/moz-ui-components-core';\nexport type { BadgeProps, BadgeTone, BadgeAppearance, BadgeSize } from '@vmscloud/moz-ui-components-core';\n\n/**\n * 각 컴포넌트는 공용 브릿지 + 코어 스펙으로 1줄 정의.\n * 사용 예:\n * <Button type=\"outline\" width={120} action=\"Search\" onClick={onSearch}\n * icon={({ disabled }) => <SearchIcon dim={disabled} />}>\n * Search\n * </Button>\n * <Toggle modelValue={on} onChange={(v) => setOn(v)} label=\"Enabled\" />\n * 스타일: `import '@vmscloud/moz-ui-components-core/styles/button.css'` (컴포넌트별)\n */\nexport const Button = createMozComponent(BUTTON_SPEC);\nexport const Label = createMozComponent(LABEL_SPEC);\nexport const Badge = createMozComponent(BADGE_SPEC);\nexport const Toggle = createMozComponent(TOGGLE_SPEC);\nexport const BreadCrumb = createMozComponent(BREADCRUMB_SPEC);\nexport const EmptyState = createMozComponent(EMPTYSTATE_SPEC);\nexport const CheckBox = createMozComponent(CHECKBOX_SPEC);\nexport const Radio = createMozComponent(RADIO_SPEC);\nexport const Input = createMozComponent(INPUT_SPEC);\nexport const PasswordInput = createMozComponent(PASSWORDINPUT_SPEC);\nexport const TextArea = createMozComponent(TEXTAREA_SPEC);\nexport const NumberInput = createMozComponent(NUMBERINPUT_SPEC);\nexport const Tab = createMozComponent(TAB_SPEC);\nexport const Slider = createMozComponent(SLIDER_SPEC);\nexport const Calendar = createMozComponent(CALENDAR_SPEC);\nexport const DateInput = createMozComponent(DATEINPUT_SPEC);\nexport const Popup = createMozComponent(POPUP_SPEC);\nexport const Select = createMozComponent(SELECT_SPEC);\nexport const MultiSelect = createMozComponent(MULTISELECT_SPEC);\nexport const TimePicker = createMozComponent(TIMEPICKER_SPEC);\nexport const TagInput = createMozComponent(TAGINPUT_SPEC);\nexport const ContextMenu = createMozComponent(CONTEXTMENU_SPEC);\nexport const TableSelect = createMozComponent(TABLESELECT_SPEC);\nexport const TreeSelect = createMozComponent(TREESELECT_SPEC);\nexport const Controller = createMozComponent(CONTROLLER_SPEC);\n\n// SplitPane/Pane 은 자식 <Pane> introspection 이 필요해 전용 래퍼로 정의(원본 사용법 유지).\nexport { SplitPane, Pane } from './split-pane';\nexport const Toast = createMozComponent(TOAST_SPEC);\n\n// Tooltip 은 트리거가 소비처의 React 엘리먼트다 — cloneElement 로 ref·포인터/포커스 핸들러·\n// aria-describedby 를 얹고, 콘텐츠는 동적 slot 경로로 넘겨 소비자 context 를 잇는다.\n// 그래서 한 줄 정의가 아니라 전용 래퍼다(SplitPane 과 같은 이유).\nexport { Tooltip, TooltipProvider, TooltipTrigger, TooltipContent } from './tooltip';\nexport type {\n TooltipProps,\n TooltipProviderProps,\n TooltipTriggerProps,\n TooltipContentProps,\n} from './tooltip';\n\n// Popover 도 같은 이유의 전용 래퍼다 — 트리거·앵커가 소비처 React 엘리먼트이고, 상태·클릭\n// 토글·aria-expanded/controls 배선이 React 쪽 일이다. 닫힘 계층은 코어 DismissStack 이 맡는다.\nexport { Popover, PopoverTrigger, PopoverAnchor, PopoverContent, PopoverClose } from './popover';\nexport type {\n PopoverProps,\n PopoverTriggerProps,\n PopoverAnchorProps,\n PopoverContentProps,\n PopoverCloseProps,\n} from './popover';\n\n// Collapsible 도 같은 이유의 전용 래퍼다 — 트리거가 소비처 React 엘리먼트이고, 열림 상태·\n// 클릭 토글·aria-expanded/controls 배선이 React 쪽 일이다. 코어는 콘텐츠 패널만 그린다.\nexport { Collapsible, CollapsibleTrigger, CollapsibleContent } from './collapsible';\nexport type {\n CollapsibleProps,\n CollapsibleTriggerProps,\n CollapsibleContentProps,\n} from './collapsible';\n\n// Avatar 는 이미지/대체 표시가 배타적이고 그 전환이 코어의 로드 상태 소관이라, 자식 두 개가\n// 설정만 담고 루트가 코어 하나를 그리는 형태다(SplitPane 의 <Pane> introspection 과 같은 방식).\nexport { Avatar, AvatarImage, AvatarFallback } from './avatar';\nexport type { AvatarProps, AvatarImageProps, AvatarFallbackProps } from './avatar';\n\n// ScrollArea 는 콘텐츠가 소비처 React 서브트리이고, 소비처가 뷰포트 element 를 직접 잡아\n// 스크롤 위치를 읽고 쓰는 경우가 있어 전용 래퍼다(viewportRef).\nexport { ScrollArea } from './scroll-area';\nexport type { ScrollAreaProps } from './scroll-area';\n\nexport type { CoreButtonProps };\n"],"names":["pendingUnmounts","unmountTimer","deferUnmount","root","batch","r","ReactRenderer","__publicField","wrapper","container","component","initialProps","createRoot","renderProps","props","element","createElement","MozLocaleContext","createContext","koKR","MozContextWrapperContext","MozConfigProvider","locale","contextWrapper","children","useMozLocale","useContext","useMozContextWrapper","ValidatorReactContext","Validator","ref","useRef","createValidator","api","useValidatorContext","handlerKeyOf","emitName","sameScope","a","b","ka","kb","k","shallowEqualProps","createMozComponent","spec","models","reservedKeys","m","name","model","Comp","forwardRef","host","core","handle","portalSlots","setPortalSlots","useState","h","_a","rendererRef","validatorCtx","propsRef","emitFn","args","key","handler","buildProps","src","p","useLayoutEffect","R","slotMap","el","scope","SlotComp","s","content","slotResolver","bag","prev","cur","next","slotSignature","sig","lastSentRef","useEffect","c","slots","last","useImperativeHandle","portals","node","createPortal","Fragment","MozSplitPane","SPLITPANE_SPEC","Pane","_props","SplitPane","horizontal","paneEls","Children","isValidElement","panes","paneProps","i","jsx","MozTooltipCore","TOOLTIP_SPEC","openTooltips","DEFAULT_DELAY","CLOSE_GRACE_MS","TooltipProviderContext","TooltipProvider","delayDuration","disableHoverableContent","value","useMemo","TooltipRootContext","useTooltipRoot","ctx","Tooltip","openProp","defaultOpen","onOpenChange","provider","delay","hoverable","uncontrolled","setUncontrolled","controlled","open","anchor","setAnchor","contentId","useId","openTimer","closeTimer","onOpenChangeRef","clearTimers","useCallback","setOpen","openNow","openDelayed","closeNow","closeSoon","cancelClose","closeRef","self","other","onKeyDown","event","chain","theirs","ours","applyRef","TooltipTrigger","asChild","child","childProps","childRef","childRefRef","anchorNodeRef","setRef","appliedChildRef","handlers","cloneElement","TooltipContent","side","align","sideOffset","collisionPadding","arrow","className","style","rest","hoverRef","onBubbleEnter","onBubbleLeave","MozPopoverCore","POPOVER_SPEC","PopoverContext","usePopover","composeRefs","refs","Popover","triggerEl","setTriggerEl","anchorEl","setAnchorEl","PopoverTrigger","PopoverAnchor","PopoverClose","PopoverContent","matchTriggerWidth","trapFocus","onOpenAutoFocus","onCloseAutoFocus","onEscapeKeyDown","onInteractOutside","latest","handleRequestClose","_reason","handleEscapeKeyDown","_b","handleInteractOutside","target","trigger","_d","_c","handleOpenAutoFocus","handleCloseAutoFocus","MozCollapsibleCore","COLLAPSIBLE_SPEC","CollapsibleContext","useCollapsible","mergeClassName","merged","v","Collapsible","disabled","rootProps","body","CollapsibleTrigger","disabledProp","onClick","rootDisabled","toggle","shared","CollapsibleContent","forceMount","onHeightChange","handleHeightChange","height","MozAvatarCore","AVATAR_SPEC","AvatarImage","AvatarFallback","Avatar","onLoadingStatusChange","image","fallback","fallbackChildren","MozScrollAreaBars","SCROLLAREA_SPEC","ScrollArea","orientation","scrollbarVisibility","viewportClassName","scrollbarClassName","thumbClassName","viewportRef","onScroll","viewport","setViewport","jsxs","Button","BUTTON_SPEC","Label","LABEL_SPEC","Badge","BADGE_SPEC","Toggle","TOGGLE_SPEC","BreadCrumb","BREADCRUMB_SPEC","EmptyState","EMPTYSTATE_SPEC","CheckBox","CHECKBOX_SPEC","Radio","RADIO_SPEC","Input","INPUT_SPEC","PasswordInput","PASSWORDINPUT_SPEC","TextArea","TEXTAREA_SPEC","NumberInput","NUMBERINPUT_SPEC","Tab","TAB_SPEC","Slider","SLIDER_SPEC","Calendar","CALENDAR_SPEC","DateInput","DATEINPUT_SPEC","Popup","POPUP_SPEC","Select","SELECT_SPEC","MultiSelect","MULTISELECT_SPEC","TimePicker","TIMEPICKER_SPEC","TagInput","TAGINPUT_SPEC","ContextMenu","CONTEXTMENU_SPEC","TableSelect","TABLESELECT_SPEC","TreeSelect","TREESELECT_SPEC","Controller","CONTROLLER_SPEC","Toast","TOAST_SPEC"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","sources":["../src/bridge/ReactRenderer.tsx","../src/locale/MozLocaleContext.tsx","../src/validator/ValidatorContext.tsx","../src/createMozComponent.tsx","../src/split-pane.tsx","../src/tooltip.tsx","../src/popover.tsx","../src/collapsible.tsx","../src/avatar.tsx","../src/scroll-area.tsx","../src/components.ts"],"sourcesContent":["import { createElement, type ComponentType, type ReactNode } from 'react';\nimport { createRoot, type Root } from 'react-dom/client';\n\n/**\n * React ↔ DOM 브릿지 (moz-ui-grid-react 의 ReactRenderer 패턴 복사 — grid 패키지 의존 없음).\n *\n * 헤드리스 코어가 slot outlet(빈 컨테이너)을 만들면, 이 브릿지가 소비자의 React 콘텐츠를\n * 그 컨테이너에 마운트/갱신/정리한다.\n *\n * - contextWrapper 옵션으로 외부 Provider 트리(Locale 등)를 각 root 에 주입\n * - unmountAll() 로 일괄 정리 (메모리 누수 방지)\n */\nexport type ContextWrapper = (children: ReactNode) => ReactNode;\n\n/**\n * slot root 의 unmount 는 **매크로태스크**로 미룬다 (mozart-cloud issue 915).\n *\n * `root.unmount()` 는 내부적으로 `flushSync` 다. 예전처럼 마이크로태스크에서 부르면 메인 root 에\n * 대기 중인 sync 업데이트(트리거 리렌더의 ref 재호출, 슬롯 재fill 의 setState 등)를 그 자리에서\n * 커밋시키고, 그 커밋이 다시 슬롯을 갈아엎어 또 unmount 를 예약한다 — root 가 둘이라 React 의\n * 중첩 업데이트 가드(50회)가 root 마다 리셋되어 한 task 안에서 끝없이 핑퐁한다(실측 커밋 4만 회).\n * `setTimeout(0)` 이면 React 스케줄러가 대기 업데이트를 먼저 정상 경로로 비운 뒤 unmount 하므로\n * 커플링이 끊긴다. 컨테이너 element 는 코어가 이미 떼어 냈으므로 화면에는 차이가 없다.\n * (commit 단계 내부의 동기 unmount 경고 회피라는 원래 목적도 그대로 충족한다.)\n */\nconst pendingUnmounts = new Set<Root>();\nlet unmountTimer: ReturnType<typeof setTimeout> | null = null;\n\nfunction deferUnmount(root: Root): void {\n pendingUnmounts.add(root);\n if (unmountTimer != null) return;\n unmountTimer = setTimeout(() => {\n unmountTimer = null;\n const batch = Array.from(pendingUnmounts);\n pendingUnmounts.clear();\n for (const r of batch) r.unmount();\n }, 0);\n}\n\nexport class ReactRenderer {\n private contextWrapper: ContextWrapper | null = null;\n private roots = new Set<Root>();\n\n /** 외부 Provider 트리를 캡처 */\n setContextWrapper(wrapper: ContextWrapper | null): void {\n this.contextWrapper = wrapper;\n }\n\n /**\n * 컨테이너 단위 인스턴스 마운트.\n * component(props) 를 컨테이너에 렌더하고, update(props) 로 갱신, destroy() 로 정리한다.\n */\n mountInstance(\n container: HTMLElement,\n component: ComponentType<any>,\n initialProps: Record<string, unknown>,\n ): { update: (props: Record<string, unknown>) => void; destroy: () => void } {\n const root = createRoot(container);\n this.roots.add(root);\n\n const renderProps = (props: Record<string, unknown>): void => {\n const element = createElement(component, props);\n root.render(this.contextWrapper ? this.contextWrapper(element) : element);\n };\n renderProps(initialProps);\n\n return {\n update: (props) => renderProps(props),\n destroy: () => {\n this.roots.delete(root);\n deferUnmount(root);\n },\n };\n }\n\n /** 전체 인스턴스 언마운트 */\n unmountAll(): void {\n for (const root of this.roots) deferUnmount(root);\n this.roots.clear();\n }\n\n get size(): number {\n return this.roots.size;\n }\n}\n","import { createContext, createElement, useContext, type ReactNode } from 'react';\nimport { koKR, type MozLocaleMessages } from '@vmscloud/moz-ui-components-core';\nimport type { ContextWrapper } from '../bridge/ReactRenderer';\n\n/**\n * React 로케일 — Vue 의 provide/inject 대응(context). Provider 없으면 koKR 기본값. per-subtree override.\n */\nexport const MozLocaleContext = createContext<MozLocaleMessages>(koKR);\n\n/**\n * slot 이 렌더될 때 감쌀 소비자 Provider 트리 (ITSM-2026-002233).\n *\n * slot 콘텐츠는 `ReactRenderer.mountInstance` 가 만드는 **독립 root** 에 렌더되므로\n * 소비자 앱의 React context 가 닿지 않는다. 소비자가 여기에 wrapper 를 주면 각 slot\n * root 가 그 트리 안에서 렌더돼 context 를 되찾는다. Provider 없으면 `null`(기존 동작).\n */\nexport const MozContextWrapperContext = createContext<ContextWrapper | null>(null);\n\nexport function MozConfigProvider({\n locale = koKR,\n contextWrapper,\n children,\n}: {\n locale?: MozLocaleMessages;\n /**\n * slot root 를 감쌀 함수. 소비자의 Provider 트리를 그대로 넘긴다.\n *\n * ```tsx\n * <MozConfigProvider contextWrapper={(node) => <QueryClientProvider client={qc}>{node}</QueryClientProvider>}>\n * ```\n *\n * **참조 동일성을 유지하세요** — 매 렌더 새 함수를 주면 마운트된 slot 이 매번 다시\n * 렌더된다. `useCallback` 이나 모듈 상수로 고정하는 것을 권장한다.\n */\n contextWrapper?: ContextWrapper;\n children?: ReactNode;\n}) {\n return createElement(\n MozLocaleContext.Provider,\n { value: locale },\n createElement(\n MozContextWrapperContext.Provider,\n { value: contextWrapper ?? null },\n children,\n ),\n );\n}\n\nexport function useMozLocale(): MozLocaleMessages {\n return useContext(MozLocaleContext);\n}\n\n/** 현재 트리에 설정된 slot context wrapper (없으면 `null`). */\nexport function useMozContextWrapper(): ContextWrapper | null {\n return useContext(MozContextWrapperContext);\n}\n","import { createContext, createElement, useContext, useRef, type ReactNode } from 'react';\nimport { createValidator, type RuleEventTarget, type ValidatorContext } from '@vmscloud/moz-ui-components-core';\n\n/** Vue 의 provide/inject('validateInput') 대응 (context) */\nexport const ValidatorReactContext = createContext<ValidatorContext | null>(null);\n\ninterface ValidatorApi {\n validate: (eventTarget?: RuleEventTarget) => Promise<boolean>;\n initValidator: () => void;\n}\n\n/**\n * Validator — 폼 컨텍스트 provider. children 은 노드 또는 render-prop({validate, initValidator}).\n */\nexport function Validator({\n children,\n}: {\n children?: ReactNode | ((api: ValidatorApi) => ReactNode);\n}) {\n const ref = useRef<ValidatorContext>();\n if (!ref.current) ref.current = createValidator();\n const api: ValidatorApi = { validate: ref.current.validate, initValidator: ref.current.initValidator };\n return createElement(\n ValidatorReactContext.Provider,\n { value: ref.current },\n typeof children === 'function' ? (children as (a: ValidatorApi) => ReactNode)(api) : children,\n );\n}\n\nexport function useValidatorContext(): ValidatorContext | null {\n return useContext(ValidatorReactContext);\n}\n","import {\n Fragment,\n createElement,\n forwardRef,\n useContext,\n useEffect,\n useImperativeHandle,\n useLayoutEffect,\n useRef,\n useState,\n} from 'react';\nimport { createPortal } from 'react-dom';\nimport type { CoreInstance, MozSpec, SlotRenderer } from '@vmscloud/moz-ui-components-core';\nimport { ReactRenderer } from './bridge/ReactRenderer';\nimport { useMozContextWrapper, useMozLocale } from './locale';\nimport { ValidatorReactContext } from './validator';\n\n/**\n * createMozComponent — 하나의 공용 React 브릿지.\n *\n * 헤드리스 코어(MozSpec)를 받아 React 컴포넌트를 만든다. props → 코어 props,\n * onXxx → 코어 emit, children/render-prop → slot 주입(ReactRenderer)을 이 파일 하나가 담당하고,\n * 각 컴포넌트는 스펙 1줄로 정의된다.\n *\n * NOTE(pilot): slot 은 ReactRenderer.mountInstance(독립 root)로 마운트한다. 소비자의 React\n * context/Suspense 를 그대로 유지하려면 createPortal 로 바꾸는 것이 다음 개선 (Decision Fork 2).\n * slot 콘텐츠의 최신 props 반영도 그 단계에서 강화한다.\n */\n/** Vue `update:x` / 코어 emit 이름 → React 관례 핸들러 prop 이름. emitFn 의 매핑과 1:1. */\nfunction handlerKeyOf(emitName: string): string {\n return emitName.startsWith('update:')\n ? 'on' + emitName.slice(7).charAt(0).toUpperCase() + emitName.slice(8) + 'Change'\n : 'on' + emitName.charAt(0).toUpperCase() + emitName.slice(1);\n}\n\n/**\n * 브릿지가 `ref` 로 노출하는 핸들 — 코어의 명령형 API + 코어가 그린 루트 element.\n *\n * `el` 이 필요한 이유: 브릿지는 위치 앵커로 `display:contents` 호스트 div 를 하나 렌더하고\n * 코어의 시맨틱 루트(`<button>`/`<input>` …)는 그 안에 그려진다. 소비자 어댑터가 루트에\n * 닿으려면 지금까지는 호스트 아래를 DOM 으로 훑어 추측해야 했고, 마크업이 바뀌면 조용히\n * 깨졌다. `el` 이 그 추측을 없앤다.\n */\nexport type MozHandle<API> = (API extends void ? unknown : API) & {\n readonly el: HTMLElement | null;\n};\n\n/** slot scope 의 얕은 동등 비교 — 코어는 렌더마다 새 객체를 만들지만 값은 대개 같다. */\nfunction sameScope(a: unknown, b: unknown): boolean {\n if (Object.is(a, b)) return true;\n if (typeof a !== 'object' || typeof b !== 'object' || a === null || b === null) return false;\n const ka = Object.keys(a as Record<string, unknown>);\n const kb = Object.keys(b as Record<string, unknown>);\n if (ka.length !== kb.length) return false;\n return ka.every((k) => Object.is((a as Record<string, unknown>)[k], (b as Record<string, unknown>)[k]));\n}\n\n/** 키 집합과 값(Object.is)이 모두 같으면 true — `replace` 갱신이라 키 소멸도 변경으로 본다. */\nfunction shallowEqualProps(a: Record<string, unknown>, b: Record<string, unknown>): boolean {\n const ka = Object.keys(a);\n const kb = Object.keys(b);\n if (ka.length !== kb.length) return false;\n for (const k of ka) {\n if (!Object.prototype.hasOwnProperty.call(b, k) || !Object.is(a[k], b[k])) return false;\n }\n return true;\n}\n\nexport function createMozComponent<P extends object, E, API>(spec: MozSpec<P, E, API>) {\n const models = (spec.models ?? {}) as Record<string, { prop: string; event: string }>;\n\n /**\n * rest 패스스루에서 제외할 키 — 스펙이 이미 소비하는 것들이다.\n *\n * 빠뜨리면 슬롯 콘텐츠(React 노드/함수)가 attribute 로 나가거나, emit 핸들러가 엉뚱한\n * DOM 이벤트 리스너로 등록된다(`spread` 는 `onXxx` 함수를 addEventListener 로 처리한다).\n */\n const reservedKeys = new Set<string>([\n ...spec.props,\n ...Object.keys(models),\n ...Object.values(models).map((m) => m.prop),\n ...(spec.slots ?? []).map((name) => (name === 'default' ? 'children' : name)),\n ...(spec.emits ?? []).map(handlerKeyOf),\n ...Object.keys(models).map((model) => handlerKeyOf(`update:${model}`)),\n ...Object.values(models).map((m) => handlerKeyOf(m.event)),\n 'children',\n 'className',\n 'style',\n 'id',\n 'key',\n 'ref',\n // 동적 slot 묶음 — `slots={{ 'a-tab': (scope) => …, a: <Panel/> }}`. Vue 브릿지는 소비자\n // slots 를 전부 등록하지만 React 는 스펙의 정적 목록만 알았다. 이름이 데이터에서 파생되는\n // 코어(Tab)는 이 통로 없이는 React 에서 콘텐츠를 받을 수 없었다.\n 'slots',\n ]);\n const Comp = forwardRef<MozHandle<API>, Record<string, any>>((props, ref) => {\n const host = useRef<HTMLDivElement>(null);\n const core = useRef<CoreInstance<P, API> | undefined>(undefined);\n /**\n * ref 로 노출할 **안정 핸들** — Vue 브릿지의 `expose(apiProxy)` 와 같은 방식이다.\n * 코어는 마운트 effect 에서야 생기므로, 객체를 먼저 만들어 두고 API 를 나중에 얹는다.\n *\n * `el` 은 브릿지 예약 키다. 코어 API 가 같은 이름을 쓰면 루트 접근이 조용히 가려지므로\n * 아래 병합에서 건너뛰고, `rootElementRef.test.tsx` 가 코어 쪽 `el` 사용을 막는다.\n */\n const handle = useRef<MozHandle<API> | undefined>(undefined);\n /**\n * 동적 slot(`slots` prop)의 outlet 들. 코어가 outlet 을 만들어 fill 을 요청하면 여기 기록하고,\n * 브릿지가 **자기 React 트리 안에서** `createPortal` 로 콘텐츠를 그린다. 독립 root 로 마운트\n * (정적 slot 의 방식)하면 Router·QueryClient 같은 소비자 context 가 끊겨, 페이지 서브트리를\n * 담는 패널(Tab)은 첫 훅에서 죽는다(소비처 실측: `useNavigate() … <Router>`). 포털은 context·\n * Suspense·act 를 소비자 트리 그대로 잇는다 — 코어 주석의 \"Decision Fork 2\" 가 이것이다.\n * 키는 코어가 outlet 마다 붙이는 `data-moz-slot-id`(반복 slot 도 고유).\n */\n const [portalSlots, setPortalSlots] = useState<\n Map<string, { name: string; el: HTMLElement; scope: unknown }>\n >(() => new Map());\n if (!handle.current) {\n const h = {} as MozHandle<API>;\n Object.defineProperty(h, 'el', {\n get: () => core.current?.el ?? null,\n enumerable: true,\n });\n handle.current = h;\n }\n const rendererRef = useRef<ReactRenderer>();\n if (!rendererRef.current) rendererRef.current = new ReactRenderer();\n\n // slot context wrapper: slot 은 독립 root 라 소비자 context 가 닿지 않는다\n // (ITSM-2026-002233). Provider 가 준 wrapper 를 renderer 에 넘겨 각 root 를 감싼다.\n // **렌더 중에 설정한다** — slot mount 는 아래 useLayoutEffect 에서 일어나므로\n // effect 로 미루면 첫 마운트가 wrapper 없이 렌더된다.\n const contextWrapper = useMozContextWrapper();\n rendererRef.current.setContextWrapper(contextWrapper);\n\n // 로케일: context 로 해석 (Provider 없으면 koKR). 코어엔 setLocale 채널로 전달.\n const locale = useMozLocale();\n // Validator: 부모 <Validator> context (없으면 null → standalone)\n const validatorCtx = useContext(ValidatorReactContext);\n\n // emit/slot 클로저가 항상 최신 props 를 참조하도록 ref 로 보관\n const propsRef = useRef(props);\n propsRef.current = props;\n\n const emitFn = ((name: any, ...args: any[]) => {\n // Vue 의 `update:X` (v-model) 는 React 관례 `onXChange` 로 매핑. 그 외는 `onX`.\n // `reservedKeys` 도 같은 함수를 쓴다 — 매핑이 갈라지면 emit 핸들러가 rest 로 새어\n // DOM 리스너로 등록되므로 반드시 한 곳에서 계산한다.\n const key = handlerKeyOf(String(name));\n const handler = propsRef.current[key];\n if (typeof handler === 'function') handler(...args);\n }) as any;\n\n const buildProps = (): P => {\n const src = propsRef.current;\n const p: Record<string, any> = {};\n // rest 를 먼저 깔고 명시 prop 이 덮어쓴다 — Vue 브릿지(`defineMozComponent`)의\n // `{ ...attrs }` 와 같은 순서다. 코어는 자신이 아는 키를 뺀 나머지를 `spread(rest)` 로\n // 루트 엘리먼트에 뿌리므로(runtime/spread.ts), 이 한 줄이 aria-*/data-*/title/role/\n // native type/rows 같은 임의 속성과 onXxx 리스너의 패스스루 경로가 된다.\n for (const k of Object.keys(src)) {\n if (reservedKeys.has(k)) continue;\n p[k] = src[k];\n }\n for (const k of spec.props) p[k] = src[k];\n for (const model of Object.keys(models)) p[models[model].prop] = src[model];\n // className/style/id 패스스루\n if (src.className != null) p.class = src.className;\n if (src.style != null) p.style = src.style;\n if (src.id != null) p.id = src.id;\n return p as P;\n };\n\n useLayoutEffect(() => {\n const R = rendererRef.current!;\n const slotMap: Record<string, SlotRenderer> = {};\n for (const name of spec.slots ?? []) {\n const key = name === 'default' ? 'children' : name;\n if (propsRef.current[key] == null) continue;\n slotMap[name] = (el, scope) => {\n const SlotComp = ({ scope: s }: { scope: unknown }) => {\n const content = propsRef.current[key];\n return (typeof content === 'function' ? content(s) : content) ?? null;\n };\n const handle = R.mountInstance(el, SlotComp as any, { scope });\n return { update: (s) => handle.update({ scope: s }), dispose: handle.destroy };\n };\n }\n // 동적 slot: 코어가 이름을 요청하는 시점에 propsRef 를 읽는다 — 마운트 뒤에 생긴 이름도 잡힌다.\n // 콘텐츠는 독립 root 가 아니라 포털로 그린다(위 portalSlots 주석).\n const slotResolver = (name: string): SlotRenderer | undefined => {\n const bag = propsRef.current.slots as Record<string, unknown> | undefined;\n if (bag == null || bag[name] == null) return undefined;\n return (el, scope) => {\n const key = el.getAttribute('data-moz-slot-id') ?? name;\n setPortalSlots((prev) => new Map(prev).set(key, { name, el, scope }));\n return {\n // scope 가 값까지 같으면 state 를 건드리지 않는다. 코어는 렌더마다 scope 객체를 새로\n // 만들어 fill 하므로, 무조건 setState 하면 브릿지 재렌더 → core.update → 다시 fill →\n // setState … 로 끝나지 않는 비동기 루프가 된다(소비처 실측: 페이지 테스트 타임아웃).\n update: (s) =>\n setPortalSlots((prev) => {\n const cur = prev.get(key);\n if (!cur || sameScope(cur.scope, s)) return prev;\n return new Map(prev).set(key, { ...cur, scope: s });\n }),\n dispose: () =>\n setPortalSlots((prev) => {\n if (!prev.has(key)) return prev;\n const next = new Map(prev);\n next.delete(key);\n return next;\n }),\n };\n };\n };\n core.current = spec.core(host.current as HTMLElement, buildProps(), emitFn, {\n slots: slotMap,\n slotResolver,\n locale,\n validator: validatorCtx ?? undefined,\n // 소비자가 실제로 넘긴 prop 키 (controlled 판별)\n providedKeys: Object.keys(propsRef.current),\n });\n // 코어 API 를 안정 핸들에 얹는다 (`el` 은 예약 키라 건너뛴다).\n const api = core.current.api as Record<string, unknown> | undefined;\n if (api) {\n for (const k of Object.keys(api)) {\n if (k === 'el') continue;\n (handle.current as unknown as Record<string, unknown>)[k] = api[k];\n }\n }\n return () => {\n core.current?.destroy();\n R.unmountAll();\n core.current = undefined;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n // 매 렌더 최신 props/로케일 을 코어로 반영 — 단, **바뀐 것이 없으면 건너뛴다**.\n // 소비처 트리의 무관한 리렌더(예: 툴팁 anchor 상태 변경)마다 코어를 update 하면 코어가\n // 템플릿을 다시 그리며 slot 을 재fill 하고, 그 재fill 이 브릿지 상태를 건드려 다시 리렌더되는\n // 루프의 한 축이 됐다(mozart-cloud issue 915). 마지막으로 보낸 props 와 얕은 비교한다.\n // slot 콘텐츠는 buildProps 에 들어가지 않지만(reservedKeys) 코어 update 가 slot 을 재fill 해야\n // 새 콘텐츠가 그려지므로, 정적 slot 값(문자열은 값·엘리먼트는 identity)과 동적 slot 이름 집합도\n // 비교 대상에 넣는다 — 라벨 문자열이 같은 리렌더는 건너뛰고, 바뀌면 예전처럼 update 한다.\n const slotSignature = (): Record<string, unknown> => {\n const src = propsRef.current;\n const sig: Record<string, unknown> = {};\n for (const name of spec.slots ?? []) {\n const key = name === 'default' ? 'children' : name;\n sig[key] = src[key];\n }\n const bag = src.slots as Record<string, unknown> | undefined;\n sig.__dynamicSlotKeys = bag ? Object.keys(bag).sort().join('\u0000') : '';\n return sig;\n };\n const lastSentRef = useRef<{\n props: Record<string, unknown>;\n slots: Record<string, unknown>;\n locale: typeof locale;\n } | null>(null);\n useEffect(() => {\n const c = core.current;\n if (!c) return;\n const next = buildProps() as Record<string, unknown>;\n const slots = slotSignature();\n const last = lastSentRef.current;\n if (\n last &&\n last.locale === locale &&\n shallowEqualProps(last.props, next) &&\n shallowEqualProps(last.slots, slots)\n )\n return;\n lastSentRef.current = { props: next, slots, locale };\n if (!last || last.locale !== locale) c.setLocale(locale);\n // 매 렌더 전체 prop 을 넘기므로 replace 로 갱신한다 — 병합하면 소비처가 조건부로\n // 뺀 prop(`aria-label` 등)이 지워지지 않고 DOM 에 남는다.\n c.update(next as P, { replace: true, sync: spec.syncUpdate });\n });\n\n useImperativeHandle(ref, () => handle.current as MozHandle<API>, []);\n\n const bag = props.slots as Record<string, unknown> | undefined;\n const portals = Array.from(portalSlots, ([key, p]) => {\n const content = bag?.[p.name];\n const node = (typeof content === 'function' ? content(p.scope) : content) ?? null;\n return createPortal(node, p.el, key);\n });\n return createElement(\n Fragment,\n null,\n createElement('div', { ref: host, style: { display: 'contents' } }),\n ...portals,\n );\n });\n Comp.displayName = spec.name;\n return Comp;\n}\n","import { Children, isValidElement, type ReactElement, type ReactNode } from 'react';\nimport { SPLITPANE_SPEC, type PaneConfig } from '@vmscloud/moz-ui-components-core';\nimport { createMozComponent } from './createMozComponent';\n\n// 코어 구동 컴포넌트(panes 배열 + pane-N 프롭) — 커스텀 래퍼가 내부적으로 사용.\nconst MozSplitPane = createMozComponent(SPLITPANE_SPEC);\n\nexport interface PaneProps {\n size?: number | string;\n minSize?: number | string;\n maxSize?: number | string;\n hidden?: boolean;\n children?: ReactNode;\n}\n\n/**\n * Pane — SplitPane 자식 마커. 직접 렌더되지 않고(반환 null) 부모 SplitPane 이 props/children 을 읽는다.\n */\nexport const Pane = (_props: PaneProps): null => null;\n\nexport interface SplitPaneProps {\n horizontal?: boolean;\n children?: ReactNode;\n}\n\n/**\n * SplitPane — 원본 사용법 그대로: `<SplitPane><Pane size=\"..\">A</Pane>…</SplitPane>`.\n *\n * 자식 `<Pane>` 엘리먼트를 읽어 코어의 `panes` 배열 + `pane-N` 슬롯(프롭)으로 변환한다.\n * React.Children introspection 은 React 전용이라 코어가 아닌 이 래퍼가 담당. (최대 8 패널 — 코어 spec.slots.)\n */\nexport const SplitPane = ({ horizontal, children }: SplitPaneProps) => {\n const paneEls = Children.toArray(children).filter(\n (c): c is ReactElement<PaneProps> => isValidElement(c) && c.type === Pane,\n );\n\n const panes: PaneConfig[] = paneEls.map((c) => ({\n size: c.props.size,\n minSize: c.props.minSize,\n maxSize: c.props.maxSize,\n hidden: c.props.hidden,\n }));\n\n const paneProps: Record<string, ReactNode> = {};\n paneEls.forEach((c, i) => {\n paneProps[`pane-${i}`] = c.props.children;\n });\n\n return <MozSplitPane panes={panes} horizontal={horizontal} {...paneProps} />;\n};\n","import {\n cloneElement,\n createContext,\n isValidElement,\n useCallback,\n useContext,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n type CSSProperties,\n type FocusEvent as ReactFocusEvent,\n type MouseEvent as ReactMouseEvent,\n type PointerEvent as ReactPointerEvent,\n type ReactElement,\n type ReactNode,\n type Ref,\n useLayoutEffect,\n} from 'react';\nimport { TOOLTIP_SPEC, type TooltipAlign, type TooltipSide } from '@vmscloud/moz-ui-components-core';\nimport { createMozComponent } from './createMozComponent';\n\n/**\n * Tooltip — 코어 버블 위의 React 전용 컴파운드 래퍼.\n *\n * 다른 컴포넌트처럼 `createMozComponent(SPEC)` 한 줄로 끝나지 않는 이유는 SplitPane 과 같다:\n * 툴팁의 **트리거는 소비처가 이미 렌더한 React 엘리먼트**이고, 그 엘리먼트에 ref·포인터·포커스\n * 핸들러·`aria-describedby` 를 얹는 일은 React 에서만 할 수 있다. 코어는 앵커 element 를 받아\n * 버블만 그리고, 지연·hover 판단·전역 단일화는 여기서 한다.\n *\n * 콘텐츠는 브릿지의 **동적 slot 경로**(`slots={{ content: … }}`)로 넘긴다. 그 경로는 브릿지가\n * 자기 React 트리 안에서 `createPortal` 로 그리므로 소비자 context(Router·QueryClient·테마)가\n * 그대로 이어진다 — 정적 slot 은 독립 root 로 마운트돼 context 가 끊긴다.\n *\n * 열림 경로는 셋이다: 트리거 위 `pointermove` / `mouseenter`(지연 후), 트리거로 버블링된\n * `focus`(지연 없이 즉시 — 키보드 사용자는 기다릴 이유가 없다). 닫힘은 `pointerleave`·`blur`·\n * `pointerdown`·ESC 이며, **즉시 언마운트**한다(닫힘 애니메이션 없음).\n */\n\nconst MozTooltipCore = createMozComponent(TOOLTIP_SPEC);\n\n/** 열려 있는 툴팁의 닫기 함수들 — 하나가 열리면 나머지를 닫는다(전역 단일화) */\nconst openTooltips = new Set<() => void>();\n\nconst DEFAULT_DELAY = 200;\n/** hoverable 콘텐츠로 포인터가 건너갈 여유 */\nconst CLOSE_GRACE_MS = 100;\n\ninterface TooltipProviderValue {\n delayDuration: number;\n disableHoverableContent: boolean;\n}\n\nconst TooltipProviderContext = createContext<TooltipProviderValue>({\n delayDuration: DEFAULT_DELAY,\n disableHoverableContent: false,\n});\n\nexport interface TooltipProviderProps {\n /** 포인터로 열릴 때까지의 지연(ms). 포커스는 이 값과 무관하게 즉시 연다 */\n delayDuration?: number;\n /** true 면 트리거를 벗어나는 즉시 닫는다(콘텐츠 위 hover 유지 안 함) */\n disableHoverableContent?: boolean;\n children?: ReactNode;\n}\n\nexport function TooltipProvider({\n delayDuration = DEFAULT_DELAY,\n disableHoverableContent = false,\n children,\n}: TooltipProviderProps) {\n const value = useMemo(\n () => ({ delayDuration, disableHoverableContent }),\n [delayDuration, disableHoverableContent],\n );\n return <TooltipProviderContext.Provider value={value}>{children}</TooltipProviderContext.Provider>;\n}\n\ninterface TooltipRootValue {\n open: boolean;\n contentId: string;\n anchor: HTMLElement | null;\n setAnchor: (el: HTMLElement | null) => void;\n hoverable: boolean;\n openNow: () => void;\n openDelayed: () => void;\n closeNow: () => void;\n closeSoon: () => void;\n cancelClose: () => void;\n}\n\nconst TooltipRootContext = createContext<TooltipRootValue | null>(null);\n\nfunction useTooltipRoot(component: string): TooltipRootValue {\n const ctx = useContext(TooltipRootContext);\n if (!ctx) throw new Error(`${component} 는 <Tooltip> 안에서만 쓸 수 있습니다.`);\n return ctx;\n}\n\nexport interface TooltipProps {\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n /** Provider 값을 이 툴팁에 한해 덮어쓴다 */\n delayDuration?: number;\n disableHoverableContent?: boolean;\n children?: ReactNode;\n}\n\nexport function Tooltip({\n open: openProp,\n defaultOpen = false,\n onOpenChange,\n delayDuration,\n disableHoverableContent,\n children,\n}: TooltipProps) {\n const provider = useContext(TooltipProviderContext);\n const delay = delayDuration ?? provider.delayDuration;\n const hoverable = !(disableHoverableContent ?? provider.disableHoverableContent);\n\n const [uncontrolled, setUncontrolled] = useState(defaultOpen);\n const controlled = openProp !== undefined;\n const open = controlled ? Boolean(openProp) : uncontrolled;\n\n const [anchor, setAnchor] = useState<HTMLElement | null>(null);\n const contentId = `moz-tooltip-${useId()}`;\n\n const openTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n const closeTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const onOpenChangeRef = useRef(onOpenChange);\n onOpenChangeRef.current = onOpenChange;\n\n const clearTimers = useCallback(() => {\n if (openTimer.current) clearTimeout(openTimer.current);\n if (closeTimer.current) clearTimeout(closeTimer.current);\n openTimer.current = null;\n closeTimer.current = null;\n }, []);\n\n const setOpen = useCallback(\n (next: boolean) => {\n if (!controlled) setUncontrolled(next);\n onOpenChangeRef.current?.(next);\n },\n [controlled],\n );\n\n const openNow = useCallback(() => {\n clearTimers();\n setOpen(true);\n }, [clearTimers, setOpen]);\n\n const openDelayed = useCallback(() => {\n if (closeTimer.current) {\n clearTimeout(closeTimer.current);\n closeTimer.current = null;\n }\n if (openTimer.current) return;\n if (delay <= 0) {\n setOpen(true);\n return;\n }\n openTimer.current = setTimeout(() => {\n openTimer.current = null;\n setOpen(true);\n }, delay);\n }, [delay, setOpen]);\n\n const closeNow = useCallback(() => {\n clearTimers();\n setOpen(false);\n }, [clearTimers, setOpen]);\n\n const closeSoon = useCallback(() => {\n if (openTimer.current) {\n clearTimeout(openTimer.current);\n openTimer.current = null;\n }\n // 콘텐츠 위 hover 를 유지하지 않는다면 유예 없이 바로 닫는다.\n if (!hoverable) {\n setOpen(false);\n return;\n }\n if (closeTimer.current) return;\n closeTimer.current = setTimeout(() => {\n closeTimer.current = null;\n setOpen(false);\n }, CLOSE_GRACE_MS);\n }, [hoverable, setOpen]);\n\n const cancelClose = useCallback(() => {\n if (closeTimer.current) {\n clearTimeout(closeTimer.current);\n closeTimer.current = null;\n }\n }, []);\n\n // 언마운트 시 타이머 정리\n useEffect(() => clearTimers, [clearTimers]);\n\n // 전역 단일화 + ESC — 열려 있는 동안에만 건다.\n const closeRef = useRef(closeNow);\n closeRef.current = closeNow;\n useEffect(() => {\n if (!open) return undefined;\n const self = () => closeRef.current();\n for (const other of Array.from(openTooltips)) other();\n openTooltips.add(self);\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape') closeRef.current();\n };\n document.addEventListener('keydown', onKeyDown);\n return () => {\n openTooltips.delete(self);\n document.removeEventListener('keydown', onKeyDown);\n };\n }, [open]);\n\n const value = useMemo<TooltipRootValue>(\n () => ({\n open,\n contentId,\n anchor,\n setAnchor,\n hoverable,\n openNow,\n openDelayed,\n closeNow,\n closeSoon,\n cancelClose,\n }),\n [open, contentId, anchor, hoverable, openNow, openDelayed, closeNow, closeSoon, cancelClose],\n );\n\n return <TooltipRootContext.Provider value={value}>{children}</TooltipRootContext.Provider>;\n}\n\n/** 소비처 핸들러를 먼저 실행하고 툴팁 핸들러를 잇는다 (소비처 동작을 가리지 않는다) */\nfunction chain<E>(theirs: unknown, ours: () => void) {\n return (event: E) => {\n if (typeof theirs === 'function') (theirs as (e: E) => void)(event);\n ours();\n };\n}\n\nfunction applyRef<T>(ref: Ref<T> | undefined, node: T | null): void {\n if (!ref) return;\n if (typeof ref === 'function') ref(node);\n else (ref as { current: T | null }).current = node;\n}\n\nexport interface TooltipTriggerProps {\n /** true 면 래퍼 없이 children 을 그대로 트리거로 쓴다(말줄임·레이아웃 보존) */\n asChild?: boolean;\n children?: ReactNode;\n}\n\nexport function TooltipTrigger({ asChild = false, children }: TooltipTriggerProps) {\n const ctx = useTooltipRoot('TooltipTrigger');\n const { open, contentId, setAnchor, openNow, openDelayed, closeNow, closeSoon } = ctx;\n\n const child = isValidElement(children) ? (children as ReactElement<Record<string, unknown>>) : null;\n const childProps = (child?.props ?? {}) as Record<string, unknown>;\n\n // ref 콜백의 identity 를 고정한다(mozart-cloud issue 915). 예전에는 `child` 를 deps 로 두어\n // 트리거가 리렌더될 때마다 새 콜백이 만들어졌고, React 는 콜백이 바뀌면 이전 콜백에 null,\n // 새 콜백에 node 를 다시 호출하므로 `setAnchor(null)`→`setAnchor(node)` 가 매 리렌더마다\n // 재발생했다. 툴팁이 열린 채 트리거가 리렌더되는 조합(클릭으로 className 이 바뀌는 MozButton)\n // 에서는 그 상태 변경이 콘텐츠를 내리고 다시 올리며, 슬롯 root 의 unmount(flushSync) 와 메인\n // root 커밋이 동기로 핑퐁해 렌더러가 멈췄다. 소비처 child 의 ref 는 최신 값을 ref 로 읽어 잇는다.\n const childRef = (child as { ref?: Ref<HTMLElement> } | null)?.ref;\n const childRefRef = useRef<Ref<HTMLElement> | undefined>(childRef);\n childRefRef.current = childRef;\n const anchorNodeRef = useRef<HTMLElement | null>(null);\n const setRef = useCallback(\n (node: HTMLElement | null) => {\n anchorNodeRef.current = node;\n setAnchor(node);\n applyRef(childRefRef.current, node);\n },\n [setAnchor],\n );\n // child 의 ref 가 다른 객체/콜백으로 바뀌면(리렌더마다 새 인라인 콜백 등) 현재 anchor 를 새 ref\n // 에도 전달한다 — React 가 ref 교체 시 하던 일 중 \"새 ref 에 node\" 만 남기고 \"이전 ref 에 null\" 은\n // 하지 않는다(anchor 상태를 흔들지 않기 위해).\n const appliedChildRef = useRef<Ref<HTMLElement> | undefined>(childRef);\n useLayoutEffect(() => {\n if (appliedChildRef.current === childRef) return;\n appliedChildRef.current = childRef;\n applyRef(childRef, anchorNodeRef.current);\n });\n\n const handlers = {\n ref: setRef,\n // pointermove·mouseenter 둘 다 받는다 — 포인터 종류·테스트 도구에 따라 어느 하나만 오는\n // 경우가 있어(예: fireEvent.pointerMove / fireEvent.mouseOver) 한쪽만 걸면 조용히 안 열린다.\n onPointerMove: chain<ReactPointerEvent<HTMLElement>>(childProps.onPointerMove, openDelayed),\n onMouseEnter: chain<ReactMouseEvent<HTMLElement>>(childProps.onMouseEnter, openDelayed),\n onPointerLeave: chain<ReactPointerEvent<HTMLElement>>(childProps.onPointerLeave, closeSoon),\n onMouseLeave: chain<ReactMouseEvent<HTMLElement>>(childProps.onMouseLeave, closeSoon),\n // 클릭하러 온 것이므로 즉시 치운다(누른 순간 가려지지 않게).\n onPointerDown: chain<ReactPointerEvent<HTMLElement>>(childProps.onPointerDown, closeNow),\n // 포커스는 지연 없이 — 버블링된 focus 도 받는다(트리거가 감싼 span 인 경우).\n onFocus: chain<ReactFocusEvent<HTMLElement>>(childProps.onFocus, openNow),\n onBlur: chain<ReactFocusEvent<HTMLElement>>(childProps.onBlur, closeNow),\n 'aria-describedby': open ? contentId : (childProps['aria-describedby'] as string | undefined),\n // 트리거는 열림 상태를 attribute 로도 노출한다 — 소비처가 열려 있는 동안의 트리거 스타일을\n // CSS 만으로 걸 수 있고(`[data-state='open']`), \"툴팁이 배선됐는가\" 를 DOM 에서 확인할 수 있다.\n 'data-state': open ? 'open' : 'closed',\n };\n\n if (asChild && child) return cloneElement(child, handlers);\n return <span {...handlers}>{children}</span>;\n}\n\nexport interface TooltipContentProps {\n side?: TooltipSide;\n align?: TooltipAlign;\n sideOffset?: number;\n collisionPadding?: number;\n /** 화살표 렌더 (기본 true) */\n arrow?: boolean;\n className?: string;\n style?: CSSProperties;\n children?: ReactNode;\n [attr: string]: unknown;\n}\n\nexport function TooltipContent({\n side = 'top',\n align = 'center',\n sideOffset = 8,\n collisionPadding = 8,\n arrow = true,\n className,\n style,\n children,\n ...rest\n}: TooltipContentProps) {\n const ctx = useTooltipRoot('TooltipContent');\n const { open, anchor, contentId, hoverable, cancelClose, closeSoon } = ctx;\n\n // 코어는 이 핸들러를 addEventListener 로 **붙일 당시의 함수**로 등록한다(ITSM-2026-002299).\n // identity 를 고정하고 최신 콜백은 ref 로 읽는다.\n const hoverRef = useRef({ cancelClose, closeSoon });\n hoverRef.current = { cancelClose, closeSoon };\n const onBubbleEnter = useCallback(() => hoverRef.current.cancelClose(), []);\n const onBubbleLeave = useCallback(() => hoverRef.current.closeSoon(), []);\n\n const slots = useMemo(() => ({ content: children }), [children]);\n\n return (\n <MozTooltipCore\n open={open}\n anchor={anchor}\n side={side}\n align={align}\n sideOffset={sideOffset}\n collisionPadding={collisionPadding}\n arrow={arrow}\n tooltipId={contentId}\n className={className}\n style={style}\n slots={slots}\n data-hoverable={hoverable ? 'true' : undefined}\n onPointerEnter={hoverable ? onBubbleEnter : undefined}\n onPointerLeave={hoverable ? onBubbleLeave : undefined}\n {...rest}\n />\n );\n}\n","import {\n cloneElement,\n createContext,\n isValidElement,\n useCallback,\n useContext,\n useId,\n useMemo,\n useRef,\n useState,\n type CSSProperties,\n type MouseEvent as ReactMouseEvent,\n type ReactElement,\n type ReactNode,\n type Ref,\n} from 'react';\nimport {\n POPOVER_SPEC,\n type PopoverAlign,\n type PopoverCloseReason,\n type PopoverSide,\n} from '@vmscloud/moz-ui-components-core';\nimport { createMozComponent } from './createMozComponent';\n\n/**\n * Popover — 코어 패널 위의 React 전용 컴파운드 래퍼.\n *\n * Tooltip 과 같은 이유의 전용 래퍼다: 트리거·앵커가 **소비처가 이미 렌더한 React 엘리먼트**\n * 이고, 거기에 ref·클릭 토글·`aria-expanded`/`aria-controls` 를 얹는 일은 React 에서만 할 수\n * 있다. 코어는 앵커 element 를 받아 패널만 그리고, 상태·이벤트 배선은 여기서 한다.\n *\n * 콘텐츠는 브릿지의 **동적 slot 경로**(`slots={{ content: … }}`)로 넘긴다 — 소비자 React 트리\n * 안에서 `createPortal` 로 그려지므로 Router·QueryClient·테마 context 가 그대로 이어진다.\n *\n * 닫힘 계약은 코어의 `DismissStack` 이 담당한다. ESC 는 `window` capture 에서 **최상위 레이어**\n * 에만 전달되고 전파가 끊기므로, 다른 라이브러리의 모달 안에 이 팝오버가 있어도 바깥 레이어가\n * 함께 닫히지 않는다. 반대로 팝오버 위에 다른 라이브러리 모달이 열리면 소비 앱이\n * `registerForeignLayer()` 로 알려 이쪽이 ESC 에 손대지 않는다.\n */\n\nconst MozPopoverCore = createMozComponent(POPOVER_SPEC);\n\ninterface PopoverContextValue {\n open: boolean;\n setOpen: (next: boolean) => void;\n contentId: string;\n triggerEl: HTMLElement | null;\n anchorEl: HTMLElement | null;\n setTriggerEl: (el: HTMLElement | null) => void;\n setAnchorEl: (el: HTMLElement | null) => void;\n}\n\nconst PopoverContext = createContext<PopoverContextValue | null>(null);\n\nfunction usePopover(component: string): PopoverContextValue {\n const ctx = useContext(PopoverContext);\n if (!ctx) throw new Error(`${component} 는 <Popover> 안에서만 쓸 수 있습니다.`);\n return ctx;\n}\n\nfunction composeRefs<T>(...refs: Array<Ref<T> | undefined>) {\n return (node: T | null) => {\n for (const r of refs) {\n if (!r) continue;\n if (typeof r === 'function') r(node);\n else (r as { current: T | null }).current = node;\n }\n };\n}\n\nfunction chain<E>(theirs: unknown, ours: (event: E) => void) {\n return (event: E) => {\n if (typeof theirs === 'function') (theirs as (e: E) => void)(event);\n ours(event);\n };\n}\n\nexport interface PopoverProps {\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n children?: ReactNode;\n}\n\nexport function Popover({ open: openProp, defaultOpen = false, onOpenChange, children }: PopoverProps) {\n const [uncontrolled, setUncontrolled] = useState(defaultOpen);\n const controlled = openProp !== undefined;\n const open = controlled ? Boolean(openProp) : uncontrolled;\n\n const [triggerEl, setTriggerEl] = useState<HTMLElement | null>(null);\n const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null);\n const contentId = `moz-popover-${useId()}`;\n\n const onOpenChangeRef = useRef(onOpenChange);\n onOpenChangeRef.current = onOpenChange;\n\n const setOpen = useCallback(\n (next: boolean) => {\n if (!controlled) setUncontrolled(next);\n onOpenChangeRef.current?.(next);\n },\n [controlled],\n );\n\n const value = useMemo<PopoverContextValue>(\n () => ({ open, setOpen, contentId, triggerEl, anchorEl, setTriggerEl, setAnchorEl }),\n [open, setOpen, contentId, triggerEl, anchorEl],\n );\n\n return <PopoverContext.Provider value={value}>{children}</PopoverContext.Provider>;\n}\n\nexport interface PopoverTriggerProps {\n /** true 면 래퍼 없이 children 을 그대로 트리거로 쓴다 */\n asChild?: boolean;\n children?: ReactNode;\n}\n\nexport function PopoverTrigger({ asChild = false, children }: PopoverTriggerProps) {\n const { open, setOpen, contentId, setTriggerEl } = usePopover('PopoverTrigger');\n const child = isValidElement(children) ? (children as ReactElement<Record<string, unknown>>) : null;\n const childProps = (child?.props ?? {}) as Record<string, unknown>;\n\n const setRef = useMemo(\n () => composeRefs<HTMLElement>(setTriggerEl, (child as { ref?: Ref<HTMLElement> } | null)?.ref),\n [setTriggerEl, child],\n );\n\n const props = {\n ref: setRef,\n onClick: chain<ReactMouseEvent<HTMLElement>>(childProps.onClick, () => setOpen(!open)),\n 'aria-haspopup': 'dialog' as const,\n 'aria-expanded': open,\n 'aria-controls': open ? contentId : undefined,\n 'data-state': open ? 'open' : 'closed',\n };\n\n if (asChild && child) return cloneElement(child, props);\n return <span {...props}>{children}</span>;\n}\n\nexport interface PopoverAnchorProps {\n /** true 면 래퍼 없이 children 을 그대로 위치 기준으로 쓴다 */\n asChild?: boolean;\n children?: ReactNode;\n}\n\n/** 트리거와 위치 기준을 분리하고 싶을 때 쓴다. 클릭 토글·aria 는 붙지 않는다. */\nexport function PopoverAnchor({ asChild = false, children }: PopoverAnchorProps) {\n const { setAnchorEl } = usePopover('PopoverAnchor');\n const child = isValidElement(children) ? (children as ReactElement<Record<string, unknown>>) : null;\n\n const setRef = useMemo(\n () => composeRefs<HTMLElement>(setAnchorEl, (child as { ref?: Ref<HTMLElement> } | null)?.ref),\n [setAnchorEl, child],\n );\n\n if (asChild && child) return cloneElement(child, { ref: setRef });\n return <span ref={setRef}>{children}</span>;\n}\n\nexport interface PopoverCloseProps {\n asChild?: boolean;\n children?: ReactNode;\n}\n\nexport function PopoverClose({ asChild = false, children }: PopoverCloseProps) {\n const { setOpen } = usePopover('PopoverClose');\n const child = isValidElement(children) ? (children as ReactElement<Record<string, unknown>>) : null;\n const childProps = (child?.props ?? {}) as Record<string, unknown>;\n const props = {\n onClick: chain<ReactMouseEvent<HTMLElement>>(childProps.onClick, () => setOpen(false)),\n };\n if (asChild && child) return cloneElement(child, props);\n return <button type=\"button\" {...props}>{children}</button>;\n}\n\nexport interface PopoverContentProps {\n side?: PopoverSide;\n align?: PopoverAlign;\n sideOffset?: number;\n collisionPadding?: number;\n /** 패널 폭을 트리거 폭에 맞춘다. `--moz-popover-trigger-width` 는 값과 무관하게 항상 실린다 */\n matchTriggerWidth?: boolean;\n /** 열린 동안 Tab 을 패널 안에서 순환시킨다 (기본 true) */\n trapFocus?: boolean;\n className?: string;\n style?: CSSProperties;\n /** 열린 직후 자동 포커스 전 — `preventDefault()` 로 막는다 */\n onOpenAutoFocus?: (event: CustomEvent) => void;\n /** 닫힌 직후 포커스 복원 전 — `preventDefault()` 로 막는다 */\n onCloseAutoFocus?: (event: CustomEvent) => void;\n /** 최상위일 때의 ESC — `preventDefault()` 로 닫힘을 막는다 */\n onEscapeKeyDown?: (event: KeyboardEvent) => void;\n /** 패널 바깥 포인터 다운 — `preventDefault()` 로 닫힘을 막는다. 트리거·앵커 위는 제외된다 */\n onInteractOutside?: (event: CustomEvent<{ originalEvent: Event }>) => void;\n children?: ReactNode;\n [attr: string]: unknown;\n}\n\nexport function PopoverContent({\n side = 'bottom',\n align = 'start',\n sideOffset = 4,\n collisionPadding = 8,\n matchTriggerWidth = false,\n trapFocus = true,\n className,\n style,\n onOpenAutoFocus,\n onCloseAutoFocus,\n onEscapeKeyDown,\n onInteractOutside,\n children,\n ...rest\n}: PopoverContentProps) {\n const { open, setOpen, contentId, triggerEl, anchorEl } = usePopover('PopoverContent');\n\n // 코어는 이 핸들러들을 붙일 당시의 함수로 기억할 수 있다(ITSM-2026-002299) — identity 를\n // 고정하고 최신 콜백은 ref 로 읽는다.\n const latest = useRef({ setOpen, triggerEl, anchorEl, onOpenAutoFocus, onCloseAutoFocus, onEscapeKeyDown, onInteractOutside });\n latest.current = { setOpen, triggerEl, anchorEl, onOpenAutoFocus, onCloseAutoFocus, onEscapeKeyDown, onInteractOutside };\n\n const handleRequestClose = useCallback((_reason: PopoverCloseReason) => {\n latest.current.setOpen(false);\n }, []);\n\n const handleEscapeKeyDown = useCallback((event: KeyboardEvent) => {\n latest.current.onEscapeKeyDown?.(event);\n }, []);\n\n const handleInteractOutside = useCallback((event: CustomEvent<{ originalEvent: Event }>) => {\n // 트리거·앵커 위의 포인터 다운은 \"바깥\" 이 아니다. 트리거는 자기 클릭으로 토글하고,\n // 앵커는 입력창을 품는 경우가 있어(검색형 팝오버) 닫으면 안 된다.\n const target = event.detail?.originalEvent?.target as Node | null;\n const { triggerEl: trigger, anchorEl: anchor } = latest.current;\n if (target && ((trigger && trigger.contains(target)) || (anchor && anchor.contains(target)))) {\n event.preventDefault();\n return;\n }\n latest.current.onInteractOutside?.(event);\n }, []);\n\n const handleOpenAutoFocus = useCallback((event: CustomEvent) => {\n latest.current.onOpenAutoFocus?.(event);\n }, []);\n\n const handleCloseAutoFocus = useCallback((event: CustomEvent) => {\n latest.current.onCloseAutoFocus?.(event);\n }, []);\n\n const slots = useMemo(() => ({ content: children }), [children]);\n\n return (\n <MozPopoverCore\n open={open}\n anchor={anchorEl ?? triggerEl}\n side={side}\n align={align}\n sideOffset={sideOffset}\n collisionPadding={collisionPadding}\n matchTriggerWidth={matchTriggerWidth}\n trapFocus={trapFocus}\n popoverId={contentId}\n className={className}\n style={style}\n slots={slots}\n onRequestClose={handleRequestClose}\n onEscapeKeyDown={handleEscapeKeyDown}\n onInteractOutside={handleInteractOutside}\n onOpenAutoFocus={handleOpenAutoFocus}\n onCloseAutoFocus={handleCloseAutoFocus}\n {...rest}\n />\n );\n}\n","import {\n cloneElement,\n createContext,\n isValidElement,\n useCallback,\n useContext,\n useId,\n useMemo,\n useRef,\n useState,\n type CSSProperties,\n type MouseEvent as ReactMouseEvent,\n type ReactElement,\n type ReactNode,\n type Ref,\n} from 'react';\nimport { COLLAPSIBLE_SPEC } from '@vmscloud/moz-ui-components-core';\nimport { createMozComponent } from './createMozComponent';\n\n/**\n * Collapsible — 코어 콘텐츠 패널 위의 React 전용 컴파운드 래퍼.\n *\n * Tooltip·Popover 와 같은 이유의 전용 래퍼다: 트리거가 **소비처가 이미 렌더한 React 엘리먼트**\n * (버튼·행 헤더·아이콘 조합)이고, 거기에 클릭 토글·`aria-expanded`/`aria-controls` 를 얹는 일은\n * React 에서만 할 수 있다. 코어는 패널만 그리고, 상태·이벤트 배선은 여기서 한다.\n *\n * 콘텐츠는 브릿지의 **동적 slot 경로**(`slots={{ content: … }}`)로 넘긴다 — 소비자 React 트리\n * 안에서 `createPortal` 로 그려지므로 Router·QueryClient·테마 context 가 그대로 이어진다.\n *\n * 열림 상태는 controlled(`open`)/uncontrolled(`defaultOpen`) 둘 다 지원한다. controlled 에서는\n * 클릭이 내부 상태를 바꾸지 않고 `onOpenChange` 만 호출한다.\n */\n\nconst MozCollapsibleCore = createMozComponent(COLLAPSIBLE_SPEC);\n\ninterface CollapsibleContextValue {\n open: boolean;\n setOpen: (next: boolean) => void;\n contentId: string;\n disabled: boolean;\n}\n\nconst CollapsibleContext = createContext<CollapsibleContextValue | null>(null);\n\nfunction useCollapsible(component: string): CollapsibleContextValue {\n const ctx = useContext(CollapsibleContext);\n if (!ctx) throw new Error(`${component} 는 <Collapsible> 안에서만 쓸 수 있습니다.`);\n return ctx;\n}\n\nfunction composeRefs<T>(...refs: Array<Ref<T> | undefined>) {\n return (node: T | null) => {\n for (const r of refs) {\n if (!r) continue;\n if (typeof r === 'function') r(node);\n else (r as { current: T | null }).current = node;\n }\n };\n}\n\nfunction chain<E>(theirs: unknown, ours: (event: E) => void) {\n return (event: E) => {\n if (typeof theirs === 'function') (theirs as (e: E) => void)(event);\n ours(event);\n };\n}\n\n/** `asChild` 로 합칠 때 소비처 className 을 지우지 않는다. */\nfunction mergeClassName(theirs: unknown, ours: string | undefined): string | undefined {\n const merged = [theirs, ours].filter((v) => typeof v === 'string' && v.length > 0).join(' ');\n return merged.length > 0 ? merged : undefined;\n}\n\nexport interface CollapsibleProps {\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n disabled?: boolean;\n /** true 면 래퍼 div 없이 children 을 그대로 루트로 쓴다 */\n asChild?: boolean;\n className?: string;\n style?: CSSProperties;\n children?: ReactNode;\n [attr: string]: unknown;\n}\n\nexport function Collapsible({\n open: openProp,\n defaultOpen = false,\n onOpenChange,\n disabled = false,\n asChild = false,\n className,\n style,\n children,\n ...rest\n}: CollapsibleProps) {\n const [uncontrolled, setUncontrolled] = useState(defaultOpen);\n const controlled = openProp !== undefined;\n const open = controlled ? Boolean(openProp) : uncontrolled;\n\n const contentId = `moz-collapsible-${useId()}`;\n\n const onOpenChangeRef = useRef(onOpenChange);\n onOpenChangeRef.current = onOpenChange;\n\n const setOpen = useCallback(\n (next: boolean) => {\n if (!controlled) setUncontrolled(next);\n onOpenChangeRef.current?.(next);\n },\n [controlled],\n );\n\n const value = useMemo<CollapsibleContextValue>(\n () => ({ open, setOpen, contentId, disabled }),\n [open, setOpen, contentId, disabled],\n );\n\n const rootProps: Record<string, unknown> = {\n 'data-state': open ? 'open' : 'closed',\n 'data-disabled': disabled ? '' : undefined,\n ...rest,\n };\n\n const child = isValidElement(children) ? (children as ReactElement<Record<string, unknown>>) : null;\n const body =\n asChild && child ? (\n cloneElement(child, {\n ...rootProps,\n className: mergeClassName(child.props.className, className),\n style: (style ?? child.props.style) as CSSProperties | undefined,\n })\n ) : (\n <div {...rootProps} className={className} style={style}>\n {children}\n </div>\n );\n\n return <CollapsibleContext.Provider value={value}>{body}</CollapsibleContext.Provider>;\n}\n\nexport interface CollapsibleTriggerProps {\n /** true 면 래퍼 없이 children 을 그대로 트리거로 쓴다 */\n asChild?: boolean;\n disabled?: boolean;\n className?: string;\n style?: CSSProperties;\n onClick?: (event: ReactMouseEvent<HTMLElement>) => void;\n children?: ReactNode;\n [attr: string]: unknown;\n}\n\nexport function CollapsibleTrigger({\n asChild = false,\n disabled: disabledProp,\n className,\n style,\n onClick,\n children,\n ...rest\n}: CollapsibleTriggerProps) {\n const { open, setOpen, contentId, disabled: rootDisabled } = useCollapsible('CollapsibleTrigger');\n const disabled = disabledProp ?? rootDisabled;\n\n const toggle = useCallback(() => {\n if (disabled) return;\n setOpen(!open);\n }, [disabled, open, setOpen]);\n\n const child = isValidElement(children) ? (children as ReactElement<Record<string, unknown>>) : null;\n const childProps = (child?.props ?? {}) as Record<string, unknown>;\n\n const shared: Record<string, unknown> = {\n 'aria-expanded': open,\n 'aria-controls': contentId,\n 'data-state': open ? 'open' : 'closed',\n 'data-disabled': disabled ? '' : undefined,\n ...rest,\n };\n\n if (asChild && child) {\n const setRef = composeRefs<HTMLElement>((child as { ref?: Ref<HTMLElement> }).ref);\n return cloneElement(child, {\n ...shared,\n ref: setRef,\n className: mergeClassName(childProps.className, className),\n style: (style ?? childProps.style) as CSSProperties | undefined,\n // 소비처 onClick 을 먼저 돌리고 토글한다 — 소비처가 stopPropagation 을 걸어도\n // 토글 의미는 유지된다(Radix 와 같은 순서).\n onClick: chain<ReactMouseEvent<HTMLElement>>(childProps.onClick, (event) => {\n onClick?.(event);\n toggle();\n }),\n disabled: disabled || undefined,\n });\n }\n\n return (\n <button\n type=\"button\"\n {...shared}\n className={className}\n style={style}\n disabled={disabled || undefined}\n onClick={chain<ReactMouseEvent<HTMLElement>>(onClick, toggle)}\n >\n {children}\n </button>\n );\n}\n\nexport interface CollapsibleContentProps {\n /** 닫혀도 DOM 에 남긴다(`hidden`). 기본은 Radix Presence 와 같이 언마운트다. */\n forceMount?: boolean;\n className?: string;\n style?: CSSProperties;\n /** 패널 자연 높이(px) 변화 — 소비처 애니메이션·가상 스크롤 보정용 */\n onHeightChange?: (height: number) => void;\n children?: ReactNode;\n [attr: string]: unknown;\n}\n\nexport function CollapsibleContent({\n forceMount = false,\n className,\n style,\n onHeightChange,\n children,\n ...rest\n}: CollapsibleContentProps) {\n const { open, contentId, disabled } = useCollapsible('CollapsibleContent');\n\n // 코어는 핸들러를 붙일 당시의 함수로 기억할 수 있다(ITSM-2026-002299) — identity 를 고정하고\n // 최신 콜백은 ref 로 읽는다.\n const latest = useRef({ onHeightChange });\n latest.current = { onHeightChange };\n const handleHeightChange = useCallback((height: number) => {\n latest.current.onHeightChange?.(height);\n }, []);\n\n const slots = useMemo(() => ({ content: children }), [children]);\n\n return (\n <MozCollapsibleCore\n open={open}\n forceMount={forceMount}\n contentId={contentId}\n disabled={disabled}\n className={className}\n style={style}\n slots={slots}\n onHeightChange={handleHeightChange}\n {...rest}\n />\n );\n}\n","import { Children, isValidElement, useMemo, type CSSProperties, type ReactElement, type ReactNode } from 'react';\nimport { AVATAR_SPEC, type AvatarLoadingStatus } from '@vmscloud/moz-ui-components-core';\nimport { createMozComponent } from './createMozComponent';\n\n/**\n * Avatar — 코어 로드 상태 기계 위의 React 컴파운드 래퍼.\n *\n * 사용법은 흔한 컴파운드 형태 그대로다:\n *\n * <Avatar className=\"h-9 w-9\">\n * <AvatarImage src={user.avatarUrl} alt={user.name} />\n * <AvatarFallback>{initial}</AvatarFallback>\n * </Avatar>\n *\n * 다만 `AvatarImage`·`AvatarFallback` 은 **스스로 DOM 을 그리지 않는다.** 이미지와 대체 표시는\n * 서로 배타적이고 그 전환을 결정하는 것은 코어의 로드 상태이므로, 두 자식은 \"설정\"만 담고\n * 루트가 코어 하나를 그린다. SplitPane 의 `<Pane>` introspection 과 같은 방식이다.\n *\n * 이 형태를 고른 이유는 소비처 호환이다 — 컴파운드 사용법을 유지하면 기존 호출부를 한 줄도\n * 고치지 않고 구현만 갈아 끼울 수 있다.\n */\n\nconst MozAvatarCore = createMozComponent(AVATAR_SPEC);\n\nexport interface AvatarImageProps {\n src?: string;\n alt?: string;\n className?: string;\n}\n\n/** 설정 전용 — 실제 `<img>` 는 코어가 로드 성공 시에만 그린다. */\nexport function AvatarImage(_props: AvatarImageProps): null {\n return null;\n}\n\nexport interface AvatarFallbackProps {\n /** 이 시간(ms)이 지나기 전에는 대체 표시를 그리지 않는다 (캐시 이미지 깜빡임 방지) */\n delayMs?: number;\n className?: string;\n children?: ReactNode;\n}\n\n/** 설정 전용 — 대체 표시는 코어의 `fallback` slot 으로 넘어간다. */\nexport function AvatarFallback(_props: AvatarFallbackProps): null {\n return null;\n}\n\nexport interface AvatarProps {\n className?: string;\n style?: CSSProperties;\n /** 로드 상태 변화 통지 (`idle`/`loading`/`loaded`/`error`) */\n onLoadingStatusChange?: (status: AvatarLoadingStatus) => void;\n children?: ReactNode;\n [attr: string]: unknown;\n}\n\nexport function Avatar({ className, style, onLoadingStatusChange, children, ...rest }: AvatarProps) {\n let image: AvatarImageProps | undefined;\n let fallback: AvatarFallbackProps | undefined;\n\n Children.forEach(children, (child) => {\n if (!isValidElement(child)) return;\n if (child.type === AvatarImage) image = (child as ReactElement<AvatarImageProps>).props;\n else if (child.type === AvatarFallback) fallback = (child as ReactElement<AvatarFallbackProps>).props;\n });\n\n const fallbackChildren = fallback?.children;\n const slots = useMemo(() => ({ fallback: fallbackChildren }), [fallbackChildren]);\n\n return (\n <MozAvatarCore\n src={image?.src}\n alt={image?.alt}\n imageClass={image?.className}\n fallbackClass={fallback?.className}\n delayMs={fallback?.delayMs}\n className={className}\n style={style}\n slots={slots}\n onLoadingStatusChange={onLoadingStatusChange}\n {...rest}\n />\n );\n}\n","import {\n useCallback,\n useState,\n type CSSProperties,\n type MutableRefObject,\n type ReactNode,\n type Ref,\n} from 'react';\nimport { SCROLLAREA_SPEC, type ScrollAreaOrientation, type ScrollbarVisibility } from '@vmscloud/moz-ui-components-core';\nimport { createMozComponent } from './createMozComponent';\n\n/**\n * ScrollArea — 네이티브 스크롤 뷰포트 + 코어가 그리는 커스텀 스크롤바.\n *\n * **뷰포트는 이 래퍼가 자기 React 트리에 직접 렌더한다.** 코어 slot 으로 끌어오지 않는 이유는\n * 타이밍이다 — slot 콘텐츠는 코어가 마운트된 뒤 포털로 그려지므로 소비자 트리보다 한 커밋\n * 늦게 마운트되고, 그러면 \"자식 layout effect 가 부모보다 먼저 돈다\" 는 React 불변식에 기대는\n * 소비처 로직이 조용히 깨진다(소비 앱 실측: 사이드바 초기 활성 항목 중앙 정렬 소실).\n * children 이 평범한 React 자식이면 그 문제가 애초에 생기지 않고 context 도 당연히 이어진다.\n *\n * 코어는 뷰포트 element 를 `viewport` prop 으로 받아 스크롤·리사이즈를 관찰하고 thumb 만\n * 그린다 — Tooltip 이 트리거를 그리지 않고 `anchor` 를 받는 것과 같은 형태다.\n *\n * 루트·뷰포트가 평범한 React element 이므로 `style` 에 숫자를 줘도 React 가 px 를 붙이고,\n * `onMouseLeave` 같은 핸들러도 합성 이벤트로 그대로 동작한다.\n */\n\nconst MozScrollAreaBars = createMozComponent(SCROLLAREA_SPEC);\n\nexport interface ScrollAreaProps {\n /** 어느 방향 스크롤바를 그릴지. 기본 `vertical` */\n orientation?: ScrollAreaOrientation;\n /** 기본 `always`. `hover` 는 영역 hover·내부 focus·thumb drag 동안만 표시한다 */\n scrollbarVisibility?: ScrollbarVisibility;\n className?: string;\n viewportClassName?: string;\n scrollbarClassName?: string;\n thumbClassName?: string;\n /** 실제 스크롤 컨테이너(뷰포트) element 를 받는다 */\n viewportRef?: Ref<HTMLDivElement | null>;\n style?: CSSProperties;\n onScroll?: (position: { scrollTop: number; scrollLeft: number }) => void;\n children?: ReactNode;\n [attr: string]: unknown;\n}\n\nexport function ScrollArea({\n orientation = 'vertical',\n scrollbarVisibility = 'always',\n className,\n viewportClassName,\n scrollbarClassName,\n thumbClassName,\n viewportRef,\n style,\n onScroll,\n children,\n ...rest\n}: ScrollAreaProps) {\n // 코어에 넘길 뷰포트는 state 여야 한다 — ref 로만 잡으면 값이 생겨도 재렌더가 없어\n // 코어가 영원히 null 을 본다.\n const [viewport, setViewport] = useState<HTMLDivElement | null>(null);\n\n const setRef = useCallback(\n (node: HTMLDivElement | null) => {\n setViewport(node);\n if (typeof viewportRef === 'function') viewportRef(node);\n else if (viewportRef) (viewportRef as MutableRefObject<HTMLDivElement | null>).current = node;\n },\n [viewportRef],\n );\n\n return (\n <div className={['moz-scroll-area', className].filter(Boolean).join(' ')} style={style} {...rest}>\n <div\n ref={setRef}\n className={['moz-scroll-area-viewport', viewportClassName].filter(Boolean).join(' ')}\n data-moz-scroll-area-viewport=\"\"\n >\n {children}\n </div>\n <MozScrollAreaBars\n viewport={viewport}\n interactionRoot={viewport?.parentElement}\n scrollbarVisibility={scrollbarVisibility}\n orientation={orientation}\n scrollbarClass={scrollbarClassName}\n thumbClass={thumbClassName}\n onScroll={onScroll}\n />\n </div>\n );\n}\n","import type { ButtonProps as CoreButtonProps } from '@vmscloud/moz-ui-components-core';\nimport {\n BADGE_SPEC,\n BREADCRUMB_SPEC,\n BUTTON_SPEC,\n CALENDAR_SPEC,\n CHIP_SPEC,\n CHECKBOX_SPEC,\n CONTEXTMENU_SPEC,\n CONTROLLER_SPEC,\n DATEINPUT_SPEC,\n EMPTYSTATE_SPEC,\n INPUT_SPEC,\n LABEL_SPEC,\n MULTISELECT_SPEC,\n NUMBERINPUT_SPEC,\n PASSWORDINPUT_SPEC,\n POPUP_SPEC,\n RADIO_SPEC,\n SELECT_SPEC,\n SLIDER_SPEC,\n TABLESELECT_SPEC,\n TAB_SPEC,\n TAGINPUT_SPEC,\n TEXTAREA_SPEC,\n TIMEPICKER_SPEC,\n TOAST_SPEC,\n TREESELECT_SPEC,\n TOGGLE_SPEC,\n} from '@vmscloud/moz-ui-components-core';\nimport { createMozComponent } from './createMozComponent';\n\nexport { useToast } from '@vmscloud/moz-ui-components-core';\nexport type { ToastOptions, ToastInstance, ToastProps, ToastType, ToastPosition } from '@vmscloud/moz-ui-components-core';\nexport type { BadgeProps, BadgeTone, BadgeAppearance, BadgeSize } from '@vmscloud/moz-ui-components-core';\nexport type { ChipProps, ChipTone, ChipAppearance, ChipSize } from '@vmscloud/moz-ui-components-core';\n\n/**\n * 각 컴포넌트는 공용 브릿지 + 코어 스펙으로 1줄 정의.\n * 사용 예:\n * <Button type=\"outline\" width={120} action=\"Search\" onClick={onSearch}\n * icon={({ disabled }) => <SearchIcon dim={disabled} />}>\n * Search\n * </Button>\n * <Toggle modelValue={on} onChange={(v) => setOn(v)} label=\"Enabled\" />\n * 스타일: `import '@vmscloud/moz-ui-components-core/styles/button.css'` (컴포넌트별)\n */\nexport const Button = createMozComponent(BUTTON_SPEC);\nexport const Label = createMozComponent(LABEL_SPEC);\nexport const Badge = createMozComponent(BADGE_SPEC);\nexport const Chip = createMozComponent(CHIP_SPEC);\nexport const Toggle = createMozComponent(TOGGLE_SPEC);\nexport const BreadCrumb = createMozComponent(BREADCRUMB_SPEC);\nexport const EmptyState = createMozComponent(EMPTYSTATE_SPEC);\nexport const CheckBox = createMozComponent(CHECKBOX_SPEC);\nexport const Radio = createMozComponent(RADIO_SPEC);\nexport const Input = createMozComponent(INPUT_SPEC);\nexport const PasswordInput = createMozComponent(PASSWORDINPUT_SPEC);\nexport const TextArea = createMozComponent(TEXTAREA_SPEC);\nexport const NumberInput = createMozComponent(NUMBERINPUT_SPEC);\nexport const Tab = createMozComponent(TAB_SPEC);\nexport const Slider = createMozComponent(SLIDER_SPEC);\nexport const Calendar = createMozComponent(CALENDAR_SPEC);\nexport const DateInput = createMozComponent(DATEINPUT_SPEC);\nexport const Popup = createMozComponent(POPUP_SPEC);\nexport const Select = createMozComponent(SELECT_SPEC);\nexport const MultiSelect = createMozComponent(MULTISELECT_SPEC);\nexport const TimePicker = createMozComponent(TIMEPICKER_SPEC);\nexport const TagInput = createMozComponent(TAGINPUT_SPEC);\nexport const ContextMenu = createMozComponent(CONTEXTMENU_SPEC);\nexport const TableSelect = createMozComponent(TABLESELECT_SPEC);\nexport const TreeSelect = createMozComponent(TREESELECT_SPEC);\nexport const Controller = createMozComponent(CONTROLLER_SPEC);\n\n// SplitPane/Pane 은 자식 <Pane> introspection 이 필요해 전용 래퍼로 정의(원본 사용법 유지).\nexport { SplitPane, Pane } from './split-pane';\nexport const Toast = createMozComponent(TOAST_SPEC);\n\n// Tooltip 은 트리거가 소비처의 React 엘리먼트다 — cloneElement 로 ref·포인터/포커스 핸들러·\n// aria-describedby 를 얹고, 콘텐츠는 동적 slot 경로로 넘겨 소비자 context 를 잇는다.\n// 그래서 한 줄 정의가 아니라 전용 래퍼다(SplitPane 과 같은 이유).\nexport { Tooltip, TooltipProvider, TooltipTrigger, TooltipContent } from './tooltip';\nexport type {\n TooltipProps,\n TooltipProviderProps,\n TooltipTriggerProps,\n TooltipContentProps,\n} from './tooltip';\n\n// Popover 도 같은 이유의 전용 래퍼다 — 트리거·앵커가 소비처 React 엘리먼트이고, 상태·클릭\n// 토글·aria-expanded/controls 배선이 React 쪽 일이다. 닫힘 계층은 코어 DismissStack 이 맡는다.\nexport { Popover, PopoverTrigger, PopoverAnchor, PopoverContent, PopoverClose } from './popover';\nexport type {\n PopoverProps,\n PopoverTriggerProps,\n PopoverAnchorProps,\n PopoverContentProps,\n PopoverCloseProps,\n} from './popover';\n\n// Collapsible 도 같은 이유의 전용 래퍼다 — 트리거가 소비처 React 엘리먼트이고, 열림 상태·\n// 클릭 토글·aria-expanded/controls 배선이 React 쪽 일이다. 코어는 콘텐츠 패널만 그린다.\nexport { Collapsible, CollapsibleTrigger, CollapsibleContent } from './collapsible';\nexport type {\n CollapsibleProps,\n CollapsibleTriggerProps,\n CollapsibleContentProps,\n} from './collapsible';\n\n// Avatar 는 이미지/대체 표시가 배타적이고 그 전환이 코어의 로드 상태 소관이라, 자식 두 개가\n// 설정만 담고 루트가 코어 하나를 그리는 형태다(SplitPane 의 <Pane> introspection 과 같은 방식).\nexport { Avatar, AvatarImage, AvatarFallback } from './avatar';\nexport type { AvatarProps, AvatarImageProps, AvatarFallbackProps } from './avatar';\n\n// ScrollArea 는 콘텐츠가 소비처 React 서브트리이고, 소비처가 뷰포트 element 를 직접 잡아\n// 스크롤 위치를 읽고 쓰는 경우가 있어 전용 래퍼다(viewportRef).\nexport { ScrollArea } from './scroll-area';\nexport type { ScrollAreaProps } from './scroll-area';\n\nexport type { CoreButtonProps };\n"],"names":["pendingUnmounts","unmountTimer","deferUnmount","root","batch","r","ReactRenderer","__publicField","wrapper","container","component","initialProps","createRoot","renderProps","props","element","createElement","MozLocaleContext","createContext","koKR","MozContextWrapperContext","MozConfigProvider","locale","contextWrapper","children","useMozLocale","useContext","useMozContextWrapper","ValidatorReactContext","Validator","ref","useRef","createValidator","api","useValidatorContext","handlerKeyOf","emitName","sameScope","a","b","ka","kb","k","shallowEqualProps","createMozComponent","spec","models","reservedKeys","m","name","model","Comp","forwardRef","host","core","handle","portalSlots","setPortalSlots","useState","h","_a","rendererRef","validatorCtx","propsRef","emitFn","args","key","handler","buildProps","src","p","useLayoutEffect","R","slotMap","el","scope","SlotComp","s","content","slotResolver","bag","prev","cur","next","slotSignature","sig","lastSentRef","useEffect","c","slots","last","useImperativeHandle","portals","node","createPortal","Fragment","MozSplitPane","SPLITPANE_SPEC","Pane","_props","SplitPane","horizontal","paneEls","Children","isValidElement","panes","paneProps","i","jsx","MozTooltipCore","TOOLTIP_SPEC","openTooltips","DEFAULT_DELAY","CLOSE_GRACE_MS","TooltipProviderContext","TooltipProvider","delayDuration","disableHoverableContent","value","useMemo","TooltipRootContext","useTooltipRoot","ctx","Tooltip","openProp","defaultOpen","onOpenChange","provider","delay","hoverable","uncontrolled","setUncontrolled","controlled","open","anchor","setAnchor","contentId","useId","openTimer","closeTimer","onOpenChangeRef","clearTimers","useCallback","setOpen","openNow","openDelayed","closeNow","closeSoon","cancelClose","closeRef","self","other","onKeyDown","event","chain","theirs","ours","applyRef","TooltipTrigger","asChild","child","childProps","childRef","childRefRef","anchorNodeRef","setRef","appliedChildRef","handlers","cloneElement","TooltipContent","side","align","sideOffset","collisionPadding","arrow","className","style","rest","hoverRef","onBubbleEnter","onBubbleLeave","MozPopoverCore","POPOVER_SPEC","PopoverContext","usePopover","composeRefs","refs","Popover","triggerEl","setTriggerEl","anchorEl","setAnchorEl","PopoverTrigger","PopoverAnchor","PopoverClose","PopoverContent","matchTriggerWidth","trapFocus","onOpenAutoFocus","onCloseAutoFocus","onEscapeKeyDown","onInteractOutside","latest","handleRequestClose","_reason","handleEscapeKeyDown","_b","handleInteractOutside","target","trigger","_d","_c","handleOpenAutoFocus","handleCloseAutoFocus","MozCollapsibleCore","COLLAPSIBLE_SPEC","CollapsibleContext","useCollapsible","mergeClassName","merged","v","Collapsible","disabled","rootProps","body","CollapsibleTrigger","disabledProp","onClick","rootDisabled","toggle","shared","CollapsibleContent","forceMount","onHeightChange","handleHeightChange","height","MozAvatarCore","AVATAR_SPEC","AvatarImage","AvatarFallback","Avatar","onLoadingStatusChange","image","fallback","fallbackChildren","MozScrollAreaBars","SCROLLAREA_SPEC","ScrollArea","orientation","scrollbarVisibility","viewportClassName","scrollbarClassName","thumbClassName","viewportRef","onScroll","viewport","setViewport","jsxs","Button","BUTTON_SPEC","Label","LABEL_SPEC","Badge","BADGE_SPEC","Chip","CHIP_SPEC","Toggle","TOGGLE_SPEC","BreadCrumb","BREADCRUMB_SPEC","EmptyState","EMPTYSTATE_SPEC","CheckBox","CHECKBOX_SPEC","Radio","RADIO_SPEC","Input","INPUT_SPEC","PasswordInput","PASSWORDINPUT_SPEC","TextArea","TEXTAREA_SPEC","NumberInput","NUMBERINPUT_SPEC","Tab","TAB_SPEC","Slider","SLIDER_SPEC","Calendar","CALENDAR_SPEC","DateInput","DATEINPUT_SPEC","Popup","POPUP_SPEC","Select","SELECT_SPEC","MultiSelect","MULTISELECT_SPEC","TimePicker","TIMEPICKER_SPEC","TagInput","TAGINPUT_SPEC","ContextMenu","CONTEXTMENU_SPEC","TableSelect","TABLESELECT_SPEC","TreeSelect","TREESELECT_SPEC","Controller","CONTROLLER_SPEC","Toast","TOAST_SPEC"],"mappings":"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"}