StringTune/Docs

Custom Modules

First Custom Module

Minimal path from extending StringModule to registering and consuming your own project module.

First Custom Module

The smallest useful custom module is usually an element module with one htmlKey, one mapped attribute, and one DOM output.

Minimal example

TypeScript
import { StringContext, StringModule, StringObject } from '@fiddle-digital/string-tune';

export class StringOutlineOffset extends StringModule {
  constructor(context: StringContext) {
    super(context);
    this.htmlKey = 'outline-offset';

    this.attributesToMap = [
      ...this.attributesToMap,
      { key: 'outline-offset', type: 'dimension', fallback: '8px' },
    ];
  }

  override onObjectConnected(object: StringObject): void {
    const offset = object.getProperty<number>('outline-offset');

    this.applyToElementAndConnects(object, (el) => {
      el.style.outline = '1px solid currentColor';
      el.style.outlineOffset = `${offset}px`;
    });
  }
}
TypeScript
import StringTune from '@fiddle-digital/string-tune';
import { StringOutlineOffset } from './modules/StringOutlineOffset';

const stringTune = StringTune.getInstance();

stringTune.use(StringOutlineOffset);
stringTune.start(60);
HTML
<button string="outline-offset" string-outline-offset="14px">
  Hover target
</button>

What each part does

  • extends StringModule opts your class into the module runtime.
  • htmlKey = 'outline-offset' means the module can connect to elements whose string list contains outline-offset.
  • attributesToMap tells the base class to read string-outline-offset and parse it as a dimension.
  • onObjectConnected(...) is the first object-specific hook where the element and parsed properties are ready.
  • applyToElementAndConnects(...) writes to the main element and any string-copy-from mirrors.

The important registration rule

stringTune.use(...) expects a class constructor, not an already-created instance.

This is correct:

TypeScript
stringTune.use(StringOutlineOffset);

This is not:

TypeScript
stringTune.use(new StringOutlineOffset(...));

Where settings come from

When the runtime instantiates the module, it merges:

  1. global defaults from stringTune.setupSettings(...)
  2. per-registration overrides from stringTune.use(Module, settings)

So this is valid:

TypeScript
stringTune.use(StringOutlineOffset, {
  'outline-offset': '12px',
});

The mapped attribute still wins when the element provides its own value.

When to stop at this level

This pattern is enough if your module only needs to:

  • read attributes once
  • apply static classes or styles
  • attach object-local listeners such as enter and leave

When you need scroll, cursor, resize, events, or batched writes, move on to the next pages instead of improvising from this example.