# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Commands ```bash npm run build # Type-check + emit .d.ts via tsc, then bundle to dist/index.js via esbuild 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 a dev server that supports TypeScript (e.g. `npx vite`). ## 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. ### Core base class: `src/core/LeafletElement.ts` `LeafletElement` (extends `HTMLElement`) is the abstract base for all components except `leaflet-map`. Subclasses must implement `createLeafletObject()` returning an `L.Layer`. The base class: - Reads `observedAttributes` to auto-populate `this.options` via `initOptions()` on connect, converting kebab-case attribute names to camelCase for Leaflet options. - Parses attribute values to booleans, numbers, or JSON automatically (`parseAttributeValue`). - On `attributeChangedCallback`, calls `updateLeafletObject()` which by default invokes the matching Leaflet setter (e.g. `setOpacity`, `setRadius`). Subclasses override this for attributes needing custom logic (e.g. lat/lng pairs). - Uses a custom `leaflet-register` bubbling event to wire children into parents. When a child connects, it dispatches this event upward; each parent intercepts and either calls `addLayer`, `bindPopup`, or `bindTooltip` depending on the child's type. ### `leaflet-map`: `src/components/leaflet-map.ts` `LeafletMap` does **not** extend `LeafletElement` — it 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)`. ### Child component pattern All other components extend `LeafletElement`. To add a new component: 1. Extend `LeafletElement`, implement `createLeafletObject()`. 2. Declare `static get observedAttributes()` listing HTML attributes (kebab-case). 3. Override `updateLeafletObject()` 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`. ### Special cases - **`leaflet-polygon`** uses `` 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`**: a passthrough container; children register themselves into it via the standard bubble mechanism. ### Output `tsc` compiles `src/` → `dist/` with `.js` files and `.d.ts` declarations. Imports within the source use `.js` extensions (required for ESM `"moduleResolution": "bundler"`).