Docs

Every `@ui/*` key the resolver respects, organized by field_type. The annotation row's `ui_config_json` is the single source of truth.

UI config reference

ui_config_json is a free-form JSON object on the annotation row; its @ui/* keys drive the resolver. This page is the exhaustive reference.

The keys are validated against the type's allow-list at write time (PUT handler refuses unknown component slugs with a 422) and at render time (the resolver console-warns and falls back to defaults).

Universal keys

These keys apply to every field_type.

KeyTypeEffect
@ui/componentstringOverride the default component for the type. Validated against the type's allow-list.
@ui/visible_whenstringExpression: when false, hide the field. Pay-as-you-go and up. Free tenants see the field rendered as if always-true.
@ui/computestringExpression: when set, the field is read-only and displays the computed value. Pay-as-you-go and up.
@ui/validate_whenstringExpression: when false, surface a zod-style validation error. Pay-as-you-go and up.

Expression keys evaluate inside a sandboxed QuickJS-emscripten runtime — no DOM access, no fetch, no eval. The available context: value, record, form, now, tenant_id, user_role. See the SmartField resolver for the full Border Control contract.

field_type = "string"

@ui/componentEffect
text (default)Native <input type="text">.
passwordNative <input type="password">.
emailNative <input type="email"> with browser-side validation.
urlNative <input type="url">.
phoneRenders as <input type="tel">.
slugSame render as text; reserved for future slug-validation refinement.

Input formatting (string)

Two optional keys reformat the user's input as they type. Both work together — mask runs first, uppercase after, so literals in the mask are unaffected by case folding.

KeyTypeEffect
@ui/input_maskstringFormat the value as the user types. Cursor position is preserved across the format pass so the next typed char lands where the user expects.
@ui/uppercasebooleanUppercase typed letters. Stacks cleanly with @ui/input_mask.

Mask token vocabulary (matches text-mask / imask conventions):

TokenAccepts
0 or 9digit (0–9)
a or Aletter (a–z, A–Z; case-insensitive accept)
*alphanumeric
anything elseliteral — rendered verbatim

Common mask examples:

MaskReads as
000-00-0000US Social Security Number
(000) 000-0000US phone
00000-0000US ZIP+4
aaa-000Canadian postal code (use with @ui/uppercase: true)
aa00-00-aaUK passport-style mixed alphanumeric

The same keys are honored on Forms v2 fields stamped with an entity_field source (admin-preview SmartField routing). For free-form Forms v2 fields without an entity binding, the same behavior is available via field.mask / field.uppercase on the form schema directly.

field_type = "longtext"

@ui/componentEffect
textarea (default)Native <textarea>.
richtextTipTap-based editor from @fastyoke/lcap-richtext. Stores HTML-escaped sanitized markup.
markdownMarkdown editor from @fastyoke/lcap-markdowneditor. Stores raw markdown.
codeMonaco-based editor from @fastyoke/lcap-codeeditor. Stores raw source.
KeyTypeEffect
@ui/code_languagestringSyntax highlighting target for code component (e.g. "javascript", "sql", "yaml").

field_type = "number"

@ui/componentEffect
number (default)Native <input type="number">.
currencyIntl.NumberFormat with style: "currency". Display only — storage stays a plain JSON number.
percentIntl.NumberFormat with style: "percent". Storage stays decimal (0.07 displays 7%).
sliderReserved for a range-slider follow-on. Renders as number today.
ratingReserved for a star-rating follow-on. Renders as number today.
KeyTypeEffect
@ui/formatstringAlias for @ui/component when the value happens to be currency / percent / decimal. Either spelling works.
@ui/currency_codestringISO-4217 (USD, EUR, JPY, …). Default: USD. Drives the locale-rendered prefix/suffix.
@ui/decimal_placesnumberClamps minimumFractionDigits + maximumFractionDigits. Also drives the zod refinement that rejects extra precision.
@ui/use_separatorsbooleanToggle useGrouping. Default: true (i.e. 1,234.56). Set to false for 1234.56.
@ui/minnumberUI bound (also surfaced in zod).
@ui/maxnumberUI bound.
@ui/stepnumberSpinner step + zod multiple-of check.

field_type = "boolean"

@ui/componentEffect
checkbox (default)Native checkbox.
switchSame <input type="checkbox"> with role="switch".
radioYes/No radio pair. Requires options_json to declare the two values.

field_type = "timestamp"

@ui/componentEffect
date (default)Native <input type="date">.
datetimeNative <input type="datetime-local">.
timeNative <input type="time"> (time-of-day only).
daterangeReserved for a range picker; renders as date today.
KeyTypeEffect
@ui/include_timebooleanSwitches the input from <DatePicker /> to <DateTimePicker /> (equivalent to picking datetime as the component slug).
@ui/date_formatstringdayjs-style display format ("MMM dd, yyyy", "yyyy-MM-dd", etc). Display-only; storage stays ISO-8601 UTC. See formatting for the full token vocabulary.
@ui/time_formatstringdayjs-style time-portion format.
@ui/timezonestringIANA tz ("America/Los_Angeles"). Applied at display only.

field_type = "enum"

@ui/componentEffect
select (default)Native <select> populated from options_json.
radioRadio group.
tagsReserved for a multi-select chip surface.

The options_json column on the annotation row carries [{ value, label }, …]. <SmartField /> reads it directly.

field_type = "fsm_state_ref"

Single-component; no overrides. When options_json carries a curated state list, the resolver renders a <select>; otherwise a free-text input.

field_type = "file_ref"

Single-component; v0 renders a read-only summary (filename (size)). The Page Designer Card block (rolling out) wraps <SmartField /> with the existing <FilePayloadView /> for full image / download rendering.

field_type = "relationship"

@ui/componentEffect
display (default)Disabled <input> showing the id string.
id_onlySame render; reserved for future "show id with no chrome" behavior.
KeyTypeEffect
@ui/display_pathstringWhen set, the resolver runs a single useEntity(target_entity, target_id) fetch and shows the named field instead of the raw id. v0 doesn't traverse multi-level paths.

Cross-references

  • Field types — the closed 9-type vocabulary and which slugs each type accepts.
  • Formatting — the full dayjs token reference + locale resolution chain.
  • Annotations — the admin editor surface that writes ui_config_json.