feat: add GeoKitHooks — programmatic callbacks alongside every DOM CustomEvent - #46
Draft
shoesCodeFor with Copilot wants to merge 3 commits into
Draft
shoesCodeFor with Copilot wants to merge 3 commits into
shoesCodeFor with Copilot wants to merge 3 commits into
Conversation
Copilot
AI
changed the title
[WIP] Add support for user-defined hooks and event emitters in geokit
feat: add GeoKitHooks — programmatic callbacks alongside every DOM CustomEvent
Apr 4, 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.
Good Vibes
Summary
Users had no way to wire callbacks directly to geokit's internal events — the only option was DOM
addEventListener. This adds ahooksproperty that accepts plain callback objects, called in lock-step with everyCustomEventdispatch.Rationale
Framework consumers (React, Preact, Django widgets) often manage state through callback props rather than DOM listeners. The
hooksobject is read at call-time so it can be replaced at any point with no controller reinit, and it composes cleanly alongside the existing event system — both paths fire for every event.The
onIngesthook receives the same mutabledetailobject as theleaflet-draw:ingestDOM event, preserving the data-transformation contract.Changes
src/types/events.ts— addedDrawStartEventDetail,DrawStopEventDetail,EditStartEventDetail,EditStopEventDetail(previously named inDrawEventconstants but untyped)src/types/public.ts— newGeoKitHooksinterface;LeafletDrawMapElementAPIgains ahookspropertysrc/lib/MapController.ts—MapControllerCallbacksextended withonDrawStart,onDrawStop,onEditStart,onEditStop; all four wired inbindDrawEvents()viaL.Draw.Event.*src/components/LeafletDrawMapElement.ts—hooksgetter/setter (null/undefinednormalised to{}); every callback and direct dispatch site now also calls the matching hookUsage:
Screenshots / Recordings (if UI-visible)
No UI change — purely additive API surface.
Test Plan
tests/component-hooks.spec.ts— 21 tests covering getter/setter, all 11 hook callbacks, DOM event co-firing, mutable ingest, live hook replacement, andMapControllerCallbacksshape.Coverage
vitest.config.ts)Breaking Changes
Docs
Checklist
npm run lint)npm run typecheck)npm run test:unit)Related Issues / Links
Warning
Firewall rules blocked me from connecting to one or more addresses (expand for details)
I tried to connect to the following addresses, but was blocked by firewall rules:
example.com/opt/hostedtoolcache/node/24.14.1/x64/bin/node /opt/hostedtoolcache/node/24.14.1/x64/bin/node --conditions node --conditions development --experimental-import-meta-resolve --require /home/REDACTED/work/leaflet-geokit/leaflet-geokit/node_modules/vitest/suppress-warnings.cjs /home/REDACTED/work/leaflet-geokit/leaflet-geokit/node_modules/vitest/dist/workers/forks.js(dns block)/opt/hostedtoolcache/node/24.14.1/x64/bin/node /opt/hostedtoolcache/node/24.14.1/x64/bin/node --conditions node --conditions development --experimental-import-meta-resolve --require /home/REDACTED/work/leaflet-geokit/leaflet-geokit/node_modules/vitest/suppress-warnings.cjs /home/REDACTED/work/leaflet-geokit/leaflet-geokit/node_modules/vitest/dist/workers/forks.js Detail, EditStar--conditions node_modules/vitnode node_modules/vit--conditions node�� HEAD(dns block)/opt/hostedtoolcache/node/24.14.1/x64/bin/node /opt/hostedtoolcache/node/24.14.1/x64/bin/node --conditions node --conditions development --experimental-import-meta-resolve --require /home/REDACTED/work/leaflet-geokit/leaflet-geokit/node_modules/vitest/suppress-warnings.cjs /home/REDACTED/work/leaflet-geokit/leaflet-geokit/node_modules/vitest/dist/workers/forks.js --require node_modules/vit--verify node_modules/vitmain src/�� es/public.ts src/types/events.ts k/leaflet-geokit/node_modules/.bin/node tests/component-dirname l, DrawStopEvent.husky/_/post-checkout --ignore-REDACTED node(dns block)If you need me to access, download, or install something from one of these locations, you can either: