import LeaderLine from "leader-line-new"; class CustomTimeline extends HTMLElement { _eventElements: Element[]; constructor() { super(); this._eventElements = this._getNodeElements(); window.addEventListener("load", this._paintLeaderLines); } _getNodeElements = (): Element[] => Array.from(this.querySelectorAll("[data-timeline-node-index]")).sort( (elementA, elementB) => Number(elementA.getAttribute("data-timeline-node-index")) - Number(elementB.getAttribute("data-timeline-node-index")), ); _paintLeaderLines = () => { let pairs = this._eventElements .map((entry, index) => { if (index < this._eventElements.length - 1) { return [entry, this._eventElements[index + 1]]; } }) .filter((pair) => pair !== undefined); let contentBodyScrolling = document.getElementById( "content-body-scrolling", ); let wrapper = this.querySelector( "[data-custom-timeline-line-wrapper]", ) as HTMLElement; const position = (line: LeaderLine) => { wrapper.style.transform = "none"; let rectWrapper = wrapper.getBoundingClientRect(); wrapper.style.transform = "translate(-" + Number(rectWrapper.left) + "px, -" + Number(rectWrapper.top) + "px)"; line.position(); }; pairs.forEach((pair) => { let line = new LeaderLine({ start: pair[0], end: pair[1], color: "#10ac25", size: 3, startSocket: "right", endSocket: "left", startPlug: "square", endPlug: "arrow3", }); // Find new element by hidden id and add to wrapper div // noinspection TypeScriptUnresolvedReference const lineId = line._id; // @ts-ignore const newLineEl = document.querySelector( `body .leader-line:has(path#leader-line-${lineId}-line-path)`, ); if (newLineEl) wrapper.appendChild(newLineEl); // Add position updaters for scrolling and resize events contentBodyScrolling?.addEventListener("scroll", () => position(line)); window.addEventListener("resize", () => position(line)); // Perform the initial positioning position(line); }); }; } customElements.define("custom-timeline", CustomTimeline);