@kong/splitpanes
Version:
A Vue.js reliable, simple and touch-ready panes splitter / resizer
2 lines (1 loc) • 9.74 kB
JavaScript
;Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const l=require("vue"),ee={__name:"splitpanes",props:{horizontal:{type:Boolean},pushOtherPanes:{type:Boolean,default:!0},dblClickSplitter:{type:Boolean,default:!0},rtl:{type:Boolean,default:!1},firstSplitter:{type:Boolean}},emits:["ready","resize","resized","pane-click","pane-maximize","pane-add","pane-remove","splitter-click"],setup(N,{emit:S}){const d=S,c=N,M=l.useSlots(),s=l.ref([]),f=l.computed(()=>s.value.length),h=l.computed(()=>s.value.reduce((e,i)=>(e[~~i.id]=i)&&e,{})),x=l.ref(null),P=l.ref(!1),m=l.ref({mouseDown:!1,dragging:!1,activeSplitter:null}),z=l.ref({splitter:null,timeoutId:null}),E=()=>{document.addEventListener("mousemove",g,{passive:!1}),document.addEventListener("mouseup",u),"ontouchstart"in window&&(document.addEventListener("touchmove",g,{passive:!1}),document.addEventListener("touchend",u))},w=()=>{document.removeEventListener("mousemove",g,{passive:!1}),document.removeEventListener("mouseup",u),"ontouchstart"in window&&(document.removeEventListener("touchmove",g,{passive:!1}),document.removeEventListener("touchend",u))},y=(e,i)=>{E(),m.value.dragging=!0,m.value.mouseDown=!0,m.value.activeSplitter=i},g=e=>{m.value.mouseDown&&(e.preventDefault(),m.value.dragging=!0,U(T(e)),d("resize",s.value.map(i=>({min:i.min,max:i.max,size:i.size}))))},u=()=>{m.value.dragging&&d("resized",s.value.map(e=>({min:e.min,max:e.max,size:e.size}))),m.value.mouseDown=!1,setTimeout(()=>{m.value.dragging=!1,w()},100)},_=(e,i)=>{"ontouchstart"in window&&(e.preventDefault(),c.dblClickSplitter&&(z.value.splitter===i?(clearTimeout(z.value.timeoutId),z.value.timeoutId=null,k(e,i),z.value.splitter=null):(z.value.splitter=i,z.value.timeoutId=setTimeout(()=>{z.value.splitter=null},500)))),m.value.dragging||d("splitter-click",s.value[i])},k=(e,i)=>{let t=0;s.value=s.value.map((n,a)=>(n.size=a===i?n.max:n.min,a!==i&&(t+=n.min),n)),s.value[i].size-=t,d("pane-maximize",s.value[i]),d("resized",s.value.map(n=>({min:n.min,max:n.max,size:n.size})))},O=(e,i)=>{d("pane-click",h.value[i])},T=e=>{const i=x.value.getBoundingClientRect(),{clientX:t,clientY:n}="ontouchstart"in window&&e.touches?e.touches[0]:e;return{x:t-i.left,y:n-i.top}},j=e=>{e=e[c.horizontal?"y":"x"];const i=x.value[c.horizontal?"clientHeight":"clientWidth"];return c.rtl&&!c.horizontal&&(e=i-e),e*100/i},U=e=>{const i=m.value.activeSplitter;let t={prevPanesSize:D(i),nextPanesSize:b(i),prevReachedMinPanes:0,nextReachedMinPanes:0};const n=0+(c.pushOtherPanes?0:t.prevPanesSize),a=100-(c.pushOtherPanes?0:t.nextPanesSize),o=Math.max(Math.min(j(e),a),n);let r=[i,i+1],v=s.value[r[0]]||null,p=s.value[r[1]]||null;const A=v.max<100&&o>=v.max+t.prevPanesSize,Z=p.max<100&&o<=100-(p.max+b(i+1));if(A||Z){A?(v.size=v.max,p.size=Math.max(100-v.max-t.prevPanesSize-t.nextPanesSize,0)):(v.size=Math.max(100-p.max-t.prevPanesSize-b(i+1),0),p.size=p.max);return}if(c.pushOtherPanes){const L=$(t,o);if(!L)return;({sums:t,panesToResize:r}=L),v=s.value[r[0]]||null,p=s.value[r[1]]||null}v!==null&&(v.size=Math.min(Math.max(o-t.prevPanesSize-t.prevReachedMinPanes,v.min),v.max)),p!==null&&(p.size=Math.min(Math.max(100-o-t.nextPanesSize-t.nextReachedMinPanes,p.min),p.max))},$=(e,i)=>{const t=m.value.activeSplitter,n=[t,t+1];return i<e.prevPanesSize+s.value[n[0]].min&&(n[0]=I(t).index,e.prevReachedMinPanes=0,n[0]<t&&s.value.forEach((a,o)=>{o>n[0]&&o<=t&&(a.size=a.min,e.prevReachedMinPanes+=a.min)}),e.prevPanesSize=D(n[0]),n[0]===void 0)?(e.prevReachedMinPanes=0,s.value[0].size=s.value[0].min,s.value.forEach((a,o)=>{o>0&&o<=t&&(a.size=a.min,e.prevReachedMinPanes+=a.min)}),s.value[n[1]].size=100-e.prevReachedMinPanes-s.value[0].min-e.prevPanesSize-e.nextPanesSize,null):i>100-e.nextPanesSize-s.value[n[1]].min&&(n[1]=F(t).index,e.nextReachedMinPanes=0,n[1]>t+1&&s.value.forEach((a,o)=>{o>t&&o<n[1]&&(a.size=a.min,e.nextReachedMinPanes+=a.min)}),e.nextPanesSize=b(n[1]-1),n[1]===void 0)?(e.nextReachedMinPanes=0,s.value[f.value-1].size=s.value[f.value-1].min.value,s.value.forEach((a,o)=>{o<f.value-1&&o>=t+1&&(a.size=a.min,e.nextReachedMinPanes+=a.min)}),s.value[n[0]].size=100-e.prevPanesSize-e.nextReachedMinPanes-s.value[f.value-1].min-e.nextPanesSize.value,null):{sums:e,panesToResize:n}},D=e=>s.value.reduce((i,t,n)=>i+(n<e?t.size:0),0),b=e=>s.value.reduce((i,t,n)=>i+(n>e+1?t.size:0),0),I=e=>[...s.value].reverse().find(t=>t.index<e&&t.size>t.min)||{},F=e=>s.value.find(t=>t.index>e+1&&t.size>t.min)||{},H=()=>{var i;Array.from(((i=x.value)==null?void 0:i.children)||[]).forEach(t=>{const n=t.classList.contains("splitpanes__pane"),a=t.classList.contains("splitpanes__splitter");!n&&!a&&(t.remove(),console.warn("Splitpanes: Only <pane> elements are allowed at the root of <splitpanes>. One of your DOM nodes was removed."))})},q=(e,i,t=!1)=>{const n=e-1,a=document.createElement("div");a.classList.add("splitpanes__splitter"),t||(a.onmousedown=o=>y(o,n),typeof window<"u"&&"ontouchstart"in window&&(a.ontouchstart=o=>y(o,n)),a.onclick=o=>_(o,n+1)),c.dblClickSplitter&&(a.ondblclick=o=>k(o,n+1)),i.parentNode.insertBefore(a,i)},G=e=>{e.onmousedown=void 0,e.onclick=void 0,e.ondblclick=void 0,e.remove()},R=()=>{var t;const e=Array.from(((t=x.value)==null?void 0:t.children)||[]);e.forEach(n=>{n.className.includes("splitpanes__splitter")&&G(n)});let i=0;e.forEach(n=>{n.className.includes("splitpanes__pane")&&(!i&&c.firstSplitter?q(i,n,!0):i&&q(i,n),i++)})},W=({uid:e,...i})=>{const t=h.value[e];Object.entries(i).forEach(([n,a])=>t[n]=a)},X=e=>{var t;let i=-1;Array.from(((t=x.value)==null?void 0:t.children)||[]).some(n=>(n.className.includes("splitpanes__pane")&&i++,n.isSameNode(e.el))),s.value.splice(i,0,{...e,index:i}),s.value.forEach((n,a)=>n.index=a),P.value&&l.nextTick(()=>{R(),C({addedPane:s.value[i]}),d("pane-add",{index:i,panes:s.value.map(n=>({min:n.min,max:n.max,size:n.size}))})})},Y=e=>{const i=s.value.findIndex(n=>n.id===e),t=s.value.splice(i,1)[0];s.value.forEach((n,a)=>n.index=a),l.nextTick(()=>{R(),C({removedPane:{...t,index:i}}),d("pane-remove",{removed:t,panes:s.value.map(n=>({min:n.min,max:n.max,size:n.size}))})})},C=(e={})=>{!e.addedPane&&!e.removedPane?K():s.value.some(i=>i.givenSize!==null||i.min||i.max<100)?Q(e):J(),P.value&&d("resized",s.value.map(i=>({min:i.min,max:i.max,size:i.size})))},J=()=>{const e=100/f.value;let i=0;const t=[],n=[];s.value.forEach(a=>{a.size=Math.max(Math.min(e,a.max),a.min),i-=a.size,a.size>=a.max&&t.push(a.id),a.size<=a.min&&n.push(a.id)}),i>.1&&B(i,t,n)},K=()=>{let e=100;const i=[],t=[];let n=0;s.value.forEach(o=>{e-=o.size,o.givenSize!==null&&n++,o.size>=o.max&&i.push(o.id),o.size<=o.min&&t.push(o.id)});let a=100;e>.1&&(s.value.forEach(o=>{o.givenSize===null&&(o.size=Math.max(Math.min(e/(f.value-n),o.max),o.min)),a-=o.size}),a>.1&&B(a,i,t))},Q=({addedPane:e,removedPane:i}={})=>{let t=100/f.value,n=0;const a=[],o=[];(e==null?void 0:e.givenSize)!==null&&(t=(100-e.givenSize)/(f.value-1).value),s.value.forEach(r=>{n-=r.size,r.size>=r.max&&a.push(r.id),r.size<=r.min&&o.push(r.id)}),!(Math.abs(n)<.1)&&(s.value.forEach(r=>{(e==null?void 0:e.givenSize)!==null&&(e==null?void 0:e.id)===r.id||(r.size=Math.max(Math.min(t,r.max),r.min)),n-=r.size,r.size>=r.max&&a.push(r.id),r.size<=r.min&&o.push(r.id)}),n>.1&&B(n,a,o))},B=(e,i,t)=>{let n;e>0?n=e/(f.value-i.length):n=e/(f.value-t.length),s.value.forEach((a,o)=>{if(e>0&&!i.includes(a.id)){const r=Math.max(Math.min(a.size+n,a.max),a.min),v=r-a.size;e-=v,a.size=r}else if(!t.includes(a.id)){const r=Math.max(Math.min(a.size+n,a.max),a.min),v=r-a.size;e-=v,a.size=r}}),Math.abs(e)>.1&&l.nextTick(()=>{P.value&&console.warn("Splitpanes: Could not resize panes correctly due to their constraints.")})};l.watch(()=>c.firstSplitter,()=>R()),l.watch(()=>c.dblClickSplitter,e=>{[...x.value.querySelectorAll(".splitpanes__splitter")].forEach((t,n)=>{t.ondblclick=e?a=>k(a,n):void 0})}),l.onBeforeUnmount(()=>P.value=!1),l.onMounted(()=>{H(),R(),C(),d("ready"),P.value=!0});const V=()=>{var e;return l.h("div",{ref:x,class:["splitpanes",`splitpanes--${c.horizontal?"horizontal":"vertical"}`,{"splitpanes--dragging":m.value.dragging}]},(e=M.default)==null?void 0:e.call(M))};return l.provide("panes",s),l.provide("indexedPanes",h),l.provide("horizontal",l.computed(()=>c.horizontal)),l.provide("requestUpdate",W),l.provide("onPaneAdd",X),l.provide("onPaneRemove",Y),l.provide("onPaneClick",O),(e,i)=>(l.openBlock(),l.createBlock(l.resolveDynamicComponent(V)))}},ie={__name:"pane",props:{size:{type:[Number,String]},minSize:{type:[Number,String],default:0},maxSize:{type:[Number,String],default:100}},setup(N){var g;const S=N,d=l.inject("requestUpdate"),c=l.inject("onPaneAdd"),M=l.inject("horizontal"),s=l.inject("onPaneRemove"),f=l.inject("onPaneClick"),h=(g=l.getCurrentInstance())==null?void 0:g.uid,x=l.inject("indexedPanes"),P=l.computed(()=>x.value[h]),m=l.ref(null),z=l.computed(()=>{const u=isNaN(S.size)||S.size===void 0?0:parseFloat(S.size);return Math.max(Math.min(u,w.value),E.value)}),E=l.computed(()=>{const u=parseFloat(S.minSize);return isNaN(u)?0:u}),w=l.computed(()=>{const u=parseFloat(S.maxSize);return isNaN(u)?100:u}),y=l.computed(()=>{var u;return`${M.value?"height":"width"}: ${(u=P.value)==null?void 0:u.size}%`});return l.onMounted(()=>{c({id:h,el:m.value,min:E.value,max:w.value,givenSize:S.size===void 0?null:z.value,size:z.value})}),l.watch(()=>z.value,u=>d({uid:h,size:u})),l.watch(()=>E.value,u=>d({uid:h,min:u})),l.watch(()=>w.value,u=>d({uid:h,max:u})),l.onBeforeUnmount(()=>s(h)),(u,_)=>(l.openBlock(),l.createElementBlock("div",{ref_key:"paneEl",ref:m,class:"splitpanes__pane",onClick:_[0]||(_[0]=k=>l.unref(f)(k,u._.uid)),style:l.normalizeStyle(y.value)},[l.renderSlot(u.$slots,"default")],4))}};exports.Pane=ie;exports.Splitpanes=ee;