Renderer
The Renderer widget renders raw framework markup returned by a callback. Use it when you need to drop a small piece of bespoke UI inside a form — a heading, a summary block, a chart — without writing a full custom widget.
import { gui } from '@golemui/gui-shared';import { html } from 'lit';
const formDef = [ gui.displays.display( (api) => html`<h1> Client Name: ${api.$form?.details?.clientName || 'unknown'} </h1>`, ), gui.inputs.textInput('details.clientName', { label: 'Client Name', placeholder: 'e.g. Jane Doe', validator: { required: true, minLength: 2 }, }),];Type a name into the input below — the heading above it re-renders on every keystroke because the callback reads $form.details.clientName:
Programmatic-only
Section titled “Programmatic-only”The Renderer widget takes a function as its only argument. There’s no JSON equivalent — JSON cannot serialize functions.
Per-framework usage
Section titled “Per-framework usage”import { gui } from '@golemui/gui-shared';
const formDef = [ gui.displays.display( (params) => ( <div className="summary"> <h2>Booking summary</h2> <p>Customer: {params?.$form?.customer?.name}</p> </div> ), ),];Angular cannot render raw markup the way React/Vue/Lit can, so the callback returns { component, api } instead. The engine calls the outer callback on every form-data change, threads the live form API into api, and RendererComponent passes it as an Input to your standalone component:
import { Component, input } from '@angular/core';import { gui } from '@golemui/gui-shared';import type { WidgetPropertyFunctionParams } from '@golemui/core';
@Component({ standalone: true, selector: 'app-booking-summary', template: ` <div class="summary"> <h2>Booking summary</h2> <p>Customer: {{ api().$form?.customer?.name }}</p> </div> `,})class BookingSummary { api = input.required<WidgetPropertyFunctionParams<any>>();}
const formDef = [ gui.displays.display((api) => ({ component: BookingSummary, api })),];For richer cases, prefer a custom display widget with its own widget loader.
import { gui } from '@golemui/gui-shared';import { html } from 'lit';
const formDef = [ gui.displays.display( (params) => html` <div class="summary"> <h2>Booking summary</h2> <p>Customer: ${params?.$form?.customer?.name}</p> </div> `, ),];import { gui } from '@golemui/gui-shared';import { h } from 'vue';
const formDef = [ gui.displays.display((params) => h('div', { class: 'summary' }, [ h('h2', 'Booking summary'), h('p', `Customer: ${params?.$form?.customer?.name ?? ''}`), ]), ),];The render callback returns a Vue VNode (built with h()). For richer templates, prefer a custom display widget that uses a full SFC.
import { gui } from '@golemui/gui-shared';
const formDef = [ gui.displays.display((params) => { const root = document.createElement('div'); root.className = 'summary';
const title = document.createElement('h2'); title.textContent = 'Booking summary';
const customer = document.createElement('p'); customer.textContent = `Customer: ${params?.$form?.customer?.name ?? ''}`;
root.append(title, customer); return root; }),];The callback returns an HTMLElement built with plain DOM APIs — no template library needed. The engine re-invokes the callback on every form-data change, so build a fresh node each time. For richer templates, prefer a custom display widget.
Reactivity
Section titled “Reactivity”The callback receives a params object with $form (the live form data tree) and re-renders whenever any referenced path changes. Read what you need from $form and the widget will keep itself in sync.
See also
Section titled “See also”gui.displays— every display shortcut.- Extending GolemUI / Display Widget — for richer cases that need a full custom widget.