@fiscozen/composables 1.0.3 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- (function(p,l){typeof exports=="object"&&typeof module<"u"?l(exports,require("vue")):typeof define=="function"&&define.amd?define(["exports","vue"],l):(p=typeof globalThis<"u"?globalThis:p||self,l(p.FzComposables={},p.Vue))})(this,function(p,l){"use strict";const L=(e,t)=>{if(!isFinite(e)||t<0)return e;if(t===0)return Math.trunc(e);const o=String(e);if(o.includes("e")||o.includes("E")){const r=Math.pow(10,t);return Math.trunc(e*r)/r}const n=o.indexOf(".");return n===-1||o.length-n-1<=t?e:Number(o.slice(0,n+t+1))},P=(e,{minimumFractionDigits:t=0,maximumFractionDigits:o=2,roundDecimals:n=!0,useGrouping:r=!0}={})=>e==null||isNaN(e)||!isFinite(e)?"":(n?e:L(e,o)).toLocaleString("it-IT",{minimumFractionDigits:t,maximumFractionDigits:o,useGrouping:r}),$=e=>{if(!e||typeof e!="string")return NaN;let t=e.trim();return t.includes(",")&&(t=t.replace(/\./g,""),t=t.replace(",",".")),parseFloat(t)},T=(e,t)=>{let o=t;const n=t%e,r=t>=0?e:-e;return n!==0&&(o=Math.abs(n)>=e/2?t+r-n:t-n),o},V=(e,t,o)=>Math.max(e,Math.min(t,o)),C=new DOMRect(0,0,window.innerWidth,window.innerHeight),b=(e,t,o,n,r)=>{let i=r?"bottom":"right",u=r?"bottom-start":"right-start";C.width=window.innerWidth,C.height=window.innerHeight,C.x=0,C.y=0;const v=e?e.getBoundingClientRect():C,x=t.getBoundingClientRect(),h=o.getBoundingClientRect(),m=(h.left-v.left-x.width)/v.width,g=(v.right-h.right-x.width)/v.width,y=(h.top-v.top-x.height)/v.height,s=(v.bottom-h.bottom-x.height)/v.height;let c=[{key:"right",space:g},{key:"top",space:y},{key:"bottom",space:s},{key:"left",space:m}].sort((f,d)=>d.space-f.space);if(r&&(c=c.filter(f=>f.key==="top"||f.key==="bottom")),i=c[0].key,!n){const f=(x.height-h.height)/2;switch(i){case"right":case"left":v.top>h.top-f&&(n="end"),v.bottom<h.top-f&&(n="start");break}}return u=n?`${i}-${n}`:i,u},F=(e,t,o,n)=>({x:t.x+e.width*o/100,y:t.y+e.height*n/100}),M=e=>typeof e=="string"?document.querySelector(e):e,j=e=>({left:parseFloat(e.marginLeft),right:parseFloat(e.marginRight),top:parseFloat(e.marginTop),bottom:parseFloat(e.marginBottom)}),D={bottom:(e,t)=>({position:{x:e.left-t.left+e.width/2,y:e.bottom},transform:{x:-50,y:0}}),"bottom-start":(e,t)=>({position:{x:e.left-t.left,y:e.bottom},transform:{x:0,y:0}}),"bottom-end":(e,t)=>({position:{x:e.right+t.right,y:e.bottom},transform:{x:-100,y:0}}),top:(e,t)=>({position:{x:e.left-t.left+e.width/2,y:e.top-t.bottom},transform:{x:-50,y:-100}}),"top-start":(e,t)=>({position:{x:e.left-t.left,y:e.top-t.bottom},transform:{x:0,y:-100}}),"top-end":(e,t)=>({position:{x:e.right+t.right,y:e.top-t.bottom},transform:{x:-100,y:-100}}),left:(e,t)=>({position:{x:e.left-t.right,y:e.top-t.top+e.height/2},transform:{x:-100,y:-50}}),"left-start":(e,t)=>({position:{x:e.left-t.right,y:e.top-t.top},transform:{x:-100,y:0}}),"left-end":(e,t)=>({position:{x:e.left-t.right,y:e.bottom+t.bottom},transform:{x:-100,y:-100}}),right:(e,t)=>({position:{x:e.right+t.left,y:e.top-t.top+e.height/2},transform:{x:0,y:-50}}),"right-start":(e,t)=>({position:{x:e.right+t.left,y:e.top-t.top},transform:{x:0,y:0}}),"right-end":(e,t)=>({position:{x:e.right+t.left,y:e.bottom+t.bottom},transform:{x:0,y:-100}})},I=(e,t,o)=>{const n=D[e];return n?n(t,o):{position:{x:0,y:0},transform:{x:0,y:0}}},K={bottom:(e,t)=>({position:{x:e.left+e.width/2,y:e.bottom-t.height},transform:{x:-50,y:0}}),"bottom-start":(e,t)=>({position:{x:e.left,y:e.bottom-t.height},transform:{x:0,y:0}}),"bottom-end":(e,t)=>({position:{x:e.right-t.width,y:e.bottom-t.height},transform:{x:0,y:0}}),top:e=>({position:{x:e.left+e.width/2,y:e.top},transform:{x:-50,y:0}}),"top-start":e=>({position:{x:e.left,y:e.top},transform:{x:0,y:0}}),"top-end":(e,t)=>({position:{x:e.right-t.width,y:e.top},transform:{x:0,y:0}}),left:(e,t)=>({position:{x:e.left,y:e.top+(e.height-t.height)/2},transform:{x:0,y:0}}),"left-start":e=>({position:{x:e.left,y:e.top},transform:{x:0,y:0}}),"left-end":(e,t)=>({position:{x:e.left,y:e.bottom-t.height},transform:{x:0,y:0}}),right:(e,t)=>({position:{x:e.right-t.width,y:e.top+(e.height-t.height)/2},transform:{x:0,y:0}}),"right-start":(e,t)=>({position:{x:e.right-t.width,y:e.top},transform:{x:0,y:0}}),"right-end":(e,t)=>({position:{x:e.right-t.width,y:e.bottom-t.height},transform:{x:0,y:0}})},q=(e,t,o)=>{const n=K[e];return n?n(t,o):{position:{x:0,y:0},transform:{x:0,y:0}}},Q=(e,t,o,n)=>{const r={...e},i={...n};if(e.x<o.left&&(r.x=o.left,i.x=0),e.x+t.width>o.right){const u=o.right-t.width;u>0&&(r.x=u),i.x=0}if(e.y<o.top&&(r.y=o.top,i.y=0),e.y+t.height>o.bottom){const u=o.bottom-t.height;u>0&&(r.y=u),i.y=0}return{position:r,transform:i}},G=(e,t,o,n,r)=>{const i=r?null:t;switch(e){case"auto":return b(i,o,n);case"auto-vertical":return b(i,o,n,void 0,!0);case"auto-start":return b(i,o,n,"start");case"auto-vertical-start":return b(i,o,n,"start",!0);case"auto-end":return b(i,o,n,"end");case"auto-vertical-end":return b(i,o,n,"end",!0);default:return"bottom-start"}},X=e=>e.startsWith("auto"),W=e=>{const t=l.ref("auto"),o=l.ref(),n=l.ref(),r=l.ref(),i=l.ref(),u=l.reactive({position:{x:0,y:0}}),v={root:null,rootMargin:"0px",threshold:1,...e.element.value.intersectionOptions},x=l.ref(new IntersectionObserver(()=>{},v)),h=()=>{var f,d;const y=M(e.element.value.domRef.value);if(!y)return null;const s=(f=e.container)!=null&&f.value?M(e.container.value.domRef.value)??document.body:document.body,c=(d=e.opener)!=null&&d.value?M(e.opener.value.domRef.value):null;return{element:y,container:s,opener:c}},m=y=>{var s;return{element:y.element.getBoundingClientRect(),container:y.container.getBoundingClientRect(),opener:((s=y.opener)==null?void 0:s.getBoundingClientRect())??null}},g=(y=!1)=>l.nextTick(()=>{var O,z,B;o.value=((O=e.position)==null?void 0:O.value)??"auto";const s=h();if(!s)return;Object.assign(s.element.style,{position:"fixed",top:"0px",left:"0px"});const c=m(s);n.value=c.element,r.value=c.opener??void 0,i.value=c.container,x.value.observe(s.element),x.value.observe(s.container),X(o.value)&&s.opener&&(o.value=G(o.value,s.container,s.element,s.opener,((z=e.useViewport)==null?void 0:z.value)??!1));const f=j(window.getComputedStyle(s.element)),d=s.opener&&c.opener?I(o.value,c.opener,f):q(o.value,c.container,c.element),E=F(c.element,d.position,d.transform.x,d.transform.y),k=Q(E,c.element,c.container,d.transform);u.position.x=k.position.x,u.position.y=k.position.y,Object.assign(s.element.style,{top:`${u.position.y}px`,left:`${u.position.x}px`,position:"fixed",display:"flex"}),n.value=s.element.getBoundingClientRect(),(B=e.callback)!=null&&B.value&&!y&&e.callback.value(n,r,i,t,o)});return l.onUnmounted(()=>{x.value.disconnect()}),{float:u,rect:n,setPosition:g,position:t,actualPosition:o,openerRect:r,containerRect:i}};function R(e){const t=window.matchMedia(e),o=l.ref(t.matches);function n(r){o.value=r.matches}return l.onMounted(()=>{t.addEventListener("change",n)}),l.onUnmounted(()=>{t.removeEventListener("change",n)}),l.computed(()=>o.value)}function Y(e){return{isGreater(t){return R(`(min-width: ${e[t]})`)},isSmaller(t){return R(`(max-width: ${e[t]})`)},isInBetween(t,o){return R(`(min-width: ${e[t]}) and (max-width: ${e[o]})`)}}}function J(e,t,o){if(!e)throw new Error("A target component has to be provided.");if(!t)throw new Error("A callback has to be provided.");const n=r=>{!e.value||r.target===e.value||r.composedPath().includes(e.value)||typeof t=="function"&&t()};o&&l.watch(o,(r,i)=>{i&&i.removeEventListener("click",n),r==null||r.addEventListener("click",n)}),l.onMounted(()=>{o||document.addEventListener("click",n)}),l.onBeforeUnmount(()=>{var r;if(o){(r=o.value)==null||r.removeEventListener("click",n);return}document.removeEventListener("click",n)})}function Z(e,t){if(!e)throw new Error("A target component has to be provided.");if(!t||typeof t!="function")throw new Error("A callback has to be provided.");const o=n=>{t(n)};l.onMounted(()=>{e.value.addEventListener("keydown",o)}),l.onBeforeUnmount(()=>{e.value.removeEventListener("keydown",o)})}function _(e,t){if(!e||typeof e!="function")throw new Error("A callback has to be provided.");const o=n=>{e(n)};l.onMounted(()=>{if(!t){document.addEventListener("keyup",o);return}t.value.addEventListener("keyup",o)}),l.onBeforeUnmount(()=>{if(!t){document.removeEventListener("keyup",o);return}t.value.removeEventListener("keyup",o)})}const ee=e=>({format:P,parse:$}),N={global:{blue:{50:{value:"#eff1ff",type:"color"},100:{value:"#dee2ff",type:"color"},200:{value:"#bdc5ff",type:"color"},300:{value:"#9ca8ff",type:"color"},400:{value:"#7b8bff",type:"color"},500:{value:"#5a6eff",type:"color"},600:{value:"#4858cc",type:"color"},700:{value:"#364299",type:"color"},800:{value:"#242c66",type:"color"},900:{value:"#1b214c",type:"color"}},purple:{50:{value:"#f8f4ff",type:"color"},100:{value:"#f0e9ff",type:"color"},200:{value:"#e1d3ff",type:"color"},300:{value:"#d2bdff",type:"color"},400:{value:"#c3a7ff",type:"color"},500:{value:"#b491ff",type:"color"},600:{value:"#9074cc",type:"color"},700:{value:"#6c5799",type:"color"},800:{value:"#483a66",type:"color"},900:{value:"#241d33",type:"color"}},orange:{50:{value:"#fff2ef",type:"color"},100:{value:"#ffe4de",type:"color"},200:{value:"#ffc9bd",type:"color"},300:{value:"#ffae9c",type:"color"},400:{value:"#ff937b",type:"color"},500:{value:"#ff785a",type:"color"},600:{value:"#cc6048",type:"color"},700:{value:"#994836",type:"color"},800:{value:"#663024",type:"color"},900:{value:"#331812",type:"color"}},pink:{50:{value:"#fff5f5",type:"color"},100:{value:"#ffe0e0",type:"color"},200:{value:"#ffcbcb",type:"color"},300:{value:"#ffc0c0",type:"color"},400:{value:"#ffabab",type:"color"},500:{value:"#ff9696",type:"color"},600:{value:"#cc7878",type:"color"},700:{value:"#995a5a",type:"color"},800:{value:"#663c3c",type:"color"},900:{value:"#331e1e",type:"color"}},yellow:{50:{value:"#fffbf4",type:"color"},100:{value:"#fff3de",type:"color"},200:{value:"#ffebc8",type:"color"},300:{value:"#ffe7bd",type:"color"},400:{value:"#ffdfa7",type:"color"},500:{value:"#ffd791",type:"color"},600:{value:"#ccac74",type:"color"},700:{value:"#998157",type:"color"},800:{value:"#806c49",type:"color"},900:{value:"#4c402b",type:"color"}},semantic:{error:{50:{value:"#fef3f3",type:"color"},100:{value:"#f8baba",type:"color"},200:{value:"#f04242",type:"color"},300:{value:"#aa2f2f",type:"color"}},warning:{50:{value:"#fff8f3",type:"color"},100:{value:"#ffdabd",type:"color"},200:{value:"#ffae4f",type:"color"},300:{value:"#b47b38",type:"color"}},success:{50:{value:"#f2f8f6",type:"color"},100:{value:"#b5d8ce",type:"color"},200:{value:"#0fa88c",type:"color"},300:{value:"#0b7763",type:"color"}},info:{50:{value:"#f3f7ff",type:"color"},100:{value:"#b4c8e1",type:"color"},200:{value:"#4e9fff",type:"color"},300:{value:"#3770b4",type:"color"}}},background:{"white-smoke":{value:"#f7f6f3",type:"color"},seashell:{value:"#f8ece7",type:"color"},"pale-purple":{value:"#f2e6ff",type:"color"},"alice-blue":{value:"#ecf2fc",type:"color"}},grey:{100:{value:"#e9edf0",type:"color"},200:{value:"#d1dde6",type:"color"},300:{value:"#9da9b2",type:"color"},400:{value:"#6e777e",type:"color"},500:{value:"#596167",type:"color"}},core:{white:{value:"#ffffff",type:"color"},black:{value:"#2c282f",type:"color"}},"font-sans":{"sharp-grotesk":{value:'"Sharp Grotesk", sans-serif',type:"fontFamilies"},inter:{value:'"Inter", sans-serif',type:"fontFamilies"}},font:{light:{value:"300",type:"fontWeights"},normal:{value:"400",type:"fontWeights"},medium:{value:"500",type:"fontWeights"}},spacing:{0:{value:"0px",type:"spacing"},1:{value:"1px",type:"spacing"},2:{value:"2px",type:"spacing"},4:{value:"4px",type:"spacing"},6:{value:"6px",type:"spacing"},8:{value:"8px",type:"spacing"},10:{value:"10px",type:"spacing"},12:{value:"12px",type:"spacing"},14:{value:"14px",type:"spacing"},16:{value:"16px",type:"spacing"},20:{value:"20px",type:"spacing"},24:{value:"24px",type:"spacing"},28:{value:"28px",type:"spacing"},32:{value:"32px",type:"spacing"},36:{value:"36px",type:"spacing"},40:{value:"40px",type:"spacing"},44:{value:"44px",type:"spacing"},48:{value:"48px",type:"spacing"},56:{value:"56px",type:"spacing"},64:{value:"64px",type:"spacing"},80:{value:"80px",type:"spacing"},96:{value:"96px",type:"spacing"},112:{value:"112px",type:"spacing"},128:{value:"128px",type:"spacing"},144:{value:"144px",type:"spacing"},160:{value:"160px",type:"spacing"},176:{value:"176px",type:"spacing"},192:{value:"192px",type:"spacing"},208:{value:"208px",type:"spacing"},224:{value:"224px",type:"spacing"},240:{value:"240px",type:"spacing"},256:{value:"256px",type:"spacing"},288:{value:"288px",type:"spacing"},320:{value:"320px",type:"spacing"},384:{value:"384px",type:"spacing"}},border:{0:{value:"0px",type:"borderWidth"},1:{value:"1px",type:"borderWidth"},2:{value:"2px",type:"borderWidth"},4:{value:"4px",type:"borderWidth"},8:{value:"8px",type:"borderWidth"}},rounded:{none:{value:"0px",type:"borderRadius"},sm:{value:"2px",type:"borderRadius"},base:{value:"4px",type:"borderRadius"},md:{value:"6px",type:"borderRadius"},lg:{value:"8px",type:"borderRadius"},xl:{value:"12px",type:"borderRadius"},"2xl":{value:"16px",type:"borderRadius"},"3xl":{value:"24px",type:"borderRadius"},full:{value:"9999px",type:"borderRadius"}},breakpoint:{xs:{value:"376px",type:"sizing"},sm:{value:"640px",type:"sizing"},md:{value:"768px",type:"sizing"},lg:{value:"1024px",type:"sizing"},xl:{value:"1280px",type:"sizing"},"2xl":{value:"1440px",type:"sizing"},"3xl":{value:"1536px",type:"sizing"}},shadow:{none:{value:{color:"#000000",type:"dropShadow",x:"0",y:"0",blur:"0",spread:"0"},type:"boxShadow"},sm:{value:{color:"#0000000d",type:"dropShadow",x:"0",y:"1",blur:"2",spread:"0"},type:"boxShadow"},base:{value:[{color:"#0000000f",type:"dropShadow",x:"0",y:"1",blur:"2",spread:"0"},{color:"#0000001a",type:"dropShadow",x:"0",y:"1",blur:"3",spread:"0"}],type:"boxShadow"},md:{value:[{color:"#0000000f",type:"dropShadow",x:"0",y:"2",blur:"4",spread:"-1"},{color:"#0000001a",type:"dropShadow",x:"0",y:"4",blur:"6",spread:"-1"}],type:"boxShadow"},lg:{value:[{color:"#0000000d",type:"dropShadow",x:"0",y:"4",blur:"6",spread:"-2"},{color:"#0000001a",type:"dropShadow",x:"0",y:"10",blur:"15",spread:"-3"}],type:"boxShadow"},xl:{value:[{color:"#0000000a",type:"dropShadow",x:"0",y:"10",blur:"10",spread:"-5"},{color:"#0000001a",type:"dropShadow",x:"0",y:"20",blur:"25",spread:"-5"}],type:"boxShadow"},"2xl":{value:{color:"#00000040",type:"dropShadow",x:"0",y:"25",blur:"50",spread:"-12"},type:"boxShadow"},inner:{value:{color:"#0000000f",type:"innerShadow",x:"0",y:"2",blur:"4",spread:"0"},type:"boxShadow"}},underline:{value:"underline",type:"textDecoration"},text:{xs:{value:"12px",type:"fontSizes"},sm:{value:"14px",type:"fontSizes"},base:{value:"16px",type:"fontSizes"},lg:{value:"18px",type:"fontSizes"},xl:{value:"20px",type:"fontSizes"},"2xl":{value:"24px",type:"fontSizes"},"3xl":{value:"30px",type:"fontSizes"},"4xl":{value:"36px",type:"fontSizes"},"5xl":{value:"48px",type:"fontSizes"},"6xl":{value:"60px",type:"fontSizes"},"7xl":{value:"72px",type:"fontSizes"},"8xl":{value:"96px",type:"fontSizes"},"9xl":{value:"128px",type:"fontSizes"}},leading:{xs:{value:"16px",type:"lineHeights"},sm:{value:"18px",type:"lineHeights"},base:{value:"20px",type:"lineHeights"},lg:{value:"24px",type:"lineHeights"},xl:{value:"28px",type:"lineHeights"},"2xl":{value:"32px",type:"lineHeights"},"3xl":{value:"36px",type:"lineHeights"},"4xl":{value:"40px",type:"lineHeights"},"5xl":{value:"48px",type:"lineHeights"},"6xl":{value:"60px",type:"lineHeights"},"7xl":{value:"72px",type:"lineHeights"},"8xl":{value:"96px",type:"lineHeights"},"9xl":{value:"128px",type:"lineHeights"}}}},te={safeColorNames:["blue","purple","orange","pink","yellow","grey","core"]},oe={semanticColorNames:["error","warning","success","info"]},ne=te.safeColorNames,le=oe.semanticColorNames,S={};ne.forEach(e=>{const t=N.global[e];t&&Object.keys(t).forEach(o=>{var r;const n=(r=t[o])==null?void 0:r.value;n&&(S[e]||(S[e]={}),S[e][o]=n)})});const H=N.global.semantic;H&&le.forEach(e=>{const t=H[e];t&&typeof t=="object"&&Object.keys(t).forEach(o=>{var r;const n=(r=t[o])==null?void 0:r.value;if(n){const i=`semantic-${e}`;S[i]||(S[i]={}),S[i][o]=n}})});const re=Object.entries(N.global.breakpoint).reduce((e,[t,o])=>(e[t]=o.value,e),{}),ie=l.defineComponent({__name:"FzFloating",props:{isOpen:{type:Boolean,default:!1},position:{default:"auto"},container:{},contentClass:{},openerClass:{},overrideContentClass:{type:Boolean},overrideOpener:{},teleport:{type:Boolean,default:!1},useViewport:{type:Boolean}},emits:["fzfloating:setPosition"],setup(e,{expose:t,emit:o}){const n=e,r=o,i=l.ref(null),u=l.ref(null),v=l.useSlots(),x=R(`(max-width: ${re.xs})`);let h=!1,m=!1,g=null,y=null;const s={position:n.position,element:{domRef:i},container:{domRef:l.toRef(n.container||document.body)},opener:{domRef:l.toRef(null)},useViewport:n.useViewport,callback(...a){r("fzfloating:setPosition",...a)}},c=l.toRefs(s);v.opener&&(s.opener={domRef:u});const f=W(c),d=()=>{h||!m||(h=!0,requestAnimationFrame(()=>{m&&n.isOpen&&f.setPosition(),h=!1}))};l.onMounted(()=>{m=!0});const E=()=>{d()},k=()=>{d()},O=()=>{window.addEventListener("scroll",E,!0),window.addEventListener("resize",k),i.value&&!g&&(g=new ResizeObserver(()=>{d()}),g.observe(i.value)),u.value&&!y&&(y=new ResizeObserver(()=>{d()}),y.observe(u.value))},z=()=>{window.removeEventListener("scroll",E,!0),window.removeEventListener("resize",k),g&&(g.disconnect(),g=null),y&&(y.disconnect(),y=null)};l.watch(()=>n.position,()=>d()),l.watch(()=>n.isOpen,a=>{var U;if(!a||!i.value||!m){z();return}O();const w=(U=u.value)==null?void 0:U.getBoundingClientRect();i.value.style.position="fixed",i.value.style.top="0px",i.value.style.left="0px",i.value.style.transform="none",i.value.style.width=x.value?(w==null?void 0:w.width)+"px":"auto",f.setPosition()}),l.watch(()=>n.overrideOpener,a=>{a&&c.opener&&c.opener.value&&(c.opener.value={domRef:a})}),l.onBeforeUnmount(()=>{m=!1,z()});const B=a=>a.startsWith("bottom")?"mt-4":a.startsWith("top")?"mb-4":a.startsWith("left")?"mr-4":a.startsWith("right")?"ml-4":"mt-4",ae=l.computed(()=>{var w;const a=((w=f.actualPosition)==null?void 0:w.value)??n.position;return B(a)}),A=l.computed(()=>n.overrideContentClass?n.contentClass:["bg-core-white fixed",ae.value,n.contentClass]);return t({setPosition:f.setPosition}),(a,w)=>(l.openBlock(),l.createElementBlock("div",null,[l.renderSlot(a.$slots,"opener-start"),l.createElementVNode("div",{ref_key:"opener",ref:u,class:"inline-flex w-full sm:w-auto"},[l.renderSlot(a.$slots,"opener",{isOpen:e.isOpen,floating:l.unref(f)})],512),l.renderSlot(a.$slots,"opener-end"),e.teleport?l.createCommentVNode("",!0):l.withDirectives((l.openBlock(),l.createElementBlock("div",{key:0,ref_key:"content",ref:i,class:l.normalizeClass(["fz__floating__content w-full sm:w-auto",A.value])},[l.renderSlot(a.$slots,"default",{isOpen:e.isOpen,floating:l.unref(f)})],2)),[[l.vShow,a.$slots.default&&(!a.$slots.opener||a.$slots.opener&&e.isOpen)]]),e.teleport?(l.openBlock(),l.createBlock(l.Teleport,{key:1,to:"body"},[l.withDirectives(l.createElementVNode("div",{ref_key:"content",ref:i,class:l.normalizeClass(["fz__floating__content",A.value])},[l.renderSlot(a.$slots,"default",{isOpen:e.isOpen,floating:l.unref(f)})],2),[[l.vShow,a.$slots.default&&(!a.$slots.opener||a.$slots.opener&&e.isOpen)]])])):l.createCommentVNode("",!0)]))}});p.FzFloating=ie,p.calcRealPos=F,p.clamp=V,p.format=P,p.getHighestAvailableSpacePos=b,p.parse=$,p.roundTo=T,p.truncateDecimals=L,p.useBreakpoints=Y,p.useClickOutside=J,p.useCurrency=ee,p.useFloating=W,p.useKeyDown=Z,p.useKeyUp=_,p.useMediaQuery=R,Object.defineProperty(p,Symbol.toStringTag,{value:"Module"})});
1
+ (function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports,require(`vue`)):typeof define==`function`&&define.amd?define([`exports`,`vue`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.FzComposables={},e.Vue))})(this,function(e,t){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var n=(e,t)=>{if(!isFinite(e)||t<0)return e;if(t===0)return Math.trunc(e);let n=String(e);if(n.includes(`e`)||n.includes(`E`)){let n=10**t;return Math.trunc(e*n)/n}let r=n.indexOf(`.`);return r===-1||n.length-r-1<=t?e:Number(n.slice(0,r+t+1))},r=(e,{minimumFractionDigits:t=0,maximumFractionDigits:r=2,roundDecimals:i=!0,useGrouping:a=!0}={})=>e==null||isNaN(e)||!isFinite(e)?``:(i?e:n(e,r)).toLocaleString(`it-IT`,{minimumFractionDigits:t,maximumFractionDigits:r,useGrouping:a}),i=e=>{if(!e||typeof e!=`string`)return NaN;let t=e.trim();return t.includes(`,`)&&(t=t.replace(/\./g,``),t=t.replace(`,`,`.`)),parseFloat(t)},a=(e,t)=>{let n=t,r=t%e,i=t>=0?e:-e;return r!==0&&(n=Math.abs(r)>=e/2?t+i-r:t-r),n},o=(e,t,n)=>Math.max(e,Math.min(t,n)),s=new DOMRect(0,0,window.innerWidth,window.innerHeight),c=(e,t,n,r,i)=>{let a=i?`bottom`:`right`,o=i?`bottom-start`:`right-start`;s.width=window.innerWidth,s.height=window.innerHeight,s.x=0,s.y=0;let c=e?e.getBoundingClientRect():s,l=t.getBoundingClientRect(),u=n.getBoundingClientRect(),d=(u.left-c.left-l.width)/c.width,f=(c.right-u.right-l.width)/c.width,p=(u.top-c.top-l.height)/c.height,m=(c.bottom-u.bottom-l.height)/c.height,h=[{key:`right`,space:f},{key:`top`,space:p},{key:`bottom`,space:m},{key:`left`,space:d}].sort((e,t)=>t.space-e.space);if(i&&(h=h.filter(e=>e.key===`top`||e.key===`bottom`)),a=h[0].key,!r){let e=(l.height-u.height)/2;switch(a){case`right`:case`left`:c.top>u.top-e&&(r=`end`),c.bottom<u.top-e&&(r=`start`);break;default:break}}return o=r?`${a}-${r}`:a,o},l=(e,t,n,r)=>({x:t.x+e.width*n/100,y:t.y+e.height*r/100}),u=e=>typeof e==`string`?document.querySelector(e):e,d=e=>({left:parseFloat(e.marginLeft),right:parseFloat(e.marginRight),top:parseFloat(e.marginTop),bottom:parseFloat(e.marginBottom)}),f=e=>e!==null&&(e.width>0||e.height>0),p={bottom:(e,t)=>({position:{x:e.left-t.left+e.width/2,y:e.bottom},transform:{x:-50,y:0}}),"bottom-start":(e,t)=>({position:{x:e.left-t.left,y:e.bottom},transform:{x:0,y:0}}),"bottom-end":(e,t)=>({position:{x:e.right+t.right,y:e.bottom},transform:{x:-100,y:0}}),top:(e,t)=>({position:{x:e.left-t.left+e.width/2,y:e.top-t.bottom},transform:{x:-50,y:-100}}),"top-start":(e,t)=>({position:{x:e.left-t.left,y:e.top-t.bottom},transform:{x:0,y:-100}}),"top-end":(e,t)=>({position:{x:e.right+t.right,y:e.top-t.bottom},transform:{x:-100,y:-100}}),left:(e,t)=>({position:{x:e.left-t.right,y:e.top-t.top+e.height/2},transform:{x:-100,y:-50}}),"left-start":(e,t)=>({position:{x:e.left-t.right,y:e.top-t.top},transform:{x:-100,y:0}}),"left-end":(e,t)=>({position:{x:e.left-t.right,y:e.bottom+t.bottom},transform:{x:-100,y:-100}}),right:(e,t)=>({position:{x:e.right+t.left,y:e.top-t.top+e.height/2},transform:{x:0,y:-50}}),"right-start":(e,t)=>({position:{x:e.right+t.left,y:e.top-t.top},transform:{x:0,y:0}}),"right-end":(e,t)=>({position:{x:e.right+t.left,y:e.bottom+t.bottom},transform:{x:0,y:-100}})},m=(e,t,n)=>{let r=p[e];return r?r(t,n):{position:{x:0,y:0},transform:{x:0,y:0}}},h={bottom:(e,t)=>({position:{x:e.left+e.width/2,y:e.bottom-t.height},transform:{x:-50,y:0}}),"bottom-start":(e,t)=>({position:{x:e.left,y:e.bottom-t.height},transform:{x:0,y:0}}),"bottom-end":(e,t)=>({position:{x:e.right-t.width,y:e.bottom-t.height},transform:{x:0,y:0}}),top:e=>({position:{x:e.left+e.width/2,y:e.top},transform:{x:-50,y:0}}),"top-start":e=>({position:{x:e.left,y:e.top},transform:{x:0,y:0}}),"top-end":(e,t)=>({position:{x:e.right-t.width,y:e.top},transform:{x:0,y:0}}),left:(e,t)=>({position:{x:e.left,y:e.top+(e.height-t.height)/2},transform:{x:0,y:0}}),"left-start":e=>({position:{x:e.left,y:e.top},transform:{x:0,y:0}}),"left-end":(e,t)=>({position:{x:e.left,y:e.bottom-t.height},transform:{x:0,y:0}}),right:(e,t)=>({position:{x:e.right-t.width,y:e.top+(e.height-t.height)/2},transform:{x:0,y:0}}),"right-start":(e,t)=>({position:{x:e.right-t.width,y:e.top},transform:{x:0,y:0}}),"right-end":(e,t)=>({position:{x:e.right-t.width,y:e.bottom-t.height},transform:{x:0,y:0}})},g=(e,t,n)=>{let r=h[e];return r?r(t,n):{position:{x:0,y:0},transform:{x:0,y:0}}},_=(e,t,n,r)=>{let i={...e},a={...r};if(e.x<n.left&&(i.x=n.left,a.x=0),e.x+t.width>n.right){let e=n.right-t.width;e>0&&(i.x=e),a.x=0}if(e.y<n.top&&(i.y=n.top,a.y=0),e.y+t.height>n.bottom){let e=n.bottom-t.height;e>0&&(i.y=e),a.y=0}return{position:i,transform:a}},v=(e,t,n,r,i)=>{let a=i?null:t;switch(e){case`auto`:return c(a,n,r);case`auto-vertical`:return c(a,n,r,void 0,!0);case`auto-start`:return c(a,n,r,`start`);case`auto-vertical-start`:return c(a,n,r,`start`,!0);case`auto-end`:return c(a,n,r,`end`);case`auto-vertical-end`:return c(a,n,r,`end`,!0);default:return`bottom-start`}},y=e=>e.startsWith(`auto`),b=e=>{let n=(0,t.ref)(`auto`),r=(0,t.ref)(),i=(0,t.ref)(),a=(0,t.ref)(),o=(0,t.ref)(),s=(0,t.reactive)({position:{x:0,y:0}}),c={root:null,rootMargin:`0px`,threshold:1,...e.element.value.intersectionOptions},p=(0,t.ref)(new IntersectionObserver(()=>{},c)),h=()=>{let t=u(e.element.value.domRef.value);return t?{element:t,container:e.container?.value?u(e.container.value.domRef.value)??document.body:document.body,opener:e.opener?.value?u(e.opener.value.domRef.value):null}:null},b=e=>({element:e.element.getBoundingClientRect(),container:e.container.getBoundingClientRect(),opener:e.opener?.getBoundingClientRect()??null});return(0,t.onUnmounted)(()=>{p.value.disconnect()}),{float:s,rect:i,setPosition:(c=!1)=>(0,t.nextTick)(()=>{r.value=e.position?.value??`auto`;let t=h();if(!t)return;Object.assign(t.element.style,{position:`fixed`,top:`0px`,left:`0px`});let u=b(t);if(i.value=u.element,a.value=u.opener??void 0,o.value=u.container,t.opener&&!f(u.opener)){t.element.style.display=`none`;return}p.value.observe(t.element),p.value.observe(t.container),y(r.value)&&t.opener&&(r.value=v(r.value,t.container,t.element,t.opener,e.useViewport?.value??!1));let x=d(window.getComputedStyle(t.element)),S=t.opener&&u.opener?m(r.value,u.opener,x):g(r.value,u.container,u.element),C=_(l(u.element,S.position,S.transform.x,S.transform.y),u.element,u.container,S.transform);s.position.x=C.position.x,s.position.y=C.position.y,Object.assign(t.element.style,{top:`${s.position.y}px`,left:`${s.position.x}px`,position:`fixed`,display:`flex`}),i.value=t.element.getBoundingClientRect(),e.callback?.value&&!c&&e.callback.value(i,a,o,n,r)}),position:n,actualPosition:r,openerRect:a,containerRect:o}};function x(e){let n=window.matchMedia(e),r=(0,t.ref)(n.matches);function i(e){r.value=e.matches}return(0,t.onMounted)(()=>{n.addEventListener(`change`,i)}),(0,t.onUnmounted)(()=>{n.removeEventListener(`change`,i)}),(0,t.computed)(()=>r.value)}function S(e){return{isGreater(t){return x(`(min-width: ${e[t]})`)},isSmaller(t){return x(`(max-width: ${e[t]})`)},isInBetween(t,n){return x(`(min-width: ${e[t]}) and (max-width: ${e[n]})`)},current(){let n=Object.entries(e).map(([e,t])=>({name:e,value:parseInt(t,10)})).sort((e,t)=>e.value-t.value),r=n.map(({name:e,value:t})=>({name:e,matches:x(`(min-width: ${t}px)`)}));return(0,t.computed)(()=>{let e=n[0].name;for(let{name:t,matches:n}of r)n.value&&(e=t);return e})}}}function C(e,n,r){if(!e)throw Error(`A target component has to be provided.`);if(!n)throw Error(`A callback has to be provided.`);let i=t=>{!e.value||t.target===e.value||t.composedPath().includes(e.value)||typeof n==`function`&&n()};r&&(0,t.watch)(r,(e,t)=>{t&&t.removeEventListener(`click`,i),e?.addEventListener(`click`,i)}),(0,t.onMounted)(()=>{r||document.addEventListener(`click`,i)}),(0,t.onBeforeUnmount)(()=>{if(r){r.value?.removeEventListener(`click`,i);return}document.removeEventListener(`click`,i)})}function w(e,n){if(!e)throw Error(`A target component has to be provided.`);if(!n||typeof n!=`function`)throw Error(`A callback has to be provided.`);let r=e=>{n(e)};(0,t.onMounted)(()=>{e.value.addEventListener(`keydown`,r)}),(0,t.onBeforeUnmount)(()=>{e.value.removeEventListener(`keydown`,r)})}function T(e,n){if(!e||typeof e!=`function`)throw Error(`A callback has to be provided.`);let r=t=>{e(t)};(0,t.onMounted)(()=>{if(!n){document.addEventListener(`keyup`,r);return}n.value.addEventListener(`keyup`,r)}),(0,t.onBeforeUnmount)(()=>{if(!n){document.removeEventListener(`keyup`,r);return}n.value.removeEventListener(`keyup`,r)})}var E=e=>({format:r,parse:i}),D={global:{blue:{50:{value:`#eff1ff`,type:`color`},100:{value:`#dee2ff`,type:`color`},200:{value:`#bdc5ff`,type:`color`},300:{value:`#9ca8ff`,type:`color`},400:{value:`#7b8bff`,type:`color`},500:{value:`#5a6eff`,type:`color`},600:{value:`#4858cc`,type:`color`},700:{value:`#364299`,type:`color`},800:{value:`#242c66`,type:`color`},900:{value:`#1b214c`,type:`color`}},purple:{50:{value:`#f8f4ff`,type:`color`},100:{value:`#f0e9ff`,type:`color`},200:{value:`#e1d3ff`,type:`color`},300:{value:`#d2bdff`,type:`color`},400:{value:`#c3a7ff`,type:`color`},500:{value:`#b491ff`,type:`color`},600:{value:`#9074cc`,type:`color`},700:{value:`#6c5799`,type:`color`},800:{value:`#483a66`,type:`color`},900:{value:`#241d33`,type:`color`}},orange:{50:{value:`#fff2ef`,type:`color`},100:{value:`#ffe4de`,type:`color`},200:{value:`#ffc9bd`,type:`color`},300:{value:`#ffae9c`,type:`color`},400:{value:`#ff937b`,type:`color`},500:{value:`#ff785a`,type:`color`},600:{value:`#cc6048`,type:`color`},700:{value:`#994836`,type:`color`},800:{value:`#663024`,type:`color`},900:{value:`#331812`,type:`color`}},pink:{50:{value:`#fff5f5`,type:`color`},100:{value:`#ffe0e0`,type:`color`},200:{value:`#ffcbcb`,type:`color`},300:{value:`#ffc0c0`,type:`color`},400:{value:`#ffabab`,type:`color`},500:{value:`#ff9696`,type:`color`},600:{value:`#cc7878`,type:`color`},700:{value:`#995a5a`,type:`color`},800:{value:`#663c3c`,type:`color`},900:{value:`#331e1e`,type:`color`}},yellow:{50:{value:`#fffbf4`,type:`color`},100:{value:`#fff3de`,type:`color`},200:{value:`#ffebc8`,type:`color`},300:{value:`#ffe7bd`,type:`color`},400:{value:`#ffdfa7`,type:`color`},500:{value:`#ffd791`,type:`color`},600:{value:`#ccac74`,type:`color`},700:{value:`#998157`,type:`color`},800:{value:`#806c49`,type:`color`},900:{value:`#4c402b`,type:`color`}},semantic:{error:{50:{value:`#fef3f3`,type:`color`},100:{value:`#f8baba`,type:`color`},200:{value:`#f04242`,type:`color`},300:{value:`#aa2f2f`,type:`color`}},warning:{50:{value:`#fff8f3`,type:`color`},100:{value:`#ffdabd`,type:`color`},200:{value:`#ffae4f`,type:`color`},300:{value:`#b47b38`,type:`color`}},success:{50:{value:`#f2f8f6`,type:`color`},100:{value:`#b5d8ce`,type:`color`},200:{value:`#0fa88c`,type:`color`},300:{value:`#0b7763`,type:`color`}},info:{50:{value:`#f3f7ff`,type:`color`},100:{value:`#b4c8e1`,type:`color`},200:{value:`#4e9fff`,type:`color`},300:{value:`#3770b4`,type:`color`}}},background:{"white-smoke":{value:`#f7f6f3`,type:`color`},seashell:{value:`#f8ece7`,type:`color`},"pale-purple":{value:`#f2e6ff`,type:`color`},"alice-blue":{value:`#ecf2fc`,type:`color`}},grey:{100:{value:`#e9edf0`,type:`color`},200:{value:`#d1dde6`,type:`color`},300:{value:`#9da9b2`,type:`color`},400:{value:`#6e777e`,type:`color`},500:{value:`#596167`,type:`color`}},core:{white:{value:`#ffffff`,type:`color`},black:{value:`#2c282f`,type:`color`}},"font-sans":{"sharp-grotesk":{value:`"Sharp Grotesk", sans-serif`,type:`fontFamilies`},inter:{value:`"Inter", sans-serif`,type:`fontFamilies`}},font:{light:{value:`300`,type:`fontWeights`},normal:{value:`400`,type:`fontWeights`},medium:{value:`500`,type:`fontWeights`}},spacing:{0:{value:`0px`,type:`spacing`},1:{value:`1px`,type:`spacing`},2:{value:`2px`,type:`spacing`},4:{value:`4px`,type:`spacing`},6:{value:`6px`,type:`spacing`},8:{value:`8px`,type:`spacing`},10:{value:`10px`,type:`spacing`},12:{value:`12px`,type:`spacing`},14:{value:`14px`,type:`spacing`},16:{value:`16px`,type:`spacing`},20:{value:`20px`,type:`spacing`},24:{value:`24px`,type:`spacing`},28:{value:`28px`,type:`spacing`},32:{value:`32px`,type:`spacing`},36:{value:`36px`,type:`spacing`},40:{value:`40px`,type:`spacing`},44:{value:`44px`,type:`spacing`},48:{value:`48px`,type:`spacing`},56:{value:`56px`,type:`spacing`},64:{value:`64px`,type:`spacing`},80:{value:`80px`,type:`spacing`},96:{value:`96px`,type:`spacing`},112:{value:`112px`,type:`spacing`},128:{value:`128px`,type:`spacing`},144:{value:`144px`,type:`spacing`},160:{value:`160px`,type:`spacing`},176:{value:`176px`,type:`spacing`},192:{value:`192px`,type:`spacing`},208:{value:`208px`,type:`spacing`},224:{value:`224px`,type:`spacing`},240:{value:`240px`,type:`spacing`},256:{value:`256px`,type:`spacing`},288:{value:`288px`,type:`spacing`},320:{value:`320px`,type:`spacing`},384:{value:`384px`,type:`spacing`}},border:{0:{value:`0px`,type:`borderWidth`},1:{value:`1px`,type:`borderWidth`},2:{value:`2px`,type:`borderWidth`},4:{value:`4px`,type:`borderWidth`},8:{value:`8px`,type:`borderWidth`}},rounded:{none:{value:`0px`,type:`borderRadius`},sm:{value:`2px`,type:`borderRadius`},base:{value:`4px`,type:`borderRadius`},md:{value:`6px`,type:`borderRadius`},lg:{value:`8px`,type:`borderRadius`},xl:{value:`12px`,type:`borderRadius`},"2xl":{value:`16px`,type:`borderRadius`},"3xl":{value:`24px`,type:`borderRadius`},full:{value:`9999px`,type:`borderRadius`}},breakpoint:{xs:{value:`376px`,type:`sizing`},sm:{value:`640px`,type:`sizing`},md:{value:`768px`,type:`sizing`},lg:{value:`1024px`,type:`sizing`},desktop:{value:`1200px`,type:`sizing`},xl:{value:`1280px`,type:`sizing`},"2xl":{value:`1440px`,type:`sizing`},"3xl":{value:`1536px`,type:`sizing`}},shadow:{none:{value:{color:`#000000`,type:`dropShadow`,x:`0`,y:`0`,blur:`0`,spread:`0`},type:`boxShadow`},sm:{value:{color:`#0000000d`,type:`dropShadow`,x:`0`,y:`1`,blur:`2`,spread:`0`},type:`boxShadow`},base:{value:[{color:`#0000000f`,type:`dropShadow`,x:`0`,y:`1`,blur:`2`,spread:`0`},{color:`#0000001a`,type:`dropShadow`,x:`0`,y:`1`,blur:`3`,spread:`0`}],type:`boxShadow`},md:{value:[{color:`#0000000f`,type:`dropShadow`,x:`0`,y:`2`,blur:`4`,spread:`-1`},{color:`#0000001a`,type:`dropShadow`,x:`0`,y:`4`,blur:`6`,spread:`-1`}],type:`boxShadow`},lg:{value:[{color:`#0000000d`,type:`dropShadow`,x:`0`,y:`4`,blur:`6`,spread:`-2`},{color:`#0000001a`,type:`dropShadow`,x:`0`,y:`10`,blur:`15`,spread:`-3`}],type:`boxShadow`},xl:{value:[{color:`#0000000a`,type:`dropShadow`,x:`0`,y:`10`,blur:`10`,spread:`-5`},{color:`#0000001a`,type:`dropShadow`,x:`0`,y:`20`,blur:`25`,spread:`-5`}],type:`boxShadow`},"2xl":{value:{color:`#00000040`,type:`dropShadow`,x:`0`,y:`25`,blur:`50`,spread:`-12`},type:`boxShadow`},inner:{value:{color:`#0000000f`,type:`innerShadow`,x:`0`,y:`2`,blur:`4`,spread:`0`},type:`boxShadow`}},underline:{value:`underline`,type:`textDecoration`},text:{xs:{value:`12px`,type:`fontSizes`},sm:{value:`14px`,type:`fontSizes`},base:{value:`16px`,type:`fontSizes`},lg:{value:`18px`,type:`fontSizes`},xl:{value:`20px`,type:`fontSizes`},"2xl":{value:`24px`,type:`fontSizes`},"3xl":{value:`30px`,type:`fontSizes`},"4xl":{value:`36px`,type:`fontSizes`},"5xl":{value:`48px`,type:`fontSizes`},"6xl":{value:`60px`,type:`fontSizes`},"7xl":{value:`72px`,type:`fontSizes`},"8xl":{value:`96px`,type:`fontSizes`},"9xl":{value:`128px`,type:`fontSizes`}},leading:{xs:{value:`16px`,type:`lineHeights`},sm:{value:`18px`,type:`lineHeights`},base:{value:`20px`,type:`lineHeights`},lg:{value:`24px`,type:`lineHeights`},xl:{value:`28px`,type:`lineHeights`},"2xl":{value:`32px`,type:`lineHeights`},"3xl":{value:`36px`,type:`lineHeights`},"4xl":{value:`40px`,type:`lineHeights`},"5xl":{value:`48px`,type:`lineHeights`},"6xl":{value:`60px`,type:`lineHeights`},"7xl":{value:`72px`,type:`lineHeights`},"8xl":{value:`96px`,type:`lineHeights`},"9xl":{value:`128px`,type:`lineHeights`}}},alias:{avatar:{initials:{"background-color":{value:`{core.black}`,type:`color`},color:{value:`{core.white}`,type:`color`},spacing:{value:`{spacing.32}`,type:`spacing`},"border-radius":{value:`{rounded.full}`,type:`borderRadius`},"font-family":{value:`{font-sans.inter}`,type:`fontFamilies`},"font-weight":{value:`{font.normal}`,type:`fontWeights`},"font-size":{value:`{text.sm}`,type:`fontSizes`},"line-height":{value:`{leading.sm}`,type:`lineHeights`}},image:{"border-radius":{value:`{rounded.full}`,type:`borderRadius`},sm:{value:`{spacing.16}`,type:`spacing`},md:{value:`{spacing.24}`,type:`spacing`},lg:{value:`{spacing.32}`,type:`spacing`},xl:{value:`{spacing.40}`,type:`spacing`}}},"nav-link":{spacing:{value:`{spacing.32}`,type:`spacing`},"border-radius":{value:`{rounded.base}`,type:`borderRadius`},"font-family":{value:`{font-sans.inter}`,type:`fontFamilies`},"font-weight":{value:`{font.medium}`,type:`fontWeights`},"line-height":{value:`{leading.sm}`,type:`lineHeights`},"font-size":{value:`{text.sm}`,type:`fontSizes`},"background-color":{default:{value:`none`,type:`color`},hover:{value:`{background.alice-blue}`,type:`color`},pressed:{value:`{background.alice-blue}`,type:`color`},focus:{value:`{background.alice-blue}`,type:`color`},disabled:{value:`none`,type:`color`}},color:{default:{value:`{grey.500}`,type:`color`},hover:{value:`{blue.500}`,type:`color`},pressed:{value:`{blue.500}`,type:`color`},focus:{value:`{blue.500}`,type:`color`},disabled:{value:`{grey.100}`,type:`color`}},border:{default:{value:`none`,type:`color`},hover:{value:`none`,type:`color`},pressed:{value:`none`,type:`color`},focus:{value:`{blue.500}`,type:`color`},disabled:{value:`none`,type:`color`}},"border-width":{default:{value:`none`,type:`borderWidth`},hover:{value:`none`,type:`borderWidth`},pressed:{value:`none`,type:`borderWidth`},focus:{value:`{border.1}`,type:`borderWidth`},disabled:{value:`none`,type:`borderWidth`}},"box-shadow":{default:{value:`{shadow.none}`,type:`boxShadow`},hover:{value:`{shadow.none}`,type:`boxShadow`},pressed:{value:`{shadow.inner}`,type:`boxShadow`},focus:{value:`none`,type:`boxShadow`},disabled:{value:`none`,type:`boxShadow`}}},"icon-button":{button:{sm:{value:`{spacing.28}`,type:`spacing`},md:{value:`{spacing.32}`,type:`spacing`},lg:{value:`{spacing.40}`,type:`spacing`}},icon:{sm:{value:`{spacing.16}`,type:`spacing`},md:{value:`{spacing.20}`,type:`spacing`}},primary:{"background-color":{default:{value:`{blue.500}`,type:`color`},hover:{value:`{blue.600}`,type:`color`},pressed:{value:`{blue.600}`,type:`color`},focus:{value:`{blue.500}`,type:`color`},disabled:{value:`{blue.200}`,type:`color`}},color:{default:{value:`{core.white}`,type:`color`},hover:{value:`{core.white}`,type:`color`},pressed:{value:`{core.white}`,type:`color`},focus:{value:`{core.white}`,type:`color`},disabled:{value:`{core.white}`,type:`color`}},border:{default:{value:`none`,type:`color`},hover:{value:`none`,type:`color`},pressed:{value:`none`,type:`color`},focus:{value:`{blue.600}`,type:`color`},disabled:{value:`none`,type:`color`}},"border-width":{default:{value:`none`,type:`borderWidth`},hover:{value:`none`,type:`borderWidth`},pressed:{value:`none`,type:`borderWidth`},focus:{value:`{border.1}`,type:`borderWidth`},disabled:{value:`none`,type:`borderWidth`}}},secondary:{"background-color":{default:{value:`none`,type:`color`},hover:{value:`{grey.100}`,type:`color`},pressed:{value:`{grey.100}`,type:`color`},focus:{value:`none`,type:`color`},disabled:{value:`none`,type:`color`}},color:{default:{value:`{grey.500}`,type:`color`},hover:{value:`{grey.500}`,type:`color`},pressed:{value:`{grey.500}`,type:`color`},focus:{value:`{grey.500}`,type:`color`},disabled:{value:`{grey.100}`,type:`color`}},border:{default:{value:`{grey.200}`,type:`color`},hover:{value:`{grey.200}`,type:`color`},pressed:{value:`{grey.200}`,type:`color`},focus:{value:`{blue.600}`,type:`color`},disabled:{value:`{grey.100}`,type:`color`}},"border-width":{value:`{border.1}`,type:`borderWidth`}},notification:{"background-color":{default:{value:`none`,type:`color`},hover:{value:`{grey.100}`,type:`color`},pressed:{value:`{grey.100}`,type:`color`}},color:{default:{value:`{grey.500}`,type:`color`},hover:{value:`{grey.500}`,type:`color`},pressed:{value:`{grey.500}`,type:`color`},focus:{value:`{grey.500}`,type:`color`},disabled:{value:`{grey.100}`,type:`color`}},border:{default:{value:`{grey.200}`,type:`color`},hover:{value:`{grey.200}`,type:`color`},pressed:{value:`{grey.200}`,type:`color`},focus:{value:`{grey.200}`,type:`color`},disabled:{value:`{grey.100}`,type:`color`}},"border-width":{value:`{border.1}`,type:`borderWidth`}},"notification-badge":{"background-color":{default:{value:`{blue.500}`,type:`color`},hover:{value:`{blue.500}`,type:`color`},pressed:{value:`{blue.500}`,type:`color`},focus:{value:`{blue.500}`,type:`color`},disabled:{value:`{grey.200}`,type:`color`}},border:{default:{value:`{core.white}`,type:`color`},hover:{value:`{core.white}`,type:`color`},pressed:{value:`{core.white}`,type:`color`},focus:{value:`{core.white}`,type:`color`},disabled:{value:`{core.white}`,type:`color`}},sm:{value:`{spacing.6}`,type:`spacing`},md:{value:`{spacing.8}`,type:`spacing`},lg:{value:`{spacing.10}`,type:`spacing`},"border-width":{value:`{border.1}`,type:`borderWidth`}},invisible:{"background-color":{default:{value:`none`,type:`color`},hover:{value:`{grey.100}`,type:`color`},pressed:{value:`{grey.100}`,type:`color`},focus:{value:`none`,type:`color`},disabled:{value:`none`,type:`color`}},color:{default:{value:`{grey.500}`,type:`color`},hover:{value:`{grey.500}`,type:`color`},pressed:{value:`{grey.500}`,type:`color`},focus:{value:`{grey.500}`,type:`color`},disabled:{value:`{grey.100}`,type:`color`}},border:{default:{value:`none`,type:`color`},hover:{value:`none`,type:`color`},pressed:{value:`none`,type:`color`},focus:{value:`{blue.600}`,type:`color`},disabled:{value:`{grey.100}`,type:`color`}},"border-width":{default:{value:`none`,type:`borderWidth`},hover:{value:`none`,type:`borderWidth`},pressed:{value:`none`,type:`borderWidth`},focus:{value:`{border.1}`,type:`borderWidth`},disabled:{value:`{border.1}`,type:`borderWidth`}}},"border-radius":{value:`{rounded.base}`,type:`borderRadius`},"box-shadow":{default:{value:`{shadow.none}`,type:`boxShadow`},hover:{value:`{shadow.none}`,type:`boxShadow`},pressed:{value:`{shadow.inner}`,type:`boxShadow`},focus:{value:`none`,type:`boxShadow`},disabled:{value:`none`,type:`boxShadow`}}},breadcrumbs:{color:{"previous-page":{value:`{blue.500}`,type:`color`},divider:{value:`{grey.300}`,type:`color`},"current-page":{value:`{grey.500}`,type:`color`}},"font-family":{value:`{font-sans.inter}`,type:`fontFamilies`},"font-weight":{value:`{font.normal}`,type:`fontWeights`},"line-height":{value:`{leading.sm}`,type:`lineHeights`},"font-size":{value:`{text.sm}`,type:`fontSizes`}},"main-content":{sm:{value:`{spacing.32}`,type:`spacing`},base:{value:`{spacing.48}`,type:`spacing`},lg:{value:`{spacing.64}`,type:`spacing`}},"section-content":{none:{value:`{spacing.0}`,type:`spacing`},xs:{value:`{spacing.8}`,type:`spacing`},sm:{value:`{spacing.16}`,type:`spacing`},base:{value:`{spacing.24}`,type:`spacing`},lg:{value:`{spacing.32}`,type:`spacing`}}},$themes:[],$metadata:{tokenSetOrder:[`global`,`alias`]}},O={$schema:`http://json-schema.org/draft-07/schema#`,description:`Lista dei colori da includere nella safelist di Tailwind. Per aggiungere un nuovo colore, aggiungi il suo nome qui e rigenera il build con 'pnpm run build'.`,safeColorNames:[`blue`,`purple`,`orange`,`pink`,`yellow`,`grey`,`core`]},k={$schema:`http://json-schema.org/draft-07/schema#`,description:`Lista dei colori semantici da includere nella safelist di Tailwind. Per aggiungere un nuovo colore semantico, aggiungi il suo nome qui e rigenera il build con 'pnpm run build'.`,semanticColorNames:[`error`,`warning`,`success`,`info`]},A=O.safeColorNames,j=k.semanticColorNames,M={};A.forEach(e=>{let t=D.global[e];t&&Object.keys(t).forEach(n=>{let r=t[n]?.value;r&&(M[e]||(M[e]={}),M[e][n]=r)})});var N=D.global.semantic;N&&j.forEach(e=>{let t=N[e];t&&typeof t==`object`&&Object.keys(t).forEach(n=>{let r=t[n]?.value;if(r){let t=`semantic-${e}`;M[t]||(M[t]={}),M[t][n]=r}})});var P=Object.entries(D.global.breakpoint).reduce((e,[t,n])=>(e[t]=n.value,e),{});e.FzFloating=(0,t.defineComponent)({__name:`FzFloating`,props:{isOpen:{type:Boolean,default:!1},position:{default:`auto`},container:{},contentClass:{},openerClass:{},overrideContentClass:{type:Boolean},overrideOpener:{},teleport:{type:Boolean,default:!1},useViewport:{type:Boolean}},emits:[`fzfloating:setPosition`],setup(e,{expose:n,emit:r}){let i=e,a=r,o=(0,t.ref)(null),s=(0,t.ref)(null),c=(0,t.useSlots)(),l=x(`(max-width: ${P.xs})`),u=!1,d=!1,f=null,p=null,m={position:i.position,element:{domRef:o},container:{domRef:(0,t.toRef)(i.container||document.body)},opener:{domRef:(0,t.toRef)(null)},useViewport:i.useViewport,callback(...e){a(`fzfloating:setPosition`,...e)}},h=(0,t.toRefs)(m);c.opener&&(m.opener={domRef:s});let g=b(h),_=()=>{u||!d||(u=!0,requestAnimationFrame(()=>{d&&i.isOpen&&g.setPosition(),u=!1}))};(0,t.onMounted)(()=>{d=!0});let v=()=>{_()},y=()=>{_()},S=()=>{window.addEventListener(`scroll`,v,!0),window.addEventListener(`resize`,y),o.value&&!f&&(f=new ResizeObserver(()=>{_()}),f.observe(o.value)),s.value&&!p&&(p=new ResizeObserver(()=>{_()}),p.observe(s.value))},C=()=>{window.removeEventListener(`scroll`,v,!0),window.removeEventListener(`resize`,y),f&&=(f.disconnect(),null),p&&=(p.disconnect(),null)};(0,t.watch)(()=>i.position,()=>_()),(0,t.watch)(()=>i.isOpen,e=>{if(!e||!o.value||!d){C();return}S();let t=s.value?.getBoundingClientRect();o.value.style.position=`fixed`,o.value.style.top=`0px`,o.value.style.left=`0px`,o.value.style.transform=`none`,o.value.style.width=l.value?t?.width+`px`:`auto`,g.setPosition()}),(0,t.watch)(()=>i.overrideOpener,e=>{e&&h.opener&&h.opener.value&&(h.opener.value={domRef:e})}),(0,t.onBeforeUnmount)(()=>{d=!1,C()});let w=e=>e.startsWith(`bottom`)?`mt-4`:e.startsWith(`top`)?`mb-4`:e.startsWith(`left`)?`mr-4`:e.startsWith(`right`)?`ml-4`:`mt-4`,T=(0,t.computed)(()=>w(g.actualPosition?.value??i.position)),E=(0,t.computed)(()=>i.overrideContentClass?i.contentClass:[`bg-core-white fixed`,T.value,i.contentClass]);return n({setPosition:g.setPosition}),(n,r)=>((0,t.openBlock)(),(0,t.createElementBlock)(`div`,null,[(0,t.renderSlot)(n.$slots,`opener-start`),(0,t.createElementVNode)(`div`,{ref_key:`opener`,ref:s,class:`inline-flex w-full sm:w-auto`},[(0,t.renderSlot)(n.$slots,`opener`,{isOpen:e.isOpen,floating:(0,t.unref)(g)})],512),(0,t.renderSlot)(n.$slots,`opener-end`),e.teleport?(0,t.createCommentVNode)(``,!0):(0,t.withDirectives)(((0,t.openBlock)(),(0,t.createElementBlock)(`div`,{key:0,ref_key:`content`,ref:o,class:(0,t.normalizeClass)([`fz__floating__content w-full sm:w-auto`,E.value])},[(0,t.renderSlot)(n.$slots,`default`,{isOpen:e.isOpen,floating:(0,t.unref)(g)})],2)),[[t.vShow,n.$slots.default&&(!n.$slots.opener||n.$slots.opener&&e.isOpen)]]),e.teleport?((0,t.openBlock)(),(0,t.createBlock)(t.Teleport,{key:1,to:`body`},[(0,t.withDirectives)((0,t.createElementVNode)(`div`,{ref_key:`content`,ref:o,class:(0,t.normalizeClass)([`fz__floating__content`,E.value])},[(0,t.renderSlot)(n.$slots,`default`,{isOpen:e.isOpen,floating:(0,t.unref)(g)})],2),[[t.vShow,n.$slots.default&&(!n.$slots.opener||n.$slots.opener&&e.isOpen)]])])):(0,t.createCommentVNode)(``,!0)]))}}),e.calcRealPos=l,e.clamp=o,e.format=r,e.getHighestAvailableSpacePos=c,e.parse=i,e.roundTo=a,e.truncateDecimals=n,e.useBreakpoints=S,e.useClickOutside=C,e.useCurrency=E,e.useFloating=b,e.useKeyDown=w,e.useKeyUp=T,e.useMediaQuery=x});
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@fiscozen/composables",
3
- "version": "1.0.3",
3
+ "version": "1.1.0",
4
4
  "description": "Design System utility composables",
5
5
  "main": "src/index.ts",
6
6
  "type": "module",
7
7
  "keywords": [],
8
8
  "author": "Riccardo Agnoletto",
9
9
  "dependencies": {
10
- "@fiscozen/style": "0.3.0"
10
+ "@fiscozen/style": "0.4.0"
11
11
  },
12
12
  "peerDependencies": {
13
13
  "tailwindcss": "^3.4.1",
@@ -17,20 +17,20 @@
17
17
  "@rushstack/eslint-patch": "^1.3.3",
18
18
  "@types/jsdom": "^21.1.6",
19
19
  "@types/node": "^18.19.3",
20
- "@vitejs/plugin-vue": "^4.5.2",
21
- "@vitest/coverage-v8": "^1.2.1",
20
+ "@vitejs/plugin-vue": "^6.0.5",
21
+ "@vitest/coverage-v8": "^4.1.1",
22
22
  "@vue/test-utils": "^2.4.3",
23
23
  "@vue/tsconfig": "^0.5.0",
24
24
  "eslint": "^8.49.0",
25
25
  "jsdom": "^23.0.1",
26
26
  "prettier": "^3.0.3",
27
- "typescript": "~5.3.0",
28
- "vite": "^5.0.10",
29
- "vitest": "^1.2.0",
30
- "vue-tsc": "^1.8.25",
31
- "@fiscozen/tsconfig": "^0.1.0",
27
+ "typescript": "~5.7.0",
28
+ "vite": "^8.0.0",
29
+ "vitest": "^4.1.1",
30
+ "vue-tsc": "^2.2.12",
32
31
  "@fiscozen/prettier-config": "^0.1.0",
33
- "@fiscozen/eslint-config": "^0.1.0"
32
+ "@fiscozen/eslint-config": "^0.1.0",
33
+ "@fiscozen/tsconfig": "^0.1.0"
34
34
  },
35
35
  "license": "ISC",
36
36
  "scripts": {
@@ -19,11 +19,10 @@ const positions: FzFloatingPosition[] = [
19
19
  'right-end'
20
20
  ]
21
21
  beforeEach(() => {
22
- const mockIntersectionObserver = vi.fn()
23
- mockIntersectionObserver.mockReturnValue({
24
- observe: () => null,
25
- unobserve: () => null,
26
- disconnect: () => null
22
+ const mockIntersectionObserver = vi.fn().mockImplementation(function (this: any) {
23
+ this.observe = () => null
24
+ this.unobserve = () => null
25
+ this.disconnect = () => null
27
26
  })
28
27
  window.IntersectionObserver = mockIntersectionObserver
29
28
 
@@ -0,0 +1,153 @@
1
+ import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'
2
+ import { defineComponent, type ComputedRef } from 'vue'
3
+ import { mount } from '@vue/test-utils'
4
+ import { useBreakpoints } from '../composables/useBreakpoints'
5
+
6
+ const BREAKPOINTS = {
7
+ xs: '376px',
8
+ sm: '640px',
9
+ md: '768px',
10
+ lg: '1024px',
11
+ xl: '1280px',
12
+ '2xl': '1440px',
13
+ '3xl': '1536px'
14
+ } as const
15
+
16
+ const originalMatchMedia = window.matchMedia
17
+
18
+ // Controls what the mocked matchMedia reports as the current viewport width.
19
+ let viewportWidth = 1024
20
+
21
+ /**
22
+ * A matchMedia mock that actually evaluates `min-width` / `max-width` queries
23
+ * against `viewportWidth`, so the descending-priority resolution in `current()`
24
+ * is exercised for real instead of being short-circuited by a coarse stub.
25
+ */
26
+ function installMatchMedia() {
27
+ Object.defineProperty(window, 'matchMedia', {
28
+ writable: true,
29
+ configurable: true,
30
+ value: vi.fn((query: string) => {
31
+ const min = /min-width:\s*(\d+)px/.exec(query)
32
+ const max = /max-width:\s*(\d+)px/.exec(query)
33
+ let matches = true
34
+ if (min) matches = matches && viewportWidth >= parseInt(min[1], 10)
35
+ if (max) matches = matches && viewportWidth <= parseInt(max[1], 10)
36
+ return {
37
+ matches,
38
+ media: query,
39
+ onchange: null,
40
+ addListener: vi.fn(),
41
+ removeListener: vi.fn(),
42
+ addEventListener: vi.fn(),
43
+ removeEventListener: vi.fn(),
44
+ dispatchEvent: vi.fn()
45
+ }
46
+ })
47
+ })
48
+ }
49
+
50
+ /** Resolve `current()` at a given viewport width inside a mounted component. */
51
+ function currentAt(
52
+ width: number,
53
+ breakpoints: Record<string, `${number}px`> = BREAKPOINTS
54
+ ): string {
55
+ viewportWidth = width
56
+ let value = ''
57
+ const Cmp = defineComponent({
58
+ setup() {
59
+ const { current } = useBreakpoints(breakpoints)
60
+ const cur: ComputedRef<string> = current()
61
+ value = cur.value
62
+ return () => null
63
+ }
64
+ })
65
+ const wrapper = mount(Cmp)
66
+ const result = value
67
+ wrapper.unmount()
68
+ return result
69
+ }
70
+
71
+ describe('useBreakpoints', () => {
72
+ beforeEach(() => {
73
+ installMatchMedia()
74
+ })
75
+
76
+ afterEach(() => {
77
+ Object.defineProperty(window, 'matchMedia', {
78
+ writable: true,
79
+ configurable: true,
80
+ value: originalMatchMedia
81
+ })
82
+ })
83
+
84
+ describe('current()', () => {
85
+ it.each([
86
+ [376, 'xs'],
87
+ [639, 'xs'],
88
+ [640, 'sm'],
89
+ [767, 'sm'],
90
+ [768, 'md'],
91
+ [1023, 'md'],
92
+ [1024, 'lg'],
93
+ [1279, 'lg'],
94
+ [1280, 'xl'],
95
+ [1439, 'xl'],
96
+ [1440, '2xl'],
97
+ [1535, '2xl'],
98
+ [1536, '3xl'],
99
+ [1920, '3xl']
100
+ ])(
101
+ 'resolves to the largest breakpoint whose min-width is met (width %ipx -> %s)',
102
+ (width, expected) => {
103
+ expect(currentAt(width)).toBe(expected)
104
+ }
105
+ )
106
+
107
+ it('has boundary parity with a `>=` check (inclusive min-width)', () => {
108
+ // Exactly at the breakpoint value resolves to that breakpoint, matching
109
+ // the previous `viewportWidth >= parseInt(value)` behaviour.
110
+ expect(currentAt(640)).toBe('sm')
111
+ expect(currentAt(1024)).toBe('lg')
112
+ })
113
+
114
+ it('falls back to the smallest breakpoint below the first threshold', () => {
115
+ expect(currentAt(320)).toBe('xs')
116
+ expect(currentAt(0)).toBe('xs')
117
+ })
118
+
119
+ it('is independent of key order in the breakpoints object', () => {
120
+ const scrambled: Record<string, `${number}px`> = {
121
+ lg: '1024px',
122
+ xs: '376px',
123
+ '3xl': '1536px',
124
+ md: '768px',
125
+ sm: '640px',
126
+ xl: '1280px',
127
+ '2xl': '1440px'
128
+ }
129
+ expect(currentAt(1024, scrambled)).toBe('lg')
130
+ expect(currentAt(700, scrambled)).toBe('sm')
131
+ })
132
+ })
133
+
134
+ describe('isGreater / isSmaller / isInBetween', () => {
135
+ it('reports isGreater relative to a breakpoint', () => {
136
+ viewportWidth = 1280
137
+ let greaterThanLg = false
138
+ let greaterThan3xl = false
139
+ const Cmp = defineComponent({
140
+ setup() {
141
+ const { isGreater } = useBreakpoints(BREAKPOINTS)
142
+ greaterThanLg = isGreater('lg').value
143
+ greaterThan3xl = isGreater('3xl').value
144
+ return () => null
145
+ }
146
+ })
147
+ const wrapper = mount(Cmp)
148
+ expect(greaterThanLg).toBe(true)
149
+ expect(greaterThan3xl).toBe(false)
150
+ wrapper.unmount()
151
+ })
152
+ })
153
+ })
@@ -11,11 +11,10 @@ describe('useFloating', () => {
11
11
 
12
12
  beforeEach(() => {
13
13
  // Mock IntersectionObserver
14
- mockIntersectionObserver = vi.fn()
15
- mockIntersectionObserver.mockReturnValue({
16
- observe: vi.fn(),
17
- unobserve: vi.fn(),
18
- disconnect: vi.fn()
14
+ mockIntersectionObserver = vi.fn().mockImplementation(function (this: any) {
15
+ this.observe = vi.fn()
16
+ this.unobserve = vi.fn()
17
+ this.disconnect = vi.fn()
19
18
  })
20
19
  window.IntersectionObserver = mockIntersectionObserver
21
20
 
@@ -344,4 +343,36 @@ describe('useFloating', () => {
344
343
  expect(mockIntersectionObserver).toHaveBeenCalled()
345
344
  })
346
345
  })
346
+
347
+ describe('collapsed opener', () => {
348
+ it('should hide the element when the opener has a zero-size rect', async () => {
349
+ // Simulate the opener living inside a collapsed accordion: a hidden element
350
+ // reports an all-zero bounding rect.
351
+ mockOpener.getBoundingClientRect = vi.fn(() => ({
352
+ width: 0,
353
+ height: 0,
354
+ top: 0,
355
+ left: 0,
356
+ right: 0,
357
+ bottom: 0,
358
+ x: 0,
359
+ y: 0,
360
+ toJSON: () => {}
361
+ })) as any
362
+
363
+ const args = toRefs({
364
+ position: ref<FzFloatingPosition>('bottom'),
365
+ element: { domRef: ref(mockElement) },
366
+ opener: { domRef: ref(mockOpener) },
367
+ container: { domRef: ref(mockContainer) }
368
+ })
369
+
370
+ const floating = useFloating(args)
371
+ await floating.setPosition()
372
+ await nextTick()
373
+
374
+ // Must NOT jump to the top-left corner; the floating content is hidden instead.
375
+ expect(mockElement.style.display).toBe('none')
376
+ })
377
+ })
347
378
  })
@@ -1,3 +1,4 @@
1
+ import { computed, type ComputedRef } from 'vue'
1
2
  import { useMediaQuery } from './useMediaQuery'
2
3
 
3
4
  function useBreakpoints<T extends string>(breakpoints: Record<T, `${number}px`>) {
@@ -10,6 +11,34 @@ function useBreakpoints<T extends string>(breakpoints: Record<T, `${number}px`>)
10
11
  },
11
12
  isInBetween(min: T, max: T) {
12
13
  return useMediaQuery(`(min-width: ${breakpoints[min]}) and (max-width: ${breakpoints[max]})`)
14
+ },
15
+ /**
16
+ * Reactive name of the largest breakpoint whose `min-width` is currently
17
+ * matched. Descending priority with an inclusive `min-width`, giving
18
+ * boundary-parity with a `viewportWidth >= breakpointValue` check.
19
+ *
20
+ * Resolution is independent of the order keys appear in `breakpoints`
21
+ * (they are sorted ascending by pixel value first). When the viewport is
22
+ * narrower than every defined breakpoint it falls back to the smallest one,
23
+ * so the result is always a valid breakpoint name.
24
+ */
25
+ current(): ComputedRef<T> {
26
+ const ordered = (Object.entries(breakpoints) as [T, `${number}px`][])
27
+ .map(([name, value]) => ({ name, value: parseInt(value, 10) }))
28
+ .sort((a, b) => a.value - b.value)
29
+
30
+ const matchers = ordered.map(({ name, value }) => ({
31
+ name,
32
+ matches: useMediaQuery(`(min-width: ${value}px)`)
33
+ }))
34
+
35
+ return computed(() => {
36
+ let result = ordered[0].name
37
+ for (const { name, matches } of matchers) {
38
+ if (matches.value) result = name
39
+ }
40
+ return result
41
+ })
13
42
  }
14
43
  }
15
44
  }
@@ -115,6 +115,12 @@ const getMargins = (style: CSSStyleDeclaration): Margins => ({
115
115
  bottom: parseFloat(style.marginBottom)
116
116
  })
117
117
 
118
+ // An element hidden via display:none (e.g. an opener inside a collapsed accordion)
119
+ // reports an all-zero bounding rect. Anchoring to it would place the floating content
120
+ // at the viewport's top-left corner, so a zero-size opener is treated as not positionable.
121
+ const isRectPositionable = (rect: DOMRect | null): boolean =>
122
+ rect !== null && (rect.width > 0 || rect.height > 0)
123
+
118
124
  // ============================================================================
119
125
  // Position Calculators WITH Opener - Lookup Table
120
126
  // Each calculator receives opener rect and element margins for consistent spacing
@@ -517,6 +523,14 @@ export const useFloating = (
517
523
  openerRect.value = rects.opener ?? undefined
518
524
  containerRect.value = rects.container
519
525
 
526
+ // Step 4b: If an opener is expected but currently hidden (zero-size rect, e.g. its
527
+ // accordion collapsed while the floating was still open), don't anchor to (0,0) and
528
+ // jump to the top-left corner — hide the floating content instead.
529
+ if (refs.opener && !isRectPositionable(rects.opener)) {
530
+ refs.element.style.display = 'none'
531
+ return
532
+ }
533
+
520
534
  // Step 5: Setup observers
521
535
  floatObserver.value.observe(refs.element)
522
536
  floatObserver.value.observe(refs.container)