MenuChevron Down
Field - Docs - Artefact

Field

Forms
Smart auto-detect

Introduction

A foundational component for form fields, managing labels, helper text, error messages, and validation state. It follows the "Smart Switcher" pattern, automatically hydrating as an interactive island when needed.

Usage

Smart Auto-Hydration

The Field component automatically determines if it should be interactive. It becomes an island if any of the following props are provided: interactive, onValueChange, value, defaultValue, validator, or minLength.

Validation

Field supports built-in and custom validation.

Minimum Length

Using minLength will automatically show an error message if the input is too short.

<Field
  label="Username"
  minLength={5}
  placeholder="Enter at least 5 characters"
/>

Custom Validator

The validator prop accepts a function that returns true for valid, false for invalid (using default error message), or a string as a custom error message.

<Field
  label="Email"
  validator={(value) => {
    if (!value.includes("@")) return "Must be a valid email";
    return true;
  }}
/>

The simplest way to use Field is with the flattened props. It will automatically render an input.

Choose a unique username.
import { Field } from "../components/ui";

export default function MyPage() {
  return (
    <Field
      label="Username"
      helperText="Choose a unique username."
      placeholder="Type here..."
      minLength={3}
    />
  );
}

Fieldset inheritance

A Field nested inside a Fieldset inherits the group's disabled/required state, and its invalid state too — but only when the Field has no validation of its own (no validator/minLength and no explicit invalid prop). An explicit prop on Field always wins over the inherited value.

<Fieldset legend="Shipping address" disabled>
  {/* inherits disabled — no need to repeat it */}
  <Field label="Street" />
</Fieldset>

Note that native <fieldset disabled> also disables every descendant form control at the browser level regardless of this inheritance — the inherited disabled prop only keeps the Field's own styling/ARIA in sync with that, it can't be overridden back to enabled from inside a disabled fieldset.

Composition

For more control, you can wrap other components like Textarea or custom inputs. The Field provides context to its children.

import { Field, Textarea } from "../components/ui";

export default function MyPage() {
  return (
    <Field
      label="Bio"
      helperText="Tell us about yourself."
      minLength={10}
    >
      <Textarea placeholder="A short bio" />
    </Field>
  );
}

CMS Page Builder

This component is available as a field block in the Page Builder (content/pages/*.json):

{
  "type": "field",
  "label": "Username",
  "helperText": "Choose a unique username.",
  "required": true
}

Props

PropTypeDescription
childrenanyContent to be rendered inside the component. If provided, the internal input is not rendered.
classstringCustom CSS classes.
idstringUnique identifier. If not provided, one is generated.
labelChildThe label for the field.
helperTextChildThe helper text for the field.
errorTextChildThe error text for the field. If provided as a string, it will be used as the message.
disabledbooleanWhether the field is disabled.
invalidbooleanWhether the field is in an invalid state.
requiredbooleanWhether the field is required.
readOnlybooleanWhether the field is read-only.
valuestringThe current value (forces interactive mode).
defaultValuestringThe initial value (forces interactive mode).
onValueChange(val: string) => voidCallback triggered when value changes (forces interactive mode).
minLengthnumberMinimum length validation (forces interactive mode).

| validator | `(val: string) => boolean \ | string` | Custom validation function (forces interactive mode). |

| interactive | boolean | Forces hydration as an island. |