Skip to content

Commit 291e9b5

Browse files
committed
Clean up the implementation
1 parent d37cdb0 commit 291e9b5

File tree

1 file changed

+65
-58
lines changed

1 file changed

+65
-58
lines changed

ts/WoltLabSuite/WebComponent/woltlab-core-list-box.ts

Lines changed: 65 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,14 @@ import { WoltlabCoreListItemElement } from "./woltlab-core-list-item";
1010

1111
// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
1212
class WoltlabCoreListBoxElement extends HTMLParsedElement {
13-
#input: HTMLInputElement | undefined = undefined;
1413
#selected = "";
15-
#shadow: ShadowRoot | undefined = undefined;
14+
readonly #formInput: HTMLInputElement;
1615
readonly #items: Set<WoltlabCoreListItemElement> = new Set();
16+
readonly #shadow: ShadowRoot;
17+
readonly #slot: HTMLSlotElement;
1718

18-
connectedCallback() {
19-
this.role = "listbox";
20-
this.setAttribute("aria-multiselectable", "false");
21-
this.setAttribute("aria-orientation", "vertical");
22-
23-
const shadow = this.#getShadow();
24-
shadow.innerHTML = "";
19+
constructor() {
20+
super();
2521

2622
const style = document.createElement("style");
2723
style.textContent = `
@@ -41,57 +37,56 @@ import { WoltlabCoreListItemElement } from "./woltlab-core-list-item";
4137
}
4238
`;
4339

44-
const elements = document.createElement("slot");
45-
elements.addEventListener("slotchange", () => {
46-
for (const element of elements.assignedElements()) {
47-
if (element instanceof WoltlabCoreListItemElement) {
48-
if (element.selected) {
49-
if (this.#selected === "") {
50-
this.#selected = element.value;
51-
this.setAttribute("selected", this.#selected);
52-
53-
if (this.#input !== undefined) {
54-
this.#input.value = element.value;
55-
}
56-
} else {
57-
element.selected = false;
58-
}
59-
}
40+
this.#slot = document.createElement("slot");
6041

61-
if (!this.#items.has(element)) {
62-
this.#items.add(element);
42+
this.#shadow = this.attachShadow({ mode: "open" });
43+
this.#shadow.append(style, this.#slot);
6344

64-
element.addEventListener("change", (event) => {
65-
if (event.detail.selected) {
66-
this.#changeSelection(element.value);
67-
} else {
68-
throw new Error("TODO: not implemented");
69-
}
70-
});
71-
}
72-
}
45+
this.#formInput = document.createElement("input");
46+
this.#formInput.type = "hidden";
47+
}
48+
49+
parsedCallback() {
50+
this.role = "listbox";
51+
this.setAttribute("aria-multiselectable", "false");
52+
this.setAttribute("aria-orientation", "vertical");
53+
54+
const selected = this.getAttribute("selected") || this.#selected;
55+
this.removeAttribute("selected");
56+
57+
let foundValue = false;
58+
for (const element of this.#slot.assignedElements()) {
59+
if (!(element instanceof WoltlabCoreListItemElement)) {
60+
continue;
7361
}
74-
});
7562

76-
shadow.append(style, elements);
63+
if (element.value === selected) {
64+
element.selected = true;
7765

78-
const name = this.getAttribute("name") || "";
79-
if (name !== "") {
80-
this.#input = document.createElement("input");
81-
this.#input.type = "hidden";
82-
this.#input.name = name;
83-
this.#input.value = this.#selected;
66+
if (this.#formInput !== undefined) {
67+
this.#formInput.value = this.#selected;
68+
}
8469

85-
this.removeAttribute("name");
86-
}
70+
foundValue = true;
71+
} else {
72+
element.selected = false;
73+
}
8774

88-
if (this.#input !== undefined) {
89-
this.append(this.#input);
75+
if (!this.#items.has(element)) {
76+
this.#items.add(element);
77+
78+
element.addEventListener("change", (event) => {
79+
if (event.detail.selected) {
80+
this.#changeSelection(element.value);
81+
} else {
82+
throw new Error("TODO: not implemented");
83+
}
84+
});
85+
}
9086
}
91-
}
9287

93-
parsedCallback(): void {
94-
console.log("parsedCallback()");
88+
this.#selected = foundValue ? selected : "";
89+
this.#updateFormInput(this.name);
9590
}
9691

9792
#changeSelection(value: string): void {
@@ -108,8 +103,8 @@ import { WoltlabCoreListItemElement } from "./woltlab-core-list-item";
108103
}
109104
}
110105

111-
if (this.#input !== undefined) {
112-
this.#input.value = value;
106+
if (this.#formInput !== undefined) {
107+
this.#formInput.value = value;
113108
}
114109

115110
const event = new CustomEvent<ChangePayload>("change", {
@@ -120,17 +115,29 @@ import { WoltlabCoreListItemElement } from "./woltlab-core-list-item";
120115
this.dispatchEvent(event);
121116
}
122117

123-
#getShadow(): ShadowRoot {
124-
if (this.#shadow === undefined) {
125-
this.#shadow = this.attachShadow({ mode: "open" });
126-
}
118+
#updateFormInput(name: string): void {
119+
if (name === "") {
120+
this.removeAttribute("name");
121+
this.#formInput.remove();
122+
} else {
123+
this.#formInput.name = name;
124+
this.#formInput.value = this.#selected;
127125

128-
return this.#shadow;
126+
this.#shadow.append(this.#formInput);
127+
}
129128
}
130129

131130
get selected(): string {
132131
return this.#selected;
133132
}
133+
134+
get name(): string {
135+
return this.getAttribute("name") || "";
136+
}
137+
138+
set name(name: string) {
139+
this.#updateFormInput(name);
140+
}
134141
}
135142

136143
// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging

0 commit comments

Comments
 (0)