feat(explorer): move zoom controls into the map toolbar

This commit is contained in:
Meysam Parvizi
2026-10-11 17:12:17 +02:00
parent 456bcb954b
commit 92a37ddac9
2 changed files with 69 additions and 24 deletions
+55 -18
View File
@@ -473,29 +473,44 @@
}
.zoom-controls {
position: absolute;
right: 16px;
bottom: 16px;
display: grid;
justify-items: center;
gap: 6px;
padding: 6px;
border: 1px solid var(--border);
border-radius: 14px;
background: var(--surface);
backdrop-filter: blur(10px);
display: flex;
align-items: center;
gap: 2px;
margin-left: auto;
padding: 1px;
border: 1px solid var(--border-strong);
border-radius: 999px;
background: var(--surface-2);
}
.zoom-controls .icon-btn {
width: 34px;
height: 34px;
font-size: 18px;
width: 26px;
height: 26px;
border: 0;
border-radius: 999px;
background: transparent;
font-size: 17px;
font-weight: 700;
}
.zoom-controls .icon-btn:hover {
background: var(--chip-hover);
}
.btn-icon {
display: block;
fill: none;
stroke: currentColor;
stroke-width: 2;
stroke-linecap: round;
stroke-linejoin: round;
}
.zoom-level {
min-width: 40px;
color: var(--muted);
font-size: 11px;
font-size: 12px;
text-align: center;
font-variant-numeric: tabular-nums;
}
@@ -527,10 +542,32 @@
.menu-list {
min-width: 0;
}
}
.zoom-controls {
bottom: 12px;
right: 12px;
/* Phones pinch to zoom, so the bar keeps only the fit button. */
@media (max-width: 600px) {
.map-top {
padding: 6px 8px;
}
.map-toolbar {
gap: 4px;
}
.map-toolbar .map-chip {
padding: 4px 9px;
}
.zoom-controls .zoom-step,
.zoom-level,
.map-chip .label-long {
display: none;
}
}
@media (min-width: 601px) {
.map-chip .label-short {
display: none;
}
}
+14 -6
View File
@@ -105,7 +105,7 @@ export function createMapView({ root, plan, data, build, onSelect }) {
h('p', { class: 'menu-heading' }, 'Importance'),
h('div', { class: 'menu-chips' }, importanceChips.map(([, el]) => el)),
clearButton);
const linksChip = chip('All connections', 'links', () => {
const linksChip = chip([h('span', { class: 'label-long' }, 'All connections'), h('span', { class: 'label-short' }, 'Links')], 'links', () => {
state.showAll = !state.showAll;
refresh();
}, 'Show the lines between all related topics');
@@ -605,16 +605,24 @@ export function createMapView({ root, plan, data, build, onSelect }) {
});
const zoomLevel = h('span', { class: 'zoom-level', 'aria-live': 'polite' }, '100%');
const fitButton = h('button', { type: 'button', class: 'icon-btn', 'aria-label': 'Toggle between fitting the width and the whole page', title: 'Show the whole page', onclick: toggleFit }, '⤢');
const zoomControls = h('div', { class: 'zoom-controls' },
h('button', { type: 'button', class: 'icon-btn', 'aria-label': 'Zoom in', title: 'Zoom in (Ctrl + scroll)', onclick: () => zoomAt(1.25) }, '+'),
// Drawn as SVG: text glyphs sit on font baselines that differ between browsers.
const btnIcon = (d) => {
const el = svg('svg', { viewBox: '0 0 16 16', width: 14, height: 14, 'aria-hidden': 'true', class: 'btn-icon' });
svg('path', { d }, el);
return el;
};
const fitButton = h('button', { type: 'button', class: 'icon-btn zoom-fit', 'aria-label': 'Toggle between fitting the width and the whole page', title: 'Show the whole page', onclick: toggleFit },
btnIcon('M9.5 2.5h4v4M13.5 2.5 9 7M6.5 13.5h-4v-4M2.5 13.5 7 9'));
const zoomControls = h('div', { class: 'zoom-controls', role: 'group', 'aria-label': 'Zoom' },
h('button', { type: 'button', class: 'icon-btn zoom-step', 'aria-label': 'Zoom out', title: 'Zoom out (Ctrl + scroll)', onclick: () => zoomAt(1 / 1.25) }, btnIcon('M3 8h10')),
zoomLevel,
h('button', { type: 'button', class: 'icon-btn', 'aria-label': 'Zoom out', title: 'Zoom out (Ctrl + scroll)', onclick: () => zoomAt(1 / 1.25) }, '−'),
h('button', { type: 'button', class: 'icon-btn zoom-step', 'aria-label': 'Zoom in', title: 'Zoom in (Ctrl + scroll)', onclick: () => zoomAt(1.25) }, btnIcon('M3 8h10M8 3v10')),
fitButton);
toolbar.append(zoomControls);
root.replaceChildren(
h('div', { class: 'map-top' }, toolbar),
h('div', { class: 'map-canvas' }, chart, zoomControls),
h('div', { class: 'map-canvas' }, chart),
tip,
);
fitWidth();