From acad0593c6971a693078eeeb4fb15f278c427fa9 Mon Sep 17 00:00:00 2001 From: Hsieh Chin Fan Date: Tue, 1 Oct 2024 16:31:39 +0800 Subject: fix: set menu position relative to click need to calculate offset of parent element --- src/MenuItem.mjs | 6 ++ src/css/dumbymap.css | 243 ++++++++++++++++++++++++++------------------------- src/dumbymap.mjs | 4 +- 3 files changed, 134 insertions(+), 119 deletions(-) (limited to 'src') diff --git a/src/MenuItem.mjs b/src/MenuItem.mjs index 6c2a1d9..8b812b1 100644 --- a/src/MenuItem.mjs +++ b/src/MenuItem.mjs @@ -4,6 +4,12 @@ class Item extends HTMLDivElement { this.innerHTML = innerHTML ?? text; this.onclick = onclick; this.classList.add('menu-item'); + + this.onmouseover = () => { + this.parentElement + .querySelectorAll('.sub-menu') + .forEach(sub => sub.remove()); + } } } window.customElements.define('menu-item', Item, { extends: 'div' }); diff --git a/src/css/dumbymap.css b/src/css/dumbymap.css index 7cb4d8c..4d0282b 100644 --- a/src/css/dumbymap.css +++ b/src/css/dumbymap.css @@ -219,6 +219,131 @@ root { } } +.menu { + display: block; + width: fit-content; + min-width: 10rem; + max-height: 40vh; + overflow-x: visible; + + position: absolute; + z-index: 9999; + + border: 2px solid gray; + border-radius: 6px; + + background: white; + + & > *:first-child { + border-top: 2px solid transparent; + border-radius: 5px 5px 0 0; + } + + & > *:last-child { + border-bottom: 2px solid transparent; + border-radius: 0 0 5px 5px; + } +} + +.menu-item { + display: flex; + justify-content: space-between; + padding: 0.5rem; + position: relative; + + z-index: 9999; + + cursor: pointer; + text-wrap: nowrap; + + &:hover { + background: rgb(226 232 240); + } + + .info { + padding-inline: 1em; + + color: steelblue; + font-weight: bold; + } + + &.folder::after { + content: '⏵'; + } +} + +.sub-menu { + overflow: scroll; + width: fit-content; + min-width: 6rem; + max-height: 40vh; + + position: absolute; + z-index: 100; + + border: 2px solid gray; + border-radius: 6px; + + background: white; + + .menu-item { + min-width: 5em; + margin: 0 auto; + padding-inline: 0.5em; + } +} + +.plainoverlay-body { + position: absolute; +} + +.plainmodal-content { + width: 700px; + height: 80%; + padding: 1em; + + position: absolute; + left: 50vw; + top: 50vh; + + background: white; + + transform: translate(-50%, -50%); + overflow-y: scroll; + white-space: pre; + + details { + margin-bottom: 0.5em; + } + + summary { + max-width: 60%; + + cursor: pointer; + } + + details > :not(summary) { + padding-left: 2em; + } + + p { + margin: 0.3em; + white-space: nowrap; + overflow-x: scroll; + } + + pre { + padding: 0.5em; + + background: #f0f0f0; + } + + .align-right { + display: inline-block; + float: right; + } +} + .Dumby { overflow: visible; width: 100%; @@ -609,121 +734,3 @@ root { .bold-options { font-weight: bold; } - -.menu { - display: none; - width: fit-content; - min-width: 10rem; - max-height: 40vh; - - position: absolute; - z-index: 9999; - - border: 2px solid gray; - border-radius: 6px; - - background: white; - overflow-y: scroll; -} - -.menu-item { - display: flex; - box-sizing: border-box; - justify-content: space-between; - padding: 0.5rem; - - z-index: 9999; - - border: 2px solid transparent; - border-radius: 5px; - - cursor: pointer; - text-wrap: nowrap; - - &:hover { - background: rgb(226 232 240); - } - - .info { - padding-inline: 1em; - - color: steelblue; - font-weight: bold; - } -} - -.folder::after { - content: '⏵'; -} - -.sub-menu { - overflow: scroll; - width: fit-content; - min-width: 6rem; - max-height: 40vh; - - position: absolute; - z-index: 100; - - border: 2px solid gray; - border-radius: 6px; - - background: white; - - .menu-item { - min-width: 5em; - margin: 0 auto; - padding-inline: 0.5em; - } -} - -.plainoverlay-body { - position: absolute; -} - -.plainmodal-content { - width: 700px; - height: 80%; - padding: 1em; - - position: absolute; - left: 50vw; - top: 50vh; - - background: white; - - transform: translate(-50%, -50%); - overflow-y: scroll; - white-space: pre; - - details { - margin-bottom: 0.5em; - } - - summary { - max-width: 60%; - - cursor: pointer; - } - - details > :not(summary) { - padding-left: 2em; - } - - p { - margin: 0.3em; - white-space: nowrap; - overflow-x: scroll; - } - - pre { - padding: 0.5em; - - background: #f0f0f0; - } - - .align-right { - display: inline-block; - float: right; - } -} diff --git a/src/dumbymap.mjs b/src/dumbymap.mjs index 2a6f332..cb528cd 100644 --- a/src/dumbymap.mjs +++ b/src/dumbymap.mjs @@ -462,12 +462,15 @@ export const generateMaps = (container, { delay, mapCallback }) => { // Menu {{{ const menu = document.createElement('div'); menu.className = 'menu'; + menu.style.display = 'none'; menu.onclick = () => (menu.style.display = 'none'); container.appendChild(menu); // Menu Items container.oncontextmenu = e => { menu.replaceChildren(); + menu.style.display = 'block'; + menu.style.cssText = `left: ${e.x - menu.offsetParent.offsetLeft + 10}px; top: ${e.y - menu.offsetParent.offsetTop + 5}px;`; e.preventDefault(); // GeoLinks @@ -476,7 +479,6 @@ export const generateMaps = (container, { delay, mapCallback }) => { const range = selection.getRangeAt(0); menu.appendChild(menuItem.addGeoLink(dumbymap, range)); } - menu.style.cssText = `overflow: visible; display: block; left: ${e.clientX + 10}px; top: ${e.clientY + 5}px;`; const map = e.target.closest('.mapclay'); if (map?.renderer?.results) { -- cgit v1.2.3-70-g09d2