Skip to content

Components ​

A component is a class extending the Base class. Every component must have a static config property with at least a name.

Defining a component ​

js
import { Base } from '@studiometa/js-toolkit';

class Counter extends Base {
  static config = {
    name: 'Counter',
  };

  count = 0;

  mounted() {
    this.$el.textContent = `Count: ${this.count}`;
  }
}

To connect a component to the DOM, add a matching data-component attribute:

html
<div data-component="Counter"></div>

Registering components ​

Use registerComponent to automatically find and mount all matching elements:

js
import { registerComponent } from '@studiometa/js-toolkit';

registerComponent(Counter);

This scans the DOM for [data-component="Counter"] elements and mounts an instance on each one. It also watches for newly added elements using a MutationObserver.

Parent–child components ​

Components can declare child components via the components config. The parent will automatically discover and mount children found inside its root element.

js
import { Base } from '@studiometa/js-toolkit';

class Child extends Base {
  static config = {
    name: 'Child',
  };

  mounted() {
    console.log('Child mounted');
  }
}

class Parent extends Base {
  static config = {
    name: 'Parent',
    components: {
      Child,
    },
  };

  mounted() {
    console.log('Parent mounted');
  }
}
html
<div data-component="Parent">
  <div data-component="Child"></div>
</div>

Children are resolved by matching [data-component="<KEY>"] elements inside the parent's root element. Children mount before the parent — so "Child mounted" logs before "Parent mounted".

Lazy imports ​

Components can be imported lazily with dynamic imports to split your bundle:

js
import { Base } from '@studiometa/js-toolkit';

class App extends Base {
  static config = {
    name: 'App',
    components: {
      HeavyWidget: () => import('./components/HeavyWidget.js'),
    },
  };
}

The import is only triggered if a matching element exists in the DOM. If no [data-component="HeavyWidget"] is found, the chunk is never fetched.

Going further

See Lazy imports for advanced lazy import strategies like importWhenVisible, importOnInteraction, and more.

Updating the DOM ​

When you dynamically add or remove HTML, call this.$update() so the component re-evaluates its children and refs:

js
class List extends Base {
  static config = {
    name: 'List',
    refs: ['items[]'],
  };

  addItem() {
    this.$el.insertAdjacentHTML(
      'beforeend',
      '<div data-ref="items[]">New</div>',
    );
    this.$update();
  }
}

See also: Configuration, data-component, Instance methods, and Instantiation.

MIT Licensed