Skip to main content
@widgentic/designer ships four designers — widget, theme, schema and action — each as a function taking a container and each as an opt-in custom element. They run in the browser, depend only on @widgentic/core, and perform no network I/O: every edit re-runs widgentic’s validators and re-renders a live preview through the real pipeline; persistence is yours.

The widget designer

createDesigner(container, options?) accepts: The handle is { getDraft, loadWidget, loadTheme, setReadOnly, subscribe, dispose }. getDraft() returns a copy of the current draft; loadWidget(definition) and loadTheme(theme) validate first and return { ok: true } or { ok: false, errors } without touching the draft on failure; subscribe(listener) calls listener(draft, diagnostics) on every change and returns an unsubscribe function; dispose() removes the UI. Read-only mode — readOnly: true or setReadOnly(true) — leaves editing surfaces visible but inert while the preview, its theme selector and Export keep working: it restricts editing, not looking.

Theme, schema and action designers

  • createThemeDesigner edits a named entry { name, label?, description?, tokens }. Its widgets option adds custom widget definitions to the preview-kind selector beside the built-ins, so a theme is judged against the widgets it will dress; invalid definitions are skipped. initialTheme opens an existing entry.
  • createSchemaDesigner edits a shared schema entry { name, label?, description?, schema }; initialSchema opens one.
  • createActionDesigner edits a stored action { name, label?, description?, definition }; initialAction opens one. schemas offers shared schemas as copy-from sources for the input and output schemas, and secretNames offers names for header and query values. A Test control appears only when you pass testCall(definition, args), which must run through your server’s execution path — the library performs no network I/O itself.
All four accept appearance, chrome and readOnly. The widget designer only selects among the themes, schemas and actions you pass; authoring each belongs to its own designer, so a host ships only what it embeds.

Custom elements

Registration happens only through the explicit calls — importing the module has no registry side effects:
Each registrar takes an optional tag name and does nothing if that tag is already defined. The elements wrap their factory and re-emit its subscription as bubbling widgentic-change CustomEvents whose detail carries { draft, diagnostics }, { theme }, { schema } or { action }. Two attributes are read when the element connects: appearance (light or dark) and chrome (the token map as JSON). The wrapped handle is available as the element’s designer property. Without a bundler, load the single-file bundle and use the elements directly:

Theming the chrome

chrome is available from @widgentic/designer 0.2.0.
The designers paint their own UI — panels, inputs, buttons, tags, menus — through 28 --wgd-* custom properties, the chrome tokens (exported as CHROME_TOKENS). The widget preview inside them is not chrome: it follows the selected theme’s --wg-* tokens from @widgentic/core/theming and is unaffected by chrome. appearance picks which built-in defaults the chrome follows. chrome layers your values on top of them, applied inline on the designer root, so they win over the light and dark blocks:
The elements take the same map as JSON:
Rules: values are CSS values; CSS-wide keywords (inherit, initial, unset, revert) are ignored — on a custom property they act on the token itself, not on what reads it — so to follow your typeface pass its variable with a fallback stack (font: "var(--app-font, system-ui, sans-serif)"). Unknown tokens, non-string values and unparseable attribute JSON are ignored, never thrown. With no chrome, nothing changes.

Helpers

The entry also exports the pieces the designers are built from — importWidgetJson, exportWidgetJson, exportThemeJson, toTypeScriptModule, and checkThemeEntry, checkSchemaEntry, checkActionEntry, which validate an untrusted entry and return error strings instead of throwing. The full list is in the designer export index.