frontend-dali/source/widgets/menu/logic.ts

211 lines
4.2 KiB
TypeScript
Raw Normal View History

2025-10-23 23:16:11 +02:00
/*
This file is part of »dali«.
Copyright 2025 'kcf' <fenris@folksprak.org>
»dali« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
»dali« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with »dali«. If not, see <http://www.gnu.org/licenses/>.
*/
namespace _dali.widgets
2025-10-17 00:10:28 +02:00
{
/**
*/
type type_entry_data = {
label : string;
groups : Array<string>;
action : (() => void);
}
/**
*/
export class class_widget_menu implements lib_plankton.zoo_widget.interface_widget
{
/**
*/
private entries : Array<
{
data : type_entry_data;
element : (null | HTMLElement);
}
>;
/**
*/
private initial_groups : Array<string>;
/**
*/
private label : (null | string);
2025-10-17 00:10:28 +02:00
/**
*/
private container : (null | HTMLElement);
/**
*/
public constructor(
entry_data_list : Array<type_entry_data>,
{
"initial_groups": initial_groups = [],
"initial_label": initial_label = "",
2025-10-17 00:10:28 +02:00
}
:
{
initial_groups ?: Array<string>;
initial_label ?: string;
2025-10-17 00:10:28 +02:00
}
=
{
}
)
{
this.entries = entry_data_list.map(
entry_data => (
{
"data": entry_data,
"element": null,
}
)
);
this.initial_groups = initial_groups;
this.label = initial_label;
2025-10-17 00:10:28 +02:00
this.container = null;
}
/**
*/
public set_groups(
groups : Array<string>
)
: void
{
this.entries.forEach(
entry => {
const active : boolean = groups.some(group => entry.data.groups.includes(group));
entry.element.classList.toggle("widget-menu-entry-hidden", (! active));
}
);
}
/**
*/
public set_label(
label ?: string
)
: void
{
this.label = label;
this.container.querySelector(".widget-menu-button").innerHTML = (
(this.label === null)
?
("[" + "=" + "]")
:
("[" + this.label + "]")
);
}
2025-10-17 00:10:28 +02:00
/**
*/
private toggle_collapsed(
{
"mode": mode = null,
}
:
{
mode ?: (null | boolean);
}
=
{
}
)
: void
{
this.container.classList.toggle("widget-menu-collapsed", mode ?? undefined);
}
/**
* [implementation]
*/
public async load(
target_element : Element
)
: Promise<void>
{
// container
{
const dom_container : HTMLElement = document.createElement("div");
dom_container.classList.add("widget-menu");
// button
{
const dom_button : HTMLElement = document.createElement("button");
dom_button.textContent = "[" + this.label + "]";
2025-10-17 00:10:28 +02:00
dom_button.classList.add("widget-menu-button");
dom_button.addEventListener(
"click",
() => {
this.toggle_collapsed();
}
);
dom_container.classList.toggle("widget-menu-collapsed", true);
dom_container.appendChild(dom_button);
}
// platform
{
const dom_platform : HTMLElement = document.createElement("div");
dom_platform.classList.add("widget-menu-platform");
{
const dom_list : HTMLElement = document.createElement("ul");
dom_list.classList.add("widget-menu-entries");
this.entries.forEach(
entry => {
const dom_entry : HTMLElement = document.createElement("li");
dom_entry.classList.add("widget-menu-entry");
dom_entry.textContent = entry.data.label;
dom_entry.addEventListener(
"click",
() => {
this.toggle_collapsed({"mode": true});
entry.data.action();
}
);
dom_list.appendChild(dom_entry);
entry.element = dom_entry;
}
);
dom_platform.appendChild(dom_list);
}
dom_container.appendChild(dom_platform);
}
target_element.appendChild(dom_container);
this.container = dom_container;
}
this.set_groups(this.initial_groups);
}
}
}