From 27feb1302304eede3cdc58ffde5ce8e0f0019da4 Mon Sep 17 00:00:00 2001 From: Hsieh Chin Fan Date: Sun, 29 Sep 2024 21:01:03 +0800 Subject: feat: add submenu for map/block/layout switching * Add general classes into MenuItem * Use MutationObserver for data-mode * Automatically unfocus other maps when one is focused TODO: * hover effect on submenu item doesn't work, why? * shorcuts hint in selector ".folder.menu-item" not looks great --- src/MenuItem.mjs | 101 ++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 82 insertions(+), 19 deletions(-) (limited to 'src/MenuItem.mjs') diff --git a/src/MenuItem.mjs b/src/MenuItem.mjs index 734c313..e974f9e 100644 --- a/src/MenuItem.mjs +++ b/src/MenuItem.mjs @@ -1,31 +1,94 @@ import { createGeoLink } from './dumbymap'; -export function nextMap() { - const element = document.createElement('div'); - element.className = 'menu-item'; - element.innerHTML = 'Next Map (Tab)'; - element.onclick = () => this.utils.focusNextMap(); +class Item { + constructor({ text, innerHTML, onclick }) { + this.text = text; + this.innerHTML = innerHTML; + this.onclick = onclick; + } - return element; + get element() { + const element = document.createElement('div'); + element.innerHTML = this.innerHTML ? this.innerHTML : this.text; + element.classList.add('menu-item'); + element.onclick = this.onclick; + return element; + } } -export function nextBlock() { - const element = document.createElement('div'); - element.className = 'menu-item'; - element.innerHTML = 'Next Block (n)'; - element.onclick = () => this.utils.focusNextBlock(); +class Folder { + constructor({ text, innerHTML, items }) { + this.text = text; + this.innerHTML = innerHTML; + this.items = items; + this.utils; + } + + get element() { + const element = document.createElement('div'); + element.classList.add(this.className); + element.className = 'menu-item folder'; + element.innerHTML = this.innerHTML; + element.style.cssText = 'position: relative; overflow: visible;'; + element.onmouseover = () => { + // Prepare submenu + this.submenu = document.createElement('div'); + this.submenu.className = 'sub-menu'; + this.submenu.style.cssText = `position: absolute; left: 105%; top: 0px;`; + this.items.forEach(item => this.submenu.appendChild(item)); - return element; + // hover effect + element.parentElement + .querySelectorAll('.sub-menu') + .forEach(sub => sub.remove()); + element.appendChild(this.submenu); + }; + return element; + } } -export function nextLayout() { - const element = document.createElement('div'); - element.className = 'menu-item'; - element.innerHTML = 'Next Layout (x)'; - element.onclick = () => this.utils.switchToNextLayout(); +export const pickMapItem = dumbymap => + new Folder({ + innerHTML: 'Focus a Map(Tab)', + items: dumbymap.utils.renderedMaps().map( + map => + new Item({ + text: map.id, + onclick: () => map.classList.add('focus'), + }).element, + ), + }).element; - return element; -} +export const pickBlockItem = dumbymap => + new Folder({ + innerHTML: 'Focus Block(n/p)', + items: dumbymap.blocks.map( + (block, index) => + new Item({ + text: `Block ${index}`, + onclick: () => block.classList.add('focus'), + }).element, + ), + }).element; + +export const pickLayoutItem = dumbymap => + new Folder({ + innerHTML: 'Switch Layout(x)', + items: [ + new Item({ + text: 'EDIT', + onclick: () => document.body.setAttribute('data-mode', 'editing'), + }).element, + ...dumbymap.layouts.map( + layout => + new Item({ + text: layout.name, + onclick: () => + dumbymap.container.setAttribute('data-layout', layout.name), + }).element, + ), + ], + }).element; export class GeoLink { constructor({ range }) { -- cgit v1.2.3-70-g09d2