You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
55 lines
3.6 KiB
Markdown
55 lines
3.6 KiB
Markdown
# CLAUDE.md
|
|
|
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
|
|
## Commands
|
|
|
|
```bash
|
|
npm run build # tsc emits individual ESM modules, then Rollup bundles ESM/CJS/UMD
|
|
npm run typecheck # tsc --noEmit
|
|
npm run lint # ESLint over src/**/*.{ts,js}
|
|
npm run format # Prettier formatting
|
|
```
|
|
|
|
There are no tests in this project. To preview components locally, open `index.html` in a browser with any static-file server.
|
|
|
|
## Architecture
|
|
|
|
This library wraps [Leaflet.js](https://leafletjs.com/) as native Web Components (Custom Elements). Each HTML element maps 1:1 to a Leaflet object.
|
|
|
|
### `WithProps` mixin: `src/core/with-props.ts`
|
|
|
|
The `WithProps(Base, PROPS)` mixin factory replaces the old `LeafletElement` base class. Each component defines a `PROPS` table (a const record mapping kebab-case attribute names to `PropDef` descriptors), then extends `WithProps(HTMLElement, PROPS)`. The mixin handles:
|
|
|
|
- `observedAttributes` getter derived from the PROPS table keys.
|
|
- `definePropAccessors` — property getters/setters on the prototype that sync attributes.
|
|
- `parseAttributeValue` for boolean, number, and JSON coersion in `attributeChangedCallback`.
|
|
- On connect, `initOptions()` builds a Leaflet options object from current attributes + PROPS defaults, then calls `createLeafletObject()`.
|
|
- On attribute change, `updateLeafletObject()` by default dispatches to the matching Leaflet setter (e.g. `setOpacity`, `setRadius`). Components override this for custom attribute handling (e.g. lat/lng pairs).
|
|
|
|
### `leaflet-map`: `src/components/leaflet-map.ts`
|
|
|
|
`LeafletMap` extends `HTMLElement` directly and uses Shadow DOM. It is the root of the component tree and terminates all bubbling `leaflet-register` events by calling `layer.addTo(this.map)`. Uses a `ResizeObserver` on the host element to call `map.invalidateSize()` automatically.
|
|
|
|
### Child component pattern
|
|
|
|
All non-map components extend `WithProps(HTMLElement, PROPS)`. To add a new component:
|
|
|
|
1. Define a `PROPS = {...}` const table mapping kebab-case attributes to `PropDef` entries.
|
|
2. Declare `class LeafletFoo extends WithProps(HTMLElement, PROPS)` implementing `createLeafletObject(): L.Layer`.
|
|
3. Override `updateLeafletObject(name, val)` only if the default setter-based update won't work (common for coordinate pairs).
|
|
4. Call `customElements.define('leaflet-foo', LeafletFoo)` at the bottom.
|
|
5. Export from `src/index.ts`.
|
|
|
|
For components that accept children (layers, popups, tooltips), use the `registerChildren`/`unregisterChildren`/`getChildren` WeakMap-backed helpers from `src/core/register.ts` in `connectedCallback`/`disconnectedCallback` instead of maintaining private fields.
|
|
|
|
### Special cases
|
|
|
|
- **`leaflet-polygon`** uses `<leaflet-line>` children for vertices. The polygon collects lat/lng from child `leaflet-line` elements rather than having them as direct attributes.
|
|
- **`leaflet-popup`** / **`leaflet-tooltip`**: content comes from `innerHTML`, not attributes. `leaflet-popup` watches for DOM mutations to keep Leaflet in sync.
|
|
- **`leaflet-layer-group`** / **`leaflet-feature-group`**: passthrough containers extending `HTMLElement` directly (not via `WithProps`). Children register themselves into them via the standard bubble mechanism.
|
|
|
|
### Output
|
|
|
|
`tsc` compiles `src/` → `dist/` as individual ESM modules (`.js` + `.d.ts` + `.d.ts.map`), then `rollup -c` bundles `dist/index.js` (ESM), `dist/index.cjs` (CJS), and `dist/index.umd.js` (UMD) — each with minified variants. Leaflet is always external (never bundled). Imports within source use `.ts` extensions; `rewriteRelativeImportExtensions` in tsconfig strips them to `.js` in the tsc output (`tsconfig.json:16`).
|