Skip to content

Item Renderers

Item renderers are framework-specific functions or components that the form engine invokes to render each item of a dropdown, list, or radiogroup. The engine forwards an ItemRenderContext<T> object that carries the raw item plus useful metadata (selected, disabled, focused, index).

Each framework adapts the same ItemRenderContext<T> to its idiomatic shape:

FrameworkTypeWhat the engine passes
ReactReactItemRenderer<T>A React.ComponentType<ItemRenderContext<T>> — the context fields arrive as props.
AngularAngularItemRenderer<T>A component class structurally matching AngularItemRenderContext<T> — one signal input() per context field.
LitLitItemRenderer<T>A (ctx: ItemRenderContext<T>) => TemplateResult — called as a function, not a custom element.
VueVueItemRenderer<T>A Component<Partial<ItemRenderContext<T>>> — the context fields arrive as props on the SFC.
Vanilla JS(ctx) => HTMLElementA plain function called with ItemRenderContext<T> that returns a DOM node — like Lit’s, but returning real DOM instead of a TemplateResult.

The shared context shape comes from @golemui/core:

export interface ItemRenderContext<T extends ItemRenderItemData> {
template: T;
value: string | number;
index: number;
selected?: boolean;
disabled?: boolean;
focused?: boolean;
}

template is the raw item from the widget’s items array. The other fields reflect the live state of the option in the rendered list.

import type { ReactItemRenderer } from '@golemui/react';
type Country = { id: string; flag: string; label: string };
export const CountryItemRenderer: ReactItemRenderer<Country> = ({
template,
index,
selected,
disabled,
focused,
}) => (
<div
className={`country-item ${selected ? 'country-item--selected' : ''} ${
disabled ? 'country-item--disabled' : ''
} ${focused ? 'country-item--focused' : ''} ${index % 2 ? 'country-item--odd' : ''}`}
>
<span className="country-item__flag">{template.flag}</span>
<span className="country-item__label">{template.label}</span>
</div>
);

Props are the full ItemRenderContext<T> — destructure whichever fields you need.

The widget references the renderer by name through its itemRenderer prop. Where the renderer map lives depends on the path:

In the Programmatic API the renderer map goes inside formConfig.itemRenderers:

import { gui } from '@golemui/gui-shared';
import { CountryItemRenderer } from './country-item-renderer';
const config = {
formDef: [
gui.inputs.dropdown('country', {
items: [
/* … */
],
itemRenderer: 'countryItemRenderer',
}),
],
formConfig: { itemRenderers: { countryItemRenderer: CountryItemRenderer } },
};
// <GuiForm config={config} />