Options hooks
option<Name>Changed(change: OptionChange): OptionChangedReturnA declared method named after an option makes that option a live effect. A component without the convention pays no setup cost and reads its options directly.
Usage
import { Base } from '@studiometa/js-toolkit';
function connect(url) {
return { dispose() {} };
}
class Feed extends Base {
static config = {
name: 'Feed',
options: { source: String },
};
optionSourceChanged({ value, previousValue, initial }) {
const connection = connect(value);
// The cleanup for *this* value.
return () => connection.dispose();
}
}The method name is the option name in pascal case: dragThreshold is optionDragThresholdChanged.
The payload
interface OptionChange<T = unknown> {
name: string;
value: T;
previousValue: T | undefined;
rawValue: string | null;
previousRawValue: string | null;
initial: boolean;
}| Field | Meaning |
|---|---|
name | the option name |
value | the parsed value now |
previousValue | the parsed value before, undefined on the first run |
rawValue | the raw attribute string, null when absent |
previousRawValue | the raw string before, null when it was absent |
initial | true on the first run of a mount cycle |
import { Base, type OptionChange } from '@studiometa/js-toolkit';
class Feed extends Base {
static config = { name: 'Feed', options: { source: String } };
optionSourceChanged({ value, previousValue, initial }: OptionChange<string>) {
console.log(value, previousValue, initial);
}
}The return value
type OptionChangedReturn = void | (() => void);Return a function to release what this value acquired. The previous cleanup runs before an update, and every active cleanup runs on $unmount().
When it runs
- Before
mounted(), on each mount cycle, withinitial: true. - On an attribute change, once the batch is processed.
- On a breakpoint crossing that changes the resolved raw value.
- Removal of the attribute applies the declared default, which is a change like any other.
- A new mount starts each effect again with
initial: true.
Coalescing
Several writes to one attribute in one batch give one change, from the first old raw value to the final DOM value. A write that ends where it started is not a change.
The comparison uses raw strings, so a breakpoint crossing and an attribute write are the same kind of event. A crossing to the same resolved value announces nothing, and a write to data-option-columns:s while the viewport is at l announces nothing.
What it costs
A matchMedia subscription opens only for a component that declares one of these hooks. $unmount() releases it. A page that only reads options holds no listener at all.
Not for arbitrary attributes
This hook is for declared options. For an attribute the framework does not read, use watchAttributes(), which shares the same coalescing rule and the same batch.