From dccc3ed8ca07dde179ce3d61d075fda44bf82cab Mon Sep 17 00:00:00 2001 From: Simon Martens Date: Wed, 4 Jun 2025 13:31:30 +0200 Subject: [PATCH] Titel --- views/assets/scripts.js | 435 ++++++++++++++++--------- views/assets/style.css | 2 +- views/routes/almanach/edit/body.gohtml | 102 +++++- views/transform/div-menu.js | 25 +- views/transform/form.css | 114 ++----- 5 files changed, 421 insertions(+), 257 deletions(-) diff --git a/views/assets/scripts.js b/views/assets/scripts.js index 739bafc..9d42f98 100644 --- a/views/assets/scripts.js +++ b/views/assets/scripts.js @@ -1,11 +1,11 @@ -var et = Object.defineProperty; -var w = (l) => { +var ut = Object.defineProperty; +var O = (l) => { throw TypeError(l); }; -var it = (l, i, t) => i in l ? et(l, i, { enumerable: !0, configurable: !0, writable: !0, value: t }) : l[i] = t; -var u = (l, i, t) => it(l, typeof i != "symbol" ? i + "" : i, t), S = (l, i, t) => i.has(l) || w("Cannot " + t); -var v = (l, i, t) => (S(l, i, "read from private field"), t ? t.call(l) : i.get(l)), _ = (l, i, t) => i.has(l) ? w("Cannot add the same private member more than once") : i instanceof WeakSet ? i.add(l) : i.set(l, t), f = (l, i, t, e) => (S(l, i, "write to private field"), e ? e.call(l, t) : i.set(l, t), t), L = (l, i, t) => (S(l, i, "access private method"), t); -class st extends HTMLElement { +var mt = (l, i, t) => i in l ? ut(l, i, { enumerable: !0, configurable: !0, writable: !0, value: t }) : l[i] = t; +var u = (l, i, t) => mt(l, typeof i != "symbol" ? i + "" : i, t), v = (l, i, t) => i.has(l) || O("Cannot " + t); +var L = (l, i, t) => (v(l, i, "read from private field"), t ? t.call(l) : i.get(l)), f = (l, i, t) => i.has(l) ? O("Cannot add the same private member more than once") : i instanceof WeakSet ? i.add(l) : i.set(l, t), g = (l, i, t, e) => (v(l, i, "write to private field"), e ? e.call(l, t) : i.set(l, t), t), I = (l, i, t) => (v(l, i, "access private method"), t); +class pt extends HTMLElement { constructor() { super(), this._value = "", this.render(); } @@ -74,13 +74,13 @@ class st extends HTMLElement { `; } } -const g = "filter-list-list", nt = "filter-list-item", lt = "filter-list-input", x = "filter-list-searchable"; -var h, m, y; -class at extends HTMLElement { +const E = "filter-list-list", _t = "filter-list-item", ft = "filter-list-input", B = "filter-list-searchable"; +var d, _, k; +class gt extends HTMLElement { constructor() { super(); - _(this, m); - _(this, h, !1); + f(this, _); + f(this, d, !1); this._items = [], this._url = "", this._filterstart = !1, this._placeholder = "Liste filtern...", this._queryparam = "", this._startparams = null, this.render(); } static get observedAttributes() { @@ -93,7 +93,7 @@ class at extends HTMLElement { return this._items; } connectedCallback() { - this._url = this.getAttribute("data-url") || "./", this._filterstart = this.getAttribute("data-filterstart") === "true", this._placeholder = this.getAttribute("data-placeholder") || "Liste filtern...", this._queryparam = this.getAttribute("data-queryparam") || "", this._queryparam, this._filterstart && f(this, h, !0), this.addEventListener("input", this.onInput.bind(this)), this.addEventListener("keydown", this.onEnter.bind(this)), this.addEventListener("focusin", this.onGainFocus.bind(this)), this.addEventListener("focusout", this.onLoseFocus.bind(this)); + this._url = this.getAttribute("data-url") || "./", this._filterstart = this.getAttribute("data-filterstart") === "true", this._placeholder = this.getAttribute("data-placeholder") || "Liste filtern...", this._queryparam = this.getAttribute("data-queryparam") || "", this._queryparam, this._filterstart && g(this, d, !0), this.addEventListener("input", this.onInput.bind(this)), this.addEventListener("keydown", this.onEnter.bind(this)), this.addEventListener("focusin", this.onGainFocus.bind(this)), this.addEventListener("focusout", this.onLoseFocus.bind(this)); } attributeChangedCallback(t, e, s) { t === "data-url" && e !== s && (this._url = s, this.render()), t === "data-filterstart" && e !== s && (this._filterstart = s === "true", this.render()), t === "data-placeholder" && e !== s && (this._placeholder = s, this.render()), t === "data-queryparam" && e !== s && (this._queryparam = s, this.render()); @@ -102,14 +102,14 @@ class at extends HTMLElement { t.target && t.target.tagName.toLowerCase() === "input" && (this._filter = t.target.value, this.renderList()); } onGainFocus(t) { - t.target && t.target.tagName.toLowerCase() === "input" && (f(this, h, !1), this.renderList()); + t.target && t.target.tagName.toLowerCase() === "input" && (g(this, d, !1), this.renderList()); } onLoseFocus(t) { let e = this.querySelector("input"); if (t.target && t.target === e) { if (relatedElement = t.relatedTarget, relatedElement && this.contains(relatedElement)) return; - e.value = "", this._filter = "", this._filterstart && f(this, h, !0), this.renderList(); + e.value = "", this._filter = "", this._filterstart && g(this, d, !0), this.renderList(); } } onEnter(t) { @@ -122,10 +122,10 @@ class at extends HTMLElement { mark() { if (typeof Mark != "function") return; - let t = this.querySelector("#" + g); + let t = this.querySelector("#" + E); if (!t) return; - let e = new Mark(t.querySelectorAll("." + x)); + let e = new Mark(t.querySelectorAll("." + B)); this._filter && e.mark(this._filter, { separateWordSearch: !0 }); @@ -165,7 +165,7 @@ class at extends HTMLElement { } getLinkText(t) { let e = this.getSearchText(t); - return e === "" ? "" : `${e}`; + return e === "" ? "" : `${e}`; } getURL(t) { if (this._queryparam) { @@ -175,7 +175,7 @@ class at extends HTMLElement { return this._url + this.getHREFEncoded(t); } renderList() { - let t = this.querySelector("#" + g); + let t = this.querySelector("#" + E); t && (t.outerHTML = this.List()), this.mark(); } render() { @@ -187,7 +187,7 @@ class at extends HTMLElement { `, htmx && htmx.process(this); } ActiveDot(t) { - return L(this, m, y).call(this, t), ""; + return I(this, _, k).call(this, t), ""; } NoItems(t) { return t.length === 0 ? '
Keine Einträge gefunden
' : ""; @@ -200,7 +200,7 @@ class at extends HTMLElement { + class="${ft} w-full placeholder:italic px-2 py-0.5" /> `; @@ -215,7 +215,7 @@ class at extends HTMLElement { t = this._items.filter((s) => e.every((n) => this.getSearchText(s).toLowerCase().includes(n.toLowerCase()))); } return ` -
+
${t.map( (e, s) => ` + class="${_t} block px-2.5 py-0.5 hover:bg-slate-200 no-underline ${s % 2 === 0 ? "bg-stone-100" : "bg-stone-50"}" + ${I(this, _, k).call(this, e) ? 'aria-current="page"' : ""}> ${this.ActiveDot(e)} ${this.getLinkText(e)} @@ -236,13 +236,13 @@ class at extends HTMLElement { `; } } -h = new WeakMap(), m = new WeakSet(), y = function(t) { +d = new WeakMap(), _ = new WeakSet(), k = function(t) { if (!t) return !1; let e = this.getHREF(t); return e === "" ? !1 : this._queryparam && (new URLSearchParams(window.location.search).get(this._queryparam) || "") === e ? !0 : !!window.location.href.endsWith(e); }; -class rt extends HTMLElement { +class Et extends HTMLElement { constructor() { super(), this.handleScroll = this.handleScroll.bind(this), this.scrollToTop = this.scrollToTop.bind(this); } @@ -278,7 +278,7 @@ class rt extends HTMLElement { window.scrollTo({ top: 0, behavior: "smooth" }); } } -class ot extends HTMLElement { +class bt extends HTMLElement { static get observedAttributes() { return ["position", "timeout"]; } @@ -379,7 +379,7 @@ class ot extends HTMLElement { } } } -class ht extends HTMLElement { +class St extends HTMLElement { constructor() { super(), this.overlay = null, this._others = null, this._thisindex = -1, this._preview = null, this._description = null, this._imageURL = "", this._hideDLButton = !1; } @@ -487,7 +487,7 @@ class ht extends HTMLElement { this.overlay.parentNode.removeChild(this.overlay), this.overlay = null; } } -class dt extends HTMLElement { +class vt extends HTMLElement { static get observedAttributes() { } constructor() { @@ -704,7 +704,7 @@ class p extends HTMLElement { return /\s|[.,;:!?]/.test(i); } } -class ct extends HTMLElement { +class Lt extends HTMLElement { constructor() { super(); } @@ -722,11 +722,11 @@ class ct extends HTMLElement { } } } -var E; -class ut extends HTMLElement { +var S; +class It extends HTMLElement { constructor() { super(); - _(this, E, 176); + f(this, S, 176); this._images = []; } connectedCallback() { @@ -742,14 +742,14 @@ class ut extends HTMLElement { calculateShownImages() { const t = this.getBoundingClientRect(); console.log(t); - const e = Math.floor(t.width / (v(this, E) + 10)); + const e = Math.floor(t.width / (L(this, S) + 10)); for (let s = 0; s < this._images.length; s++) s < e - 1 ? this._images[s].classList.remove("hidden") : this._images[s].classList.add("hidden"); } } -E = new WeakMap(); -const pt = "msr-component-wrapper", O = "msr-selected-items-container", k = "msr-placeholder-no-selection-text", mt = "msr-selected-item-pill", _t = "msr-selected-item-text", ft = "msr-item-name", gt = "msr-item-additional-data", bt = "msr-selected-item-role", M = "msr-selected-item-delete-btn", Et = "msr-controls-area", R = "msr-pre-add-button", B = "msr-input-area-wrapper", b = "msr-input-area-default-border", I = "msr-input-area-staged", $ = "msr-staging-area-container", St = "msr-staged-item-pill", vt = "msr-staged-item-text", A = "msr-staged-role-select", P = "msr-staged-cancel-btn", N = "msr-text-input", D = "msr-add-button", H = "msr-options-list", q = "msr-option-item", Lt = "msr-option-item-name", It = "msr-option-item-detail", U = "msr-option-item-highlighted", C = "msr-hidden-select", At = "msr-state-no-selection", Ct = "msr-state-has-selection", Tt = "msr-state-list-open", yt = "msr-state-item-staged"; -class X extends HTMLElement { +S = new WeakMap(); +const At = "msr-component-wrapper", R = "msr-selected-items-container", $ = "msr-placeholder-no-selection-text", Tt = "msr-selected-item-pill", Ct = "msr-selected-item-text", yt = "msr-item-name", wt = "msr-item-additional-data", xt = "msr-selected-item-role", P = "msr-selected-item-delete-btn", Mt = "msr-controls-area", N = "msr-pre-add-button", D = "msr-input-area-wrapper", b = "msr-input-area-default-border", A = "msr-input-area-staged", H = "msr-staging-area-container", kt = "msr-staged-item-pill", Ot = "msr-staged-item-text", T = "msr-staged-role-select", q = "msr-staged-cancel-btn", U = "msr-text-input", F = "msr-add-button", V = "msr-options-list", W = "msr-option-item", Bt = "msr-option-item-name", Rt = "msr-option-item-detail", G = "msr-option-item-highlighted", C = "msr-hidden-select", $t = "msr-state-no-selection", Pt = "msr-state-has-selection", Nt = "msr-state-list-open", Dt = "msr-state-item-staged"; +class ot extends HTMLElement { constructor() { super(); u(this, "_blurTimeout", null); @@ -828,23 +828,23 @@ class X extends HTMLElement { } _setupTemplates() { this.optionTemplate = document.createElement("template"), this.optionTemplate.innerHTML = ` -
  • - - +
  • + +
  • `, this.selectedItemTemplate = document.createElement("template"), this.selectedItemTemplate.innerHTML = ` - - - + + + `, this.stagedPlacePillTemplate = document.createElement("template"), this.stagedPlacePillTemplate.innerHTML = ` - - + + `, this.stagedCancelBtnTemplate = document.createElement("template"), this.stagedCancelBtnTemplate.innerHTML = ` - + `, this.stagedRoleSelectTemplate = document.createElement("template"), this.stagedRoleSelectTemplate.innerHTML = ` - `; } @@ -883,9 +883,9 @@ class X extends HTMLElement { if (typeof a == "string") { const r = a.split(","); if (r.length === 2) { - const o = r[0].trim(), d = r[1].trim(); - if (this._getItemById(o) && this._roles.includes(d)) - return { itemId: o, role: d, instanceId: crypto.randomUUID() }; + const o = r[0].trim(), h = r[1].trim(); + if (this._getItemById(o) && this._roles.includes(h)) + return { itemId: o, role: h, instanceId: crypto.randomUUID() }; } } return null; @@ -906,7 +906,7 @@ class X extends HTMLElement { this.setAttribute("name", t), this.hiddenSelect && (this.hiddenSelect.name = t); } connectedCallback() { - if (this.placeholderNoSelection = this.getAttribute("placeholder-no-selection") || this._placeholderNoSelection, this.placeholderSearch = this.getAttribute("placeholder-search") || this._placeholderSearch, this.placeholderRoleSelect = this.getAttribute("placeholder-role-select") || this._placeholderRoleSelect, this._render(), this.inputAreaWrapper = this.querySelector(`.${B}`), this.inputElement = this.querySelector(`.${N}`), this.stagedItemPillContainer = this.querySelector(`.${$}`), this.optionsListElement = this.querySelector(`.${H}`), this.selectedItemsContainer = this.querySelector(`.${O}`), this.addButtonElement = this.querySelector(`.${D}`), this.preAddButtonElement = this.querySelector(`.${R}`), this.hiddenSelect = this.querySelector(`.${C}`), this.name && this.hiddenSelect && (this.hiddenSelect.name = this.name), this.hasAttribute("show-add-button") ? this.showAddButton = this.getAttribute("show-add-button") : this.setAttribute("show-add-button", String(this._showAddButton)), this.inputElement && (this.inputElement.placeholder = this.placeholderSearch), this.inputElement.addEventListener("input", this._handleInput), this.inputElement.addEventListener("keydown", this._handleInputKeyDown), this.inputElement.addEventListener("focus", this._handleFocus), this.inputElement.addEventListener("blur", this._handleBlur), this.optionsListElement.addEventListener("mousedown", this._handleOptionMouseDown), this.optionsListElement.addEventListener("click", this._handleOptionClick), this.addButtonElement.addEventListener("click", this._handleAddButtonClick), this.addEventListener("keydown", this._handleKeyDown), this._renderStagedPillOrInput(), this._updateAddButtonState(), this._updatePreAddButtonVisibility(), this._updateRootElementStateClasses(), this.hasAttribute("value")) { + if (this.placeholderNoSelection = this.getAttribute("placeholder-no-selection") || this._placeholderNoSelection, this.placeholderSearch = this.getAttribute("placeholder-search") || this._placeholderSearch, this.placeholderRoleSelect = this.getAttribute("placeholder-role-select") || this._placeholderRoleSelect, this._render(), this.inputAreaWrapper = this.querySelector(`.${D}`), this.inputElement = this.querySelector(`.${U}`), this.stagedItemPillContainer = this.querySelector(`.${H}`), this.optionsListElement = this.querySelector(`.${V}`), this.selectedItemsContainer = this.querySelector(`.${R}`), this.addButtonElement = this.querySelector(`.${F}`), this.preAddButtonElement = this.querySelector(`.${N}`), this.hiddenSelect = this.querySelector(`.${C}`), this.name && this.hiddenSelect && (this.hiddenSelect.name = this.name), this.hasAttribute("show-add-button") ? this.showAddButton = this.getAttribute("show-add-button") : this.setAttribute("show-add-button", String(this._showAddButton)), this.inputElement && (this.inputElement.placeholder = this.placeholderSearch), this.inputElement.addEventListener("input", this._handleInput), this.inputElement.addEventListener("keydown", this._handleInputKeyDown), this.inputElement.addEventListener("focus", this._handleFocus), this.inputElement.addEventListener("blur", this._handleBlur), this.optionsListElement.addEventListener("mousedown", this._handleOptionMouseDown), this.optionsListElement.addEventListener("click", this._handleOptionClick), this.addButtonElement.addEventListener("click", this._handleAddButtonClick), this.addEventListener("keydown", this._handleKeyDown), this._renderStagedPillOrInput(), this._updateAddButtonState(), this._updatePreAddButtonVisibility(), this._updateRootElementStateClasses(), this.hasAttribute("value")) { const t = this.getAttribute("value"); try { const e = JSON.parse(t); @@ -934,10 +934,10 @@ class X extends HTMLElement { this.disabledCallback(t); } disabledCallback(t) { - this.inputElement && (this.inputElement.disabled = t), this.classList.toggle("pointer-events-none", t), this.querySelectorAll(`.${M}`).forEach( + this.inputElement && (this.inputElement.disabled = t), this.classList.toggle("pointer-events-none", t), this.querySelectorAll(`.${P}`).forEach( (s) => s.disabled = t ); - const e = this.querySelector(`.${A}`); + const e = this.querySelector(`.${T}`); e && (e.disabled = t), this.hiddenSelect && (this.hiddenSelect.disabled = t), this._updateAddButtonState(), this._updatePreAddButtonVisibility(); } formResetCallback() { @@ -957,7 +957,7 @@ class X extends HTMLElement { this.internals_.setFormValue(null), this._synchronizeHiddenSelect(); } _updateRootElementStateClasses() { - this.classList.toggle(At, this._value.length === 0), this.classList.toggle(Ct, this._value.length > 0), this.classList.toggle(Tt, this._isOptionsListVisible), this.classList.toggle(yt, !!this._stagedItem); + this.classList.toggle($t, this._value.length === 0), this.classList.toggle(Pt, this._value.length > 0), this.classList.toggle(Nt, this._isOptionsListVisible), this.classList.toggle(Dt, !!this._stagedItem); } _render() { const t = this.id || `msr-${crypto.randomUUID().slice(0, 8)}`; @@ -968,27 +968,27 @@ class X extends HTMLElement { width: 0 !important; height: 0 !important; opacity: 0 !important; pointer-events: none !important; } -
    -
    - ${this._value.length === 0 ? `${this.placeholderNoSelection}` : ""} +
    +
    + ${this._value.length === 0 ? `${this.placeholderNoSelection}` : ""}
    -
    -
    - +
    +
    +
    - +
    - +
    `; @@ -1011,7 +1011,7 @@ class X extends HTMLElement { _renderStagedPillOrInput() { if (!(!this.stagedItemPillContainer || !this.inputElement || !this.inputAreaWrapper)) { if (this.stagedItemPillContainer.innerHTML = "", this._stagedItem && this._stagedItem.item) { - this.inputAreaWrapper.classList.remove(b), this.inputAreaWrapper.classList.add(I); + this.inputAreaWrapper.classList.remove(b), this.inputAreaWrapper.classList.add(A); const t = this._createStagedItemPillElement(this._stagedItem.item); this.stagedItemPillContainer.appendChild(t); const e = this._getAvailableRolesForItem(this._stagedItem.item.id), s = this._createStagedRoleSelectElement( @@ -1022,7 +1022,7 @@ class X extends HTMLElement { const n = this._createStagedCancelButtonElement(this._stagedItem.item.name); this.stagedItemPillContainer.appendChild(n), this.inputElement.classList.add("hidden"), this.inputElement.value = "", this.inputElement.removeAttribute("aria-activedescendant"), this.inputElement.setAttribute("aria-expanded", "false"); } else - this.inputAreaWrapper.classList.add(b), this.inputAreaWrapper.classList.remove(I), this.inputElement.classList.remove("hidden"); + this.inputAreaWrapper.classList.add(b), this.inputAreaWrapper.classList.remove(A), this.inputElement.classList.remove("hidden"); this._updateAddButtonState(), this._updatePreAddButtonVisibility(), this._updateRootElementStateClasses(); } } @@ -1041,15 +1041,15 @@ class X extends HTMLElement { const e = this._getItemById(t.itemId); if (!e) return null; const n = this.selectedItemTemplate.content.cloneNode(!0).firstElementChild, a = n.querySelector('[data-ref="textEl"]'); - let r = `${e.name}`, o = e.additional_data ? ` (${e.additional_data})` : "", d = ` ${t.role}`; - a.innerHTML = `${r}${o}${d}`; + let r = `${e.name}`, o = e.additional_data ? ` (${e.additional_data})` : "", h = ` ${t.role}`; + a.innerHTML = `${r}${o}${h}`; const c = n.querySelector('[data-ref="deleteBtn"]'); - return c.setAttribute("aria-label", `Entferne ${e.name} als ${t.role}`), c.dataset.instanceId = t.instanceId, c.disabled = this.hasAttribute("disabled"), c.addEventListener("click", (tt) => { - tt.stopPropagation(), this._handleDeleteSelectedItem(t.instanceId); + return c.setAttribute("aria-label", `Entferne ${e.name} als ${t.role}`), c.dataset.instanceId = t.instanceId, c.disabled = this.hasAttribute("disabled"), c.addEventListener("click", (ct) => { + ct.stopPropagation(), this._handleDeleteSelectedItem(t.instanceId); }), n; } _renderSelectedItems() { - this.selectedItemsContainer && (this.selectedItemsContainer.innerHTML = "", this._value.length === 0 ? this.selectedItemsContainer.innerHTML = `${this.placeholderNoSelection}` : this._value.forEach((t) => { + this.selectedItemsContainer && (this.selectedItemsContainer.innerHTML = "", this._value.length === 0 ? this.selectedItemsContainer.innerHTML = `${this.placeholderNoSelection}` : this._value.forEach((t) => { const e = this._createSelectedItemElement(t); e && this.selectedItemsContainer.appendChild(e); }), this._updateRootElementStateClasses()); @@ -1062,7 +1062,7 @@ class X extends HTMLElement { } _createOptionElement(t, e) { const n = this.optionTemplate.content.cloneNode(!0).firstElementChild; - return n.querySelector('[data-ref="nameEl"]').textContent = t.name, n.querySelector('[data-ref="detailEl"]').textContent = t.additional_data ? `(${t.additional_data})` : "", n.dataset.id = t.id, n.setAttribute("aria-selected", String(e === this._highlightedIndex)), n.id = `${this.id || "msr"}-option-${t.id}`, e === this._highlightedIndex && n.classList.add(U), n; + return n.querySelector('[data-ref="nameEl"]').textContent = t.name, n.querySelector('[data-ref="detailEl"]').textContent = t.additional_data ? `(${t.additional_data})` : "", n.dataset.id = t.id, n.setAttribute("aria-selected", String(e === this._highlightedIndex)), n.id = `${this.id || "msr"}-option-${t.id}`, e === this._highlightedIndex && n.classList.add(G), n; } _renderOptionsList() { if (!(!this.optionsListElement || !this.inputElement)) { @@ -1074,7 +1074,7 @@ class X extends HTMLElement { this.optionsListElement.appendChild(n); }); const t = this.optionsListElement.querySelector( - `.${U}` + `.${G}` ); t ? (t.scrollIntoView({ block: "nearest" }), this.inputElement.setAttribute("aria-activedescendant", t.id)) : this.inputElement.removeAttribute("aria-activedescendant"); } @@ -1086,7 +1086,7 @@ class X extends HTMLElement { return; this._stagedItem = { item: t, currentRole: "" }, this.inputElement && (this.inputElement.value = "", this.inputElement.setAttribute("aria-expanded", "false"), this.inputElement.removeAttribute("aria-activedescendant")), this._renderStagedPillOrInput(), this._hideOptionsList(); const s = this.stagedItemPillContainer.querySelector( - `.${A}` + `.${T}` ); s && !s.disabled ? s.focus() : this.addButtonElement && !this.addButtonElement.disabled && this.addButtonElement.focus(); } @@ -1123,7 +1123,7 @@ class X extends HTMLElement { if (!this.hasAttribute("disabled")) { if (t.key === "Enter" && this._stagedItem && this._stagedItem.item) { const s = document.activeElement, n = (e = this.stagedItemPillContainer) == null ? void 0 : e.querySelector( - `.${P}` + `.${q}` ); if (s === n) { t.preventDefault(), this._handleCancelStagedItem(t); @@ -1161,7 +1161,7 @@ class X extends HTMLElement { } _handleFocus() { if (!(this.hasAttribute("disabled") || this.inputElement && this.inputElement.disabled || this._stagedItem)) { - if (!this._stagedItem && this.inputAreaWrapper && (this.inputAreaWrapper.classList.add(b), this.inputAreaWrapper.classList.remove(I)), this.inputElement && this.inputElement.value.length > 0) { + if (!this._stagedItem && this.inputAreaWrapper && (this.inputAreaWrapper.classList.add(b), this.inputAreaWrapper.classList.remove(A)), this.inputElement && this.inputElement.value.length > 0) { const t = this.inputElement.value.toLowerCase(); this._filteredOptions = this._options.filter((e) => this._getAvailableRolesForItem(e.id).length === 0 ? !1 : e.name.toLowerCase().includes(t) || e.additional_data && e.additional_data.toLowerCase().includes(t)), this._filteredOptions.length > 0 ? (this._isOptionsListVisible = !0, this._highlightedIndex = 0, this._renderOptionsList()) : this._hideOptionsList(); } else @@ -1180,7 +1180,7 @@ class X extends HTMLElement { } _handleOptionClick(t) { if (this.hasAttribute("disabled")) return; - const e = t.target.closest(`li[data-id].${q}`); + const e = t.target.closest(`li[data-id].${W}`); if (e) { const s = e.dataset.id, n = this._filteredOptions.find((a) => a.id === s); n && this._stageItem(n); @@ -1190,9 +1190,9 @@ class X extends HTMLElement { this.hasAttribute("disabled") || (this._value = this._value.filter((e) => e.instanceId !== t), this._updateFormValue(), this._renderSelectedItems(), this._stagedItem && this._stagedItem.item && this._renderStagedPillOrInput(), this.inputElement && this.inputElement.focus(), this._updatePreAddButtonVisibility()); } } -u(X, "formAssociated", !0); -const wt = "mss-component-wrapper", F = "mss-selected-items-container", xt = "mss-selected-item-pill", Ot = "mss-selected-item-text", kt = "mss-selected-item-pill-detail", V = "mss-selected-item-delete-btn", W = "mss-input-controls-container", G = "mss-input-wrapper", z = "mss-input-wrapper-focused", K = "mss-text-input", j = "mss-create-new-button", Q = "mss-options-list", Mt = "mss-option-item", Rt = "mss-option-item-name", Bt = "mss-option-item-detail", J = "mss-option-item-highlighted", T = "mss-hidden-select", $t = "mss-no-items-text", Pt = "mss-state-no-selection", Nt = "mss-state-has-selection", Dt = "mss-state-list-open"; -class Y extends HTMLElement { +u(ot, "formAssociated", !0); +const Ht = "mss-component-wrapper", z = "mss-selected-items-container", qt = "mss-selected-item-pill", Ut = "mss-selected-item-text", Ft = "mss-selected-item-pill-detail", K = "mss-selected-item-delete-btn", j = "mss-input-controls-container", Q = "mss-input-wrapper", J = "mss-input-wrapper-focused", X = "mss-text-input", Y = "mss-create-new-button", Z = "mss-options-list", Vt = "mss-option-item", Wt = "mss-option-item-name", Gt = "mss-option-item-detail", tt = "mss-option-item-highlighted", y = "mss-hidden-select", zt = "mss-no-items-text", Kt = "mss-state-no-selection", jt = "mss-state-has-selection", Qt = "mss-state-list-open"; +class ht extends HTMLElement { constructor() { super(); u(this, "_blurTimeout", null); @@ -1219,15 +1219,15 @@ class Y extends HTMLElement { } _setupTemplates() { this.optionTemplate = document.createElement("template"), this.optionTemplate.innerHTML = ` -
  • - - +
  • + +
  • `, this.selectedItemTemplate = document.createElement("template"), this.selectedItemTemplate.innerHTML = ` - - - - + + + + `; } @@ -1280,7 +1280,7 @@ class Y extends HTMLElement { this.setAttribute("name", t), this.hiddenSelect && (this.hiddenSelect.name = t); } connectedCallback() { - if (this._render(), this.inputControlsContainer = this.querySelector(`.${W}`), this.inputWrapper = this.querySelector(`.${G}`), this.inputElement = this.querySelector(`.${K}`), this.createNewButton = this.querySelector(`.${j}`), this.optionsListElement = this.querySelector(`.${Q}`), this.selectedItemsContainer = this.querySelector(`.${F}`), this.hiddenSelect = this.querySelector(`.${T}`), this.placeholder = this.getAttribute("placeholder") || "Search items...", this.showCreateButton = this.getAttribute("show-create-button") !== "false", this.name && this.hiddenSelect && (this.hiddenSelect.name = this.name), this.inputElement.addEventListener("input", this._handleInput), this.inputElement.addEventListener("keydown", this._handleKeyDown), this.inputElement.addEventListener("focus", this._handleFocus), this.inputElement.addEventListener("blur", this._handleBlur), this.optionsListElement.addEventListener("mousedown", this._handleOptionMouseDown), this.optionsListElement.addEventListener("click", this._handleOptionClick), this.createNewButton.addEventListener("click", this._handleCreateNewButtonClick), this.selectedItemsContainer.addEventListener("click", this._handleSelectedItemsContainerClick), this._updateRootElementStateClasses(), this.hasAttribute("value")) { + if (this._render(), this.inputControlsContainer = this.querySelector(`.${j}`), this.inputWrapper = this.querySelector(`.${Q}`), this.inputElement = this.querySelector(`.${X}`), this.createNewButton = this.querySelector(`.${Y}`), this.optionsListElement = this.querySelector(`.${Z}`), this.selectedItemsContainer = this.querySelector(`.${z}`), this.hiddenSelect = this.querySelector(`.${y}`), this.placeholder = this.getAttribute("placeholder") || "Search items...", this.showCreateButton = this.getAttribute("show-create-button") !== "false", this.name && this.hiddenSelect && (this.hiddenSelect.name = this.name), this.inputElement.addEventListener("input", this._handleInput), this.inputElement.addEventListener("keydown", this._handleKeyDown), this.inputElement.addEventListener("focus", this._handleFocus), this.inputElement.addEventListener("blur", this._handleBlur), this.optionsListElement.addEventListener("mousedown", this._handleOptionMouseDown), this.optionsListElement.addEventListener("click", this._handleOptionClick), this.createNewButton.addEventListener("click", this._handleCreateNewButtonClick), this.selectedItemsContainer.addEventListener("click", this._handleSelectedItemsContainerClick), this._updateRootElementStateClasses(), this.hasAttribute("value")) { const t = this.getAttribute("value"); try { this.value = JSON.parse(t); @@ -1335,35 +1335,35 @@ class Y extends HTMLElement { this.internals_.setFormValue(null), this._synchronizeHiddenSelect(); } disabledCallback(t) { - this.inputElement && (this.inputElement.disabled = t), this.createNewButton && (this.createNewButton.disabled = t), this.toggleAttribute("disabled", t), this.querySelectorAll(`.${V}`).forEach( + this.inputElement && (this.inputElement.disabled = t), this.createNewButton && (this.createNewButton.disabled = t), this.toggleAttribute("disabled", t), this.querySelectorAll(`.${K}`).forEach( (e) => e.disabled = t ), this.hiddenSelect && (this.hiddenSelect.disabled = t), t && this._hideOptionsList(); } _updateRootElementStateClasses() { - this.classList.toggle(Pt, this._value.length === 0), this.classList.toggle(Nt, this._value.length > 0), this.classList.toggle(Dt, this._isOptionsListVisible); + this.classList.toggle(Kt, this._value.length === 0), this.classList.toggle(jt, this._value.length > 0), this.classList.toggle(Qt, this._isOptionsListVisible); } _render() { const t = this.id || `mss-${crypto.randomUUID().slice(0, 8)}`; this.id || this.setAttribute("id", t), this.innerHTML = ` -
    -
    -
    -
    +
    +
    +
    +
    - +
    - - + +
    `; } @@ -1371,12 +1371,12 @@ class Y extends HTMLElement { const e = this._getItemById(t); if (!e) return null; const n = this.selectedItemTemplate.content.cloneNode(!0).firstElementChild, a = n.querySelector('[data-ref="textEl"]'), r = n.querySelector('[data-ref="detailEl"]'), o = n.querySelector('[data-ref="deleteBtn"]'); - return a.textContent = e.name, e.additional_data ? (r.textContent = `(${e.additional_data})`, r.classList.remove("hidden")) : r.classList.add("hidden"), o.setAttribute("aria-label", `Remove ${e.name}`), o.dataset.id = t, o.disabled = this.hasAttribute("disabled"), o.addEventListener("click", (d) => { - d.stopPropagation(), this._handleDeleteSelectedItem(t); + return a.textContent = e.name, e.additional_data ? (r.textContent = `(${e.additional_data})`, r.classList.remove("hidden")) : r.classList.add("hidden"), o.setAttribute("aria-label", `Remove ${e.name}`), o.dataset.id = t, o.disabled = this.hasAttribute("disabled"), o.addEventListener("click", (h) => { + h.stopPropagation(), this._handleDeleteSelectedItem(t); }), n; } _renderSelectedItems() { - this.selectedItemsContainer && (this.selectedItemsContainer.innerHTML = "", this._value.length === 0 ? this.selectedItemsContainer.innerHTML = `No items selected` : this._value.forEach((t) => { + this.selectedItemsContainer && (this.selectedItemsContainer.innerHTML = "", this._value.length === 0 ? this.selectedItemsContainer.innerHTML = `No items selected` : this._value.forEach((t) => { const e = this._createSelectedItemElement(t); e && this.selectedItemsContainer.appendChild(e); }), this._updateRootElementStateClasses()); @@ -1385,7 +1385,7 @@ class Y extends HTMLElement { const n = this.optionTemplate.content.cloneNode(!0).firstElementChild, a = n.querySelector('[data-ref="nameEl"]'), r = n.querySelector('[data-ref="detailEl"]'); a.textContent = t.name, r.textContent = t.additional_data ? `(${t.additional_data})` : "", n.dataset.id = t.id, n.setAttribute("aria-selected", String(e === this._highlightedIndex)); const o = `option-${this.id || "mss"}-${t.id}`; - return n.id = o, e === this._highlightedIndex && (n.classList.add(J), this.inputElement && this.inputElement.setAttribute("aria-activedescendant", o)), n; + return n.id = o, e === this._highlightedIndex && (n.classList.add(tt), this.inputElement && this.inputElement.setAttribute("aria-activedescendant", o)), n; } _renderOptionsList() { if (!(!this.optionsListElement || !this.inputElement)) { @@ -1397,7 +1397,7 @@ class Y extends HTMLElement { this.optionsListElement.appendChild(n); }); const t = this.optionsListElement.querySelector( - `.${J}` + `.${tt}` ); t && (t.scrollIntoView({ block: "nearest" }), this.inputElement.setAttribute("aria-activedescendant", t.id)); } @@ -1461,10 +1461,10 @@ class Y extends HTMLElement { this._isOptionsListVisible = !1, this._highlightedIndex = -1, this.optionsListElement && this._renderOptionsList(); } _handleFocus() { - this.inputElement.disabled || (this.inputWrapper && this.inputWrapper.classList.add(z), this.inputElement.value.length > 0 && this._handleInput({ target: this.inputElement }), this._updateRootElementStateClasses()); + this.inputElement.disabled || (this.inputWrapper && this.inputWrapper.classList.add(J), this.inputElement.value.length > 0 && this._handleInput({ target: this.inputElement }), this._updateRootElementStateClasses()); } _handleBlur() { - this.inputWrapper && this.inputWrapper.classList.remove(z), this._blurTimeout = setTimeout(() => { + this.inputWrapper && this.inputWrapper.classList.remove(J), this._blurTimeout = setTimeout(() => { this.contains(document.activeElement) || this._hideOptionsList(); }, 150); } @@ -1482,9 +1482,9 @@ class Y extends HTMLElement { this.value = this._value.filter((e) => e !== t), this.inputElement && this.inputElement.value && this._handleInput({ target: this.inputElement }), this.inputElement && !this.hasAttribute("disabled") && this.inputElement.focus(); } } -u(Y, "formAssociated", !0); -const Ht = "rbi-button", qt = "rbi-icon"; -class Ut extends HTMLElement { +u(ht, "formAssociated", !0); +const Jt = "rbi-button", Xt = "rbi-icon"; +class Yt extends HTMLElement { constructor() { super(), this.initialStates = /* @__PURE__ */ new Map(), this._controlledElements = [], this.button = null, this.lastOverallModifiedState = null, this.handleInputChange = this.handleInputChange.bind(this), this.handleReset = this.handleReset.bind(this); } @@ -1493,10 +1493,10 @@ class Ut extends HTMLElement { } connectedCallback() { const i = ` - `; @@ -1638,24 +1638,167 @@ class Ut extends HTMLElement { this.button.setAttribute("aria-label", i); } } -const Ft = "filter-list", Vt = "scroll-button", Wt = "tool-tip", Gt = "abbrev-tooltips", zt = "int-link", Kt = "popup-image", jt = "tab-list", Qt = "filter-pill", Jt = "image-reel", Xt = "multi-select-places", Yt = "multi-select-simple", Z = "reset-button"; -customElements.define(zt, ct); -customElements.define(Gt, p); -customElements.define(Ft, at); -customElements.define(Vt, rt); -customElements.define(Wt, ot); -customElements.define(Kt, ht); -customElements.define(jt, dt); -customElements.define(Qt, st); -customElements.define(Jt, ut); -customElements.define(Xt, X); -customElements.define(Yt, Y); -customElements.define(Z, Ut); -function Zt() { +const w = "div-menu-button", et = "ts-menu-popup", it = "ts-menu-list", Zt = "menu-label", st = "ts-menu-placeholder-message", te = "ts-menu-list-item", x = "ts-menu-item-action", nt = "ts-item-is-selected", m = "hidden", M = "ts-menu-button--disabled", lt = "ts-menu-label--in-menu", at = "ts-menu-label--displayed", rt = "ts-target-placeholder"; +class ee extends HTMLElement { + constructor() { + super(), this._menuItemsMap = /* @__PURE__ */ new Map(), this._targetElement = null, this._originalChildDivs = [], this._observer = null, this._menuPlaceholderMessageElement = null, this._menuButton = null, this._toggleMenu = this._toggleMenu.bind(this), this._handleMenuItemClick = this._handleMenuItemClick.bind(this), this._handleClickOutside = this._handleClickOutside.bind(this), this._handleContentClose = this._handleContentClose.bind(this), this._handleMutations = this._handleMutations.bind(this), this._checkMenuPlaceholderAndButton = this._checkMenuPlaceholderAndButton.bind(this), this._clearFormElements = this._clearFormElements.bind(this), this._refreshTargetOrder = this._refreshTargetOrder.bind(this); + } + connectedCallback() { + this._menuButton = this.querySelector(`.${w}`), this._menuButton || console.error(`TabSelectorMenu: User-provided menu button with class '${w}' not found.`), this._originalChildDivs = Array.from(this.children).filter((e) => e.nodeType === Node.ELEMENT_NODE && e.tagName === "DIV" && !e.classList.contains(w)), this._originalChildDivs.forEach((e) => e.remove()); + const i = ` +
    +
      +
    • All items are currently shown.
    • +
    +
    + `; + if (this.insertAdjacentHTML("beforeend", i), this._menuPopupElement = this.querySelector(`.${et}`), this._menuListElement = this.querySelector(`.${it}`), this._menuPlaceholderMessageElement = this.querySelector(`.${st}`), !this._menuPopupElement || !this._menuListElement || !this._menuPlaceholderMessageElement) { + console.error("CRITICAL: Popup structure parts missing."); + return; + } + const t = this.getAttribute("target-id"); + t ? (this._targetElement = document.getElementById(t), this._targetElement || console.warn(`TabSelectorMenu: Target ID '${t}' not found.`)) : console.warn("TabSelectorMenu: 'target-id' attribute missing."), this._observer = new MutationObserver(this._handleMutations), this._originalChildDivs.forEach((e) => { + const s = e.querySelector("label." + Zt), n = e.dataset.value; + if (!s || !n) { + console.warn('TabSelectorMenu: Source div missing
    + +
    {{ template "_usermessage" $model }} -
    + + +
    +
    + + +
    + +
    + +
    +
    + +
    + + + + +
    +
    + +
    + + +
    +
    + +
    + +
    +
    + +
    + + +
    +
    + +
    + +
    +
    + +
    + + +
    +
    + +
    + +
    +
    + +
    + + +
    +
    + +
    +
    diff --git a/views/transform/div-menu.js b/views/transform/div-menu.js index 4192197..77c2ade 100644 --- a/views/transform/div-menu.js +++ b/views/transform/div-menu.js @@ -1,6 +1,9 @@ +// Define CSS class names as constants, above the component class const USER_PROVIDED_MENU_BUTTON_CLASS = "div-menu-button"; +const TS_MENU_COMPONENT = "ts-menu"; const TS_POPUP = "ts-menu-popup"; const TS_LIST = "ts-menu-list"; +const TS_MENU_LABEL = "menu-label"; const TS_PLACEHOLDER_MESSAGE = "ts-menu-placeholder-message"; const TS_LIST_ITEM = "ts-menu-list-item"; const TS_ITEM_ACTION = "ts-menu-item-action"; @@ -8,9 +11,9 @@ const TS_ITEM_IS_SELECTED = "ts-item-is-selected"; const TS_CONTENT_CLOSE_BUTTON = "ts-content-close-button"; const TAILWIND_HIDDEN_CLASS = "hidden"; const TS_MENU_BUTTON_STATE_DISABLED = "ts-menu-button--disabled"; -// New constants for menu label states const TS_MENU_LABEL_IN_MENU_STATE = "ts-menu-label--in-menu"; const TS_MENU_LABEL_DISPLAYED_STATE = "ts-menu-label--displayed"; +const TS_TARGET_PLACEHOLDER_CLASS = "ts-target-placeholder"; // For the target area placeholder // // Prereq: child divs must have prop data-value, and a label element // the label element must have class "menu-label" @@ -76,7 +79,7 @@ export class DivMenu extends HTMLElement { this._observer = new MutationObserver(this._handleMutations); this._originalChildDivs.forEach((sourceDiv) => { - const menuLabelElement = sourceDiv.querySelector("label.menu-label"); + const menuLabelElement = sourceDiv.querySelector("label." + TS_MENU_LABEL); const itemValue = sourceDiv.dataset.value; if (!menuLabelElement || !itemValue) { @@ -84,14 +87,6 @@ export class DivMenu extends HTMLElement { return; } - const closeButton = document.createElement("button"); - closeButton.type = "button"; - closeButton.className = TS_CONTENT_CLOSE_BUTTON; - closeButton.innerHTML = "×"; - closeButton.dataset.value = itemValue; - closeButton.addEventListener("click", this._handleContentClose); - sourceDiv.prepend(closeButton); - const isInitiallySelected = !sourceDiv.classList.contains(TAILWIND_HIDDEN_CLASS); this.appendChild(sourceDiv); @@ -135,12 +130,6 @@ export class DivMenu extends HTMLElement { if (this._observer) { this._observer.disconnect(); } - this._menuItemsMap.forEach((itemData) => { - const closeButton = itemData.sourceDiv.querySelector(`.${TS_CONTENT_CLOSE_BUTTON}`); - if (closeButton) { - closeButton.removeEventListener("click", this._handleContentClose); - } - }); if (this._menuButton) { this._menuButton.removeEventListener("click", this._toggleMenu); } @@ -202,7 +191,6 @@ export class DivMenu extends HTMLElement { if (!hasSelectedItems) { const placeholder = document.createElement("p"); placeholder.className = TS_TARGET_PLACEHOLDER_CLASS; - placeholder.innerHTML = "Selected content will appear here."; this._targetElement.appendChild(placeholder); } } @@ -255,10 +243,11 @@ export class DivMenu extends HTMLElement { } _toggleMenu(event) { + event.preventDefault(); + event.stopPropagation(); if (this._menuButton && this._menuButton.classList.contains(TS_MENU_BUTTON_STATE_DISABLED)) { return; } - event.stopPropagation(); const isHidden = this._menuPopupElement.style.display === "none" || this._menuPopupElement.style.display === ""; if (isHidden) { this._checkMenuPlaceholderAndButton(); diff --git a/views/transform/form.css b/views/transform/form.css index 6f90ce7..4960f7b 100644 --- a/views/transform/form.css +++ b/views/transform/form.css @@ -1,8 +1,8 @@ @layer components { .dbform .inputwrapper { - @apply rounded-xs border-2 border-transparent px-3 + @apply rounded-xs border-2 border-transparent pl-3 pr-1.5 py-1 pb-1.5 border-l-2 focus-within:border-l-slate-600 - bg-slate-200 focus-within:bg-slate-100 transition-all duration-100; + bg-stone-100 focus-within:bg-slate-100 transition-all duration-100; } .dbform .inputwrapper .inputlabel { @@ -22,6 +22,10 @@ @apply mt-1 block w-full focus:border-none focus:outline-none; } + .dbform .inputwrapper .inputtextarea { + @apply mt-1 block w-full focus:border-none focus:outline-none min-h-[20rem] resize-y; + } + .dbform .submitbutton { @apply w-full inline-flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-slate-700 hover:bg-slate-800 cursor-pointer focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-slate-500 active:bg-slate-900 transition-all duration-75; } @@ -30,6 +34,10 @@ @apply w-full inline-flex justify-center py-2 px-4 border border-transparent rounded-md text-sm font-medium text-gray-800 bg-stone-200 hover:bg-stone-300 cursor-pointer focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-slate-500 no-underline; } + .dbform div-menu { + @apply relative inline-block; + } + /* Multi-Select-Role example styles */ .msr-selected-items-container { @apply rounded-md; @@ -270,104 +278,28 @@ @apply disabled:hidden; } - .ts-menu { - position: relative; - display: inline-block; - } .ts-menu-popup { - display: none; - position: absolute; - top: 100%; - left: 0; - background-color: white; - border: 1px solid #ccc; - border-radius: 6px; - box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); - z-index: 1000; - min-width: 220px; /* Slightly wider for longer labels */ - margin-top: 4px; - } - .ts-menu-toggle-button { - padding: 10px 15px; - font-size: 1rem; - color: #ffffff; - background-color: #3498db; - border: none; - border-radius: 6px; - cursor: pointer; - transition: - background-color 0.2s ease, - opacity 0.2s ease; - } - .ts-menu-toggle-button:hover { - background-color: #2980b9; - } - .ts-menu-toggle-button:focus { - outline: 2px solid #2980b9; - outline-offset: 2px; - } - .ts-menu-toggle-button:disabled { - background-color: #bdc3c7; - cursor: not-allowed; - opacity: 0.7; + @apply hidden absolute top-full left-0 bg-white border border-gray-300 rounded-xs shadow z-50 min-w-[200px] mt-1; } + .ts-menu-list { list-style: none; - padding: 8px 0; + padding: 0px 0; margin: 0; } - .ts-menu-list-item { + + .ts-menu-list li { + @apply cursor-pointer ml-0 list-none px-2.5 py-1 hover:bg-gray-100 border-b; } - .ts-menu-placeholder-message { - padding: 10px 15px; - font-style: italic; - color: #7f8c8d; - text-align: center; - display: none; + + .ts-menu-list li:last-child { + @apply border-b-0; } - .ts-menu-item-action { - display: block; - width: 100%; - text-align: left; - padding: 10px 15px; - background: none; - border: none; - cursor: pointer; - font-size: 0.95rem; - color: #333; - transition: - background-color 0.2s ease, - color 0.2s ease; - } - .ts-menu-item-action:hover { - background-color: #ecf0f1; - } - .ts-item-is-selected { - font-weight: bold; - color: #2980b9; - background-color: #e8f4f8; - } - .ts-content-close-button { - position: absolute; - top: 8px; /* Adjusted for better alignment with padding */ - right: 8px; /* Adjusted */ - background-color: #e74c3c; - color: white; - border: none; - border-radius: 50%; - width: 22px; /* Slightly larger */ - height: 22px; /* Slightly larger */ - font-size: 13px; - line-height: 20px; - text-align: center; - cursor: pointer; - font-weight: bold; - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2); - transition: background-color 0.2s ease; - } - .ts-content-close-button:hover { - background-color: #c0392b; + + .ts-menu-list li button { + @apply w-full cursor-pointer text-left text-gray-700; } + .form-submit-button { margin-top: 20px; padding: 12px 20px;