215 lines
3.9 KiB
TypeScript
215 lines
3.9 KiB
TypeScript
/*
|
|
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
|
|
{
|
|
|
|
/**
|
|
*/
|
|
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>;
|
|
|
|
|
|
/**
|
|
*/
|
|
private initial_groups : Array<string>;
|
|
|
|
|
|
/**
|
|
*/
|
|
private label : (null | string);
|
|
|
|
|
|
/**
|
|
*/
|
|
private container : (null | HTMLElement);
|
|
|
|
|
|
/**
|
|
*/
|
|
public constructor(
|
|
entries : Array<type_entry_data>,
|
|
{
|
|
"initial_groups": initial_groups = [],
|
|
"initial_label": initial_label = "",
|
|
}
|
|
:
|
|
{
|
|
initial_groups ?: Array<string>;
|
|
initial_label ?: string;
|
|
}
|
|
=
|
|
{
|
|
}
|
|
)
|
|
{
|
|
this.entries = entries;
|
|
this.initial_groups = initial_groups;
|
|
this.label = initial_label;
|
|
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));
|
|
}
|
|
);
|
|
}
|
|
|
|
|
|
/**
|
|
*/
|
|
public set_label(
|
|
label : (null | string)
|
|
)
|
|
: void
|
|
{
|
|
this.label = label;
|
|
this.container.querySelector(".widget-menu-button").innerHTML = (
|
|
(this.label === null)
|
|
?
|
|
("[" + "=" + "]")
|
|
:
|
|
("[" + this.label + "]")
|
|
);
|
|
}
|
|
|
|
|
|
/**
|
|
*/
|
|
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
|
|
{
|
|
// collapser
|
|
{
|
|
this.container.querySelector(".widget-menu-button").addEventListener(
|
|
"click",
|
|
() => {
|
|
this.toggle_collapsed();
|
|
}
|
|
);
|
|
}
|
|
// entries
|
|
{
|
|
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();
|
|
}
|
|
);
|
|
}
|
|
);
|
|
}
|
|
}
|
|
|
|
// init
|
|
{
|
|
this.toggle_collapsed({"mode": true});
|
|
this.set_groups(this.initial_groups);
|
|
this.set_label(null);
|
|
}
|
|
|
|
// finish
|
|
target_element.appendChild(this.container);
|
|
}
|
|
|
|
}
|
|
|
|
}
|