refactor: rename withProps to WithProps

Capitalize the mixin factory name since it's used in the extends
position (class Foo extends WithProps(...)). Update CLAUDE.md to
match.
main
Buddy 3 months ago
parent f615dceea3
commit 10027c9fe7

@ -17,9 +17,9 @@ There are no tests in this project. To preview components locally, open `index.h
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`
### `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:
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.
@ -33,10 +33,10 @@ The `withProps(Base, PROPS)` mixin factory replaces the old `LeafletElement` bas
### Child component pattern
All non-map components extend `withProps(HTMLElement, PROPS)`. To add a new component:
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`.
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`.
@ -47,7 +47,7 @@ For components that accept children (layers, popups, tooltips), use the `registe
- **`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.
- **`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

@ -1,6 +1,6 @@
import { CircleMarker } from 'leaflet';
import { buildOptions, numAttr } from '../core/utils.ts';
import { withProps } from '../core/with-props.ts';
import { WithProps } from '../core/with-props.ts';
import { registerChildren, unregisterChildren } from '../core/register.ts';
import { isPathStyleAttr, updatePathStyle } from '../core/path-style.ts';
@ -18,7 +18,7 @@ const PROPS = defineProps({
fillOpacity: num(0.2),
});
export default class LeafletCircleMarker extends withProps(HTMLElement, PROPS) {
export default class LeafletCircleMarker extends WithProps(HTMLElement, PROPS) {
#obj?: CircleMarker;
connectedCallback() {

@ -1,6 +1,6 @@
import { Circle } from 'leaflet';
import { buildOptions, numAttr } from '../core/utils.ts';
import { withProps } from '../core/with-props.ts';
import { WithProps } from '../core/with-props.ts';
import { registerChildren, unregisterChildren } from '../core/register.ts';
import { isPathStyleAttr, updatePathStyle } from '../core/path-style.ts';
@ -18,7 +18,7 @@ const PROPS = defineProps({
fillOpacity: num(0.2),
});
export default class LeafletCircle extends withProps(HTMLElement, PROPS) {
export default class LeafletCircle extends WithProps(HTMLElement, PROPS) {
#obj?: Circle;
connectedCallback() {

@ -1,6 +1,6 @@
import { Control, ControlPosition } from 'leaflet';
import { registerWithParent } from '../core/utils.ts';
import { withProps } from '../core/with-props.ts';
import { WithProps } from '../core/with-props.ts';
import { defineProps, str } from '../core/props.ts';
@ -9,7 +9,7 @@ const PROPS = defineProps({
prefix: str(),
});
export default class LeafletControlAttribution extends withProps(HTMLElement, PROPS) {
export default class LeafletControlAttribution extends WithProps(HTMLElement, PROPS) {
#obj?: Control.Attribution;
connectedCallback() {

@ -1,6 +1,6 @@
import { Control, ControlPosition } from 'leaflet';
import { registerWithParent } from '../core/utils.ts';
import { withProps } from '../core/with-props.ts';
import { WithProps } from '../core/with-props.ts';
import { defineProps, num, str, on } from '../core/props.ts';
@ -12,7 +12,7 @@ const PROPS = defineProps({
updateWhenIdle: on(),
});
export default class LeafletControlScale extends withProps(HTMLElement, PROPS) {
export default class LeafletControlScale extends WithProps(HTMLElement, PROPS) {
#obj?: Control.Scale;
connectedCallback() {

@ -1,6 +1,6 @@
import { Control, ControlPosition } from 'leaflet';
import { registerWithParent } from '../core/utils.ts';
import { withProps } from '../core/with-props.ts';
import { WithProps } from '../core/with-props.ts';
import { defineProps, str } from '../core/props.ts';
@ -12,7 +12,7 @@ const PROPS = defineProps({
zoomOutTitle: str('Zoom out'),
});
export default class LeafletControlZoom extends withProps(HTMLElement, PROPS) {
export default class LeafletControlZoom extends WithProps(HTMLElement, PROPS) {
#obj?: Control.Zoom;
connectedCallback() {

@ -1,6 +1,6 @@
import { GeoJSON, PathOptions, Layer } from 'leaflet';
import { buildOptions } from '../core/utils.ts';
import { withProps } from '../core/with-props.ts';
import { WithProps } from '../core/with-props.ts';
import { registerChildren, unregisterChildren, getChildren } from '../core/register.ts';
import { defineProps, num, str, on } from '../core/props.ts';
@ -25,7 +25,7 @@ const PROP_BY_ATTR = new Map<string, string>(
Object.entries(PROPS).map(([name, spec]) => [spec.attr, name]),
);
export default class LeafletGeoJSON extends withProps(HTMLElement, PROPS) {
export default class LeafletGeoJSON extends WithProps(HTMLElement, PROPS) {
#obj?: GeoJSON;
connectedCallback() {

@ -1,7 +1,7 @@
import { ImageOverlay, LatLngBounds, LatLngExpression } from 'leaflet';
import type { ImageOverlayOptions } from 'leaflet';
import { buildOptions, buildAttrMap, setLayerAttr, parseBoundsAttr } from '../core/utils.ts';
import { withProps } from '../core/with-props.ts';
import { WithProps } from '../core/with-props.ts';
import { registerChildren, unregisterChildren } from '../core/register.ts';
import { defineProps, num, str, on } from '../core/props.ts';
@ -20,7 +20,7 @@ const PROPS = defineProps({
const PROP_BY_ATTR = buildAttrMap(PROPS);
export default class LeafletImageOverlay extends withProps(HTMLElement, PROPS) {
export default class LeafletImageOverlay extends WithProps(HTMLElement, PROPS) {
#obj?: ImageOverlay;
connectedCallback() {

@ -1,6 +1,6 @@
import { Marker } from 'leaflet';
import { buildOptions, numAttr, buildAttrMap, setLayerAttr } from '../core/utils.ts';
import { withProps } from '../core/with-props.ts';
import { WithProps } from '../core/with-props.ts';
import { registerChildren, unregisterChildren } from '../core/register.ts';
import { defineProps, num, str, on } from '../core/props.ts';
@ -17,7 +17,7 @@ const PROPS = defineProps({
const PROP_BY_ATTR = buildAttrMap(PROPS);
export default class LeafletMarker extends withProps(HTMLElement, PROPS) {
export default class LeafletMarker extends WithProps(HTMLElement, PROPS) {
#obj?: Marker;
#syncing = false;

@ -1,6 +1,6 @@
import { Polygon } from 'leaflet';
import { buildOptions } from '../core/utils.ts';
import { withProps } from '../core/with-props.ts';
import { WithProps } from '../core/with-props.ts';
import { registerChildren, unregisterChildren } from '../core/register.ts';
import { isPathStyleAttr, updatePathStyle } from '../core/path-style.ts';
@ -16,7 +16,7 @@ const PROPS = defineProps({
fillOpacity: num(0.2),
});
export default class LeafletPolygon extends withProps(HTMLElement, PROPS) {
export default class LeafletPolygon extends WithProps(HTMLElement, PROPS) {
#obj?: Polygon;
#observer?: MutationObserver;

@ -1,6 +1,6 @@
import { Polyline } from 'leaflet';
import { buildOptions } from '../core/utils.ts';
import { withProps } from '../core/with-props.ts';
import { WithProps } from '../core/with-props.ts';
import { registerChildren, unregisterChildren } from '../core/register.ts';
import { isPathStyleAttr, updatePathStyle } from '../core/path-style.ts';
@ -16,7 +16,7 @@ const PROPS = defineProps({
fillOpacity: num(0.2),
});
export default class LeafletPolyline extends withProps(HTMLElement, PROPS) {
export default class LeafletPolyline extends WithProps(HTMLElement, PROPS) {
#obj?: Polyline;
#observer?: MutationObserver;

@ -1,6 +1,6 @@
import { Popup } from 'leaflet';
import { registerWithParent, buildOptions, numAttr } from '../core/utils.ts';
import { withProps } from '../core/with-props.ts';
import { WithProps } from '../core/with-props.ts';
import { defineProps, num, on } from '../core/props.ts';
@ -15,7 +15,7 @@ const PROPS = defineProps({
autoClose: on(),
});
export default class LeafletPopup extends withProps(HTMLElement, PROPS) {
export default class LeafletPopup extends WithProps(HTMLElement, PROPS) {
#obj?: Popup;
#observer?: MutationObserver;

@ -1,6 +1,6 @@
import { Rectangle } from 'leaflet';
import { buildOptions, parseBoundsAttr } from '../core/utils.ts';
import { withProps } from '../core/with-props.ts';
import { WithProps } from '../core/with-props.ts';
import { registerChildren, unregisterChildren } from '../core/register.ts';
import { isPathStyleAttr, updatePathStyle } from '../core/path-style.ts';
@ -16,7 +16,7 @@ const PROPS = defineProps({
fillOpacity: num(0.2),
});
export default class LeafletRectangle extends withProps(HTMLElement, PROPS) {
export default class LeafletRectangle extends WithProps(HTMLElement, PROPS) {
#obj?: Rectangle;
connectedCallback() {

@ -1,7 +1,7 @@
import { SVGOverlay, LatLngBounds, LatLngExpression } from 'leaflet';
import type { ImageOverlayOptions } from 'leaflet';
import { buildOptions, buildAttrMap, setLayerAttr, parseBoundsAttr } from '../core/utils.ts';
import { withProps } from '../core/with-props.ts';
import { WithProps } from '../core/with-props.ts';
import { registerChildren, unregisterChildren } from '../core/register.ts';
import { defineProps, num, str, on } from '../core/props.ts';
@ -17,7 +17,7 @@ const PROPS = defineProps({
const PROP_BY_ATTR = buildAttrMap(PROPS);
export default class LeafletSVGOverlay extends withProps(HTMLElement, PROPS) {
export default class LeafletSVGOverlay extends WithProps(HTMLElement, PROPS) {
#obj?: SVGOverlay;
connectedCallback() {

@ -1,6 +1,6 @@
import { TileLayer } from 'leaflet';
import { buildOptions, buildAttrMap, setLayerAttr, parseAttributeValue } from '../core/utils.ts';
import { withProps } from '../core/with-props.ts';
import { WithProps } from '../core/with-props.ts';
import { registerChildren, unregisterChildren } from '../core/register.ts';
import { defineProps, num, str, on } from '../core/props.ts';
@ -17,7 +17,7 @@ const PROPS = defineProps({
const PROP_BY_ATTR = buildAttrMap(PROPS);
export default class LeafletTileLayerWMS extends withProps(HTMLElement, PROPS) {
export default class LeafletTileLayerWMS extends WithProps(HTMLElement, PROPS) {
#obj?: TileLayer.WMS;
connectedCallback() {

@ -1,6 +1,6 @@
import { TileLayer } from 'leaflet';
import { buildOptions, buildAttrMap, setLayerAttr } from '../core/utils.ts';
import { withProps } from '../core/with-props.ts';
import { WithProps } from '../core/with-props.ts';
import { registerChildren, unregisterChildren } from '../core/register.ts';
import { defineProps, num, str } from '../core/props.ts';
@ -16,7 +16,7 @@ const PROPS = defineProps({
const PROP_BY_ATTR = buildAttrMap(PROPS);
export default class LeafletTileLayer extends withProps(HTMLElement, PROPS) {
export default class LeafletTileLayer extends WithProps(HTMLElement, PROPS) {
#obj?: TileLayer;
connectedCallback() {

@ -1,7 +1,7 @@
import { Tooltip } from 'leaflet';
import type { TooltipOptions } from 'leaflet';
import { registerWithParent, buildOptions, numAttr } from '../core/utils.ts';
import { withProps } from '../core/with-props.ts';
import { WithProps } from '../core/with-props.ts';
import { defineProps, num, str, on } from '../core/props.ts';
@ -16,7 +16,7 @@ const PROPS = defineProps({
opacity: num(1.0),
});
export default class LeafletTooltip extends withProps(HTMLElement, PROPS) {
export default class LeafletTooltip extends WithProps(HTMLElement, PROPS) {
#obj?: Tooltip;
#observer?: MutationObserver;

@ -1,7 +1,7 @@
import { VideoOverlay, LatLngBounds, LatLngExpression } from 'leaflet';
import type { VideoOverlayOptions } from 'leaflet';
import { buildOptions, buildAttrMap, setLayerAttr, parseBoundsAttr } from '../core/utils.ts';
import { withProps } from '../core/with-props.ts';
import { WithProps } from '../core/with-props.ts';
import { registerChildren, unregisterChildren } from '../core/register.ts';
import { defineProps, num, str, on } from '../core/props.ts';
@ -21,7 +21,7 @@ const PROPS = defineProps({
const PROP_BY_ATTR = buildAttrMap(PROPS);
export default class LeafletVideoOverlay extends withProps(HTMLElement, PROPS) {
export default class LeafletVideoOverlay extends WithProps(HTMLElement, PROPS) {
#obj?: VideoOverlay;
connectedCallback() {

@ -21,7 +21,7 @@ export function parseAttributeValue(value: string | null): unknown {
// Installs reactive getter/setter pairs on a prototype for every entry in
// a PROPS table. Each getter reads from the attribute (coerced to the
// correct type), each setter writes via setAttribute/toggleAttribute.
// Used by the withProps() mixin so components have `el.lat = 51.5` sugar.
// Used by the WithProps() mixin so components have `el.lat = 51.5` sugar.
export function definePropAccessors(proto: object, props: Record<string, PropDef>) {
for (const [name, spec] of Object.entries(props)) {
Object.defineProperty(proto, name, {

@ -10,10 +10,10 @@ type Ctor<T = object> = new (...args: any[]) => T;
// defining a static initialization block, getters/setters, and an
// observedAttributes getter.
//
// Usage: `class LeafletFoo extends withProps(HTMLElement, PROPS)`
// Usage: `class LeafletFoo extends WithProps(HTMLElement, PROPS)`
// Returns an intersection type so consumers see the generated
// properties from PropTypesFromTable.
export function withProps<TBase extends Ctor<HTMLElement>, TProps extends Record<string, PropDef>>(
export function WithProps<TBase extends Ctor<HTMLElement>, TProps extends Record<string, PropDef>>(
Base: TBase,
props: TProps,
): TBase & Ctor<HTMLElement & PropTypesFromTable<TProps>> {

Loading…
Cancel
Save