edge/pkg/sdk/client/src/menu-manager.ts

144 lines
3.6 KiB
TypeScript

import { Menu } from "./components/menu"
export interface MenuItem {
label: string
iconUrl: string
linkUrl: string
order: number
}
const EdgeBodyAutoPaddingAttrName = 'edge-auto-padding'
export class MenuManager {
_items: { [name:string]: MenuItem }
_menu: Menu
_appIconUrl: string
_appTitle: string
_hidden: boolean
_previousBodyAutoPadding: string
constructor() {
this._items = {};
this._handleLoad = this._handleLoad.bind(this);
window.addEventListener('load', this._handleLoad);
}
setItem(name: string, label:string, options?: { iconUrl?: string, linkUrl?: string, order?: number }) {
this._items[name] = {
label: label,
iconUrl: options?.iconUrl ? options?.iconUrl : '',
linkUrl: options?.linkUrl ? options?.linkUrl : '#',
order: options?.order ? options?.order : 0,
}
this._render();
return this;
}
removeItem(name: string) {
delete this._items[name];
this._render();
return this;
}
setAppIconUrl(url: string) {
this._appIconUrl = url;
this._render();
return this;
}
setAppTitle(title: string) {
this._appTitle = title;
this._render();
return this;
}
show() {
if (!this._hidden) return;
this._hidden = false;
if (this._previousBodyAutoPadding) {
document.body.setAttribute(EdgeBodyAutoPaddingAttrName, this._previousBodyAutoPadding);
} else {
document.body.removeAttribute(EdgeBodyAutoPaddingAttrName);
}
this._render();
}
hide() {
if (this._hidden) return;
this._hidden = true;
this._previousBodyAutoPadding = document.body.getAttribute(EdgeBodyAutoPaddingAttrName);
document.body.setAttribute(EdgeBodyAutoPaddingAttrName, "false");
this._render();
}
_handleLoad() {
this._init();
}
_init() {
this._initMenu();
this._initGlobalStyle();
}
_initMenu() {
const menu = document.createElement('edge-menu');
document.body.appendChild(menu);
this._menu = menu;
this._render();
}
_initGlobalStyle() {
const style = document.createElement('style');
style.textContent = `
body:not([${EdgeBodyAutoPaddingAttrName}="false"]) {
padding-top: 60px;
}
`;
document.head.appendChild(style);
}
_render() {
if (!this._menu) return;
if (this._hidden) {
this._menu.setAttribute("hidden", "true");
} else {
this._menu.removeAttribute("hidden");
}
if (this._appIconUrl) {
this._menu.setAttribute("app-icon-url", this._appIconUrl);
} else {
this._menu.removeAttribute("app-icon-url");
}
if (this._appTitle) {
this._menu.setAttribute("app-title", this._appTitle);
} else {
this._menu.removeAttribute("app-title");
}
const children: Node[] = [];
const items: MenuItem[] = Object.keys(this._items)
.map(key => ({ name: key, ...this._items[key] }))
.sort((a, b) => a.order - b.order)
;
for (let item: MenuItem, i = 0; (item = items[i]); i++) {
const node = document.createElement('edge-menu-sub-item');
node.label = item.label;
node.iconUrl = item.iconUrl;
node.linkUrl = item.linkUrl;
children.push(node);
}
this._menu.replaceChildren(...children);
}
}