Page MenuHomeSealhub

component-debugger.stimulus.ts
No OneTemporary

component-debugger.stimulus.ts

/* eslint-disable @typescript-eslint/consistent-type-assertions */
/* eslint-disable @typescript-eslint/no-unnecessary-type-assertion */
import { Controller } from "stimulus";
export default class ComponentDebugger extends Controller {
declare gutterTarget: HTMLDivElement;
declare checkboxTarget: HTMLInputElement;
declare checkboxTargets: HTMLInputElement[];
declare previewTarget: HTMLDivElement;
declare componentBlockTargets: HTMLDivElement[];
declare componentBlockTargetDisconnected: (e: HTMLDivElement) => void;
static targets = ["gutter", "componentBlock", "checkbox", "preview"];
id: string;
main_form: HTMLFormElement;
is_resizing = false;
origin_x: number;
origin_width: number;
connect() {
this.main_form = document.querySelector("#component-debugger").closest("form");
document.documentElement.addEventListener("ts-rebuilt", () => {
this.main_form.requestSubmit();
});
this.main_form.addEventListener("turbo:submit-end", () => {
// this clears the values of file inputs, so they don't get unecessarily
// re-uploaded on future submissions - the file is alreade there on the server
this.main_form
.querySelectorAll("input[type=file]")
.forEach((input: HTMLInputElement) => (input.value = ""));
});
window.addEventListener("load", () => {
this.update_width_display();
});
document.addEventListener("turbo:render", () => this.update_width_display());
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
const gutter = this.gutterTarget;
gutter.addEventListener("mousedown", (e) => {
this.is_resizing = true;
this.origin_x = e.clientX;
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
const resizable = this.targets.find("preview") as HTMLSpanElement;
this.origin_width = resizable.getBoundingClientRect().width;
const handler = (e: MouseEvent) => this.resizeHandler(e);
document.addEventListener("mousemove", handler);
document.addEventListener("mouseup", () => {
document.removeEventListener("mousemove", handler);
});
e.preventDefault();
});
}
update_width_display() {
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
const preview = this.targets.find("preview") as HTMLSpanElement;
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
const component_width_element = this.targets.find(
"component-width"
) as HTMLSpanElement;
const component_width = preview.offsetWidth;
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
component_width_element.innerHTML = `(width: ${component_width}px)`;
}
resizeHandler(e: MouseEvent) {
const width_offset = this.origin_x - e.clientX;
const new_width = Math.max(this.origin_width + width_offset, 1);
this.setPreviewWidth(new_width);
this.update_width_display();
}
setPreviewWidth(width: number) {
document
.getElementById("component-debugger")
.style.setProperty("--resizable-column-width", width.toString() + "px");
this.update_width_display();
}
handleWidthDropdown() {
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
const dropdown = this.targets.find("size-select") as HTMLSelectElement;
const value = dropdown.value;
this.setPreviewWidth(parseInt(value));
}
componentBlockTargetConnected(block_element: HTMLDivElement) {
const index = parseInt(block_element.getAttribute("data-component-index"));
block_element.addEventListener("focusin", () => {
this.scrollToComponentPreview(index);
});
}
previewTargetConnected(preview_element: HTMLDivElement) {
preview_element.addEventListener("click", ({ target }) => {
if (!(target instanceof HTMLElement)) {
return;
}
const closest = target.closest(".jdd-component");
if (!closest) {
return;
}
const index = parseInt(
Array.from(closest.classList)
.find((c) => c.startsWith("component-number-"))
?.replace("component-number-", "")
);
if (isNaN(index)) {
return;
}
this.focusComponentBlock(index);
});
}
focusComponentBlock(index: number) {
const block = this.componentBlockTargets[index];
if (!block) {
return;
}
this.checkboxTargets[index].checked = true;
block.scrollIntoView({ behavior: "smooth" });
(
block.querySelector(".component-preview-parameters input") as HTMLInputElement
)?.focus();
}
getIndex(block_element: HTMLDivElement) {
const index = parseInt(block_element.getAttribute("data-component-index"));
return index;
}
labelClicked(element: MouseEvent) {
const block_element = (element.target as HTMLDivElement).closest(
`[data-component-debugger-target="componentBlock"]`
) as HTMLDivElement;
const index = this.getIndex(block_element);
if (!this.checkboxTargets?.[index].checked) {
this.scrollToComponentPreview(index);
}
}
getPreviewElementForComponentIndex(index: number) {
const element = this.element.querySelector(
`.component-number-${index}`
) as HTMLDialogElement;
return element;
}
scrollToComponentPreview(index: number) {
const element = this.getPreviewElementForComponentIndex(index);
if (!element) {
return;
}
const preview_element = this.element.querySelector(".component-preview");
if (element.clientHeight > preview_element.clientHeight) {
preview_element.scrollTop = element.offsetTop - 44;
} else {
preview_element.scrollTop =
element.offsetTop -
(preview_element.clientHeight - element.clientHeight) / 2 -
44;
}
}
}

File Metadata

Mime Type
text/x-java
Expires
Sun, Nov 2, 15:28 (16 m, 16 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1018886
Default Alt Text
component-debugger.stimulus.ts (5 KB)

Event Timeline