or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

form-components.mdindex.mdnavigation-components.mdoverlay-components.mdselection-components.mdutility-components.md
tile.json

form-components.mddocs/

Form Components

Basic form controls including buttons, inputs, checkboxes, switches, and form organization components with built-in accessibility and interaction states.

Capabilities

Button

A basic button component with interaction states and polymorphic rendering.

/**
 * Basic button component with interaction states
 * @param props - Button properties including standard HTML button attributes
 */
function Button<TTag extends keyof JSX.IntrinsicElements = 'button'>(
  props: ButtonProps<TTag>
): JSX.Element;

interface ButtonProps<TTag extends keyof JSX.IntrinsicElements = 'button'> 
  extends PolymorphicProps<TTag> {
  /** Whether the button is disabled */
  disabled?: boolean;
  /** Whether to auto-focus on mount */
  autoFocus?: boolean;
  /** Button type for form submission */
  type?: 'button' | 'submit' | 'reset';
  /** Render prop providing interaction state */
  children?: React.ReactNode | ((props: ButtonRenderProps) => React.ReactNode);
}

interface ButtonRenderProps {
  /** Whether button is disabled */
  disabled: boolean;
  /** Whether button is being hovered */
  hover: boolean;
  /** Whether button has focus */
  focus: boolean;
  /** Whether button is being pressed */
  active: boolean;
  /** Whether button has autofocus */
  autofocus: boolean;
}

Usage Examples:

import { Button } from "@headlessui/react";

// Basic button
<Button className="px-4 py-2 bg-blue-500 text-white rounded">
  Click me
</Button>

// Button with render props for dynamic styling
<Button>
  {({ hover, focus, active, disabled }) => (
    <span className={`
      px-4 py-2 rounded transition-colors
      ${disabled ? 'bg-gray-300 cursor-not-allowed' : 'bg-blue-500'}
      ${hover && !disabled ? 'bg-blue-600' : ''}
      ${focus ? 'ring-2 ring-blue-300' : ''}
      ${active ? 'bg-blue-700' : ''}
    `}>
      Click me
    </span>
  )}
</Button>

// Polymorphic button as link
<Button as="a" href="/profile" className="text-blue-500 underline">
  Go to Profile
</Button>

Checkbox

A checkbox input component with form integration and indeterminate state support.

/**
 * Checkbox input component with form integration
 * @param props - Checkbox properties including form attributes
 */
function Checkbox<TType = string>(
  props: CheckboxProps<TType>
): JSX.Element;

interface CheckboxProps<TType = string> extends PolymorphicProps<'input'> {
  /** Value for form submission */
  value?: TType;
  /** Whether checkbox is disabled */
  disabled?: boolean;
  /** Whether checkbox is in indeterminate state */
  indeterminate?: boolean;
  /** Controlled checked state */
  checked?: boolean;
  /** Default checked state for uncontrolled usage */
  defaultChecked?: boolean;
  /** Whether to auto-focus on mount */
  autoFocus?: boolean;
  /** Associated form ID */
  form?: string;
  /** Form field name */
  name?: string;
  /** Change handler receiving checked state */
  onChange?: (checked: boolean) => void;
  /** Tab index */
  tabIndex?: number;
  /** Render prop providing interaction and state */
  children?: React.ReactNode | ((props: CheckboxRenderProps) => React.ReactNode);
}

interface CheckboxRenderProps {
  /** Current checked state */
  checked: boolean;
  /** Whether currently changing state */
  changing: boolean;
  /** Whether has focus */
  focus: boolean;
  /** Whether being pressed */
  active: boolean;
  /** Whether being hovered */
  hover: boolean;
  /** Whether has autofocus */
  autofocus: boolean;
  /** Whether disabled */
  disabled: boolean;
  /** Whether in indeterminate state */
  indeterminate: boolean;
}

Usage Examples:

import { useState } from "react";
import { Checkbox } from "@headlessui/react";

// Controlled checkbox
function ControlledExample() {
  const [enabled, setEnabled] = useState(false);
  
  return (
    <Checkbox checked={enabled} onChange={setEnabled}>
      {({ checked }) => (
        <span className={`${checked ? 'bg-blue-500' : 'bg-gray-200'} 
                         relative inline-block w-6 h-6 rounded border-2`}>
          {checked && (
            <svg className="w-4 h-4 text-white" fill="currentColor" viewBox="0 0 20 20">
              <path fillRule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clipRule="evenodd" />
            </svg>
          )}
        </span>
      )}
    </Checkbox>
  );
}

// Uncontrolled checkbox with form integration
<form>
  <Checkbox name="newsletter" value="yes" defaultChecked>
    Subscribe to newsletter
  </Checkbox>
</form>

// Indeterminate checkbox (for "select all" scenarios)
<Checkbox indeterminate={someSelected && !allSelected}>
  Select All
</Checkbox>

Input

A text input component with form integration and validation states.

/**
 * Text input component with form integration
 * @param props - Input properties including standard HTML input attributes
 */
function Input<TTag extends keyof JSX.IntrinsicElements = 'input'>(
  props: InputProps<TTag>
): JSX.Element;

interface InputProps<TTag extends keyof JSX.IntrinsicElements = 'input'> 
  extends PolymorphicProps<TTag> {
  /** Whether input is disabled */
  disabled?: boolean;
  /** Whether input is in invalid state */
  invalid?: boolean;
  /** Whether to auto-focus on mount */
  autoFocus?: boolean;
  /** Render prop providing interaction state */
  children?: React.ReactNode | ((props: InputRenderProps) => React.ReactNode);
}

interface InputRenderProps {
  /** Whether disabled */
  disabled: boolean;
  /** Whether being hovered */
  hover: boolean;
  /** Whether has focus */
  focus: boolean;
  /** Whether has autofocus */
  autofocus: boolean;
  /** Whether in invalid state */
  invalid: boolean;
}

Usage Examples:

import { Input, Field, Label, Description } from "@headlessui/react";

// Basic input with styling
<Input 
  type="email" 
  placeholder="Enter your email"
  className="w-full px-3 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-blue-500"
/>

// Input with render props for dynamic styling
<Input>
  {({ focus, invalid, hover }) => (
    <input
      className={`
        w-full px-3 py-2 border rounded-md transition-colors
        ${invalid ? 'border-red-500' : 'border-gray-300'}
        ${focus ? 'ring-2 ring-blue-500' : ''}
        ${hover && !focus ? 'border-gray-400' : ''}
      `}
      placeholder="Username"
    />
  )}
</Input>

// Input in form context
<Field>
  <Label>Email address</Label>
  <Input 
    type="email" 
    name="email" 
    required 
    className="mt-1 w-full px-3 py-2 border border-gray-300 rounded-md"
  />
  <Description>We'll never share your email</Description>
</Field>

Switch

A toggle switch component with form integration.

/**
 * Toggle switch component
 * @param props - Switch properties including form attributes
 */
function Switch<TTag extends keyof JSX.IntrinsicElements = 'button'>(
  props: SwitchProps<TTag>
): JSX.Element;

interface SwitchProps<TTag extends keyof JSX.IntrinsicElements = 'button'> 
  extends PolymorphicProps<TTag> {
  /** Current checked state */
  checked?: boolean;
  /** Default checked state for uncontrolled usage */
  defaultChecked?: boolean;
  /** Change handler receiving checked state */
  onChange?: (checked: boolean) => void;
  /** Form field name */
  name?: string;
  /** Form value when checked */
  value?: string;
  /** Associated form ID */
  form?: string;
  /** Whether to auto-focus on mount */
  autoFocus?: boolean;
  /** Whether switch is disabled */
  disabled?: boolean;
  /** Tab index */
  tabIndex?: number;
  /** Render prop providing interaction and state */
  children?: React.ReactNode | ((props: SwitchRenderProps) => React.ReactNode);
}

interface SwitchRenderProps {
  /** Whether switch is checked */
  checked: boolean;
  /** Whether being hovered */
  hover: boolean;
  /** Whether has focus */
  focus: boolean;
  /** Whether being pressed */
  active: boolean;
  /** Whether has autofocus */
  autofocus: boolean;
  /** Whether currently changing state */
  changing: boolean;
  /** Whether disabled */
  disabled: boolean;
}

Usage Examples:

import { useState } from "react";
import { Switch } from "@headlessui/react";

// Toggle switch with custom styling
function ToggleExample() {
  const [enabled, setEnabled] = useState(false);
  
  return (
    <Switch checked={enabled} onChange={setEnabled}>
      {({ checked }) => (
        <span className={`${checked ? 'bg-blue-600' : 'bg-gray-200'} 
                         relative inline-flex h-6 w-11 items-center rounded-full 
                         transition-colors focus:outline-none focus:ring-2 focus:ring-blue-500`}>
          <span className={`${checked ? 'translate-x-6' : 'translate-x-1'} 
                           inline-block h-4 w-4 transform rounded-full bg-white transition`} />
        </span>
      )}
    </Switch>
  );
}

// Switch with form integration
<form>
  <Switch name="notifications" value="enabled" defaultChecked>
    Enable notifications
  </Switch>
</form>

Select

A native select element wrapper with enhanced styling capabilities.

/**
 * Native select element wrapper
 * @param props - Select properties including standard HTML select attributes
 */
function Select<TTag extends keyof JSX.IntrinsicElements = 'select'>(
  props: SelectProps<TTag>
): JSX.Element;

interface SelectProps<TTag extends keyof JSX.IntrinsicElements = 'select'> 
  extends PolymorphicProps<TTag> {
  /** Whether select is disabled */
  disabled?: boolean;
  /** Whether select is in invalid state */
  invalid?: boolean;
  /** Whether to auto-focus on mount */
  autoFocus?: boolean;
  /** Render prop providing interaction state */
  children?: React.ReactNode | ((props: SelectRenderProps) => React.ReactNode);
}

interface SelectRenderProps {
  /** Whether disabled */
  disabled: boolean;
  /** Whether being hovered */
  hover: boolean;
  /** Whether has focus */
  focus: boolean;
  /** Whether being pressed */
  active: boolean;
  /** Whether has autofocus */
  autofocus: boolean;
  /** Whether in invalid state */
  invalid: boolean;
}

Textarea

A textarea element wrapper with enhanced styling capabilities.

/**
 * Textarea element wrapper
 * @param props - Textarea properties including standard HTML textarea attributes
 */
function Textarea<TTag extends keyof JSX.IntrinsicElements = 'textarea'>(
  props: TextareaProps<TTag>
): JSX.Element;

interface TextareaProps<TTag extends keyof JSX.IntrinsicElements = 'textarea'> 
  extends PolymorphicProps<TTag> {
  /** Whether textarea is disabled */
  disabled?: boolean;
  /** Whether textarea is in invalid state */
  invalid?: boolean;
  /** Whether to auto-focus on mount */
  autoFocus?: boolean;
  /** Render prop providing interaction state */
  children?: React.ReactNode | ((props: TextareaRenderProps) => React.ReactNode);
}

interface TextareaRenderProps {
  /** Whether disabled */
  disabled: boolean;
  /** Whether being hovered */
  hover: boolean;
  /** Whether has focus */
  focus: boolean;
  /** Whether has autofocus */
  autofocus: boolean;
  /** Whether in invalid state */
  invalid: boolean;
}

Form Organization Components

Field

A field wrapper that provides form field context and disabled state propagation.

/**
 * Field wrapper that provides form field context
 * @param props - Field properties
 */
function Field<TTag extends keyof JSX.IntrinsicElements = 'div'>(
  props: FieldProps<TTag>
): JSX.Element;

interface FieldProps<TTag extends keyof JSX.IntrinsicElements = 'div'> 
  extends PolymorphicProps<TTag> {
  /** Whether field is disabled (propagates to children) */
  disabled?: boolean;
  /** Render prop providing field state */
  children?: React.ReactNode | ((props: FieldRenderProps) => React.ReactNode);
}

interface FieldRenderProps {
  /** Whether field is disabled */
  disabled: boolean;
}

Fieldset

A fieldset wrapper for grouping related form fields.

/**
 * Fieldset wrapper for grouping form fields
 * @param props - Fieldset properties including standard HTML fieldset attributes
 */
function Fieldset<TTag extends keyof JSX.IntrinsicElements = 'fieldset'>(
  props: FieldsetProps<TTag>
): JSX.Element;

interface FieldsetProps<TTag extends keyof JSX.IntrinsicElements = 'fieldset'> 
  extends PolymorphicProps<TTag> {
  /** Whether fieldset is disabled (affects all contained fields) */
  disabled?: boolean;
  /** Render prop providing fieldset state */
  children?: React.ReactNode | ((props: FieldsetRenderProps) => React.ReactNode);
}

interface FieldsetRenderProps {
  /** Whether fieldset is disabled */
  disabled: boolean;
}

Legend

A legend component for fieldsets (wrapper around Label).

/**
 * Legend component for fieldsets
 * @param props - Legend properties
 */
function Legend<TTag extends keyof JSX.IntrinsicElements = 'legend'>(
  props: LegendProps<TTag>
): JSX.Element;

interface LegendProps<TTag extends keyof JSX.IntrinsicElements = 'legend'> 
  extends PolymorphicProps<TTag> {
  /** Standard legend props inherit from Label */
}

Usage Examples:

import { Field, Fieldset, Legend, Label, Input, Checkbox, Description } from "@headlessui/react";

// Form with field organization
<form>
  <Fieldset>
    <Legend>Personal Information</Legend>
    
    <Field>
      <Label>First Name</Label>
      <Input name="firstName" required />
      <Description>Enter your first name</Description>
    </Field>
    
    <Field>
      <Label>Last Name</Label>
      <Input name="lastName" required />
    </Field>
  </Fieldset>
  
  <Fieldset disabled={isSubmitting}>
    <Legend>Preferences</Legend>
    
    <Field>
      <Checkbox name="newsletter">
        Subscribe to newsletter
      </Checkbox>
    </Field>
  </Fieldset>
</form>

CloseButton

A specialized button that closes its containing component (Dialog, Popover, etc.).

/**
 * Button that closes its containing component
 * @param props - CloseButton properties (inherits all ButtonProps)
 */
function CloseButton<TTag extends keyof JSX.IntrinsicElements = 'button'>(
  props: CloseButtonProps<TTag>
): JSX.Element;

interface CloseButtonProps<TTag extends keyof JSX.IntrinsicElements = 'button'> 
  extends ButtonProps<TTag> {
  /** All props inherited from Button component */
}

Usage Examples:

import { Dialog, DialogPanel, CloseButton } from "@headlessui/react";

<Dialog open={isOpen} onClose={() => setIsOpen(false)}>
  <DialogPanel>
    <h2>Dialog Title</h2>
    <p>Dialog content...</p>
    
    {/* Automatically closes the dialog when clicked */}
    <CloseButton className="absolute top-2 right-2 p-1">
      <XMarkIcon className="w-5 h-5" />
    </CloseButton>
  </DialogPanel>
</Dialog>

Common Types

// Base polymorphic props for all components
interface PolymorphicProps<TTag extends keyof JSX.IntrinsicElements = 'div'> {
  /** Element or component to render as */
  as?: TTag;
  /** Children content or render prop function */
  children?: React.ReactNode | ((props: any) => React.ReactNode);
}

// Common interaction states
interface BaseInteractionState {
  disabled: boolean;
  hover: boolean;
  focus: boolean;
  active: boolean;
  autofocus: boolean;
}