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