You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
svelte/site/src/components/Repl/SplitPane.svelte

164 lines
2.9 KiB

<script>
import * as yootils from 'yootils';
import { createEventDispatcher } from 'svelte';
const dispatch = createEventDispatcher();
export let type;
export let pos = 50;
export let fixed = false;
export let fixed_pos = pos;
export let min = 50;
// export let min1 = min;
// export let min2 = min;
const refs = {};
const side = type === 'horizontal' ? 'left' : 'top';
const dimension = type === 'horizontal' ? 'width' : 'height';
let dragging = false;
function setPos(event) {
const { top, bottom, left, right } = refs.container.getBoundingClientRect();
const extents = type === 'vertical' ? [top, bottom] : [left, right];
const px = yootils.clamp(
type === 'vertical' ? event.clientY : event.clientX,
extents[0] + min,
extents[1] - min
);
pos = 100 * (px - extents[0]) / (extents[1] - extents[0]);
dispatch('change');
}
function drag(node, callback) {
const mousedown = event => {
if (event.which !== 1) return;
event.preventDefault();
dragging = true;
const onmouseup = () => {
dragging = false;
window.removeEventListener('mousemove', callback, false);
window.removeEventListener('mouseup', onmouseup, false);
};
window.addEventListener('mousemove', callback, false);
window.addEventListener('mouseup', onmouseup, false);
}
node.addEventListener('mousedown', mousedown, false);
return {
destroy() {
node.removeEventListener('mousedown', onmousedown, false);
}
};
}
</script>
<style>
.container {
position: relative;
width: 100%;
height: 100%;
}
.pane {
position: relative;
float: left;
width: 100%;
height: 100%;
}
.mousecatcher {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: rgba(255,255,255,.01);
}
.divider {
position: absolute;
z-index: 10;
display: none;
}
.divider::after {
content: '';
position: absolute;
/* background-color: #eee; */
background-color: var(--second);
}
.horizontal {
padding: 0 8px;
width: 0;
height: 100%;
cursor: ew-resize;
}
.horizontal::after {
left: 8px;
top: 0;
width: 1px;
height: 100%;
}
.vertical {
padding: 8px 0;
width: 100%;
height: 0;
cursor: ns-resize;
}
.vertical::after {
top: 8px;
left: 0;
width: 100%;
height: 1px;
}
.left, .right, .divider {
display: block;
}
.left, .right {
height: 100%;
float: left;
}
.top, .bottom {
position: absolute;
width: 100%;
}
.top { top: 0; }
.bottom { bottom: 0; }
</style>
<div class="container" bind:this={refs.container}>
<div class="pane" style="{dimension}: {fixed ? fixed_pos : pos}%;">
<slot name="a"></slot>
</div>
<div class="pane" style="{dimension}: {100 - (fixed ? fixed_pos : pos)}%;">
<slot name="b"></slot>
</div>
{#if !fixed}
<div class="{type} divider" style="{side}: calc({pos}% - 8px)" use:drag={setPos}></div>
{/if}
</div>
{#if dragging}
<div class="mousecatcher"></div>
{/if}