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.
31 lines
1.2 KiB
TypeScript
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>>;
|
|
}
|