From bdf5bd56f3626f02012ae081b72e952704d92471 Mon Sep 17 00:00:00 2001 From: Buddy Date: Sun, 14 Jun 2026 20:50:21 -0700 Subject: [PATCH] chore: rename core files and move functions Removed the utils.ts file. The functions in there either should have been a part of the register.ts or props.ts files. The only functions left related to attributes so utils.ts was renamed to attributes.ts --- src/components/leaflet-circle-marker.ts | 4 +- src/components/leaflet-circle.ts | 4 +- src/components/leaflet-control-attribution.ts | 3 +- src/components/leaflet-control-layers.ts | 3 +- src/components/leaflet-control-scale.ts | 3 +- src/components/leaflet-control-zoom.ts | 3 +- src/components/leaflet-feature-group.ts | 3 +- src/components/leaflet-geojson.ts | 3 +- src/components/leaflet-image-overlay.ts | 4 +- src/components/leaflet-layer-group.ts | 3 +- src/components/leaflet-marker.ts | 4 +- src/components/leaflet-polygon.ts | 4 +- src/components/leaflet-polyline.ts | 4 +- src/components/leaflet-popup.ts | 5 +- src/components/leaflet-rectangle.ts | 4 +- src/components/leaflet-svg-overlay.ts | 4 +- src/components/leaflet-tile-layer-wms.ts | 4 +- src/components/leaflet-tile-layer.ts | 4 +- src/components/leaflet-tooltip.ts | 5 +- src/components/leaflet-video-overlay.ts | 4 +- src/core/{utils.ts => attributes.ts} | 55 +------------------ src/core/props.ts | 35 ++++++++++++ src/core/register.ts | 17 +++++- src/index.ts | 2 +- 24 files changed, 94 insertions(+), 90 deletions(-) rename src/core/{utils.ts => attributes.ts} (61%) diff --git a/src/components/leaflet-circle-marker.ts b/src/components/leaflet-circle-marker.ts index 3460b7f..cb74791 100644 --- a/src/components/leaflet-circle-marker.ts +++ b/src/components/leaflet-circle-marker.ts @@ -1,7 +1,7 @@ import { CircleMarker } from 'leaflet'; -import { WithProps, defineProps, num, str, on } from '../core/props.ts'; +import { WithProps, defineProps, num, str, on, buildOptions } from '../core/props.ts'; import { registerChildren, unregisterChildren } from '../core/register.ts'; -import { buildOptions, isPathStyleAttr, numAttr, updatePathStyle } from '../core/utils.ts'; +import { isPathStyleAttr, numAttr, updatePathStyle } from '../core/attributes.ts'; const PROPS = defineProps({ lat: num(), diff --git a/src/components/leaflet-circle.ts b/src/components/leaflet-circle.ts index 2025e5a..4a0b142 100644 --- a/src/components/leaflet-circle.ts +++ b/src/components/leaflet-circle.ts @@ -1,7 +1,7 @@ import { Circle } from 'leaflet'; -import { WithProps, defineProps, num, str, on } from '../core/props.ts'; +import { WithProps, defineProps, num, str, on, buildOptions } from '../core/props.ts'; import { registerChildren, unregisterChildren } from '../core/register.ts'; -import { buildOptions, isPathStyleAttr, numAttr, updatePathStyle } from '../core/utils.ts'; +import { isPathStyleAttr, numAttr, updatePathStyle } from '../core/attributes.ts'; const PROPS = defineProps({ lat: num(), diff --git a/src/components/leaflet-control-attribution.ts b/src/components/leaflet-control-attribution.ts index 53b0c73..210ae10 100644 --- a/src/components/leaflet-control-attribution.ts +++ b/src/components/leaflet-control-attribution.ts @@ -1,6 +1,7 @@ import { Control, ControlPosition } from 'leaflet'; import { WithProps, defineProps, str } from '../core/props.ts'; -import { registerWithParent } from '../core/utils.ts'; + +import { registerWithParent } from '../core/register.ts'; const PROPS = defineProps({ position: str('bottomright'), diff --git a/src/components/leaflet-control-layers.ts b/src/components/leaflet-control-layers.ts index 7b48369..7e9d9be 100644 --- a/src/components/leaflet-control-layers.ts +++ b/src/components/leaflet-control-layers.ts @@ -1,7 +1,6 @@ import { Control, ControlPosition, Layer } from 'leaflet'; import { WithProps, defineProps, str } from '../core/props.ts'; -import { registerWithParent } from '../core/utils.ts'; -import { LeafletRegisterEvent } from '../core/register.ts'; +import { LeafletRegisterEvent, registerWithParent } from '../core/register.ts'; const PROPS = defineProps({ position: str('topright'), diff --git a/src/components/leaflet-control-scale.ts b/src/components/leaflet-control-scale.ts index 1d8d7fe..298b8c2 100644 --- a/src/components/leaflet-control-scale.ts +++ b/src/components/leaflet-control-scale.ts @@ -1,6 +1,7 @@ import { Control, ControlPosition } from 'leaflet'; import { WithProps, defineProps, num, str, on } from '../core/props.ts'; -import { registerWithParent } from '../core/utils.ts'; + +import { registerWithParent } from '../core/register.ts'; const PROPS = defineProps({ position: str('bottomleft'), diff --git a/src/components/leaflet-control-zoom.ts b/src/components/leaflet-control-zoom.ts index f15e5ac..7b464e7 100644 --- a/src/components/leaflet-control-zoom.ts +++ b/src/components/leaflet-control-zoom.ts @@ -1,6 +1,7 @@ import { Control, ControlPosition } from 'leaflet'; import { WithProps, defineProps, str } from '../core/props.ts'; -import { registerWithParent } from '../core/utils.ts'; + +import { registerWithParent } from '../core/register.ts'; const PROPS = defineProps({ position: str('topleft'), diff --git a/src/components/leaflet-feature-group.ts b/src/components/leaflet-feature-group.ts index 1d7de08..5ff3cd4 100644 --- a/src/components/leaflet-feature-group.ts +++ b/src/components/leaflet-feature-group.ts @@ -1,6 +1,7 @@ import { FeatureGroup, Layer } from 'leaflet'; import { registerChildren, unregisterChildren, getChildren } from '../core/register.ts'; -import { buildOptions } from '../core/utils.ts'; + +import { buildOptions } from '../core/props.ts'; export class LeafletFeatureGroup extends HTMLElement { #obj?: FeatureGroup; diff --git a/src/components/leaflet-geojson.ts b/src/components/leaflet-geojson.ts index 78e8898..087e793 100644 --- a/src/components/leaflet-geojson.ts +++ b/src/components/leaflet-geojson.ts @@ -1,7 +1,6 @@ import { GeoJSON, PathOptions, Layer } from 'leaflet'; -import { WithProps, defineProps, num, str, on } from '../core/props.ts'; +import { WithProps, defineProps, num, str, on, buildOptions } from '../core/props.ts'; import { registerChildren, unregisterChildren, getChildren } from '../core/register.ts'; -import { buildOptions } from '../core/utils.ts'; import type { GeoJsonObject } from 'geojson'; const PROPS = defineProps({ diff --git a/src/components/leaflet-image-overlay.ts b/src/components/leaflet-image-overlay.ts index 1762d5c..108169e 100644 --- a/src/components/leaflet-image-overlay.ts +++ b/src/components/leaflet-image-overlay.ts @@ -1,8 +1,8 @@ import { ImageOverlay, LatLngBounds, LatLngExpression } from 'leaflet'; import type { ImageOverlayOptions } from 'leaflet'; -import { WithProps, defineProps, num, str, on } from '../core/props.ts'; +import { WithProps, defineProps, num, str, on, buildOptions } from '../core/props.ts'; import { registerChildren, unregisterChildren } from '../core/register.ts'; -import { buildAttrMap, buildOptions, parseBoundsAttr, setLayerAttr } from '../core/utils.ts'; +import { buildAttrMap, parseBoundsAttr, setLayerAttr } from '../core/attributes.ts'; const PROPS = defineProps({ url: str(), diff --git a/src/components/leaflet-layer-group.ts b/src/components/leaflet-layer-group.ts index e95592c..181bc80 100644 --- a/src/components/leaflet-layer-group.ts +++ b/src/components/leaflet-layer-group.ts @@ -1,6 +1,7 @@ import { LayerGroup, Layer } from 'leaflet'; import { registerChildren, unregisterChildren, getChildren } from '../core/register.ts'; -import { buildOptions } from '../core/utils.ts'; + +import { buildOptions } from '../core/props.ts'; export class LeafletLayerGroup extends HTMLElement { #obj?: LayerGroup; diff --git a/src/components/leaflet-marker.ts b/src/components/leaflet-marker.ts index f462299..a468f96 100644 --- a/src/components/leaflet-marker.ts +++ b/src/components/leaflet-marker.ts @@ -1,7 +1,7 @@ import { Icon, Marker } from 'leaflet'; -import { WithProps, defineProps, num, str, on } from '../core/props.ts'; +import { WithProps, defineProps, num, str, on, buildOptions } from '../core/props.ts'; import { LeafletIconChangedEvent, registerChildren, unregisterChildren } from '../core/register.ts'; -import { buildAttrMap, buildOptions, numAttr, setLayerAttr } from '../core/utils.ts'; +import { buildAttrMap, numAttr, setLayerAttr } from '../core/attributes.ts'; const PROPS = defineProps({ lat: num(), diff --git a/src/components/leaflet-polygon.ts b/src/components/leaflet-polygon.ts index a4e9e2a..52b2c77 100644 --- a/src/components/leaflet-polygon.ts +++ b/src/components/leaflet-polygon.ts @@ -1,7 +1,7 @@ import { Polygon } from 'leaflet'; import { registerChildren, unregisterChildren } from '../core/register.ts'; -import { WithProps, defineProps, num, str, on } from '../core/props.ts'; -import { buildOptions, isPathStyleAttr, updatePathStyle } from '../core/utils.ts'; +import { WithProps, defineProps, num, str, on, buildOptions } from '../core/props.ts'; +import { isPathStyleAttr, updatePathStyle } from '../core/attributes.ts'; import type { LeafletLine } from './leaflet-line.ts'; const PROPS = defineProps({ diff --git a/src/components/leaflet-polyline.ts b/src/components/leaflet-polyline.ts index 433bee7..09a1fa3 100644 --- a/src/components/leaflet-polyline.ts +++ b/src/components/leaflet-polyline.ts @@ -1,7 +1,7 @@ import { Polyline } from 'leaflet'; -import { WithProps, defineProps, num, str, on } from '../core/props.ts'; +import { WithProps, defineProps, num, str, on, buildOptions } from '../core/props.ts'; import { registerChildren, unregisterChildren } from '../core/register.ts'; -import { buildOptions, isPathStyleAttr, updatePathStyle } from '../core/utils.ts'; +import { isPathStyleAttr, updatePathStyle } from '../core/attributes.ts'; import type { LeafletLine } from './leaflet-line.ts'; const PROPS = defineProps({ diff --git a/src/components/leaflet-popup.ts b/src/components/leaflet-popup.ts index 6688d63..c676d06 100644 --- a/src/components/leaflet-popup.ts +++ b/src/components/leaflet-popup.ts @@ -1,6 +1,7 @@ import { Popup } from 'leaflet'; -import { WithProps, defineProps, num, on } from '../core/props.ts'; -import { buildOptions, numAttr, registerWithParent } from '../core/utils.ts'; +import { WithProps, defineProps, num, on, buildOptions } from '../core/props.ts'; +import { numAttr } from '../core/attributes.ts'; +import { registerWithParent } from '../core/register.ts'; const PROPS = defineProps({ lat: num(), diff --git a/src/components/leaflet-rectangle.ts b/src/components/leaflet-rectangle.ts index 306b6f5..dd02bd4 100644 --- a/src/components/leaflet-rectangle.ts +++ b/src/components/leaflet-rectangle.ts @@ -1,7 +1,7 @@ import { Rectangle } from 'leaflet'; -import { WithProps, defineProps, num, str, on } from '../core/props.ts'; +import { WithProps, defineProps, num, str, on, buildOptions } from '../core/props.ts'; import { registerChildren, unregisterChildren } from '../core/register.ts'; -import { buildOptions, isPathStyleAttr, parseBoundsAttr, updatePathStyle } from '../core/utils.ts'; +import { isPathStyleAttr, parseBoundsAttr, updatePathStyle } from '../core/attributes.ts'; const PROPS = defineProps({ bounds: str(), diff --git a/src/components/leaflet-svg-overlay.ts b/src/components/leaflet-svg-overlay.ts index f398b30..d50b8b3 100644 --- a/src/components/leaflet-svg-overlay.ts +++ b/src/components/leaflet-svg-overlay.ts @@ -1,8 +1,8 @@ import { SVGOverlay, LatLngBounds, LatLngExpression } from 'leaflet'; import type { ImageOverlayOptions } from 'leaflet'; -import { WithProps, defineProps, num, str, on } from '../core/props.ts'; +import { WithProps, defineProps, num, str, on, buildOptions } from '../core/props.ts'; import { registerChildren, unregisterChildren } from '../core/register.ts'; -import { buildAttrMap, buildOptions, parseBoundsAttr, setLayerAttr } from '../core/utils.ts'; +import { buildAttrMap, parseBoundsAttr, setLayerAttr } from '../core/attributes.ts'; const PROPS = defineProps({ bounds: str(), diff --git a/src/components/leaflet-tile-layer-wms.ts b/src/components/leaflet-tile-layer-wms.ts index 95a7db6..d413bc6 100644 --- a/src/components/leaflet-tile-layer-wms.ts +++ b/src/components/leaflet-tile-layer-wms.ts @@ -1,7 +1,7 @@ import { TileLayer } from 'leaflet'; -import { WithProps, defineProps, str, on } from '../core/props.ts'; +import { WithProps, defineProps, str, on, buildOptions } from '../core/props.ts'; import { registerChildren, unregisterChildren } from '../core/register.ts'; -import { buildAttrMap, buildOptions, parseAttributeValue, setLayerAttr } from '../core/utils.ts'; +import { buildAttrMap, parseAttributeValue, setLayerAttr } from '../core/attributes.ts'; const PROPS = defineProps({ url: str(), diff --git a/src/components/leaflet-tile-layer.ts b/src/components/leaflet-tile-layer.ts index c56207c..e726659 100644 --- a/src/components/leaflet-tile-layer.ts +++ b/src/components/leaflet-tile-layer.ts @@ -1,7 +1,7 @@ import { TileLayer } from 'leaflet'; import { registerChildren, unregisterChildren } from '../core/register.ts'; -import { WithProps, defineProps, num, str } from '../core/props.ts'; -import { buildAttrMap, buildOptions, setLayerAttr } from '../core/utils.ts'; +import { WithProps, defineProps, num, str, buildOptions } from '../core/props.ts'; +import { buildAttrMap, setLayerAttr } from '../core/attributes.ts'; const PROPS = defineProps({ url: str(), diff --git a/src/components/leaflet-tooltip.ts b/src/components/leaflet-tooltip.ts index 9962ea4..83a66fd 100644 --- a/src/components/leaflet-tooltip.ts +++ b/src/components/leaflet-tooltip.ts @@ -1,7 +1,8 @@ import { Tooltip } from 'leaflet'; import type { TooltipOptions } from 'leaflet'; -import { WithProps, defineProps, num, str, on } from '../core/props.ts'; -import { buildOptions, numAttr, registerWithParent } from '../core/utils.ts'; +import { WithProps, defineProps, num, str, on, buildOptions } from '../core/props.ts'; +import { numAttr } from '../core/attributes.ts'; +import { registerWithParent } from '../core/register.ts'; const PROPS = defineProps({ lat: num(), diff --git a/src/components/leaflet-video-overlay.ts b/src/components/leaflet-video-overlay.ts index 8422de8..e6fc1d3 100644 --- a/src/components/leaflet-video-overlay.ts +++ b/src/components/leaflet-video-overlay.ts @@ -1,8 +1,8 @@ import { VideoOverlay, LatLngBounds, LatLngExpression } from 'leaflet'; import type { VideoOverlayOptions } from 'leaflet'; -import { WithProps, defineProps, num, str, on } from '../core/props.ts'; +import { WithProps, defineProps, num, str, on, buildOptions } from '../core/props.ts'; import { registerChildren, unregisterChildren } from '../core/register.ts'; -import { buildAttrMap, buildOptions, parseBoundsAttr, setLayerAttr } from '../core/utils.ts'; +import { buildAttrMap, parseBoundsAttr, setLayerAttr } from '../core/attributes.ts'; const PROPS = defineProps({ url: str(), diff --git a/src/core/utils.ts b/src/core/attributes.ts similarity index 61% rename from src/core/utils.ts rename to src/core/attributes.ts index 04be03a..146c1cc 100644 --- a/src/core/utils.ts +++ b/src/core/attributes.ts @@ -1,6 +1,6 @@ -import { Path } from 'leaflet'; -import type { PropDef, PropTypesFromTable } from './props.ts'; import type { LatLngBoundsExpression } from 'leaflet'; +import { Path } from 'leaflet'; +import type { PropDef } from './props.ts'; // Reads a numeric attribute from an element, falling back to the default // value declared in the PROPS table. Handles the common pattern of @@ -72,57 +72,6 @@ export function parseAttributeValue(value: string | null): unknown { } } -// Builds the initial Leaflet options object from the PROPS table and the -// element's current attributes at connection time. Props listed in -// `exclude` are skipped (they're passed separately to Leaflet -// constructors, like coordinates or URLs). Null attributes use the -// default from PROPS if one exists (skipping empty-string defaults to -// avoid Leaflet rejecting them). -// -// The return type is derived from the PROPS table: each prop name maps -// to its kind's value type (number for `num`, boolean for `bool-on`/`bool-off`, -// string for `str`). The `const` type parameter makes literal exclude arrays -// narrow correctly, so excluded keys are stripped from the return type. -export function buildOptions< - TProps extends Record, - const TExclude extends readonly string[] = [], ->( - el: HTMLElement, - props: TProps, - exclude: TExclude = [] as unknown as TExclude, -): Omit, TExclude[number]> { - const opts = {} as Record; - for (const [propName, spec] of Object.entries(props)) { - if (exclude.includes(propName)) continue; - const val = el.getAttribute(spec.attr); - if (val === null) { - if ('default' in spec && spec.default !== '') opts[propName] = spec.default; - continue; - } - if (spec.kind === 'num') opts[propName] = +val; - else if (spec.kind === 'bool-on') opts[propName] = true; - else if (spec.kind === 'bool-off') opts[propName] = false; - else opts[propName] = val; - } - return opts as Omit, TExclude[number]>; -} - -// Dispatches a custom `leaflet-register` event upward through the DOM -// tree, carrying a Leaflet object and its host element. Parent components -// (map, circles, groups, etc.) intercept this event and add the layer, -// bind the popup, or bind the tooltip. This is the core wiring mechanism -// that replaces the parent-child relationship that Leaflet normally -// manages via imperative code. -export function registerWithParent(el: HTMLElement, obj: unknown) { - el.dispatchEvent( - new CustomEvent('leaflet-register', { - detail: { leafletObject: obj, element: el }, - bubbles: true, - composed: true, - }), - ); -} - const PATH_STYLE_ATTRS = new Set([ 'color', 'weight', diff --git a/src/core/props.ts b/src/core/props.ts index 982282e..5e9950c 100644 --- a/src/core/props.ts +++ b/src/core/props.ts @@ -146,3 +146,38 @@ function definePropAccessors(proto: object, props: Record) { }); } } + +// Builds the initial Leaflet options object from the PROPS table and the +// element's current attributes at connection time. Props listed in +// `exclude` are skipped (they're passed separately to Leaflet +// constructors, like coordinates or URLs). Null attributes use the +// default from PROPS if one exists (skipping empty-string defaults to +// avoid Leaflet rejecting them). +// +// The return type is derived from the PROPS table: each prop name maps +// to its kind's value type (number for `num`, boolean for `bool-on`/`bool-off`, +// string for `str`). The `const` type parameter makes literal exclude arrays +// narrow correctly, so excluded keys are stripped from the return type. +export function buildOptions< + TProps extends Record, + const TExclude extends readonly string[] = [], +>( + el: HTMLElement, + props: TProps, + exclude: TExclude = [] as unknown as TExclude, +): Omit, TExclude[number]> { + const opts = {} as Record; + for (const [propName, spec] of Object.entries(props)) { + if (exclude.includes(propName)) continue; + const val = el.getAttribute(spec.attr); + if (val === null) { + if ('default' in spec && spec.default !== '') opts[propName] = spec.default; + continue; + } + if (spec.kind === 'num') opts[propName] = +val; + else if (spec.kind === 'bool-on') opts[propName] = true; + else if (spec.kind === 'bool-off') opts[propName] = false; + else opts[propName] = val; + } + return opts as Omit, TExclude[number]>; +} \ No newline at end of file diff --git a/src/core/register.ts b/src/core/register.ts index 846e6a2..e25848f 100644 --- a/src/core/register.ts +++ b/src/core/register.ts @@ -1,5 +1,4 @@ import { DivIcon, Icon, Layer, LayerGroup, Popup, Tooltip } from 'leaflet'; -import { registerWithParent } from './utils.ts'; // Custom event type for the bubbling registration protocol. Carries the // Leaflet object and the originating element so the nearest parent can @@ -66,6 +65,22 @@ function createChildRegisterHandler(layer: Layer, children: Map>(); const handlerMap = new WeakMap void>(); +// Dispatches a custom `leaflet-register` event upward through the DOM +// tree, carrying a Leaflet object and its host element. Parent components +// (map, circles, groups, etc.) intercept this event and add the layer, +// bind the popup, or bind the tooltip. This is the core wiring mechanism +// that replaces the parent-child relationship that Leaflet normally +// manages via imperative code. +export function registerWithParent(el: HTMLElement, obj: unknown) { + el.dispatchEvent( + new CustomEvent('leaflet-register', { + detail: { leafletObject: obj, element: el }, + bubbles: true, + composed: true, + }), + ); +} + // Called during connectedCallback: creates the child tracker and event // handler, wires up the listener, and registers this element with its // own parent (so nested structures like polygon→line→point work). diff --git a/src/index.ts b/src/index.ts index d2f6b77..25a48dc 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,4 @@ -export * from './core/utils.ts'; +export * from './core/attributes.ts'; export * from './core/register.ts'; export * from './core/props.ts'; export { LeafletMap } from './components/leaflet-map.ts';