Re-Implemented Div-Menu

This commit is contained in:
Simon Martens
2025-06-04 19:52:52 +02:00
parent 715be79115
commit 3a6dcc0e3d
7 changed files with 413 additions and 640 deletions

View File

@@ -1,11 +1,11 @@
var ut = Object.defineProperty; var ht = Object.defineProperty;
var O = (l) => { var O = (l) => {
throw TypeError(l); throw TypeError(l);
}; };
var mt = (l, i, t) => i in l ? ut(l, i, { enumerable: !0, configurable: !0, writable: !0, value: t }) : l[i] = t; var dt = (l, i, t) => i in l ? ht(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 p = (l, i, t) => dt(l, typeof i != "symbol" ? i + "" : i, t), A = (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); var T = (l, i, t) => (A(l, i, "read from private field"), t ? t.call(l) : i.get(l)), m = (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) => (A(l, i, "write to private field"), e ? e.call(l, t) : i.set(l, t), t), b = (l, i, t) => (A(l, i, "access private method"), t);
class pt extends HTMLElement { class ct extends HTMLElement {
constructor() { constructor() {
super(), this._value = "", this.render(); super(), this._value = "", this.render();
} }
@@ -74,13 +74,13 @@ class pt extends HTMLElement {
`; `;
} }
} }
const E = "filter-list-list", _t = "filter-list-item", ft = "filter-list-input", B = "filter-list-searchable"; const E = "filter-list-list", ut = "filter-list-item", pt = "filter-list-input", k = "filter-list-searchable";
var d, _, k; var d, f, M;
class gt extends HTMLElement { class mt extends HTMLElement {
constructor() { constructor() {
super(); super();
f(this, _); m(this, f);
f(this, d, !1); m(this, d, !1);
this._items = [], this._url = "", this._filterstart = !1, this._placeholder = "Liste filtern...", this._queryparam = "", this._startparams = null, this.render(); this._items = [], this._url = "", this._filterstart = !1, this._placeholder = "Liste filtern...", this._queryparam = "", this._startparams = null, this.render();
} }
static get observedAttributes() { static get observedAttributes() {
@@ -125,7 +125,7 @@ class gt extends HTMLElement {
let t = this.querySelector("#" + E); let t = this.querySelector("#" + E);
if (!t) if (!t)
return; return;
let e = new Mark(t.querySelectorAll("." + B)); let e = new Mark(t.querySelectorAll("." + k));
this._filter && e.mark(this._filter, { this._filter && e.mark(this._filter, {
separateWordSearch: !0 separateWordSearch: !0
}); });
@@ -165,7 +165,7 @@ class gt extends HTMLElement {
} }
getLinkText(t) { getLinkText(t) {
let e = this.getSearchText(t); let e = this.getSearchText(t);
return e === "" ? "" : `<span class="${B}">${e}</span>`; return e === "" ? "" : `<span class="${k}">${e}</span>`;
} }
getURL(t) { getURL(t) {
if (this._queryparam) { if (this._queryparam) {
@@ -187,7 +187,7 @@ class gt extends HTMLElement {
`, htmx && htmx.process(this); `, htmx && htmx.process(this);
} }
ActiveDot(t) { ActiveDot(t) {
return I(this, _, k).call(this, t), ""; return b(this, f, M).call(this, t), "";
} }
NoItems(t) { NoItems(t) {
return t.length === 0 ? '<div class="px-2 py-0.5 italic text-gray-500">Keine Einträge gefunden</div>' : ""; return t.length === 0 ? '<div class="px-2 py-0.5 italic text-gray-500">Keine Einträge gefunden</div>' : "";
@@ -200,7 +200,7 @@ class gt extends HTMLElement {
<input <input
type="text" type="text"
placeholder="${this._placeholder}" placeholder="${this._placeholder}"
class="${ft} w-full placeholder:italic px-2 py-0.5" /> class="${pt} w-full placeholder:italic px-2 py-0.5" />
</div> </div>
</div> </div>
`; `;
@@ -215,7 +215,7 @@ class gt extends HTMLElement {
t = this._items.filter((s) => e.every((n) => this.getSearchText(s).toLowerCase().includes(n.toLowerCase()))); t = this._items.filter((s) => e.every((n) => this.getSearchText(s).toLowerCase().includes(n.toLowerCase())));
} }
return ` return `
<div id="${E}" class="${E} pt-1 max-h-60 overflow-auto bg-stone-50 ${L(this, d) ? "hidden" : ""}"> <div id="${E}" class="${E} pt-1 max-h-60 overflow-auto bg-stone-50 ${T(this, d) ? "hidden" : ""}">
${t.map( ${t.map(
(e, s) => ` (e, s) => `
<a <a
@@ -224,8 +224,8 @@ class gt extends HTMLElement {
hx-swap="outerHTML show:none" hx-swap="outerHTML show:none"
hx-select="main" hx-select="main"
hx-target="main" hx-target="main"
class="${_t} block px-2.5 py-0.5 hover:bg-slate-200 no-underline ${s % 2 === 0 ? "bg-stone-100" : "bg-stone-50"}" class="${ut} 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"' : ""}> ${b(this, f, M).call(this, e) ? 'aria-current="page"' : ""}>
${this.ActiveDot(e)} ${this.ActiveDot(e)}
${this.getLinkText(e)} ${this.getLinkText(e)}
</a> </a>
@@ -236,13 +236,13 @@ class gt extends HTMLElement {
`; `;
} }
} }
d = new WeakMap(), _ = new WeakSet(), k = function(t) { d = new WeakMap(), f = new WeakSet(), M = function(t) {
if (!t) if (!t)
return !1; return !1;
let e = this.getHREF(t); 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); return e === "" ? !1 : this._queryparam && (new URLSearchParams(window.location.search).get(this._queryparam) || "") === e ? !0 : !!window.location.href.endsWith(e);
}; };
class Et extends HTMLElement { class _t extends HTMLElement {
constructor() { constructor() {
super(), this.handleScroll = this.handleScroll.bind(this), this.scrollToTop = this.scrollToTop.bind(this); super(), this.handleScroll = this.handleScroll.bind(this), this.scrollToTop = this.scrollToTop.bind(this);
} }
@@ -278,7 +278,7 @@ class Et extends HTMLElement {
window.scrollTo({ top: 0, behavior: "smooth" }); window.scrollTo({ top: 0, behavior: "smooth" });
} }
} }
class bt extends HTMLElement { class ft extends HTMLElement {
static get observedAttributes() { static get observedAttributes() {
return ["position", "timeout"]; return ["position", "timeout"];
} }
@@ -379,7 +379,7 @@ class bt extends HTMLElement {
} }
} }
} }
class St extends HTMLElement { class gt extends HTMLElement {
constructor() { constructor() {
super(), this.overlay = null, this._others = null, this._thisindex = -1, this._preview = null, this._description = null, this._imageURL = "", this._hideDLButton = !1; 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 St extends HTMLElement {
this.overlay.parentNode.removeChild(this.overlay), this.overlay = null; this.overlay.parentNode.removeChild(this.overlay), this.overlay = null;
} }
} }
class vt extends HTMLElement { class bt extends HTMLElement {
static get observedAttributes() { static get observedAttributes() {
} }
constructor() { constructor() {
@@ -575,7 +575,7 @@ class vt extends HTMLElement {
return null; return null;
} }
} }
class p extends HTMLElement { class _ extends HTMLElement {
static get observedAttributes() { static get observedAttributes() {
return ["data-text", "data-abbrevmap"]; return ["data-text", "data-abbrevmap"];
} }
@@ -638,7 +638,7 @@ class p extends HTMLElement {
}; };
} }
constructor() { constructor() {
super(), this._abbrevMap = p.defaultAbbrevMap; super(), this._abbrevMap = _.defaultAbbrevMap;
} }
connectedCallback() { connectedCallback() {
this.render(); this.render();
@@ -648,13 +648,13 @@ class p extends HTMLElement {
} }
_parseAndSetAbbrevMap(i) { _parseAndSetAbbrevMap(i) {
if (!i) { if (!i) {
this._abbrevMap = p.defaultAbbrevMap; this._abbrevMap = _.defaultAbbrevMap;
return; return;
} }
try { try {
this._abbrevMap = JSON.parse(i); this._abbrevMap = JSON.parse(i);
} catch { } catch {
this._abbrevMap = p.defaultAbbrevMap; this._abbrevMap = _.defaultAbbrevMap;
} }
} }
setAbbrevMap(i) { setAbbrevMap(i) {
@@ -704,7 +704,7 @@ class p extends HTMLElement {
return /\s|[.,;:!?]/.test(i); return /\s|[.,;:!?]/.test(i);
} }
} }
class Lt extends HTMLElement { class Et extends HTMLElement {
constructor() { constructor() {
super(); super();
} }
@@ -722,11 +722,11 @@ class Lt extends HTMLElement {
} }
} }
} }
var S; var L;
class It extends HTMLElement { class St extends HTMLElement {
constructor() { constructor() {
super(); super();
f(this, S, 176); m(this, L, 176);
this._images = []; this._images = [];
} }
connectedCallback() { connectedCallback() {
@@ -742,17 +742,17 @@ class It extends HTMLElement {
calculateShownImages() { calculateShownImages() {
const t = this.getBoundingClientRect(); const t = this.getBoundingClientRect();
console.log(t); console.log(t);
const e = Math.floor(t.width / (L(this, S) + 10)); const e = Math.floor(t.width / (T(this, L) + 10));
for (let s = 0; s < this._images.length; s++) for (let s = 0; s < this._images.length; s++)
s < e - 1 ? this._images[s].classList.remove("hidden") : this._images[s].classList.add("hidden"); s < e - 1 ? this._images[s].classList.remove("hidden") : this._images[s].classList.add("hidden");
} }
} }
S = new WeakMap(); L = 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"; const vt = "msr-component-wrapper", B = "msr-selected-items-container", R = "msr-placeholder-no-selection-text", Lt = "msr-selected-item-pill", It = "msr-selected-item-text", At = "msr-item-name", Tt = "msr-item-additional-data", Ct = "msr-selected-item-role", $ = "msr-selected-item-delete-btn", yt = "msr-controls-area", N = "msr-pre-add-button", P = "msr-input-area-wrapper", S = "msr-input-area-default-border", C = "msr-input-area-staged", D = "msr-staging-area-container", wt = "msr-staged-item-pill", xt = "msr-staged-item-text", y = "msr-staged-role-select", H = "msr-staged-cancel-btn", q = "msr-text-input", U = "msr-add-button", F = "msr-options-list", V = "msr-option-item", Mt = "msr-option-item-name", Ot = "msr-option-item-detail", W = "msr-option-item-highlighted", w = "msr-hidden-select", kt = "msr-state-no-selection", Bt = "msr-state-has-selection", Rt = "msr-state-list-open", $t = "msr-state-item-staged";
class ot extends HTMLElement { class nt extends HTMLElement {
constructor() { constructor() {
super(); super();
u(this, "_blurTimeout", null); p(this, "_blurTimeout", null);
this.internals_ = this.attachInternals(), this._value = [], this._stagedItem = null, this._showAddButton = !0, this._placeholderNoSelection = "Keine Elemente ausgewählt", this._placeholderSearch = "Elemente suchen...", this._placeholderRoleSelect = "Rolle auswählen...", this._options = [], this._roles = [ this.internals_ = this.attachInternals(), this._value = [], this._stagedItem = null, this._showAddButton = !0, this._placeholderNoSelection = "Keine Elemente ausgewählt", this._placeholderSearch = "Elemente suchen...", this._placeholderRoleSelect = "Rolle auswählen...", this._options = [], this._roles = [
"Leitung", "Leitung",
"Unterstützung", "Unterstützung",
@@ -828,23 +828,23 @@ class ot extends HTMLElement {
} }
_setupTemplates() { _setupTemplates() {
this.optionTemplate = document.createElement("template"), this.optionTemplate.innerHTML = ` this.optionTemplate = document.createElement("template"), this.optionTemplate.innerHTML = `
<li role="option" class="${W} group"> <li role="option" class="${V} group">
<span data-ref="nameEl" class="${Bt}"></span> <span data-ref="nameEl" class="${Mt}"></span>
<span data-ref="detailEl" class="${Rt}"></span> <span data-ref="detailEl" class="${Ot}"></span>
</li> </li>
`, this.selectedItemTemplate = document.createElement("template"), this.selectedItemTemplate.innerHTML = ` `, this.selectedItemTemplate = document.createElement("template"), this.selectedItemTemplate.innerHTML = `
<span class="${Tt} group"> <span class="${Lt} group">
<span data-ref="textEl" class="${Ct}"></span> <span data-ref="textEl" class="${It}"></span>
<button type="button" data-ref="deleteBtn" class="${P} ml-2">&times;</button> <button type="button" data-ref="deleteBtn" class="${$} ml-2">&times;</button>
</span> </span>
`, this.stagedPlacePillTemplate = document.createElement("template"), this.stagedPlacePillTemplate.innerHTML = ` `, this.stagedPlacePillTemplate = document.createElement("template"), this.stagedPlacePillTemplate.innerHTML = `
<span class="${kt} flex items-center"> <span class="${wt} flex items-center">
<span data-ref="nameEl" class="${Ot}"></span> <span data-ref="nameEl" class="${xt}"></span>
</span> </span>
`, this.stagedCancelBtnTemplate = document.createElement("template"), this.stagedCancelBtnTemplate.innerHTML = ` `, this.stagedCancelBtnTemplate = document.createElement("template"), this.stagedCancelBtnTemplate.innerHTML = `
<button type="button" class="${q} flex items-center justify-center">&times;</button> <button type="button" class="${H} flex items-center justify-center">&times;</button>
`, this.stagedRoleSelectTemplate = document.createElement("template"), this.stagedRoleSelectTemplate.innerHTML = ` `, this.stagedRoleSelectTemplate = document.createElement("template"), this.stagedRoleSelectTemplate.innerHTML = `
<select class="${T}"> <select class="${y}">
</select> </select>
`; `;
} }
@@ -883,9 +883,9 @@ class ot extends HTMLElement {
if (typeof a == "string") { if (typeof a == "string") {
const r = a.split(","); const r = a.split(",");
if (r.length === 2) { if (r.length === 2) {
const o = r[0].trim(), h = r[1].trim(); const o = r[0].trim(), c = r[1].trim();
if (this._getItemById(o) && this._roles.includes(h)) if (this._getItemById(o) && this._roles.includes(c))
return { itemId: o, role: h, instanceId: crypto.randomUUID() }; return { itemId: o, role: c, instanceId: crypto.randomUUID() };
} }
} }
return null; return null;
@@ -906,7 +906,7 @@ class ot extends HTMLElement {
this.setAttribute("name", t), this.hiddenSelect && (this.hiddenSelect.name = t); this.setAttribute("name", t), this.hiddenSelect && (this.hiddenSelect.name = t);
} }
connectedCallback() { 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(`.${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")) { 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(`.${P}`), this.inputElement = this.querySelector(`.${q}`), this.stagedItemPillContainer = this.querySelector(`.${D}`), this.optionsListElement = this.querySelector(`.${F}`), this.selectedItemsContainer = this.querySelector(`.${B}`), this.addButtonElement = this.querySelector(`.${U}`), this.preAddButtonElement = this.querySelector(`.${N}`), this.hiddenSelect = this.querySelector(`.${w}`), 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"); const t = this.getAttribute("value");
try { try {
const e = JSON.parse(t); const e = JSON.parse(t);
@@ -934,10 +934,10 @@ class ot extends HTMLElement {
this.disabledCallback(t); this.disabledCallback(t);
} }
disabledCallback(t) { disabledCallback(t) {
this.inputElement && (this.inputElement.disabled = t), this.classList.toggle("pointer-events-none", t), this.querySelectorAll(`.${P}`).forEach( this.inputElement && (this.inputElement.disabled = t), this.classList.toggle("pointer-events-none", t), this.querySelectorAll(`.${$}`).forEach(
(s) => s.disabled = t (s) => s.disabled = t
); );
const e = this.querySelector(`.${T}`); const e = this.querySelector(`.${y}`);
e && (e.disabled = t), this.hiddenSelect && (this.hiddenSelect.disabled = t), this._updateAddButtonState(), this._updatePreAddButtonVisibility(); e && (e.disabled = t), this.hiddenSelect && (this.hiddenSelect.disabled = t), this._updateAddButtonState(), this._updatePreAddButtonVisibility();
} }
formResetCallback() { formResetCallback() {
@@ -957,26 +957,26 @@ class ot extends HTMLElement {
this.internals_.setFormValue(null), this._synchronizeHiddenSelect(); this.internals_.setFormValue(null), this._synchronizeHiddenSelect();
} }
_updateRootElementStateClasses() { _updateRootElementStateClasses() {
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); this.classList.toggle(kt, this._value.length === 0), this.classList.toggle(Bt, this._value.length > 0), this.classList.toggle(Rt, this._isOptionsListVisible), this.classList.toggle($t, !!this._stagedItem);
} }
_render() { _render() {
const t = this.id || `msr-${crypto.randomUUID().slice(0, 8)}`; const t = this.id || `msr-${crypto.randomUUID().slice(0, 8)}`;
this.id || this.setAttribute("id", t), this.innerHTML = ` this.id || this.setAttribute("id", t), this.innerHTML = `
<style> <style>
.${C} { .${w} {
display: none !important; visibility: hidden !important; position: absolute !important; display: none !important; visibility: hidden !important; position: absolute !important;
width: 0 !important; height: 0 !important; opacity: 0 !important; pointer-events: none !important; width: 0 !important; height: 0 !important; opacity: 0 !important; pointer-events: none !important;
} }
</style> </style>
<div class="${At} relative"> <div class="${vt} relative">
<div class="${R} flex flex-wrap gap-1 mb-2 min-h-[2.625rem] rounded-md" aria-live="polite"> <div class="${B} flex flex-wrap gap-1 mb-2 min-h-[2.625rem] rounded-md" aria-live="polite">
${this._value.length === 0 ? `<span class="${$}">${this.placeholderNoSelection}</span>` : ""} ${this._value.length === 0 ? `<span class="${R}">${this.placeholderNoSelection}</span>` : ""}
</div> </div>
<div class="${Mt} flex items-center"> <div class="${yt} flex items-center">
<div class="${D} ${b} flex-grow min-h-[42px] flex items-center flex-wrap gap-1" tabindex="-1"> <div class="${P} ${S} flex-grow min-h-[42px] flex items-center flex-wrap gap-1" tabindex="-1">
<span class="${H} flex items-center gap-2"></span> <span class="${D} flex items-center gap-2"></span>
<input type="text" <input type="text"
class="${U} flex-1 min-w-[100px] outline-none" class="${q} flex-1 min-w-[100px] outline-none"
placeholder="${this.placeholderSearch}" placeholder="${this.placeholderSearch}"
aria-haspopup="listbox" aria-haspopup="listbox"
aria-expanded="false"> aria-expanded="false">
@@ -986,10 +986,10 @@ class ot extends HTMLElement {
aria-label="Element schnell hinzufügen"> aria-label="Element schnell hinzufügen">
+ +
</button> </button>
<button type="button" class="${F} hidden ml-2">Hinzufügen</button> <button type="button" class="${U} hidden ml-2">Hinzufügen</button>
</div> </div>
<ul role="listbox" id="${t}-options-list" class="${V} absolute z-20 w-full max-h-60 overflow-y-auto mt-1 hidden"></ul> <ul role="listbox" id="${t}-options-list" class="${F} absolute z-20 w-full max-h-60 overflow-y-auto mt-1 hidden"></ul>
<select multiple name="${this.getAttribute("name") || "items_with_roles_default"}" id="hidden-select-${t}" class="${C}" aria-hidden="true"></select> <select multiple name="${this.getAttribute("name") || "items_with_roles_default"}" id="hidden-select-${t}" class="${w}" aria-hidden="true"></select>
</div> </div>
`; `;
} }
@@ -1011,7 +1011,7 @@ class ot extends HTMLElement {
_renderStagedPillOrInput() { _renderStagedPillOrInput() {
if (!(!this.stagedItemPillContainer || !this.inputElement || !this.inputAreaWrapper)) { if (!(!this.stagedItemPillContainer || !this.inputElement || !this.inputAreaWrapper)) {
if (this.stagedItemPillContainer.innerHTML = "", this._stagedItem && this._stagedItem.item) { if (this.stagedItemPillContainer.innerHTML = "", this._stagedItem && this._stagedItem.item) {
this.inputAreaWrapper.classList.remove(b), this.inputAreaWrapper.classList.add(A); this.inputAreaWrapper.classList.remove(S), this.inputAreaWrapper.classList.add(C);
const t = this._createStagedItemPillElement(this._stagedItem.item); const t = this._createStagedItemPillElement(this._stagedItem.item);
this.stagedItemPillContainer.appendChild(t); this.stagedItemPillContainer.appendChild(t);
const e = this._getAvailableRolesForItem(this._stagedItem.item.id), s = this._createStagedRoleSelectElement( const e = this._getAvailableRolesForItem(this._stagedItem.item.id), s = this._createStagedRoleSelectElement(
@@ -1022,7 +1022,7 @@ class ot extends HTMLElement {
const n = this._createStagedCancelButtonElement(this._stagedItem.item.name); 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"); this.stagedItemPillContainer.appendChild(n), this.inputElement.classList.add("hidden"), this.inputElement.value = "", this.inputElement.removeAttribute("aria-activedescendant"), this.inputElement.setAttribute("aria-expanded", "false");
} else } else
this.inputAreaWrapper.classList.add(b), this.inputAreaWrapper.classList.remove(A), this.inputElement.classList.remove("hidden"); this.inputAreaWrapper.classList.add(S), this.inputAreaWrapper.classList.remove(C), this.inputElement.classList.remove("hidden");
this._updateAddButtonState(), this._updatePreAddButtonVisibility(), this._updateRootElementStateClasses(); this._updateAddButtonState(), this._updatePreAddButtonVisibility(), this._updateRootElementStateClasses();
} }
} }
@@ -1041,15 +1041,15 @@ class ot extends HTMLElement {
const e = this._getItemById(t.itemId); const e = this._getItemById(t.itemId);
if (!e) return null; if (!e) return null;
const n = this.selectedItemTemplate.content.cloneNode(!0).firstElementChild, a = n.querySelector('[data-ref="textEl"]'); const n = this.selectedItemTemplate.content.cloneNode(!0).firstElementChild, a = n.querySelector('[data-ref="textEl"]');
let r = `<span class="${yt}">${e.name}</span>`, o = e.additional_data ? ` <span class="${wt}">(${e.additional_data})</span>` : "", h = ` <span class="${xt}">${t.role}</span>`; let r = `<span class="${At}">${e.name}</span>`, o = e.additional_data ? ` <span class="${Tt}">(${e.additional_data})</span>` : "", c = ` <span class="${Ct}">${t.role}</span>`;
a.innerHTML = `${r}${o}${h}`; a.innerHTML = `${r}${o}${c}`;
const c = n.querySelector('[data-ref="deleteBtn"]'); const u = 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", (ct) => { return u.setAttribute("aria-label", `Entferne ${e.name} als ${t.role}`), u.dataset.instanceId = t.instanceId, u.disabled = this.hasAttribute("disabled"), u.addEventListener("click", (ot) => {
ct.stopPropagation(), this._handleDeleteSelectedItem(t.instanceId); ot.stopPropagation(), this._handleDeleteSelectedItem(t.instanceId);
}), n; }), n;
} }
_renderSelectedItems() { _renderSelectedItems() {
this.selectedItemsContainer && (this.selectedItemsContainer.innerHTML = "", this._value.length === 0 ? this.selectedItemsContainer.innerHTML = `<span class="${$}">${this.placeholderNoSelection}</span>` : this._value.forEach((t) => { this.selectedItemsContainer && (this.selectedItemsContainer.innerHTML = "", this._value.length === 0 ? this.selectedItemsContainer.innerHTML = `<span class="${R}">${this.placeholderNoSelection}</span>` : this._value.forEach((t) => {
const e = this._createSelectedItemElement(t); const e = this._createSelectedItemElement(t);
e && this.selectedItemsContainer.appendChild(e); e && this.selectedItemsContainer.appendChild(e);
}), this._updateRootElementStateClasses()); }), this._updateRootElementStateClasses());
@@ -1062,7 +1062,7 @@ class ot extends HTMLElement {
} }
_createOptionElement(t, e) { _createOptionElement(t, e) {
const n = this.optionTemplate.content.cloneNode(!0).firstElementChild; 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(G), 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(W), n;
} }
_renderOptionsList() { _renderOptionsList() {
if (!(!this.optionsListElement || !this.inputElement)) { if (!(!this.optionsListElement || !this.inputElement)) {
@@ -1074,7 +1074,7 @@ class ot extends HTMLElement {
this.optionsListElement.appendChild(n); this.optionsListElement.appendChild(n);
}); });
const t = this.optionsListElement.querySelector( const t = this.optionsListElement.querySelector(
`.${G}` `.${W}`
); );
t ? (t.scrollIntoView({ block: "nearest" }), this.inputElement.setAttribute("aria-activedescendant", t.id)) : this.inputElement.removeAttribute("aria-activedescendant"); t ? (t.scrollIntoView({ block: "nearest" }), this.inputElement.setAttribute("aria-activedescendant", t.id)) : this.inputElement.removeAttribute("aria-activedescendant");
} }
@@ -1086,7 +1086,7 @@ class ot extends HTMLElement {
return; 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(); 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( const s = this.stagedItemPillContainer.querySelector(
`.${T}` `.${y}`
); );
s && !s.disabled ? s.focus() : this.addButtonElement && !this.addButtonElement.disabled && this.addButtonElement.focus(); s && !s.disabled ? s.focus() : this.addButtonElement && !this.addButtonElement.disabled && this.addButtonElement.focus();
} }
@@ -1123,7 +1123,7 @@ class ot extends HTMLElement {
if (!this.hasAttribute("disabled")) { if (!this.hasAttribute("disabled")) {
if (t.key === "Enter" && this._stagedItem && this._stagedItem.item) { if (t.key === "Enter" && this._stagedItem && this._stagedItem.item) {
const s = document.activeElement, n = (e = this.stagedItemPillContainer) == null ? void 0 : e.querySelector( const s = document.activeElement, n = (e = this.stagedItemPillContainer) == null ? void 0 : e.querySelector(
`.${q}` `.${H}`
); );
if (s === n) { if (s === n) {
t.preventDefault(), this._handleCancelStagedItem(t); t.preventDefault(), this._handleCancelStagedItem(t);
@@ -1161,7 +1161,7 @@ class ot extends HTMLElement {
} }
_handleFocus() { _handleFocus() {
if (!(this.hasAttribute("disabled") || this.inputElement && this.inputElement.disabled || this._stagedItem)) { 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(A)), this.inputElement && this.inputElement.value.length > 0) { if (!this._stagedItem && this.inputAreaWrapper && (this.inputAreaWrapper.classList.add(S), this.inputAreaWrapper.classList.remove(C)), this.inputElement && this.inputElement.value.length > 0) {
const t = this.inputElement.value.toLowerCase(); 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(); 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 } else
@@ -1180,7 +1180,7 @@ class ot extends HTMLElement {
} }
_handleOptionClick(t) { _handleOptionClick(t) {
if (this.hasAttribute("disabled")) return; if (this.hasAttribute("disabled")) return;
const e = t.target.closest(`li[data-id].${W}`); const e = t.target.closest(`li[data-id].${V}`);
if (e) { if (e) {
const s = e.dataset.id, n = this._filteredOptions.find((a) => a.id === s); const s = e.dataset.id, n = this._filteredOptions.find((a) => a.id === s);
n && this._stageItem(n); n && this._stageItem(n);
@@ -1190,12 +1190,12 @@ class ot 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()); 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(ot, "formAssociated", !0); p(nt, "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"; const Nt = "mss-component-wrapper", G = "mss-selected-items-container", Pt = "mss-selected-item-pill", Dt = "mss-selected-item-text", Ht = "mss-selected-item-pill-detail", z = "mss-selected-item-delete-btn", K = "mss-input-controls-container", j = "mss-input-wrapper", Q = "mss-input-wrapper-focused", J = "mss-text-input", X = "mss-create-new-button", Y = "mss-options-list", qt = "mss-option-item", Ut = "mss-option-item-name", Ft = "mss-option-item-detail", Z = "mss-option-item-highlighted", x = "mss-hidden-select", Vt = "mss-no-items-text", Wt = "mss-state-no-selection", Gt = "mss-state-has-selection", zt = "mss-state-list-open";
class ht extends HTMLElement { class lt extends HTMLElement {
constructor() { constructor() {
super(); super();
u(this, "_blurTimeout", null); p(this, "_blurTimeout", null);
this.internals_ = this.attachInternals(), this._value = [], this._options = [ this.internals_ = this.attachInternals(), this._value = [], this._options = [
{ id: "marie_curie", name: "Marie Curie", additional_data: "Physicist and Chemist" }, { id: "marie_curie", name: "Marie Curie", additional_data: "Physicist and Chemist" },
{ id: "leonardo_da_vinci", name: "Leonardo da Vinci", additional_data: "Polymath" }, { id: "leonardo_da_vinci", name: "Leonardo da Vinci", additional_data: "Polymath" },
@@ -1219,15 +1219,15 @@ class ht extends HTMLElement {
} }
_setupTemplates() { _setupTemplates() {
this.optionTemplate = document.createElement("template"), this.optionTemplate.innerHTML = ` this.optionTemplate = document.createElement("template"), this.optionTemplate.innerHTML = `
<li role="option" class="${Vt}"> <li role="option" class="${qt}">
<span data-ref="nameEl" class="${Wt}"></span> <span data-ref="nameEl" class="${Ut}"></span>
<span data-ref="detailEl" class="${Gt}"></span> <span data-ref="detailEl" class="${Ft}"></span>
</li> </li>
`, this.selectedItemTemplate = document.createElement("template"), this.selectedItemTemplate.innerHTML = ` `, this.selectedItemTemplate = document.createElement("template"), this.selectedItemTemplate.innerHTML = `
<span class="${qt} flex items-center"> <span class="${Pt} flex items-center">
<span data-ref="textEl" class="${Ut}"></span> <span data-ref="textEl" class="${Dt}"></span>
<span data-ref="detailEl" class="${Ft} hidden"></span> <span data-ref="detailEl" class="${Ht} hidden"></span>
<button type="button" data-ref="deleteBtn" class="${K}">&times;</button> <button type="button" data-ref="deleteBtn" class="${z}">&times;</button>
</span> </span>
`; `;
} }
@@ -1280,7 +1280,7 @@ class ht extends HTMLElement {
this.setAttribute("name", t), this.hiddenSelect && (this.hiddenSelect.name = t); this.setAttribute("name", t), this.hiddenSelect && (this.hiddenSelect.name = t);
} }
connectedCallback() { connectedCallback() {
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")) { if (this._render(), this.inputControlsContainer = this.querySelector(`.${K}`), this.inputWrapper = this.querySelector(`.${j}`), this.inputElement = this.querySelector(`.${J}`), this.createNewButton = this.querySelector(`.${X}`), this.optionsListElement = this.querySelector(`.${Y}`), this.selectedItemsContainer = this.querySelector(`.${G}`), this.hiddenSelect = this.querySelector(`.${x}`), 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"); const t = this.getAttribute("value");
try { try {
this.value = JSON.parse(t); this.value = JSON.parse(t);
@@ -1335,35 +1335,35 @@ class ht extends HTMLElement {
this.internals_.setFormValue(null), this._synchronizeHiddenSelect(); this.internals_.setFormValue(null), this._synchronizeHiddenSelect();
} }
disabledCallback(t) { disabledCallback(t) {
this.inputElement && (this.inputElement.disabled = t), this.createNewButton && (this.createNewButton.disabled = t), this.toggleAttribute("disabled", t), this.querySelectorAll(`.${K}`).forEach( this.inputElement && (this.inputElement.disabled = t), this.createNewButton && (this.createNewButton.disabled = t), this.toggleAttribute("disabled", t), this.querySelectorAll(`.${z}`).forEach(
(e) => e.disabled = t (e) => e.disabled = t
), this.hiddenSelect && (this.hiddenSelect.disabled = t), t && this._hideOptionsList(); ), this.hiddenSelect && (this.hiddenSelect.disabled = t), t && this._hideOptionsList();
} }
_updateRootElementStateClasses() { _updateRootElementStateClasses() {
this.classList.toggle(Kt, this._value.length === 0), this.classList.toggle(jt, this._value.length > 0), this.classList.toggle(Qt, this._isOptionsListVisible); this.classList.toggle(Wt, this._value.length === 0), this.classList.toggle(Gt, this._value.length > 0), this.classList.toggle(zt, this._isOptionsListVisible);
} }
_render() { _render() {
const t = this.id || `mss-${crypto.randomUUID().slice(0, 8)}`; const t = this.id || `mss-${crypto.randomUUID().slice(0, 8)}`;
this.id || this.setAttribute("id", t), this.innerHTML = ` this.id || this.setAttribute("id", t), this.innerHTML = `
<style> <style>
.${y} { display: block !important; visibility: hidden !important; position: absolute !important; width: 0px !important; height: 0px !important; opacity: 0 !important; pointer-events: none !important; margin: -1px !important; padding: 0 !important; border: 0 !important; overflow: hidden !important; clip: rect(0, 0, 0, 0) !important; white-space: nowrap !important; } .${x} { display: block !important; visibility: hidden !important; position: absolute !important; width: 0px !important; height: 0px !important; opacity: 0 !important; pointer-events: none !important; margin: -1px !important; padding: 0 !important; border: 0 !important; overflow: hidden !important; clip: rect(0, 0, 0, 0) !important; white-space: nowrap !important; }
</style> </style>
<div class="${Ht} relative"> <div class="${Nt} relative">
<div class="${z} flex flex-wrap gap-1 mb-1 min-h-[38px]" aria-live="polite" tabindex="-1"></div> <div class="${G} flex flex-wrap gap-1 mb-1 min-h-[38px]" aria-live="polite" tabindex="-1"></div>
<div class="${j} flex items-center space-x-2"> <div class="${K} flex items-center space-x-2">
<div class="${Q} relative rounded-md flex items-center flex-grow"> <div class="${j} relative rounded-md flex items-center flex-grow">
<input type="text" <input type="text"
class="${X} w-full outline-none bg-transparent text-sm" class="${J} w-full outline-none bg-transparent text-sm"
placeholder="${this.placeholder}" placeholder="${this.placeholder}"
aria-autocomplete="list" aria-autocomplete="list"
aria-expanded="${this._isOptionsListVisible}" aria-expanded="${this._isOptionsListVisible}"
aria-controls="options-list-${t}" aria-controls="options-list-${t}"
autocomplete="off" autocorrect="off" autocapitalize="none" spellcheck="false" role="combobox" /> autocomplete="off" autocorrect="off" autocapitalize="none" spellcheck="false" role="combobox" />
</div> </div>
<button type="button" class="${Y} ${this.showCreateButton ? "" : "hidden"}" title="Create new item from input">+</button> <button type="button" class="${X} ${this.showCreateButton ? "" : "hidden"}" title="Create new item from input">+</button>
</div> </div>
<ul id="options-list-${t}" role="listbox" class="${Z} absolute z-20 w-full max-h-60 overflow-y-auto mt-1 hidden"></ul> <ul id="options-list-${t}" role="listbox" class="${Y} absolute z-20 w-full max-h-60 overflow-y-auto mt-1 hidden"></ul>
<select multiple name="${this.getAttribute("name") || "mss_default_name"}" id="hidden-select-${t}" class="${y}" aria-hidden="true"></select> <select multiple name="${this.getAttribute("name") || "mss_default_name"}" id="hidden-select-${t}" class="${x}" aria-hidden="true"></select>
</div> </div>
`; `;
} }
@@ -1371,12 +1371,12 @@ class ht extends HTMLElement {
const e = this._getItemById(t); const e = this._getItemById(t);
if (!e) return null; 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"]'); 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", (h) => { 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", (c) => {
h.stopPropagation(), this._handleDeleteSelectedItem(t); c.stopPropagation(), this._handleDeleteSelectedItem(t);
}), n; }), n;
} }
_renderSelectedItems() { _renderSelectedItems() {
this.selectedItemsContainer && (this.selectedItemsContainer.innerHTML = "", this._value.length === 0 ? this.selectedItemsContainer.innerHTML = `<span class="${zt}">No items selected</span>` : this._value.forEach((t) => { this.selectedItemsContainer && (this.selectedItemsContainer.innerHTML = "", this._value.length === 0 ? this.selectedItemsContainer.innerHTML = `<span class="${Vt}">No items selected</span>` : this._value.forEach((t) => {
const e = this._createSelectedItemElement(t); const e = this._createSelectedItemElement(t);
e && this.selectedItemsContainer.appendChild(e); e && this.selectedItemsContainer.appendChild(e);
}), this._updateRootElementStateClasses()); }), this._updateRootElementStateClasses());
@@ -1385,7 +1385,7 @@ class ht extends HTMLElement {
const n = this.optionTemplate.content.cloneNode(!0).firstElementChild, a = n.querySelector('[data-ref="nameEl"]'), r = n.querySelector('[data-ref="detailEl"]'); 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)); 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}`; const o = `option-${this.id || "mss"}-${t.id}`;
return n.id = o, e === this._highlightedIndex && (n.classList.add(tt), this.inputElement && this.inputElement.setAttribute("aria-activedescendant", o)), n; return n.id = o, e === this._highlightedIndex && (n.classList.add(Z), this.inputElement && this.inputElement.setAttribute("aria-activedescendant", o)), n;
} }
_renderOptionsList() { _renderOptionsList() {
if (!(!this.optionsListElement || !this.inputElement)) { if (!(!this.optionsListElement || !this.inputElement)) {
@@ -1397,7 +1397,7 @@ class ht extends HTMLElement {
this.optionsListElement.appendChild(n); this.optionsListElement.appendChild(n);
}); });
const t = this.optionsListElement.querySelector( const t = this.optionsListElement.querySelector(
`.${tt}` `.${Z}`
); );
t && (t.scrollIntoView({ block: "nearest" }), this.inputElement.setAttribute("aria-activedescendant", t.id)); t && (t.scrollIntoView({ block: "nearest" }), this.inputElement.setAttribute("aria-activedescendant", t.id));
} }
@@ -1461,10 +1461,10 @@ class ht extends HTMLElement {
this._isOptionsListVisible = !1, this._highlightedIndex = -1, this.optionsListElement && this._renderOptionsList(); this._isOptionsListVisible = !1, this._highlightedIndex = -1, this.optionsListElement && this._renderOptionsList();
} }
_handleFocus() { _handleFocus() {
this.inputElement.disabled || (this.inputWrapper && this.inputWrapper.classList.add(J), this.inputElement.value.length > 0 && this._handleInput({ target: this.inputElement }), this._updateRootElementStateClasses()); this.inputElement.disabled || (this.inputWrapper && this.inputWrapper.classList.add(Q), this.inputElement.value.length > 0 && this._handleInput({ target: this.inputElement }), this._updateRootElementStateClasses());
} }
_handleBlur() { _handleBlur() {
this.inputWrapper && this.inputWrapper.classList.remove(J), this._blurTimeout = setTimeout(() => { this.inputWrapper && this.inputWrapper.classList.remove(Q), this._blurTimeout = setTimeout(() => {
this.contains(document.activeElement) || this._hideOptionsList(); this.contains(document.activeElement) || this._hideOptionsList();
}, 150); }, 150);
} }
@@ -1482,9 +1482,9 @@ class ht 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(); 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(ht, "formAssociated", !0); p(lt, "formAssociated", !0);
const Jt = "rbi-button", Xt = "rbi-icon"; const Kt = "rbi-button", jt = "rbi-icon";
class Yt extends HTMLElement { class Qt extends HTMLElement {
constructor() { 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); 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 Yt extends HTMLElement {
} }
connectedCallback() { connectedCallback() {
const i = ` const i = `
<button type="button" class="${Jt} cursor-pointer disabled:cursor-default" aria-label="Reset field"> <button type="button" class="${Kt} cursor-pointer disabled:cursor-default" aria-label="Reset field">
<tool-tip position="right"> <tool-tip position="right">
<div class="data-tip">Feld zurücksetzen</div> <div class="data-tip">Feld zurücksetzen</div>
<span class="${Xt} ri-arrow-go-back-fill"></span> <span class="${jt} ri-arrow-go-back-fill"></span>
</tool-tip> </tool-tip>
</button> </button>
`; `;
@@ -1513,7 +1513,7 @@ class Yt extends HTMLElement {
updateControlledElements() { updateControlledElements() {
this._controlledElements.forEach((e) => { this._controlledElements.forEach((e) => {
e.removeEventListener("input", this.handleInputChange), e.removeEventListener("change", this.handleInputChange); e.removeEventListener("input", this.handleInputChange), e.removeEventListener("change", this.handleInputChange);
}), this._controlledElements = [], this.initialStates.clear(), this.lastOverallModifiedState = null; }), this._controlledElements = [], this.lastOverallModifiedState = null;
const i = (this.getAttribute("controls") || "").split(",").map((e) => e.trim()).filter((e) => e); const i = (this.getAttribute("controls") || "").split(",").map((e) => e.trim()).filter((e) => e);
if (!i.length && this.button) { if (!i.length && this.button) {
this.button.disabled = !0, this.button.setAttribute("aria-disabled", "true"), this.checkIfModified(); this.button.disabled = !0, this.button.setAttribute("aria-disabled", "true"), this.checkIfModified();
@@ -1526,6 +1526,8 @@ class Yt extends HTMLElement {
}), this._controlledElements = t, this.button && (this.button.disabled = this._controlledElements.length === 0, this.button.setAttribute("aria-controls", this._controlledElements.map((e) => e.id).join(" ")), this.button.disabled ? this.button.setAttribute("aria-disabled", "true") : this.button.removeAttribute("aria-disabled")), this.checkIfModified(); }), this._controlledElements = t, this.button && (this.button.disabled = this._controlledElements.length === 0, this.button.setAttribute("aria-controls", this._controlledElements.map((e) => e.id).join(" ")), this.button.disabled ? this.button.setAttribute("aria-disabled", "true") : this.button.removeAttribute("aria-disabled")), this.checkIfModified();
} }
storeInitialState(i) { storeInitialState(i) {
if (this.initialStates.has(i.id))
return;
let t; let t;
switch (i.type) { switch (i.type) {
case "checkbox": case "checkbox":
@@ -1638,167 +1640,113 @@ class Yt extends HTMLElement {
this.button.setAttribute("aria-label", i); this.button.setAttribute("aria-label", i);
} }
} }
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"; const h = "hidden", tt = "dm-stay", et = "dm-title", it = "dm-menu-button", Jt = "dm-target", v = "dm-menu", st = "dm-menu-item", Xt = "dm-close-button";
class ee extends HTMLElement { var I, at;
class Yt extends HTMLElement {
constructor() { 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); super();
m(this, I);
b(this, I, at).call(this);
} }
connectedCallback() { 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()); if (this._cildren = Array.from(this.children).filter((t) => t.nodeType === Node.ELEMENT_NODE && !t.classList.contains(it)).map((t) => ({
const i = ` node: t,
<div class="${et}"> stay: () => t.hasAttribute(tt) && t.getAttribute(tt) == "true",
<ul class="${it}"> hidden: () => t.classList.contains(h),
<li class="${st}"></li> name: () => {
</ul> const e = t.querySelector("label");
</div> return e ? e.innerHTML : t.hasAttribute(et) ? t.getAttribute(et) : "";
`; }
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) { })), this._target = document.getElementById(this.getAttribute(Jt)), this._target || (this._target = this), this._button = this.querySelector(`.${it}`), !this._button) {
console.error("CRITICAL: Popup structure parts missing."); console.error("DivManagerMenu needs a button element.");
return; return;
} }
const t = this.getAttribute("target-id"); for (const t of this._cildren)
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) => { this.removeChild(t.node);
const s = e.querySelector("label." + Zt), n = e.dataset.value; this._button.addEventListener("click", this._toggleMenu.bind(this)), this._button.classList.add("relative");
if (!s || !n) { for (const t of this._cildren)
console.warn('TabSelectorMenu: Source div missing <label class="menu-label"> or data-value:', e); t.node.querySelectorAll(`.${Xt}`).forEach((s) => {
s.addEventListener("click", (n) => {
this.hideDiv(n, t.node);
});
});
this.renderMenu(), this.renderIntoTarget();
}
_toggleMenu(t) {
if (t.preventDefault(), t.stopPropagation(), this._menu || (this._menu = this.querySelector(`.${v}`)), !this._menu) {
console.error("DivManagerMenu: Menu not found.");
return; return;
} }
const a = !e.classList.contains(m); this._menu.classList.contains(h) ? this._menu.classList.remove(h) : this._menu.classList.add(h);
this.appendChild(e);
const r = s.textContent.trim(), o = `
<li class="${te}">
<button type="button" class="${x}" data-value="${n}">
${r}
</button>
</li>`;
this._menuPlaceholderMessageElement.insertAdjacentHTML("beforebegin", o);
const h = this._menuListElement.querySelector(`.${x}[data-value="${n}"]`);
this._menuItemsMap.set(n, {
sourceDiv: e,
menuItemButton: h,
menuListItem: h.parentElement,
menuLabelElement: s,
selected: a
}), this._observer.observe(e, { attributes: !0, attributeFilter: ["class"] });
}), this._menuItemsMap.forEach((e) => {
this._updateItemState(e, !1, !0);
}), this._checkMenuPlaceholderAndButton(), this._menuButton && this._menuButton.addEventListener("click", this._toggleMenu), this._menuListElement.addEventListener("click", this._handleMenuItemClick), document.addEventListener("click", this._handleClickOutside);
} }
disconnectedCallback() { renderButton() {
document.removeEventListener("click", this._handleClickOutside), this._observer && this._observer.disconnect(), this._menuButton && this._menuButton.removeEventListener("click", this._toggleMenu); if (this._button) {
for (const t of this._cildren)
if (t.hidden()) {
this._button.parentElement !== this && (this._button.classList.remove(h), this.appendChild(this._button));
return;
} }
_clearFormElements(i) { this._button.classList.add(h), this.removeChild(this._button);
if (!i) return;
i.querySelectorAll("input, textarea, select").forEach((e) => {
switch (e.type) {
case "button":
case "submit":
case "reset":
case "image":
break;
case "checkbox":
case "radio":
e.checked = !1;
break;
case "file":
e.value = null;
break;
default:
e.value = "";
} }
e.tagName === "SELECT" && (e.selectedIndex = 0); }
hideDiv(t, e) {
if (t && (t.preventDefault(), t.stopPropagation()), !e || !(e instanceof HTMLElement)) {
console.error("DivManagerMenu: Invalid node provided.");
return;
}
const s = this._cildren.find((n) => n.node === e);
if (!s) {
console.error("DivManagerMenu: Child not found.");
return;
}
s.hidden() || s.node.classList.add(h), this._target.removeChild(s.node), this.renderButton(), this.renderMenu();
}
showDiv(t, e) {
if (t && (t.preventDefault(), t.stopPropagation()), e < 0 || e >= this._cildren.length) {
console.error("DivManagerMenu: Invalid index.");
return;
}
const s = this._cildren[e];
s.hidden() && s.node.classList.remove(h), this._target.appendChild(s.node), this.renderMenu(), this.renderButton();
}
renderMenu() {
this._menu || (this._button.innerHTML += `<div class="${v} absolute hidden"></div>`, this._menu = this._button.querySelector(`.${v}`)), this._menu.innerHTML = `${this._cildren.map((e, s) => e.hidden() ? `
<button type="button" class="${st}" dm-itemno="${s}">
${e.name()}
</button>` : "").join("")}`, this._menu = this.querySelector(`.${v}`), this._menu.querySelectorAll(`.${st}`).forEach((e) => {
e.addEventListener("click", (s) => {
this.showDiv(s, parseInt(e.getAttribute("dm-itemno"))), this._toggleMenu(s);
});
}); });
} }
_refreshTargetOrder() { renderIntoTarget() {
if (!this._targetElement) return; this._cildren.forEach((t) => {
const i = []; t.hidden() || this._target.appendChild(t.node);
this._menuItemsMap.forEach((s) => {
s.sourceDiv.parentElement === this._targetElement && i.push(s.sourceDiv);
}), i.forEach((s) => this._targetElement.removeChild(s));
const t = this._targetElement.querySelector(`.${rt}`);
t && this._targetElement.removeChild(t);
let e = !1;
if (this._menuItemsMap.forEach((s) => {
s.selected && (s.sourceDiv.classList.remove(m), this._targetElement.appendChild(s.sourceDiv), e = !0);
}), !e) {
const s = document.createElement("p");
s.className = rt, this._targetElement.appendChild(s);
}
}
_checkMenuPlaceholderAndButton() {
if (!this._menuPlaceholderMessageElement || !this._menuButton) return;
let i = 0;
this._menuItemsMap.forEach((e) => {
e.menuListItem.style.display !== "none" && i++;
}); });
const t = i === 0;
this._menuPlaceholderMessageElement.style.display = t ? "block" : "none", t ? this._menuButton.classList.add(M) : this._menuButton.classList.remove(M);
}
_handleMutations(i) {
for (const t of i)
if (t.type === "attributes" && t.attributeName === "class") {
const e = t.target, s = e.dataset.value, n = this._menuItemsMap.get(s);
if (n) {
const a = e.classList.contains(m);
a && n.selected ? (n.selected = !1, this._updateItemState(n, !1, !0)) : !a && !n.selected && (n.selected = !0, this._updateItemState(n, !1, !0));
} }
} }
} I = new WeakSet(), at = function() {
_handleContentClose(i) { this._cildren = [], this._rendered = [], this._target = null, this._button = null, this._menu = null;
const t = i.currentTarget.dataset.value, e = this._menuItemsMap.get(t); };
e && e.selected && (e.selected = !1, this._updateItemState(e, !1, !0)); const Zt = "filter-list", te = "scroll-button", ee = "tool-tip", ie = "abbrev-tooltips", se = "int-link", ne = "popup-image", le = "tab-list", ae = "filter-pill", re = "image-reel", oe = "multi-select-places", he = "multi-select-simple", rt = "reset-button", de = "div-manager";
}
_toggleMenu(i) {
if (i.preventDefault(), i.stopPropagation(), this._menuButton && this._menuButton.classList.contains(M))
return;
const t = this._menuPopupElement.style.display === "none" || this._menuPopupElement.style.display === "";
t && this._checkMenuPlaceholderAndButton(), this._menuPopupElement.style.display = t ? "block" : "none";
}
_closeMenu() {
this._menuPopupElement.style.display = "none";
}
_handleClickOutside(i) {
if (!this.contains(i.target) && this._menuPopupElement.style.display !== "none") {
if (this._menuButton && this._menuButton.contains(i.target))
return;
this._closeMenu();
}
}
_handleMenuItemClick(i) {
const t = i.target.closest(`.${x}`);
if (t && t.dataset.value) {
const e = t.dataset.value, s = this._menuItemsMap.get(e);
s && (s.selected || (s.selected = !0, this._updateItemState(s, !0, !0)));
}
}
_updateItemState(i, t, e) {
if (!i || !i.sourceDiv || !i.menuItemButton || !i.menuListItem || !i.menuLabelElement) {
console.warn("TabSelectorMenu: Incomplete itemData for update:", i);
return;
}
const s = i.menuLabelElement;
i.selected ? (e && i.sourceDiv.classList.remove(m), i.menuItemButton.classList.add(nt), i.menuListItem.style.display = "none", s.classList.add(at), s.classList.remove(lt)) : (e && i.sourceDiv.classList.add(m), this._clearFormElements(i.sourceDiv), i.menuItemButton.classList.remove(nt), i.menuListItem.style.display = "", s.classList.add(lt), s.classList.remove(at), i.sourceDiv.parentElement !== this && i.sourceDiv.parentElement !== this._targetElement ? this.appendChild(i.sourceDiv) : (i.sourceDiv.parentElement, this._targetElement)), this._refreshTargetOrder(), this._checkMenuPlaceholderAndButton(), t && this._closeMenu();
}
}
const ie = "filter-list", se = "scroll-button", ne = "tool-tip", le = "abbrev-tooltips", ae = "int-link", re = "popup-image", oe = "tab-list", he = "filter-pill", de = "image-reel", ce = "multi-select-places", ue = "multi-select-simple", dt = "reset-button", me = "div-menu";
customElements.define(ae, Lt);
customElements.define(le, p);
customElements.define(ie, gt);
customElements.define(se, Et); customElements.define(se, Et);
customElements.define(ne, bt); customElements.define(ie, _);
customElements.define(Zt, mt);
customElements.define(te, _t);
customElements.define(ee, ft);
customElements.define(ne, gt);
customElements.define(le, bt);
customElements.define(ae, ct);
customElements.define(re, St); customElements.define(re, St);
customElements.define(oe, vt); customElements.define(oe, nt);
customElements.define(he, pt); customElements.define(he, lt);
customElements.define(de, It); customElements.define(rt, Qt);
customElements.define(ce, ot); customElements.define(de, Yt);
customElements.define(ue, ht); function ce() {
customElements.define(dt, Yt);
customElements.define(me, ee);
function pe() {
const l = window.location.pathname, i = window.location.search, t = l + i; const l = window.location.pathname, i = window.location.search, t = l + i;
return encodeURIComponent(t); return encodeURIComponent(t);
} }
function _e(l = 5e3, i = 100) { function ue(l = 5e3, i = 100) {
return new Promise((t, e) => { return new Promise((t, e) => {
let s = 0; let s = 0;
const n = setInterval(() => { const n = setInterval(() => {
@@ -1806,8 +1754,8 @@ function _e(l = 5e3, i = 100) {
}, i); }, i);
}); });
} }
async function fe(l) { async function pe(l) {
const i = await _e(), t = document.getElementById("qr"); const i = await ue(), t = document.getElementById("qr");
t && (t.innerHTML = "", t.classList.add("hidden"), new i(t, { t && (t.innerHTML = "", t.classList.add("hidden"), new i(t, {
text: l, text: l,
width: 1280, width: 1280,
@@ -1819,7 +1767,7 @@ async function fe(l) {
t.classList.remove("hidden"); t.classList.remove("hidden");
}, 20)); }, 20));
} }
function ge(l) { function me(l) {
l && (l.addEventListener("focus", (i) => { l && (l.addEventListener("focus", (i) => {
i.preventDefault(), l.select(); i.preventDefault(), l.select();
}), l.addEventListener("mousedown", (i) => { }), l.addEventListener("mousedown", (i) => {
@@ -1832,7 +1780,7 @@ function ge(l) {
l.select(); l.select();
})); }));
} }
function Ee() { function _e() {
document.body.addEventListener("htmx:responseError", function(l) { document.body.addEventListener("htmx:responseError", function(l) {
const i = l.detail.requestConfig; const i = l.detail.requestConfig;
if (i.boosted) { if (i.boosted) {
@@ -1842,7 +1790,7 @@ function Ee() {
} }
}); });
} }
function be(l, i) { function fe(l, i) {
if (!(l instanceof HTMLElement)) { if (!(l instanceof HTMLElement)) {
console.warn("Target must be an HTMLElement."); console.warn("Target must be an HTMLElement.");
return; return;
@@ -1851,7 +1799,7 @@ function be(l, i) {
console.warn("Action must be a function."); console.warn("Action must be a function.");
return; return;
} }
const t = l.querySelectorAll(dt); const t = l.querySelectorAll(rt);
l.addEventListener("rbichange", (e) => { l.addEventListener("rbichange", (e) => {
for (const s of t) for (const s of t)
if (s.isCurrentlyModified()) { if (s.isCurrentlyModified()) {
@@ -1861,21 +1809,21 @@ function be(l, i) {
i(e.details, !1); i(e.details, !1);
}); });
} }
window.ShowBoostedErrors = Ee; window.ShowBoostedErrors = _e;
window.GenQRCode = fe; window.GenQRCode = pe;
window.SelectableInput = ge; window.SelectableInput = me;
window.PathPlusQuery = pe; window.PathPlusQuery = ce;
window.HookupRBChange = be; window.HookupRBChange = fe;
export { export {
p as AbbreviationTooltips, _ as AbbreviationTooltips,
gt as FilterList, mt as FilterList,
pt as FilterPill, ct as FilterPill,
It as ImageReel, St as ImageReel,
Lt as IntLink, Et as IntLink,
ot as MultiSelectRole, nt as MultiSelectRole,
ht as MultiSelectSimple, lt as MultiSelectSimple,
St as PopupImage, gt as PopupImage,
Et as ScrollButton, _t as ScrollButton,
vt as TabList, bt as TabList,
bt as ToolTip ft as ToolTip
}; };

File diff suppressed because one or more lines are too long

View File

@@ -108,17 +108,6 @@ type AlmanachResult struct {
} }
}); });
}); });
const closeButtons = document.querySelectorAll(".close-button");
closeButtons.forEach((el) => {
el.addEventListener("click", (ev) => {
ev.preventDefault();
const inputWrapper = el.closest(".inputwrapper");
if (inputWrapper) {
inputWrapper.classList.add("hidden");
}
});
});
</script> </script>
<div class="container-normal mx-auto px-8 mt-4"> <div class="container-normal mx-auto px-8 mt-4">
@@ -132,7 +121,10 @@ type AlmanachResult struct {
<label for="preferred_title" class="inputlabel"> Kurztitel <i class="ri-text"></i> </label> <label for="preferred_title" class="inputlabel"> Kurztitel <i class="ri-text"></i> </label>
<reset-button class="text-sm" controls="preferred_title" wrapper-class="inputwrapper" modified-class-suffix="modified"></reset-button> <reset-button class="text-sm" controls="preferred_title" wrapper-class="inputwrapper" modified-class-suffix="modified"></reset-button>
</div> </div>
<textarea name="preferred_title" id="preferred_title" class="inputinput no-enter" placeholder="" required autocomplete="off">{{ $model.result.Entry.PreferredTitle }}</textarea> <textarea name="preferred_title" id="preferred_title" class="inputinput no-enter" placeholder="" required autocomplete="off">
{{- $model.result.Entry.PreferredTitle -}}
</textarea
>
</div> </div>
<div class="col-span-4"></div> <div class="col-span-4"></div>
@@ -140,60 +132,76 @@ type AlmanachResult struct {
<div class="col-span-4"></div> <div class="col-span-4"></div>
<div-menu target-id="titles" class="col-span-2 col-start-7"> <div-manager dm-target="titles" class="col-span-2 col-start-7">
<button class="div-menu-button text-xs text-right w-full cursor-pointer"><i class="ri-add-line"></i> Titel hinzufügen</button> <button class="dm-menu-button text-xs text-right w-full cursor-pointer"><i class="ri-add-line"></i> Titel hinzufügen</button>
<div class="inputwrapper {{ if eq $model.result.Entry.TitleStmt "" }}hidden{{ end }}" data-value="titel"> <div class="inputwrapper {{ if eq $model.result.Entry.TitleStmt "" }}hidden{{ end }}">
<div class="flex flex-row justify-between"> <div class="flex flex-row justify-between">
<label for="title" class="inputlabel menu-label"> Titel <i class="ri-text"></i> </label> <label for="title" class="inputlabel menu-label"> Titel <i class="ri-text"></i> </label>
<div class="text-xs"> <div class="text-xs">
<reset-button controls="title" wrapper-class="inputwrapper" modified-class-suffix="modified" class="text-sm"></reset-button> <reset-button class="text-sm" controls="title" wrapper-class="inputwrapper" modified-class-suffix="modified"></reset-button>
<button class="close-button text-sm cursor-pointer"> <button class="dm-close-button">
<i class="ri-close-line"></i> <i class="ri-close-line"></i>
</button> </button>
</div> </div>
</div> </div>
<textarea name="title" id="title" class="inputinput" placeholder="" autocomplete="off" rows="2">{{ $model.result.Entry.TitleStmt }}</textarea>
<textarea name="title" id="title" class="inputinput" placeholder="" autocomplete="off" rows="2">
{{- $model.result.Entry.TitleStmt -}}
</textarea
>
</div> </div>
<div class="mt-3 inputwrapper {{ if eq $model.result.Entry.SubtitleStmt "" }}hidden{{ end }}" data-value="subtitle"> <div class="mt-3 inputwrapper {{ if eq $model.result.Entry.SubtitleStmt "" }}hidden{{ end }}">
<div class="flex flex-row justify-between"> <div class="flex flex-row justify-between">
<label for="subtitle" class="inputlabel menu-label"> Untertitel <i class="ri-text"></i> </label> <label for="subtitle" class="inputlabel menu-label"> Untertitel <i class="ri-text"></i> </label>
<div> <div class="text-xs">
<reset-button controls="subtitle" wrapper-class="inputwrapper" modified-class-suffix="modified" class="text-sm"></reset-button> <reset-button class="text-sm" controls="subtitle" wrapper-class="inputwrapper" modified-class-suffix="modified"></reset-button>
<button class="close-button text-sm cursor-pointer"> <button class="dm-close-button">
<i class="ri-close-line"></i> <i class="ri-close-line"></i>
</button> </button>
</div> </div>
</div> </div>
<textarea name="subtitle" id="subtitle" class="inputinput" placeholder="" autocomplete="off" rows="2">{{ $model.result.Entry.SubtitleStmt }}</textarea>
<textarea name="subtitle" id="subtitle" class="inputinput" placeholder="" autocomplete="off" rows="2">
{{- $model.result.Entry.SubtitleStmt -}}
</textarea
>
</div> </div>
<div class="mt-3 inputwrapper {{ if eq $model.result.Entry.VariantTitle "" }}hidden{{ end }}" data-value="varianttitle"> <div class="mt-3 inputwrapper {{ if eq $model.result.Entry.VariantTitle "" }}hidden{{ end }}">
<div class="flex flex-row justify-between"> <div class="flex flex-row justify-between">
<label for="varianttitle" class="inputlabel menu-label"> Titelvarianten <i class="ri-text"></i> </label> <label for="varianttitle" class="inputlabel menu-label"> Titelvarianten <i class="ri-text"></i> </label>
<div> <div class="text-xs">
<reset-button controls="varianttitle" wrapper-class="inputwrapper" modified-class-suffix="modified" class="text-sm"></reset-button> <reset-button class="text-sm" controls="varianttitle" wrapper-class="inputwrapper" modified-class-suffix="modified"></reset-button>
<button class="close-button text-sm cursor-pointer"> <button class="dm-close-button">
<i class="ri-close-line"></i> <i class="ri-close-line"></i>
</button> </button>
</div> </div>
</div> </div>
<textarea name="varianttitle" id="varianttitle" class="inputinput" placeholder="" autocomplete="off" rows="2">{{ $model.result.Entry.VariantTitle }}</textarea>
</div>
<div class="mt-3 inputwrapper {{ if eq $model.result.Entry.ParallelTitle "" }}hidden{{ end }}" data-value="paralleltitle"> <textarea name="varianttitle" id="varianttitle" class="inputinput" placeholder="" autocomplete="off" rows="2">
{{- $model.result.Entry.VariantTitle -}}
</textarea
>
</div>
<div class="mt-3 inputwrapper {{ if eq $model.result.Entry.ParallelTitle "" }}hidden{{ end }}">
<div class="flex flex-row justify-between"> <div class="flex flex-row justify-between">
<label for="paralleltitle" class="inputlabel menu-label"> Übersetzter Titel <i class="ri-text"></i> </label> <label for="paralleltitle" class="inputlabel menu-label"> Übersetzter Titel <i class="ri-text"></i> </label>
<div> <div class="text-xs">
<reset-button controls="paralleltitle" wrapper-class="inputwrapper" modified-class-suffix="modified" class="text-sm"></reset-button> <reset-button class="text-sm" controls="paralleltitle" wrapper-class="inputwrapper" modified-class-suffix="modified"></reset-button>
<button class="close-button text-sm cursor-pointer"> <button class="dm-close-button">
<i class="ri-close-line"></i> <i class="ri-close-line"></i>
</button> </button>
</div> </div>
</div> </div>
<textarea name="paralleltitle" id="paralleltitle" class="inputinput" placeholder="" autocomplete="off" rows="2">{{ $model.result.Entry.ParallelTitle }}</textarea>
<textarea name="paralleltitle" id="paralleltitle" class="inputinput" placeholder="" autocomplete="off" rows="2">
{{- $model.result.Entry.ParallelTitle -}}
</textarea
>
</div> </div>
</div-menu> </div-manager>
</form> </form>
</div> </div>

View File

@@ -1,32 +1,20 @@
// Define CSS class names as constants, above the component class
const USER_PROVIDED_MENU_BUTTON_CLASS = "div-menu-button";
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";
const TS_ITEM_IS_SELECTED = "ts-item-is-selected";
const TAILWIND_HIDDEN_CLASS = "hidden"; const TAILWIND_HIDDEN_CLASS = "hidden";
const TS_MENU_BUTTON_STATE_DISABLED = "ts-menu-button--disabled"; const DM_STAY_ATTRIBUTE = "dm-stay";
const TS_MENU_LABEL_IN_MENU_STATE = "ts-menu-label--in-menu"; const DM_TITLE_ATTRIBUTE = "dm-title";
const TS_MENU_LABEL_DISPLAYED_STATE = "ts-menu-label--displayed"; const DM_MENU_BUTTON_CLASS = "dm-menu-button";
const TS_TARGET_PLACEHOLDER_CLASS = "ts-target-placeholder"; // For the target area placeholder const DM_TARGET_ATTRIBUTE = "dm-target";
const TARGET_ID_ATTRIBUTE = "target-id"; // Attribute to specify the target element ID const DM_MENU_CLASS = "dm-menu";
const DM_ITEM_CLASS = "dm-menu-item";
const DM_STAY_ATTRIBUTE = "dm-stay"; // Attribute to indicate if a div should stay in the menu const DM_CLOSE_BUTTON_CLASS = "dm-close-button";
const DM_TITLE_ATTRIBUTE = "dm-title"; // Attribute to indicate if a div has a title
const DM_MENU_BUTTON_CLASS = "dm-menu-button"; // Class for the menu button
const DM_TARGET_ATTRIBUTE = "dm-target"; // Attribute to specify the target element ID for the redesigned menu
// //
// Prereq: child divs must have prop data-value, and a label element // Prereq: child divs must eiteher have dm-title attr or a label element
// The child divs will be moved to the target element when selected // The child divs will be moved to the target element when selected
// The target element must be specified by the attribute target-id on the custom element // The target element must be specified by the attribute dm-target on the custom element
// The menu button must have the class div-menu-button // The menu button must have the class dm-menu-button
// // The child divs can contain a button with the class dm-close-button
export class DivMenuRedesigned extends HTMLElement { export class DivManager extends HTMLElement {
constructor() { constructor() {
super(); super();
this.#reset(); this.#reset();
@@ -34,6 +22,7 @@ export class DivMenuRedesigned extends HTMLElement {
#reset() { #reset() {
this._cildren = []; this._cildren = [];
this._rendered = [];
this._target = null; this._target = null;
this._button = null; this._button = null;
this._menu = null; this._menu = null;
@@ -66,321 +55,142 @@ export class DivMenuRedesigned extends HTMLElement {
} }
for (const child of this._cildren) { for (const child of this._cildren) {
parentNode.removeChild(child.node); this.removeChild(child.node);
} }
this._button.addEventListener("click", this._toggleMenu.bind(this)); this._button.addEventListener("click", this._toggleMenu.bind(this));
this._button.classList.add("relative"); this._button.classList.add("relative");
}
renderMenu() { for (const child of this._cildren) {
this._menu += `<ul class="${TS_P}">`; const closebtns = child.node.querySelectorAll(`.${DM_CLOSE_BUTTON_CLASS}`);
} closebtns.forEach((btn) => {
btn.addEventListener("click", (event) => {
renderNode() {} this.hideDiv(event, child.node);
}
export class DivMenu extends HTMLElement {
constructor() {
super();
this._menuItemsMap = 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); // Bind new method
}
connectedCallback() {
this._menuButton = this.querySelector(`.${USER_PROVIDED_MENU_BUTTON_CLASS}`);
if (!this._menuButton) {
console.error(`TabSelectorMenu: User-provided menu button with class '${USER_PROVIDED_MENU_BUTTON_CLASS}' not found.`);
}
this._originalChildDivs = Array.from(this.children).filter((node) => node.nodeType === Node.ELEMENT_NODE && node.tagName === "DIV" && !node.classList.contains(USER_PROVIDED_MENU_BUTTON_CLASS));
this._originalChildDivs.forEach((div) => div.remove());
const componentPopupHTML = `
<div class="${TS_POPUP}">
<ul class="${TS_LIST}">
<li class="${TS_PLACEHOLDER_MESSAGE}"></li>
</ul>
</div>
`;
this.insertAdjacentHTML("beforeend", componentPopupHTML);
this._menuPopupElement = this.querySelector(`.${TS_POPUP}`);
this._menuListElement = this.querySelector(`.${TS_LIST}`);
this._menuPlaceholderMessageElement = this.querySelector(`.${TS_PLACEHOLDER_MESSAGE}`);
if (!this._menuPopupElement || !this._menuListElement || !this._menuPlaceholderMessageElement) {
console.error("CRITICAL: Popup structure parts missing.");
return;
}
const targetId = this.getAttribute("target-id");
if (targetId) {
this._targetElement = document.getElementById(targetId);
if (!this._targetElement) console.warn(`TabSelectorMenu: Target ID '${targetId}' not found.`);
} else {
console.warn(`TabSelectorMenu: 'target-id' attribute missing.`);
}
this._observer = new MutationObserver(this._handleMutations);
this._originalChildDivs.forEach((sourceDiv) => {
const menuLabelElement = sourceDiv.querySelector("label." + TS_MENU_LABEL);
const itemValue = sourceDiv.dataset.value;
if (!menuLabelElement || !itemValue) {
console.warn('TabSelectorMenu: Source div missing <label class="menu-label"> or data-value:', sourceDiv);
return;
}
const isInitiallySelected = !sourceDiv.classList.contains(TAILWIND_HIDDEN_CLASS);
this.appendChild(sourceDiv);
const labelText = menuLabelElement.textContent.trim();
const menuItemHTML = `
<li class="${TS_LIST_ITEM}">
<button type="button" class="${TS_ITEM_ACTION}" data-value="${itemValue}">
${labelText}
</button>
</li>`;
this._menuPlaceholderMessageElement.insertAdjacentHTML("beforebegin", menuItemHTML);
const addedMenuItemButton = this._menuListElement.querySelector(`.${TS_ITEM_ACTION}[data-value="${itemValue}"]`);
this._menuItemsMap.set(itemValue, {
sourceDiv,
menuItemButton: addedMenuItemButton,
menuListItem: addedMenuItemButton.parentElement,
menuLabelElement: menuLabelElement,
selected: isInitiallySelected,
}); });
this._observer.observe(sourceDiv, { attributes: true, attributeFilter: ["class"] });
});
this._menuItemsMap.forEach((itemData) => {
this._updateItemState(itemData, false, true);
});
// _refreshTargetOrder() is called within _updateItemState, so target should be correct.
this._checkMenuPlaceholderAndButton();
if (this._menuButton) {
this._menuButton.addEventListener("click", this._toggleMenu);
}
this._menuListElement.addEventListener("click", this._handleMenuItemClick);
document.addEventListener("click", this._handleClickOutside);
}
disconnectedCallback() {
document.removeEventListener("click", this._handleClickOutside);
if (this._observer) {
this._observer.disconnect();
}
if (this._menuButton) {
this._menuButton.removeEventListener("click", this._toggleMenu);
}
}
_clearFormElements(parentElement) {
if (!parentElement) return;
const inputs = parentElement.querySelectorAll("input, textarea, select");
inputs.forEach((el) => {
switch (el.type) {
case "button":
case "submit":
case "reset":
case "image":
break;
case "checkbox":
case "radio":
el.checked = false;
break;
case "file":
el.value = null;
break;
default:
el.value = "";
}
if (el.tagName === "SELECT") el.selectedIndex = 0;
}); });
} }
_refreshTargetOrder() { this.renderMenu();
if (!this._targetElement) return; this.renderIntoTarget();
// Detach all currently managed divs from target
const managedDivsInTarget = [];
this._menuItemsMap.forEach((item) => {
if (item.sourceDiv.parentElement === this._targetElement) {
managedDivsInTarget.push(item.sourceDiv);
}
});
managedDivsInTarget.forEach((div) => this._targetElement.removeChild(div));
// Remove existing component-managed placeholder if any
const existingPlaceholder = this._targetElement.querySelector(`.${TS_TARGET_PLACEHOLDER_CLASS}`);
if (existingPlaceholder) {
this._targetElement.removeChild(existingPlaceholder);
}
// Append selected divs in their original order
let hasSelectedItems = false;
this._menuItemsMap.forEach((item) => {
if (item.selected) {
item.sourceDiv.classList.remove(TAILWIND_HIDDEN_CLASS); // Ensure it's visible
this._targetElement.appendChild(item.sourceDiv);
hasSelectedItems = true;
}
});
// Add placeholder if target is empty and no items were selected to be appended
if (!hasSelectedItems) {
const placeholder = document.createElement("p");
placeholder.className = TS_TARGET_PLACEHOLDER_CLASS;
this._targetElement.appendChild(placeholder);
}
}
_checkMenuPlaceholderAndButton() {
if (!this._menuPlaceholderMessageElement || !this._menuButton) return;
let visibleItemCount = 0;
this._menuItemsMap.forEach((itemData) => {
if (itemData.menuListItem.style.display !== "none") {
visibleItemCount++;
}
});
const allItemsSelected = visibleItemCount === 0;
this._menuPlaceholderMessageElement.style.display = allItemsSelected ? "block" : "none";
if (allItemsSelected) {
this._menuButton.classList.add(TS_MENU_BUTTON_STATE_DISABLED);
} else {
this._menuButton.classList.remove(TS_MENU_BUTTON_STATE_DISABLED);
}
}
_handleMutations(mutationsList) {
for (const mutation of mutationsList) {
if (mutation.type === "attributes" && mutation.attributeName === "class") {
const targetDiv = mutation.target;
const itemValue = targetDiv.dataset.value;
const itemData = this._menuItemsMap.get(itemValue);
if (itemData) {
const isNowHiddenByClass = targetDiv.classList.contains(TAILWIND_HIDDEN_CLASS);
if (isNowHiddenByClass && itemData.selected) {
itemData.selected = false;
this._updateItemState(itemData, false, true);
} else if (!isNowHiddenByClass && !itemData.selected) {
itemData.selected = true;
this._updateItemState(itemData, false, true);
}
}
}
}
}
_handleContentClose(event) {
const itemValue = event.currentTarget.dataset.value;
const itemData = this._menuItemsMap.get(itemValue);
if (itemData && itemData.selected) {
itemData.selected = false;
this._updateItemState(itemData, false, true);
}
} }
_toggleMenu(event) { _toggleMenu(event) {
event.preventDefault(); event.preventDefault();
event.stopPropagation(); event.stopPropagation();
if (this._menuButton && this._menuButton.classList.contains(TS_MENU_BUTTON_STATE_DISABLED)) {
return; if (!this._menu) {
} this._menu = this.querySelector(`.${DM_MENU_CLASS}`);
const isHidden = this._menuPopupElement.style.display === "none" || this._menuPopupElement.style.display === "";
if (isHidden) {
this._checkMenuPlaceholderAndButton();
}
this._menuPopupElement.style.display = isHidden ? "block" : "none";
} }
_closeMenu() { if (!this._menu) {
this._menuPopupElement.style.display = "none"; console.error("DivManagerMenu: Menu not found.");
}
_handleClickOutside(event) {
if (!this.contains(event.target) && this._menuPopupElement.style.display !== "none") {
if (this._menuButton && this._menuButton.contains(event.target)) {
return;
}
this._closeMenu();
}
}
_handleMenuItemClick(event) {
const clickedButton = event.target.closest(`.${TS_ITEM_ACTION}`);
if (clickedButton && clickedButton.dataset.value) {
const itemValue = clickedButton.dataset.value;
const itemData = this._menuItemsMap.get(itemValue);
if (itemData) {
if (!itemData.selected) {
itemData.selected = true;
this._updateItemState(itemData, true, true);
}
}
}
}
_updateItemState(itemData, closeMenuAfterUpdate, manageHiddenClass) {
if (!itemData || !itemData.sourceDiv || !itemData.menuItemButton || !itemData.menuListItem || !itemData.menuLabelElement) {
console.warn("TabSelectorMenu: Incomplete itemData for update:", itemData);
return; return;
} }
const menuLabel = itemData.menuLabelElement; if (this._menu.classList.contains(TAILWIND_HIDDEN_CLASS)) {
this._menu.classList.remove(TAILWIND_HIDDEN_CLASS);
if (itemData.selected) {
// No direct DOM manipulation of sourceDiv here regarding targetElement
// _refreshTargetOrder will handle placement.
if (manageHiddenClass) itemData.sourceDiv.classList.remove(TAILWIND_HIDDEN_CLASS);
itemData.menuItemButton.classList.add(TS_ITEM_IS_SELECTED);
itemData.menuListItem.style.display = "none";
menuLabel.classList.add(TS_MENU_LABEL_DISPLAYED_STATE);
menuLabel.classList.remove(TS_MENU_LABEL_IN_MENU_STATE);
} else { } else {
if (manageHiddenClass) itemData.sourceDiv.classList.add(TAILWIND_HIDDEN_CLASS); this._menu.classList.add(TAILWIND_HIDDEN_CLASS);
this._clearFormElements(itemData.sourceDiv);
itemData.menuItemButton.classList.remove(TS_ITEM_IS_SELECTED);
itemData.menuListItem.style.display = "";
menuLabel.classList.add(TS_MENU_LABEL_IN_MENU_STATE);
menuLabel.classList.remove(TS_MENU_LABEL_DISPLAYED_STATE);
// If the div is being hidden, ensure it's moved back to the component
// if it was in the target. _refreshTargetOrder will handle its removal from target.
if (itemData.sourceDiv.parentElement !== this && itemData.sourceDiv.parentElement !== this._targetElement) {
this.appendChild(itemData.sourceDiv);
} else if (itemData.sourceDiv.parentElement === this._targetElement) {
// It will be removed by _refreshTargetOrder, then re-appended to 'this' if needed
// For now, just ensure it's not orphaned if _refreshTargetOrder doesn't run immediately after this.
// Actually, better to let _refreshTargetOrder handle removal from target.
// And if it's not selected, ensure it's a child of 'this' for mutation observer.
} }
} }
this._refreshTargetOrder(); // Centralize target DOM updates renderButton() {
this._checkMenuPlaceholderAndButton(); if (!this._button) {
return;
}
if (closeMenuAfterUpdate) this._closeMenu(); for (const child of this._cildren) {
if (child.hidden()) {
if (this._button.parentElement !== this) {
this._button.classList.remove(TAILWIND_HIDDEN_CLASS);
this.appendChild(this._button);
}
return;
}
}
this._button.classList.add(TAILWIND_HIDDEN_CLASS);
this.removeChild(this._button);
}
hideDiv(event, node) {
if (event) {
event.preventDefault();
event.stopPropagation();
}
if (!node || !(node instanceof HTMLElement)) {
console.error("DivManagerMenu: Invalid node provided.");
return;
}
const child = this._cildren.find((c) => c.node === node);
if (!child) {
console.error("DivManagerMenu: Child not found.");
return;
}
if (!child.hidden()) {
child.node.classList.add(TAILWIND_HIDDEN_CLASS);
}
this._target.removeChild(child.node);
// INFO: the order of these matter, dont fuck it up
this.renderButton();
this.renderMenu();
}
showDiv(event, index) {
if (event) {
event.preventDefault();
event.stopPropagation();
}
if (index < 0 || index >= this._cildren.length) {
console.error("DivManagerMenu: Invalid index.");
return;
}
const child = this._cildren[index];
if (child.hidden()) {
child.node.classList.remove(TAILWIND_HIDDEN_CLASS);
}
this._target.appendChild(child.node);
// INFO: the order of these matter, dont fuck it up
this.renderMenu();
this.renderButton();
}
renderMenu() {
if (!this._menu) {
this._button.innerHTML += `<div class="${DM_MENU_CLASS} absolute hidden"></div>`;
this._menu = this._button.querySelector(`.${DM_MENU_CLASS}`);
}
this._menu.innerHTML = `${this._cildren
.map((c, index) => {
if (!c.hidden()) return "";
return `
<button type="button" class="${DM_ITEM_CLASS}" dm-itemno="${index}">
${c.name()}
</button>`;
})
.join("")}`;
this._menu = this.querySelector(`.${DM_MENU_CLASS}`);
const buttons = this._menu.querySelectorAll(`.${DM_ITEM_CLASS}`);
buttons.forEach((button) => {
button.addEventListener("click", (event) => {
this.showDiv(event, parseInt(button.getAttribute("dm-itemno")));
this._toggleMenu(event);
});
});
}
renderIntoTarget() {
this._cildren.forEach((child) => {
if (!child.hidden()) {
this._target.appendChild(child.node);
}
});
} }
} }

View File

@@ -1,4 +1,8 @@
@layer components { @layer components {
button {
@apply cursor-pointer disabled:cursor-default;
}
.dbform .inputwrapper { .dbform .inputwrapper {
@apply rounded-xs border-2 border-transparent pl-3 pr-1.5 @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 py-1 pb-1.5 border-l-2 focus-within:border-l-slate-600
@@ -278,26 +282,24 @@
@apply disabled:hidden; @apply disabled:hidden;
} }
.ts-menu-popup { .dm-menu-button {
@apply hidden absolute top-full left-0 bg-white border border-gray-300 rounded-xs shadow z-50 min-w-[200px] mt-1; @apply text-gray-700 hover:text-gray-950 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-slate-500;
} }
.ts-menu-list { .dm-menu {
list-style: none; @apply top-full right-0 bg-white border border-gray-300 rounded-xs shadow z-50 mt-1 flex flex-col;
padding: 0px 0;
margin: 0;
} }
.ts-menu-list li { .dm-menu .dm-menu-item {
@apply cursor-pointer ml-0 list-none px-2.5 py-1 hover:bg-gray-100 border-b; @apply cursor-pointer ml-0 list-none px-2.5 py-1 hover:bg-gray-100 border-b w-full;
} }
.ts-menu-list li:last-child { .dm-menu .dm-menu-item:last-child {
@apply border-b-0; @apply border-b-0;
} }
.ts-menu-list li button { .dm-menu .dm-menu-item {
@apply w-full cursor-pointer text-left text-gray-700; @apply cursor-pointer text-left text-gray-700;
} }
.form-submit-button { .form-submit-button {

View File

@@ -13,7 +13,7 @@ import { ImageReel } from "./image-reel.js";
import { MultiSelectRole } from "./multi-select-role.js"; import { MultiSelectRole } from "./multi-select-role.js";
import { MultiSelectSimple } from "./multi-select-simple.js"; import { MultiSelectSimple } from "./multi-select-simple.js";
import { ResetButton } from "./reset-button.js"; import { ResetButton } from "./reset-button.js";
import { DivMenu } from "./div-menu.js"; import { DivManager } from "./div-menu.js";
const FILTER_LIST_ELEMENT = "filter-list"; const FILTER_LIST_ELEMENT = "filter-list";
const SCROLL_BUTTON_ELEMENT = "scroll-button"; const SCROLL_BUTTON_ELEMENT = "scroll-button";
@@ -27,7 +27,7 @@ const IMAGE_REEL_ELEMENT = "image-reel";
const MULTI_SELECT_ROLE_ELEMENT = "multi-select-places"; const MULTI_SELECT_ROLE_ELEMENT = "multi-select-places";
const MULTI_SELECT_SIMPLE_ELEMENT = "multi-select-simple"; const MULTI_SELECT_SIMPLE_ELEMENT = "multi-select-simple";
const RESET_BUTTON_ELEMENT = "reset-button"; const RESET_BUTTON_ELEMENT = "reset-button";
const DIV_MENU_ELEMENT = "div-menu"; const DIV_MANAGER_ELEMENT = "div-manager";
customElements.define(INT_LINK_ELEMENT, IntLink); customElements.define(INT_LINK_ELEMENT, IntLink);
customElements.define(ABBREV_TOOLTIPS_ELEMENT, AbbreviationTooltips); customElements.define(ABBREV_TOOLTIPS_ELEMENT, AbbreviationTooltips);
@@ -41,7 +41,7 @@ customElements.define(IMAGE_REEL_ELEMENT, ImageReel);
customElements.define(MULTI_SELECT_ROLE_ELEMENT, MultiSelectRole); customElements.define(MULTI_SELECT_ROLE_ELEMENT, MultiSelectRole);
customElements.define(MULTI_SELECT_SIMPLE_ELEMENT, MultiSelectSimple); customElements.define(MULTI_SELECT_SIMPLE_ELEMENT, MultiSelectSimple);
customElements.define(RESET_BUTTON_ELEMENT, ResetButton); customElements.define(RESET_BUTTON_ELEMENT, ResetButton);
customElements.define(DIV_MENU_ELEMENT, DivMenu); customElements.define(DIV_MANAGER_ELEMENT, DivManager);
function PathPlusQuery() { function PathPlusQuery() {
const path = window.location.pathname; const path = window.location.pathname;

View File

@@ -65,7 +65,9 @@ export class ResetButton extends HTMLElement {
el.removeEventListener("change", this.handleInputChange); el.removeEventListener("change", this.handleInputChange);
}); });
this._controlledElements = []; this._controlledElements = [];
this.initialStates.clear(); // INFO: we don't clear the intitial states here, in case we
// want to reattach the same elements later.
// this.initialStates.clear();
this.lastOverallModifiedState = null; this.lastOverallModifiedState = null;
const controlIds = (this.getAttribute("controls") || "") const controlIds = (this.getAttribute("controls") || "")
@@ -107,6 +109,9 @@ export class ResetButton extends HTMLElement {
} }
storeInitialState(element) { storeInitialState(element) {
if (this.initialStates.has(element.id)) {
return;
}
let state; let state;
switch (element.type) { switch (element.type) {
case "checkbox": case "checkbox":