feat(map): adopt cooperative gestures to stop trapping page scroll#266
Merged
Conversation
Leaflet binds the wheel to zoom and a single finger to pan, so scrolling the page with the pointer over a map got swallowed and the page stuck — the scroll trap that mod-mermaid removed from inline diagrams in v4.10.0. The map now claims only a gesture that is unambiguously meant for it: - Wheel scrolls the page; Ctrl/Cmd + wheel zooms the map. - Mouse drag still pans, unchanged. - One finger scrolls the page; two fingers pan and pinch-zoom. A gesture the map ignores briefly shows an overlay explaining how to address the map instead, so it does not read as broken. The listeners run in the capture phase, which settles the gesture before Leaflet's own handlers further down the tree ever see it. The hint text is rendered by the shortcode, so it stays translatable; only the modifier is resolved in the browser, because it depends on the visitor's platform. Adds i18n for the eight languages Hinode ships, and mounts i18n, which the module did not do before. Leaflet's vendored stylesheet is remounted as leaflet-vendor.scss so that assets/scss/leaflet.scss — the module's single stylesheet slot — can import it and add the overlay styles, leaving the file that postinstall regenerates untouched. The overlay class keeps the leaflet- prefix that Hinode's PurgeCSS safelist already covers. Verified in a browser on the block reference: a plain wheel leaves the tiles at zoom 13 and shows the hint, Ctrl + wheel takes them to 12, and both the overlay styles and the vendored Leaflet CSS compile. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Contributor
Author
|
🎉 This PR is included in version 3.1.0 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
This was referenced Jul 13, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Leaflet binds the wheel to zoom and a single finger to pan. Scrolling the page with the
pointer over a map therefore gets swallowed and the page sticks — the classic embedded-map scroll
trap. It reproduces today on
gethinode.com/docs/components/map: a plain wheel over
the map takes the tiles from zoom 13 to 12 instead of scrolling the page.
This is the same trap gethinode/mod-mermaid#338 removed from inline diagrams in v4.10.0. That PR
described its goal as following "the cooperative-gesture pattern used by embedded maps" — so this
restores the pattern to the map it was named after.
Change
The map now claims only a gesture that is unambiguously meant for it:
Ctrl/⌘+ wheel+/−, keyboardA gesture the map ignores briefly shows an overlay — "Use ⌘ + scroll to zoom the map" — so an
ignored gesture does not read as a broken map.
How it works
Every listener runs in the capture phase. Leaflet binds its own handlers deeper in the tree, so
stopping the event here (wheel without a modifier) or withdrawing the handler here (
draggingduring a one-finger touch) settles the gesture before Leaflet ever sees it. With the modifier held
the event is simply let through, so Leaflet applies its own tuned zoom rather than a reimplementation
of it.
Notable details
data-leaflet-hint-*; only themodifier is resolved in the browser, since it depends on the visitor's platform (
⌘vsCtrl).Adds
i18n/for the eight languages Hinode ships, and thei18nmount, which the module lacked.dist/leaflet.scssis Leaflet's vendored CSS, regenerated bypostinstall, and it occupied the module's singleassets/scss/leaflet.scssslot — so the overlaystyles had nowhere to live. It is remounted as
leaflet-vendor.scss, and a hand-writtenassets/scss/leaflet.scssimports it and adds the overlay. The vendored file stays untouched.leaflet-prefix that Hinode's PurgeCSS safelist (/^leaflet-/)already covers, and is
pointer-events: none+aria-hidden— it is advisory and must neverswallow the gesture it is explaining.
reintroduce the bug.
Verification
Driven in a real browser against the block reference, with the module replaced locally into a
Hinode host:
Ctrl+ wheel{modifier}placeholder⌘on macOS ✅position: absolute, scrim,pointer-events: none✅pnpm testpasses.Review notes
The seven non-English translations are mine and have not been reviewed by a native speaker —
worth a look, particularly
zh-hans/zh-hant. The hint timing (2s) and the dark scrim are easy toadjust.
🤖 Generated with Claude Code