15 Commits (4d05109d98909c2feda6eebb5acd18de9698927c)

Author SHA1 Message Date
Buddy ebd6f20cdf chore: packaging polish for 0.1.0
- ship `src/` in the npm tarball alongside `dist/` — the emitted `.d.ts.map`
  reference `../../src/*.ts`, so "go to definition" only lands on real code
  if the source is there; also gives npm/JSR source parity. (+16 kB packed.)
- `sideEffects` becomes an explicit allowlist (`dist/index.js`,
  `dist/index.npm.js`, `dist/components/*.js`) instead of `true`, so bundlers
  can tree-shake the side-effect-free `elements/*` and `core/*`.
- add `scripts/sync-version.mjs`: copies `package.json` version into
  `jsr.json`. Wired into the `version` npm lifecycle hook (so `npm version`
  bumps and stages both) and re-run in `prepublishOnly`.
- add `repository` / `bugs` / `homepage`; `author` -> "Buddy Sandidge" (was
  "buddy", now matches LICENSE); a few more `keywords`.
- note in README/CLAUDE/docs that per-component deep imports
  (`./elements/*.js`, `./components/*.js`) are npm-only — JSR has no subpath
  patterns, so `jsr.json` exposes just `.` and `./elements`.
- exclude `scripts/` and `CLAUDE.md` from the JSR tarball.

Verified: `typecheck`, `lint`, `test` (76), `build`, `jsr publish --dry-run`
("Success"), and a fresh `npm pack` consumer typecheck all pass.
2 weeks ago
Buddy c03eb77d5b chore: fix packaging anti-patterns before 0.1.0 publish
- 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
Buddy b7f7a43113 chore: prep 0.1.0 for npm + JSR publish
npm name `leaflet-components` is taken by another author, so the npm package
is renamed to `leaflet-web-components`; JSR stays `@buddy/leaflet-components`.
Adds the MIT `LICENSE` file (was declared but missing).

Entry split so JSR can publish with no slow types:

- `src/index.ts` is the shared/JSR entry and no longer carries any
  `declare global`.
- `src/core/globals.ts` (new) holds the `HTMLElementTagNameMap` /
  `HTMLElementEventMap` augmentations; imported only by the new npm entry
  `src/index.npm.ts` and by `test/setup.ts`, and listed in `jsr.json`'s
  `publish.exclude` so it never enters JSR's module graph.
- `package.json` `.`/`main`/`module`/`types` now point at `dist/index.npm.*`.

Every element file switches from `class extends WithProps({...})` to a
`const PROPS` (with an explicit type) plus
`const Base: LeafletElementConstructor<TheClass, typeof PROPS> = WithProps(PROPS)`,
which is what clears JSR's `unsupported-super-class-expr` /
`missing-explicit-type` errors. Adds a `Positional<T, Obj>` alias in
`props.ts` and explicit object types on the `shared-props.ts` fragments to
keep those annotations short. Empty group tables use `Record<never, never>`.

`npx jsr publish --dry-run` now reports "Success" with zero slow-type
errors; `npm run typecheck`, `lint`, `test` (76) and `build` all pass.

CLAUDE.md, docs/ and README.md updated for the rename, the entry split, and
the `const PROPS` / `const Base` pattern.
2 weeks ago
Buddy f9c07a263d refactor: split element classes from customElements.define
Every component is now two modules sharing a basename:

- src/elements/leaflet-foo.ts -- `export default class LeafletFooElement
  extends WithProps(...)`, the class only, no customElements.define, no
  side effects. src/elements/index.ts is an order-free barrel.
- src/components/leaflet-foo.ts -- three lines: import the class, define
  the tag, re-export. Importing this (or src/index.ts) registers the tag.

Plugin authors can now import a class without triggering the built-in
define, to subclass it or register it under a different tag name. Package
subpath exports `leaflet-components/elements`,
`leaflet-components/elements/leaflet-foo.js`, and
`leaflet-components/components/leaflet-foo.js` map onto dist/; jsr.json
gains an `./elements` entry.

The load-bearing ordering moves from the export statements in src/index.ts
to its `./components/*` side-effect imports (the elements barrel carries no
define, so its order is free). Classes are renamed LeafletFoo ->
LeafletFooElement, including in the HTMLElementTagNameMap augmentation.

Docs (CLAUDE.md, docs/, README.md) updated for the new layout.
2 weeks ago
Buddy 2c77784345 docs: add design docs breaking down architecture and major decisions
Eight docs under docs/ covering the current design: the WithProps mixin
and lifecycle, the PropDef/attribute model, the leaflet-register bubbling
protocol, generic event forwarding and its typing, per-component special
cases, the load-bearing export order in src/index.ts, and the toolchain
(TS 7, oxlint, oxfmt, Vitest, the no-bundle build, dual npm/JSR publish).

Also wire docs/**/*.md into the format script and point at docs/ from
CLAUDE.md and README.md.
3 weeks ago
Buddy 449767335b chore: migrate formatter from prettier to oxfmt
Replace prettier with oxfmt (oxc's Prettier-compatible formatter), config
seeded via `oxfmt --migrate=prettier` and kept as `oxfmt.config.ts`
(defineConfig default export) so settings match the old prettier.config.js.
The `format` script now runs `oxfmt`; docs and the local tool allowlist
updated to match.
3 weeks ago
Buddy ef7828128b feat: make WMS crs extensible via a nested provider element, not a registry
Replaces the mutable registerCRS() registry (never released beyond this
branch) with a web-components-first design: any custom element, no base
class required, can provide a CRS Leaflet doesn't ship by nesting inside
<leaflet-tile-layer-wms> and firing a bubbling leaflet-crs-changed event
(detail: { crs: CRS | null }, mirroring icon-changed's { icon: null }
pattern for "revert to default"). The plain `crs="EPSG4326"` attribute
stays as a convenience shortcut for the 4 CRSes Leaflet itself ships; a
nested provider takes priority over it when both are present.

This surfaced a real, previously-undiscovered bug in with-props.ts:
recreateLeafletObject() was declared on the public LeafletElement
interface but only ever implemented as a private #recreateLeafletObject()
-- calling it would throw "is not a function" at runtime despite
type-checking cleanly. Fixed by making it public, and it now also
re-dispatches registerWithParent() for attach !== 'none' components,
which it never did before (previously only safe for attach: 'none'
components like icons, since recreate would otherwise rebuild a layer
without ever re-adding it to whatever registered it the first time --
exactly what leaflet-tile-layer-wms needs when a nested provider's crs
arrives after it already constructed itself with the default).
4 weeks ago
Buddy b90616d3c5 docs: add plugin authoring guide to README
Documents the toolkit third-party components are built from, now that
it's exported from the package root: the WithProps + PROPS table
pattern, the prop builder reference, reusing the shared fragments
(pathProps/latLngProps/tileLayerProps/urlProp), how nesting works
(attach modes, and why Leaflet plugin classes register correctly without
any special-casing on either side), typing events with
LeafletAddEventListener and the event-types.ts fragments, the
emitIconChanged protocol for custom marker icons, and the
customElements.define ordering pitfall for a plugin with multiple
interdependent custom elements of its own.
4 weeks ago
Buddy 255d10499b docs: bring README and CLAUDE.md up to date
README.md:
- Import options: drop CJS/UMD/minified-bundle mentions, none exist since
  the build simplified to ESM-only.
- New Events + TypeScript sections documenting the leaflet:<type> event
  forwarding mechanism and the HTMLElementTagNameMap / per-component
  addEventListener typing added this session.
- leaflet-tile-layer: 6 -> 23 attributes (full tileLayerProps), fixed
  z-index default (0 -> 1).
- leaflet-tile-layer-wms: now documents that it inherits all tile-layer
  attributes (previously listed none, matching the bug fixed earlier) +
  the new crs attribute.
- leaflet-video-overlay: added the 4 attributes added this session.
- leaflet-polyline: fixed a wrong "excludes fill*" claim and added
  smooth-factor/no-clip.
- leaflet-geojson: was documenting a stale hand-picked subset of path
  attributes (with stroke mis-described as a color); now says all
  path-style attributes apply, matching the dedup against pathProps.
- Path style table: added stroke/interactive/bubbling-mouse-events/
  class-name/pane, fixed fill's default.
- Added leaflet-icon/leaflet-div-icon sections (existed but were
  undocumented).
- Nesting rules and Development section brought in line with reality.

CLAUDE.md: the WithProps mixin description referenced an API from before
this session that no longer exists (WithProps(Base, PROPS), definePropAccessors,
initOptions(), updateLeafletObject()) and claimed LeafletMap extends
HTMLElement directly when it extends WithProps(...) like everything else.
Rewrote to match the real internals, fixed the child-component-pattern
steps, and documented how to type a new component's events.

Also added '*.md' to the format script's glob -- root markdown files
weren't covered, so this formatting could have silently drifted again.
4 weeks ago
Buddy 0855851504 docs: document leaflet-control-layers component and active attribute 3 months ago
Buddy c283632262 feat: add leafletObject escape hatch + move event wiring
Every component now exposes a uniform get leafletObject() returning
the underlying Leaflet instance (undefined before connected).

Event wiring:
- Marker: listen for 'dragend move' via onChange, syncing lat/lng
  back to attributes. Converted from arrow property to regular
  method using Leaflet's 3rd context arg pattern.
- Circle, CircleMarker: listen for 'move' via onMove with syncing
  guard (same pattern).
- Popup, Tooltip: listen for 'move' via onChange with syncing
  guard and null-check on getLatLng().

Also:
- Update README with escape hatch section
- Change map getter from get map() to get leafletObject() for
  consistency
- index.html: add importmap for leaflet
- All component exports changed from default to named
- index.ts re-exports updated accordingly
3 months ago
Buddy edecb44533 docs: update README and CLAUDE.md for current build and architecture
Remove stale JSR reference, add import-options section (formats, deep
imports, leaflet as external dep), fix build command (esbuild -> Rollup).
Rewrite CLAUDE.md architecture to reflect withProps mixin, register.ts
helpers, feature-group, and the full rollup output.
3 months ago
Buddy 319b7bdb0c docs: remove vite mentions from README and CLAUDE.md 3 months ago
Buddy fcfcdbfb7a docs: add full attribute tables for all components
Replace the brief 'Other components' section with complete per-component
attribute tables including defaults and descriptions. Add CSS/resize docs
for leaflet-map and a shared path-style reference table.
4 months ago
Buddy 6b448ba092 feat: Initial implementation of leaflet-components
Wraps Leaflet.js as native Web Components. Each element maps 1:1 to a
Leaflet object with reactive attribute binding and proper lifecycle cleanup.

Key design decisions:
- LeafletElement base class handles attribute→option mapping, the
  leaflet-register bubble event for parent/child wiring, and
  disconnectedCallback cleanup tracking parent bindings.
- LeafletControl base class for map controls (zoom, attribution, scale).
- leaflet-map uses a PROPS table to drive observedAttributes, getters/setters,
  attributeChangedCallback, and map event listeners from a single source of
  truth. Property types are derived via a mapped type over the table; the
  mixin-base pattern (TypedBase) makes them visible to TypeScript without an
  interface merge.
- Boolean map options that default to true use disable-* attributes.
- Leaflet and its CSS are bundled into dist/index.js via esbuild.
- JSR config included for @buddy/leaflet-components.
4 months ago