Skip to main content

Displays validation error messages for form fields.

Import

import { FieldError } from "heroui-solid";

Usage

The FieldError component displays validation error messages for form fields. It automatically appears when the parent field is marked as invalid and provides smooth opacity transitions.

Username must be at least 3 characters
import { FieldError, Input, Label, TextField } from "heroui-solid"
import { createSignal } from "solid-js"

export function Basic() {
  const [value, setValue] = createSignal("jr")
  const isInvalid = () => value().length > 0 && value().length < 3

  return (
    <TextField
      class="w-64"
      isInvalid={isInvalid()}
      value={value()}
      onChange={setValue}
    >
      <Label for="username">Username</Label>
      <Input id="username" placeholder="Enter username" />
      <FieldError>Username must be at least 3 characters</FieldError>
    </TextField>
  )
}
  • TextField: Composition-friendly fields with labels and validation
  • Input: Single-line text input
  • TextArea: Multiline text input

Accessibility

The FieldError component ensures accessibility by:

  • Registering itself in the field's aria-describedby for error announcement
  • Supporting screen readers with semantic HTML
  • Providing visual and programmatic error indication
  • Automatically managing visibility based on validation state

Styling

The FieldError component uses the following CSS classes:

  • .field-error - Base error styles with danger color
  • Only shows when the data-visible attribute is present

Examples

Basic Validation

import { FieldError, Input, Label, TextField } from "heroui-solid";
import { createSignal } from "solid-js";

function UsernameField() {
  const [value, setValue] = createSignal("");
  const isInvalid = () => value().length > 0 && value().length < 3;

  return (
    <TextField class="w-64" isInvalid={isInvalid()} value={value()} onChange={setValue}>
      <Label for="username">Username</Label>
      <Input id="username" placeholder="Enter username" />
      <FieldError>Username must be at least 3 characters</FieldError>
    </TextField>
  );
}

With Dynamic Messages

There is no React Aria ValidationResult render prop — drive the message from your own state instead.

<TextField isInvalid={errors().length > 0}>
  <Label>Password</Label>
  <Input type="password" />
  <FieldError>{errors().join(", ")}</FieldError>
</TextField>

Custom Validation Logic

import { FieldError, Input, Label, TextField } from "heroui-solid";
import { createSignal } from "solid-js";

function EmailField() {
  const [email, setEmail] = createSignal("");
  const isInvalid = () => email().length > 0 && !email().includes("@");

  return (
    <TextField isInvalid={isInvalid()} value={email()} onChange={setEmail}>
      <Label>Email</Label>
      <Input type="email" />
      <FieldError>Email must include @ symbol</FieldError>
    </TextField>
  );
}

Multiple Error Messages

<TextField isInvalid={hasErrors()}>
  <Label>Username</Label>
  <Input />
  <FieldError>
    <For each={errors()}>{(error) => <div>{error}</div>}</For>
  </FieldError>
</TextField>

API

FieldError Props

PropTypeDefaultDescription
classstring-Additional CSS classes
childrenJSX.Element-Error message content
forceMountbooleanfalseKeep the element mounted while the field is valid; it stays hidden (no data-visible) until invalid, letting the reveal transition animate (Kobalte extra)

Differences from HeroUI React

  • Use class instead of className.
  • No render-prop children — there is no React Aria ValidationResult; drive the message content from your own state (see the Usage example).
  • Renders only inside a field (TextField for now); standalone usage renders nothing, matching upstream behavior.

Last updated: 7/19/26, 3:27 AM

HeroUI SolidUnofficial SolidJS port of HeroUI v3, built on Kobalte and @heroui/styles