switch the app from floating panels to a static sidebar on the right with resizable tools expect more layout bugs from now on
96 lines
3.2 KiB
JavaScript
96 lines
3.2 KiB
JavaScript
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);
|