splitpanes.DuIxzowM.js 11 KB

1
  1. import{ai as m,c as u,o as c,E as z,F as x}from"./vue.D1BjjNmv.js";const M={name:"splitpanes",emits:["ready","resize","resized","pane-click","pane-maximize","pane-add","pane-remove","splitter-click"],props:{horizontal:{type:Boolean},pushOtherPanes:{type:Boolean,default:!0},dblClickSplitter:{type:Boolean,default:!0},rtl:{type:Boolean,default:!1},firstSplitter:{type:Boolean}},provide(){return{requestUpdate:this.requestUpdate,onPaneAdd:this.onPaneAdd,onPaneRemove:this.onPaneRemove,onPaneClick:this.onPaneClick}},data:()=>({container:null,ready:!1,panes:[],touch:{mouseDown:!1,dragging:!1,activeSplitter:null},splitterTaps:{splitter:null,timeoutId:null}}),computed:{panesCount(){return this.panes.length},indexedPanes(){return this.panes.reduce((e,s)=>(e[s.id]=s)&&e,{})}},methods:{updatePaneComponents(){this.panes.forEach(e=>{e.update&&e.update({[this.horizontal?"height":"width"]:`${this.indexedPanes[e.id].size}%`})})},bindEvents(){document.addEventListener("mousemove",this.onMouseMove,{passive:!1}),document.addEventListener("mouseup",this.onMouseUp),"ontouchstart"in window&&(document.addEventListener("touchmove",this.onMouseMove,{passive:!1}),document.addEventListener("touchend",this.onMouseUp))},unbindEvents(){document.removeEventListener("mousemove",this.onMouseMove,{passive:!1}),document.removeEventListener("mouseup",this.onMouseUp),"ontouchstart"in window&&(document.removeEventListener("touchmove",this.onMouseMove,{passive:!1}),document.removeEventListener("touchend",this.onMouseUp))},onMouseDown(e,s){this.bindEvents(),this.touch.mouseDown=!0,this.touch.activeSplitter=s},onMouseMove(e){this.touch.mouseDown&&(e.preventDefault(),this.touch.dragging=!0,this.calculatePanesSize(this.getCurrentMouseDrag(e)),this.$emit("resize",this.panes.map(s=>({min:s.min,max:s.max,size:s.size}))))},onMouseUp(){this.touch.dragging&&this.$emit("resized",this.panes.map(e=>({min:e.min,max:e.max,size:e.size}))),this.touch.mouseDown=!1,setTimeout(()=>{this.touch.dragging=!1,this.unbindEvents()},100)},onSplitterClick(e,s){"ontouchstart"in window&&(e.preventDefault(),this.dblClickSplitter&&(this.splitterTaps.splitter===s?(clearTimeout(this.splitterTaps.timeoutId),this.splitterTaps.timeoutId=null,this.onSplitterDblClick(e,s),this.splitterTaps.splitter=null):(this.splitterTaps.splitter=s,this.splitterTaps.timeoutId=setTimeout(()=>{this.splitterTaps.splitter=null},500)))),this.touch.dragging||this.$emit("splitter-click",this.panes[s])},onSplitterDblClick(e,s){let n=0;this.panes=this.panes.map((t,i)=>(t.size=i===s?t.max:t.min,i!==s&&(n+=t.min),t)),this.panes[s].size-=n,this.$emit("pane-maximize",this.panes[s]),this.$emit("resized",this.panes.map(t=>({min:t.min,max:t.max,size:t.size})))},onPaneClick(e,s){this.$emit("pane-click",this.indexedPanes[s])},getCurrentMouseDrag(e){const s=this.container.getBoundingClientRect(),{clientX:n,clientY:t}="ontouchstart"in window&&e.touches?e.touches[0]:e;return{x:n-s.left,y:t-s.top}},getCurrentDragPercentage(e){e=e[this.horizontal?"y":"x"];const s=this.container[this.horizontal?"clientHeight":"clientWidth"];return this.rtl&&!this.horizontal&&(e=s-e),e*100/s},calculatePanesSize(e){const s=this.touch.activeSplitter;let n={prevPanesSize:this.sumPrevPanesSize(s),nextPanesSize:this.sumNextPanesSize(s),prevReachedMinPanes:0,nextReachedMinPanes:0};const t=0+(this.pushOtherPanes?0:n.prevPanesSize),i=100-(this.pushOtherPanes?0:n.nextPanesSize),a=Math.max(Math.min(this.getCurrentDragPercentage(e),i),t);let o=[s,s+1],h=this.panes[o[0]]||null,r=this.panes[o[1]]||null;const p=h.max<100&&a>=h.max+n.prevPanesSize,d=r.max<100&&a<=100-(r.max+this.sumNextPanesSize(s+1));if(p||d){p?(h.size=h.max,r.size=Math.max(100-h.max-n.prevPanesSize-n.nextPanesSize,0)):(h.size=Math.max(100-r.max-n.prevPanesSize-this.sumNextPanesSize(s+1),0),r.size=r.max);return}if(this.pushOtherPanes){const l=this.doPushOtherPanes(n,a);if(!l)return;({sums:n,panesToResize:o}=l),h=this.panes[o[0]]||null,r=this.panes[o[1]]||null}h!==null&&(h.size=Math.min(Math.max(a-n.prevPanesSize-n.prevReachedMinPanes,h.min),h.max)),r!==null&&(r.size=Math.min(Math.max(100-a-n.nextPanesSize-n.nextReachedMinPanes,r.min),r.max))},doPushOtherPanes(e,s){const n=this.touch.activeSplitter,t=[n,n+1];return s<e.prevPanesSize+this.panes[t[0]].min&&(t[0]=this.findPrevExpandedPane(n).index,e.prevReachedMinPanes=0,t[0]<n&&this.panes.forEach((i,a)=>{a>t[0]&&a<=n&&(i.size=i.min,e.prevReachedMinPanes+=i.min)}),e.prevPanesSize=this.sumPrevPanesSize(t[0]),t[0]===void 0)?(e.prevReachedMinPanes=0,this.panes[0].size=this.panes[0].min,this.panes.forEach((i,a)=>{a>0&&a<=n&&(i.size=i.min,e.prevReachedMinPanes+=i.min)}),this.panes[t[1]].size=100-e.prevReachedMinPanes-this.panes[0].min-e.prevPanesSize-e.nextPanesSize,null):s>100-e.nextPanesSize-this.panes[t[1]].min&&(t[1]=this.findNextExpandedPane(n).index,e.nextReachedMinPanes=0,t[1]>n+1&&this.panes.forEach((i,a)=>{a>n&&a<t[1]&&(i.size=i.min,e.nextReachedMinPanes+=i.min)}),e.nextPanesSize=this.sumNextPanesSize(t[1]-1),t[1]===void 0)?(e.nextReachedMinPanes=0,this.panes[this.panesCount-1].size=this.panes[this.panesCount-1].min,this.panes.forEach((i,a)=>{a<this.panesCount-1&&a>=n+1&&(i.size=i.min,e.nextReachedMinPanes+=i.min)}),this.panes[t[0]].size=100-e.prevPanesSize-e.nextReachedMinPanes-this.panes[this.panesCount-1].min-e.nextPanesSize,null):{sums:e,panesToResize:t}},sumPrevPanesSize(e){return this.panes.reduce((s,n,t)=>s+(t<e?n.size:0),0)},sumNextPanesSize(e){return this.panes.reduce((s,n,t)=>s+(t>e+1?n.size:0),0)},findPrevExpandedPane(e){return[...this.panes].reverse().find(s=>s.index<e&&s.size>s.min)||{}},findNextExpandedPane(e){return this.panes.find(s=>s.index>e+1&&s.size>s.min)||{}},checkSplitpanesNodes(){Array.from(this.container.children).forEach(e=>{const s=e.classList.contains("splitpanes__pane"),n=e.classList.contains("splitpanes__splitter");!s&&!n&&(e.parentNode.removeChild(e),console.warn("Splitpanes: Only <pane> elements are allowed at the root of <splitpanes>. One of your DOM nodes was removed."))})},addSplitter(e,s,n=!1){const t=e-1,i=document.createElement("div");i.classList.add("splitpanes__splitter"),n||(i.onmousedown=a=>this.onMouseDown(a,t),typeof window<"u"&&"ontouchstart"in window&&(i.ontouchstart=a=>this.onMouseDown(a,t)),i.onclick=a=>this.onSplitterClick(a,t+1)),this.dblClickSplitter&&(i.ondblclick=a=>this.onSplitterDblClick(a,t+1)),s.parentNode.insertBefore(i,s)},removeSplitter(e){e.onmousedown=void 0,e.onclick=void 0,e.ondblclick=void 0,e.parentNode.removeChild(e)},redoSplitters(){const e=Array.from(this.container.children);e.forEach(n=>{n.className.includes("splitpanes__splitter")&&this.removeSplitter(n)});let s=0;e.forEach(n=>{n.className.includes("splitpanes__pane")&&(!s&&this.firstSplitter?this.addSplitter(s,n,!0):s&&this.addSplitter(s,n),s++)})},requestUpdate({target:e,...s}){const n=this.indexedPanes[e._.uid];Object.entries(s).forEach(([t,i])=>n[t]=i)},onPaneAdd(e){let s=-1;Array.from(e.$el.parentNode.children).some(i=>(i.className.includes("splitpanes__pane")&&s++,i===e.$el));const n=parseFloat(e.minSize),t=parseFloat(e.maxSize);this.panes.splice(s,0,{id:e._.uid,index:s,min:isNaN(n)?0:n,max:isNaN(t)?100:t,size:e.size===null?null:parseFloat(e.size),givenSize:e.size,update:e.update}),this.panes.forEach((i,a)=>i.index=a),this.ready&&this.$nextTick(()=>{this.redoSplitters(),this.resetPaneSizes({addedPane:this.panes[s]}),this.$emit("pane-add",{index:s,panes:this.panes.map(i=>({min:i.min,max:i.max,size:i.size}))})})},onPaneRemove(e){const s=this.panes.findIndex(t=>t.id===e._.uid),n=this.panes.splice(s,1)[0];this.panes.forEach((t,i)=>t.index=i),this.$nextTick(()=>{this.redoSplitters(),this.resetPaneSizes({removedPane:{...n,index:s}}),this.$emit("pane-remove",{removed:n,panes:this.panes.map(t=>({min:t.min,max:t.max,size:t.size}))})})},resetPaneSizes(e={}){!e.addedPane&&!e.removedPane?this.initialPanesSizing():this.panes.some(s=>s.givenSize!==null||s.min||s.max<100)?this.equalizeAfterAddOrRemove(e):this.equalize(),this.ready&&this.$emit("resized",this.panes.map(s=>({min:s.min,max:s.max,size:s.size})))},equalize(){const e=100/this.panesCount;let s=0;const n=[],t=[];this.panes.forEach(i=>{i.size=Math.max(Math.min(e,i.max),i.min),s-=i.size,i.size>=i.max&&n.push(i.id),i.size<=i.min&&t.push(i.id)}),s>.1&&this.readjustSizes(s,n,t)},initialPanesSizing(){let e=100;const s=[],n=[];let t=0;this.panes.forEach(a=>{e-=a.size,a.size!==null&&t++,a.size>=a.max&&s.push(a.id),a.size<=a.min&&n.push(a.id)});let i=100;e>.1&&(this.panes.forEach(a=>{a.size===null&&(a.size=Math.max(Math.min(e/(this.panesCount-t),a.max),a.min)),i-=a.size}),i>.1&&this.readjustSizes(e,s,n))},equalizeAfterAddOrRemove({addedPane:e,removedPane:s}={}){let n=100/this.panesCount,t=0;const i=[],a=[];e&&e.givenSize!==null&&(n=(100-e.givenSize)/(this.panesCount-1)),this.panes.forEach(o=>{t-=o.size,o.size>=o.max&&i.push(o.id),o.size<=o.min&&a.push(o.id)}),!(Math.abs(t)<.1)&&(this.panes.forEach(o=>{e&&e.givenSize!==null&&e.id===o.id||(o.size=Math.max(Math.min(n,o.max),o.min)),t-=o.size,o.size>=o.max&&i.push(o.id),o.size<=o.min&&a.push(o.id)}),t>.1&&this.readjustSizes(t,i,a))},readjustSizes(e,s,n){let t;e>0?t=e/(this.panesCount-s.length):t=e/(this.panesCount-n.length),this.panes.forEach((i,a)=>{if(e>0&&!s.includes(i.id)){const o=Math.max(Math.min(i.size+t,i.max),i.min),h=o-i.size;e-=h,i.size=o}else if(!n.includes(i.id)){const o=Math.max(Math.min(i.size+t,i.max),i.min),h=o-i.size;e-=h,i.size=o}i.update({[this.horizontal?"height":"width"]:`${this.indexedPanes[i.id].size}%`})}),Math.abs(e)>.1&&this.$nextTick(()=>{this.ready&&console.warn("Splitpanes: Could not resize panes correctly due to their constraints.")})}},watch:{panes:{deep:!0,immediate:!1,handler(){this.updatePaneComponents()}},horizontal(){this.updatePaneComponents()},firstSplitter(){this.redoSplitters()},dblClickSplitter(e){[...this.container.querySelectorAll(".splitpanes__splitter")].forEach((s,n)=>{s.ondblclick=e?t=>this.onSplitterDblClick(t,n):void 0})}},beforeUnmount(){this.ready=!1},mounted(){this.container=this.$refs.container,this.checkSplitpanesNodes(),this.redoSplitters(),this.resetPaneSizes(),this.$emit("ready"),this.ready=!0},render(){return m("div",{ref:"container",class:["splitpanes",`splitpanes--${this.horizontal?"horizontal":"vertical"}`,{"splitpanes--dragging":this.touch.dragging}]},this.$slots.default())}},P=(e,s)=>{const n=e.__vccOpts||e;for(const[t,i]of s)n[t]=i;return n},v={name:"pane",inject:["requestUpdate","onPaneAdd","onPaneRemove","onPaneClick"],props:{size:{type:[Number,String],default:null},minSize:{type:[Number,String],default:0},maxSize:{type:[Number,String],default:100}},data:()=>({style:{}}),mounted(){this.onPaneAdd(this)},beforeUnmount(){this.onPaneRemove(this)},methods:{update(e){this.style=e}},computed:{sizeNumber(){return this.size||this.size===0?parseFloat(this.size):null},minSizeNumber(){return parseFloat(this.minSize)},maxSizeNumber(){return parseFloat(this.maxSize)}},watch:{sizeNumber(e){this.requestUpdate({target:this,size:e})},minSizeNumber(e){this.requestUpdate({target:this,min:e})},maxSizeNumber(e){this.requestUpdate({target:this,max:e})}}};function S(e,s,n,t,i,a){return c(),u("div",{class:"splitpanes__pane",onClick:s[0]||(s[0]=o=>a.onPaneClick(o,e._.uid)),style:x(e.style)},[z(e.$slots,"default")],4)}const g=P(v,[["render",S]]);export{M,g};