Propel

Field

The shared labeling and validation shell for composing a custom form control with a label, description, and error text.

Shown anywhere your profile is visible.

Show code
import { Field, FieldDescription, FieldLabel } from "@makeplane/propel/components/field";
import { Input } from "@makeplane/propel/components/input";

export default function BasicDemo() {
  return (
    <Field name="displayName">
      <FieldLabel size="lg" inset={false} required>
        Display name
      </FieldLabel>
      <Input size="lg" placeholder="Ada Lovelace" required />
      <FieldDescription size="lg">Shown anywhere your profile is visible.</FieldDescription>
    </Field>
  );
}

Installation

import { Field, FieldDescription, FieldLabel } from "@makeplane/propel/components/field";
import { Input } from "@makeplane/propel/components/input";

Usage

import { Field, FieldDescription, FieldLabel } from "@makeplane/propel/components/field";
import { Input } from "@makeplane/propel/components/input";

export default function BasicDemo() {
  return (
    <Field name="displayName">
      <FieldLabel size="lg" inset={false} required>
        Display name
      </FieldLabel>
      <Input size="lg" placeholder="Ada Lovelace" required />
      <FieldDescription size="lg">Shown anywhere your profile is visible.</FieldDescription>
    </Field>
  );
}

Examples

Sizes

Pass the same size to every part of a field so the label, control, and description scale together.

Shown anywhere your profile is visible.

Shown anywhere your profile is visible.

Shown anywhere your profile is visible.

Show code
import {
  Field,
  FieldDescription,
  FieldLabel,
  type FieldSize,
} from "@makeplane/propel/components/field";
import { Input } from "@makeplane/propel/components/input";

const SIZES: FieldSize[] = ["lg", "xl", "2xl"];

export default function SizesDemo() {
  return (
    <div className="flex flex-wrap items-start gap-8">
      {SIZES.map((size) => (
        <Field key={size} name={`displayName-${size}`}>
          <FieldLabel size={size} inset={false} required>
            Display name ({size})
          </FieldLabel>
          <Input size={size} placeholder="Ada Lovelace" required />
          <FieldDescription size={size}>Shown anywhere your profile is visible.</FieldDescription>
        </Field>
      ))}
    </div>
  );
}

Invalid

Choose a different workspace slug.
Show code
import { Field, FieldError, FieldLabel } from "@makeplane/propel/components/field";
import { Input } from "@makeplane/propel/components/input";

export default function InvalidDemo() {
  return (
    <Field name="workspaceSlug" invalid>
      <FieldLabel size="lg" inset={false}>
        Workspace slug
      </FieldLabel>
      <Input size="lg" defaultValue="Already taken" />
      <FieldError size="lg" match={true}>
        Choose a different workspace slug.
      </FieldError>
    </Field>
  );
}

Required validation

Native constraint validity drives FieldError through match; with validationMode="onBlur" the message appears when the user leaves the field empty and clears once a value is committed.

Visible on your profile.

Show code
import {
  Field,
  FieldDescription,
  FieldError,
  FieldLabel,
} from "@makeplane/propel/components/field";
import { Input } from "@makeplane/propel/components/input";

export default function RequiredValidationDemo() {
  return (
    <Field name="fullName" validationMode="onBlur">
      <FieldLabel size="lg" inset={false} required>
        Full name
      </FieldLabel>
      <Input size="lg" placeholder="Ada Lovelace" required />
      <FieldError size="lg" match="valueMissing">
        Enter your full name.
      </FieldError>
      <FieldDescription size="lg">Visible on your profile.</FieldDescription>
    </Field>
  );
}

Horizontal label

FieldLabelGroup bundles the label and description into one block; with orientation="horizontal" it sits beside the control in a flex row.

Shown across your projects.

Show code
import { Field, FieldLabelGroup } from "@makeplane/propel/components/field";
import { Input } from "@makeplane/propel/components/input";

export default function HorizontalDemo() {
  return (
    <Field name="workspaceName">
      <div className="flex items-start gap-4">
        <FieldLabelGroup
          size="lg"
          orientation="horizontal"
          required
          label="Workspace name"
          description="Shown across your projects."
        />
        <Input size="lg" placeholder="Acme Inc." />
      </div>
    </Field>
  );
}

Helper text

FieldHelperText renders the hint below the control and swaps it for the error when one is set, keeping the error-XOR-hint rule in one part.

Lowercase letters, numbers, and dashes.

Only lowercase letters, numbers, and dashes are allowed.
Show code
import { Field, FieldHelperText, FieldLabel } from "@makeplane/propel/components/field";
import { Input } from "@makeplane/propel/components/input";

export default function HelperTextDemo() {
  return (
    <div className="flex flex-wrap items-start gap-8">
      <Field name="slug">
        <FieldLabel size="lg" inset={false}>
          Slug
        </FieldLabel>
        <Input size="lg" placeholder="acme-inc" />
        <FieldHelperText size="lg" hint="Lowercase letters, numbers, and dashes." />
      </Field>
      <Field name="slugTaken">
        <FieldLabel size="lg" inset={false}>
          Slug
        </FieldLabel>
        <Input size="lg" defaultValue="acme inc" />
        <FieldHelperText
          size="lg"
          hint="Lowercase letters, numbers, and dashes."
          error="Only lowercase letters, numbers, and dashes are allowed."
        />
      </Field>
    </div>
  );
}

API Reference

Field

The shared field chrome for custom controls: Base UI's labeling/validation `Field.Root` behavior grafted onto the styled `Field` element (rule 1a). Compose it with `FieldLabel`, a control, `FieldDescription`, and `FieldError`.

PropTypeDefaultDescription
renderReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, FieldRootState>Allows you to replace the component's HTML element with a different tag, or compose it with another component. Accepts a `ReactElement` or a function that returns the element to render.

FieldLabel

The ready-made field label: Base UI's `Field.Label` (auto-associated with the control) grafted onto the styled `FieldLabel` element (rule 1a), plus a `FieldLabelRequiredMarker` when `required`.

PropTypeDefaultDescription
size(required)"lg" | "xl" | "2xl"
inset(required)NonNullable<boolean | null | undefined>
renderReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, FieldLabelState>Allows you to replace the component's HTML element with a different tag, or compose it with another component. Accepts a `ReactElement` or a function that returns the element to render.
requiredboolean

FieldLabelGroup

The ready-made label/description block of a field: lays out an optional `FieldLabel` and `FieldDescription` inside the `FieldLabelGroup` container. Renders nothing when both are absent.

PropTypeDefaultDescription
orientation(required)"vertical" | "horizontal"
size(required)"lg" | "xl" | "2xl"
requiredboolean
labelstring
descriptionReactNode

FieldItemContent

The label + description column for a single choice option (checkbox/radio/switch row).

PropTypeDefaultDescription
size(required)"lg" | "xl" | "2xl"
descriptionReactNode

FieldDescription

Supporting / helper text for a field: Base UI's `Field.Description` (auto-associated as the control's accessible description) grafted onto the styled `FieldDescription` element (rule 1a).

PropTypeDefaultDescription
size(required)"lg" | "xl" | "2xl"
renderReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, FieldDescriptionState>Allows you to replace the component's HTML element with a different tag, or compose it with another component. Accepts a `ReactElement` or a function that returns the element to render.

FieldError

Error text for a field: Base UI's `Field.Error` (shown per the control's validity / `match`) grafted onto the styled `FieldError` element (rule 1a).

PropTypeDefaultDescription
size(required)"lg" | "xl" | "2xl"
renderReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, FieldErrorState>Allows you to replace the component's HTML element with a different tag, or compose it with another component. Accepts a `ReactElement` or a function that returns the element to render.

FieldHelperText

The error-or-hint line beneath a field: shows the `FieldError` when there is an error, otherwise the `FieldDescription` hint. With no explicit `error`, the `FieldError` renders unmatched so Base UI's own error channel stays open — validity messages and external `Form` `errors` for this field display (and clear) automatically. A components-tier composition of the two elements parts; shared by the ready-made field types so the error-XOR-hint rule lives in one place.

PropTypeDefaultDescription
size(required)"lg" | "xl" | "2xl"
hintReactNode
errorReactNode