forked from opentiny/tiny-engine
687 lines
22 KiB
Vue
687 lines
22 KiB
Vue
<script>
|
|
import { h } from 'vue'
|
|
|
|
export default {
|
|
name: 'Splitpanes',
|
|
|
|
provide() {
|
|
return {
|
|
onPaneClick: this.onPaneClick,
|
|
onPaneAdd: this.onPaneAdd,
|
|
requestUpdate: this.requestUpdate,
|
|
onPaneRemove: this.onPaneRemove
|
|
}
|
|
},
|
|
|
|
props: {
|
|
horizontal: { type: Boolean },
|
|
pushOtherPanes: { type: Boolean, default: true },
|
|
dblClickSplitter: { type: Boolean, default: true },
|
|
rtl: { type: Boolean, default: false },
|
|
firstSplitter: { type: Boolean }
|
|
},
|
|
emits: ['ready', 'resize', 'resized', 'pane-click', 'pane-maximize', 'pane-add', 'pane-remove', 'splitter-click'],
|
|
|
|
data: () => ({
|
|
ready: false,
|
|
container: null,
|
|
touch: {
|
|
dragging: false,
|
|
activeSplitter: null,
|
|
mouseDown: false
|
|
},
|
|
panes: [],
|
|
lowcodeSplitterTaps: {
|
|
timeoutId: null,
|
|
splitter: null
|
|
}
|
|
}),
|
|
|
|
computed: {
|
|
indexedPanes() {
|
|
return this.panes.reduce((obj, pane) => {
|
|
obj[pane.id] = pane
|
|
return obj
|
|
}, {})
|
|
},
|
|
panesCount() {
|
|
return this.panes.length
|
|
}
|
|
},
|
|
|
|
watch: {
|
|
horizontal() {
|
|
this.updateLowCodePaneComponents()
|
|
},
|
|
panes: {
|
|
deep: true,
|
|
immediate: false,
|
|
handler() {
|
|
this.updateLowCodePaneComponents()
|
|
}
|
|
},
|
|
firstSplitter() {
|
|
this.redoLowCodeSplitters()
|
|
},
|
|
dblClickSplitter(enable) {
|
|
const splitters = [...this.container.querySelectorAll('.splitpanes-lowcode__splitter')]
|
|
splitters.forEach((item, i) => {
|
|
item.ondblclick = enable ? (event) => this.onSplitterDblClick(event, i) : undefined
|
|
})
|
|
}
|
|
},
|
|
mounted() {
|
|
this.container = this.$refs.container
|
|
this.checkLowCodeSplitpanesNodes()
|
|
this.redoLowCodeSplitters()
|
|
this.resetLowCodePaneSizes()
|
|
this.$emit('ready')
|
|
this.ready = true
|
|
},
|
|
beforeUnmount() {
|
|
this.ready = false
|
|
},
|
|
methods: {
|
|
updateLowCodePaneComponents() {
|
|
this.panes.forEach((item) => {
|
|
item.update &&
|
|
item.update({
|
|
[this.horizontal ? 'height' : 'width']: `${this.indexedPanes[item.id].size}%`
|
|
})
|
|
})
|
|
},
|
|
bindEvents() {
|
|
document.addEventListener('mousemove', this.onLowCodeMouseMove, { passive: false })
|
|
document.addEventListener('mouseup', this.onLowCodeMouseUp)
|
|
},
|
|
unbindEvents() {
|
|
document.removeEventListener('mousemove', this.onLowCodeMouseMove, { passive: false })
|
|
document.removeEventListener('mouseup', this.onLowCodeMouseUp)
|
|
},
|
|
onMouseDown(event, splitterLowCodeIndex) {
|
|
this.bindEvents()
|
|
this.touch.mouseDown = true
|
|
this.touch.activeSplitter = splitterLowCodeIndex
|
|
},
|
|
|
|
onLowCodeMouseMove(event) {
|
|
if (this.touch.mouseDown) {
|
|
event.preventDefault()
|
|
this.touch.dragging = true
|
|
this.calculatePanesSize(this.getCurrentMouseDrag(event))
|
|
this.$emit(
|
|
'resize',
|
|
this.panes.map((pane) => ({ min: pane.min, max: pane.max, size: pane.size }))
|
|
)
|
|
}
|
|
},
|
|
|
|
onLowCodeMouseUp() {
|
|
if (this.touch.dragging) {
|
|
this.$emit(
|
|
'resized',
|
|
this.panes.map((pane) => ({ min: pane.min, max: pane.max, size: pane.size }))
|
|
)
|
|
}
|
|
this.touch.mouseDown = false
|
|
setTimeout(() => {
|
|
this.touch.dragging = false
|
|
this.unbindEvents()
|
|
}, 100)
|
|
},
|
|
onSplitterClick(event, splitterLowCodeIndex) {
|
|
if ('ontouchstart' in window) {
|
|
event.preventDefault()
|
|
if (this.dblClickSplitter) {
|
|
if (this.lowcodeSplitterTaps.splitter === splitterLowCodeIndex) {
|
|
clearTimeout(this.lowcodeSplitterTaps.timeoutId)
|
|
this.lowcodeSplitterTaps.timeoutId = null
|
|
this.onSplitterDblClick(event, splitterLowCodeIndex)
|
|
this.lowcodeSplitterTaps.splitter = null
|
|
} else {
|
|
this.lowcodeSplitterTaps.splitter = splitterLowCodeIndex
|
|
this.lowcodeSplitterTaps.timeoutId = setTimeout(() => {
|
|
this.lowcodeSplitterTaps.splitter = null
|
|
}, 500)
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!this.touch.dragging) this.$emit('splitter-click', this.panes[splitterLowCodeIndex])
|
|
},
|
|
onSplitterDblClick(event, splitterLowCodeIndex) {
|
|
let totalMinSizes = 0
|
|
this.panes = this.panes.map((pane, i) => {
|
|
pane.size = i === splitterLowCodeIndex ? pane.max : pane.min
|
|
if (i !== splitterLowCodeIndex) totalMinSizes += pane.min
|
|
|
|
return pane
|
|
})
|
|
this.panes[splitterLowCodeIndex].size -= totalMinSizes
|
|
this.$emit('pane-maximize', this.panes[splitterLowCodeIndex])
|
|
},
|
|
|
|
onPaneClick(event, paneId) {
|
|
this.$emit('pane-click', this.indexedPanes[paneId])
|
|
},
|
|
getCurrentMouseDrag(event) {
|
|
const rect = this.container.getBoundingClientRect()
|
|
const { clientX, clientY } = 'ontouchstart' in window && event.touches ? event.touches[0] : event
|
|
|
|
return {
|
|
x: clientX - rect.left,
|
|
y: clientY - rect.top
|
|
}
|
|
},
|
|
getCurrentDragPercentage(drag) {
|
|
drag = drag[this.horizontal ? 'y' : 'x']
|
|
const containerSize = this.container?.[this.horizontal ? 'clientHeight' : 'clientWidth'] || 0
|
|
if (this.rtl && !this.horizontal) drag = containerSize - drag
|
|
|
|
return (drag * 100) / containerSize
|
|
},
|
|
|
|
calculatePanesSize(drag) {
|
|
const splitterLowCodeIndex = this.touch.activeSplitter
|
|
let sums = {
|
|
prevPanesSize: this.sumLowCodePrevPanesSize(splitterLowCodeIndex),
|
|
nextPanesSize: this.sumLowCodeNextPanesSize(splitterLowCodeIndex),
|
|
prevLowcodeReachedMinPanes: 0,
|
|
nextLowCodeReachedMinPanes: 0
|
|
}
|
|
|
|
const minLowCodeDrag = 0 + (this.pushOtherPanes ? 0 : sums.prevPanesSize)
|
|
const maxLowCodeDrag = 100 - (this.pushOtherPanes ? 0 : sums.nextPanesSize)
|
|
const dragLowCodePercentage = Math.max(
|
|
Math.min(this.getCurrentDragPercentage(drag), maxLowCodeDrag),
|
|
minLowCodeDrag
|
|
)
|
|
let panesLowCodeToResize = [splitterLowCodeIndex, splitterLowCodeIndex + 1]
|
|
let paneLowCodeBefore = this.panes[panesLowCodeToResize[0]] || null
|
|
let paneLowCodeAfter = this.panes[panesLowCodeToResize[1]] || null
|
|
|
|
const paneLowCodeBeforeMaxReached =
|
|
paneLowCodeBefore.max < 100 && dragLowCodePercentage >= paneLowCodeBefore.max + sums.prevPanesSize
|
|
const paneLowCodeAfterMaxReached =
|
|
paneLowCodeAfter.max < 100 &&
|
|
dragLowCodePercentage <= 100 - (paneLowCodeAfter.max + this.sumLowCodeNextPanesSize(splitterLowCodeIndex + 1))
|
|
if (paneLowCodeBeforeMaxReached || paneLowCodeAfterMaxReached) {
|
|
if (paneLowCodeBeforeMaxReached) {
|
|
paneLowCodeBefore.size = paneLowCodeBefore.max
|
|
paneLowCodeAfter.size = Math.max(100 - paneLowCodeBefore.max - sums.prevPanesSize - sums.nextPanesSize, 0)
|
|
} else {
|
|
paneLowCodeBefore.size = Math.max(
|
|
100 - paneLowCodeAfter.max - sums.prevPanesSize - this.sumLowCodeNextPanesSize(splitterLowCodeIndex + 1),
|
|
0
|
|
)
|
|
paneLowCodeAfter.size = paneLowCodeAfter.max
|
|
}
|
|
return
|
|
}
|
|
if (this.pushOtherPanes) {
|
|
const vars = this.doPushOtherPanes(sums, dragLowCodePercentage)
|
|
if (!vars) return
|
|
;({ sums, panesLowCodeToResize } = vars)
|
|
paneLowCodeBefore = this.panes[panesLowCodeToResize[0]] || null
|
|
paneLowCodeAfter = this.panes[panesLowCodeToResize[1]] || null
|
|
}
|
|
|
|
if (paneLowCodeBefore !== null) {
|
|
paneLowCodeBefore.size = Math.min(
|
|
Math.max(dragLowCodePercentage - sums.prevPanesSize - sums.prevLowcodeReachedMinPanes, paneLowCodeBefore.min),
|
|
paneLowCodeBefore.max
|
|
)
|
|
}
|
|
if (paneLowCodeAfter !== null) {
|
|
paneLowCodeAfter.size = Math.min(
|
|
Math.max(
|
|
100 - dragLowCodePercentage - sums.nextPanesSize - sums.nextLowCodeReachedMinPanes,
|
|
paneLowCodeAfter.min
|
|
),
|
|
paneLowCodeAfter.max
|
|
)
|
|
}
|
|
},
|
|
|
|
doPushOtherPanes(sums, dragLowCodePercentage) {
|
|
const splitterLowCodeIndex = this.touch.activeSplitter
|
|
const panesLowCodeToResize = [splitterLowCodeIndex, splitterLowCodeIndex + 1]
|
|
if (dragLowCodePercentage < sums.prevPanesSize + this.panes[panesLowCodeToResize[0]].min) {
|
|
panesLowCodeToResize[0] = this.findPrevExpandedPane(splitterLowCodeIndex).index
|
|
|
|
sums.prevLowcodeReachedMinPanes = 0
|
|
if (panesLowCodeToResize[0] < splitterLowCodeIndex) {
|
|
this.panes.forEach((pane, i) => {
|
|
if (i > panesLowCodeToResize[0] && i <= splitterLowCodeIndex) {
|
|
pane.size = pane.min
|
|
sums.prevLowcodeReachedMinPanes += pane.min
|
|
}
|
|
})
|
|
}
|
|
sums.prevPanesSize = this.sumLowCodePrevPanesSize(panesLowCodeToResize[0])
|
|
if (panesLowCodeToResize[0] === undefined) {
|
|
sums.prevLowcodeReachedMinPanes = 0
|
|
this.panes[0].size = this.panes[0].min
|
|
this.panes.forEach((pane, i) => {
|
|
if (i > 0 && i <= splitterLowCodeIndex) {
|
|
pane.size = pane.min
|
|
sums.prevLowcodeReachedMinPanes += pane.min
|
|
}
|
|
})
|
|
this.panes[panesLowCodeToResize[1]].size =
|
|
100 - sums.prevLowcodeReachedMinPanes - this.panes[0].min - sums.prevPanesSize - sums.nextPanesSize
|
|
return null
|
|
}
|
|
}
|
|
if (dragLowCodePercentage > 100 - sums.nextPanesSize - this.panes[panesLowCodeToResize[1]].min) {
|
|
panesLowCodeToResize[1] = this.findNextExpandedPane(splitterLowCodeIndex).index
|
|
sums.nextLowCodeReachedMinPanes = 0
|
|
if (panesLowCodeToResize[1] > splitterLowCodeIndex + 1) {
|
|
this.panes.forEach((pane, i) => {
|
|
if (i > splitterLowCodeIndex && i < panesLowCodeToResize[1]) {
|
|
pane.size = pane.min
|
|
sums.nextLowCodeReachedMinPanes += pane.min
|
|
}
|
|
})
|
|
}
|
|
sums.nextPanesSize = this.sumLowCodeNextPanesSize(panesLowCodeToResize[1] - 1)
|
|
if (panesLowCodeToResize[1] === undefined) {
|
|
sums.nextLowCodeReachedMinPanes = 0
|
|
this.panes[this.panesCount - 1].size = this.panes[this.panesCount - 1].min
|
|
this.panes.forEach((pane, i) => {
|
|
if (i < this.panesCount - 1 && i >= splitterLowCodeIndex + 1) {
|
|
pane.size = pane.min
|
|
sums.nextLowCodeReachedMinPanes += pane.min
|
|
}
|
|
})
|
|
this.panes[panesLowCodeToResize[0]].size =
|
|
100 -
|
|
sums.prevPanesSize -
|
|
sums.nextLowCodeReachedMinPanes -
|
|
this.panes[this.panesCount - 1].min -
|
|
sums.nextPanesSize
|
|
return null
|
|
}
|
|
}
|
|
return { sums, panesLowCodeToResize }
|
|
},
|
|
sumLowCodePrevPanesSize(splitterLowCodeIndex) {
|
|
return this.panes.reduce((total, pane, i) => total + (i < splitterLowCodeIndex ? pane.size : 0), 0)
|
|
},
|
|
sumLowCodeNextPanesSize(splitterLowCodeIndex) {
|
|
return this.panes.reduce((total, pane, i) => total + (i > splitterLowCodeIndex + 1 ? pane.size : 0), 0)
|
|
},
|
|
findPrevExpandedPane(splitterLowCodeIndex) {
|
|
const pane = [...this.panes].reverse().find((p) => p.index < splitterLowCodeIndex && p.size > p.min)
|
|
return pane || {}
|
|
},
|
|
findNextExpandedPane(splitterLowCodeIndex) {
|
|
const pane = this.panes.find((p) => p.index > splitterLowCodeIndex + 1 && p.size > p.min)
|
|
return pane || {}
|
|
},
|
|
checkLowCodeSplitpanesNodes() {
|
|
const children = Array.from(this.container.children)
|
|
children.forEach((child) => {
|
|
const isPane = child.classList.contains('splitpanes__pane')
|
|
const isSplitter = child.classList.contains('splitpanes-lowcode__splitter')
|
|
if (!isPane && !isSplitter) {
|
|
child.parentNode.removeChild(child)
|
|
return
|
|
}
|
|
})
|
|
},
|
|
|
|
addSplitter(paneIndex, nextPaneNode, isVeryFirst = false) {
|
|
const splitterLowCodeIndex = paneIndex - 1
|
|
const elm = document.createElement('div')
|
|
elm.classList.add('splitpanes-lowcode__splitter')
|
|
|
|
if (!isVeryFirst) {
|
|
elm.onmousedown = (event) => this.onMouseDown(event, splitterLowCodeIndex)
|
|
|
|
if (typeof window !== 'undefined' && 'ontouchstart' in window) {
|
|
elm.ontouchstart = (event) => this.onMouseDown(event, splitterLowCodeIndex)
|
|
}
|
|
elm.onclick = (event) => this.onSplitterClick(event, splitterLowCodeIndex + 1)
|
|
}
|
|
|
|
if (this.dblClickSplitter) {
|
|
elm.ondblclick = (event) => this.onSplitterDblClick(event, splitterLowCodeIndex + 1)
|
|
}
|
|
|
|
nextPaneNode.parentNode.insertBefore(elm, nextPaneNode)
|
|
},
|
|
|
|
removeSplitter(node) {
|
|
node.onmousedown = undefined
|
|
node.onclick = undefined
|
|
node.ondblclick = undefined
|
|
node.parentNode.removeChild(node)
|
|
},
|
|
|
|
redoLowCodeSplitters() {
|
|
const children = Array.from(this.container.children)
|
|
children.forEach((el) => {
|
|
if (el.className.includes('splitpanes-lowcode__splitter')) this.removeSplitter(el)
|
|
})
|
|
let paneIndex = 0
|
|
children.forEach((el) => {
|
|
if (el.className.includes('splitpanes__pane')) {
|
|
if (!paneIndex && this.firstSplitter) this.addSplitter(paneIndex, el, true)
|
|
else if (paneIndex) this.addSplitter(paneIndex, el)
|
|
paneIndex++
|
|
}
|
|
})
|
|
},
|
|
requestUpdate({ target, ...args }) {
|
|
const pane = this.indexedPanes[target._.uid]
|
|
Object.entries(args).forEach(([key, value]) => {
|
|
pane[key] = value
|
|
})
|
|
},
|
|
|
|
onPaneAdd(pane) {
|
|
let index = -1
|
|
Array.from(pane.$el.parentNode.children).some((el) => {
|
|
if (el.className.includes('splitpanes__pane')) index++
|
|
return el === pane.$el
|
|
})
|
|
|
|
const min = parseFloat(pane.minSize)
|
|
const max = parseFloat(pane.maxSize)
|
|
this.panes.splice(index, 0, {
|
|
index,
|
|
id: pane._.uid,
|
|
max: isNaN(max) ? 100 : max,
|
|
min: isNaN(min) ? 0 : min,
|
|
givenSize: pane.size,
|
|
size: pane.size === null ? null : parseFloat(pane.size),
|
|
update: pane.update
|
|
})
|
|
|
|
this.panes.forEach((p, i) => {
|
|
p.index = i
|
|
})
|
|
|
|
if (this.ready) {
|
|
this.$nextTick(() => {
|
|
this.redoLowCodeSplitters()
|
|
this.resetLowCodePaneSizes({ addedPane: this.panes[index] })
|
|
this.$emit('pane-add', {
|
|
index,
|
|
panes: this.panes.map((pane) => ({ min: pane.min, max: pane.max, size: pane.size }))
|
|
})
|
|
})
|
|
}
|
|
},
|
|
|
|
onPaneRemove(pane) {
|
|
const index = this.panes.findIndex((p) => p.id === pane._.uid)
|
|
const removed = this.panes.splice(index, 1)[0]
|
|
this.panes.forEach((p, i) => {
|
|
p.index = i
|
|
})
|
|
|
|
this.$nextTick(() => {
|
|
this.redoLowCodeSplitters()
|
|
|
|
this.resetLowCodePaneSizes({ removedPane: { ...removed, index } })
|
|
|
|
this.$emit('pane-remove', {
|
|
removed,
|
|
panes: this.panes.map((pane) => ({ min: pane.min, max: pane.max, size: pane.size }))
|
|
})
|
|
})
|
|
},
|
|
|
|
resetLowCodePaneSizes(changedPanes = {}) {
|
|
if (!changedPanes.addedPane && !changedPanes.removedPane) this.initialPanesSizing()
|
|
else if (this.panes.some((pane) => pane.givenSize !== null || pane.min || pane.max < 100))
|
|
this.equalizeAfterAddOrRemove(changedPanes)
|
|
else this.equalize()
|
|
|
|
if (this.ready)
|
|
this.$emit(
|
|
'resized',
|
|
this.panes.map((pane) => ({ min: pane.min, max: pane.max, size: pane.size }))
|
|
)
|
|
},
|
|
|
|
equalize() {
|
|
const equalSpace = 100 / this.panesCount
|
|
let leftLowCodeToAllocate = 0
|
|
let ungrowableLowCode = []
|
|
let unshrinkableLowCode = []
|
|
|
|
this.panes.forEach((pane) => {
|
|
pane.size = Math.max(Math.min(equalSpace, pane.max), pane.min)
|
|
|
|
leftLowCodeToAllocate -= pane.size
|
|
if (pane.size >= pane.max) ungrowableLowCode.push(pane.id)
|
|
if (pane.size <= pane.min) unshrinkableLowCode.push(pane.id)
|
|
})
|
|
|
|
if (leftLowCodeToAllocate > 0.1) this.readjustSizes(leftLowCodeToAllocate, ungrowableLowCode, unshrinkableLowCode)
|
|
},
|
|
|
|
initialPanesSizing() {
|
|
let leftLowCodeToAllocate = 100
|
|
let ungrowableLowCode = []
|
|
let unshrinkableLowCode = []
|
|
let definedSizes = 0
|
|
this.panes.forEach((pane) => {
|
|
leftLowCodeToAllocate -= pane.size
|
|
if (pane.size !== null) definedSizes++
|
|
if (pane.size >= pane.max) ungrowableLowCode.push(pane.id)
|
|
if (pane.size <= pane.min) unshrinkableLowCode.push(pane.id)
|
|
})
|
|
|
|
let leftLowCodeToAllocate2 = 100
|
|
if (leftLowCodeToAllocate > 0.1) {
|
|
this.panes.forEach((pane) => {
|
|
if (pane.size === null) {
|
|
pane.size = Math.max(Math.min(leftLowCodeToAllocate / (this.panesCount - definedSizes), pane.max), pane.min)
|
|
}
|
|
leftLowCodeToAllocate2 -= pane.size
|
|
})
|
|
|
|
if (leftLowCodeToAllocate2 > 0.1)
|
|
this.readjustSizes(leftLowCodeToAllocate, ungrowableLowCode, unshrinkableLowCode)
|
|
}
|
|
},
|
|
|
|
equalizeAfterAddOrRemove({ addedPane } = {}) {
|
|
let equalSpace = 100 / this.panesCount
|
|
let leftLowCodeToAllocate = 0
|
|
let ungrowableLowCode = []
|
|
let unshrinkableLowCode = []
|
|
|
|
if (addedPane && addedPane.givenSize !== null) {
|
|
equalSpace = (100 - addedPane.givenSize) / (this.panesCount - 1)
|
|
}
|
|
this.panes.forEach((pane) => {
|
|
leftLowCodeToAllocate -= pane.size
|
|
if (pane.size >= pane.max) ungrowableLowCode.push(pane.id)
|
|
if (pane.size <= pane.min) unshrinkableLowCode.push(pane.id)
|
|
})
|
|
|
|
if (Math.abs(leftLowCodeToAllocate) < 0.1) return // Ok.
|
|
|
|
this.panes.forEach((pane) => {
|
|
if (!(addedPane && addedPane.givenSize !== null && addedPane.id === pane.id)) {
|
|
pane.size = Math.max(Math.min(equalSpace, pane.max), pane.min)
|
|
}
|
|
|
|
leftLowCodeToAllocate -= pane.size
|
|
if (pane.size >= pane.max) ungrowableLowCode.push(pane.id)
|
|
if (pane.size <= pane.min) unshrinkableLowCode.push(pane.id)
|
|
})
|
|
|
|
if (leftLowCodeToAllocate > 0.1) this.readjustSizes(leftLowCodeToAllocate, ungrowableLowCode, unshrinkableLowCode)
|
|
},
|
|
readjustSizes(leftLowCodeToAllocate, ungrowableLowCode, unshrinkableLowCode) {
|
|
let equalLowCodeSpaceToAllocate
|
|
if (leftLowCodeToAllocate > 0)
|
|
equalLowCodeSpaceToAllocate = leftLowCodeToAllocate / (this.panesCount - ungrowableLowCode.length)
|
|
else equalLowCodeSpaceToAllocate = leftLowCodeToAllocate / (this.panesCount - unshrinkableLowCode.length)
|
|
|
|
this.panes.forEach((pane) => {
|
|
if (leftLowCodeToAllocate > 0 && !ungrowableLowCode.includes(pane.id)) {
|
|
const newLowCodePaneSize = Math.max(Math.min(pane.size + equalLowCodeSpaceToAllocate, pane.max), pane.min)
|
|
const allocated = newLowCodePaneSize - pane.size
|
|
leftLowCodeToAllocate -= allocated
|
|
pane.size = newLowCodePaneSize
|
|
} else if (!unshrinkableLowCode.includes(pane.id)) {
|
|
const newLowCodePaneSize = Math.max(Math.min(pane.size + equalLowCodeSpaceToAllocate, pane.max), pane.min)
|
|
const allocated = newLowCodePaneSize - pane.size
|
|
leftLowCodeToAllocate -= allocated
|
|
pane.size = newLowCodePaneSize
|
|
}
|
|
pane.update({
|
|
[this.horizontal ? 'height' : 'width']: `${this.indexedPanes[pane.id].size}%`
|
|
})
|
|
})
|
|
|
|
if (Math.abs(leftLowCodeToAllocate) > 0.1) {
|
|
this.$nextTick(() => {
|
|
if (this.ready) {
|
|
// eslint-disable-next-line no-console
|
|
console.warn('Splitpanes: Could not resize panes correctly due to their constraints.')
|
|
}
|
|
})
|
|
}
|
|
}
|
|
},
|
|
|
|
render() {
|
|
return h(
|
|
'div',
|
|
{
|
|
class: [
|
|
`splitpanes--${this.horizontal ? 'horizontal' : 'vertical'}`,
|
|
'splitpanes',
|
|
{
|
|
'splitpanes--dragging': this.touch.dragging
|
|
}
|
|
],
|
|
ref: 'container'
|
|
},
|
|
this.$slots.default()
|
|
)
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="less">
|
|
.splitpanes {
|
|
height: 100%;
|
|
width: 100%;
|
|
display: flex;
|
|
|
|
&--horizontal {
|
|
flex-direction: column;
|
|
}
|
|
&--vertical {
|
|
flex-direction: row;
|
|
}
|
|
&--dragging * {
|
|
user-select: none;
|
|
}
|
|
|
|
&__splitter {
|
|
touch-action: none;
|
|
}
|
|
&__pane {
|
|
height: 100%;
|
|
overflow: hidden;
|
|
width: 100%;
|
|
|
|
.splitpanes--horizontal & {
|
|
transition: height 0.3s ease-out;
|
|
}
|
|
.splitpanes--vertical & {
|
|
transition: width 0.3s ease-out;
|
|
}
|
|
.splitpanes--dragging & {
|
|
transition: none;
|
|
}
|
|
}
|
|
&--vertical > .splitpanes-lowcode__splitter {
|
|
min-width: 1px;
|
|
cursor: col-resize;
|
|
}
|
|
&--horizontal > .splitpanes-lowcode__splitter {
|
|
min-height: 1px;
|
|
cursor: row-resize;
|
|
}
|
|
}
|
|
.splitpanes.default-theme {
|
|
.splitpanes__pane {
|
|
background-color: #f2f2f2;
|
|
}
|
|
.splitpanes-lowcode__splitter {
|
|
background-color: #fff;
|
|
box-sizing: border-box;
|
|
position: relative;
|
|
flex-shrink: 0;
|
|
&:before,
|
|
&:after {
|
|
content: '';
|
|
position: absolute;
|
|
top: 50%;
|
|
left: 50%;
|
|
background-color: rgba(0, 0, 0, 0.15);
|
|
transition: background-color 0.3s;
|
|
}
|
|
&:hover:before,
|
|
&:hover:after {
|
|
background-color: rgba(0, 0, 0, 0.25);
|
|
}
|
|
&:first-child {
|
|
cursor: auto;
|
|
}
|
|
}
|
|
}
|
|
.default-theme {
|
|
&.splitpanes .splitpanes .splitpanes-lowcode__splitter {
|
|
z-index: 1;
|
|
}
|
|
&.splitpanes--vertical > .splitpanes-lowcode__splitter,
|
|
.splitpanes--vertical > .splitpanes-lowcode__splitter {
|
|
width: 7px;
|
|
border-left: 1px solid #eee;
|
|
margin-left: -1px;
|
|
&:after,
|
|
&:before {
|
|
width: 1px;
|
|
transform: translateY(-50%);
|
|
height: 30px;
|
|
}
|
|
&:after {
|
|
margin-left: 1px;
|
|
}
|
|
&:before {
|
|
margin-left: -2px;
|
|
}
|
|
}
|
|
&.splitpanes--horizontal > .splitpanes-lowcode__splitter,
|
|
.splitpanes--horizontal > .splitpanes-lowcode__splitter {
|
|
border-top: 1px solid #eee;
|
|
margin-top: -1px;
|
|
height: 7px;
|
|
&:after,
|
|
&:before {
|
|
height: 1px;
|
|
transform: translateX(-50%);
|
|
width: 30px;
|
|
}
|
|
&:before {
|
|
margin-top: -2px;
|
|
}
|
|
&:after {
|
|
margin-top: 1px;
|
|
}
|
|
}
|
|
}
|
|
</style>
|