Skip to content

v5.0.0-alpha.9

Pre-release
Pre-release

Choose a tag to compare

@danielweinmann danielweinmann released this 15 Apr 03:02

New Features

First-class array and object field support (#418, closes #74)

Until now, SchemaForm only knew about scalar fields — strings, numbers, booleans, dates, and files. Array and object fields in your schema were ignored, requiring manual wiring with hidden inputs and setValue.

This release teaches SchemaForm to understand the full depth of your schema. Scalar arrays, object arrays, arrays of arrays, and deeply nested objects all auto-render out of the box:

<SchemaForm schema={schema} />

The polymorphic Field component detects each field's schema type and generates the appropriate UI automatically, with unlimited recursive depth.

Children render functions adapt per field type. Array fields expose Item, items, append, remove, move, swap, AddButton, RemoveButton, ArrayEmpty, ScalarArrayField, Title, and Errors. Object fields expose a scoped Field, ObjectFields, Title, and Errors. Components received in children functions are automatically enhanced via mapChildren — labels, ids, ARIA attributes, and content are injected without manual prop passing.

Item children are optional — omitting them auto-renders the item content plus a RemoveButton, wrapped in the appropriate type-specific slot component (scalarArrayItem, objectArrayItem, or arrayArrayItem).

Array and object headings use Title (not Label) backed by dedicated arrayTitle/objectTitle slots that default to <div> — avoiding a11y warnings from labels not associated with form controls.

Auto-focus — the Add button automatically focuses the first input of the newly added item across all array types.

No hardcoded strings — all user-facing copy is configurable via props: emptyArrayLabel (default: 'No items'), addButtonLabel (default: 'Add'), removeButtonLabel (default: 'Remove').

Nested enum fields automatically render as <select> with options inferred from the schema.

6 type-specific render functions (#418)

With SchemaForm now rendering three categories of fields (scalar, array, object) and three categories of array items (scalar, object, nested array), customizing rendering requires more granularity than a single renderField could provide.

The old renderField prop has been renamed to renderScalarField — it works the same way, just with a more precise name. Five new render functions join it for the new field and item types:

Field-level (wrap <Field>):

  • renderScalarField — the old renderField, for string, number, boolean, date, and file fields
  • renderArrayField — customize how array fields render (e.g., wrap in a <section> with a heading)
  • renderObjectField — customize how object fields render (e.g., wrap in a <fieldset> with a <legend>)

Item-level (wrap <Item> inside arrays):

  • renderScalarArrayItem — customize scalar items in arrays
  • renderObjectArrayItem — customize object items in arrays (e.g., add drag-and-drop handles)
  • renderArrayArrayItem — customize nested array items in arrays

Each receives narrowed fieldType and shape props with full TypeScript safety. All follow a 3-level fallback: per-form prop → makeSchemaForm factory → default.

create-remix-forms CLI (#420, closes #419)

New npx create-remix-forms command that scaffolds styled components for makeSchemaForm. Ships with two presets:

  • Tailwind CSS — plain utility classes
  • DaisyUI — Tailwind + DaisyUI component classes

Generates 27 individual component files + barrel index.ts in a configurable output directory. Supports interactive prompts and CI-friendly flags (--preset, --output, -y). Auto-detects your package manager and installs remix-forms and tailwind-merge.

Type safety improvements (#418)

Replaced 58 noExplicitAny biome-ignores with proper types:

  • ComponentSlots constrains resolved components to the 26 known slot keys — Resolved['typo'] is now a compile error
  • ArrayFieldInnerProps / ObjectFieldInnerProps use proper interfaces instead of Record<string, any>
  • ArraySchemaInfo / ObjectSchemaInfo narrowed from generic SchemaInfo for type-safe .item and .fields access
  • UseFormRegister<Infer<Schema>> — schema-aware register type in createField

Breaking Changes

Peer dependency bumps

Two peer dependencies now require higher minimum versions:

  • schema-info>=0.4.1>=0.5.0 (adds array/object schema introspection)
  • coerce-form-data>=2.1>=3.0.0 (adds nested field coercion)

renderField renamed to renderScalarField

The renderField prop on SchemaForm and makeSchemaForm has been renamed to renderScalarField. The function signature is unchanged — just update the prop name.

Exported types renamed

  • RenderFieldPropsRenderScalarFieldProps
  • RenderFieldRenderScalarField

FormValues type narrowed

FormValues<T> values changed from any to unknown. Consumers accessing .values.field on MutationResult must narrow the type first.

ComponentMap expanded

10 new required slots for array/object support: scalarArrayField, scalarArrayItem, objectArrayItem, arrayArrayItem, addButton, removeButton, arrayEmpty, objectFields, arrayTitle, objectTitle. Consumers passing a full custom ComponentMap to makeSchemaForm must include these new slots (all have sensible defaults when omitted).

What's Changed

Full Changelog: v5.0.0-alpha.8...v5.0.0-alpha.9