Add a fluent API to create menus
authorAlexander Ebert <ebert@woltlab.com>
Tue, 3 Oct 2023 15:52:18 +0000 (17:52 +0200)
committerTim Düsterhus <duesterhus@woltlab.com>
Thu, 5 Oct 2023 15:22:08 +0000 (17:22 +0200)
ts/WoltLabSuite/Core/Bootstrap.ts
ts/WoltLabSuite/Core/Component/Menu.ts [new file with mode: 0644]
ts/WoltLabSuite/Core/Component/Menu/Builder.ts [new file with mode: 0644]
ts/WoltLabSuite/Core/Component/Menu/Group.ts [new file with mode: 0644]
wcfsetup/install/files/js/WoltLabSuite/Core/Bootstrap.js
wcfsetup/install/files/js/WoltLabSuite/Core/Component/Menu.js [new file with mode: 0644]
wcfsetup/install/files/js/WoltLabSuite/Core/Component/Menu/Builder.js [new file with mode: 0644]
wcfsetup/install/files/js/WoltLabSuite/Core/Component/Menu/Group.js [new file with mode: 0644]

index 351fed5d6e020be38827baa8192bca5093476cfb..ad4820bc1c9da0d8ef7718ae1dfbc70100ec4bcd 100644 (file)
@@ -170,9 +170,6 @@ export function setup(options: BoostrapOptions): void {
   });
 
   whenFirstSeen("woltlab-core-menu", () => {
-    void import("./Element/woltlab-core-menu");
-    void import("./Element/woltlab-core-menu-group");
-    void import("./Element/woltlab-core-menu-item");
-    void import("./Element/woltlab-core-menu-separator");
+    void import("./Component/Menu");
   });
 }
diff --git a/ts/WoltLabSuite/Core/Component/Menu.ts b/ts/WoltLabSuite/Core/Component/Menu.ts
new file mode 100644 (file)
index 0000000..c20d768
--- /dev/null
@@ -0,0 +1,12 @@
+import "../Element/woltlab-core-menu";
+import "../Element/woltlab-core-menu-group";
+import "../Element/woltlab-core-menu-item";
+import "../Element/woltlab-core-menu-separator";
+import MenuBuilder from "./Menu/Builder";
+
+export function create(label: string): MenuBuilder {
+  const menu = document.createElement("woltlab-core-menu");
+  menu.label = label;
+
+  return new MenuBuilder(menu);
+}
diff --git a/ts/WoltLabSuite/Core/Component/Menu/Builder.ts b/ts/WoltLabSuite/Core/Component/Menu/Builder.ts
new file mode 100644 (file)
index 0000000..4e88d97
--- /dev/null
@@ -0,0 +1,48 @@
+import type WoltlabCoreMenuElement from "WoltLabSuite/Core/Element/woltlab-core-menu";
+import MenuGroup from "./Group";
+
+export class MenuBuilder {
+  readonly #menu: WoltlabCoreMenuElement;
+
+  constructor(menu: WoltlabCoreMenuElement) {
+    this.#menu = menu;
+  }
+
+  addGroup(callback: (group: MenuGroup) => void): this {
+    const group = new MenuGroup(this.#menu);
+    callback(group);
+
+    return this;
+  }
+
+  addItem(value: string, label: string): this {
+    const item = document.createElement("woltlab-core-menu-item");
+    item.value = value;
+    item.textContent = label;
+    this.#menu.append(item);
+
+    return this;
+  }
+
+  addItemWithHtml(value: string, html: string): this {
+    const item = document.createElement("woltlab-core-menu-item");
+    item.value = value;
+    item.innerHTML = html;
+    this.#menu.append(item);
+
+    return this;
+  }
+
+  addDivider(): this {
+    const divider = document.createElement("woltlab-core-menu-separator");
+    this.#menu.append(divider);
+
+    return this;
+  }
+
+  finalize(): WoltlabCoreMenuElement {
+    return this.#menu;
+  }
+}
+
+export default MenuBuilder;
diff --git a/ts/WoltLabSuite/Core/Component/Menu/Group.ts b/ts/WoltLabSuite/Core/Component/Menu/Group.ts
new file mode 100644 (file)
index 0000000..6a3e94c
--- /dev/null
@@ -0,0 +1,38 @@
+import type WoltlabCoreMenuElement from "WoltLabSuite/Core/Element/woltlab-core-menu";
+import type WoltlabCoreMenuGroupElement from "WoltLabSuite/Core/Element/woltlab-core-menu-group";
+
+export class MenuGroup {
+  readonly #group: WoltlabCoreMenuGroupElement;
+
+  constructor(menu: WoltlabCoreMenuElement) {
+    this.#group = document.createElement("woltlab-core-menu-group");
+    menu.append(this.#group);
+  }
+
+  addItem(value: string, label: string): this {
+    const item = document.createElement("woltlab-core-menu-item");
+    item.value = value;
+    item.textContent = label;
+    this.#group.append(item);
+
+    return this;
+  }
+
+  addItemWithHtml(value: string, html: string): this {
+    const item = document.createElement("woltlab-core-menu-item");
+    item.value = value;
+    item.innerHTML = html;
+    this.#group.append(item);
+
+    return this;
+  }
+
+  addDivider(): this {
+    const divider = document.createElement("woltlab-core-menu-separator");
+    this.#group.append(divider);
+
+    return this;
+  }
+}
+
+export default MenuGroup;
index 745a702239ab152ee1340871a613d13c65e559e8..dca25a503d1c9adc8bdca0368e918096016c1eb0 100644 (file)
@@ -134,10 +134,7 @@ define(["require", "exports", "tslib", "./Core", "./Date/Picker", "./Devtools",
             void new Promise((resolve_5, reject_5) => { require(["./Component/GoogleMaps/Geocoding"], resolve_5, reject_5); }).then(tslib_1.__importStar).then(({ setup }) => setup());
         });
         (0, LazyLoader_1.whenFirstSeen)("woltlab-core-menu", () => {
-            void new Promise((resolve_6, reject_6) => { require(["./Element/woltlab-core-menu"], resolve_6, reject_6); }).then(tslib_1.__importStar);
-            void new Promise((resolve_7, reject_7) => { require(["./Element/woltlab-core-menu-group"], resolve_7, reject_7); }).then(tslib_1.__importStar);
-            void new Promise((resolve_8, reject_8) => { require(["./Element/woltlab-core-menu-item"], resolve_8, reject_8); }).then(tslib_1.__importStar);
-            void new Promise((resolve_9, reject_9) => { require(["./Element/woltlab-core-menu-separator"], resolve_9, reject_9); }).then(tslib_1.__importStar);
+            void new Promise((resolve_6, reject_6) => { require(["./Component/Menu"], resolve_6, reject_6); }).then(tslib_1.__importStar);
         });
     }
     exports.setup = setup;
diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Component/Menu.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Component/Menu.js
new file mode 100644 (file)
index 0000000..7114622
--- /dev/null
@@ -0,0 +1,12 @@
+define(["require", "exports", "tslib", "./Menu/Builder", "../Element/woltlab-core-menu", "../Element/woltlab-core-menu-group", "../Element/woltlab-core-menu-item", "../Element/woltlab-core-menu-separator"], function (require, exports, tslib_1, Builder_1) {
+    "use strict";
+    Object.defineProperty(exports, "__esModule", { value: true });
+    exports.create = void 0;
+    Builder_1 = tslib_1.__importDefault(Builder_1);
+    function create(label) {
+        const menu = document.createElement("woltlab-core-menu");
+        menu.label = label;
+        return new Builder_1.default(menu);
+    }
+    exports.create = create;
+});
diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Component/Menu/Builder.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Component/Menu/Builder.js
new file mode 100644 (file)
index 0000000..6a3f76c
--- /dev/null
@@ -0,0 +1,41 @@
+define(["require", "exports", "tslib", "./Group"], function (require, exports, tslib_1, Group_1) {
+    "use strict";
+    Object.defineProperty(exports, "__esModule", { value: true });
+    exports.MenuBuilder = void 0;
+    Group_1 = tslib_1.__importDefault(Group_1);
+    class MenuBuilder {
+        #menu;
+        constructor(menu) {
+            this.#menu = menu;
+        }
+        addGroup(callback) {
+            const group = new Group_1.default(this.#menu);
+            callback(group);
+            return this;
+        }
+        addItem(value, label) {
+            const item = document.createElement("woltlab-core-menu-item");
+            item.value = value;
+            item.textContent = label;
+            this.#menu.append(item);
+            return this;
+        }
+        addItemWithHtml(value, html) {
+            const item = document.createElement("woltlab-core-menu-item");
+            item.value = value;
+            item.innerHTML = html;
+            this.#menu.append(item);
+            return this;
+        }
+        addDivider() {
+            const divider = document.createElement("woltlab-core-menu-separator");
+            this.#menu.append(divider);
+            return this;
+        }
+        finalize() {
+            return this.#menu;
+        }
+    }
+    exports.MenuBuilder = MenuBuilder;
+    exports.default = MenuBuilder;
+});
diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Component/Menu/Group.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Component/Menu/Group.js
new file mode 100644 (file)
index 0000000..f65ae81
--- /dev/null
@@ -0,0 +1,33 @@
+define(["require", "exports"], function (require, exports) {
+    "use strict";
+    Object.defineProperty(exports, "__esModule", { value: true });
+    exports.MenuGroup = void 0;
+    class MenuGroup {
+        #group;
+        constructor(menu) {
+            this.#group = document.createElement("woltlab-core-menu-group");
+            menu.append(this.#group);
+        }
+        addItem(value, label) {
+            const item = document.createElement("woltlab-core-menu-item");
+            item.value = value;
+            item.textContent = label;
+            this.#group.append(item);
+            return this;
+        }
+        addItemWithHtml(value, html) {
+            const item = document.createElement("woltlab-core-menu-item");
+            item.value = value;
+            item.innerHTML = html;
+            this.#group.append(item);
+            return this;
+        }
+        addDivider() {
+            const divider = document.createElement("woltlab-core-menu-separator");
+            this.#group.append(divider);
+            return this;
+        }
+    }
+    exports.MenuGroup = MenuGroup;
+    exports.default = MenuGroup;
+});