@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
createThemeDesigneredits a named entry{ name, label?, description?, tokens }. Itswidgetsoption 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.initialThemeopens an existing entry.createSchemaDesigneredits a shared schema entry{ name, label?, description?, schema };initialSchemaopens one.createActionDesigneredits a stored action{ name, label?, description?, definition };initialActionopens one.schemasoffers shared schemas as copy-from sources for the input and output schemas, andsecretNamesoffers names for header and query values. A Test control appears only when you passtestCall(definition, args), which must run through your server’s execution path — the library performs no network I/O itself.
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: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.--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:
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.