FormGroup

A layout wrapper for form fields that provides consistent label, hint text, and error message styling. Use when building custom inputs or when you need more control than the built-in labeled inputs.

Installation

typescript
import { FormGroup } from '@happyvertical/smrt-svelte';

Basic Usage

Wrap any input element with a label and optional hint.

svelte
<script lang="ts">
  import { FormGroup } from '@happyvertical/smrt-svelte';
</script>

<FormGroup label="Username" id="username" hint="Choose a unique username">
  <input type="text" id="username" name="username" />
</FormGroup>

Required Fields

Show a required indicator next to the label.

svelte
<FormGroup label="Email" id="email" required>
  <input type="email" id="email" name="email" required />
</FormGroup>

With Error

Display an error message (hides hint when shown).

svelte
<script lang="ts">
  let error = $state<string | undefined>(undefined);

  function validate(value: string) {
    if (!value.includes('@')) {
      error = 'Please enter a valid email address';
    } else {
      error = undefined;
    }
  }
</script>

<FormGroup
  label="Email"
  id="email"
  hint="We'll never share your email"
  {error}
>
  <input
    type="email"
    id="email"
    oninput={(e) => validate(e.currentTarget.value)}
  />
</FormGroup>

With Custom Input

Works with any input type or custom component.

svelte
<FormGroup label="Quantity" id="qty">
  <input type="range" id="qty" min="1" max="10" />
</FormGroup>

<FormGroup label="Color" id="color">
  <input type="color" id="color" />
</FormGroup>

<FormGroup label="Notes" id="notes">
  <textarea id="notes" rows="4"></textarea>
</FormGroup>

Props

PropTypeDefaultDescription
label *string-Label text for the form field
id stringundefinedID to associate label with input (for accessibility)
error stringundefinedError message to display
hint stringundefinedHint text shown below input (hidden when error is shown)
required booleanfalseShow required indicator (*) next to label
children *Snippet-Form input element(s)

TypeScript

typescript
import { FormGroup } from '@happyvertical/smrt-svelte';
import type { Snippet } from 'svelte';

interface FormGroupProps {
  label: string;
  id?: string;
  error?: string;
  hint?: string;
  required?: boolean;
  children: Snippet;
}

Accessibility

  • for attribute links label to input
  • Required indicator uses visible text (*)
  • Error messages have distinct styling for visibility