Design System

Form Atoms

ImportCC

Available via @stackmates/ui-forms

FormInput

Text input with label, validation, and error display. Wraps TanStack Field internally.

FormInputProps

PropTypeDefaultDescription
form*FormApiTanStack Form instance
name*keyof TFormDataField name in form data
label*stringField label text
typeHTMLInputTypeAttribute'text'Input type (text, email, password, etc.)
placeholderstringPlaceholder text
requiredbooleanShow required indicator
helpTextstringHelp text below input
disabledbooleanDisable the input
size'sm' | 'md' | 'lg''md'Input size variant
autoCompletestringBrowser autocomplete hint
autoFocusbooleanFocus on mount

Installation

typescript
import { FormInput } from '@stackmates/ui-forms';

Usage

Basic

tsx
<FormInput<FormData>
  form={form}
  name="email"
  label="Email"
  type="email"
  placeholder="you@example.com"
/>

Accessibility

  • Label auto-linked via htmlFor
  • Error messages use aria-describedby
  • Required fields marked with aria-required
  • Help text linked via aria-describedby

FormSelect

Dropdown select with TanStack Form integration. Uses native <select> for accessibility.

FormSelectProps

PropTypeDefaultDescription
form*FormApiTanStack Form instance
name*keyof TFormDataField name in form data
label*stringField label text
options*{ value: string; label: string }[]Select options array
placeholderstringPlaceholder text
requiredbooleanShow required indicator
helpTextstringHelp text below select
disabledbooleanDisable the select
size'sm' | 'md' | 'lg''md'Select size variant

Installation

typescript
import { FormSelect } from '@stackmates/ui-forms';

Usage

With options

tsx
<FormSelect<FormData>
  form={form}
  name="country"
  label="Country"
  options={[
    { value: 'us', label: 'United States' },
    { value: 'uk', label: 'United Kingdom' },
  ]}
/>

Accessibility

  • Uses native <select> semantics
  • Keyboard navigable with arrow keys
  • Label linked via htmlFor
  • Error messages use aria-describedby

FormTextarea

Multi-line text input with TanStack Form integration. Supports rows and maxLength.

FormTextareaProps

PropTypeDefaultDescription
form*FormApiTanStack Form instance
name*keyof TFormDataField name in form data
label*stringField label text
placeholderstringPlaceholder text
rowsnumber4Number of visible text rows
maxLengthnumberMaximum character count
requiredbooleanShow required indicator
helpTextstringHelp text below textarea
disabledbooleanDisable the textarea
size'sm' | 'md' | 'lg''md'Textarea size variant

Installation

typescript
import { FormTextarea } from '@stackmates/ui-forms';

Usage

Basic

tsx
<FormTextarea<FormData>
  form={form}
  name="bio"
  label="Bio"
  placeholder="Tell us about yourself..."
/>

With character limit

tsx
<FormTextarea<FormData>
  form={form}
  name="notes"
  label="Notes"
  maxLength={500}
  rows={6}
/>

Accessibility

  • Label linked via htmlFor
  • Error messages use aria-describedby
  • Resizable by default for user comfort

RawInput

Lowest-level input primitive. Renders a styled <input> with optional TanStack Form fieldApi for automatic value/onChange/onBlur wiring. Use this when you need full control over layout and labeling, or when building custom form field molecules.

Sizes

States

RawInputProps

PropTypeDefaultDescription
fieldApiAnyFieldApiOptional TanStack Form field API for automatic state management
size'sm' | 'md' | 'lg''md'Input size variant
hasErrorbooleanfalseShow error styling (red border and focus ring)
typeHTMLInputTypeAttribute'text'HTML input type (text, email, password, etc.)
placeholderstringPlaceholder text
disabledbooleanDisable the input

Installation

typescript
import { RawInput } from '@stackmates/ui-forms';

Usage

Standalone

tsx
<RawInput
  placeholder="Enter value"
  size="md"
/>

With TanStack Field API

tsx
<form.Field name="email">
  {(field) => (
    <RawInput
      fieldApi={field}
      type="email"
      placeholder="you@example.com"
    />
  )}
</form.Field>

Accessibility

  • Forwards ref for external focus management
  • Sets aria-invalid automatically when fieldApi has errors
  • Supports aria-describedby for linked help/error text

RawCheckbox

Checkbox primitive with optional TanStack Form fieldApi binding. Renders a styled native <input type="checkbox"> with size variants and error state. Use inside a FormField or custom layout when the higher-level FormCheckbox does not fit.

RawCheckboxProps

PropTypeDefaultDescription
fieldApiAnyFieldApiOptional TanStack Form field API for automatic state management
size'sm' | 'md' | 'lg''md'Checkbox size variant
hasErrorbooleanfalseShow error styling (red border and focus ring)
checkedbooleanControlled checked state (when not using fieldApi)
disabledbooleanDisable the checkbox

Installation

typescript
import { RawCheckbox } from '@stackmates/ui-forms';

Usage

Standalone with label

tsx
<label className="flex items-center gap-2">
  <RawCheckbox size="md" />
  <span>Accept terms</span>
</label>

With TanStack Field API

tsx
<form.Field name="agreeToTerms">
  {(field) => (
    <label className="flex items-center gap-2">
      <RawCheckbox fieldApi={field} />
      <span>I agree</span>
    </label>
  )}
</form.Field>

Accessibility

  • Native checkbox semantics -- screen readers announce state
  • Forwards ref for external focus management
  • Sets aria-invalid when fieldApi has errors
  • Keyboard togglable with Space key

RawSelect

Native <select> primitive with options array, optional placeholder, and TanStack Form fieldApi support. Use when you need a lightweight dropdown without Radix overhead, or when building custom select molecules.

Sizes

States

RawSelectProps

PropTypeDefaultDescription
options*{ value: string; label: string }[]Options to render in the dropdown
fieldApiAnyFieldApiOptional TanStack Form field API for automatic state management
placeholderstringPlaceholder text displayed as disabled first option
size'sm' | 'md' | 'lg''md'Select size variant
hasErrorbooleanfalseShow error styling (red border and focus ring)
disabledbooleanDisable the select

Installation

typescript
import { RawSelect } from '@stackmates/ui-forms';

Usage

Standalone

tsx
<RawSelect
  placeholder="Choose..."
  options={[
    { value: 'a', label: 'Option A' },
    { value: 'b', label: 'Option B' },
  ]}
/>

With TanStack Field API

tsx
<form.Field name="country">
  {(field) => (
    <RawSelect
      fieldApi={field}
      placeholder="Select country"
      options={countries}
    />
  )}
</form.Field>

Accessibility

  • Uses native <select> -- full keyboard and screen reader support
  • Placeholder rendered as disabled first option
  • Forwards ref for external focus management
  • Sets aria-invalid when fieldApi has errors

RawTextarea

Textarea primitive with size variants and optional TanStack Form fieldApi. Renders a styled native <textarea> with error state support. Use for multi-line text input when you need full control over surrounding layout.

Sizes

States

RawTextareaProps

PropTypeDefaultDescription
fieldApiAnyFieldApiOptional TanStack Form field API for automatic state management
size'sm' | 'md' | 'lg''md'Textarea size variant
hasErrorbooleanfalseShow error styling (red border and focus ring)
placeholderstringPlaceholder text
rowsnumberNumber of visible text rows
disabledbooleanDisable the textarea

Installation

typescript
import { RawTextarea } from '@stackmates/ui-forms';

Usage

Standalone

tsx
<RawTextarea
  placeholder="Write something..."
  rows={4}
  size="md"
/>

With TanStack Field API

tsx
<form.Field name="bio">
  {(field) => (
    <RawTextarea
      fieldApi={field}
      placeholder="Tell us about yourself"
      rows={6}
    />
  )}
</form.Field>

Accessibility

  • Native textarea semantics
  • Forwards ref for external focus management
  • Sets aria-invalid when fieldApi has errors
  • Resizable by default for user comfort