Form components provide accessible, styled input controls for building forms with validation, labels, and error states.
Text input field with variant support.
import { Input, InputPropsProvider } from "@chakra-ui/react";
interface InputProps extends HTMLChakraProps<"input"> {
variant?: "outline" | "subtle" | "flushed";
size?: "xs" | "sm" | "md" | "lg";
}
const Input: ChakraComponent<"input", InputProps>;
const InputPropsProvider: React.FC<{ value: InputProps; children: React.ReactNode }>;Group inputs with prefix/suffix addons and icons using a props-based composition pattern.
import { InputGroup, InputAddon, InputElement, Input } from "@chakra-ui/react";
interface InputGroupProps extends HTMLChakraProps<"div"> {
startElementProps?: InputElementProps;
endElementProps?: InputElementProps;
startElement?: React.ReactNode;
endElement?: React.ReactNode;
startAddon?: React.ReactNode;
startAddonProps?: InputAddonProps;
endAddon?: React.ReactNode;
endAddonProps?: InputAddonProps;
children: React.ReactElement; // Single Input component
}
const InputGroup: ChakraComponent<"div", InputGroupProps>;
interface InputAddonProps extends HTMLChakraProps<"div"> {}
const InputAddon: ChakraComponent<"div", InputAddonProps>;
interface InputElementProps extends HTMLChakraProps<"div"> {}
const InputElement: ChakraComponent<"div", InputElementProps>;Usage:
// With start element (icon)
<InputGroup startElement={<SearchIcon />}>
<Input placeholder="Search..." />
</InputGroup>
// With start and end addons
<InputGroup
startAddon="https://"
endAddon=".com"
>
<Input placeholder="mysite" />
</InputGroup>
// With element props for custom styling
<InputGroup
startElement={<PhoneIcon />}
startElementProps={{ color: "blue.500" }}
>
<Input type="tel" placeholder="Phone number" />
</InputGroup>Multi-line text input.
import { Textarea, TextareaPropsProvider } from "@chakra-ui/react";
interface TextareaProps extends HTMLChakraProps<"textarea"> {
variant?: "outline" | "subtle" | "flushed";
size?: "xs" | "sm" | "md" | "lg";
resize?: "none" | "both" | "horizontal" | "vertical";
}
const Textarea: ChakraComponent<"textarea", TextareaProps>;
const TextareaPropsProvider: React.FC<{ value: TextareaProps; children: React.ReactNode }>;Multi-part checkbox input with label and indicator.
import { Checkbox, useCheckbox, useCheckboxContext } from "@chakra-ui/react";
// Root container
interface CheckboxRootProps {
name?: string;
value?: string;
checked?: boolean;
defaultChecked?: boolean;
disabled?: boolean;
required?: boolean;
invalid?: boolean;
readOnly?: boolean;
onCheckedChange?: (details: CheckboxCheckedChangeDetails) => void;
children?: React.ReactNode;
}
const CheckboxRoot: React.FC<CheckboxRootProps>;
const CheckboxRootProvider: React.FC<CheckboxRootProps & { children: React.ReactNode }>;
// Control wrapper
interface CheckboxControlProps extends HTMLChakraProps<"label"> {}
const CheckboxControl: ChakraComponent<"label", CheckboxControlProps>;
// Indicator (checkmark)
interface CheckboxIndicatorProps extends HTMLChakraProps<"div"> {}
const CheckboxIndicator: ChakraComponent<"div", CheckboxIndicatorProps>;
// Label text
interface CheckboxLabelProps extends HTMLChakraProps<"span"> {}
const CheckboxLabel: ChakraComponent<"span", CheckboxLabelProps>;
// Hidden input
const CheckboxHiddenInput: React.FC;
// Group
interface CheckboxGroupProps {
name?: string;
value?: string[];
defaultValue?: string[];
disabled?: boolean;
onValueChange?: (details: { value: string[] }) => void;
children?: React.ReactNode;
}
const CheckboxGroup: React.FC<CheckboxGroupProps>;
// Hooks
function useCheckbox(props: UseCheckboxProps): UseCheckboxReturn;
function useCheckboxContext(): CheckboxContext;
function useCheckboxGroup(props: UseCheckboxGroupProps): UseCheckboxGroupReturn;
function useCheckboxGroupContext(): CheckboxGroupContext;
// Namespace
namespace Checkbox {
export const Root: typeof CheckboxRoot;
export const RootProvider: typeof CheckboxRootProvider;
export const Control: typeof CheckboxControl;
export const Indicator: typeof CheckboxIndicator;
export const Label: typeof CheckboxLabel;
export const HiddenInput: typeof CheckboxHiddenInput;
export const Group: typeof CheckboxGroup;
}
interface CheckboxCheckedChangeDetails {
checked: boolean | "indeterminate";
}Usage:
<Checkbox.Root>
<Checkbox.Control>
<Checkbox.Indicator />
</Checkbox.Control>
<Checkbox.Label>Accept terms</Checkbox.Label>
<Checkbox.HiddenInput />
</Checkbox.Root>Card-style checkbox with richer content.
import { CheckboxCard } from "@chakra-ui/react";
namespace CheckboxCard {
export const Root: React.FC<CheckboxRootProps>;
export const RootProvider: React.FC<CheckboxRootProps>;
export const Control: ChakraComponent<"label">;
export const Indicator: ChakraComponent<"div">;
export const Label: ChakraComponent<"span">;
export const Description: ChakraComponent<"div">;
export const Addon: ChakraComponent<"div">;
export const Content: ChakraComponent<"div">;
export const HiddenInput: React.FC;
}Toggle switch input control.
import { Switch, useSwitch, useSwitchContext } from "@chakra-ui/react";
// Root container
interface SwitchRootProps {
name?: string;
checked?: boolean;
defaultChecked?: boolean;
disabled?: boolean;
required?: boolean;
invalid?: boolean;
readOnly?: boolean;
onCheckedChange?: (details: { checked: boolean }) => void;
children?: React.ReactNode;
}
const SwitchRoot: React.FC<SwitchRootProps>;
const SwitchRootProvider: React.FC<SwitchRootProps>;
// Parts
const SwitchControl: ChakraComponent<"label">;
const SwitchThumb: ChakraComponent<"div">;
const SwitchIndicator: ChakraComponent<"div">;
const SwitchThumbIndicator: ChakraComponent<"div">;
const SwitchLabel: ChakraComponent<"span">;
const SwitchHiddenInput: React.FC;
// Hooks
function useSwitch(props: UseSwitchProps): UseSwitchReturn;
function useSwitchContext(): SwitchContext;
namespace Switch {
export const Root: typeof SwitchRoot;
export const RootProvider: typeof SwitchRootProvider;
export const Control: typeof SwitchControl;
export const Thumb: typeof SwitchThumb;
export const Indicator: typeof SwitchIndicator;
export const ThumbIndicator: typeof SwitchThumbIndicator;
export const Label: typeof SwitchLabel;
export const HiddenInput: typeof SwitchHiddenInput;
}Radio button group for single selection.
import { RadioGroup, useRadioGroup, useRadioGroupContext } from "@chakra-ui/react";
// Root container
interface RadioGroupRootProps {
name?: string;
value?: string;
defaultValue?: string;
disabled?: boolean;
orientation?: "horizontal" | "vertical";
onValueChange?: (details: { value: string }) => void;
children?: React.ReactNode;
}
const RadioGroupRoot: React.FC<RadioGroupRootProps>;
const RadioGroupRootProvider: React.FC<RadioGroupRootProps>;
// Parts
interface RadioGroupItemProps {
value: string;
disabled?: boolean;
invalid?: boolean;
children?: React.ReactNode;
}
const RadioGroupItem: React.FC<RadioGroupItemProps>;
const RadioGroupItemControl: ChakraComponent<"label">;
const RadioGroupItemText: ChakraComponent<"span">;
const RadioGroupItemIndicator: ChakraComponent<"div">;
const RadioGroupLabel: ChakraComponent<"div">;
const RadioGroupItemHiddenInput: React.FC;
namespace RadioGroup {
export const Root: typeof RadioGroupRoot;
export const RootProvider: typeof RadioGroupRootProvider;
export const Item: typeof RadioGroupItem;
export const ItemControl: typeof RadioGroupItemControl;
export const ItemText: typeof RadioGroupItemText;
export const ItemIndicator: typeof RadioGroupItemIndicator;
export const Label: typeof RadioGroupLabel;
export const ItemHiddenInput: typeof RadioGroupItemHiddenInput;
}Card-style radio buttons for richer options.
import { RadioCard } from "@chakra-ui/react";
namespace RadioCard {
export const Root: React.FC<RadioGroupRootProps>;
export const RootProvider: React.FC<RadioGroupRootProps>;
export const Item: React.FC<RadioGroupItemProps>;
export const ItemControl: ChakraComponent<"label">;
export const ItemText: ChakraComponent<"span">;
export const ItemIndicator: ChakraComponent<"div">;
export const ItemDescription: ChakraComponent<"div">;
export const ItemAddon: ChakraComponent<"div">;
export const ItemContent: ChakraComponent<"div">;
export const Label: ChakraComponent<"div">;
export const ItemHiddenInput: React.FC;
}Custom select dropdown with rich features.
import { Select, useSelect, useSelectContext } from "@chakra-ui/react";
interface SelectRootProps<T = any> {
name?: string;
value?: string[];
defaultValue?: string[];
multiple?: boolean;
disabled?: boolean;
invalid?: boolean;
readOnly?: boolean;
positioning?: PositioningOptions;
onValueChange?: (details: { value: string[]; items: T[] }) => void;
onOpenChange?: (details: { open: boolean }) => void;
children?: React.ReactNode;
}
namespace Select {
export const Root: React.FC<SelectRootProps>;
export const RootProvider: React.FC<SelectRootProps>;
export const Control: ChakraComponent<"div">;
export const Trigger: ChakraComponent<"button">;
export const ValueText: ChakraComponent<"span">;
export const ClearTrigger: ChakraComponent<"button">;
export const Indicator: ChakraComponent<"div">;
export const IndicatorGroup: ChakraComponent<"div">;
export const Positioner: ChakraComponent<"div">;
export const Content: ChakraComponent<"div">;
export const ItemGroup: ChakraComponent<"div">;
export const ItemGroupLabel: ChakraComponent<"div">;
export const Item: React.FC<{ value: string; disabled?: boolean; children: React.ReactNode }>;
export const ItemText: ChakraComponent<"span">;
export const ItemIndicator: ChakraComponent<"div">;
export const Label: ChakraComponent<"label">;
export const HiddenSelect: React.FC;
}Native HTML select element with Chakra styling.
import { NativeSelect, useNativeSelectStyles } from "@chakra-ui/react";
namespace NativeSelect {
export const Root: ChakraComponent<"div">;
export const Field: ChakraComponent<"select">;
export const Indicator: ChakraComponent<"div">;
}Range slider input for numeric values.
import { Slider, useSlider, useSliderContext } from "@chakra-ui/react";
interface SliderRootProps {
name?: string;
value?: number[];
defaultValue?: number[];
min?: number;
max?: number;
step?: number;
minStepsBetweenThumbs?: number;
disabled?: boolean;
invalid?: boolean;
readOnly?: boolean;
orientation?: "horizontal" | "vertical";
onValueChange?: (details: { value: number[] }) => void;
onValueChangeEnd?: (details: { value: number[] }) => void;
children?: React.ReactNode;
}
namespace Slider {
export const Root: React.FC<SliderRootProps>;
export const RootProvider: React.FC<SliderRootProps>;
export const Control: ChakraComponent<"div">;
export const Track: ChakraComponent<"div">;
export const Range: ChakraComponent<"div">;
export const Thumb: React.FC<{ index: number; children?: React.ReactNode }>;
export const ValueText: ChakraComponent<"div">;
export const Marker: React.FC<{ value: number; children?: React.ReactNode }>;
export const MarkerGroup: ChakraComponent<"div">;
export const MarkerIndicator: ChakraComponent<"div">;
export const Label: ChakraComponent<"label">;
export const DraggingIndicator: ChakraComponent<"div">;
export const HiddenInput: React.FC<{ index: number }>;
}Numeric input with increment/decrement controls.
import { NumberInput, useNumberInput, useNumberInputContext } from "@chakra-ui/react";
interface NumberInputRootProps {
name?: string;
value?: string;
defaultValue?: string;
min?: number;
max?: number;
step?: number;
disabled?: boolean;
invalid?: boolean;
readOnly?: boolean;
allowMouseWheel?: boolean;
clampValueOnBlur?: boolean;
formatOptions?: Intl.NumberFormatOptions;
onValueChange?: (details: { value: string; valueAsNumber: number }) => void;
children?: React.ReactNode;
}
namespace NumberInput {
export const Root: React.FC<NumberInputRootProps>;
export const RootProvider: React.FC<NumberInputRootProps>;
export const Control: ChakraComponent<"div">;
export const Input: ChakraComponent<"input">;
export const IncrementTrigger: ChakraComponent<"button">;
export const DecrementTrigger: ChakraComponent<"button">;
export const Scrubber: ChakraComponent<"div">;
export const ValueText: ChakraComponent<"div">;
export const Label: ChakraComponent<"label">;
}PIN/OTP input fields for codes.
import { PinInput, usePinInput, usePinInputContext } from "@chakra-ui/react";
interface PinInputRootProps {
name?: string;
value?: string[];
defaultValue?: string[];
type?: "alphanumeric" | "numeric" | "alphabetic";
mask?: boolean;
otp?: boolean;
placeholder?: string;
disabled?: boolean;
invalid?: boolean;
readOnly?: boolean;
onValueChange?: (details: { value: string[]; valueAsString: string }) => void;
onValueComplete?: (details: { value: string[]; valueAsString: string }) => void;
children?: React.ReactNode;
}
namespace PinInput {
export const Root: React.FC<PinInputRootProps>;
export const RootProvider: React.FC<PinInputRootProps>;
export const Control: ChakraComponent<"div">;
export const Input: React.FC<{ index: number }>;
export const Label: ChakraComponent<"label">;
export const HiddenInput: React.FC;
}Inline editable text field.
import { Editable, useEditable, useEditableContext } from "@chakra-ui/react";
interface EditableRootProps {
name?: string;
value?: string;
defaultValue?: string;
placeholder?: string;
disabled?: boolean;
invalid?: boolean;
readOnly?: boolean;
autoResize?: boolean;
activationMode?: "focus" | "dblclick" | "none";
selectOnFocus?: boolean;
submitMode?: "enter" | "blur" | "both" | "none";
onValueChange?: (details: { value: string }) => void;
onEdit?: () => void;
onCancel?: (details: { value: string }) => void;
onSubmit?: (details: { value: string }) => void;
children?: React.ReactNode;
}
namespace Editable {
export const Root: React.FC<EditableRootProps>;
export const RootProvider: React.FC<EditableRootProps>;
export const Area: ChakraComponent<"div">;
export const Preview: ChakraComponent<"span">;
export const Input: ChakraComponent<"input">;
export const Textarea: ChakraComponent<"textarea">;
export const Control: ChakraComponent<"div">;
export const EditTrigger: ChakraComponent<"button">;
export const SubmitTrigger: ChakraComponent<"button">;
export const CancelTrigger: ChakraComponent<"button">;
}Form field wrappers with labels, help text, and error messages.
import { Field, Fieldset } from "@chakra-ui/react";
// Field
namespace Field {
export const Root: ChakraComponent<"div", {
invalid?: boolean;
disabled?: boolean;
required?: boolean;
readOnly?: boolean;
}>;
export const Label: ChakraComponent<"label">;
export const HelperText: ChakraComponent<"div">;
export const ErrorText: ChakraComponent<"div">;
export const ErrorIcon: ChakraComponent<"svg">;
export const RequiredIndicator: ChakraComponent<"span">;
}
// Fieldset
namespace Fieldset {
export const Root: ChakraComponent<"fieldset", {
invalid?: boolean;
disabled?: boolean;
}>;
export const Legend: ChakraComponent<"legend">;
export const HelperText: ChakraComponent<"div">;
export const ErrorText: ChakraComponent<"div">;
export const Content: ChakraComponent<"div">;
}File upload component with drag-and-drop support.
import { FileUpload, useFileUpload, useFileUploadContext } from "@chakra-ui/react";
interface FileUploadRootProps {
name?: string;
accept?: string | Record<string, string[]>;
multiple?: boolean;
maxFiles?: number;
maxFileSize?: number;
minFileSize?: number;
disabled?: boolean;
invalid?: boolean;
readOnly?: boolean;
allowDrop?: boolean;
onFileChange?: (details: { acceptedFiles: File[] }) => void;
onFileReject?: (details: { rejectedFiles: File[] }) => void;
children?: React.ReactNode;
}
namespace FileUpload {
export const Root: React.FC<FileUploadRootProps>;
export const RootProvider: React.FC<FileUploadRootProps>;
export const Dropzone: ChakraComponent<"div">;
export const DropzoneContent: ChakraComponent<"div">;
export const Trigger: ChakraComponent<"button">;
export const Label: ChakraComponent<"label">;
export const ItemGroup: ChakraComponent<"ul">;
export const Item: React.FC<{ file: File; children?: React.ReactNode }>;
export const ItemContent: ChakraComponent<"div">;
export const ItemName: ChakraComponent<"div">;
export const ItemSizeText: ChakraComponent<"div">;
export const ItemPreview: ChakraComponent<"div">;
export const ItemPreviewImage: ChakraComponent<"img">;
export const ItemDeleteTrigger: ChakraComponent<"button">;
export const ClearTrigger: ChakraComponent<"button">;
export const HiddenInput: React.FC;
}interface UseCheckboxProps {
checked?: boolean;
defaultChecked?: boolean;
disabled?: boolean;
required?: boolean;
invalid?: boolean;
readOnly?: boolean;
name?: string;
value?: string;
onCheckedChange?: (details: CheckboxCheckedChangeDetails) => void;
}
interface UseCheckboxReturn {
checked: boolean | "indeterminate";
focused: boolean;
disabled: boolean;
getInputProps: () => any;
getLabelProps: () => any;
getControlProps: () => any;
}
interface PositioningOptions {
placement?: Placement;
strategy?: "absolute" | "fixed";
offset?: { mainAxis?: number; crossAxis?: number };
flip?: boolean;
slide?: boolean;
}
type Placement =
| "top"
| "top-start"
| "top-end"
| "bottom"
| "bottom-start"
| "bottom-end"
| "left"
| "left-start"
| "left-end"
| "right"
| "right-start"
| "right-end";