From af3ef17ec4b72aa876ccd22a2de0f56ac8665de7 Mon Sep 17 00:00:00 2001 From: James Lyne Date: Fri, 28 May 2021 19:14:06 +0100 Subject: [PATCH] Make layers toggle on click like other UI elements --- src/index.d.ts | 2 +- src/leaflet/control/DynmapLayerControl.ts | 93 +++++++++++++++++------ src/scss/leaflet/_controls.scss | 13 ++-- 3 files changed, 78 insertions(+), 30 deletions(-) diff --git a/src/index.d.ts b/src/index.d.ts index a71493d..935c542 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -60,5 +60,5 @@ interface LiveAtlasMessageConfig { mapTitle: string; } -export type LiveAtlasUIElement = 'chat' | 'players' | 'maps' | 'settings'; +export type LiveAtlasUIElement = 'layers' | 'chat' | 'players' | 'maps' | 'settings'; export type LiveAtlasSidebarSection = 'servers' | 'players' | 'maps'; \ No newline at end of file diff --git a/src/leaflet/control/DynmapLayerControl.ts b/src/leaflet/control/DynmapLayerControl.ts index 4629f43..1bb996c 100644 --- a/src/leaflet/control/DynmapLayerControl.ts +++ b/src/leaflet/control/DynmapLayerControl.ts @@ -24,14 +24,23 @@ import Layers = Control.Layers; import '@/assets/icons/layers.svg'; import '@/assets/icons/checkbox.svg'; +import {useStore} from "@/store"; +import {MutationTypes} from "@/store/mutation-types"; +import {watch} from "vue"; + +const store = useStore(); export class DynmapLayerControl extends Control.Layers { - private _layersLink?: HTMLElement; + private _layersButton?: HTMLElement; private _map ?: LeafletMap; private _overlaysList?: HTMLElement; private _baseLayersList?: HTMLElement; private _layerControlInputs?: HTMLElement[]; private _layerPositions: Map; + private _container?: HTMLElement; + private _section?: HTMLElement; + private _separator?: HTMLElement; + private visible: boolean = false; constructor(baseLayers?: LayersObject, overlays?: LayersObject, options?: LayersOptions) { // noinspection JSUnusedGlobalSymbols @@ -51,30 +60,15 @@ export class DynmapLayerControl extends Control.Layers { this._layerPositions = new Map(); } - onAdd(map: LeafletMap) { - // @ts-ignore - const element = super.onAdd(map); - - this._layersLink!.parentElement!.removeAttribute('aria-haspopup'); - this._layersLink!.setAttribute('role', 'button'); - this._layersLink!.setAttribute('aria-expanded', 'false'); - this._layersLink!.innerHTML = ` - `; - - return element; - } - hasLayer(layer: Layer): boolean { // @ts-ignore return !!super._getLayer(Util.stamp(layer)); } expand() { - // @ts-ignore - DomUtil.addClass(this._container, 'leaflet-control-layers-expanded'); - this._layersLink!.setAttribute('aria-expanded', 'true'); + this._layersButton!.setAttribute('aria-expanded', 'true'); + this._section!.style.display = ''; + this.handleResize(); // @ts-ignore super._checkDisabledLayers(); @@ -82,13 +76,68 @@ export class DynmapLayerControl extends Control.Layers { } collapse() { - // @ts-ignore - DomUtil.removeClass(this._container, 'leaflet-control-layers-expanded'); - this._layersLink!.setAttribute('aria-expanded', 'false'); + this._layersButton!.setAttribute('aria-expanded', 'false'); + this._section!.style.display = 'none'; return this; } + _initLayout() { + const className = 'leaflet-control-layers', + container = this._container = DomUtil.create('div', className); + + DomEvent.disableClickPropagation(container); + DomEvent.disableScrollPropagation(container); + + const section = this._section = DomUtil.create('section', className + '-list'), + button = this._layersButton = DomUtil.create('button', className + '-toggle', container); + + section.style.display = 'none'; + + button.title = 'Layers'; + button.setAttribute('aria-expanded', 'false'); + button.innerHTML = ` + `; + + //Use vuex to toggle and track expanded state + DomEvent.on(button,'click', () => store.commit(MutationTypes.TOGGLE_UI_ELEMENT_VISIBILITY, 'layers')); + + watch(store.state.ui.visibleElements, (newValue) => { + if(newValue.has('layers') && !this.visible) { + this.expand(); + } else if(this.visible && !newValue.has('layers')) { + this.collapse(); + } + + this.visible = store.state.ui.visibleElements.has('layers'); + }); + + this.visible = store.state.ui.visibleElements.has('layers'); + + if (this.visible) { + this.expand(); + } + + this._baseLayersList = DomUtil.create('div', className + '-base', section); + this._separator = DomUtil.create('div', className + '-separator', section); + this._overlaysList = DomUtil.create('div', className + '-overlays', section); + + container.appendChild(section); + + window.addEventListener('resize', () => this.handleResize()); + this.handleResize(); + } + + handleResize() { + const y = this._layersButton!.getBoundingClientRect().y; + + //Limit height to remaining vertical space + // Including 30px element padding, 10px padding from edge of viewport, and 55px padding to avoid covering bottom bar + this._section!.style.maxHeight = `calc(100vh - ${(y + 30 + 10 + 55)}px)`; + } + addOverlayAtPosition(layer: Layer, name: string, position: number): this { this._layerPositions.set(layer, position); return super.addOverlay(layer, name); diff --git a/src/scss/leaflet/_controls.scss b/src/scss/leaflet/_controls.scss index d211d2e..3dd93a8 100644 --- a/src/scss/leaflet/_controls.scss +++ b/src/scss/leaflet/_controls.scss @@ -144,15 +144,14 @@ width: auto; border: none; color: var(--text-base); - - &.leaflet-control-layers-expanded { - padding: 0; - } + position: relative; .leaflet-control-layers-list { - padding: 0.7rem 1.5rem; - height: 100%; - box-sizing: border-box; + @extend %panel; + display: block; + position: absolute; + top: 0; + left: 6rem; overflow: auto; .layer {