@clicktap/ui 0.40.7 → 0.40.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (23) hide show
  1. package/components/Menu/Menu.js +1 -1
  2. package/docs/migrations/2026/01/2026-01-14-external-link-detection.md +290 -0
  3. package/docs/migrations/2026/01/2026-01-14-use-route-hook.md +142 -0
  4. package/docs/migrations/2026/01/2026-01-15-input-disable-skeleton.md +82 -0
  5. package/docs/migrations/2026/02/2026-02-16-env-utils-from-clicktap-ui.md +94 -0
  6. package/docs/migrations/2026/02/2026-02-17-select-popover-portal-container-restored.md +84 -0
  7. package/docs/migrations/2026/03/2026-03-24-image-dimmed-hidden-onready.md +108 -0
  8. package/docs/migrations/2026/03/2026-03-24-modal-overlay-backdrop-dismiss.md +81 -0
  9. package/docs/migrations/2026/04/2026-04-17-select-address-input-onchange-key-or-item.md +182 -0
  10. package/docs/migrations/2026/04/2026-04-24-image-placeholder-frontend-fallback.md +85 -0
  11. package/docs/migrations/2026/04/2026-04-30-prune-invalid-pdp-selections.md +166 -0
  12. package/docs/migrations/2026/04/2026-04-30-top-down-pdp-option-dependency.md +286 -0
  13. package/docs/migrations/2026/05/2026-05-01-build-pdp-url-util.md +128 -0
  14. package/docs/migrations/2026/05/2026-05-03-auth-aware-graphql-client.md +278 -0
  15. package/docs/migrations/2026/05/2026-05-20-framer-motion-11-idioms.md +391 -0
  16. package/docs/migrations/2026/05/2026-05-21-button-loading-content.md +265 -0
  17. package/docs/migrations/2026/05/2026-05-21-password-check-hide-on-empty.md +50 -0
  18. package/docs/migrations/2026/05/2026-05-29-password-check-requirements-variant.md +63 -0
  19. package/docs/migrations/2026/06/2026-06-17-select-standardization.md +286 -0
  20. package/docs/migrations/2026/06/2026-06-18-select-hiddenselect-setvalue-crash.md +75 -0
  21. package/docs/migrations/2026/07/2026-07-31-ui-exports-bundler-resolution.md +50 -0
  22. package/docs/migrations/README.md +31 -0
  23. package/package.json +2 -2
@@ -1 +1 @@
1
- "use client";import{jsx as Oe,jsxs as Ye,Fragment as Ot}from"react/jsx-runtime";import*as g from"react";import{useLayoutEffect as lt,useEffect as Tt,useRef as ut,useState as St,useId as At,cloneElement as Dt}from"react";import{motion as Lt}from"framer-motion";import*as Mt from"react-dom";function ft(e){return at(e)?(e.nodeName||"").toLowerCase():"#document"}function ce(e){var t;return(e==null||(t=e.ownerDocument)==null?void 0:t.defaultView)||window}function kt(e){var t;return(t=(at(e)?e.ownerDocument:e.document)||window.document)==null?void 0:t.documentElement}function at(e){return e instanceof Node||e instanceof ce(e).Node}function _(e){return e instanceof Element||e instanceof ce(e).Element}function Re(e){return e instanceof HTMLElement||e instanceof ce(e).HTMLElement}function ke(e){return typeof ShadowRoot>"u"?!1:e instanceof ShadowRoot||e instanceof ce(e).ShadowRoot}function Ft(e){return["html","body","#document"].includes(ft(e))}function $t(e){return ce(e).getComputedStyle(e)}function It(e){if(ft(e)==="html")return e;const t=e.assignedSlot||e.parentNode||ke(e)&&e.host||kt(e);return ke(t)?t.host:t}function Nt(e){let t=e.activeElement;for(;((n=t)==null||(o=n.shadowRoot)==null?void 0:o.activeElement)!=null;){var n,o;t=t.shadowRoot.activeElement}return t}function se(e,t){if(!e||!t)return!1;const n=t.getRootNode&&t.getRootNode();if(e.contains(t))return!0;if(n&&ke(n)){let o=t;for(;o;){if(e===o)return!0;o=o.parentNode||o.host}}return!1}function _t(){const e=navigator.userAgentData;return e!=null&&e.platform?e.platform:navigator.platform}function Wt(){const e=navigator.userAgentData;return e&&Array.isArray(e.brands)?e.brands.map(t=>{let{brand:n,version:o}=t;return n+"/"+o}).join(" "):navigator.userAgent}function Bt(e){if(e.mozInputSource===0&&e.isTrusted)return!0;const t=/Android/i;return(t.test(_t())||t.test(Wt()))&&e.pointerType?e.type==="click"&&e.buttons===1:e.detail===0&&!e.pointerType}function Vt(e){return e.width===0&&e.height===0||e.width===1&&e.height===1&&e.pressure===0&&e.detail===0&&e.pointerType!=="mouse"||e.width<1&&e.height<1&&e.pressure===0&&e.detail===0}function he(e,t){const n=["mouse","pen"];return t||n.push("",void 0),n.includes(e)}function Ht(e){return"nativeEvent"in e}function Kt(e){return e.matches("html,body")}function X(e){return e?.ownerDocument||document}function de(e,t){if(t==null)return!1;if("composedPath"in e)return e.composedPath().includes(t);const n=e;return n.target!=null&&t.contains(n.target)}function jt(e){return"composedPath"in e?e.composedPath()[0]:e.target}const Xt="input:not([type='hidden']):not([disabled]),[contenteditable]:not([contenteditable='false']),textarea:not([disabled])";function zt(e){return Re(e)&&e.matches(Xt)}const oe=Math.min,Z=Math.max,ve=Math.round,ae=Math.floor,K=e=>({x:e,y:e}),Yt={left:"right",right:"left",bottom:"top",top:"bottom"};function Fe(e,t,n){return Z(e,oe(t,n))}function le(e,t){return typeof e=="function"?e(t):e}function J(e){return e.split("-")[0]}function ue(e){return e.split("-")[1]}function dt(e){return e==="x"?"y":"x"}function We(e){return e==="y"?"height":"width"}function Y(e){const t=e[0];return t==="t"||t==="b"?"y":"x"}function Be(e){return dt(Y(e))}function Ut(e,t,n){n===void 0&&(n=!1);const o=ue(e),r=Be(e),i=We(r);let s=r==="x"?o===(n?"end":"start")?"right":"left":o==="start"?"bottom":"top";return t.reference[i]>t.floating[i]&&(s=ye(s)),[s,ye(s)]}function qt(e){const t=ye(e);return[$e(e),t,$e(t)]}function $e(e){return e.includes("start")?e.replace("start","end"):e.replace("end","start")}const Ue=["left","right"],qe=["right","left"],Gt=["top","bottom"],Qt=["bottom","top"];function Zt(e,t,n){switch(e){case"top":case"bottom":return n?t?qe:Ue:t?Ue:qe;case"left":case"right":return t?Gt:Qt;default:return[]}}function Jt(e,t,n,o){const r=ue(e);let i=Zt(J(e),n==="start",o);return r&&(i=i.map(s=>s+"-"+r),t&&(i=i.concat(i.map($e)))),i}function ye(e){const t=J(e);return Yt[t]+e.slice(t.length)}function en(e){return{top:0,right:0,bottom:0,left:0,...e}}function mt(e){return typeof e!="number"?en(e):{top:e,right:e,bottom:e,left:e}}function we(e){const{x:t,y:n,width:o,height:r}=e;return{width:o,height:r,top:n,left:t,right:t+o,bottom:n+r,x:t,y:n}}function Ge(e,t,n){let{reference:o,floating:r}=e;const i=Y(t),s=Be(t),c=We(s),u=J(t),f=i==="y",d=o.x+o.width/2-r.width/2,a=o.y+o.height/2-r.height/2,m=o[c]/2-r[c]/2;let l;switch(u){case"top":l={x:d,y:o.y-r.height};break;case"bottom":l={x:d,y:o.y+o.height};break;case"right":l={x:o.x+o.width,y:a};break;case"left":l={x:o.x-r.width,y:a};break;default:l={x:o.x,y:o.y}}switch(ue(t)){case"start":l[s]-=m*(n&&f?-1:1);break;case"end":l[s]+=m*(n&&f?-1:1);break}return l}async function tn(e,t){var n;t===void 0&&(t={});const{x:o,y:r,platform:i,rects:s,elements:c,strategy:u}=e,{boundary:f="clippingAncestors",rootBoundary:d="viewport",elementContext:a="floating",altBoundary:m=!1,padding:l=0}=le(t,e),p=mt(l),E=c[m?a==="floating"?"reference":"floating":a],x=we(await i.getClippingRect({element:(n=await(i.isElement==null?void 0:i.isElement(E)))==null||n?E:E.contextElement||await(i.getDocumentElement==null?void 0:i.getDocumentElement(c.floating)),boundary:f,rootBoundary:d,strategy:u})),C=a==="floating"?{x:o,y:r,width:s.floating.width,height:s.floating.height}:s.reference,S=await(i.getOffsetParent==null?void 0:i.getOffsetParent(c.floating)),b=await(i.isElement==null?void 0:i.isElement(S))?await(i.getScale==null?void 0:i.getScale(S))||{x:1,y:1}:{x:1,y:1},O=we(i.convertOffsetParentRelativeRectToViewportRelativeRect?await i.convertOffsetParentRelativeRectToViewportRelativeRect({elements:c,rect:C,offsetParent:S,strategy:u}):C);return{top:(x.top-O.top+p.top)/b.y,bottom:(O.bottom-x.bottom+p.bottom)/b.y,left:(x.left-O.left+p.left)/b.x,right:(O.right-x.right+p.right)/b.x}}const nn=50,on=async(e,t,n)=>{const{placement:o="bottom",strategy:r="absolute",middleware:i=[],platform:s}=n,c=s.detectOverflow?s:{...s,detectOverflow:tn},u=await(s.isRTL==null?void 0:s.isRTL(t));let f=await s.getElementRects({reference:e,floating:t,strategy:r}),{x:d,y:a}=Ge(f,o,u),m=o,l=0;const p={};for(let h=0;h<i.length;h++){const E=i[h];if(!E)continue;const{name:x,fn:C}=E,{x:S,y:b,data:O,reset:P}=await C({x:d,y:a,initialPlacement:o,placement:m,strategy:r,middlewareData:p,rects:f,platform:c,elements:{reference:e,floating:t}});d=S??d,a=b??a,p[x]={...p[x],...O},P&&l<nn&&(l++,typeof P=="object"&&(P.placement&&(m=P.placement),P.rects&&(f=P.rects===!0?await s.getElementRects({reference:e,floating:t,strategy:r}):P.rects),{x:d,y:a}=Ge(f,m,u)),h=-1)}return{x:d,y:a,placement:m,strategy:r,middlewareData:p}},rn=e=>({name:"arrow",options:e,async fn(t){const{x:n,y:o,placement:r,rects:i,platform:s,elements:c,middlewareData:u}=t,{element:f,padding:d=0}=le(e,t)||{};if(f==null)return{};const a=mt(d),m={x:n,y:o},l=Be(r),p=We(l),h=await s.getDimensions(f),E=l==="y",x=E?"top":"left",C=E?"bottom":"right",S=E?"clientHeight":"clientWidth",b=i.reference[p]+i.reference[l]-m[l]-i.floating[p],O=m[l]-i.reference[l],P=await(s.getOffsetParent==null?void 0:s.getOffsetParent(f));let v=P?P[S]:0;(!v||!await(s.isElement==null?void 0:s.isElement(P)))&&(v=c.floating[S]||i.floating[p]);const k=b/2-O/2,I=v/2-h[p]/2-1,$=oe(a[x],I),A=oe(a[C],I),M=$,R=v-h[p]-A,y=v/2-h[p]/2+k,T=Fe(M,y,R),L=!u.arrow&&ue(r)!=null&&y!==T&&i.reference[p]/2-(y<M?$:A)-h[p]/2<0,F=L?y<M?y-M:y-R:0;return{[l]:m[l]+F,data:{[l]:T,centerOffset:y-T-F,...L&&{alignmentOffset:F}},reset:L}}}),sn=function(e){return e===void 0&&(e={}),{name:"flip",options:e,async fn(t){var n,o;const{placement:r,middlewareData:i,rects:s,initialPlacement:c,platform:u,elements:f}=t,{mainAxis:d=!0,crossAxis:a=!0,fallbackPlacements:m,fallbackStrategy:l="bestFit",fallbackAxisSideDirection:p="none",flipAlignment:h=!0,...E}=le(e,t);if((n=i.arrow)!=null&&n.alignmentOffset)return{};const x=J(r),C=Y(c),S=J(c)===c,b=await(u.isRTL==null?void 0:u.isRTL(f.floating)),O=m||(S||!h?[ye(c)]:qt(c)),P=p!=="none";!m&&P&&O.push(...Jt(c,h,p,b));const v=[c,...O],k=await u.detectOverflow(t,E),I=[];let $=((o=i.flip)==null?void 0:o.overflows)||[];if(d&&I.push(k[x]),a){const y=Ut(r,s,b);I.push(k[y[0]],k[y[1]])}if($=[...$,{placement:r,overflows:I}],!I.every(y=>y<=0)){var A,M;const y=(((A=i.flip)==null?void 0:A.index)||0)+1,T=v[y];if(T&&(!(a==="alignment"?C!==Y(T):!1)||$.every(w=>Y(w.placement)===C?w.overflows[0]>0:!0)))return{data:{index:y,overflows:$},reset:{placement:T}};let L=(M=$.filter(F=>F.overflows[0]<=0).sort((F,w)=>F.overflows[1]-w.overflows[1])[0])==null?void 0:M.placement;if(!L)switch(l){case"bestFit":{var R;const F=(R=$.filter(w=>{if(P){const D=Y(w.placement);return D===C||D==="y"}return!0}).map(w=>[w.placement,w.overflows.filter(D=>D>0).reduce((D,N)=>D+N,0)]).sort((w,D)=>w[1]-D[1])[0])==null?void 0:R[0];F&&(L=F);break}case"initialPlacement":L=c;break}if(r!==L)return{reset:{placement:L}}}return{}}}},cn=new Set(["left","top"]);async function ln(e,t){const{placement:n,platform:o,elements:r}=e,i=await(o.isRTL==null?void 0:o.isRTL(r.floating)),s=J(n),c=ue(n),u=Y(n)==="y",f=cn.has(s)?-1:1,d=i&&u?-1:1,a=le(t,e);let{mainAxis:m,crossAxis:l,alignmentAxis:p}=typeof a=="number"?{mainAxis:a,crossAxis:0,alignmentAxis:null}:{mainAxis:a.mainAxis||0,crossAxis:a.crossAxis||0,alignmentAxis:a.alignmentAxis};return c&&typeof p=="number"&&(l=c==="end"?p*-1:p),u?{x:l*d,y:m*f}:{x:m*f,y:l*d}}const un=function(e){return e===void 0&&(e=0),{name:"offset",options:e,async fn(t){var n,o;const{x:r,y:i,placement:s,middlewareData:c}=t,u=await ln(t,e);return s===((n=c.offset)==null?void 0:n.placement)&&(o=c.arrow)!=null&&o.alignmentOffset?{}:{x:r+u.x,y:i+u.y,data:{...u,placement:s}}}}},fn=function(e){return e===void 0&&(e={}),{name:"shift",options:e,async fn(t){const{x:n,y:o,placement:r,platform:i}=t,{mainAxis:s=!0,crossAxis:c=!1,limiter:u={fn:x=>{let{x:C,y:S}=x;return{x:C,y:S}}},...f}=le(e,t),d={x:n,y:o},a=await i.detectOverflow(t,f),m=Y(J(r)),l=dt(m);let p=d[l],h=d[m];if(s){const x=l==="y"?"top":"left",C=l==="y"?"bottom":"right",S=p+a[x],b=p-a[C];p=Fe(S,p,b)}if(c){const x=m==="y"?"top":"left",C=m==="y"?"bottom":"right",S=h+a[x],b=h-a[C];h=Fe(S,h,b)}const E=u.fn({...t,[l]:p,[m]:h});return{...E,data:{x:E.x-n,y:E.y-o,enabled:{[l]:s,[m]:c}}}}}};function be(){return typeof window<"u"}function ie(e){return gt(e)?(e.nodeName||"").toLowerCase():"#document"}function W(e){var t;return(e==null||(t=e.ownerDocument)==null?void 0:t.defaultView)||window}function j(e){var t;return(t=(gt(e)?e.ownerDocument:e.document)||window.document)==null?void 0:t.documentElement}function gt(e){return be()?e instanceof Node||e instanceof W(e).Node:!1}function B(e){return be()?e instanceof Element||e instanceof W(e).Element:!1}function z(e){return be()?e instanceof HTMLElement||e instanceof W(e).HTMLElement:!1}function Qe(e){return!be()||typeof ShadowRoot>"u"?!1:e instanceof ShadowRoot||e instanceof W(e).ShadowRoot}function fe(e){const{overflow:t,overflowX:n,overflowY:o,display:r}=V(e);return/auto|scroll|overlay|hidden|clip/.test(t+o+n)&&r!=="inline"&&r!=="contents"}function an(e){return/^(table|td|th)$/.test(ie(e))}function Ee(e){try{if(e.matches(":popover-open"))return!0}catch{}try{return e.matches(":modal")}catch{return!1}}const dn=/transform|translate|scale|rotate|perspective|filter/,mn=/paint|layout|strict|content/,Q=e=>!!e&&e!=="none";let Te;function Ve(e){const t=B(e)?V(e):e;return Q(t.transform)||Q(t.translate)||Q(t.scale)||Q(t.rotate)||Q(t.perspective)||!He()&&(Q(t.backdropFilter)||Q(t.filter))||dn.test(t.willChange||"")||mn.test(t.contain||"")}function gn(e){let t=G(e);for(;z(t)&&!re(t);){if(Ve(t))return t;if(Ee(t))return null;t=G(t)}return null}function He(){return Te==null&&(Te=typeof CSS<"u"&&CSS.supports&&CSS.supports("-webkit-backdrop-filter","none")),Te}function re(e){return/^(html|body|#document)$/.test(ie(e))}function V(e){return W(e).getComputedStyle(e)}function Ce(e){return B(e)?{scrollLeft:e.scrollLeft,scrollTop:e.scrollTop}:{scrollLeft:e.scrollX,scrollTop:e.scrollY}}function G(e){if(ie(e)==="html")return e;const t=e.assignedSlot||e.parentNode||Qe(e)&&e.host||j(e);return Qe(t)?t.host:t}function pt(e){const t=G(e);return re(t)?e.ownerDocument?e.ownerDocument.body:e.body:z(t)&&fe(t)?t:pt(t)}function U(e,t,n){var o;t===void 0&&(t=[]),n===void 0&&(n=!0);const r=pt(e),i=r===((o=e.ownerDocument)==null?void 0:o.body),s=W(r);if(i){const c=Ie(s);return t.concat(s,s.visualViewport||[],fe(r)?r:[],c&&n?U(c):[])}else return t.concat(r,U(r,[],n))}function Ie(e){return e.parent&&Object.getPrototypeOf(e.parent)?e.frameElement:null}function ht(e){const t=V(e);let n=parseFloat(t.width)||0,o=parseFloat(t.height)||0;const r=z(e),i=r?e.offsetWidth:n,s=r?e.offsetHeight:o,c=ve(n)!==i||ve(o)!==s;return c&&(n=i,o=s),{width:n,height:o,$:c}}function Ke(e){return B(e)?e:e.contextElement}function ne(e){const t=Ke(e);if(!z(t))return K(1);const n=t.getBoundingClientRect(),{width:o,height:r,$:i}=ht(t);let s=(i?ve(n.width):n.width)/o,c=(i?ve(n.height):n.height)/r;return(!s||!Number.isFinite(s))&&(s=1),(!c||!Number.isFinite(c))&&(c=1),{x:s,y:c}}const pn=K(0);function vt(e){const t=W(e);return!He()||!t.visualViewport?pn:{x:t.visualViewport.offsetLeft,y:t.visualViewport.offsetTop}}function hn(e,t,n){return t===void 0&&(t=!1),!n||t&&n!==W(e)?!1:t}function ee(e,t,n,o){t===void 0&&(t=!1),n===void 0&&(n=!1);const r=e.getBoundingClientRect(),i=Ke(e);let s=K(1);t&&(o?B(o)&&(s=ne(o)):s=ne(e));const c=hn(i,n,o)?vt(i):K(0);let u=(r.left+c.x)/s.x,f=(r.top+c.y)/s.y,d=r.width/s.x,a=r.height/s.y;if(i){const m=W(i),l=o&&B(o)?W(o):o;let p=m,h=Ie(p);for(;h&&o&&l!==p;){const E=ne(h),x=h.getBoundingClientRect(),C=V(h),S=x.left+(h.clientLeft+parseFloat(C.paddingLeft))*E.x,b=x.top+(h.clientTop+parseFloat(C.paddingTop))*E.y;u*=E.x,f*=E.y,d*=E.x,a*=E.y,u+=S,f+=b,p=W(h),h=Ie(p)}}return we({width:d,height:a,x:u,y:f})}function Pe(e,t){const n=Ce(e).scrollLeft;return t?t.left+n:ee(j(e)).left+n}function yt(e,t){const n=e.getBoundingClientRect(),o=n.left+t.scrollLeft-Pe(e,n),r=n.top+t.scrollTop;return{x:o,y:r}}function vn(e){let{elements:t,rect:n,offsetParent:o,strategy:r}=e;const i=r==="fixed",s=j(o),c=t?Ee(t.floating):!1;if(o===s||c&&i)return n;let u={scrollLeft:0,scrollTop:0},f=K(1);const d=K(0),a=z(o);if((a||!a&&!i)&&((ie(o)!=="body"||fe(s))&&(u=Ce(o)),a)){const l=ee(o);f=ne(o),d.x=l.x+o.clientLeft,d.y=l.y+o.clientTop}const m=s&&!a&&!i?yt(s,u):K(0);return{width:n.width*f.x,height:n.height*f.y,x:n.x*f.x-u.scrollLeft*f.x+d.x+m.x,y:n.y*f.y-u.scrollTop*f.y+d.y+m.y}}function yn(e){return Array.from(e.getClientRects())}function wn(e){const t=j(e),n=Ce(e),o=e.ownerDocument.body,r=Z(t.scrollWidth,t.clientWidth,o.scrollWidth,o.clientWidth),i=Z(t.scrollHeight,t.clientHeight,o.scrollHeight,o.clientHeight);let s=-n.scrollLeft+Pe(e);const c=-n.scrollTop;return V(o).direction==="rtl"&&(s+=Z(t.clientWidth,o.clientWidth)-r),{width:r,height:i,x:s,y:c}}const Ze=25;function xn(e,t){const n=W(e),o=j(e),r=n.visualViewport;let i=o.clientWidth,s=o.clientHeight,c=0,u=0;if(r){i=r.width,s=r.height;const d=He();(!d||d&&t==="fixed")&&(c=r.offsetLeft,u=r.offsetTop)}const f=Pe(o);if(f<=0){const d=o.ownerDocument,a=d.body,m=getComputedStyle(a),l=d.compatMode==="CSS1Compat"&&parseFloat(m.marginLeft)+parseFloat(m.marginRight)||0,p=Math.abs(o.clientWidth-a.clientWidth-l);p<=Ze&&(i-=p)}else f<=Ze&&(i+=f);return{width:i,height:s,x:c,y:u}}function Rn(e,t){const n=ee(e,!0,t==="fixed"),o=n.top+e.clientTop,r=n.left+e.clientLeft,i=z(e)?ne(e):K(1),s=e.clientWidth*i.x,c=e.clientHeight*i.y,u=r*i.x,f=o*i.y;return{width:s,height:c,x:u,y:f}}function Je(e,t,n){let o;if(t==="viewport")o=xn(e,n);else if(t==="document")o=wn(j(e));else if(B(t))o=Rn(t,n);else{const r=vt(e);o={x:t.x-r.x,y:t.y-r.y,width:t.width,height:t.height}}return we(o)}function wt(e,t){const n=G(e);return n===t||!B(n)||re(n)?!1:V(n).position==="fixed"||wt(n,t)}function bn(e,t){const n=t.get(e);if(n)return n;let o=U(e,[],!1).filter(c=>B(c)&&ie(c)!=="body"),r=null;const i=V(e).position==="fixed";let s=i?G(e):e;for(;B(s)&&!re(s);){const c=V(s),u=Ve(s);!u&&c.position==="fixed"&&(r=null),(i?!u&&!r:!u&&c.position==="static"&&!!r&&(r.position==="absolute"||r.position==="fixed")||fe(s)&&!u&&wt(e,s))?o=o.filter(d=>d!==s):r=c,s=G(s)}return t.set(e,o),o}function En(e){let{element:t,boundary:n,rootBoundary:o,strategy:r}=e;const s=[...n==="clippingAncestors"?Ee(t)?[]:bn(t,this._c):[].concat(n),o],c=Je(t,s[0],r);let u=c.top,f=c.right,d=c.bottom,a=c.left;for(let m=1;m<s.length;m++){const l=Je(t,s[m],r);u=Z(l.top,u),f=oe(l.right,f),d=oe(l.bottom,d),a=Z(l.left,a)}return{width:f-a,height:d-u,x:a,y:u}}function Cn(e){const{width:t,height:n}=ht(e);return{width:t,height:n}}function Pn(e,t,n){const o=z(t),r=j(t),i=n==="fixed",s=ee(e,!0,i,t);let c={scrollLeft:0,scrollTop:0};const u=K(0);function f(){u.x=Pe(r)}if(o||!o&&!i)if((ie(t)!=="body"||fe(r))&&(c=Ce(t)),o){const l=ee(t,!0,i,t);u.x=l.x+t.clientLeft,u.y=l.y+t.clientTop}else r&&f();i&&!o&&r&&f();const d=r&&!o&&!i?yt(r,c):K(0),a=s.left+c.scrollLeft-u.x-d.x,m=s.top+c.scrollTop-u.y-d.y;return{x:a,y:m,width:s.width,height:s.height}}function Se(e){return V(e).position==="static"}function et(e,t){if(!z(e)||V(e).position==="fixed")return null;if(t)return t(e);let n=e.offsetParent;return j(e)===n&&(n=n.ownerDocument.body),n}function xt(e,t){const n=W(e);if(Ee(e))return n;if(!z(e)){let r=G(e);for(;r&&!re(r);){if(B(r)&&!Se(r))return r;r=G(r)}return n}let o=et(e,t);for(;o&&an(o)&&Se(o);)o=et(o,t);return o&&re(o)&&Se(o)&&!Ve(o)?n:o||gn(e)||n}const On=async function(e){const t=this.getOffsetParent||xt,n=this.getDimensions,o=await n(e.floating);return{reference:Pn(e.reference,await t(e.floating),e.strategy),floating:{x:0,y:0,width:o.width,height:o.height}}};function Tn(e){return V(e).direction==="rtl"}const Rt={convertOffsetParentRelativeRectToViewportRelativeRect:vn,getDocumentElement:j,getClippingRect:En,getOffsetParent:xt,getElementRects:On,getClientRects:yn,getDimensions:Cn,getScale:ne,isElement:B,isRTL:Tn};function bt(e,t){return e.x===t.x&&e.y===t.y&&e.width===t.width&&e.height===t.height}function Sn(e,t){let n=null,o;const r=j(e);function i(){var c;clearTimeout(o),(c=n)==null||c.disconnect(),n=null}function s(c,u){c===void 0&&(c=!1),u===void 0&&(u=1),i();const f=e.getBoundingClientRect(),{left:d,top:a,width:m,height:l}=f;if(c||t(),!m||!l)return;const p=ae(a),h=ae(r.clientWidth-(d+m)),E=ae(r.clientHeight-(a+l)),x=ae(d),S={rootMargin:-p+"px "+-h+"px "+-E+"px "+-x+"px",threshold:Z(0,oe(1,u))||1};let b=!0;function O(P){const v=P[0].intersectionRatio;if(v!==u){if(!b)return s();v?s(!1,v):o=setTimeout(()=>{s(!1,1e-7)},1e3)}v===1&&!bt(f,e.getBoundingClientRect())&&s(),b=!1}try{n=new IntersectionObserver(O,{...S,root:r.ownerDocument})}catch{n=new IntersectionObserver(O,S)}n.observe(e)}return s(!0),i}function An(e,t,n,o){o===void 0&&(o={});const{ancestorScroll:r=!0,ancestorResize:i=!0,elementResize:s=typeof ResizeObserver=="function",layoutShift:c=typeof IntersectionObserver=="function",animationFrame:u=!1}=o,f=Ke(e),d=r||i?[...f?U(f):[],...t?U(t):[]]:[];d.forEach(x=>{r&&x.addEventListener("scroll",n,{passive:!0}),i&&x.addEventListener("resize",n)});const a=f&&c?Sn(f,n):null;let m=-1,l=null;s&&(l=new ResizeObserver(x=>{let[C]=x;C&&C.target===f&&l&&t&&(l.unobserve(t),cancelAnimationFrame(m),m=requestAnimationFrame(()=>{var S;(S=l)==null||S.observe(t)})),n()}),f&&!u&&l.observe(f),t&&l.observe(t));let p,h=u?ee(e):null;u&&E();function E(){const x=ee(e);h&&!bt(h,x)&&n(),h=x,p=requestAnimationFrame(E)}return n(),()=>{var x;d.forEach(C=>{r&&C.removeEventListener("scroll",n),i&&C.removeEventListener("resize",n)}),a?.(),(x=l)==null||x.disconnect(),l=null,u&&cancelAnimationFrame(p)}}const Dn=un,Ln=fn,Mn=sn,tt=rn,kn=(e,t,n)=>{const o=new Map,r={platform:Rt,...n},i={...r.platform,_c:o};return on(e,t,{...r,platform:i})};var Fn=typeof document<"u",$n=function(){},me=Fn?lt:$n;function xe(e,t){if(e===t)return!0;if(typeof e!=typeof t)return!1;if(typeof e=="function"&&e.toString()===t.toString())return!0;let n,o,r;if(e&&t&&typeof e=="object"){if(Array.isArray(e)){if(n=e.length,n!==t.length)return!1;for(o=n;o--!==0;)if(!xe(e[o],t[o]))return!1;return!0}if(r=Object.keys(e),n=r.length,n!==Object.keys(t).length)return!1;for(o=n;o--!==0;)if(!{}.hasOwnProperty.call(t,r[o]))return!1;for(o=n;o--!==0;){const i=r[o];if(!(i==="_owner"&&e.$$typeof)&&!xe(e[i],t[i]))return!1}return!0}return e!==e&&t!==t}function Et(e){return typeof window>"u"?1:(e.ownerDocument.defaultView||window).devicePixelRatio||1}function nt(e,t){const n=Et(e);return Math.round(t*n)/n}function Ae(e){const t=g.useRef(e);return me(()=>{t.current=e}),t}function In(e){e===void 0&&(e={});const{placement:t="bottom",strategy:n="absolute",middleware:o=[],platform:r,elements:{reference:i,floating:s}={},transform:c=!0,whileElementsMounted:u,open:f}=e,[d,a]=g.useState({x:0,y:0,strategy:n,placement:t,middlewareData:{},isPositioned:!1}),[m,l]=g.useState(o);xe(m,o)||l(o);const[p,h]=g.useState(null),[E,x]=g.useState(null),C=g.useCallback(w=>{w!==P.current&&(P.current=w,h(w))},[]),S=g.useCallback(w=>{w!==v.current&&(v.current=w,x(w))},[]),b=i||p,O=s||E,P=g.useRef(null),v=g.useRef(null),k=g.useRef(d),I=u!=null,$=Ae(u),A=Ae(r),M=Ae(f),R=g.useCallback(()=>{if(!P.current||!v.current)return;const w={placement:t,strategy:n,middleware:m};A.current&&(w.platform=A.current),kn(P.current,v.current,w).then(D=>{const N={...D,isPositioned:M.current!==!1};y.current&&!xe(k.current,N)&&(k.current=N,Mt.flushSync(()=>{a(N)}))})},[m,t,n,A,M]);me(()=>{f===!1&&k.current.isPositioned&&(k.current.isPositioned=!1,a(w=>({...w,isPositioned:!1})))},[f]);const y=g.useRef(!1);me(()=>(y.current=!0,()=>{y.current=!1}),[]),me(()=>{if(b&&(P.current=b),O&&(v.current=O),b&&O){if($.current)return $.current(b,O,R);R()}},[b,O,R,$,I]);const T=g.useMemo(()=>({reference:P,floating:v,setReference:C,setFloating:S}),[C,S]),L=g.useMemo(()=>({reference:b,floating:O}),[b,O]),F=g.useMemo(()=>{const w={position:n,left:0,top:0};if(!L.floating)return w;const D=nt(L.floating,d.x),N=nt(L.floating,d.y);return c?{...w,transform:"translate("+D+"px, "+N+"px)",...Et(L.floating)>=1.5&&{willChange:"transform"}}:{position:n,left:D,top:N}},[n,c,L.floating,d.x,d.y]);return g.useMemo(()=>({...d,update:R,refs:T,elements:L,floatingStyles:F}),[d,R,T,L,F])}const Nn=e=>{function t(n){return{}.hasOwnProperty.call(n,"current")}return{name:"arrow",options:e,fn(n){const{element:o,padding:r}=typeof e=="function"?e(n):e;return o&&t(o)?o.current!=null?tt({element:o.current,padding:r}).fn(n):{}:o?tt({element:o,padding:r}).fn(n):{}}}},_n=(e,t)=>{const n=Dn(e);return{name:n.name,fn:n.fn,options:[e,t]}},Wn=(e,t)=>{const n=Ln(e);return{name:n.name,fn:n.fn,options:[e,t]}},Bn=(e,t)=>{const n=Mn(e);return{name:n.name,fn:n.fn,options:[e,t]}},Vn=(e,t)=>{const n=Nn(e);return{name:n.name,fn:n.fn,options:[e,t]}};var q=typeof document<"u"?lt:Tt;function Ne(){return Ne=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var o in n)Object.prototype.hasOwnProperty.call(n,o)&&(e[o]=n[o])}return e},Ne.apply(this,arguments)}let De=!1,Hn=0;const ot=()=>"floating-ui-"+Hn++;function Kn(){const[e,t]=g.useState(()=>De?ot():void 0);return q(()=>{e==null&&t(ot())},[]),g.useEffect(()=>{De||(De=!0)},[]),e}const jn=g.useId,je=jn||Kn,Xn=g.forwardRef(function(t,n){let{context:{placement:o,elements:{floating:r},middlewareData:{arrow:i}},width:s=14,height:c=7,tipRadius:u=0,strokeWidth:f=0,staticOffset:d,stroke:a,d:m,style:{transform:l,...p}={},...h}=t;process.env.NODE_ENV!=="production"&&(n||console.warn("Floating UI: The `ref` prop is required for the `FloatingArrow`","component."));const E=je();if(!r)return null;f*=2;const x=f/2,C=s/2*(u/-8+1),S=c/2*u/4,[b,O]=o.split("-"),P=Rt.isRTL(r),v=!!m,k=b==="top"||b==="bottom",I=d&&O==="end"?"bottom":"top";let $=d&&O==="end"?"right":"left";d&&P&&($=O==="end"?"left":"right");const A=i?.x!=null?d||i.x:"",M=i?.y!=null?d||i.y:"",R=m||"M0,0"+(" H"+s)+(" L"+(s-C)+","+(c-S))+(" Q"+s/2+","+c+" "+C+","+(c-S))+" Z",y={top:v?"rotate(180deg)":"",left:v?"rotate(90deg)":"rotate(-90deg)",bottom:v?"":"rotate(180deg)",right:v?"rotate(-90deg)":"rotate(90deg)"}[b];return g.createElement("svg",Ne({},h,{"aria-hidden":!0,ref:n,width:v?s:s+f,height:s,viewBox:"0 0 "+s+" "+(c>s?c:s),style:{position:"absolute",pointerEvents:"none",[$]:A,[I]:M,[b]:k||v?"100%":"calc(100% - "+f/2+"px)",transform:""+y+(l??""),...p}}),f>0&&g.createElement("path",{clipPath:"url(#"+E+")",fill:"none",stroke:a,strokeWidth:f+(m?0:1),d:R}),g.createElement("path",{stroke:f&&!m?h.fill:"none",d:R}),g.createElement("clipPath",{id:E},g.createElement("rect",{x:-x,y:x*(v?-1:1),width:s+f,height:s})))});function zn(){const e=new Map;return{emit(t,n){var o;(o=e.get(t))==null||o.forEach(r=>r(n))},on(t,n){e.set(t,[...e.get(t)||[],n])},off(t,n){var o;e.set(t,((o=e.get(t))==null?void 0:o.filter(r=>r!==n))||[])}}}const Yn=g.createContext(null),Un=g.createContext(null),Ct=()=>{var e;return((e=g.useContext(Yn))==null?void 0:e.id)||null},Xe=()=>g.useContext(Un);function ze(e){return"data-floating-ui-"+e}function rt(e){const t=ut(e);return q(()=>{t.current=e}),t}const it=ze("safe-polygon");function ge(e,t,n){return n&&!he(n)?0:typeof e=="number"?e:e?.[t]}function qn(e,t){t===void 0&&(t={});const{open:n,onOpenChange:o,dataRef:r,events:i,elements:{domReference:s,floating:c},refs:u}=e,{enabled:f=!0,delay:d=0,handleClose:a=null,mouseOnly:m=!1,restMs:l=0,move:p=!0}=t,h=Xe(),E=Ct(),x=rt(a),C=rt(d),S=g.useRef(),b=g.useRef(),O=g.useRef(),P=g.useRef(),v=g.useRef(!0),k=g.useRef(!1),I=g.useRef(()=>{}),$=g.useCallback(()=>{var y;const T=(y=r.current.openEvent)==null?void 0:y.type;return T?.includes("mouse")&&T!=="mousedown"},[r]);g.useEffect(()=>{if(!f)return;function y(){clearTimeout(b.current),clearTimeout(P.current),v.current=!0}return i.on("dismiss",y),()=>{i.off("dismiss",y)}},[f,i]),g.useEffect(()=>{if(!f||!x.current||!n)return;function y(L){$()&&o(!1,L)}const T=X(c).documentElement;return T.addEventListener("mouseleave",y),()=>{T.removeEventListener("mouseleave",y)}},[c,n,o,f,x,r,$]);const A=g.useCallback(function(y,T){T===void 0&&(T=!0);const L=ge(C.current,"close",S.current);L&&!O.current?(clearTimeout(b.current),b.current=setTimeout(()=>o(!1,y),L)):T&&(clearTimeout(b.current),o(!1,y))},[C,o]),M=g.useCallback(()=>{I.current(),O.current=void 0},[]),R=g.useCallback(()=>{if(k.current){const y=X(u.floating.current).body;y.style.pointerEvents="",y.removeAttribute(it),k.current=!1}},[u]);return g.useEffect(()=>{if(!f)return;function y(){return r.current.openEvent?["click","mousedown"].includes(r.current.openEvent.type):!1}function T(w){if(clearTimeout(b.current),v.current=!1,m&&!he(S.current)||l>0&&ge(C.current,"open")===0)return;const D=ge(C.current,"open",S.current);D?b.current=setTimeout(()=>{o(!0,w)},D):o(!0,w)}function L(w){if(y())return;I.current();const D=X(c);if(clearTimeout(P.current),x.current){n||clearTimeout(b.current),O.current=x.current({...e,tree:h,x:w.clientX,y:w.clientY,onClose(){R(),M(),A(w)}});const H=O.current;D.addEventListener("mousemove",H),I.current=()=>{D.removeEventListener("mousemove",H)};return}(S.current!=="touch"||!se(c,w.relatedTarget))&&A(w)}function F(w){y()||x.current==null||x.current({...e,tree:h,x:w.clientX,y:w.clientY,onClose(){R(),M(),A(w)}})(w)}if(_(s)){const w=s;return n&&w.addEventListener("mouseleave",F),c?.addEventListener("mouseleave",F),p&&w.addEventListener("mousemove",T,{once:!0}),w.addEventListener("mouseenter",T),w.addEventListener("mouseleave",L),()=>{n&&w.removeEventListener("mouseleave",F),c?.removeEventListener("mouseleave",F),p&&w.removeEventListener("mousemove",T),w.removeEventListener("mouseenter",T),w.removeEventListener("mouseleave",L)}}},[s,c,f,e,m,l,p,A,M,R,o,n,h,C,x,r]),q(()=>{var y;if(f&&n&&(y=x.current)!=null&&y.__options.blockPointerEvents&&$()){const F=X(c).body;if(F.setAttribute(it,""),F.style.pointerEvents="none",k.current=!0,_(s)&&c){var T,L;const w=s,D=h==null||(T=h.nodesRef.current.find(N=>N.id===E))==null||(L=T.context)==null?void 0:L.elements.floating;return D&&(D.style.pointerEvents=""),w.style.pointerEvents="auto",c.style.pointerEvents="auto",()=>{w.style.pointerEvents="",c.style.pointerEvents=""}}}},[f,n,E,c,s,h,x,r,$]),q(()=>{n||(S.current=void 0,M(),R())},[n,M,R]),g.useEffect(()=>()=>{M(),clearTimeout(b.current),clearTimeout(P.current),R()},[f,s,M,R]),g.useMemo(()=>{if(!f)return{};function y(T){S.current=T.pointerType}return{reference:{onPointerDown:y,onPointerEnter:y,onMouseMove(T){n||l===0||(clearTimeout(P.current),P.current=setTimeout(()=>{v.current||o(!0,T.nativeEvent)},l))}},floating:{onMouseEnter(){clearTimeout(b.current)},onMouseLeave(T){i.emit("dismiss",{type:"mouseLeave",data:{returnFocus:!1}}),A(T.nativeEvent,!1)}}}},[i,f,l,n,o,A])}const Gn=g.createContext({delay:0,initialDelay:0,timeoutMs:0,currentId:null,setCurrentId:()=>{},setState:()=>{},isInstantPhase:!1}),Pt=()=>g.useContext(Gn),Qn=(e,t)=>{let{open:n,onOpenChange:o}=e,{id:r}=t;const{currentId:i,setCurrentId:s,initialDelay:c,setState:u,timeoutMs:f}=Pt();q(()=>{i&&(u({delay:{open:1,close:ge(c,"close")}}),i!==r&&o(!1))},[r,o,u,i,c]),q(()=>{function d(){o(!1),u({delay:c,currentId:null})}if(!n&&i===r)if(f){const a=window.setTimeout(d,f);return()=>{clearTimeout(a)}}else d()},[n,u,i,r,o,c,f]),q(()=>{n&&s(r)},[n,s,r])};function Le(e,t){let n=e.filter(r=>{var i;return r.parentId===t&&((i=r.context)==null?void 0:i.open)}),o=n;for(;o.length;)o=e.filter(r=>{var i;return(i=o)==null?void 0:i.some(s=>{var c;return r.parentId===s.id&&((c=r.context)==null?void 0:c.open)})}),n=n.concat(o);return n}function st(e){return Re(e.target)&&e.target.tagName==="BUTTON"}function ct(e){return zt(e)}function Zn(e,t){t===void 0&&(t={});const{open:n,onOpenChange:o,dataRef:r,elements:{domReference:i}}=e,{enabled:s=!0,event:c="click",toggle:u=!0,ignoreMouse:f=!1,keyboardHandlers:d=!0}=t,a=g.useRef(),m=g.useRef(!1);return g.useMemo(()=>s?{reference:{onPointerDown(l){a.current=l.pointerType},onMouseDown(l){l.button===0&&(he(a.current,!0)&&f||c!=="click"&&(n&&u&&(!r.current.openEvent||r.current.openEvent.type==="mousedown")?o(!1,l.nativeEvent):(l.preventDefault(),o(!0,l.nativeEvent))))},onClick(l){if(c==="mousedown"&&a.current){a.current=void 0;return}he(a.current,!0)&&f||(n&&u&&(!r.current.openEvent||r.current.openEvent.type==="click")?o(!1,l.nativeEvent):o(!0,l.nativeEvent))},onKeyDown(l){a.current=void 0,!(l.defaultPrevented||!d||st(l))&&(l.key===" "&&!ct(i)&&(l.preventDefault(),m.current=!0),l.key==="Enter"&&o(!(n&&u),l.nativeEvent))},onKeyUp(l){l.defaultPrevented||!d||st(l)||ct(i)||l.key===" "&&m.current&&(m.current=!1,o(!(n&&u),l.nativeEvent))}}}:{},[s,r,c,f,d,i,u,n,o])}const Jn=g.useInsertionEffect,eo=Jn||(e=>e());function pe(e){const t=g.useRef(()=>{if(process.env.NODE_ENV!=="production")throw new Error("Cannot call an event handler while rendering.")});return eo(()=>{t.current=e}),g.useCallback(function(){for(var n=arguments.length,o=new Array(n),r=0;r<n;r++)o[r]=arguments[r];return t.current==null?void 0:t.current(...o)},[])}const to={pointerdown:"onPointerDown",mousedown:"onMouseDown",click:"onClick"},no={pointerdown:"onPointerDownCapture",mousedown:"onMouseDownCapture",click:"onClickCapture"},oo=e=>{var t,n;return{escapeKeyBubbles:typeof e=="boolean"?e:(t=e?.escapeKey)!=null?t:!1,outsidePressBubbles:typeof e=="boolean"?e:(n=e?.outsidePress)!=null?n:!0}};function ro(e,t){t===void 0&&(t={});const{open:n,onOpenChange:o,events:r,nodeId:i,elements:{reference:s,domReference:c,floating:u},dataRef:f}=e,{enabled:d=!0,escapeKey:a=!0,outsidePress:m=!0,outsidePressEvent:l="pointerdown",referencePress:p=!1,referencePressEvent:h="pointerdown",ancestorScroll:E=!1,bubbles:x}=t,C=Xe(),S=Ct()!=null,b=pe(typeof m=="function"?m:()=>!1),O=typeof m=="function"?b:m,P=g.useRef(!1),{escapeKeyBubbles:v,outsidePressBubbles:k}=oo(x),I=pe(A=>{if(!n||!d||!a||A.key!=="Escape")return;const M=C?Le(C.nodesRef.current,i):[];if(!v&&(A.stopPropagation(),M.length>0)){let R=!0;if(M.forEach(y=>{var T;if((T=y.context)!=null&&T.open&&!y.context.dataRef.current.__escapeKeyBubbles){R=!1;return}}),!R)return}r.emit("dismiss",{type:"escapeKey",data:{returnFocus:{preventScroll:!1}}}),o(!1,Ht(A)?A.nativeEvent:A)}),$=pe(A=>{const M=P.current;if(P.current=!1,M||typeof O=="function"&&!O(A))return;const R=jt(A),y="["+ze("inert")+"]",T=X(u).querySelectorAll(y);let L=_(R)?R:null;for(;L&&!Ft(L);){const D=It(L);if(D===X(u).body||!_(D))break;L=D}if(T.length&&_(R)&&!Kt(R)&&!se(R,u)&&Array.from(T).every(D=>!se(L,D)))return;if(Re(R)&&u){const D=R.clientWidth>0&&R.scrollWidth>R.clientWidth,N=R.clientHeight>0&&R.scrollHeight>R.clientHeight;let H=N&&A.offsetX>R.clientWidth;if(N&&$t(R).direction==="rtl"&&(H=A.offsetX<=R.offsetWidth-R.clientWidth),H||D&&A.offsetY>R.clientHeight)return}const F=C&&Le(C.nodesRef.current,i).some(D=>{var N;return de(A,(N=D.context)==null?void 0:N.elements.floating)});if(de(A,u)||de(A,c)||F)return;const w=C?Le(C.nodesRef.current,i):[];if(w.length>0){let D=!0;if(w.forEach(N=>{var H;if((H=N.context)!=null&&H.open&&!N.context.dataRef.current.__outsidePressBubbles){D=!1;return}}),!D)return}r.emit("dismiss",{type:"outsidePress",data:{returnFocus:S?{preventScroll:!0}:Bt(A)||Vt(A)}}),o(!1,A)});return g.useEffect(()=>{if(!n||!d)return;f.current.__escapeKeyBubbles=v,f.current.__outsidePressBubbles=k;function A(y){o(!1,y)}const M=X(u);a&&M.addEventListener("keydown",I),O&&M.addEventListener(l,$);let R=[];return E&&(_(c)&&(R=U(c)),_(u)&&(R=R.concat(U(u))),!_(s)&&s&&s.contextElement&&(R=R.concat(U(s.contextElement)))),R=R.filter(y=>{var T;return y!==((T=M.defaultView)==null?void 0:T.visualViewport)}),R.forEach(y=>{y.addEventListener("scroll",A,{passive:!0})}),()=>{a&&M.removeEventListener("keydown",I),O&&M.removeEventListener(l,$),R.forEach(y=>{y.removeEventListener("scroll",A)})}},[f,u,c,s,a,O,l,n,o,E,d,v,k,I,$]),g.useEffect(()=>{P.current=!1},[O,l]),g.useMemo(()=>d?{reference:{onKeyDown:I,[to[h]]:A=>{p&&(r.emit("dismiss",{type:"referencePress",data:{returnFocus:!1}}),o(!1,A.nativeEvent))}},floating:{onKeyDown:I,[no[l]]:()=>{P.current=!0}}}:{},[d,r,p,l,h,o,I])}let _e;process.env.NODE_ENV!=="production"&&(_e=new Set);function io(e){var t;e===void 0&&(e={});const{open:n=!1,onOpenChange:o,nodeId:r}=e;if(process.env.NODE_ENV!=="production"){var i;const v="Floating UI: Cannot pass a virtual element to the `elements.reference` option, as it must be a real DOM element. Use `refs.setPositionReference` instead.";if((i=e.elements)!=null&&i.reference&&!_(e.elements.reference)){var s;if(!((s=_e)!=null&&s.has(v))){var c;(c=_e)==null||c.add(v),console.error(v)}}}const[u,f]=g.useState(null),d=((t=e.elements)==null?void 0:t.reference)||u,a=In(e),m=Xe(),l=pe((v,k)=>{v&&(h.current.openEvent=k),o?.(v,k)}),p=g.useRef(null),h=g.useRef({}),E=g.useState(()=>zn())[0],x=je(),C=g.useCallback(v=>{const k=_(v)?{getBoundingClientRect:()=>v.getBoundingClientRect(),contextElement:v}:v;a.refs.setReference(k)},[a.refs]),S=g.useCallback(v=>{(_(v)||v===null)&&(p.current=v,f(v)),(_(a.refs.reference.current)||a.refs.reference.current===null||v!==null&&!_(v))&&a.refs.setReference(v)},[a.refs]),b=g.useMemo(()=>({...a.refs,setReference:S,setPositionReference:C,domReference:p}),[a.refs,S,C]),O=g.useMemo(()=>({...a.elements,domReference:d}),[a.elements,d]),P=g.useMemo(()=>({...a,refs:b,elements:O,dataRef:h,nodeId:r,floatingId:x,events:E,open:n,onOpenChange:l}),[a,r,x,E,n,l,b,O]);return q(()=>{const v=m?.nodesRef.current.find(k=>k.id===r);v&&(v.context=P)}),g.useMemo(()=>({...a,context:P,refs:b,elements:O}),[a,b,O,P])}function so(e,t){t===void 0&&(t={});const{open:n,onOpenChange:o,dataRef:r,events:i,refs:s,elements:{floating:c,domReference:u}}=e,{enabled:f=!0,keyboardOnly:d=!0}=t,a=g.useRef(""),m=g.useRef(!1),l=g.useRef();return g.useEffect(()=>{if(!f)return;const h=X(c).defaultView||window;function E(){!n&&Re(u)&&u===Nt(X(u))&&(m.current=!0)}return h.addEventListener("blur",E),()=>{h.removeEventListener("blur",E)}},[c,u,n,f]),g.useEffect(()=>{if(!f)return;function p(h){(h.type==="referencePress"||h.type==="escapeKey")&&(m.current=!0)}return i.on("dismiss",p),()=>{i.off("dismiss",p)}},[i,f]),g.useEffect(()=>()=>{clearTimeout(l.current)},[]),g.useMemo(()=>f?{reference:{onPointerDown(p){let{pointerType:h}=p;a.current=h,m.current=!!(h&&d)},onMouseLeave(){m.current=!1},onFocus(p){var h;m.current||p.type==="focus"&&((h=r.current.openEvent)==null?void 0:h.type)==="mousedown"&&de(r.current.openEvent,u)||o(!0,p.nativeEvent)},onBlur(p){m.current=!1;const h=p.relatedTarget,E=_(h)&&h.hasAttribute(ze("focus-guard"))&&h.getAttribute("data-type")==="outside";l.current=setTimeout(()=>{se(s.floating.current,h)||se(u,h)||E||o(!1,p.nativeEvent)})}}}:{},[f,d,u,s,r,o])}function Me(e,t,n){const o=new Map;return{...n==="floating"&&{tabIndex:-1},...e,...t.map(r=>r?r[n]:null).concat(e).reduce((r,i)=>(i&&Object.entries(i).forEach(s=>{let[c,u]=s;if(c.indexOf("on")===0){if(o.has(c)||o.set(c,[]),typeof u=="function"){var f;(f=o.get(c))==null||f.push(u),r[c]=function(){for(var d,a=arguments.length,m=new Array(a),l=0;l<a;l++)m[l]=arguments[l];return(d=o.get(c))==null?void 0:d.map(p=>p(...m)).find(p=>p!==void 0)}}}else r[c]=u}),r),{})}}function co(e){e===void 0&&(e=[]);const t=e,n=g.useCallback(i=>Me(i,e,"reference"),t),o=g.useCallback(i=>Me(i,e,"floating"),t),r=g.useCallback(i=>Me(i,e,"item"),e.map(i=>i?.item));return g.useMemo(()=>({getReferenceProps:n,getFloatingProps:o,getItemProps:r}),[n,o,r])}function lo(e,t){t===void 0&&(t={});const{open:n,floatingId:o}=e,{enabled:r=!0,role:i="dialog"}=t,s=je();return g.useMemo(()=>{const c={id:o,role:i};return r?i==="tooltip"?{reference:{"aria-describedby":n?o:void 0},floating:c}:{reference:{"aria-expanded":n?"true":"false","aria-haspopup":i==="alertdialog"?"dialog":i,"aria-controls":n?o:void 0,...i==="listbox"&&{role:"combobox"},...i==="menu"&&{id:s}},floating:{...c,...i==="menu"&&{"aria-labelledby":s}}}:{}},[r,i,n,o,s])}function mo({closeDelay:e=300,offset:t=20,openDelay:n=0,placement:o="bottom-start",slots:r,trigger:i=["hover","focus"],withArrow:s=!0,arrow:c,role:u="dialog",visible:f={},hidden:d={},floatingOptions:a={},isOpen:m,onOpenChange:l}){const[p,h]=St(!1),E=ut(null),x=At(),{x:C,y:S,strategy:b,refs:O,context:P}=io({placement:o,middleware:[_n(t),Bn(),Wn(),Vn({element:E})],open:m||p,onOpenChange:l||h,whileElementsMounted:An,...a}),v=ro(P),k=lo(P,{role:u}),{delay:I}=Pt(),A=qn(P,{delay:I||{open:n,close:e}}),M=so(P),R=Zn(P),y=[i.find(te=>te==="hover")?A:void 0,i.find(te=>te==="click")?R:void 0,i.find(te=>te==="focus")?M:void 0,v,k],{getReferenceProps:T,getFloatingProps:L}=co(y);Qn(P,{id:x});const{onClick:F,...w}=T(),D=String((r?.content?.props).className).includes("pressable")?{onPress:F}:{onClick:F},N=r?.content?Dt(r.content,{...r.content.props,ref:O.setReference,...w,...D}):Oe("div",{ref:O.setReference,...T(),children:"Menu Action"}),H=r?.submenu?Ye(Lt.nav,{ref:O.setFloating,style:{position:b,top:S??0,left:C??0,width:"max-content",zIndex:50},...L(),variants:{hidden:d,visible:f},initial:"hidden",animate:m||p?"visible":"hidden",children:[s&&Oe(Xn,{ref:E,context:P,...c}),r.submenu]}):Oe("nav",{children:"Submenu"});return Ye(Ot,{children:[N,H]})}export{mo as Menu,mo as default};
1
+ "use client";import{jsxs as Be,jsx as oe,Fragment as $t}from"react/jsx-runtime";import*as v from"react";import{useLayoutEffect as vt,useState as Nt,useRef as Wt,useId as Vt,cloneElement as Bt}from"react";import{motion as Ht}from"framer-motion";import*as Kt from"react-dom";function Te(){return typeof window<"u"}function ae(e){return wt(e)?(e.nodeName||"").toLowerCase():"#document"}function K(e){var t;return(e==null||(t=e.ownerDocument)==null?void 0:t.defaultView)||window}function J(e){var t;return(t=(wt(e)?e.ownerDocument:e.document)||window.document)==null?void 0:t.documentElement}function wt(e){return Te()?e instanceof Node||e instanceof K(e).Node:!1}function N(e){return Te()?e instanceof Element||e instanceof K(e).Element:!1}function X(e){return Te()?e instanceof HTMLElement||e instanceof K(e).HTMLElement:!1}function He(e){return!Te()||typeof ShadowRoot>"u"?!1:e instanceof ShadowRoot||e instanceof K(e).ShadowRoot}function Me(e){const{overflow:t,overflowX:n,overflowY:o,display:r}=j(e);return/auto|scroll|overlay|hidden|clip/.test(t+o+n)&&r!=="inline"&&r!=="contents"}function Xt(e){return/^(table|td|th)$/.test(ae(e))}function Se(e){try{if(e.matches(":popover-open"))return!0}catch{}try{return e.matches(":modal")}catch{return!1}}const Ut=/transform|translate|scale|rotate|perspective|filter/,jt=/paint|layout|strict|content/,ne=e=>!!e&&e!=="none";let Ie;function je(e){const t=N(e)?j(e):e;return ne(t.transform)||ne(t.translate)||ne(t.scale)||ne(t.rotate)||ne(t.perspective)||!Le()&&(ne(t.backdropFilter)||ne(t.filter))||Ut.test(t.willChange||"")||jt.test(t.contain||"")}function Yt(e){let t=te(e);for(;X(t)&&!Z(t);){if(je(t))return t;if(Se(t))return null;t=te(t)}return null}function Le(){return Ie==null&&(Ie=typeof CSS<"u"&&CSS.supports&&CSS.supports("-webkit-backdrop-filter","none")),Ie}function Z(e){return/^(html|body|#document)$/.test(ae(e))}function j(e){return K(e).getComputedStyle(e)}function Ae(e){return N(e)?{scrollLeft:e.scrollLeft,scrollTop:e.scrollTop}:{scrollLeft:e.scrollX,scrollTop:e.scrollY}}function te(e){if(ae(e)==="html")return e;const t=e.assignedSlot||e.parentNode||He(e)&&e.host||J(e);return He(t)?t.host:t}function yt(e){const t=te(e);return Z(t)?(e.ownerDocument||e).body:X(t)&&Me(t)?t:yt(t)}function ee(e,t,n){var o;t===void 0&&(t=[]),n===void 0&&(n=!0);const r=yt(e),s=r===((o=e.ownerDocument)==null?void 0:o.body),i=K(r);if(s){const c=Ke(i);return t.concat(i,i.visualViewport||[],Me(r)?r:[],c&&n?ee(c):[])}else return t.concat(r,ee(r,[],n))}function Ke(e){return e.parent&&Object.getPrototypeOf(e.parent)?e.frameElement:null}const ue=Math.min,ie=Math.max,Ee=Math.round,we=Math.floor,G=e=>({x:e,y:e}),zt={left:"right",right:"left",bottom:"top",top:"bottom"};function Rt(e,t,n){return ie(e,ue(t,n))}function he(e,t){return typeof e=="function"?e(t):e}function fe(e){return e.split("-")[0]}function ve(e){return e.split("-")[1]}function xt(e){return e==="x"?"y":"x"}function Ye(e){return e==="y"?"height":"width"}function Q(e){const t=e[0];return t==="t"||t==="b"?"y":"x"}function ze(e){return xt(Q(e))}function qt(e,t,n){n===void 0&&(n=!1);const o=ve(e),r=ze(e),s=Ye(r);let i=r==="x"?o===(n?"end":"start")?"right":"left":o==="start"?"bottom":"top";return t.reference[s]>t.floating[s]&&(i=Ce(i)),[i,Ce(i)]}function Gt(e){const t=Ce(e);return[Xe(e),t,Xe(t)]}function Xe(e){return e.includes("start")?e.replace("start","end"):e.replace("end","start")}const et=["left","right"],tt=["right","left"],Jt=["top","bottom"],Qt=["bottom","top"];function Zt(e,t,n){switch(e){case"top":case"bottom":return n?t?tt:et:t?et:tt;case"left":case"right":return t?Jt:Qt;default:return[]}}function en(e,t,n,o){const r=ve(e);let s=Zt(fe(e),n==="start",o);return r&&(s=s.map(i=>i+"-"+r),t&&(s=s.concat(s.map(Xe)))),s}function Ce(e){const t=fe(e);return zt[t]+e.slice(t.length)}function tn(e){var t,n,o,r;return{top:(t=e.top)!=null?t:0,right:(n=e.right)!=null?n:0,bottom:(o=e.bottom)!=null?o:0,left:(r=e.left)!=null?r:0}}function bt(e){return typeof e!="number"?tn(e):{top:e,right:e,bottom:e,left:e}}function Oe(e){const{x:t,y:n,width:o,height:r}=e;return{width:o,height:r,top:n,left:t,right:t+o,bottom:n+r,x:t,y:n}}function nn(){const e=navigator.userAgentData;return e!=null&&e.platform?e.platform:navigator.platform}function on(){const e=navigator.userAgentData;return e&&Array.isArray(e.brands)?e.brands.map(t=>{let{brand:n,version:o}=t;return n+"/"+o}).join(" "):navigator.userAgent}function rn(){return/apple/i.test(navigator.vendor)}function sn(){return nn().toLowerCase().startsWith("mac")&&!navigator.maxTouchPoints}function cn(){return on().includes("jsdom/")}const nt="data-floating-ui-focusable",ln="input:not([type='hidden']):not([disabled]),[contenteditable]:not([contenteditable='false']),textarea:not([disabled])";function ot(e){let t=e.activeElement;for(;((n=t)==null||(n=n.shadowRoot)==null?void 0:n.activeElement)!=null;){var n;t=t.shadowRoot.activeElement}return t}function me(e,t){if(!e||!t)return!1;const n=t.getRootNode==null?void 0:t.getRootNode();if(e.contains(t))return!0;if(n&&He(n)){let o=t;for(;o;){if(e===o)return!0;o=o.parentNode||o.host}}return!1}function ce(e){return"composedPath"in e?e.composedPath()[0]:e.target}function Fe(e,t){if(t==null)return!1;if("composedPath"in e)return e.composedPath().includes(t);const n=e;return n.target!=null&&t.contains(n.target)}function un(e){return e.matches("html,body")}function re(e){return e?.ownerDocument||document}function Et(e){return X(e)&&e.matches(ln)}function fn(e){if(!e||cn())return!0;try{return e.matches(":focus-visible")}catch{return!0}}function an(e){return e?e.hasAttribute(nt)?e:e.querySelector("["+nt+"]")||e:null}function Re(e,t,n){return n===void 0&&(n=!0),e.filter(r=>{var s;return r.parentId===t&&(!n||((s=r.context)==null?void 0:s.open))}).flatMap(r=>[r,...Re(e,r.id,n)])}function dn(e){return"nativeEvent"in e}function ge(e,t){const n=["mouse","pen"];return t||n.push("",void 0),n.includes(e)}var mn=typeof document<"u",gn=function(){},z=mn?vt:gn;const pn={...v};function ye(e){const t=v.useRef(e);return z(()=>{t.current=e}),t}const hn=pn.useInsertionEffect,vn=hn||(e=>e());function Y(e){const t=v.useRef(()=>{if(process.env.NODE_ENV!=="production")throw new Error("Cannot call an event handler while rendering.")});return vn(()=>{t.current=e}),v.useCallback(function(){for(var n=arguments.length,o=new Array(n),r=0;r<n;r++)o[r]=arguments[r];return t.current==null?void 0:t.current(...o)},[])}function rt(e,t,n){let{reference:o,floating:r}=e;const s=Q(t),i=ze(t),c=Ye(i),u=fe(t),f=s==="y",g=o.x+o.width/2-r.width/2,m=o.y+o.height/2-r.height/2,d=o[c]/2-r[c]/2;let l;switch(u){case"top":l={x:g,y:o.y-r.height};break;case"bottom":l={x:g,y:o.y+o.height};break;case"right":l={x:o.x+o.width,y:m};break;case"left":l={x:o.x-r.width,y:m};break;default:l={x:o.x,y:o.y}}const p=ve(t);return p&&(l[i]+=d*(p==="end"?1:-1)*(n&&f?-1:1)),l}async function wn(e,t){var n;t===void 0&&(t={});const{x:o,y:r,platform:s,rects:i,elements:c,strategy:u}=e,{boundary:f="clippingAncestors",rootBoundary:g="viewport",elementContext:m="floating",altBoundary:d=!1,padding:l=0}=he(t,e),p=bt(l),y=c[d?m==="floating"?"reference":"floating":m],w=Oe(await s.getClippingRect({element:(n=await(s.isElement==null?void 0:s.isElement(y)))==null||n?y:y.contextElement||await(s.getDocumentElement==null?void 0:s.getDocumentElement(c.floating)),boundary:f,rootBoundary:g,strategy:u})),x=m==="floating"?{x:o,y:r,width:i.floating.width,height:i.floating.height}:i.reference,T=await(s.getOffsetParent==null?void 0:s.getOffsetParent(c.floating)),E=await(s.isElement==null?void 0:s.isElement(T))&&await(s.getScale==null?void 0:s.getScale(T))||{x:1,y:1},M=Oe(s.convertOffsetParentRelativeRectToViewportRelativeRect?await s.convertOffsetParentRelativeRectToViewportRelativeRect({elements:c,rect:x,offsetParent:T,strategy:u}):x);return{top:(w.top-M.top+p.top)/E.y,bottom:(M.bottom-w.bottom+p.bottom)/E.y,left:(w.left-M.left+p.left)/E.x,right:(M.right-w.right+p.right)/E.x}}const yn=50,Rn=async(e,t,n)=>{const{placement:o="bottom",strategy:r="absolute",middleware:s=[],platform:i}=n,c=i.detectOverflow?i:{...i,detectOverflow:wn},u=await(i.isRTL==null?void 0:i.isRTL(t));let f=await i.getElementRects({reference:e,floating:t,strategy:r}),{x:g,y:m}=rt(f,o,u),d=o,l=0;const p={};for(let a=0;a<s.length;a++){const y=s[a];if(!y)continue;const{name:w,fn:x}=y,{x:T,y:E,data:M,reset:C}=await x({x:g,y:m,initialPlacement:o,placement:d,strategy:r,middlewareData:p,rects:f,platform:c,elements:{reference:e,floating:t}});g=T??g,m=E??m,p[w]={...p[w],...M},C&&l<yn&&(l++,typeof C=="object"&&(C.placement&&(d=C.placement),C.rects&&(f=C.rects===!0?await i.getElementRects({reference:e,floating:t,strategy:r}):C.rects),{x:g,y:m}=rt(f,d,u)),a=-1)}return{x:g,y:m,placement:d,strategy:r,middlewareData:p}},xn=e=>({name:"arrow",options:e,async fn(t){const{x:n,y:o,placement:r,rects:s,platform:i,elements:c,middlewareData:u}=t,{element:f,padding:g=0}=he(e,t)||{};if(f==null)return{};const m=bt(g),d={x:n,y:o},l=ze(r),p=Ye(l),a=await i.getDimensions(f),y=l==="y",w=y?"top":"left",x=y?"bottom":"right",T=y?"clientHeight":"clientWidth",E=s.reference[p]+s.reference[l]-d[l]-s.floating[p],M=d[l]-s.reference[l],C=await(i.getOffsetParent==null?void 0:i.getOffsetParent(f));let P=C?C[T]:0;(!P||!await(i.isElement==null?void 0:i.isElement(C)))&&(P=c.floating[T]||s.floating[p]);const S=E/2-M/2,$=P/2-a[p]/2-1,I=ue(m[w],$),W=ue(m[x],$),_=P-a[p]-W,F=P/2-a[p]/2+S,R=Rt(I,F,_),L=!u.arrow&&ve(r)!=null&&F!==R&&s.reference[p]/2-(F<I?I:W)-a[p]/2<0,A=L?F<I?F-I:F-_:0;return{[l]:d[l]+A,data:{[l]:R,centerOffset:F-R-A,...L&&{alignmentOffset:A}},reset:L}}}),bn=function(e){return e===void 0&&(e={}),{name:"flip",options:e,async fn(t){var n,o;const{placement:r,middlewareData:s,rects:i,initialPlacement:c,platform:u,elements:f}=t,{mainAxis:g=!0,crossAxis:m=!0,fallbackPlacements:d,fallbackStrategy:l="bestFit",fallbackAxisSideDirection:p="none",flipAlignment:a=!0,...y}=he(e,t);if((n=s.arrow)!=null&&n.alignmentOffset)return{};const w=fe(r),x=Q(c),T=fe(c)===c,E=await(u.isRTL==null?void 0:u.isRTL(f.floating)),M=d||(T||!a?[Ce(c)]:Gt(c)),C=p!=="none";!d&&C&&M.push(...en(c,a,p,E));const P=[c,...M],S=await u.detectOverflow(t,y),$=[];let I=((o=s.flip)==null?void 0:o.overflows)||[];if(g&&$.push(S[w]),m){const R=qt(r,i,E);$.push(S[R[0]],S[R[1]])}if(I=[...I,{placement:r,overflows:$}],!$.every(R=>R<=0)){var W,_;const R=(((W=s.flip)==null?void 0:W.index)||0)+1,L=P[R];if(L&&(!(m==="alignment"?x!==Q(L):!1)||I.every(h=>Q(h.placement)===x?h.overflows[0]>0:!0)))return{data:{index:R,overflows:I},reset:{placement:L}};let A=(_=I.filter(b=>b.overflows[0]<=0).sort((b,h)=>b.overflows[1]-h.overflows[1])[0])==null?void 0:_.placement;if(!A)switch(l){case"bestFit":{var F;const b=(F=I.filter(h=>{if(C){const O=Q(h.placement);return O===x||O==="y"}return!0}).map(h=>[h.placement,h.overflows.filter(O=>O>0).reduce((O,D)=>O+D,0)]).sort((h,O)=>h[1]-O[1])[0])==null?void 0:F[0];b&&(A=b);break}case"initialPlacement":A=c;break}if(r!==A)return{reset:{placement:A}}}return{}}}},En=new Set(["left","top"]);async function Cn(e,t){const{placement:n,platform:o,elements:r}=e,s=await(o.isRTL==null?void 0:o.isRTL(r.floating)),i=fe(n),c=ve(n),u=Q(n)==="y",f=En.has(i)?-1:1,g=s&&u?-1:1,m=he(t,e);let{mainAxis:d,crossAxis:l,alignmentAxis:p}=typeof m=="number"?{mainAxis:m,crossAxis:0,alignmentAxis:null}:{mainAxis:m.mainAxis||0,crossAxis:m.crossAxis||0,alignmentAxis:m.alignmentAxis};return c&&typeof p=="number"&&(l=c==="end"?p*-1:p),u?{x:l*g,y:d*f}:{x:d*f,y:l*g}}const On=function(e){return e===void 0&&(e=0),{name:"offset",options:e,async fn(t){var n,o;const{x:r,y:s,placement:i,middlewareData:c}=t,u=await Cn(t,e);return i===((n=c.offset)==null?void 0:n.placement)&&(o=c.arrow)!=null&&o.alignmentOffset?{}:{x:r+u.x,y:s+u.y,data:{...u,placement:i}}}}},Pn=function(e){return e===void 0&&(e={}),{name:"shift",options:e,async fn(t){const{x:n,y:o,placement:r,platform:s}=t,{mainAxis:i=!0,crossAxis:c=!1,limiter:u={fn:x=>{let{x:T,y:E}=x;return{x:T,y:E}}},...f}=he(e,t),g={x:n,y:o},m=await s.detectOverflow(t,f),d=Q(r),l=xt(d);let p=g[l],a=g[d];const y=(x,T)=>Rt(T+m[x==="y"?"top":"left"],T,T-m[x==="y"?"bottom":"right"]);i&&(p=y(l,p)),c&&(a=y(d,a));const w=u.fn({...t,[l]:p,[d]:a});return{...w,data:{x:w.x-n,y:w.y-o,enabled:{[l]:i,[d]:c}}}}}};function Ct(e){const t=j(e);let n=parseFloat(t.width)||0,o=parseFloat(t.height)||0;const r=X(e),s=r?e.offsetWidth:n,i=r?e.offsetHeight:o,c=Ee(n)!==s||Ee(o)!==i;return c&&(n=s,o=i),{width:n,height:o,$:c}}function qe(e){return N(e)?e:e.contextElement}function le(e){const t=qe(e);if(!X(t))return G(1);const n=t.getBoundingClientRect(),{width:o,height:r,$:s}=Ct(t);let i=(s?Ee(n.width):n.width)/o,c=(s?Ee(n.height):n.height)/r;return(!i||!Number.isFinite(i))&&(i=1),(!c||!Number.isFinite(c))&&(c=1),{x:i,y:c}}const Tn=G(0);function Ot(e){const t=K(e);return!Le()||!t.visualViewport?Tn:{x:t.visualViewport.offsetLeft,y:t.visualViewport.offsetTop}}function Mn(e,t,n){return t===void 0&&(t=!1),!!n&&t&&n===K(e)}function se(e,t,n,o){t===void 0&&(t=!1),n===void 0&&(n=!1);const r=e.getBoundingClientRect(),s=qe(e);let i=G(1);t&&(o?N(o)&&(i=le(o)):i=le(e));const c=Mn(s,n,o)?Ot(s):G(0);let u=(r.left+c.x)/i.x,f=(r.top+c.y)/i.y,g=r.width/i.x,m=r.height/i.y;if(s&&o){const d=K(s),l=N(o)?K(o):o;let p=d,a=Ke(p);for(;a&&l!==p;){const y=le(a),w=a.getBoundingClientRect(),x=j(a),T=w.left+(a.clientLeft+parseFloat(x.paddingLeft))*y.x,E=w.top+(a.clientTop+parseFloat(x.paddingTop))*y.y;u*=y.x,f*=y.y,g*=y.x,m*=y.y,u+=T,f+=E,p=K(a),a=Ke(p)}}return Oe({width:g,height:m,x:u,y:f})}function De(e,t){const n=Ae(e).scrollLeft;return t?t.left+n:se(J(e)).left+n}function Pt(e,t){const n=e.getBoundingClientRect(),o=n.left+t.scrollLeft-De(e,n),r=n.top+t.scrollTop;return{x:o,y:r}}function Sn(e){let{elements:t,rect:n,offsetParent:o,strategy:r}=e;const s=r==="fixed",i=J(o),c=t?Se(t.floating):!1;if(o===i||c&&s)return n;let u={scrollLeft:0,scrollTop:0},f=G(1);const g=G(0),m=X(o);if((m||!s)&&((ae(o)!=="body"||Me(i))&&(u=Ae(o)),m)){const l=se(o);f=le(o),g.x=l.x+o.clientLeft,g.y=l.y+o.clientTop}const d=i&&!m&&!s?Pt(i,u):G(0);return{width:n.width*f.x,height:n.height*f.y,x:n.x*f.x-u.scrollLeft*f.x+g.x+d.x,y:n.y*f.y-u.scrollTop*f.y+g.y+d.y}}function Ln(e){return e.getClientRects?Array.from(e.getClientRects()):[]}function An(e){const t=Ae(e),n=e.ownerDocument.body,o=ie(e.scrollWidth,e.clientWidth,n.scrollWidth,n.clientWidth),r=ie(e.scrollHeight,e.clientHeight,n.scrollHeight,n.clientHeight);let s=-t.scrollLeft+De(e);const i=-t.scrollTop;return j(n).direction==="rtl"&&(s+=ie(e.clientWidth,n.clientWidth)-o),{width:o,height:r,x:s,y:i}}const Dn=25;function kn(e,t,n){n===void 0&&(n="viewport");const o=n==="layoutViewport",r=K(e),s=J(e),i=r.visualViewport;let c=s.clientWidth,u=s.clientHeight,f=0,g=0;if(i){const d=!Le()||t==="fixed";o?d||(f=-i.offsetLeft,g=-i.offsetTop):(c=i.width,u=i.height,d&&(f=i.offsetLeft,g=i.offsetTop))}if(De(s)<=0){const d=s.ownerDocument,l=d.body,p=getComputedStyle(l),a=d.compatMode==="CSS1Compat"&&parseFloat(p.marginLeft)+parseFloat(p.marginRight)||0,y=Math.abs(s.clientWidth-l.clientWidth-a),w=getComputedStyle(s).scrollbarGutter==="stable both-edges"?y/2:y;w<=Dn&&(c-=w)}return{width:c,height:u,x:f,y:g}}function In(e,t){const n=se(e,!0,t==="fixed"),o=n.top+e.clientTop,r=n.left+e.clientLeft,s=le(e),i=e.clientWidth*s.x,c=e.clientHeight*s.y,u=r*s.x,f=o*s.y;return{width:i,height:c,x:u,y:f}}function it(e,t,n){let o;if(t==="viewport"||t==="layoutViewport")o=kn(e,n,t);else if(t==="document")o=An(J(e));else if(N(t))o=In(t,n);else{const r=Ot(e);o={x:t.x-r.x,y:t.y-r.y,width:t.width,height:t.height}}return Oe(o)}function Fn(e,t){const n=t.get(e);if(n)return n;let o=ee(e,[],!1).filter(c=>N(c)&&ae(c)!=="body"),r=null;const s=j(e).position==="fixed";let i=s?te(e):e;for(;N(i)&&!Z(i);){const c=j(i),u=je(i),f=r?r.position:s?"fixed":"";!u&&(f==="fixed"||f==="absolute"&&c.position==="static")?o=o.filter(m=>m!==i):r=c,i=te(i)}return t.set(e,o),o}function _n(e){let{element:t,boundary:n,rootBoundary:o,strategy:r}=e;const i=[...n==="clippingAncestors"?Se(t)?[]:Fn(t,this._c):[].concat(n),o],c=it(t,i[0],r);let u=c.top,f=c.right,g=c.bottom,m=c.left;for(let d=1;d<i.length;d++){const l=it(t,i[d],r);u=ie(l.top,u),f=ue(l.right,f),g=ue(l.bottom,g),m=ie(l.left,m)}return{width:f-m,height:g-u,x:m,y:u}}function $n(e){const{width:t,height:n}=Ct(e);return{width:t,height:n}}function Nn(e,t,n){const o=X(t),r=J(t),s=n==="fixed",i=se(e,!0,s,t);let c={scrollLeft:0,scrollTop:0};const u=G(0);if((o||!s)&&((ae(t)!=="body"||Me(r))&&(c=Ae(t)),o)){const d=se(t,!0,s,t);u.x=d.x+t.clientLeft,u.y=d.y+t.clientTop}!o&&r&&(u.x=De(r));const f=r&&!o&&!s?Pt(r,c):G(0),g=i.left+c.scrollLeft-u.x-f.x,m=i.top+c.scrollTop-u.y-f.y;return{x:g,y:m,width:i.width,height:i.height}}function _e(e){return j(e).position==="static"}function st(e,t){if(!X(e)||j(e).position==="fixed")return null;if(t)return t(e);let n=e.offsetParent;return J(e)===n&&(n=n.ownerDocument.body),n}function Tt(e,t){const n=K(e);if(Se(e))return n;if(!X(e)){let r=te(e);for(;r&&!Z(r);){if(N(r)&&!_e(r))return r;r=te(r)}return n}let o=st(e,t);for(;o&&Xt(o)&&_e(o);)o=st(o,t);return o&&Z(o)&&_e(o)&&!je(o)?n:o||Yt(e)||n}const Wn=async function(e){const t=this.getOffsetParent||Tt,n=this.getDimensions,o=await n(e.floating);return{reference:Nn(e.reference,await t(e.floating),e.strategy),floating:{x:0,y:0,width:o.width,height:o.height}}};function Vn(e){return j(e).direction==="rtl"}const Bn={convertOffsetParentRelativeRectToViewportRelativeRect:Sn,getDocumentElement:J,getClippingRect:_n,getOffsetParent:Tt,getElementRects:Wn,getClientRects:Ln,getDimensions:$n,getScale:le,isElement:N,isRTL:Vn};function Mt(e,t){return e.x===t.x&&e.y===t.y&&e.width===t.width&&e.height===t.height}function Hn(e,t,n){let o=null,r;const s=J(e);function i(){var g;clearTimeout(r),(g=o)==null||g.disconnect(),o=null}function c(g,m){g===void 0&&(g=!1),m===void 0&&(m=1),i();const d=e.getBoundingClientRect(),{left:l,top:p,width:a,height:y}=d;if(g||t(),!a||!y)return;const w=we(p),x=we(s.clientWidth-(l+a)),T=we(s.clientHeight-(p+y)),E=we(l),C={rootMargin:-w+"px "+-x+"px "+-T+"px "+-E+"px",threshold:ie(0,ue(1,m))||1};let P=!0;function S($){const I=$[0].intersectionRatio;if(!Mt(d,e.getBoundingClientRect()))return c();if(I!==m){if(!P)return c();I?c(!1,I):r=setTimeout(()=>{c(!1,1e-7)},1e3)}P=!1}try{o=new IntersectionObserver(S,{...C,root:s.ownerDocument})}catch{o=new IntersectionObserver(S,C)}o.observe(e)}const u=K(e),f=()=>c(n);return u.addEventListener("resize",f),c(!0),()=>{u.removeEventListener("resize",f),i()}}function Kn(e,t,n,o){o===void 0&&(o={});const{ancestorScroll:r=!0,ancestorResize:s=!0,elementResize:i=typeof ResizeObserver=="function",layoutShift:c=typeof IntersectionObserver=="function",animationFrame:u=!1}=o,f=qe(e),g=r||s?[...f?ee(f):[],...t?ee(t):[]]:[];g.forEach(w=>{r&&w.addEventListener("scroll",n),s&&w.addEventListener("resize",n)});const m=f&&c?Hn(f,n,s):null;let d=-1,l=null;i&&(l=new ResizeObserver(w=>{let[x]=w;x&&x.target===f&&l&&t&&(l.unobserve(t),cancelAnimationFrame(d),d=requestAnimationFrame(()=>{var T;(T=l)==null||T.observe(t)})),n()}),f&&!u&&l.observe(f),t&&l.observe(t));let p,a=u?se(e):null;u&&y();function y(){const w=se(e);a&&!Mt(a,w)&&n(),a=w,p=requestAnimationFrame(y)}return n(),()=>{var w;g.forEach(x=>{r&&x.removeEventListener("scroll",n),s&&x.removeEventListener("resize",n)}),m?.(),(w=l)==null||w.disconnect(),l=null,u&&cancelAnimationFrame(p)}}const Xn=On,Un=Pn,jn=bn,ct=xn,Yn=(e,t,n)=>{const o=new Map,r=n??{},s={...Bn,...r.platform,_c:o};return Rn(e,t,{...r,platform:s})};var zn=typeof document<"u",qn=function(){},xe=zn?vt:qn;function Pe(e,t){if(e===t)return!0;if(typeof e!=typeof t)return!1;if(typeof e=="function"&&e.toString()===t.toString())return!0;let n,o,r;if(e&&t&&typeof e=="object"){if(Array.isArray(e)){if(n=e.length,n!==t.length)return!1;for(o=n;o--!==0;)if(!Pe(e[o],t[o]))return!1;return!0}if(r=Object.keys(e),n=r.length,n!==Object.keys(t).length)return!1;for(o=n;o--!==0;)if(!{}.hasOwnProperty.call(t,r[o]))return!1;for(o=n;o--!==0;){const s=r[o];if(!(s==="_owner"&&e.$$typeof)&&!Pe(e[s],t[s]))return!1}return!0}return e!==e&&t!==t}function St(e){return typeof window>"u"?1:(e.ownerDocument.defaultView||window).devicePixelRatio||1}function lt(e,t){const n=St(e);return Math.round(t*n)/n}function $e(e){const t=v.useRef(e);return xe(()=>{t.current=e}),t}function Gn(e){e===void 0&&(e={});const{placement:t="bottom",strategy:n="absolute",middleware:o=[],platform:r,elements:{reference:s,floating:i}={},transform:c=!0,whileElementsMounted:u,open:f}=e,[g,m]=v.useState({x:0,y:0,strategy:n,placement:t,middlewareData:{},isPositioned:!1}),[d,l]=v.useState(o);Pe(d,o)||l(o);const[p,a]=v.useState(null),[y,w]=v.useState(null),x=v.useCallback(h=>{h!==C.current&&(C.current=h,a(h))},[]),T=v.useCallback(h=>{h!==P.current&&(P.current=h,w(h))},[]),E=s||p,M=i||y,C=v.useRef(null),P=v.useRef(null),S=v.useRef(g),$=u!=null,I=$e(u),W=$e(r),_=$e(f),F=v.useCallback(()=>{if(!C.current||!P.current)return;const h={placement:t,strategy:n,middleware:d};W.current&&(h.platform=W.current),Yn(C.current,P.current,h).then(O=>{const D={...O,isPositioned:_.current!==!1};R.current&&!Pe(S.current,D)&&(S.current=D,Kt.flushSync(()=>{m(D)}))})},[d,t,n,W,_]);xe(()=>{f===!1&&S.current.isPositioned&&(S.current.isPositioned=!1,m(h=>({...h,isPositioned:!1})))},[f]);const R=v.useRef(!1);xe(()=>(R.current=!0,()=>{R.current=!1}),[]),xe(()=>{if(E&&(C.current=E),M&&(P.current=M),E&&M){if(I.current)return I.current(E,M,F);F()}},[E,M,F,I,$]);const L=v.useMemo(()=>({reference:C,floating:P,setReference:x,setFloating:T}),[x,T]),A=v.useMemo(()=>({reference:E,floating:M}),[E,M]),b=v.useMemo(()=>{const h={position:n,left:0,top:0};if(!A.floating)return h;const O=lt(A.floating,g.x),D=lt(A.floating,g.y);return c?{...h,transform:"translate("+O+"px, "+D+"px)",...St(A.floating)>=1.5&&{willChange:"transform"}}:{position:n,left:O,top:D}},[n,c,A.floating,g.x,g.y]);return v.useMemo(()=>({...g,update:F,refs:L,elements:A,floatingStyles:b}),[g,F,L,A,b])}const Jn=e=>{function t(n){return{}.hasOwnProperty.call(n,"current")}return{name:"arrow",options:e,fn(n){const{element:o,padding:r}=typeof e=="function"?e(n):e;return o&&t(o)?o.current!=null?ct({element:o.current,padding:r}).fn(n):{}:o?ct({element:o,padding:r}).fn(n):{}}}},Qn=(e,t)=>{const n=Xn(e);return{name:n.name,fn:n.fn,options:[e,t]}},Zn=(e,t)=>{const n=Un(e);return{name:n.name,fn:n.fn,options:[e,t]}},eo=(e,t)=>{const n=jn(e);return{name:n.name,fn:n.fn,options:[e,t]}},to=(e,t)=>{const n=Jn(e);return{name:n.name,fn:n.fn,options:[e,t]}},no="data-floating-ui-focusable",ut="active",ft="selected",oo={...v};let at=!1,ro=0;const dt=()=>"floating-ui-"+Math.random().toString(36).slice(2,6)+ro++;function io(){const[e,t]=v.useState(()=>at?dt():void 0);return z(()=>{e==null&&t(dt())},[]),v.useEffect(()=>{at=!0},[]),e}const so=oo.useId,Ge=so||io;let pe;process.env.NODE_ENV!=="production"&&(pe=new Set);function co(){for(var e,t=arguments.length,n=new Array(t),o=0;o<t;o++)n[o]=arguments[o];const r="Floating UI: "+n.join(" ");if(!((e=pe)!=null&&e.has(r))){var s;(s=pe)==null||s.add(r),console.warn(r)}}function lo(){for(var e,t=arguments.length,n=new Array(t),o=0;o<t;o++)n[o]=arguments[o];const r="Floating UI: "+n.join(" ");if(!((e=pe)!=null&&e.has(r))){var s;(s=pe)==null||s.add(r),console.error(r)}}const uo=v.forwardRef(function(t,n){const{context:{placement:o,elements:{floating:r},middlewareData:{arrow:s,shift:i}},width:c=14,height:u=7,tipRadius:f=0,strokeWidth:g=0,staticOffset:m,stroke:d,d:l,style:{transform:p,...a}={},...y}=t;process.env.NODE_ENV!=="production"&&(n||co("The `ref` prop is required for `FloatingArrow`."));const w=Ge(),[x,T]=v.useState(!1);if(z(()=>{if(!r)return;j(r).direction==="rtl"&&T(!0)},[r]),!r)return null;const[E,M]=o.split("-"),C=E==="top"||E==="bottom";let P=m;(C&&i!=null&&i.x||!C&&i!=null&&i.y)&&(P=null);const S=g*2,$=S/2,I=c/2*(f/-8+1),W=u/2*f/4,_=!!l,F=P&&M==="end"?"bottom":"top";let R=P&&M==="end"?"right":"left";P&&x&&(R=M==="end"?"left":"right");const L=s?.x!=null?P||s.x:"",A=s?.y!=null?P||s.y:"",b=l||"M0,0"+(" H"+c)+(" L"+(c-I)+","+(u-W))+(" Q"+c/2+","+u+" "+I+","+(u-W))+" Z",h={top:_?"rotate(180deg)":"",left:_?"rotate(90deg)":"rotate(-90deg)",bottom:_?"":"rotate(180deg)",right:_?"rotate(-90deg)":"rotate(90deg)"}[E];return Be("svg",{...y,"aria-hidden":!0,ref:n,width:_?c:c+S,height:c,viewBox:"0 0 "+c+" "+(u>c?u:c),style:{position:"absolute",pointerEvents:"none",[R]:L,[F]:A,[E]:C||_?"100%":"calc(100% - "+S/2+"px)",transform:[h,p].filter(O=>!!O).join(" "),...a},children:[S>0&&oe("path",{clipPath:"url(#"+w+")",fill:"none",stroke:d,strokeWidth:S+(l?0:1),d:b}),oe("path",{stroke:S&&!l?y.fill:"none",d:b}),oe("clipPath",{id:w,children:oe("rect",{x:-$,y:$*(_?-1:1),width:c+S,height:c})})]})});function fo(){const e=new Map;return{emit(t,n){var o;(o=e.get(t))==null||o.forEach(r=>r(n))},on(t,n){e.has(t)||e.set(t,new Set),e.get(t).add(n)},off(t,n){var o;(o=e.get(t))==null||o.delete(n)}}}const ao=v.createContext(null),mo=v.createContext(null),Je=()=>{var e;return((e=v.useContext(ao))==null?void 0:e.id)||null},Qe=()=>v.useContext(mo);function Ze(e){return"data-floating-ui-"+e}function U(e){e.current!==-1&&(clearTimeout(e.current),e.current=-1)}const mt=Ze("safe-polygon");function be(e,t,n){if(n&&!ge(n))return 0;if(typeof e=="number")return e;if(typeof e=="function"){const o=e();return typeof o=="number"?o:o?.[t]}return e?.[t]}function Ne(e){return typeof e=="function"?e():e}function go(e,t){t===void 0&&(t={});const{open:n,onOpenChange:o,dataRef:r,events:s,elements:i}=e,{enabled:c=!0,delay:u=0,handleClose:f=null,mouseOnly:g=!1,restMs:m=0,move:d=!0}=t,l=Qe(),p=Je(),a=ye(f),y=ye(u),w=ye(n),x=ye(m),T=v.useRef(),E=v.useRef(-1),M=v.useRef(),C=v.useRef(-1),P=v.useRef(!0),S=v.useRef(!1),$=v.useRef(()=>{}),I=v.useRef(!1),W=Y(()=>{var b;const h=(b=r.current.openEvent)==null?void 0:b.type;return h?.includes("mouse")&&h!=="mousedown"});v.useEffect(()=>{if(!c)return;function b(h){let{open:O}=h;O||(U(E),U(C),P.current=!0,I.current=!1)}return s.on("openchange",b),()=>{s.off("openchange",b)}},[c,s]),v.useEffect(()=>{if(!c||!a.current||!n)return;function b(O){W()&&o(!1,O,"hover")}const h=re(i.floating).documentElement;return h.addEventListener("mouseleave",b),()=>{h.removeEventListener("mouseleave",b)}},[i.floating,n,o,c,a,W]);const _=v.useCallback(function(b,h,O){h===void 0&&(h=!0),O===void 0&&(O="hover");const D=be(y.current,"close",T.current);D&&!M.current?(U(E),E.current=window.setTimeout(()=>o(!1,b,O),D)):h&&(U(E),o(!1,b,O))},[y,o]),F=Y(()=>{$.current(),M.current=void 0}),R=Y(()=>{if(S.current){const b=re(i.floating).body;b.style.pointerEvents="",b.removeAttribute(mt),S.current=!1}}),L=Y(()=>r.current.openEvent?["click","mousedown"].includes(r.current.openEvent.type):!1);v.useEffect(()=>{if(!c)return;function b(k){if(U(E),P.current=!1,g&&!ge(T.current)||Ne(x.current)>0&&!be(y.current,"open"))return;const V=be(y.current,"open",T.current);V?E.current=window.setTimeout(()=>{w.current||o(!0,k,"hover")},V):n||o(!0,k,"hover")}function h(k){if(L()){R();return}$.current();const V=re(i.floating);if(U(C),I.current=!1,a.current&&r.current.floatingContext){n||U(E),M.current=a.current({...r.current.floatingContext,tree:l,x:k.clientX,y:k.clientY,onClose(){R(),F(),L()||_(k,!0,"safe-polygon")}});const H=M.current;V.addEventListener("mousemove",H),$.current=()=>{V.removeEventListener("mousemove",H)};return}(T.current!=="touch"||!me(i.floating,k.relatedTarget))&&_(k)}function O(k){L()||r.current.floatingContext&&(a.current==null||a.current({...r.current.floatingContext,tree:l,x:k.clientX,y:k.clientY,onClose(){R(),F(),L()||_(k)}})(k))}function D(){U(E)}function B(k){L()||_(k,!1)}if(N(i.domReference)){const k=i.domReference,V=i.floating;return n&&k.addEventListener("mouseleave",O),d&&k.addEventListener("mousemove",b,{once:!0}),k.addEventListener("mouseenter",b),k.addEventListener("mouseleave",h),V&&(V.addEventListener("mouseleave",O),V.addEventListener("mouseenter",D),V.addEventListener("mouseleave",B)),()=>{n&&k.removeEventListener("mouseleave",O),d&&k.removeEventListener("mousemove",b),k.removeEventListener("mouseenter",b),k.removeEventListener("mouseleave",h),V&&(V.removeEventListener("mouseleave",O),V.removeEventListener("mouseenter",D),V.removeEventListener("mouseleave",B))}}},[i,c,e,g,d,_,F,R,o,n,w,l,y,a,r,L,x]),z(()=>{var b;if(c&&n&&(b=a.current)!=null&&(b=b.__options)!=null&&b.blockPointerEvents&&W()){S.current=!0;const O=i.floating;if(N(i.domReference)&&O){var h;const D=re(i.floating).body;D.setAttribute(mt,"");const B=i.domReference,k=l==null||(h=l.nodesRef.current.find(V=>V.id===p))==null||(h=h.context)==null?void 0:h.elements.floating;return k&&(k.style.pointerEvents=""),D.style.pointerEvents="none",B.style.pointerEvents="auto",O.style.pointerEvents="auto",()=>{D.style.pointerEvents="",B.style.pointerEvents="",O.style.pointerEvents=""}}}},[c,n,p,i,l,a,W]),z(()=>{n||(T.current=void 0,I.current=!1,F(),R())},[n,F,R]),v.useEffect(()=>()=>{F(),U(E),U(C),R()},[c,i.domReference,F,R]);const A=v.useMemo(()=>{function b(h){T.current=h.pointerType}return{onPointerDown:b,onPointerEnter:b,onMouseMove(h){const{nativeEvent:O}=h;function D(){!P.current&&!w.current&&o(!0,O,"hover")}g&&!ge(T.current)||n||Ne(x.current)===0||I.current&&h.movementX**2+h.movementY**2<2||(U(C),T.current==="touch"?D():(I.current=!0,C.current=window.setTimeout(D,Ne(x.current))))}}},[g,o,n,w,x]);return v.useMemo(()=>c?{reference:A}:{},[c,A])}const Ue=()=>{},po=v.createContext({delay:0,initialDelay:0,timeoutMs:0,currentId:null,setCurrentId:Ue,setState:Ue,isInstantPhase:!1}),ho=()=>v.useContext(po);function vo(e,t){t===void 0&&(t={});const{open:n,onOpenChange:o,floatingId:r}=e,{id:s,enabled:i=!0}=t,c=s??r,u=ho(),{currentId:f,setCurrentId:g,initialDelay:m,setState:d,timeoutMs:l}=u;return z(()=>{i&&f&&(d({delay:{open:1,close:be(m,"close")}}),f!==c&&o(!1))},[i,c,o,d,f,m]),z(()=>{function p(){o(!1),d({delay:m,currentId:null})}if(i&&f&&!n&&f===c){if(l){const a=window.setTimeout(p,l);return()=>{clearTimeout(a)}}p()}},[i,n,d,f,c,o,m,l]),z(()=>{i&&(g===Ue||!n||g(c))},[i,n,g,c]),u}function gt(e){return X(e.target)&&e.target.tagName==="BUTTON"}function wo(e){return X(e.target)&&e.target.tagName==="A"}function pt(e){return Et(e)}function yo(e,t){t===void 0&&(t={});const{open:n,onOpenChange:o,dataRef:r,elements:{domReference:s}}=e,{enabled:i=!0,event:c="click",toggle:u=!0,ignoreMouse:f=!1,keyboardHandlers:g=!0,stickIfOpen:m=!0}=t,d=v.useRef(),l=v.useRef(!1),p=v.useMemo(()=>({onPointerDown(a){d.current=a.pointerType},onMouseDown(a){const y=d.current;a.button===0&&c!=="click"&&(ge(y,!0)&&f||(n&&u&&(!(r.current.openEvent&&m)||r.current.openEvent.type==="mousedown")?o(!1,a.nativeEvent,"click"):(a.preventDefault(),o(!0,a.nativeEvent,"click"))))},onClick(a){const y=d.current;if(c==="mousedown"&&d.current){d.current=void 0;return}ge(y,!0)&&f||(n&&u&&(!(r.current.openEvent&&m)||r.current.openEvent.type==="click")?o(!1,a.nativeEvent,"click"):o(!0,a.nativeEvent,"click"))},onKeyDown(a){d.current=void 0,!(a.defaultPrevented||!g||gt(a))&&(a.key===" "&&!pt(s)&&(a.preventDefault(),l.current=!0),!wo(a)&&a.key==="Enter"&&o(!(n&&u),a.nativeEvent,"click"))},onKeyUp(a){a.defaultPrevented||!g||gt(a)||pt(s)||a.key===" "&&l.current&&(l.current=!1,o(!(n&&u),a.nativeEvent,"click"))}}),[r,s,c,f,g,o,n,m,u]);return v.useMemo(()=>i?{reference:p}:{},[i,p])}const Ro={pointerdown:"onPointerDown",mousedown:"onMouseDown",click:"onClick"},xo={pointerdown:"onPointerDownCapture",mousedown:"onMouseDownCapture",click:"onClickCapture"},ht=e=>{var t,n;return{escapeKey:typeof e=="boolean"?e:(t=e?.escapeKey)!=null?t:!1,outsidePress:typeof e=="boolean"?e:(n=e?.outsidePress)!=null?n:!0}};function bo(e,t){t===void 0&&(t={});const{open:n,onOpenChange:o,elements:r,dataRef:s}=e,{enabled:i=!0,escapeKey:c=!0,outsidePress:u=!0,outsidePressEvent:f="pointerdown",referencePress:g=!1,referencePressEvent:m="pointerdown",ancestorScroll:d=!1,bubbles:l,capture:p}=t,a=Qe(),y=Y(typeof u=="function"?u:()=>!1),w=typeof u=="function"?y:u,x=v.useRef(!1),{escapeKey:T,outsidePress:E}=ht(l),{escapeKey:M,outsidePress:C}=ht(p),P=v.useRef(!1),S=Y(R=>{var L;if(!n||!i||!c||R.key!=="Escape"||P.current)return;const A=(L=s.current.floatingContext)==null?void 0:L.nodeId,b=a?Re(a.nodesRef.current,A):[];if(!T&&(R.stopPropagation(),b.length>0)){let h=!0;if(b.forEach(O=>{var D;if((D=O.context)!=null&&D.open&&!O.context.dataRef.current.__escapeKeyBubbles){h=!1;return}}),!h)return}o(!1,dn(R)?R.nativeEvent:R,"escape-key")}),$=Y(R=>{var L;const A=()=>{var b;S(R),(b=ce(R))==null||b.removeEventListener("keydown",A)};(L=ce(R))==null||L.addEventListener("keydown",A)}),I=Y(R=>{var L;const A=s.current.insideReactTree;s.current.insideReactTree=!1;const b=x.current;if(x.current=!1,f==="click"&&b||A||typeof w=="function"&&!w(R))return;const h=ce(R),O="["+Ze("inert")+"]",D=re(r.floating).querySelectorAll(O);let B=N(h)?h:null;for(;B&&!Z(B);){const H=te(B);if(Z(H)||!N(H))break;B=H}if(D.length&&N(h)&&!un(h)&&!me(h,r.floating)&&Array.from(D).every(H=>!me(B,H)))return;if(X(h)&&F){const H=Z(h),q=j(h),de=/auto|scroll/,Lt=H||de.test(q.overflowX),At=H||de.test(q.overflowY),Dt=Lt&&h.clientWidth>0&&h.scrollWidth>h.clientWidth,kt=At&&h.clientHeight>0&&h.scrollHeight>h.clientHeight,It=q.direction==="rtl",Ft=kt&&(It?R.offsetX<=h.offsetWidth-h.clientWidth:R.offsetX>h.clientWidth),_t=Dt&&R.offsetY>h.clientHeight;if(Ft||_t)return}const k=(L=s.current.floatingContext)==null?void 0:L.nodeId,V=a&&Re(a.nodesRef.current,k).some(H=>{var q;return Fe(R,(q=H.context)==null?void 0:q.elements.floating)});if(Fe(R,r.floating)||Fe(R,r.domReference)||V)return;const ke=a?Re(a.nodesRef.current,k):[];if(ke.length>0){let H=!0;if(ke.forEach(q=>{var de;if((de=q.context)!=null&&de.open&&!q.context.dataRef.current.__outsidePressBubbles){H=!1;return}}),!H)return}o(!1,R,"outside-press")}),W=Y(R=>{var L;const A=()=>{var b;I(R),(b=ce(R))==null||b.removeEventListener(f,A)};(L=ce(R))==null||L.addEventListener(f,A)});v.useEffect(()=>{if(!n||!i)return;s.current.__escapeKeyBubbles=T,s.current.__outsidePressBubbles=E;let R=-1;function L(D){o(!1,D,"ancestor-scroll")}function A(){window.clearTimeout(R),P.current=!0}function b(){R=window.setTimeout(()=>{P.current=!1},Le()?5:0)}const h=re(r.floating);c&&(h.addEventListener("keydown",M?$:S,M),h.addEventListener("compositionstart",A),h.addEventListener("compositionend",b)),w&&h.addEventListener(f,C?W:I,C);let O=[];return d&&(N(r.domReference)&&(O=ee(r.domReference)),N(r.floating)&&(O=O.concat(ee(r.floating))),!N(r.reference)&&r.reference&&r.reference.contextElement&&(O=O.concat(ee(r.reference.contextElement)))),O=O.filter(D=>{var B;return D!==((B=h.defaultView)==null?void 0:B.visualViewport)}),O.forEach(D=>{D.addEventListener("scroll",L)}),()=>{c&&(h.removeEventListener("keydown",M?$:S,M),h.removeEventListener("compositionstart",A),h.removeEventListener("compositionend",b)),w&&h.removeEventListener(f,C?W:I,C),O.forEach(D=>{D.removeEventListener("scroll",L)}),window.clearTimeout(R)}},[s,r,c,w,f,n,o,d,i,T,E,S,M,$,I,C,W]),v.useEffect(()=>{s.current.insideReactTree=!1},[s,w,f]);const _=v.useMemo(()=>({onKeyDown:S,...g&&{[Ro[m]]:R=>{o(!1,R.nativeEvent,"reference-press")},...m!=="click"&&{onClick(R){o(!1,R.nativeEvent,"reference-press")}}}}),[S,o,g,m]),F=v.useMemo(()=>{function R(L){L.button===0&&(x.current=!0)}return{onKeyDown:S,onMouseDown:R,onMouseUp:R,[xo[f]]:()=>{s.current.insideReactTree=!0}}},[S,f,s]);return v.useMemo(()=>i?{reference:_,floating:F}:{},[i,_,F])}function Eo(e){const{open:t=!1,onOpenChange:n,elements:o}=e,r=Ge(),s=v.useRef({}),[i]=v.useState(()=>fo()),c=Je()!=null;if(process.env.NODE_ENV!=="production"){const l=o.reference;l&&!N(l)&&lo("Cannot pass a virtual element to the `elements.reference` option,","as it must be a real DOM element. Use `refs.setPositionReference()`","instead.")}const[u,f]=v.useState(o.reference),g=Y((l,p,a)=>{s.current.openEvent=l?p:void 0,i.emit("openchange",{open:l,event:p,reason:a,nested:c}),n?.(l,p,a)}),m=v.useMemo(()=>({setPositionReference:f}),[]),d=v.useMemo(()=>({reference:u||o.reference||null,floating:o.floating||null,domReference:o.reference}),[u,o.reference,o.floating]);return v.useMemo(()=>({dataRef:s,open:t,onOpenChange:g,elements:d,events:i,floatingId:r,refs:m}),[t,g,d,i,r,m])}function Co(e){var t,n;let{elements:o,...r}=e===void 0?{}:e;const{nodeId:s}=r,i=Eo({...r,elements:{reference:(t=o?.reference)!=null?t:null,floating:(n=o?.floating)!=null?n:null}}),c=r.rootContext||i,u=c.elements,[f,g]=v.useState(null),[m,d]=v.useState(null),p=u?.domReference||f,a=v.useRef(null),y=Qe();z(()=>{p&&(a.current=p)},[p]);const w=Gn({...r,elements:{...u,...m&&{reference:m}}}),x=v.useCallback(P=>{const S=N(P)?{getBoundingClientRect:()=>P.getBoundingClientRect(),getClientRects:()=>P.getClientRects(),contextElement:P}:P;d(S),w.refs.setReference(S)},[w.refs]),T=v.useCallback(P=>{(N(P)||P===null)&&(a.current=P,g(P)),(N(w.refs.reference.current)||w.refs.reference.current===null||P!==null&&!N(P))&&w.refs.setReference(P)},[w.refs]),E=v.useMemo(()=>({...w.refs,setReference:T,setPositionReference:x,domReference:a}),[w.refs,T,x]),M=v.useMemo(()=>({...w.elements,domReference:p}),[w.elements,p]),C=v.useMemo(()=>({...w,...c,refs:E,elements:M,nodeId:s}),[w,E,M,s,c]);return z(()=>{c.dataRef.current.floatingContext=C;const P=y?.nodesRef.current.find(S=>S.id===s);P&&(P.context=C)}),v.useMemo(()=>({...w,context:C,refs:E,elements:M}),[w,E,M,C])}function We(){return sn()&&rn()}function Oo(e,t){t===void 0&&(t={});const{open:n,onOpenChange:o,events:r,dataRef:s,elements:i}=e,{enabled:c=!0,visibleOnly:u=!0}=t,f=v.useRef(!1),g=v.useRef(-1),m=v.useRef(!0);v.useEffect(()=>{if(!c)return;const l=K(i.domReference);function p(){!n&&X(i.domReference)&&i.domReference===ot(re(i.domReference))&&(f.current=!0)}function a(){m.current=!0}function y(){m.current=!1}return l.addEventListener("blur",p),We()&&(l.addEventListener("keydown",a,!0),l.addEventListener("pointerdown",y,!0)),()=>{l.removeEventListener("blur",p),We()&&(l.removeEventListener("keydown",a,!0),l.removeEventListener("pointerdown",y,!0))}},[i.domReference,n,c]),v.useEffect(()=>{if(!c)return;function l(p){let{reason:a}=p;(a==="reference-press"||a==="escape-key")&&(f.current=!0)}return r.on("openchange",l),()=>{r.off("openchange",l)}},[r,c]),v.useEffect(()=>()=>{U(g)},[]);const d=v.useMemo(()=>({onMouseLeave(){f.current=!1},onFocus(l){if(f.current)return;const p=ce(l.nativeEvent);if(u&&N(p)){if(We()&&!l.relatedTarget){if(!m.current&&!Et(p))return}else if(!fn(p))return}o(!0,l.nativeEvent,"focus")},onBlur(l){f.current=!1;const p=l.relatedTarget,a=l.nativeEvent,y=N(p)&&p.hasAttribute(Ze("focus-guard"))&&p.getAttribute("data-type")==="outside";g.current=window.setTimeout(()=>{var w;const x=ot(i.domReference?i.domReference.ownerDocument:document);!p&&x===i.domReference||me((w=s.current.floatingContext)==null?void 0:w.refs.floating.current,x)||me(i.domReference,x)||y||o(!1,a,"focus")})}}),[s,i.domReference,o,u]);return v.useMemo(()=>c?{reference:d}:{},[c,d])}function Ve(e,t,n){const o=new Map,r=n==="item";let s=e;if(r&&e){const{[ut]:i,[ft]:c,...u}=e;s=u}return{...n==="floating"&&{tabIndex:-1,[no]:""},...s,...t.map(i=>{const c=i?i[n]:null;return typeof c=="function"?e?c(e):null:c}).concat(e).reduce((i,c)=>(c&&Object.entries(c).forEach(u=>{let[f,g]=u;if(!(r&&[ut,ft].includes(f)))if(f.indexOf("on")===0){if(o.has(f)||o.set(f,[]),typeof g=="function"){var m;(m=o.get(f))==null||m.push(g),i[f]=function(){for(var d,l=arguments.length,p=new Array(l),a=0;a<l;a++)p[a]=arguments[a];return(d=o.get(f))==null?void 0:d.map(y=>y(...p)).find(y=>y!==void 0)}}}else i[f]=g}),i),{})}}function Po(e){e===void 0&&(e=[]);const t=e.map(c=>c?.reference),n=e.map(c=>c?.floating),o=e.map(c=>c?.item),r=v.useCallback(c=>Ve(c,e,"reference"),t),s=v.useCallback(c=>Ve(c,e,"floating"),n),i=v.useCallback(c=>Ve(c,e,"item"),o);return v.useMemo(()=>({getReferenceProps:r,getFloatingProps:s,getItemProps:i}),[r,s,i])}const To=new Map([["select","listbox"],["combobox","listbox"],["label",!1]]);function Mo(e,t){var n,o;t===void 0&&(t={});const{open:r,elements:s,floatingId:i}=e,{enabled:c=!0,role:u="dialog"}=t,f=Ge(),g=((n=s.domReference)==null?void 0:n.id)||f,m=v.useMemo(()=>{var x;return((x=an(s.floating))==null?void 0:x.id)||i},[s.floating,i]),d=(o=To.get(u))!=null?o:u,p=Je()!=null,a=v.useMemo(()=>d==="tooltip"||u==="label"?{["aria-"+(u==="label"?"labelledby":"describedby")]:r?m:void 0}:{"aria-expanded":r?"true":"false","aria-haspopup":d==="alertdialog"?"dialog":d,"aria-controls":r?m:void 0,...d==="listbox"&&{role:"combobox"},...d==="menu"&&{id:g},...d==="menu"&&p&&{role:"menuitem"},...u==="select"&&{"aria-autocomplete":"none"},...u==="combobox"&&{"aria-autocomplete":"list"}},[d,m,p,r,g,u]),y=v.useMemo(()=>{const x={id:m,...d&&{role:d}};return d==="tooltip"||u==="label"?x:{...x,...d==="menu"&&{"aria-labelledby":g}}},[d,m,g,u]),w=v.useCallback(x=>{let{active:T,selected:E}=x;const M={role:"option",...T&&{id:m+"-fui-option"}};switch(u){case"select":case"combobox":return{...M,"aria-selected":E}}return{}},[m,u]);return v.useMemo(()=>c?{reference:a,floating:y,item:w}:{},[c,a,y,w])}function Do({closeDelay:e=300,offset:t=20,openDelay:n=0,placement:o="bottom-start",slots:r,trigger:s=["hover","focus"],withArrow:i=!0,arrow:c,role:u="dialog",visible:f={},hidden:g={},floatingOptions:m={},isOpen:d,onOpenChange:l}){const[p,a]=Nt(!1),y=Wt(null),w=Vt(),{x,y:T,strategy:E,refs:M,context:C}=Co({placement:o,middleware:[Qn(t),eo(),Zn(),to({element:y})],open:d||p,onOpenChange:l||a,whileElementsMounted:Kn,...m}),P=bo(C),S=Mo(C,{role:u}),{delay:$}=vo(C,{id:w}),W=go(C,{delay:$||{open:n,close:e}}),_=Oo(C),F=yo(C),R=[s.find(k=>k==="hover")?W:void 0,s.find(k=>k==="click")?F:void 0,s.find(k=>k==="focus")?_:void 0,P,S],{getReferenceProps:L,getFloatingProps:A}=Po(R),{onClick:b,...h}=L(),O=String((r?.content?.props).className).includes("pressable")?{onPress:b}:{onClick:b},D=r?.content?Bt(r.content,{...r.content.props,ref:M.setReference,...h,...O}):oe("div",{ref:M.setReference,...L(),children:"Menu Action"}),B=r?.submenu?Be(Ht.nav,{ref:M.setFloating,style:{position:E,top:T??0,left:x??0,width:"max-content",zIndex:50},...A(),variants:{hidden:g,visible:f},initial:"hidden",animate:d||p?"visible":"hidden",children:[i&&oe(uo,{ref:y,context:C,...c}),r.submenu]}):oe("nav",{children:"Submenu"});return Be($t,{children:[D,B]})}export{Do as Menu,Do as default};
@@ -0,0 +1,290 @@
1
+ # External Link Detection Migration
2
+
3
+ **Date:** 2026-01-14
4
+ **Affects:** `@clicktap/ui`, `apps/frontend`
5
+ **Breaking:** No (additive, but requires provider setup for SSR)
6
+ **Classification:** IMPROVEMENT
7
+
8
+
9
+ ## Dependencies
10
+
11
+ *None*
12
+
13
+ ## Summary
14
+
15
+ The `Link` component from `@clicktap/ui` now automatically detects external URLs and applies `target="_blank"` and `rel="noopener noreferrer"` attributes. This requires setting up `LinkProvider` for proper SSR support.
16
+
17
+ ## Changes
18
+
19
+ 1. `Link` component auto-detects external URLs
20
+ 2. New `LinkProvider` for SSR base URL configuration
21
+ 3. New `isExternalUrl` utility function
22
+ 4. Layout files must pass `baseUrl` from host header
23
+
24
+ ## Setup
25
+
26
+ ### 1. Update Layouts to Pass baseUrl
27
+
28
+ In your Next.js layout files (Server Components), extract the host header and pass it to Providers:
29
+
30
+ ```tsx
31
+ // app/(base)/layout.tsx
32
+ import { headers } from 'next/headers';
33
+
34
+ export default function Layout({ children }) {
35
+ const h = headers();
36
+ const baseUrl = `https://${h.get('host')}`;
37
+
38
+ return (
39
+ <Providers baseUrl={baseUrl}>
40
+ {children}
41
+ </Providers>
42
+ );
43
+ }
44
+ ```
45
+
46
+ ```tsx
47
+ // app/(checkout)/layout.tsx
48
+ import { headers } from 'next/headers';
49
+
50
+ export default function CheckoutLayout({ children }) {
51
+ const h = headers();
52
+ const baseUrl = `https://${h.get('host')}`;
53
+
54
+ return (
55
+ <Providers baseUrl={baseUrl}>
56
+ {children}
57
+ </Providers>
58
+ );
59
+ }
60
+ ```
61
+
62
+ ### 2. Update Providers Component
63
+
64
+ Add the `baseUrl` prop and wrap with `LinkProvider`:
65
+
66
+ ```tsx
67
+ // providers/Providers.tsx
68
+ import { LinkProvider } from '@clicktap/ui/components/Link';
69
+
70
+ type Props = {
71
+ baseUrl?: string;
72
+ children: ReactNode;
73
+ // ... other props
74
+ };
75
+
76
+ export function Providers({ baseUrl, children, ...props }: Props) {
77
+ return (
78
+ <LinkProvider config={{ baseUrl }}>
79
+ {/* other providers */}
80
+ {children}
81
+ </LinkProvider>
82
+ );
83
+ }
84
+ ```
85
+
86
+ ## How It Works
87
+
88
+ ### Detection Logic
89
+
90
+ - **Relative URLs** (`/path`, `#anchor`) → Internal (no attributes added)
91
+ - **Absolute URLs** → Compared against current host
92
+ - Same host → Internal
93
+ - Different host → External (adds `target="_blank"` and `rel="noopener noreferrer"`)
94
+
95
+ ### Host Detection
96
+
97
+ - **Client-side:** Uses `window.location.host` automatically
98
+ - **Server-side (SSR):** Uses `baseUrl` from `LinkProvider`
99
+
100
+ This ensures external links are correctly identified during both SSR and client-side rendering.
101
+
102
+ ## Usage
103
+
104
+ No changes needed in component code. The `Link` component handles detection automatically:
105
+
106
+ ```tsx
107
+ import { Link } from '@clicktap/ui/components/Link';
108
+
109
+ // Internal - renders normally
110
+ <Link href="/products">Products</Link>
111
+
112
+ // External - automatically gets target="_blank" rel="noopener noreferrer"
113
+ <Link href="https://google.com">Google</Link>
114
+
115
+ // Anchor - renders normally
116
+ <Link href="#section">Jump to section</Link>
117
+ ```
118
+
119
+ ### Override Behavior
120
+
121
+ You can override the automatic behavior if needed:
122
+
123
+ ```tsx
124
+ // Force internal link behavior on external URL
125
+ <Link href="https://subdomain.mysite.com" target="_self">
126
+ Subdomain
127
+ </Link>
128
+
129
+ // Force external link behavior on internal URL
130
+ <Link href="/download" target="_blank" rel="noopener noreferrer">
131
+ Download
132
+ </Link>
133
+ ```
134
+
135
+ ## Utility Function
136
+
137
+ The `isExternalUrl` utility is exported for use outside the Link component:
138
+
139
+ ```tsx
140
+ import { isExternalUrl } from '@clicktap/ui/components/Link';
141
+
142
+ const external = isExternalUrl('https://google.com', 'mysite.com');
143
+ // true
144
+
145
+ const internal = isExternalUrl('/products', 'mysite.com');
146
+ // false
147
+ ```
148
+
149
+ ## Files Changed
150
+
151
+ - `libs/ui/src/components/Link/Link.tsx` - Auto-detection logic
152
+ - `libs/ui/src/components/Link/LinkContext.tsx` - New provider
153
+ - `libs/ui/src/components/Link/utils.ts` - `isExternalUrl` utility
154
+ - `libs/ui/src/components/Link/index.ts` - Updated exports
155
+ - `apps/frontend/app/(base)/layout.tsx` - Pass baseUrl
156
+ - `apps/frontend/app/(checkout)/layout.tsx` - Pass baseUrl
157
+ - `apps/frontend/providers/Providers.tsx` - Add LinkProvider
158
+
159
+ ## Migration Checklist
160
+
161
+ 1. [ ] Update `libs/ui` to latest version
162
+ 2. [ ] Add `baseUrl` prop to Providers component
163
+ 3. [ ] Wrap app with `LinkProvider`
164
+ 4. [ ] Update all layout files to pass `baseUrl` from host header
165
+ 5. [ ] Test external links open in new tab
166
+ 6. [ ] Test internal links work normally
167
+ 7. [ ] Verify SSR renders correct attributes
168
+
169
+ ---
170
+
171
+ # LinkAsButton → @clicktap/ui
172
+
173
+ **Date:** 2026-02-06
174
+
175
+ ## Summary
176
+
177
+ `LinkAsButton` has been promoted from `apps/frontend/components/LinkAsButton/` into the shared UI library. `Button` also gains `primary`/`secondary`/`tertiary` variant aliases.
178
+
179
+ ## Changes
180
+
181
+ ### `LinkAsButton` promoted to shared UI library
182
+
183
+ - **Old import:** `import { LinkAsButton } from '../LinkAsButton/LinkAsButton'` (relative, app-level)
184
+ - **New import:** `import { LinkAsButton } from '@clicktap/ui/components/LinkAsButton'`
185
+ - The `[k: string]: any` catch-all type is removed — proper typing via `LinkProps` + `Pick<ButtonProps, 'variant' | 'size'>`
186
+ - Now supports all Button variants (`solid`, `outline`, `ghost`) plus aliases (`primary`, `secondary`, `tertiary`), `size` prop (`sm`, `md`, `lg`), and `isLoading`
187
+ - `apps/frontend/components/LinkAsButton/` has been deleted
188
+
189
+ ### Breaking: `LinkAsButton` default behavior changed
190
+
191
+ The old local component had no default variant — it rendered as a transparent link with base layout classes. The new shared component defaults to `variant="solid"` and `size="md"`:
192
+
193
+ | Property | Old (local) | New (`@clicktap/ui`) |
194
+ |----------|-------------|----------------------|
195
+ | `variant` | none (transparent background, transparent border) | `solid` (dark background, white text) |
196
+ | `size` | none (no height constraint) | `md` (`h-10` = 40px height) |
197
+
198
+ **Impact:** Any `<LinkAsButton>` without an explicit `variant` prop now renders as a dark solid button with a 40px height constraint. This is especially problematic when wrapping images — the image gets constrained inside a styled button container.
199
+
200
+ **Fix:** Use `variant="ghost"` for transparent links, or use `<Link>` directly when button styling isn't appropriate (e.g., clickable product images):
201
+
202
+ ```tsx
203
+ // Before: image wrapped in default LinkAsButton (was transparent, now solid)
204
+ <LinkAsButton href={url}>
205
+ <Image ... />
206
+ </LinkAsButton>
207
+
208
+ // After: use plain Link for image wrappers
209
+ <Link href={url}>
210
+ <Image ... />
211
+ </Link>
212
+
213
+ // After: use ghost variant if button semantics are needed
214
+ <LinkAsButton variant="ghost" href={url}>
215
+ Text link
216
+ </LinkAsButton>
217
+ ```
218
+
219
+ ### Button variant aliases
220
+
221
+ - `Button` now accepts `primary`, `secondary`, and `tertiary` as variant values
222
+ - `primary` → `solid`, `secondary` → `outline`, `tertiary` → `ghost`
223
+ - Existing `solid`, `outline`, `ghost` values continue to work unchanged
224
+
225
+ ---
226
+
227
+ # Image Component: Remove `width: 'auto'` Auto-Styling
228
+
229
+ **Date:** 2026-02-08
230
+ **Affects:** `@clicktap/ui` Image component, all consumers
231
+ **Breaking:** Yes - images using `width`/`height` props may render differently
232
+
233
+ ## Summary
234
+
235
+ The `@clicktap/ui` Image component previously auto-prepended `{ width: 'auto', height: 'auto' }` to the style prop when `width` and `height` props were provided (not `fill`). The `width: 'auto'` has been removed because it overrides the HTML `width` attribute via CSS, causing images to render at their natural intrinsic size instead of the dimensions specified by the props.
236
+
237
+ ## What Changed
238
+
239
+ ```diff
240
+ const imageStyle = hasSizedProps
241
+ - ? { width: 'auto' as const, height: 'auto' as const, ...style }
242
+ + ? { height: 'auto' as const, ...style }
243
+ : style;
244
+ ```
245
+
246
+ **Before:** Images with `width={100} height={100}` and no explicit `style` rendered at their natural resolution (CSS `width: auto` overrode the HTML attribute).
247
+
248
+ **After:** Images render at the width specified by the `width` prop. `height: 'auto'` preserves the natural aspect ratio.
249
+
250
+ ## Migration
251
+
252
+ ### Review Image usages without explicit `style` prop
253
+
254
+ Any `<Image>` that passes `width` and `height` props without a `style` override will now render at the `width` prop size instead of the natural image size. In most cases this is the correct behavior.
255
+
256
+ If the natural-size behavior was intentional, restore it with an explicit style:
257
+
258
+ ```tsx
259
+ <Image width={100} height={100} style={{ width: 'auto', height: 'auto' }} ... />
260
+ ```
261
+
262
+ ### Add aspect ratio control where needed
263
+
264
+ If the displayed image needs a specific aspect ratio that differs from the source image's natural ratio, add CSS classes. Use the actual source image dimensions to determine the ratio (e.g., 960x1200 images → `aspect-[4/5]`):
265
+
266
+ ```tsx
267
+ // Explicit aspect ratio matching source images (e.g., 960x1200 = 4:5)
268
+ <Image
269
+ width={100} height={125}
270
+ className="aspect-[4/5] object-cover"
271
+ style={{ width: '100%', height: 'auto' }}
272
+ />
273
+
274
+ // Fill container width, natural aspect ratio (common pattern, no extra classes needed)
275
+ <Image
276
+ width={400} height={300}
277
+ style={{ width: '100%', height: 'auto' }}
278
+ />
279
+ ```
280
+
281
+ ### Affected areas to check
282
+
283
+ Visually inspect any page that displays product images:
284
+ - Cart drawer (mini-cart)
285
+ - Cart page
286
+ - Checkout order summary
287
+ - Checkout success / order confirmation
288
+ - Category listing pages
289
+ - Product collection components
290
+ - Account order history
@@ -0,0 +1,142 @@
1
+ # useRoute Hook Migration
2
+
3
+ **Date:** 2026-01-14
4
+ **Affects:** `@clicktap/ui`, `apps/frontend`
5
+ **Breaking:** No (additive, but recommended migration)
6
+ **Classification:** IMPROVEMENT
7
+
8
+
9
+ ## Dependencies
10
+
11
+ *None*
12
+
13
+ ## Summary
14
+
15
+ Introduces a centralized route configuration system with the `useRoute` hook for generating URLs. Handles dynamic params, protected route redirects, and login-with-return patterns automatically.
16
+
17
+ ## New Files
18
+
19
+ - `libs/ui/src/hooks/useRoute/` - Hook and RouteProvider
20
+ - `apps/frontend/config/routes.ts` - Centralized route definitions
21
+
22
+ ## Provider Setup
23
+
24
+ Add `RouteProviderWithAuth` inside your `AuthProvider`:
25
+
26
+ ```tsx
27
+ import { RouteProvider } from '@clicktap/ui/hooks/useRoute';
28
+ import { useAuth } from '../state/auth/AuthProvider';
29
+
30
+ function RouteProviderWithAuth({ children }: { children: ReactNode }) {
31
+ const { isLoggedIn } = useAuth();
32
+ return <RouteProvider config={{ isLoggedIn }}>{children}</RouteProvider>;
33
+ }
34
+
35
+ // In provider tree:
36
+ <AuthProvider actor={authActor}>
37
+ <RouteProviderWithAuth>
38
+ {children}
39
+ </RouteProviderWithAuth>
40
+ </AuthProvider>
41
+ ```
42
+
43
+ ## Migration Patterns
44
+
45
+ ### Static Routes
46
+
47
+ ```tsx
48
+ // Before
49
+ <Link href="/cart">Cart</Link>
50
+
51
+ // After
52
+ import { useRoute } from '@clicktap/ui/hooks/useRoute';
53
+ import { Routes } from '../config/routes';
54
+
55
+ const cartUrl = useRoute(Routes.cart.index);
56
+ <Link href={cartUrl}>Cart</Link>
57
+ ```
58
+
59
+ ### Dynamic Routes
60
+
61
+ ```tsx
62
+ // Before
63
+ <Link href={`/account/orders/${orderId}`}>View Order</Link>
64
+
65
+ // After
66
+ const orderUrl = useRoute(Routes.account.orders.view, { orderId });
67
+ <Link href={orderUrl}>View Order</Link>
68
+ ```
69
+
70
+ ### Protected Routes
71
+
72
+ Protected routes automatically redirect through auth when logged out:
73
+
74
+ ```tsx
75
+ // Before
76
+ const ordersUrl = isLoggedIn
77
+ ? '/account/orders'
78
+ : `/account/authenticate?redirect=${encodeURIComponent('/account/orders')}`;
79
+
80
+ // After
81
+ const ordersUrl = useRoute(Routes.account.orders.index);
82
+ // Logged in: '/account/orders'
83
+ // Logged out: '/account/authenticate?redirect=%2Faccount%2Forders'
84
+ ```
85
+
86
+ ### Login with Return
87
+
88
+ ```tsx
89
+ // Before
90
+ const loginUrl = `/account/authenticate?redirect=${encodeURIComponent(pathname)}`;
91
+ const loginUrl = Routes.account.loginAndReturn(Routes.cart.index);
92
+
93
+ // After
94
+ const loginUrl = useRoute(Routes.account.authenticate, null, { returnHere: true });
95
+ ```
96
+
97
+ ### router.push
98
+
99
+ ```tsx
100
+ // Before
101
+ router.push('/checkout');
102
+ router.push(`/checkout/success/${orderId}`);
103
+
104
+ // After
105
+ const checkoutUrl = useRoute(Routes.checkout.index);
106
+ router.push(checkoutUrl);
107
+
108
+ const successUrl = useRoute(Routes.checkout.success, { orderId });
109
+ router.push(successUrl);
110
+ ```
111
+
112
+ ## Adding New Routes
113
+
114
+ Add to `apps/frontend/config/routes.ts`:
115
+
116
+ ```tsx
117
+ const RawRoutes = {
118
+ // Static route
119
+ newPage: {
120
+ path: '/new-page',
121
+ isProtected: false,
122
+ },
123
+
124
+ // Nested with dynamic param
125
+ feature: {
126
+ index: {
127
+ path: '/feature',
128
+ isProtected: false,
129
+ },
130
+ details: {
131
+ path: '/feature/:featureId',
132
+ isProtected: true,
133
+ },
134
+ },
135
+ } as const;
136
+ ```
137
+
138
+ ## Deprecated
139
+
140
+ - `Routes.account.loginAndReturn()` - Use `useRoute(route, null, { returnHere: true })`
141
+ - `isProtectedRoute(pathname)` - Use `route.isProtected` directly
142
+ - Direct `.path` access - Use `useRoute()` for all URL generation