Skip to content
Forms, switch product

Widget Sets Overview

A widget set is everything that sits between a form definition and the rendered form: the widgets themselves, the validators, an authoring namespace like gui.*, and the form components that host it in each framework. GolemUI ships one widget set, gui, and since v1.2.0 the pipeline that builds it is public. You can now build a second one: your design system’s components with their own myset.inputs.* namespace, their own selectors, and a <my-form> component per framework.

Building a widget set has three independent parts:

  1. The authoring pipeline (@golemui/dx): declare your widget types, get a typed namespace and a selector chain back. This is the part that turns myset.inputs.textInput('email', {...}) into engine widgets. See Authoring pipeline.
  2. The form components (createFormComponent in @golemui/react, @golemui/vue, @golemui/lit; provideWidgetSet in @golemui/angular): turn the widget set into a ready-to-use <Form> component or custom element for your framework. See Framework form components.
  3. The JSON schemas (@golemui/schemas): publish a schema tree for your widget types so JSON form definitions get completion and validation. See JSON schemas.

The first two meet in a small contract, the widget set definition: widget loaders, a validator factory, and the resolveFormInput function the authoring pipeline produces. The third is independent of both: a widget set can ship JSON support without a TypeScript namespace, or the other way around.

If you only need one extra widget inside the shipped set, you do not need any of this: register it with customWidgetLoaders and use it via gui.inputs.custom(...). That path is covered in Custom Widgets. A widget set is the bigger move: your own namespace, your own selectors, your own form component, with the gui set nowhere in the bundle unless you put it there.

There is no private machinery left: the shipped gui namespace is built with the exact APIs documented here. Its wiring is three calls:

// How @golemui/gui-shared builds gui (abridged)
import {
createItemTypeRegistry,
createSelectors,
createImplementation,
} from '@golemui/dx';
const guiRegistry = createItemTypeRegistry();
for (const shortcutType of guiShortcutTypes) {
registerShortcutType(guiRegistry, shortcutType);
}
const guiSelectors = createSelectors({
inputs,
inputByUid,
textInputs /* ...one entry per selector */,
});
const guiImplementation = createImplementation({
name: 'gui',
registry: guiRegistry,
facade: { inputs, actions, displays, layouts },
selectors: guiSelectors,
adapter: guiAdapter,
});
export const gui = guiImplementation.namespace;

And each framework package builds its GuiForm / <gui-form> from the same factory you would use:

// @golemui/gui-lit, complete source of the gui-form element
@customElement('gui-form')
export class FormElement extends createFormComponent<GuiFormInitConfig>({
widgetLoaders,
validators: initValidators,
resolveFormInput,
}) {}