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
main
Buddy 3 months ago
parent e2382f1117
commit bdf5bd56f3

@ -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(),

@ -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(),

@ -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'),

@ -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'),

@ -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'),

@ -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'),

@ -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;

@ -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({

@ -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(),

@ -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;

@ -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(),

@ -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({

@ -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({

@ -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(),

@ -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(),

@ -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(),

@ -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(),

@ -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(),

@ -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(),

@ -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(),

@ -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<string, PropDef>,
const TExclude extends readonly string[] = [],
>(
el: HTMLElement,
props: TProps,
exclude: TExclude = [] as unknown as TExclude,
): Omit<PropTypesFromTable<TProps>, TExclude[number]> {
const opts = {} as Record<string, unknown>;
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<PropTypesFromTable<TProps>, 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',

@ -146,3 +146,38 @@ function definePropAccessors(proto: object, props: Record<string, PropDef>) {
});
}
}
// 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<string, PropDef>,
const TExclude extends readonly string[] = [],
>(
el: HTMLElement,
props: TProps,
exclude: TExclude = [] as unknown as TExclude,
): Omit<PropTypesFromTable<TProps>, TExclude[number]> {
const opts = {} as Record<string, unknown>;
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<PropTypesFromTable<TProps>, TExclude[number]>;
}

@ -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<HTMLElement, Chi
const childrenMap = new WeakMap<HTMLElement, Map<HTMLElement, ChildEntry>>();
const handlerMap = new WeakMap<HTMLElement, (e: LeafletRegisterEvent) => 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).

@ -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';

Loading…
Cancel
Save