diff --git a/client/public/stylesheets/contextmenus.css b/client/public/stylesheets/contextmenus.css index 9ed665f4..f6981488 100644 --- a/client/public/stylesheets/contextmenus.css +++ b/client/public/stylesheets/contextmenus.css @@ -5,7 +5,7 @@ position: absolute; row-gap: 5px; width: 230px; - z-index: 1000; + z-index: 9999; } #aircraft-spawn-menu { diff --git a/client/public/stylesheets/olympus.css b/client/public/stylesheets/olympus.css index 013a8290..306ae8b3 100644 --- a/client/public/stylesheets/olympus.css +++ b/client/public/stylesheets/olympus.css @@ -142,8 +142,9 @@ form > div { } .ol-select>.ol-select-options { - position: absolute; + border-radius: var( --border-radius-md ); overflow: hidden; + position: absolute; max-height: 0; translate: 0 -2px; z-index: 1000; @@ -160,9 +161,15 @@ form > div { overflow-y: auto; padding: 8px 0; min-width: 100%; + z-index:9999; } +.ol-select.is-open[data-position="top"] > .ol-select-options { + top:0; + translate:0 -100%; +} + .ol-select>.ol-select-options > div { diff --git a/client/src/controls/dropdown.ts b/client/src/controls/dropdown.ts index 52716b01..2870db8c 100644 --- a/client/src/controls/dropdown.ts +++ b/client/src/controls/dropdown.ts @@ -8,15 +8,61 @@ export class Dropdown { constructor(ID: string, callback: CallableFunction, options: string[] | null = null) { - this.#element = document.getElementById(ID); - this.#options = this.#element.querySelector(".ol-select-options"); - this.#value = this.#element.querySelector(".ol-select-value"); + this.#element = document.getElementById(ID); + this.#options = this.#element.querySelector(".ol-select-options"); + this.#value = this.#element.querySelector(".ol-select-value"); this.#defaultValue = this.#value.innerText; - this.#callback = callback; - if (options != null) + this.#callback = callback; + + if (options != null) { this.setOptions(options); + } + + this.#value.addEventListener( "click", ev => { + + this.#element.classList.toggle( "is-open" ); + this.#clip(); + + }); + + this.#element.addEventListener("mouseleave", ev => { + this.#close(); + }); + } + #clip() { + + const options = this.#options; + const bounds = options.getBoundingClientRect(); + + this.#element.dataset.position = ( bounds.bottom > window.innerHeight ) ? "top" : ""; + + } + + + #close() { + this.#element.classList.remove( "is-open" ); + this.#element.dataset.position = ""; + } + + + #open() { + this.#element.classList.add( "is-open" ); + } + + + #toggle() { + + if ( this.#element.classList.contains( "is-open" ) ) { + this.#close(); + } else { + this.#open(); + } + + } + + setOptions(optionsList: string[]) { this.#optionsList = optionsList; @@ -26,8 +72,10 @@ export class Dropdown { button.textContent = option; div.appendChild(button); button.addEventListener("click", (e: MouseEvent) => { + e.stopPropagation(); this.#value.innerText = option; - this.#callback(option); + this.#close(); + this.#callback( option, e ); }); return div; })); diff --git a/client/src/index.ts b/client/src/index.ts index 10a3b720..266f34e2 100644 --- a/client/src/index.ts +++ b/client/src/index.ts @@ -213,27 +213,6 @@ function setupEvents() { el.classList.toggle( "hide" ); }) }); - - /** Olympus UI ***/ - document.querySelectorAll(".ol-select").forEach(select => { - - // Do open/close toggle - select.addEventListener("click", ev => { - - if ( ev.target instanceof HTMLElement && ev.target.nodeName !== "A" ) { - ev.preventDefault(); - } - - ev.stopPropagation(); - select.classList.toggle("is-open"); - }); - - // Autoclose on mouseleave - select.addEventListener("mouseleave", ev => { - select.classList.remove("is-open"); - }); - - }); } export function getMap() { diff --git a/client/views/uikit.ejs b/client/views/uikit.ejs index cccaa8be..998a071d 100644 --- a/client/views/uikit.ejs +++ b/client/views/uikit.ejs @@ -982,6 +982,42 @@ + +
+ +
+
+ The selected value goes here +
+
+
+ +
+
+ +
+
+
+ +
+ +
+ +
+
+ Options go up +
+
+
+ +
+
+ +
+
+
+ +