new multipane

This commit is contained in:
Pete Richards 2018-08-15 12:43:32 -07:00
parent f6b90caaff
commit f67f03af47
2 changed files with 159 additions and 0 deletions

View File

@ -0,0 +1,88 @@
<template>
<div class="multipane"
:class="{
'multipane--vertical': type === 'vertical',
'multipane--horizontal': type === 'horizontal'
}">
<slot></slot>
</div>
</template>
<style lang="scss">
.multipane {
$backgroundColor: #06f;
$size: 10px;
& > .multipane__pane > .multipane__splitter {
z-index: 1;
display: block;
background: #ccc;
position: absolute;
&:before {
content: '';
}
&:hover {
background: rgba($backgroundColor, 0.3);
&:before {
background: $backgroundColor;
}
}
}
&--horizontal > .multipane__pane > .multipane__splitter {
cursor: col-resize;
width: $size;
top: 0px;
bottom: 0px;
&--before {
left: (- $size / 2);
}
&--after {
right: (- $size / 2);
}
&:before {
// Divider line
width: 1px;
height: 100%;
left: 50%;
transform: translateX(-50%);
}
}
&--vertical > .multipane__pane > .multipane__splitter {
cursor: row-resize;
height: $size;
left: 0px;
right: 0px;
&--before {
top: (- $size / 2);
}
&--after {
left: (- $size / 2);
}
&:before {
// Divider line
width: 100%;
height: 1px;
top: 50%;
transform: translateY(-50%);
}
}
}
</style>
<script>
export default {
props: {
type: {
type: String,
validator: function (value) {
return ['vertical', 'horizontal'].indexOf(value) !== -1;
}
}
}
}
</script>

View File

@ -0,0 +1,71 @@
<template>
<div class="multipane__pane">
<div v-if="splitter"
class="multipane__splitter"
:class="{
'multipane__splitter--before': splitter === 'before',
'multipane__splitter--after': splitter === 'after',
}"
@mousedown="start"
></div>
<slot></slot>
</div>
</template>
<script>
export default {
props: {
splitter: {
type: String,
validator: function (value) {
return ['before', 'after'].indexOf(value) !== -1;
}
}
},
mounted() {
this.type = this.$parent.type;
this.trackSize();
},
methods: {
trackSize: function() {
if (this.type === 'vertical') {
this.initial = this.$el.offsetHeight;
} else if (this.type === 'horizontal') {
this.initial = this.$el.offsetWidth;
}
},
getPosition: function (event) {
return this.type === 'horizontal' ?
event.pageX :
event.pageY;
},
getNewSize: function (event) {
let delta = this.startPosition - this.getPosition(event);
if (this.splitter === "before") {
return `${this.initial + delta}px`;
}
if (this.splitter === "after") {
return `${this.initial - delta}px`;
}
},
updatePosition: function (event) {
let size = this.getNewSize(event);
if (this.type === 'horizontal') {
this.$el.style.width = size;
} else {
this.$el.style.height = size;
}
},
start: function (event) {
this.startPosition = this.getPosition(event);
document.body.addEventListener('mousemove', this.updatePosition);
document.body.addEventListener('mouseup', this.end);
},
end: function (event) {
document.body.removeEventListener('mousemove', this.updatePosition);
document.body.removeEventListener('mouseup', this.end);
this.trackSize();
}
}
}
</script>