stellify/ui

Components

Field

An input wrapper that validates on blur and drives existing error markup.

Preview

Please enter a valid email address.

Usage

<st-field class="grid gap-2">
  <label for="email">Email address</label>
  <input
    id="email"
    name="email"
    type="email"
    required
  >
</st-field>

Laravel Blade Integration

st-field reads its initial error state from the DOM. Use Laravel's @error directive:

<st-field class="grid gap-2">
  <label for="email">Email address</label>
  <input
    id="email"
    name="email"
    type="email"
    required
    value="{{ old('email') }}"
    @error('email') aria-invalid="true" @enderror
  >
  @error('email')
    <p data-error class="text-sm text-destructive">{{ $message }}</p>
  @enderror
</st-field>

How It Works

  1. On page load, st-field discovers any existing <p data-error> element and the input's aria-invalid attribute.
  2. If either is present, the field is treated as "touched" — subsequent client-side validation updates the error message in place.
  3. If there is no server error, the <p data-error> element is absent. When client-side validation produces an error, the component creates and inserts it.

The Error Element

The error message element must have data-error attribute. The component will:

  • Update its text content when validation fails
  • Show/hide it based on validation state
  • Create it dynamically if it doesn't exist
<!-- Server-rendered error -->
<p data-error class="text-sm text-red-600">The email is invalid.</p>

<!-- Or dynamically created by the component -->

Validation Timing

Event Behaviour
blur Validates when user leaves the field (marks as touched)
input Re-validates on each keystroke if already touched
submit Parent st-form validates all fields

Styling Invalid State

Use CSS attribute selectors to style invalid inputs:

st-field input[aria-invalid="true"] {
  border-color: var(--color-destructive);
}

st-field [data-error] {
  color: var(--color-destructive);
  font-size: 0.875rem;
}