Saltar al contenido
EspañolEnglish
Todos los componentes (244)

Formulario desde esquema

Campos · SchemaForm

Qué es y cuándo usarlo

Un formulario entero a partir de un JSON Schema: los campos, sus etiquetas y sus reglas salen del esquema, y se valida con ese mismo esquema (el que ya usa el servidor). Por dentro es un Form: el foco va al primer campo inválido, el resumen de errores se anuncia y no se envía dos veces.

Cuándo usarlo

  • Cuando el formulario lo describe una configuración, un backend o una IA y no se quiere escribir cada campo a mano.
  • Para formularios con condiciones (if/then/else, dependentRequired, oneOf por un valor fijo): los campos aparecen y se van según lo que se escribe, y lo apagado no viaja al enviar.
  • Para listas que crecen (una lista de objetos) y objetos anidados, y para formularios largos por steps.

Cuándo no

  • Un formulario fijo y pequeño: Form con sus campos conectados da más control sobre la maquetación.
  • Un asistente cuyos pasos no son campos de un mismo esquema: Wizard.

Qué campo sale de cada esquema: texto, correo (format: email), web (uri), contraseña (writeOnly), área de texto (x-multiline o maxLength largo), número (con minimum, maximum y multipleOf de paso), interruptor (boolean), botones de radio (enum de hasta cuatro opciones) o desplegable (más), selector múltiple (una lista de enum), fecha, hora y fecha con hora (format date, time, date-time). ui cambia el campo, la etiqueta, la ayuda, el orden o lo oculta, por la ruta con puntos del campo (en una lista, lines.*.sku).

Teclado y accesibilidad: los campos son los de siempre, cada uno con su etiqueta enlazada; lo obligatorio se anuncia como tal, un objeto es un fieldset con su legend y cada error sale junto a su campo y en el resumen. En pasos, no se avanza hasta que los campos del paso valen y se anuncia el paso nuevo.

Validación: sin dependencias. Soporta tipos, enum/const, largo, patrón y formatos de un texto, límites y múltiplos de un número, tamaño y repetidos de una lista, allOf/anyOf/oneOf/not, condiciones y referencias locales (#/$defs/...). Un campo vacío cuenta como ausente. Los textos de los errores salen en el idioma activo.

Cómo se ve

Plan

Rellena y envía: aquí sale lo que llegaría al servidor.

const esquema: JsonSchema = {
  type: "object",
  properties: {
    nombre: { type: "string", title: "Nombre", minLength: 2 },
    correo: { type: "string", title: "Correo", format: "email" },
    plan: { type: "string", title: "Plan", enum: ["Básico", "Profesional"] },
    avisos: { type: "boolean", title: "Recibir avisos por correo" },
  },
  required: ["nombre", "correo"],
};

<SchemaForm label="Alta de cliente" schema={esquema} submitLabel="Dar de alta" onSubmit={guardar} />

Props

Se importa con import { SchemaForm } from '@amset/ui/form'. Las obligatorias van marcadas.

PropTipoPara qué sirve
schemaobligatoriaJsonSchemaEl esquema del formulario: un objeto, descrito con JSON Schema. Los mismos que valida el servidor.
uiUiSchemaLo que se puede decir de cada campo aparte de su esquema, por su ruta con puntos.
initialValuesReadonly<Record<string, unknown>>Valores con los que empieza, por encima de los `default` del esquema. Si cambian despues (datos que llegan de una peticion), el formulario los toma sin pisar lo que la persona ya haya cambiado a mano.
onSubmitobligatoriaFormProps<Record<string, unknown>>['onSubmit']Se llama solo con los datos ya validados y limpios: sin campos vacios y sin los que una condicion ha apagado. Lo que devuelve se pinta como en `Form`: `errors` en sus campos y `error` en el resumen.
stepsreadonly SchemaFormStep[]Parte el formulario en pasos: cada uno pide sus campos y no deja avanzar hasta que valen.
labelstringEl nombre del formulario, para el lector de pantalla. Por defecto, el `title` del esquema.
submitLabelstringEl texto del boton de enviar (o de terminar, en pasos).
summaryboolean—
validateOnFormProps<Record<string, unknown>>['validateOn']—
widgetsReadonly<Record<string, SchemaWidgetRenderer>>Widgets propios, por nombre: `widgets={{ swatch: (field) => <Swatch {...field} /> }}` y `ui={{ color: { widget: 'swatch' } }}`. El widget recibe su valor, su error y los datos de todo el formulario.
onChange(values: Readonly<Record<string, unknown>>, state: { readonly dirty: boolean; }) => voidSe llama en cada cambio de los datos (no al montar), con los datos tal cual estan en el formulario y si ha cambiado respecto a lo ultimo guardado (`dirty`): sirve para avisar antes de salir con cambios sin guardar. Un envio que sale bien cuenta como guardado y vuelve a `dirty: false`.
classNamestring—

En el banco de pruebas

Cada estado y cada variante, para tocarlos de uno en uno, en su ficha de ui.amset.tech: