Base class
Every component extends Base. It carries the element, the live views over its markup, the lifecycle, the event conventions and the scheduling handles — and nothing else. Base knows nothing about services, view transitions or storage.
import { Base } from '@studiometa/js-toolkit';
class Component extends Base {
static config = {
name: 'Component',
};
}Sections
- Configuration —
static configand how it merges - Lifecycle hooks —
mounted()andunmounted() - Options hooks —
option<Name>Changed() - Events hooks —
on<Event>,on<Ref><Event>,on<Child><Event>,onWindow<Event>,onDocument<Event> - Services hooks —
ticked(),scrolled(),resized()and the rest - Instance properties —
$el,$id,$refs,$options,$config,$isMounted - Instance methods —
$mount(),$emit(),$query(),$provide(),$read()and the rest - Instance events — what an instance dispatches
The constructor
new Base(el: HTMLElement)Do not call it. The registry is the only code that constructs an instance, and an instance built by hand is not in the element's instance map, so nothing finds it and nothing unmounts it.
A component's own constructor is a legitimate place for field initializers, and two registrations belong there because they are instance-scoped rather than unmount-scoped:
class Slider extends Base {
static config = { name: 'Slider', components: {} };
// Never released. Both die with the element.
api = this.$provide(Ctx, { goNext: () => {} });
items = this.$watchChildren('SliderItem');
}Fixed properties
$el, $id, $options and $refs are fixed properties of the instance, not fields it happens to hold. They are defined non-writable in the constructor, so an assignment throws in a module rather than replacing what every other part of the framework reads.
readonly states it for a reader with a build step; the property descriptor states it for everyone else. They stay enumerable, so an instance still reads as one.
The typed surface
Base takes an optional props type with four optional keys — $el, $refs, $options and $emits. See TypeScript.
import { Base } from '@studiometa/js-toolkit';
class Slider extends Base<{
$refs: { next: HTMLButtonElement };
$options: { speed: number };
$emits: { goto: { index: number }; stop: void };
}> {
static config = {
name: 'Slider',
refs: ['next'],
options: { speed: { type: Number, default: 1 } },
};
}