Make layers toggle on click like other UI elements

This commit is contained in:
James Lyne 2021-05-28 19:14:06 +01:00
parent 3cf9a01184
commit af3ef17ec4
3 changed files with 78 additions and 30 deletions

2
src/index.d.ts vendored
View File

@ -60,5 +60,5 @@ interface LiveAtlasMessageConfig {
mapTitle: string; mapTitle: string;
} }
export type LiveAtlasUIElement = 'chat' | 'players' | 'maps' | 'settings'; export type LiveAtlasUIElement = 'layers' | 'chat' | 'players' | 'maps' | 'settings';
export type LiveAtlasSidebarSection = 'servers' | 'players' | 'maps'; export type LiveAtlasSidebarSection = 'servers' | 'players' | 'maps';

View File

@ -24,14 +24,23 @@ import Layers = Control.Layers;
import '@/assets/icons/layers.svg'; import '@/assets/icons/layers.svg';
import '@/assets/icons/checkbox.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 { export class DynmapLayerControl extends Control.Layers {
private _layersLink?: HTMLElement; private _layersButton?: HTMLElement;
private _map ?: LeafletMap; private _map ?: LeafletMap;
private _overlaysList?: HTMLElement; private _overlaysList?: HTMLElement;
private _baseLayersList?: HTMLElement; private _baseLayersList?: HTMLElement;
private _layerControlInputs?: HTMLElement[]; private _layerControlInputs?: HTMLElement[];
private _layerPositions: Map<Layer, number>; private _layerPositions: Map<Layer, number>;
private _container?: HTMLElement;
private _section?: HTMLElement;
private _separator?: HTMLElement;
private visible: boolean = false;
constructor(baseLayers?: LayersObject, overlays?: LayersObject, options?: LayersOptions) { constructor(baseLayers?: LayersObject, overlays?: LayersObject, options?: LayersOptions) {
// noinspection JSUnusedGlobalSymbols // noinspection JSUnusedGlobalSymbols
@ -51,30 +60,15 @@ export class DynmapLayerControl extends Control.Layers {
this._layerPositions = new Map<Layer, number>(); this._layerPositions = new Map<Layer, number>();
} }
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 = `
<svg class="svg-icon" aria-hidden="true">
<use xlink:href="#icon--layers" />
</svg>`;
return element;
}
hasLayer(layer: Layer): boolean { hasLayer(layer: Layer): boolean {
// @ts-ignore // @ts-ignore
return !!super._getLayer(Util.stamp(layer)); return !!super._getLayer(Util.stamp(layer));
} }
expand() { expand() {
// @ts-ignore this._layersButton!.setAttribute('aria-expanded', 'true');
DomUtil.addClass(this._container, 'leaflet-control-layers-expanded'); this._section!.style.display = '';
this._layersLink!.setAttribute('aria-expanded', 'true'); this.handleResize();
// @ts-ignore // @ts-ignore
super._checkDisabledLayers(); super._checkDisabledLayers();
@ -82,13 +76,68 @@ export class DynmapLayerControl extends Control.Layers {
} }
collapse() { collapse() {
// @ts-ignore this._layersButton!.setAttribute('aria-expanded', 'false');
DomUtil.removeClass(this._container, 'leaflet-control-layers-expanded'); this._section!.style.display = 'none';
this._layersLink!.setAttribute('aria-expanded', 'false');
return this; 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 = `
<svg class="svg-icon" aria-hidden="true">
<use xlink:href="#icon--layers" />
</svg>`;
//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 { addOverlayAtPosition(layer: Layer, name: string, position: number): this {
this._layerPositions.set(layer, position); this._layerPositions.set(layer, position);
return super.addOverlay(layer, name); return super.addOverlay(layer, name);

View File

@ -144,15 +144,14 @@
width: auto; width: auto;
border: none; border: none;
color: var(--text-base); color: var(--text-base);
position: relative;
&.leaflet-control-layers-expanded {
padding: 0;
}
.leaflet-control-layers-list { .leaflet-control-layers-list {
padding: 0.7rem 1.5rem; @extend %panel;
height: 100%; display: block;
box-sizing: border-box; position: absolute;
top: 0;
left: 6rem;
overflow: auto; overflow: auto;
.layer { .layer {