OSS-first docs

These docs teach the open system first: contracts, generated surfaces, runtimes, governance, and incremental adoption. Studio shows up as the operating layer on top, not as the source of truth.

Contracts: FormSpec

This document defines the canonical contracts for declarative forms.

field.key.label
Contracts: FormSpec
field.version.label
field.type.label
field.title.label
Contracts: FormSpec
field.description.label

This document defines the canonical contracts for declarative forms.

field.tags.label
tech,contracts,forms
field.owners.label
field.stability.label
public

This document defines the canonical contracts for declarative forms.

Overview

`FormSpec` (in `@lssm-tech/lib.contracts-spec/forms`) declares:

`meta` (extends `OwnerShipMeta`) + `key`/`version` for stability.

`model` (`@lssm-tech/lib.schema` `SchemaModel`) as the single source of truth.

`fields` built from `FieldSpec` kinds: `text`, `email`, `textarea`, `select`, `checkbox`, `radio`, `switch`, `autocomplete`, `address`, `phone`, `number`, `percent`, `currency`, `date`, `time`, `datetime`, `duration`, `group`, `array`.

`text.password` for masked current/new password fields with password-manager hints.

field-level `readOnly` support that preserves submitted values.

Optional `layout`, `layout.flow`, `actions`, `policy.flags`, `constraints` and `renderHints`.

Relations DSL provides `visibleWhen`, `enabledWhen`, `requiredWhen` based on predicates.

`buildZodWithRelations(spec)` augments the base zod with conditional rules and constraints.

React adapter renders with React Hook Form + driver API for UI components.

Rich field contracts

`autocomplete` supports local filtering or resolver-backed search, including debounce/min-query hints and configurable submit-value mapping.

Resolver-backed autocomplete stays runtime-neutral: forms declare `resolverKey`, dependency paths, and optional args while host renderers provide the actual fetcher.

`email` represents one string email-address field; schema validation remains model-owned while renderers supply email input affordances.

`address` uses the canonical `AddressFormValue` object shape.

`phone` uses the canonical `PhoneFormValue` object shape.

`number`, `percent`, and `currency` map numeric schema intent to native input controls while preserving locale, precision, rounding, and currency-display metadata.

`date`, `time`, `datetime`, and `duration` map temporal schema intent to native controls while preserving locale, timezone, unit, and display metadata.

`array` remains the canonical dynamic-field primitive and can repeat grouped item layouts.

`text` can declare `password.purpose` as `current` or `new`; renderers map those to masked controls and `current-password` / `new-password` autocomplete hints.

Progressive form layout

`layout.flow.kind: "sections"` groups existing fields into accessible sections while keeping all sections visible.

`layout.flow.kind: "steps"` uses the same section metadata for progressive, one-section-at-a-time rendering.

`FormSectionSpec.fieldNames` references existing immediate field names; field definitions stay in `FormSpec.fields`.

Unlisted fields remain visible so flow metadata cannot accidentally drop required model inputs.

`text` and `textarea` can declare portable `inputGroup` addons for text and host-resolved icons.

Layout and Groups

`FormSpec.layout` and `group.layout` can declare 1-4 responsive columns, gap size, and default field orientation.

`field.layout.colSpan` lets fields span one or more grid columns or the full row.

`wrapper.orientation` remains a compatibility alias for `layout.orientation`.

`group.legendI18n` renders as the semantic legend, falling back to `labelI18n`.

Driver API (UI-agnostic)

Host apps supply a driver mapping slots to components:

Required: `Field`, `FieldLabel`, `FieldDescription`, `FieldError`, `Input`, `Textarea`, `Select`, `Checkbox`, `RadioGroup`, `Switch`, `Autocomplete`, `AddressField`, `PhoneField`, `NumberField`, `PercentField`, `CurrencyField`, `DateField`, `TimeField`, `DateTimeField`, `DurationField`, `Button`.

Optional: `FieldContent`, `FieldGroup`, `FieldSet`, `FieldLegend`, `FieldSeparator`, `InputGroup`, `InputGroupAddon`, `InputGroupInput`, `InputGroupTextarea`, `InputGroupText`, `InputGroupIcon`, and `PasswordInput`.

Autocomplete drivers should accept optional `loading`, `error`, `emptyText`, `loadingText`, and `errorText` props so resolver-backed fields can expose async state without embedding transport details in the contract.

Use `createFormRenderer({ driver })` to obtain a `render(spec)` function.

Arrays and Groups

`array` items are rendered with `useFieldArray`, honoring `min`/`max` and add/remove controls.

`array.of` can repeat grouped multi-field rows.

`group` composes nested fields and provides optional legend/description/layout.

Feature Flags

Declare `policy.flags` on forms to signal gating. Gate usage at host boundary; avoid scattering flags across individual fields.

Example

Use the exported `RichFieldsShowcaseForm` as the canonical reference for readonly, password, autocomplete, address, phone, temporal, layout, and input-group field authoring.