|
<script lang="ts">
|
|
import { onMount } from "svelte";
|
|
|
|
export let position = 0.5;
|
|
export let disabled = false;
|
|
export let show_nav = true;
|
|
|
|
let active = false;
|
|
let hidden = true;
|
|
let el: HTMLDivElement;
|
|
let inner: HTMLDivElement;
|
|
let box: DOMRect;
|
|
let px = 0;
|
|
let offset = 0;
|
|
|
|
function handle_mousedown(e: MouseEvent) {
|
|
if (disabled) return;
|
|
active = true;
|
|
box = el.getBoundingClientRect();
|
|
const innerbox = inner.getBoundingClientRect();
|
|
offset = e.clientX - innerbox.left;
|
|
}
|
|
|
|
function handle_mouseup(e: MouseEvent) {
|
|
active = false;
|
|
}
|
|
|
|
function handle_mousemove(e: MouseEvent) {
|
|
if (!active) return;
|
|
px = clamp(e.clientX - offset - box.left, 100, box.width - 240);
|
|
position = round((px + 10) / box.width, 5);
|
|
}
|
|
|
|
function clamp(n: number, min: number, max: number) {
|
|
return n < min ? min : n > max ? max : n;
|
|
}
|
|
|
|
function round(n: number, points: number) {
|
|
const mod = Math.pow(10, points);
|
|
return Math.round((n + Number.EPSILON) * mod) / mod;
|
|
}
|
|
|
|
function set_position() {
|
|
box = el.getBoundingClientRect();
|
|
px = box.width * position - 10;
|
|
hidden = false;
|
|
}
|
|
|
|
onMount(set_position);
|
|
|
|
$: if (!hidden && show_nav) {
|
|
box = el.getBoundingClientRect();
|
|
px = box.width * position - 10;
|
|
} else if (!hidden && !show_nav) {
|
|
box = el.getBoundingClientRect();
|
|
px = box.width * position - 10;
|
|
}
|
|
</script>
|
|
|
|
<svelte:window
|
|
on:resize={set_position}
|
|
on:mousemove={handle_mousemove}
|
|
on:mouseup={handle_mouseup}
|
|
/>
|
|
|
|
<div class="wrap" bind:this={el}>
|
|
<slot />
|
|
<div
|
|
class="outer hidden sm:block"
|
|
class:disabled
|
|
on:mousedown={handle_mousedown}
|
|
on:mouseup={handle_mouseup}
|
|
bind:this={inner}
|
|
role="none"
|
|
style="transform: translateX({px}px)"
|
|
>
|
|
<div {hidden} class="inner">
|
|
<div class="notches text-gray-400 select-none">||</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<style>
|
|
.wrap {
|
|
position: relative;
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
|
|
.outer {
|
|
width: 20px;
|
|
height: 100%;
|
|
position: absolute;
|
|
cursor: grab;
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
cursor: ew-resize;
|
|
}
|
|
|
|
.inner {
|
|
width: 15px;
|
|
height: 100%;
|
|
background: #fbfcfc;
|
|
position: absolute;
|
|
left: calc((100% - 2px) / 2);
|
|
border-right: 1px solid rgb(229, 231, 235);
|
|
border-left: 1px solid rgb(229, 231, 235);
|
|
}
|
|
|
|
.disabled {
|
|
cursor: auto;
|
|
}
|
|
|
|
.disabled .inner {
|
|
box-shadow: none;
|
|
}
|
|
|
|
.notches {
|
|
margin: 0;
|
|
position: absolute;
|
|
top: 50%;
|
|
left: 50%;
|
|
transform: translate(-50%, -50%) scale(1, 2.5);
|
|
font-weight: bold;
|
|
}
|
|
</style>
|
|
|