You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
leaflet-components/src/core/with-props.ts

31 lines
1.2 KiB
TypeScript

import type { PropDef, PropTypesFromTable } from './props.ts';
import { definePropAccessors } from './utils.ts';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
type Ctor<T = object> = new (...args: any[]) => T;
// Mixin factory that turns a PROPS table into reactive property
// accessors + observedAttributes in one shot. Every component that
// follows the PROPS-table pattern uses this instead of manually
// defining a static initialization block, getters/setters, and an
// observedAttributes getter.
//
// 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>>(
Base: TBase,
props: TProps,
): TBase & Ctor<HTMLElement & PropTypesFromTable<TProps>> {
class WithProps extends Base {
static {
definePropAccessors(WithProps.prototype, props);
}
static get observedAttributes(): string[] {
return Object.values(props).map((s) => s.attr);
}
}
return WithProps as TBase & Ctor<HTMLElement & PropTypesFromTable<TProps>>;
}