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>
)
}Related Components
- 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-describedbyfor 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-visibleattribute 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
| Prop | Type | Default | Description |
|---|---|---|---|
class | string | - | Additional CSS classes |
children | JSX.Element | - | Error message content |
forceMount | boolean | false | Keep 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
classinstead ofclassName. - No render-prop
children— there is no React AriaValidationResult; drive the message content from your own state (see the Usage example). - Renders only inside a field (
TextFieldfor now); standalone usage renders nothing, matching upstream behavior.
Last updated: 7/19/26, 3:27 AM