HookName and hook handler types
The hook slot names and handler types, from a subpath that loads no React code and registers no default handlers.
import { HookName, HookHandler, HookHandlers, HookDefinition } from '@salla.sa/twilight-theme-engine/types/hooks';In plain words
Slot names such as header:start, and the types of the functions you place in slots, belong to the engine's hook system. This import path gives you only those: the HookName list and three types, without the hooks, components and default slot content that @salla.sa/twilight-theme-engine/hooks brings along.
Use it in a file that only needs the names, such as a list of the slots your theme fills. Each name is explained on the HookName page.
Signature
enum HookName {
BODY_START = 'body:start', BODY_END = 'body:end', BODY_INNER = 'body:inner',
HEAD_START = 'head:start', HEAD_END = 'head:end', HEAD_INNER = 'head:inner',
HEADER_START = 'header:start', HEADER_END = 'header:end',
FOOTER_START = 'footer:start', FOOTER_END = 'footer:end',
PRODUCT_FORM_START = 'product:single.form.start',
CART_SUMMARY_START = 'cart:summary.start',
// …26 members in all
}
type HookHandler<T = Record<string, unknown>> = (context: T) => ReactNode;
type HookHandlers = Record<
string,
HookHandler | Array<{ priority?: number; handler: HookHandler }>
>;
interface HookDefinition {
id: number;
handler: HookHandler;
priority: number;
}Example
// app/hooks/slots.ts: the slots this theme fills, importable from any file.
import { HookName } from '@salla.sa/twilight-theme-engine/types/hooks';
export const PROMO_SLOTS = {
top: HookName.HEADER_START,
bottom: HookName.FOOTER_START,
cart: HookName.CART_SUMMARY_START,
} satisfies Record<string, HookName>;
export type PromoSlot = keyof typeof PROMO_SLOTS;
// app/hooks/promo.tsx
import { hookRegistry } from '@salla.sa/twilight-theme-engine/hooks/HookRegistry';
import type { HookHandler } from '@salla.sa/twilight-theme-engine/types/hooks';
import { PROMO_SLOTS, type PromoSlot } from './slots';
const promo: HookHandler = () => <p className="promo">Free delivery over 200 SAR</p>;
export function registerPromo(slot: PromoSlot) {
hookRegistry.register(PROMO_SLOTS[slot], promo);
}
How it behaves
At runtime this subpath is the
HookNameenum alone, in a small shared chunk; the three types are erased.@salla.sa/twilight-theme-engine/hooks, by contrast, loads every engine hook and runsregisterDefaultHooksthe first time it is imported.It is the same enum object that the package root,
/typesand/hooksexport, so values from any of them compare equal and type-check together.HookDefinitionis whathookRegistry.getHandlers(name)returns, highest priority first;idis a registry-wide counter thatHookSlotuses as the React key.The handler types, with their traps, are explained on HookHandler, HookHandlers, HookDefinition.
Gotchas
HookNameis a value, not only a type.import type { HookName }compiles, butHookName.BODY_ENDthen fails with TS1361, "cannot be used as a value because it was imported using 'import type'". Import it withouttype.A name from this list shows content only where a component renders a
HookSlotfor it. No engine component rendersBODY_INNER,HEAD_INNER, the fourSEARCH_*or the threeHOMEPAGE_*names, so handlers registered there appear nowhere until your theme adds the slot.
Related
The predefined slot names as a TypeScript enum, so a typo fails to compile instead of silently filling a slot nobody renders.
HookHandler, HookHandlers, HookDefinitionTypes for a slot handler function, the object defineHooks accepts, and a handler as the registry stores it.
hookRegistryThe one shared list of slot handlers: register content under a slot name, read or clear it, or register many at once with defineHooks.
HookSlotA named empty place in the page that renders every handler registered under its name, plus a spot where Salla apps inject content.