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

HookHandler, HookHandlers, HookDefinition

typeAdvanced

Types for a slot handler function, the object defineHooks accepts, and a handler as the registry stores it.

import { HookHandler, HookHandlers, HookDefinition } from '@salla.sa/twilight-theme-engine/hooks';

In plain words

Type names for the hook system, so your editor can check your handlers. A HookHandler is "a function that receives the slot's context object and returns something React can render, or null". HookHandlers is the object you pass to defineHooks, and HookDefinition is one entry as hookRegistry.getHandlers returns it.

Types disappear when the theme is built: they only help while you write code.

Signature

type HookHandler<T = Record<string, unknown>> = (context: T) => ReactNode;

type HookHandlers = Record<
  string,
  HookHandler | Array<{ priority?: number; handler: HookHandler }>
>;

interface HookDefinition {
  id: number;         // registry-wide counter, the React key in HookSlot
  handler: HookHandler;
  priority: number;
}

Example

app/hooks/cart.tsx
import type { HookContext, HookDefinition, HookHandler, HookHandlers } from '@salla.sa/twilight-theme-engine/hooks';
import { defineHooks, hookRegistry } from '@salla.sa/twilight-theme-engine/hooks/HookRegistry';

const freeShipping: HookHandler<HookContext> = ({ twilight }) =>
  twilight.locale.startsWith('ar') ? <p>شحن مجاني</p> : <p>Free shipping over 200 SAR</p>;

const cartHooks: HookHandlers = {
  'cart:summary.end': freeShipping as HookHandler,
  'cart:end': [{ handler: () => <hr />, priority: 10 }],
};

defineHooks(cartHooks);

export const summaryHandlers: HookDefinition[] = hookRegistry.getHandlers('cart:summary.end');

How it behaves

  • The default T is Record<string, unknown>, so twilight is unknown inside an unannotated handler. Annotate the parameter as HookContext (or an interface extending it) to get types.

  • HookHandlers values are typed with the default T, which is why a handler typed with HookContext needs a cast inside a HookHandlers object. hookRegistry.register is generic and needs none.

  • The same three names are exported from @salla.sa/twilight-theme-engine (the package root); HookHandler is also exported from /types and /types/hooks.

  • getHandlers returns the registry's own array, sorted highest priority first. Copy it before changing it.

Gotchas

  • A handler may return undefined (it is a valid ReactNode), and it renders nothing, the same as null.

Related

Source and docs