Skip to content

Creating a display widget

A display widget renders read-only content. It has no data binding, no validation, and no events — just props. The example we’ll walk through is productDescription — a product image alongside a markdown description.

import { gui } from '@golemui/gui-shared';
gui.displays.custom('productDescription', {
img: 'assets/product-image.png',
description: `### My Cool Product
The declarative form engine.`,
});
{
"kind": "display",
"type": "productDescription",
"props": {
"img": "assets/product-image.png",
"description": "### GolemUI\nThe declarative form engine for JavaScript. Build complex, data-driven forms with zero boilerplate."
}
}

For inline ad-hoc markup that doesn’t justify a full custom widget, use the Renderer widget instead.

This is a great place to show how you can use GolemUI’s library of custom elements inside your own widgets. The gui-markdown-text web component ships with @golemui/gui-components and renders markdown as HTML — no extra dependencies needed.

Key concepts (React)

  • useDisplayWidget is the simplest of the four hooks — it returns just uid and the merged templateData (your custom props plus engine-managed values).
  • There’s no onValueChanged, no events; you just render.
  • Importing @golemui/gui-components once unlocks every GolemUI custom element (like <gui-markdown-text>) inside your JSX.
  • style={{ flex: templateData.size }} lets the display participate in flex parents — see Sizing custom widgets for the rationale.
ProductDescription.tsx
import type { DisplayWidget, WithWidget } from '@golemui/core';
import { useDisplayWidget } from '@golemui/react';
import '@golemui/gui-components';
interface ProductDescriptionProps {
img: string;
description: string;
}
export function ProductDescription(widgetInstance: WithWidget) {
const widget = widgetInstance.widget as DisplayWidget;
const { uid, templateData } =
useDisplayWidget<ProductDescriptionProps>(widget);
return (
<div className="product-description" style={{ flex: templateData.size }}>
<div className="product-description__widget" id={uid}>
<img
className="product-description__image"
src={templateData.img}
alt="Product"
/>
<gui-markdown-text md={templateData.description} />
</div>
</div>
);
}

Here’s the product description displaying an image alongside rendered markdown: