Skip to main content

Extension API

widgemoRegistry is the supported extension surface for registering and resolving custom icons, field types, renderAs renderers, hooks, and modes.

Exports​

ExportKindPurpose
widgemoRegistryNamespace objectStable registration and lookup surface
advancedNamespace objectLower-level renderer components and hooks
TooltipComponentShared UI primitive for custom renderers
defaultRenderWidgemoIconFunctionStateless icon renderer safe for SSG/SSR
InteractionContextTypeCanonical payload for actions and gestures
InteractionKindTypeInteraction discriminant
InteractionScopeTypeShared interaction scope fields
IconRegistryEntryTypeIcon registry entry contract
FieldTypeRegistryEntryTypeField type registry entry contract
RenderAsRegistryEntryTyperenderAs registry entry contract
HookRegistryEntryTypeHook registry entry contract
ModeRegistryEntryTypeMode registry entry contract

widgemoRegistry namespace​

All stable registry methods are grouped on the widgemoRegistry named export.

import { widgemoRegistry } from '@widgemo/widgemo-core';

Register Methods​

MethodSignaturePurpose
registerWidgemoIcon(entry: IconRegistryEntry) => voidRegister a custom icon entry
registerWidgemoFieldType(entry: FieldTypeRegistryEntry) => voidRegister a custom field type renderer
registerWidgemoRenderAs(entry: RenderAsRegistryEntry) => voidRegister a custom renderAs renderer
registerWidgemoHook(entry: HookRegistryEntry) => voidRegister a named lifecycle hook
registerWidgemoMode(entry: ModeRegistryEntry) => voidRegister a custom content mode

Resolve and Execute Helpers​

Registry TypeHelpersNotes
IconsgetWidgemoIcon, renderWidgemoIconIcon lookup falls back to a default icon entry when a custom icon is not registered
Field typesgetWidgemoFieldType, renderWidgemoFieldUnknown field types fall back through core field rendering
renderAs renderersgetWidgemoRenderAs, renderWidgemoRenderAsrenderWidgemoRenderAs returns null when no renderer is registered
HooksgetWidgemoHook, executeWidgemoHookexecuteWidgemoHook returns undefined when hook is missing
ModesgetWidgemoMode, getModeComponent, getRegisteredModesgetModeComponent returns null when mode is missing

Registry Entry Shapes​

IconRegistryEntry​

FieldTypeDescription
namestringRegistry key
componentComponentType<{ className?, size?, color? }> | ((props) => ReactNode)Icon component or render function
defaultPropsRecord<string, unknown>Optional default props applied at render time

FieldTypeRegistryEntry​

FieldTypeDescription
namestringRegistry key
render(value, config, entity) => ReactNodeField-type render function
defaultConfigPartial<FieldConfig>Default field config merged by host/core usage
validate(value, config) => boolean | stringOptional validation hook

RenderAsRegistryEntry​

FieldTypeDescription
namestringRegistry key
render(value, options, entity) => ReactNodeVisual renderer override
defaultOptionsPartial<RenderAsOptions>Default options merged before render

HookRegistryEntry​

FieldTypeDescription
namestringHook key
hook(...args: unknown[]) => unknownExecuted by core or explicit executeWidgemoHook invocation

ModeRegistryEntry​

FieldTypeDescription
namestringRegistry key
componentComponentType<{ data, config?, actions?, gestures?, onInteractionEvent? }>Custom mode renderer
defaultConfigRecord<string, unknown>Default mode-level config

Lifecycle Hooks​

Lifecycle hooks are registry hooks resolved by name via widgemoRegistry.

Widgemo exposes two complementary extension surfaces: registry-based lifecycle hooks (this page) and config-based interaction handling via gestures and interactions.onEvent.

When to Use Which​

Use CasePreferWhy
Per-Widgemo interaction behavior (click, drag start, drop)Gestures (zones.content.gestures)Gestures are config-driven interaction handlers intended for app/business behavior
Global interaction fallback handlinginteractions.onEventReceives interaction contexts when no local gesture/action handler is provided
Runtime interception of render/mode/interaction lifecycle eventsLifecycle hooks (registerWidgemoHook)Hooks run at explicit core lifecycle trigger points

Practical recommendation:

  • For most integrators, use gestures for per-Widgemo interaction behavior.
  • Use lifecycle hooks when you need runtime interception behavior.
  • Lifecycle customization usually means overriding built-in lifecycle names.

All five lifecycle hook names are registered by default in core:

  • preRender
  • postRender
  • onItemClick
  • onModeChange
  • onDragDrop

Auto-Invoked Names vs Custom-Named Hooks​

  • Built-in lifecycle hook names are the only lifecycle hooks auto-fired by current core runtime.
  • Registering a new custom hook name alone does not create a new core lifecycle trigger.
  • A custom-named hook runs only where code explicitly calls executeWidgemoHook('<name>', ...).
  • Adding new automatic lifecycle trigger points requires core/runtime code changes.

Hook Contract Matrix​

HookWhere It RunsReceivesReturnsBuilt-In Default Registration
preRenderCalled by runtime before render in Widgemo, BoardMode, and CarouselModePositional args. Current runtime calls include ('Widgemo', { data, config, className, id }), ('BoardMode', config), and ('CarouselMode', config)Optional value. Built-in default returns payload passthrough (args[1])Yes
postRenderCalled after render composition for Widgemo root and each CarouselItemPositional args: (componentName, renderedElement)May return a transformed/wrapped element. Runtime falls back to original element when hook returns nothing/falsyYes
onItemClickEmitted from board card click and carousel item interactionsPositional args: (item, index, metadata)Return value ignoredYes
onModeChangeEmitted when resolved effective mode changes in content renderingSingle payload object with previousMode, nextMode, requestedMode, breakpoint, reasonReturn value ignoredYes
onDragDropEmitted from board drag/drop pathsSingle payload object with movement context: item, from, to, fromLocation, toLocationReturn value ignoredYes

preRender: Config Callback vs Registry Hook​

preRender exists in two distinct places:

  • Config callback: config.preRender in WidgemoConfig is called as () => void from Widgemo.
  • Registry hook: registerWidgemoHook({ name: 'preRender', ... }) is executed via executeWidgemoHook with positional runtime payloads.

They are separate mechanisms and should not be treated as the same API surface.

Runtime Trigger Notes​

  • onModeChange does not fire on initial mount; it fires only when the resolved effective mode changes.
  • onDragDrop is currently emitted from board drag/drop paths.
  • onItemClick is currently emitted from board and carousel interaction paths.

Minimal Usage Examples​

  1. Gesture use case: per-Widgemo click business logic
const config = {
zones: {
content: {
mode: 'table',
gestures: [
{
type: 'item-click',
onTrigger: (ctx) => {
auditLog(ctx.entity?.id);
},
},
],
item: { fields: [{ key: 'name' }], layout: { type: 'auto' } },
},
},
};
  1. Lifecycle use case: wrap rendered output
widgemoRegistry.registerWidgemoHook({
name: 'postRender',
hook: (componentName, element) => {
if (componentName !== 'Widgemo') return element;
return <div className="widget-shell">{element}</div>;
},
});
  1. Built-in override example: mode transition side effect
widgemoRegistry.registerWidgemoHook({
name: 'onModeChange',
hook: (payload) => {
analytics.track('widgemo.mode.changed', payload);
},
});
  1. Custom-named manual invocation example
import { executeWidgemoHook, widgemoRegistry } from '@widgemo/widgemo-core';

widgemoRegistry.registerWidgemoHook({
name: 'afterExport',
hook: (payload) => {
console.info('afterExport', payload);
},
});

// This runs only because application/extension code explicitly invokes it.
executeWidgemoHook('afterExport', { format: 'csv', rows: 120 });

Registration Collisions​

When a registration name already exists, core applies silent last-write-wins behavior.

  • Duplicate registration replaces the previous entry for the same name.
  • No warning, error, or rejection is performed by core.
  • This behavior applies uniformly to icon, field type, renderAs renderer, hook, and mode registrations.
  • Overriding built-in entries and third-party entries is supported by design.

Best Practice​

Use namespaced extension names (for example, acme.calendar, myteam.status-pill) to reduce accidental collisions across teams and dependencies.

Canonical Example​

import { widgemoRegistry } from '@widgemo/widgemo-core';

widgemoRegistry.registerWidgemoIcon({
name: 'sparkle',
component: ({ size = 16 }) => <span style={{ fontSize: size }}>✦</span>,
});

widgemoRegistry.registerWidgemoFieldType({
name: 'swatch',
render: (value) => (
<span
style={{
display: 'inline-block',
width: 14,
height: 14,
borderRadius: 3,
border: '1px solid #ddd',
backgroundColor: String(value),
}}
/>
),
defaultConfig: { type: 'swatch' },
});

widgemoRegistry.registerWidgemoRenderAs({
name: 'uppercase',
render: (value) => String(value).toUpperCase(),
});

widgemoRegistry.registerWidgemoHook({
name: 'preRender',
hook: (...args) => args[1],
});

widgemoRegistry.registerWidgemoMode({
name: 'simple-list',
component: ({ data = [] }) => (
<ul>
{data.map((row, index) => (
<li key={index}>{String(row.name ?? row.id ?? index)}</li>
))}
</ul>
),
});

const iconEntry = widgemoRegistry.getWidgemoIcon('sparkle');
const modeNames = widgemoRegistry.getRegisteredModes();
const preRenderHook = widgemoRegistry.getWidgemoHook('preRender');

void iconEntry;
void modeNames;
void preRenderHook;

Icon management​

MethodSignatureDescription
registerWidgemoIcon(entry: IconRegistryEntry) => voidRegister a custom icon.
getWidgemoIcon(name: string) => IconRegistryEntryLook up an icon by name. Falls back to a default icon entry when no custom icon exists.
renderWidgemoIcon(props: { name, size?, className?, color? }) => ReactNodeRender an icon via the registry.

Field type management​

MethodSignatureDescription
registerWidgemoFieldType(entry: FieldTypeRegistryEntry) => voidRegister a custom field type (e.g. type: 'swatch').
getWidgemoFieldType(name: string) => FieldTypeRegistryEntry | nullLook up a field type by name.
renderWidgemoField(value, config, entity) => ReactNodeRender a field value via the registry.

RenderAs renderer management​

MethodSignatureDescription
registerWidgemoRenderAs(entry: RenderAsRegistryEntry) => voidRegister a custom renderAs renderer.
getWidgemoRenderAs(name: string) => RenderAsRegistryEntry | nullLook up a renderer by name.
renderWidgemoRenderAs(value, renderAs, options, entity) => ReactNode | nullRender a value via a registered renderAs renderer. Returns null if missing.

Hook management​

MethodSignatureDescription
registerWidgemoHook(entry: HookRegistryEntry) => voidRegister a named lifecycle hook.
getWidgemoHook(name: string) => HookRegistryEntry | nullLook up a hook by name.
executeWidgemoHook(name: string, ...args) => unknown | undefinedExecute a hook by name. Returns undefined when missing.

Mode management​

MethodSignatureDescription
registerWidgemoMode(entry: ModeRegistryEntry) => voidRegister a custom content mode.
getWidgemoMode(name: string) => ModeRegistryEntry | nullLook up a mode by name.
getModeComponent(name: string) => ComponentType | nullGet the React component for a mode.
getRegisteredModes() => string[]List all registered mode names.

See the Register Methods and Canonical Example sections above for full usage examples.

advanced​

Lower-level renderer components and hooks exposed for host applications that need to compose custom layouts. These are internal surfaces — they may change between minor versions. Use the stable Widgemo component for production rendering.

import { advanced } from '@widgemo/widgemo-core';

const { ContainerRenderer, ItemRenderer, FieldRenderer, TableMode, usePagination } = advanced;
ExportKindDescription
ContainerRendererComponentFull Widgemo layout shell (zones, chrome).
ActionsRendererComponentAction bar renderer for zones and items.
ItemRendererComponentSingle entity card/row renderer.
FieldRendererComponentSingle field value renderer.
ModalRendererComponentModal/overlay renderer.
GridModeComponentGrid mode renderer.
TableModeComponentTable mode renderer.
CarouselModeComponentCarousel mode renderer.
BoardModeComponentBoard mode renderer.
ChartModeComponentChart mode renderer.
ConfigIconComponentDev-mode config toggle icon.
PaginationControlsComponentPagination UI component.
SearchBarComponentSearch/filter input component.
usePaginationHookPagination state hook.
useFilterHookFilter state hook.
applySearchFilterFunctionApply a text search filter to an entity array.
applyStaticFiltersFunctionApply StaticFilterRule[] to an entity array.

defaultRenderWidgemoIcon is part of the stable public API (not in advanced). It is a stateless icon renderer that does not touch the registry — safe for SSG/SSR. Import it directly: import { defaultRenderWidgemoIcon } from '@widgemo/widgemo-core'.

InteractionContext​

All action and gesture callbacks receive an InteractionContext payload. This is the type received by interactions.onEvent, gestures[].onTrigger, and actions[].onAction.

interface InteractionContext {
kind: InteractionKind; // what triggered the interaction
interactionId: string; // stable identifier
interactionLabel: string; // human-readable label
entity?: Entity; // entity in scope (item-level interactions)
data: Entity[]; // full data array in the render scope
zone: string; // zone where the interaction fired
nativeEvent?: React.MouseEvent | React.DragEvent;
from?: InteractionBoardLocation; // board drag source location
to?: InteractionBoardLocation; // board drag destination location
// reference-click only:
fieldKey?: string; // the field key that was clicked
fieldValue?: unknown; // raw FK/ID value from the entity
fieldLabel?: string; // resolved display label from options
relatedEntity?: string; // entity type declared on the field
}

InteractionKind values​

KindWhen it fires
'zone-action'An action in the header or footer zone was triggered.
'item-action'A per-item action was triggered. entity is set.
'item-click'An item was clicked (board card, carousel item, etc.). entity is set.
'item-drag-start'A board card drag was initiated. entity and from are set.
'item-drop'A board card was dropped onto a column. entity, from, and to are set.
'reference-click'A reference field link was clicked. entity, fieldKey, fieldValue, fieldLabel, and relatedEntity are set.

Board location fields​

from and to are only set on board drag/drop interactions (item-drag-start, item-drop). Each is an InteractionBoardLocation object.

FieldTypeDescription
columnIdstringBoard column identifier
swimlaneValuestringOptional swimlane value
indexnumberOptional index within the lane at interaction time

UI Primitives​

Two stable exports are available for use inside custom renderers and host applications:

  • Tooltip — shared tooltip component. Import: import { Tooltip } from '@widgemo/widgemo-core'. Props: TooltipProps (content, position, children).
  • defaultRenderWidgemoIcon — stateless icon renderer. Does not touch the registry. Safe to call during SSG/SSR. Import: import { defaultRenderWidgemoIcon } from '@widgemo/widgemo-core'.

See Also​