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

215 lines
3.9 KiB
TypeScript
Raw Permalink 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<type_entry_data>;
2025-10-17 00:10:28 +02:00
/**
*/
private initial_groups : Array<string>;
/**
*/
private label : (null | string);
2025-10-17 00:10:28 +02:00
/**
*/
private container : (null | HTMLElement);
/**
*/
public constructor(
entries : Array<type_entry_data>,
2025-10-17 00:10:28 +02:00
{
"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 = entries;
2025-10-17 00:10:28 +02:00
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, index) => {
const active : boolean = groups.some(group => entry.groups.includes(group));
const rel : string = index.toFixed(0);
const dom_entry = this.container.querySelector(".widget-menu-entry[rel=\"" + rel + "\"]");
dom_entry.classList.toggle("widget-menu-entry-hidden", (! active));
2025-10-17 00:10:28 +02:00
}
);
}
/**
*/
public set_label(
label : (null | 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>
{
// structure
this.container = await _dali.helpers.element_from_template(
"widget-menu",
"main",
{
"entries": (
(
await lib_plankton.call.promise_condense(
this.entries.map(
(entry, index) => () => _dali.helpers.template_coin(
"widget-menu",
"entry",
{
"label": entry.label,
"rel": index.toFixed(0),
}
)
)
)
)
.join("")
),
}
);
// logic
2025-10-17 00:10:28 +02:00
{
// collapser
2025-10-17 00:10:28 +02:00
{
this.container.querySelector(".widget-menu-button").addEventListener(
2025-10-17 00:10:28 +02:00
"click",
() => {
this.toggle_collapsed();
}
);
}
// entries
2025-10-17 00:10:28 +02:00
{
this.container.querySelectorAll(".widget-menu-entry").forEach(
dom_entry => {
dom_entry.addEventListener(
"click",
() => {
const index : int = parseInt(dom_entry.getAttribute("rel"));
const entry : type_entry_data = this.entries[index];
this.toggle_collapsed({"mode": true});
entry.action();
}
);
}
);
2025-10-17 00:10:28 +02:00
}
}
// init
{
this.toggle_collapsed({"mode": true});
this.set_groups(this.initial_groups);
this.set_label(null);
}
// finish
target_element.appendChild(this.container);
2025-10-17 00:10:28 +02:00
}
}
}