Skip to content
Twilight React Playground
ثيم رائدaren

ComponentRegistry

classAdvancedlive demo

The class behind registry. A new instance is a private registry that engine components never read, useful in tests and tooling.

import { ComponentRegistry } from '@salla.sa/twilight-theme-engine';

In plain words

registry is one object made from this class. new ComponentRegistry() gives you another one: separate, empty, with the same methods.

Nothing in the engine looks at your instance, which makes it good for tests and for experiments that must not change the storefront.

Signature

class ComponentRegistry {
  register<P>(name: string, component: ComponentType<P>): void;
  override<P>(name: string, component: ComponentType<P>): void;
  resolve<P>(name: string): ComponentType<P> | null;
  getOriginal<P>(name: string): ComponentType<P> | null;
  has(name: string): boolean;
  list(): string[];                       // insertion order
  listByPrefix(prefix: string): string[];
  remove(name: string): boolean;          // true if it existed
  clear(): void;
}

Try it live

A private ComponentRegistry, created with new. Its methods work the same, but the engine only ever reads the global registry.Try this: override twice in a row: getOriginal now returns Fancy, because each override keeps whatever was there before it.
Storefront canvas · en · LTR
sandbox.list()
[]
sandbox.resolve(name)
null
sandbox.getOriginal(name)
null
registry.has(name) (the global one)
false
Controls
What a theme writes
import { ComponentRegistry } from '@salla.sa/twilight-theme-engine';

// For tests or tooling. Engine components never look here.
const sandbox = new ComponentRegistry();

sandbox.register('playground:sandbox', Plain);
sandbox.override('playground:sandbox', Fancy);

sandbox.resolve('playground:sandbox'); // Fancy
sandbox.getOriginal('playground:sandbox'); // Plain
sandbox.list(); // ['playground:sandbox']

Example

tests/registry.test.tsx
import { ComponentRegistry } from '@salla.sa/twilight-theme-engine';

it('keeps the seed as the original', () => {
  const sandbox = new ComponentRegistry();
  const Seed = () => <span>seed</span>;
  const Mine = () => <span>mine</span>;

  sandbox.register('product:card', Seed);
  sandbox.override('product:card', Mine);

  expect(sandbox.resolve('product:card')).toBe(Mine);
  expect(sandbox.getOriginal('product:card')).toBe(Seed);
});

How it behaves

  • Entries live in a Map of { component, displayName, original } records (ComponentDefinition in /types); displayName is the registered name, not the component's own.

  • register on an existing name replaces the whole record, dropping its original; override chains the previous record as original.

Gotchas

  • Engine code (Component, useComponent, ProductCard, ProductGallery, the home page renderer) only ever reads the exported registry instance. Registering on your own instance changes nothing on the page.

Related

Source and docs