import { listen, SaveData } from "rkgk/framework.js"; export class ResizeHandle extends HTMLElement { saveData = new SaveData("resizeHandle"); constructor(props) { super(); this.props = props; } connectedCallback() { let props = this.props ?? this.dataset; this.direction = this.dataset.direction = props.direction; this.targetProperty = props.targetProperty; this.initSize = parseInt(props.initSize); this.minSize = parseInt(props.minSize); this.inverse = props.inverse != null; if (props.targetElement != null) { // In case you want to construct the resize handle programatically: // pass in the target element via targetElement. // Don't forget to set its id. this.target = props.targetElement; this.targetId = this.target.id; } else { // Else use data-target. this.targetId = props.target; this.target = document.getElementById(this.targetId); } this.saveData.elementId = this.targetId; // NOTE(localStorage): Migration from old local storage key. let oldSizeKey = `rkgk.resizeHandle.size.${this.targetId}`; this.#setSize( this.saveData.get("size") ?? localStorage.getItem(oldSizeKey) ?? this.initSize, ); this.#saveSize(); this.#updateTargetProperty(); this.visual = this.appendChild(document.createElement("div")); this.visual.classList.add("visual"); this.#draggingBehaviour(); // NOTE(localStorage): Migration from old local storage key. localStorage.removeItem(oldSizeKey); } #setSize(newSize) { if (newSize != newSize) { newSize = this.initSize; } this.size = Math.max(this.minSize, newSize); } #saveSize() { this.saveData.set("size", this.size); } #updateTargetProperty() { this.target.style.setProperty(this.targetProperty, `${this.size}px`); } async #draggingBehaviour() { while (true) { let mouseDown = await listen([this, "mousedown"]); let startingSize = this.size; if (mouseDown.button == 0) { mouseDown.preventDefault(); this.classList.add("dragging"); while (true) { let event = await listen([window, "mousemove"], [window, "mouseup"]); if (event.type == "mousemove") { let delta = this.direction == "vertical" ? event.clientX - mouseDown.clientX : event.clientY - mouseDown.clientY; if (this.inverse) delta = -delta; this.#setSize(startingSize + delta); this.#updateTargetProperty(); } else if (event.type == "mouseup") { this.classList.remove("dragging"); this.#saveSize(); break; } } } } } } customElements.define("rkgk-resize-handle", ResizeHandle);