Custom Modules
Module Contract
What StringModule gives you by default: settings, htmlKey matching, attribute mapping, connection flow, and output channels.
Module Contract
StringModule is the authoring base class. It already gives you a connection model, default attribute mapping, object collections, helper methods for mirrored elements, and a full lifecycle surface.
What your module usually sets
Most custom modules define these three things first:
export class StringMyModule extends StringModule {
constructor(context: StringContext) {
super(context);
this.htmlKey = 'my-module';
this.attributesToMap = [
...this.attributesToMap,
{ key: 'my-value', type: 'number', fallback: 0 },
];
}
}
htmlKeycontrols default object matching.attributesToMapdeclares additional per-object properties to parse.cssPropertiesis optional and only needed when the module wantsCSS.registerProperty(...).
Base attributes you already inherit
StringModule starts with a shared mapping for:
activefixedoutside-containerrepeatself-disableabskeyoffset-topoffset-bottominview-topinview-bottomstartendsizehalf-widthhalf-heightenter-elenter-vpexit-elexit-vp
That means custom modules automatically get the same geometry-oriented authoring surface as many built-ins.
Attribute mapping
Each entry in attributesToMap has this shape:
{
key: 'my-value',
type: 'number',
fallback: 10,
transform: (value) => value * 2,
}
How the base class resolves values:
- It checks the raw
attributesrecord passed intoinitializeObject(...). - It looks for
key,string-key, anddata-string-key. - It falls back to module settings.
- It falls back to the mapping fallback value or fallback function.
- It parses by
type. - It applies
transform(...)if present. - It stores the final value on the object with
object.setProperty(key, parsed).
Supported parse types
The current base parser supports:
numberbooleanjsontupleeasingcolordimensionbreakpoint-dimension- enum objects like
{ type: 'enum', values: [...] }
If you need something else, parse it in transform(...) or override initializeObject(...).
Connection and storage
StringModule manages two object collections:
objectsOnPageevery connected object currently present in the DOMobjectsobjects that are currently entered or active in the module scope
For scroll-oriented modules, objects is usually the hot path collection used on frame or mutate hooks.
Output channels
A custom module normally writes through one or more of these channels:
- CSS variables
- inline styles
- classes
- helper DOM nodes
- events
The base class gives you helpers for mirrored output:
applyToElementAndConnects(...)applyVarToElement(...)applyPropToElement(...)applyVarToConnects(...)applyPropToConnects(...)
Use these instead of hand-duplicating writes to string-copy-from mirrors.
Custom matching
If htmlKey is not enough, override canConnect(...).
Example:
override canConnect(object: StringObject): boolean {
return object.keys.includes('progress') && object.keys.includes('rotate-progress');
}
That is the correct place for connection rules. Do not bury connect logic inside onObjectConnected(...).
Cleanup contract
If your module writes persistent styles or subscribes to object-local listeners, clean them up in onObjectDisconnected(...).
That usually means:
- removing inline styles your module owns
- removing CSS variables your module owns
- disconnecting observers created by that module
- unsubscribing from
object.events
Do not remove styles or attributes that belong to other modules.