- leaflet moves from `dependencies` to `peerDependencies` (^1.9.4), kept in `devDependencies` for local dev/tests. The nesting protocol dispatches on `instanceof` against Leaflet's own Layer/Popup/Tooltip, so a second copy pulled in transitively would silently break child registration. - `@types/leaflet` (and its `@types/geojson` dep, imported directly by leaflet-geojson's emitted .d.ts) move to `dependencies` — the published declarations reference them and `leaflet` ships no types of its own, so a TS consumer had a broken type surface with nothing signalling why. - Drop the `exports["./dist/*"]` wildcard: it exposed the whole internal tree (`core/*`, explicitly "not a stable contract") as importable, semver-relevant surface. Root + `./elements` + `./components/*.js` cover every intended entry. - `prepublishOnly` now runs `typecheck` + `test` + `build`, not just `build`. Verified against a packed tarball: a fresh consumer with only the declared deps present typechecks clean under `moduleResolution` bundler and nodenext. CLAUDE.md / docs / README updated to match. |
2 weeks ago | |
|---|---|---|
| .. | ||
| 01-architecture.md | 2 weeks ago | |
| 02-props-and-attributes.md | 2 weeks ago | |
| 03-component-tree.md | 3 weeks ago | |
| 04-events.md | 2 weeks ago | |
| 05-special-cases.md | 2 weeks ago | |
| 06-load-order.md | 2 weeks ago | |
| 07-tooling-and-build.md | 2 weeks ago | |
| README.md | 2 weeks ago | |
README.md
Design docs
These describe how leaflet-components is built and why — the load-bearing
decisions, in their current form. They are not a usage guide (that's the
top-level README.md) and not a working cheat-sheet (that's
CLAUDE.md).
| Doc | Covers |
|---|---|
| 01 — Architecture | Element-per-Leaflet-object, the WithProps mixin, the lifecycle it owns |
| 02 — Props & attributes | The PropDef model, the codec factories, two-way attribute↔object sync |
| 03 — Component tree & registration | The leaflet-register bubbling protocol, attach modes, the other announcement events |
| 04 — Events | Re-emitting Leaflet events as leaflet:<type>, and how they're typed |
| 05 — Per-component special cases | Where a component does something the mixin can't express generically |
| 06 — Load order | Why the ./components/* import order in src/index.ts is load-bearing |
| 07 — Tooling & build | TypeScript 7, oxlint, oxfmt, Vitest, the no-bundle build, dual publish |
The one-paragraph version
Each leaflet-* custom element wraps exactly one Leaflet object. A mixin
(WithProps) generates the element class from a table of property
descriptors: it derives observedAttributes, builds the Leaflet options
object from the current attributes, calls the component's
createLeafletObject(), keeps attributes and the live object in sync in both
directions, and re-fires every Leaflet event on the element. Components join
each other through a DOM-event registration protocol that bubbles up to
<leaflet-map> at the root — no component ever reads another component's
state or queries the DOM for its relatives. The build is tsc with no
bundler; Leaflet is always external.