Comprehensive form input library providing accessible, responsive, and validated form controls with consistent Carbon Design System styling.
Primary interactive elements with multiple variants and sizes for different use cases.
/**
* Primary button component with polymorphic support
*/
interface ButtonProps<T extends React.ElementType = "button"> extends PolymorphicProps<T> {
/** Button visual style variant */
kind?: "primary" | "secondary" | "tertiary" | "ghost" | "danger" | "danger--tertiary" | "danger--ghost";
/** Button size */
size?: "sm" | "md" | "lg" | "xl" | "2xl";
/** Disabled state */
disabled?: boolean;
/** Icon-only button (affects padding and ARIA) */
hasIconOnly?: boolean;
/** Click handler */
onClick?: (event: React.MouseEvent<HTMLButtonElement>) => void;
/** Button content */
children?: React.ReactNode;
/** CSS class name */
className?: string;
/** Tooltip alignment for icon buttons */
tooltipAlignment?: "start" | "center" | "end";
/** Tooltip position for icon buttons */
tooltipPosition?: "top" | "right" | "bottom" | "left";
}
/**
* Button loading skeleton
*/
interface ButtonSkeletonProps {
/** Button size */
size?: "sm" | "md" | "lg" | "xl" | "2xl";
/** Small button variant */
small?: boolean;
}
/**
* Button group container
*/
interface ButtonSetProps {
/** Buttons to group */
children: React.ReactNode;
/** Stacked layout */
stacked?: boolean;
}Usage Examples:
import { Button, ButtonSkeleton, ButtonSet } from "@carbon/react";
import { Add, Edit } from "@carbon/react/icons";
// Basic buttons
<Button kind="primary">Primary action</Button>
<Button kind="secondary">Secondary action</Button>
<Button kind="danger">Delete</Button>
// Icon buttons
<Button hasIconOnly iconDescription="Add item" tooltipAlignment="center">
<Add />
</Button>
// Button set
<ButtonSet>
<Button kind="secondary">Cancel</Button>
<Button kind="primary">Save</Button>
</ButtonSet>
// Loading state
<ButtonSkeleton />Text input controls with validation, helper text, and various input types.
/**
* Single-line text input component
*/
interface TextInputProps extends Omit<React.ComponentPropsWithoutRef<"input">, "size"> {
/** Input label text (required) */
labelText: string;
/** Helper text below input */
helperText?: string;
/** Error state */
invalid?: boolean;
/** Error message */
invalidText?: string;
/** Warning state */
warn?: boolean;
/** Warning message */
warnText?: string;
/** Input size */
size?: "sm" | "md" | "lg";
/** Light theme variant */
light?: boolean;
/** Hide label visually (still accessible) */
hideLabel?: boolean;
/** Read-only state */
readOnly?: boolean;
}
/**
* Multi-line text input component
*/
interface TextAreaProps extends Omit<React.ComponentPropsWithoutRef<"textarea">, "cols"> {
/** Textarea label */
labelText: string;
/** Helper text */
helperText?: string;
/** Error state */
invalid?: boolean;
/** Error message */
invalidText?: string;
/** Warning state */
warn?: boolean;
/** Warning message */
warnText?: string;
/** Enable resize handles */
enableCounter?: boolean;
/** Max character count */
maxCount?: number;
/** Light theme */
light?: boolean;
/** Number of visible rows */
rows?: number;
/** Number of columns */
cols?: number;
}
/**
* Password input component with show/hide toggle
*/
interface PasswordInputProps extends Omit<TextInputProps, "type"> {
/** Show password toggle tooltip */
showPasswordLabel?: string;
/** Hide password toggle tooltip */
hidePasswordLabel?: string;
/** Size variant */
size?: "sm" | "md" | "lg";
}Usage Examples:
import { TextInput, TextArea, PasswordInput } from "@carbon/react";
// Basic text input
<TextInput
id="username"
labelText="Username"
helperText="Enter your username"
placeholder="Enter username..."
/>
// Text input with validation
<TextInput
id="email"
labelText="Email"
invalid={emailError}
invalidText="Please enter a valid email address"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
// Text area
<TextArea
id="description"
labelText="Description"
helperText="Describe your project"
enableCounter
maxCount={500}
rows={4}
/>
// Password input
<PasswordInput
id="password"
labelText="Password"
showPasswordLabel="Show password"
hidePasswordLabel="Hide password"
/>Dropdown, multi-select, radio buttons, and checkboxes for user selections.
/**
* Dropdown selection component
*/
interface DropdownProps {
/** Dropdown items */
items?: any[];
/** Selected item value */
selectedItem?: any;
/** Change handler */
onChange?: (options: { selectedItem: any }) => void;
/** Item to string function */
itemToString?: (item: any) => string;
/** Item to element function */
itemToElement?: (item: any) => React.ReactNode;
/** Label text */
label?: string;
/** Title text */
titleText?: string;
/** Helper text */
helperText?: string;
/** Error state */
invalid?: boolean;
/** Error message */
invalidText?: string;
/** Warning state */
warn?: boolean;
/** Warning message */
warnText?: string;
/** Disabled state */
disabled?: boolean;
/** Light theme */
light?: boolean;
/** Size variant */
size?: "sm" | "md" | "lg";
/** Dropdown type */
type?: "default" | "inline";
}
/**
* Multi-selection dropdown component
*/
interface MultiSelectProps {
/** Selectable items */
items: any[];
/** Initially selected items */
initialSelectedItems?: any[];
/** Selection change handler */
onChange?: (options: { selectedItems: any[] }) => void;
/** Item to string function */
itemToString?: (item: any) => string;
/** Label text */
label?: string;
/** Title text */
titleText?: string;
/** Helper text */
helperText?: string;
/** Error state */
invalid?: boolean;
/** Error message */
invalidText?: string;
/** Warning state */
warn?: boolean;
/** Warning message */
warnText?: string;
/** Disabled state */
disabled?: boolean;
/** Size variant */
size?: "sm" | "md" | "lg";
/** Selection feedback */
selectionFeedback?: "top" | "fixed" | "top-after-reopen";
}
/**
* Checkbox input component
*/
interface CheckboxProps extends Omit<React.ComponentPropsWithoutRef<"input">, "type"> {
/** Label text */
labelText: string;
/** Indeterminate state */
indeterminate?: boolean;
/** Hide label visually */
hideLabel?: boolean;
/** Wrapper CSS classes */
wrapperClassName?: string;
}
/**
* Radio button component
*/
interface RadioButtonProps extends Omit<React.ComponentPropsWithoutRef<"input">, "type"> {
/** Label text */
labelText: string;
/** Hide label visually */
hideLabel?: boolean;
}
/**
* Radio button group container
*/
interface RadioButtonGroupProps {
/** Group name attribute */
name: string;
/** Default selected value */
defaultSelected?: string;
/** Value change handler */
onChange?: (value: string, name: string, event: React.ChangeEvent<HTMLInputElement>) => void;
/** Radio buttons */
children: React.ReactNode;
/** Group orientation */
orientation?: "horizontal" | "vertical";
/** Legend text for fieldset */
legendText?: string;
/** Helper text */
helperText?: string;
/** Error state */
invalid?: boolean;
/** Error message */
invalidText?: string;
/** Warning state */
warn?: boolean;
/** Warning message */
warnText?: string;
/** Read-only state */
readOnly?: boolean;
}Usage Examples:
import {
Dropdown,
MultiSelect,
Checkbox,
RadioButton,
RadioButtonGroup
} from "@carbon/react";
const countries = [
{ id: "us", text: "United States" },
{ id: "ca", text: "Canada" },
{ id: "uk", text: "United Kingdom" }
];
// Dropdown
<Dropdown
id="country"
titleText="Select country"
label="Choose country"
items={countries}
itemToString={(item) => (item ? item.text : "")}
selectedItem={selectedCountry}
onChange={({ selectedItem }) => setSelectedCountry(selectedItem)}
/>
// Multi-select
<MultiSelect
id="skills"
titleText="Select skills"
label="Choose skills"
items={skills}
itemToString={(item) => (item ? item.text : "")}
onChange={({ selectedItems }) => setSelectedSkills(selectedItems)}
/>
// Checkbox
<Checkbox
id="terms"
labelText="I agree to the terms and conditions"
checked={agreedToTerms}
onChange={(checked) => setAgreedToTerms(checked)}
/>
// Radio button group
<RadioButtonGroup
name="theme"
legendText="Select theme"
defaultSelected="light"
onChange={(value) => setTheme(value)}
>
<RadioButton labelText="Light" value="light" />
<RadioButton labelText="Dark" value="dark" />
<RadioButton labelText="Auto" value="auto" />
</RadioButtonGroup>Specialized input components for numeric and date/time values.
/**
* Number input component with increment/decrement controls
*/
interface NumberInputProps extends Omit<React.ComponentPropsWithoutRef<"input">, "type" | "size"> {
/** Label text */
label?: string;
/** Helper text */
helperText?: string;
/** Error state */
invalid?: boolean;
/** Error message */
invalidText?: string;
/** Warning state */
warn?: boolean;
/** Warning message */
warnText?: string;
/** Minimum value */
min?: number;
/** Maximum value */
max?: number;
/** Step increment */
step?: number;
/** Size variant */
size?: "sm" | "md" | "lg";
/** Allow empty value */
allowEmpty?: boolean;
/** Hide step buttons */
hideSteppers?: boolean;
/** Light theme */
light?: boolean;
/** Read-only state */
readOnly?: boolean;
}
/**
* Date picker component
*/
interface DatePickerProps {
/** Date picker type */
datePickerType?: "simple" | "single" | "range";
/** Date format */
dateFormat?: string;
/** Locale for date formatting */
locale?: string;
/** Light theme */
light?: boolean;
/** Short variant */
short?: boolean;
/** Value change handler */
onChange?: (dates: Date[]) => void;
/** Date picker children (inputs) */
children: React.ReactNode;
}
/**
* Date picker input component
*/
interface DatePickerInputProps extends Omit<React.ComponentPropsWithoutRef<"input">, "size"> {
/** Label text */
labelText?: string;
/** Helper text */
helperText?: string;
/** Error state */
invalid?: boolean;
/** Error message */
invalidText?: string;
/** Warning state */
warn?: boolean;
/** Warning message */
warnText?: string;
/** Input size */
size?: "sm" | "md" | "lg";
/** Hide label */
hideLabel?: boolean;
}Usage Examples:
import { NumberInput, DatePicker, DatePickerInput } from "@carbon/react";
// Number input
<NumberInput
id="quantity"
label="Quantity"
helperText="Enter quantity (1-100)"
min={1}
max={100}
step={1}
value={quantity}
onChange={(e, { value }) => setQuantity(value)}
/>
// Date picker
<DatePicker datePickerType="single" onChange={(dates) => setSelectedDate(dates[0])}>
<DatePickerInput
id="start-date"
labelText="Start date"
placeholder="mm/dd/yyyy"
/>
</DatePicker>
// Date range picker
<DatePicker datePickerType="range" onChange={(dates) => setDateRange(dates)}>
<DatePickerInput
id="start-date"
labelText="Start date"
placeholder="mm/dd/yyyy"
/>
<DatePickerInput
id="end-date"
labelText="End date"
placeholder="mm/dd/yyyy"
/>
</DatePicker>Components for organizing and structuring forms with proper spacing and relationships.
/**
* Form container component
*/
interface FormProps {
/** Form children */
children: React.ReactNode;
/** CSS class name */
className?: string;
}
/**
* Form group for related form elements
*/
interface FormGroupProps {
/** Group children */
children: React.ReactNode;
/** Legend text for fieldset */
legendText?: string;
/** Error state */
invalid?: boolean;
/** Error message */
message?: string;
/** Message type */
messageText?: string;
/** CSS class name */
className?: string;
}
/**
* Form item wrapper for individual form elements
*/
interface FormItemProps {
/** Form element */
children: React.ReactNode;
/** CSS class name */
className?: string;
}
/**
* Form label component
*/
interface FormLabelProps extends React.ComponentPropsWithoutRef<"label"> {
/** Label content */
children: React.ReactNode;
/** CSS class name */
className?: string;
}
/**
* Fluid form with integrated styling
*/
interface FluidFormProps {
/** Form children */
children: React.ReactNode;
/** CSS class name */
className?: string;
}Usage Examples:
import { Form, FormGroup, FormItem, FormLabel, Stack } from "@carbon/react";
// Basic form structure
<Form>
<Stack gap={6}>
<FormItem>
<TextInput id="name" labelText="Full name" />
</FormItem>
<FormItem>
<TextInput id="email" labelText="Email address" />
</FormItem>
<FormGroup legendText="Preferences">
<Checkbox id="newsletter" labelText="Subscribe to newsletter" />
<Checkbox id="updates" labelText="Receive product updates" />
</FormGroup>
<ButtonSet>
<Button kind="secondary">Cancel</Button>
<Button kind="primary" type="submit">Submit</Button>
</ButtonSet>
</Stack>
</Form>Binary input components for enabling/disabling options and features.
/**
* Binary toggle component with custom labels
*/
interface ToggleProps extends Omit<React.ComponentPropsWithoutRef<"input">, "type" | "size"> {
/** Unique identifier */
id: string;
/** Label for "off" state */
labelA?: string;
/** Label for "on" state */
labelB?: string;
/** Main label text */
labelText?: string;
/** Hide label visually */
hideLabel?: boolean;
/** Toggle size */
size?: "sm" | "md";
/** Default toggled state */
defaultToggled?: boolean;
/** Controlled toggled state */
toggled?: boolean;
/** Toggle change handler */
onToggle?: (checked: boolean, id: string, event: React.ChangeEvent<HTMLInputElement>) => void;
/** CSS class name */
className?: string;
/** Disabled state */
disabled?: boolean;
/** Read-only state */
readOnly?: boolean;
}
/**
* Switch component for simple on/off controls
*/
interface SwitchProps extends Omit<React.ComponentPropsWithoutRef<"input">, "type" | "size"> {
/** Unique identifier */
id: string;
/** Label text */
text?: string;
/** Size variant */
size?: "sm" | "md" | "lg";
/** CSS class name */
className?: string;
}Usage Examples:
import { Toggle, Switch } from "@carbon/react";
// Toggle with custom labels
<Toggle
id="notifications"
labelText="Email notifications"
labelA="Off"
labelB="On"
defaultToggled={false}
onToggle={(checked) => setNotifications(checked)}
/>
// Simple switch
<Switch
id="dark-mode"
text="Enable dark mode"
size="md"
onChange={(e) => setDarkMode(e.target.checked)}
/>All form components include skeleton loading states for better perceived performance.
interface TextInputSkeletonProps {
hideLabel?: boolean;
}
interface DropdownSkeletonProps {
size?: "sm" | "md" | "lg";
}
interface NumberInputSkeletonProps {
hideLabel?: boolean;
}Most form components share these common props:
interface CommonFormProps {
/** Error state */
invalid?: boolean;
/** Error message */
invalidText?: string;
/** Warning state */
warn?: boolean;
/** Warning message */
warnText?: string;
/** Helper text */
helperText?: string;
/** Disabled state */
disabled?: boolean;
/** Size variant */
size?: "sm" | "md" | "lg";
/** Light theme variant */
light?: boolean;
/** Read-only state */
readOnly?: boolean;
}