refactor expanding control

This commit is contained in:
Gwendolyn 2024-12-26 01:27:45 +01:00
parent c9ecf967df
commit 7057919fd3
2 changed files with 150 additions and 188 deletions

View file

@ -1073,7 +1073,7 @@ main:not([data-view=route-result]) #route-summary {
font-size: 20px; font-size: 20px;
} }
.leaflet-bar, .leaflet-touch .leaflet-bar, .leaflet-control-key, .leaflet-control-overlays { .leaflet-bar, .leaflet-touch .leaflet-bar, .leaflet-control-expanding, .leaflet-control-overlays {
overflow: hidden; overflow: hidden;
background-color: var(--color-control-background); background-color: var(--color-control-background);
border-radius: var(--border-radius-leaflet-control); border-radius: var(--border-radius-leaflet-control);
@ -1691,10 +1691,10 @@ blink {
margin-top: 48px; margin-top: 48px;
} }
.leaflet-control-key, .leaflet-control-overlays { .leaflet-control-expanding {
background-clip: padding-box; background-clip: padding-box;
&.leaflet-control-key-expanded > .collapsed-toggle, &.leaflet-control-overlays-expanded > .collapsed-toggle { &.leaflet-control-expanded > .collapsed-toggle {
display: none; display: none;
} }
@ -1704,6 +1704,8 @@ blink {
height: 26px; height: 26px;
line-height: 26px; line-height: 26px;
text-align: center; text-align: center;
font-family: 'Material Symbols Outlined';
font-size: 26px;
color: var(--color-control); color: var(--color-control);
@ -1711,12 +1713,6 @@ blink {
width: 30px; width: 30px;
height: 30px; height: 30px;
} }
&::before {
font-family: 'Material Symbols Outlined';
font-size: 26px;
line-height: 26px;
}
} }
> .pin-toggle { > .pin-toggle {
@ -1750,15 +1746,14 @@ blink {
} }
} }
&.leaflet-control-key-expanded > .pin-toggle, &.leaflet-control-overlays-expanded > .pin-toggle { &.leaflet-control-expanded > .pin-toggle {
display: block; display: block;
.leaflet-touch & { .leaflet-touch & {
display: none; display: none;
} }
} }
> .content { > .leaflet-control-expanding-content {
display: none;
padding: 1rem 4rem 1rem 1rem; padding: 1rem 4rem 1rem 1rem;
.leaflet-touch & { .leaflet-touch & {
@ -1766,18 +1761,15 @@ blink {
} }
} }
&.leaflet-control-key-expanded > .content { &:not(.leaflet-control-expanded) > .leaflet-control-expanding-content {
display: grid; display: none;
} }
} }
.leaflet-control-key { .leaflet-control-key {
> .collapsed-toggle::before {
content: 'legend_toggle';
}
> .content { > .leaflet-control-expanding-content {
display: grid;
gap: 1rem; gap: 1rem;
grid-template-columns: 2rem 1fr; grid-template-columns: 2rem 1fr;
@ -1796,17 +1788,15 @@ blink {
} }
} }
&.leaflet-control-key-expanded > .content { &.leaflet-control-expanded > .leaflet-control-expanding-content {
display: grid; display: grid;
} }
} }
.leaflet-control-overlays { .leaflet-control-overlays {
> .collapsed-toggle::before {
content: 'stacks';
}
> .content { > .leaflet-control-expanding-content {
display: flex;
flex-direction: column; flex-direction: column;
gap: 1rem; gap: 1rem;
@ -1851,10 +1841,6 @@ blink {
margin-bottom: 0; margin-bottom: 0;
} }
} }
&.leaflet-control-overlays-expanded > .content {
display: flex;
}
} }
.leaflet-top.leaflet-right { .leaflet-top.leaflet-right {

View file

@ -2337,6 +2337,118 @@ function mobileclientOnResume() {
c3nav._resume(); c3nav._resume();
} }
ExpandingControl = L.Control.extend({
options: {
storageKey: null,
pinIcon: 'push_pin',
icon: '',
},
getStored: function(key, fallback=null) {
if (this.options.storageKey !== null) {
const fullKey = `c3nav.control.${this.options.storageKey}.${key}`;
try {
const value = localStorageWrapper.getItem(fullKey);
if (value === null) {
return fallback;
}
return JSON.parse(value);
} catch (err) {
console.warn(err);
localStorageWrapper.removeKey(fullKey);
return fallback;
}
} else {
return fallback;
}
},
setStored: function(key, value) {
if (this.options.storageKey !== null) {
const fullKey = `c3nav.control.${this.options.storageKey}.${key}`;
localStorageWrapper.setItem(fullKey, JSON.stringify(value));
}
},
onAdd: function () {
this._pinned = this.getStored('pinned', false);
this._container = L.DomUtil.create('div', 'leaflet-control-expanding ' + this.options.addClasses);
this._content = L.DomUtil.create('div', 'leaflet-control-expanding-content', this._container);
this._pin = L.DomUtil.create('div', 'pin-toggle material-symbols', this._container);
this._pin.innerText = c3nav._map_material_icon(this.options.pinIcon);
this._collapsed = L.DomUtil.create('a', 'collapsed-toggle', this._container);
this._collapsed.textContent = c3nav._map_material_icon(this.options.icon);
this._collapsed.href = '#';
if (!L.Browser.android) {
L.DomEvent.on(this._container, {
mouseenter: this.expand,
mouseleave: this.collapse
}, this);
}
if (L.Browser.mobile) {
this._pinned = false;
}
if (L.Browser.touch) {
$(this._collapsed).click((e) => {
e.preventDefault();
e.stopPropagation();
this.expand();
});
$(this._map).on('click', (e) => {
this.collapse();
});
} else {
L.DomEvent.on(this._container, 'focus', this.expand, this);
L.DomEvent.on(this._container, 'blur', this.collapse, this);
}
this._expanded = this._pinned;
this._container.classList.toggle('leaflet-control-expanded', this._expanded);
this._pin.classList.toggle('active', this._pinned);
$(this._container).on('click', 'div.pin-toggle', e => {
this.togglePinned();
});
$(this._container).on('mousedown pointerdown wheel', e => {
e.stopPropagation();
});
this.render();
return this._container;
},
expand: function () {
if (this._pinned) return;
this._expanded = true;
this._container.classList.add('leaflet-control-expanded');
return this;
},
collapse: function () {
if (this._pinned) return;
this._expanded = false;
this._container.classList.remove('leaflet-control-expanded');
return this;
},
togglePinned: function () {
this._pinned = !this._pinned;
if (this._pinned) {
this._expanded = true;
}
this._pin.classList.toggle('active', this._pinned);
this.setStored('pinned', this._pinned);
},
render: function () {},
});
LevelControl = L.Control.extend({ LevelControl = L.Control.extend({
options: { options: {
position: 'bottomright', position: 'bottomright',
@ -2440,7 +2552,6 @@ LevelControl = L.Control.extend({
} }
}); });
UserLocationControl = L.Control.extend({ UserLocationControl = L.Control.extend({
options: { options: {
position: 'bottomright', position: 'bottomright',
@ -2549,7 +2660,6 @@ ThemeControl = L.Control.extend({
}, },
}) })
QuestsControl = L.Control.extend({ QuestsControl = L.Control.extend({
options: { options: {
position: 'topright', position: 'topright',
@ -2635,7 +2745,6 @@ QuestsControl = L.Control.extend({
} }
}); });
L.SquareGridLayer = L.Layer.extend({ L.SquareGridLayer = L.Layer.extend({
initialize: function (config) { initialize: function (config) {
this.config = config; this.config = config;
@ -2735,59 +2844,14 @@ L.SquareGridLayer = L.Layer.extend({
} }
}); });
KeyControl = L.Control.extend({ KeyControl = ExpandingControl.extend({
options: {position: 'topright', addClasses: ''}, options: {
_keys: [], position: 'topright',
addClasses: 'leaflet-control-key',
onAdd: function () { icon: 'legend_toggle',
this._pinned = JSON.parse(localStorage.getItem('c3nav.key.pinned') ?? 'false'); storageKey: 'key',
this._container = L.DomUtil.create('div', 'leaflet-control-key ' + this.options.addClasses);
this._content = L.DomUtil.create('div', 'content', this._container);
this._pin = L.DomUtil.create('div', 'pin-toggle material-symbols', this._container);
this._pin.innerText = 'push_pin';
this._collapsed = L.DomUtil.create('a', 'collapsed-toggle', this._container);
this._collapsed.href = '#';
if (!L.Browser.android) {
L.DomEvent.on(this._container, {
mouseenter: this.expand,
mouseleave: this.collapse
}, this);
}
if (L.Browser.mobile) {
this._pinned = false;
}
if (L.Browser.touch) {
$(this._collapsed).click((e) => {
e.preventDefault();
e.stopPropagation();
this.expand();
});
$(this._map).on('click', (e) => {
this.collapse();
});
} else {
L.DomEvent.on(this._container, 'focus', this.expand, this);
L.DomEvent.on(this._container, 'blur', this.collapse, this);
}
this._expanded = this._pinned;
this._container.classList.toggle('leaflet-control-key-expanded', this._expanded);
this._pin.classList.toggle('active', this._pinned);
this.render();
$(this._container).on('click', 'div.pin-toggle', e => {
this.togglePinned();
});
$(this._container).on('mousedown pointerdown wheel', e => {
e.stopPropagation();
});
return this._container;
}, },
_keys: [],
addKey: function (name, background, border) { addKey: function (name, background, border) {
this._keys.push({ this._keys.push({
@ -2820,38 +2884,20 @@ KeyControl = L.Control.extend({
} }
this._content.replaceChildren(...fragment.children); this._content.replaceChildren(...fragment.children);
}, },
expand: function () {
if (this._pinned) return;
this._expanded = true;
this._container.classList.add('leaflet-control-key-expanded');
return this;
},
collapse: function () {
if (this._pinned) return;
this._expanded = false;
this._container.classList.remove('leaflet-control-key-expanded');
return this;
},
togglePinned: function () {
this._pinned = !this._pinned;
if (this._pinned) {
this._expanded = true;
}
this._pin.classList.toggle('active', this._pinned);
localStorage.setItem('c3nav.key.pinned', JSON.stringify(this._pinned));
},
}); });
OverlayControl = L.Control.extend({ OverlayControl = ExpandingControl.extend({
options: {position: 'topright', addClasses: '', levels: {}}, options: {
position: 'topright',
addClasses: 'leaflet-control-overlays',
icon: 'stacks',
storageKey: 'overlays',
levels: {}
},
_overlays: {}, _overlays: {},
_ungrouped: [], _ungrouped: [],
_groups: {}, _groups: {},
_initialActiveOverlays: null,
_initialCollapsedGroups: null,
initialize: function ({levels, ...config}) { initialize: function ({levels, ...config}) {
this.config = config; this.config = config;
@ -2859,81 +2905,34 @@ OverlayControl = L.Control.extend({
}, },
onAdd: function () { onAdd: function () {
this._initialActiveOverlays = JSON.parse(localStorage.getItem('c3nav.overlays.active-overlays') ?? '[]');
this._initialCollapsedGroups = JSON.parse(localStorage.getItem('c3nav.overlays.collapsed-groups') ?? '[]');
this._pinned = JSON.parse(localStorage.getItem('c3nav.overlays.pinned') ?? 'false');
this._container = L.DomUtil.create('div', 'leaflet-control-overlays ' + this.options.addClasses); const initialActiveOverlays = this.getStored('active', []);
this._content = L.DomUtil.create('div', 'content'); const initialCollapsedGroups = this.getStored('collapsed', []);
this._collapsed = L.DomUtil.create('a', 'collapsed-toggle');
this._collapsed.href = '#';
this._pin = L.DomUtil.create('div', 'pin-toggle material-symbols');
this._pin.innerText = 'push_pin';
this._container.append(this._pin, this._content, this._collapsed);
if (!L.Browser.android) { for (const overlay of initialActiveOverlays) {
L.DomEvent.on(this._container, {
mouseenter: this.expand,
mouseleave: this.collapse
}, this);
}
if (L.Browser.mobile) {
this._pinned = false;
}
if (L.Browser.touch) {
$(this._collapsed).click((e) => {
e.preventDefault();
e.stopPropagation();
this.expand();
});
$(this._container).click((e) => {
e.stopPropagation();
});
$(this._map).on('click', (e) => {
if (this._expanded) {
this.collapse();
}
});
} else {
L.DomEvent.on(this._container, 'focus', this.expand, this);
L.DomEvent.on(this._container, 'blur', this.collapse, this);
}
this._expanded = this._pinned;
this._container.classList.toggle('leaflet-control-overlays-expanded', this._expanded)
this._pin.classList.toggle('active', this._pinned);
for (const overlay of this._initialActiveOverlays) {
if (overlay in this._overlays) { if (overlay in this._overlays) {
this._overlays[overlay].visible = true; this._overlays[overlay].visible = true;
this._overlays[overlay].enable(this._levels); this._overlays[overlay].enable(this._levels);
} }
} }
for (const group of this._initialCollapsedGroups) { for (const group of initialCollapsedGroups) {
if (group in this._groups) { if (group in this._groups) {
this._groups[group].expanded = false; this._groups[group].expanded = false;
} }
} }
ExpandingControl.prototype.onAdd.call(this);
this.render(); this.render();
$(this._container).on('change', 'input[type=checkbox]', e => { $(this._container).on('change', 'input[type=checkbox]', e => {
this._overlays[e.target.dataset.id].visible = e.target.checked; this._overlays[e.target.dataset.id].visible = e.target.checked;
this.updateOverlay(e.target.dataset.id); this.updateOverlay(e.target.dataset.id);
}); });
$(this._container).on('click', 'div.pin-toggle', e => {
this.togglePinned();
});
$(this._container).on('click', '.content h4', e => { $(this._container).on('click', '.content h4', e => {
this.toggleGroup(e.target.parentElement.dataset.group); this.toggleGroup(e.target.parentElement.dataset.group);
}); });
$(this._container).on('mousedown pointerdown wheel', e => {
e.stopPropagation();
});
return this._container; return this._container;
}, },
@ -2963,7 +2962,7 @@ OverlayControl = L.Control.extend({
overlay.disable(this._levels); overlay.disable(this._levels);
} }
const activeOverlays = Object.keys(this._overlays).filter(k => this._overlays[k].visible); const activeOverlays = Object.keys(this._overlays).filter(k => this._overlays[k].visible);
localStorage.setItem('c3nav.overlays.active-overlays', JSON.stringify(activeOverlays)); this.setStored('active', activeOverlays);
}, },
render: function () { render: function () {
@ -3007,35 +3006,12 @@ OverlayControl = L.Control.extend({
this._content.replaceChildren(...ungrouped.children, ...groups.children); this._content.replaceChildren(...ungrouped.children, ...groups.children);
}, },
expand: function () {
if (this._pinned) return;
this._expanded = true;
this._container.classList.add('leaflet-control-overlays-expanded');
return this;
},
collapse: function () {
if (this._pinned) return;
this._expanded = false;
this._container.classList.remove('leaflet-control-overlays-expanded');
return this;
},
toggleGroup: function (name) { toggleGroup: function (name) {
const group = this._groups[name]; const group = this._groups[name];
group.expanded = !group.expanded; group.expanded = !group.expanded;
group.el.classList.toggle('expanded', group.expanded); group.el.classList.toggle('expanded', group.expanded);
const collapsedGroups = Object.keys(this._groups).filter(k => !this._groups[k].expanded); const collapsedGroups = Object.keys(this._groups).filter(k => !this._groups[k].expanded);
localStorage.setItem('c3nav.overlays.collapsed-groups', JSON.stringify(collapsedGroups)); this.setStored('collapsed', collapsedGroups);
},
togglePinned: function () {
this._pinned = !this._pinned;
if (this._pinned) {
this._expanded = true;
}
this._pin.classList.toggle('active', this._pinned);
localStorage.setItem('c3nav.overlays.pinned', JSON.stringify(this._pinned));
}, },
}); });