tag)
+import 'leaflet-components/components/leaflet-marker.js';
+```
+
+Each component is two modules with the same basename: `components/leaflet-marker.js` is the side-effecting one that calls `customElements.define()`, and `elements/leaflet-marker.js` is just the class (`default` export, **no** `define`). Import from `elements/` when you want to subclass a component or register it under a different tag name:
+
+```js
+// The class only — nothing is registered
+import LeafletMarkerElement from 'leaflet-components/elements/leaflet-marker.js';
+// …or the whole set, by name
+import { LeafletMarkerElement, LeafletCircleElement } from 'leaflet-components/elements';
```
`leaflet` is always an external dependency — you must install it yourself. There is no CommonJS or UMD build.
@@ -597,7 +606,7 @@ This library's own components are built from a small toolkit — a mixin, some p
1. Describe your attributes as a `PROPS` table, then extend `WithProps(PROPS, options?)`.
2. Implement `createLeafletObject(options)`, returning whatever Leaflet object your plugin provides.
3. `declare readonly leafletObject?: TheType;` — `WithProps`'s own inference of the object type from the `PROPS` table alone isn't reliable enough to skip this (every component in this package does it).
-4. Call `customElements.define('my-plugin-layer', MyPluginLayer)`.
+4. Call `customElements.define('my-plugin-layer', MyPluginLayer)`. (If you want to let _your_ consumers subclass or re-register, mirror this package's split: put the class in its own module as a `default` export and keep the `define()` call in a separate side-effecting module.)
```ts
import { MyClusterGroup, type MyClusterGroupOptions } from 'some-leaflet-plugin';
diff --git a/docs/01-architecture.md b/docs/01-architecture.md
index 2dbfb63..9e96ddb 100644
--- a/docs/01-architecture.md
+++ b/docs/01-architecture.md
@@ -7,21 +7,41 @@ Every `leaflet-*` custom element maps 1:1 to a single Leaflet object — a
element owns that object for its connected lifetime, holds the only reference
to it, and exposes it as `element.leafletObject`.
-Nothing about the wrapping is per-object hand-written plumbing. A component
-file is small (often 30–60 lines): a table of property descriptors, a
-`createLeafletObject()` that calls one Leaflet constructor, a couple of
-`declare` lines for types, and `customElements.define()`. Everything else —
-attributes, option building, two-way sync, event forwarding, tree membership
-— comes from the `WithProps` mixin.
+Nothing about the wrapping is per-object hand-written plumbing. An element
+class is small (often 30–60 lines): a table of property descriptors, a
+`createLeafletObject()` that calls one Leaflet constructor, and a couple of
+`declare` lines for types. Everything else — attributes, option building,
+two-way sync, event forwarding, tree membership — comes from the `WithProps`
+mixin.
+
+## `elements/` and `components/`
+
+Each component is two files sharing a basename:
+
+- **`src/elements/leaflet-foo.ts`** exports `default class LeafletFooElement
+extends WithProps(PROPS)` — the class alone, no side effects. Import it (or
+ the `src/elements/index.ts` barrel, which re-exports every class by name)
+ to get the constructor **without** registering a tag; useful for
+ subclassing or defining it under a different name.
+- **`src/components/leaflet-foo.ts`** is three lines: import the class,
+ `customElements.define('leaflet-foo', LeafletFooElement)`, re-export it.
+ Importing this module (or `src/index.ts`, which imports all of them in a
+ load-bearing order — see [06](./06-load-order.md)) is what registers the
+ tag.
+
+`package.json` maps `leaflet-components/elements`,
+`leaflet-components/elements/leaflet-foo.js` and
+`leaflet-components/components/leaflet-foo.js` onto the matching `dist/`
+files.
## The `WithProps` mixin
`src/core/with-props.ts`. `WithProps(PROPS, options?)` is a mixin **factory**:
it always extends `HTMLElement` internally (there is no base-class parameter)
-and returns a constructor. A component does:
+and returns a constructor. An element class does:
```ts
-export class LeafletMarker extends WithProps(PROPS) {
+export default class LeafletMarkerElement extends WithProps(PROPS) {
declare readonly leafletObject?: Marker;
createLeafletObject(options: MarkerOptions): Marker {
return new Marker([this.lat, this.lng], options);
@@ -97,8 +117,8 @@ anything about the concrete class.
## `leaflet-map` is special
-`src/components/leaflet-map.ts`. It still extends `WithProps(PROPS)` with
-`attach: 'none'`, but additionally:
+`src/elements/leaflet-map.ts`. `LeafletMapElement` still extends
+`WithProps(PROPS)` with `attach: 'none'`, but additionally:
- builds its own **Shadow DOM** in `connectedCallback` (a `` container
for Leaflet, a `