CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-nextui-org--react

Beautiful and modern React UI library with comprehensive components, theming, and accessibility support.

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

inputs.mddocs/

Input Components

NextUI provides a comprehensive set of form input components with built-in validation, accessibility support, and consistent styling across different input types.

Capabilities

Input

A versatile text input component with support for labels, validation, helper text, and various visual states.

interface InputProps {
  /** Input content and elements */
  children?: React.ReactNode;
  /** Input label */
  label?: React.ReactNode;
  /** Current input value */
  value?: string;
  /** Default value for uncontrolled mode */
  defaultValue?: string;
  /** Placeholder text */
  placeholder?: string;
  /** Helper description text */
  description?: React.ReactNode;
  /** Error message content */
  errorMessage?: React.ReactNode | ((v: ValidationResult) => React.ReactNode);
  /** Validation function */
  validate?: (value: string) => ValidationError | true | null | undefined;
  /** Validation behavior */
  validationBehavior?: "aria" | "native";
  /** Validation state */
  validationState?: "valid" | "invalid";
  /** Whether input is required */
  isRequired?: boolean;
  /** Whether input is read-only */
  isReadOnly?: boolean;
  /** Whether input is disabled */
  isDisabled?: boolean;
  /** Whether input is invalid */
  isInvalid?: boolean;
  /** Base container ref */
  baseRef?: React.RefObject<HTMLDivElement>;
  /** Whether to show helper content */
  hasHelper?: boolean;
  /** Input size variant */
  size?: "sm" | "md" | "lg";
  /** Border radius */
  radius?: "none" | "sm" | "md" | "lg" | "full";
  /** Visual variant */
  variant?: "flat" | "bordered" | "underlined" | "faded";
  /** Color theme */
  color?: "default" | "primary" | "secondary" | "success" | "warning" | "danger";
  /** Label placement */
  labelPlacement?: "inside" | "outside" | "outside-left";
  /** Whether input takes full width */
  fullWidth?: boolean;
  /** Whether to show clear button */
  isClearable?: boolean;
  /** Disable animations */
  disableAnimation?: boolean;
  /** Input type */
  type?: "text" | "email" | "password" | "search" | "tel" | "url" | "number";
  /** Start content (icon, etc.) */
  startContent?: React.ReactNode;
  /** End content (icon, button, etc.) */
  endContent?: React.ReactNode;
  /** Custom CSS class */
  className?: string;
  /** Slot-based styling */
  classNames?: SlotsToClasses<InputSlots>;
  /** Value change handler */
  onValueChange?: (value: string) => void;
  /** Clear button press handler */
  onClear?: () => void;
}

type InputSlots = 
  | "base" | "mainWrapper" | "inputWrapper" | "innerWrapper"
  | "input" | "clearButton" | "label" | "description" 
  | "errorMessage" | "helperWrapper";

function Input(props: InputProps): JSX.Element;

/**
 * Hook for Input state management
 */
function useInput(props: InputProps): {
  Component: React.ElementType;
  label?: React.ReactNode;
  description?: React.ReactNode;
  errorMessage?: React.ReactNode;
  isInvalid: boolean;
  validationErrors: string[];
  validationDetails: ValidationDetails;
  slots: Record<InputSlots, string>;
  classNames: SlotsToClasses<InputSlots>;
  getBaseProps: () => any;
  getLabelProps: () => any;
  getInputProps: () => any;
  getInputWrapperProps: () => any;
  getInnerWrapperProps: () => any;
  getMainWrapperProps: () => any;
  getClearButtonProps: () => any;
  getDescriptionProps: () => any;
  getErrorMessageProps: () => any;
};

Input Usage Examples:

import { Input } from "@nextui-org/react";
import { SearchIcon, EyeFilledIcon, EyeSlashFilledIcon } from "@heroicons/react/24/solid";

function InputExamples() {
  const [isVisible, setIsVisible] = useState(false);
  const [value, setValue] = useState("");

  const toggleVisibility = () => setIsVisible(!isVisible);

  const validateEmail = (value: string) => {
    return value.match(/^[A-Z0-9._%+-]+@[A-Z0-9.-]+.[A-Z]{2,4}$/i);
  };

  const isInvalid = useMemo(() => {
    if (value === "") return false;
    return validateEmail(value) ? false : true;
  }, [value]);

  return (
    <div className="space-y-4">
      {/* Basic input */}
      <Input
        type="text"
        label="Name"
        placeholder="Enter your name"
        labelPlacement="outside"
      />

      {/* Email input with validation */}
      <Input
        value={value}
        onValueChange={setValue}
        isInvalid={isInvalid}
        label="Email"
        variant="bordered"
        placeholder="Enter your email"
        description="We'll never share your email with anyone else."
        errorMessage={isInvalid && "Please enter a valid email"}
        color={isInvalid ? "danger" : "success"}
        className="max-w-xs"
      />

      {/* Password input with toggle visibility */}
      <Input
        label="Password"
        variant="bordered"
        placeholder="Enter your password"
        endContent={
          <button className="focus:outline-none" type="button" onClick={toggleVisibility}>
            {isVisible ? (
              <EyeSlashFilledIcon className="text-2xl text-default-400 pointer-events-none" />
            ) : (
              <EyeFilledIcon className="text-2xl text-default-400 pointer-events-none" />
            )}
          </button>
        }
        type={isVisible ? "text" : "password"}
        className="max-w-xs"
      />

      {/* Search input with icon */}
      <Input
        label="Search"
        isClearable
        radius="lg"
        placeholder="Type to search..."
        startContent={
          <SearchIcon className="text-black/50 mb-0.5 dark:text-white/90 text-slate-400 pointer-events-none flex-shrink-0" />
        }
      />
    </div>
  );
}

Textarea

Multi-line text input component with automatic resizing and validation support.

interface TextAreaProps {
  /** Textarea content */
  children?: React.ReactNode;
  /** Textarea label */
  label?: React.ReactNode;
  /** Current textarea value */
  value?: string;
  /** Default value for uncontrolled mode */
  defaultValue?: string;
  /** Placeholder text */
  placeholder?: string;
  /** Helper description text */
  description?: React.ReactNode;
  /** Error message content */
  errorMessage?: React.ReactNode | ((v: ValidationResult) => React.ReactNode);
  /** Validation function */
  validate?: (value: string) => ValidationError | true | null | undefined;
  /** Validation behavior */
  validationBehavior?: "aria" | "native";
  /** Validation state */
  validationState?: "valid" | "invalid";
  /** Whether textarea is required */
  isRequired?: boolean;
  /** Whether textarea is read-only */
  isReadOnly?: boolean;
  /** Whether textarea is disabled */
  isDisabled?: boolean;
  /** Whether textarea is invalid */
  isInvalid?: boolean;
  /** Textarea size variant */
  size?: "sm" | "md" | "lg";
  /** Border radius */
  radius?: "none" | "sm" | "md" | "lg" | "full";
  /** Visual variant */
  variant?: "flat" | "bordered" | "underlined" | "faded";
  /** Color theme */
  color?: "default" | "primary" | "secondary" | "success" | "warning" | "danger";
  /** Label placement */
  labelPlacement?: "inside" | "outside" | "outside-left";
  /** Whether textarea takes full width */
  fullWidth?: boolean;
  /** Disable animations */
  disableAnimation?: boolean;
  /** Minimum number of rows */
  minRows?: number;
  /** Maximum number of rows */
  maxRows?: number;
  /** Whether to cache height for performance */
  cacheMeasurements?: boolean;
  /** Custom CSS class */
  className?: string;
  /** Slot-based styling */
  classNames?: SlotsToClasses<InputSlots>;
  /** Value change handler */
  onValueChange?: (value: string) => void;
}

function Textarea(props: TextAreaProps): JSX.Element;

Textarea Usage Example:

import { Textarea } from "@nextui-org/react";

function TextareaExample() {
  return (
    <div className="space-y-4">
      <Textarea
        label="Description"
        placeholder="Enter your description"
        description="Provide a detailed description of your project"
        className="max-w-xs"
      />

      <Textarea
        isRequired
        label="Feedback"
        labelPlacement="outside"
        placeholder="Share your feedback..."
        variant="bordered"
        minRows={3}
        maxRows={8}
        className="max-w-lg"
      />
    </div>
  );
}

Select

Dropdown selection component with search, multiple selection, and custom item rendering support.

interface SelectProps<T = object> {
  /** Select content and options */
  children?: React.ReactNode;
  /** Data items for dynamic rendering */
  items?: Iterable<T>;
  /** Select label */
  label?: React.ReactNode;
  /** Placeholder text when no selection */
  placeholder?: string;
  /** Helper description text */
  description?: React.ReactNode;
  /** Error message content */
  errorMessage?: React.ReactNode | ((v: ValidationResult) => React.ReactNode);
  /** Validation function */
  validate?: (value: SelectValue<T>) => ValidationError | true | null | undefined;
  /** Selection mode */
  selectionMode?: "single" | "multiple";
  /** Currently selected keys */
  selectedKeys?: "all" | Iterable<React.Key>;
  /** Default selected keys for uncontrolled mode */
  defaultSelectedKeys?: "all" | Iterable<React.Key>;
  /** Prevent empty selection */
  disallowEmptySelection?: boolean;
  /** Whether popover should flip to fit */
  shouldFlip?: boolean;
  /** Whether select is required */
  isRequired?: boolean;
  /** Whether select is invalid */
  isInvalid?: boolean;
  /** Whether select is disabled */
  isDisabled?: boolean;
  /** Whether select is in loading state */
  isLoading?: boolean;
  /** Select size variant */
  size?: "sm" | "md" | "lg";
  /** Border radius */
  radius?: "none" | "sm" | "md" | "lg" | "full";
  /** Visual variant */
  variant?: "flat" | "bordered" | "underlined" | "faded";
  /** Color theme */
  color?: "default" | "primary" | "secondary" | "success" | "warning" | "danger";
  /** Label placement */
  labelPlacement?: "inside" | "outside" | "outside-left";
  /** Whether select takes full width */
  fullWidth?: boolean;
  /** Popover placement */
  placement?: Placement;
  /** Start content (icon, etc.) */
  startContent?: React.ReactNode;
  /** End content (icon, button, etc.) */
  endContent?: React.ReactNode;
  /** Selector icon (dropdown arrow) */
  selectorIcon?: React.ReactNode;
  /** Disable animations */
  disableAnimation?: boolean;
  /** Disable selector icon animation */
  disableSelectorIconRotation?: boolean;
  /** Custom scroll reference */
  scrollRef?: React.RefObject<HTMLElement>;
  /** Listbox props */
  listboxProps?: Partial<ListboxProps>;
  /** Popover props */
  popoverProps?: Partial<PopoverProps>;
  /** Spinner props for loading state */
  spinnerProps?: Partial<SpinnerProps>;
  /** Custom CSS class */
  className?: string;
  /** Slot-based styling */
  classNames?: SlotsToClasses<SelectSlots>;
  /** Selection change handler */
  onSelectionChange?: (keys: Selection) => void;
  /** Open state change handler */
  onOpenChange?: (isOpen: boolean) => void;
  /** Close handler */
  onClose?: () => void;
}

type SelectSlots = 
  | "base" | "label" | "trigger" | "innerWrapper" | "selectorIcon"
  | "value" | "listboxWrapper" | "listbox" | "popoverContent"
  | "helperWrapper" | "description" | "errorMessage";

type SelectValue<T> = T | null | undefined;

function Select<T = object>(props: SelectProps<T>): JSX.Element;

/**
 * Hook for Select state management
 */
function useSelect<T = object>(props: UseSelectProps<T>): {
  Component: React.ElementType;
  state: SelectState<T>;
  slots: Record<SelectSlots, string>;
  classNames: SlotsToClasses<SelectSlots>;
  isOpen: boolean;
  isLoading?: boolean;
  getSelectProps: () => any;
  getTriggerProps: () => any;
  getValueProps: () => any;
  getListboxProps: () => any;
  getPopoverProps: () => any;
};

interface UseSelectProps<T> extends Omit<SelectProps<T>, 'children'> {
  /** Trigger ref */
  triggerRef?: React.RefObject<HTMLElement>;
  /** Value ref */
  valueRef?: React.RefObject<HTMLElement>;
  /** Listbox ref */
  listboxRef?: React.RefObject<HTMLElement>;
  /** Popover ref */
  popoverRef?: React.RefObject<HTMLDivElement>;
}

Select Items

Components for defining select options and sections.

// SelectItem is an alias for ListboxItem
interface SelectItemProps {
  /** Item key identifier */
  key?: React.Key;
  /** Item text content */
  children?: React.ReactNode;
  /** Item text value for controlled components */
  textValue?: string;
  /** Whether item is disabled */
  isDisabled?: boolean;
  /** Whether to hide selected indicator */
  hideSelectedIcon?: boolean;
  /** Item start content (icon, avatar, etc.) */
  startContent?: React.ReactNode;
  /** Item end content (icon, badge, etc.) */
  endContent?: React.ReactNode;
  /** Item description text */
  description?: React.ReactNode;
  /** Custom CSS class */
  className?: string;
  /** Slot-based styling */
  classNames?: SlotsToClasses<ListboxItemSlots>;
}

// SelectSection is an alias for ListboxSection  
interface SelectSectionProps {
  /** Section title */
  title?: React.ReactNode;
  /** Section items */
  children?: React.ReactNode;
  /** Whether to hide divider */
  hideDivider?: boolean;
  /** Whether to show divider */
  showDivider?: boolean;
  /** Divider props */
  dividerProps?: DividerProps;
  /** Item heading */
  heading?: React.ReactNode;
  /** Custom CSS class */
  className?: string;
  /** Slot-based styling */
  classNames?: SlotsToClasses<ListboxSectionSlots>;
}

const SelectItem: React.FC<SelectItemProps>;
const SelectSection: React.FC<SelectSectionProps>;

Select Usage Examples:

import { Select, SelectItem, SelectSection } from "@nextui-org/react";

function SelectExamples() {
  const animals = [
    {key: "cat", label: "Cat"},
    {key: "dog", label: "Dog"},
    {key: "elephant", label: "Elephant"},
    {key: "lion", label: "Lion"},
    {key: "tiger", label: "Tiger"},
  ];

  const [selectedValue, setSelectedValue] = useState(new Set(["cat"]));

  return (
    <div className="space-y-4">
      {/* Basic select */}
      <Select 
        label="Favorite Animal" 
        placeholder="Select an animal"
        className="max-w-xs"
      >
        {animals.map((animal) => (
          <SelectItem key={animal.key}>
            {animal.label}
          </SelectItem>
        ))}
      </Select>

      {/* Multiple selection */}
      <Select
        label="Animals"
        selectionMode="multiple"
        placeholder="Select animals"
        selectedKeys={selectedValue}
        onSelectionChange={setSelectedValue}
        className="max-w-xs"
      >
        {animals.map((animal) => (
          <SelectItem key={animal.key}>
            {animal.label}
          </SelectItem>
        ))}
      </Select>

      {/* Select with sections */}
      <Select 
        label="Pets by category"
        placeholder="Select a pet"
        className="max-w-xs"
      >
        <SelectSection title="Mammals">
          <SelectItem key="cat">Cat</SelectItem>
          <SelectItem key="dog">Dog</SelectItem>
        </SelectSection>
        <SelectSection title="Birds">
          <SelectItem key="parrot">Parrot</SelectItem>
          <SelectItem key="canary">Canary</SelectItem>
        </SelectSection>
      </Select>

      {/* Dynamic items */}
      <Select
        items={animals}
        label="Dynamic Animals"
        placeholder="Select an animal"
        className="max-w-xs"
      >
        {(item) => <SelectItem key={item.key}>{item.label}</SelectItem>}
      </Select>
    </div>
  );
}

Checkbox

Individual checkbox component with indeterminate state support and custom styling.

interface CheckboxProps {
  /** Checkbox label content */
  children?: React.ReactNode;
  /** Checkbox value */
  value?: string;
  /** Whether checkbox is selected */
  isSelected?: boolean;
  /** Default selection state */
  defaultSelected?: boolean;
  /** Whether checkbox is indeterminate */
  isIndeterminate?: boolean;
  /** Whether checkbox is required */
  isRequired?: boolean;
  /** Whether checkbox is read-only */
  isReadOnly?: boolean;
  /** Whether checkbox is disabled */
  isDisabled?: boolean;
  /** Whether checkbox is invalid */
  isInvalid?: boolean;
  /** Validation state */
  validationState?: "valid" | "invalid";
  /** Checkbox size */
  size?: "sm" | "md" | "lg";
  /** Color theme */
  color?: "default" | "primary" | "secondary" | "success" | "warning" | "danger";
  /** Border radius */
  radius?: "none" | "sm" | "md" | "lg" | "full";
  /** Line through text when selected */
  lineThrough?: boolean;
  /** Disable animations */
  disableAnimation?: boolean;
  /** Custom icon for checkbox */
  icon?: React.ReactNode | ((props: CheckboxIconProps) => React.ReactNode);
  /** Custom CSS class */
  className?: string;
  /** Slot-based styling */
  classNames?: SlotsToClasses<CheckboxSlots>;
  /** Selection change handler */
  onValueChange?: (isSelected: boolean) => void;
}

type CheckboxSlots = "base" | "wrapper" | "icon" | "label";

function Checkbox(props: CheckboxProps): JSX.Element;

/**
 * Hook for Checkbox state management
 */
function useCheckbox(props: CheckboxProps): {
  Component: React.ElementType;
  slots: Record<CheckboxSlots, string>;
  classNames: SlotsToClasses<CheckboxSlots>;
  isSelected: boolean;
  isPressed: boolean;
  isFocused: boolean;
  isInvalid: boolean;
  getBaseProps: () => any;
  getWrapperProps: () => any;
  getInputProps: () => any;
  getLabelProps: () => any;
  getIconProps: () => any;
};

Checkbox Icon

Customizable icon component for checkbox states.

interface CheckboxIconProps {
  /** Icon data attributes */
  "data-checked"?: string;
  /** Whether checkbox is selected */
  isSelected?: boolean;
  /** Whether checkbox is indeterminate */
  isIndeterminate?: boolean;
  /** Disable animations */
  disableAnimation?: boolean;
  /** Custom CSS class */
  className?: string;
}

function CheckboxIcon(props: CheckboxIconProps): JSX.Element;

Checkbox Group

Container for managing groups of related checkboxes with shared state and validation.

interface CheckboxGroupProps {
  /** Group label */
  label?: React.ReactNode;
  /** Checkbox items */
  children?: React.ReactNode;
  /** Currently selected values */
  value?: string[];
  /** Default selected values */
  defaultValue?: string[];
  /** Group name attribute */
  name?: string;
  /** Group size */
  size?: "sm" | "md" | "lg";
  /** Color theme */
  color?: "default" | "primary" | "secondary" | "success" | "warning" | "danger";
  /** Border radius for all checkboxes */
  radius?: "none" | "sm" | "md" | "lg" | "full";
  /** Group orientation */
  orientation?: "horizontal" | "vertical";
  /** Whether group is required */
  isRequired?: boolean;
  /** Whether group is read-only */
  isReadOnly?: boolean;
  /** Whether group is disabled */
  isDisabled?: boolean;
  /** Whether group is invalid */
  isInvalid?: boolean;
  /** Validation state */
  validationState?: "valid" | "invalid";
  /** Helper description text */
  description?: React.ReactNode;
  /** Error message content */
  errorMessage?: React.ReactNode;
  /** Disable animations */
  disableAnimation?: boolean;
  /** Custom CSS class */
  className?: string;
  /** Slot-based styling */
  classNames?: SlotsToClasses<CheckboxGroupSlots>;
  /** Value change handler */
  onValueChange?: (value: string[]) => void;
}

type CheckboxGroupSlots = "base" | "label" | "wrapper" | "description" | "errorMessage";

function CheckboxGroup(props: CheckboxGroupProps): JSX.Element;

/**
 * Hook for CheckboxGroup state management
 */
function useCheckboxGroup(props: CheckboxGroupProps): {
  Component: React.ElementType;
  slots: Record<CheckboxGroupSlots, string>;
  classNames: SlotsToClasses<CheckboxGroupSlots>;
  groupState: CheckboxGroupState;
  getGroupProps: () => any;
  getLabelProps: () => any;
  getWrapperProps: () => any;
  getDescriptionProps: () => any;
  getErrorMessageProps: () => any;
};

Checkbox Usage Examples:

import { Checkbox, CheckboxGroup } from "@nextui-org/react";

function CheckboxExamples() {
  const [selected, setSelected] = useState(["argentina"]);

  return (
    <div className="space-y-6">
      {/* Individual checkboxes */}
      <div className="space-y-2">
        <Checkbox defaultSelected>Option 1</Checkbox>
        <Checkbox isIndeterminate>Option 2</Checkbox>
        <Checkbox isDisabled>Option 3</Checkbox>
      </div>

      {/* Checkbox group */}
      <CheckboxGroup
        label="Select countries"
        color="secondary"
        value={selected}
        onValueChange={setSelected}
        description="Choose your favorite countries"
      >
        <Checkbox value="argentina">Argentina</Checkbox>
        <Checkbox value="venezuela">Venezuela</Checkbox>
        <Checkbox value="brazil">Brazil</Checkbox>
        <Checkbox value="colombia">Colombia</Checkbox>
      </CheckboxGroup>

      {/* Custom icon checkbox */}
      <Checkbox
        icon={<HeartIcon />}
        color="danger"
        defaultSelected
      >
        Add to favorites
      </Checkbox>
    </div>
  );
}

Checkbox Group Context

Context system for sharing checkbox group state.

interface CheckboxGroupProviderProps {
  children: React.ReactNode;
  value: CheckboxGroupContextValue;
}

interface CheckboxGroupContextValue {
  groupState: CheckboxGroupState;
  size?: "sm" | "md" | "lg";
  color?: "default" | "primary" | "secondary" | "success" | "warning" | "danger";
  radius?: "none" | "sm" | "md" | "lg" | "full";
  isInvalid?: boolean;
  isReadOnly?: boolean;
  isDisabled?: boolean;
  disableAnimation?: boolean;
}

const CheckboxGroupProvider: React.FC<CheckboxGroupProviderProps>;

/**
 * Hook to access checkbox group context
 * @throws Error if used outside CheckboxGroupProvider
 */
function useCheckboxGroupContext(): CheckboxGroupContextValue | undefined;

Radio

Individual radio button component for single selection within groups.

interface RadioProps {
  /** Radio label content */
  children?: React.ReactNode;
  /** Radio value */
  value: string;
  /** Radio size */
  size?: "sm" | "md" | "lg";
  /** Color theme */
  color?: "default" | "primary" | "secondary" | "success" | "warning" | "danger";
  /** Whether radio is disabled */
  isDisabled?: boolean;
  /** Whether radio is invalid */
  isInvalid?: boolean;
  /** Custom description */
  description?: React.ReactNode;
  /** Disable animations */
  disableAnimation?: boolean;
  /** Custom CSS class */
  className?: string;
  /** Slot-based styling */
  classNames?: SlotsToClasses<RadioSlots>;
}

type RadioSlots = "base" | "wrapper" | "labelWrapper" | "control" | "label" | "description";

function Radio(props: RadioProps): JSX.Element;

/**
 * Hook for Radio state management
 */
function useRadio(props: RadioProps): {
  Component: React.ElementType;
  slots: Record<RadioSlots, string>;
  classNames: SlotsToClasses<RadioSlots>;
  isSelected: boolean;
  isPressed: boolean;
  isFocused: boolean;
  isInvalid: boolean;
  getBaseProps: () => any;
  getWrapperProps: () => any;
  getInputProps: () => any;
  getLabelWrapperProps: () => any;
  getLabelProps: () => any;
  getControlProps: () => any;
  getDescriptionProps: () => any;
};

Radio Group

Container for managing groups of radio buttons with single selection state.

interface RadioGroupProps {
  /** Group label */
  label?: React.ReactNode;
  /** Radio items */
  children?: React.ReactNode;
  /** Currently selected value */
  value?: string;
  /** Default selected value */
  defaultValue?: string;
  /** Group name attribute */
  name?: string;
  /** Group size */
  size?: "sm" | "md" | "lg";
  /** Color theme */
  color?: "default" | "primary" | "secondary" | "success" | "warning" | "danger";
  /** Group orientation */
  orientation?: "horizontal" | "vertical";
  /** Whether group is required */
  isRequired?: boolean;
  /** Whether group is read-only */
  isReadOnly?: boolean;
  /** Whether group is disabled */
  isDisabled?: boolean;
  /** Whether group is invalid */
  isInvalid?: boolean;
  /** Validation state */
  validationState?: "valid" | "invalid";
  /** Helper description text */
  description?: React.ReactNode;
  /** Error message content */
  errorMessage?: React.ReactNode;
  /** Disable animations */
  disableAnimation?: boolean;
  /** Custom CSS class */
  className?: string;
  /** Slot-based styling */
  classNames?: SlotsToClasses<RadioGroupSlots>;
  /** Value change handler */
  onValueChange?: (value: string) => void;
}

type RadioGroupSlots = "base" | "label" | "wrapper" | "description" | "errorMessage";

function RadioGroup(props: RadioGroupProps): JSX.Element;

/**
 * Hook for RadioGroup state management
 */
function useRadioGroup(props: RadioGroupProps): {
  Component: React.ElementType;
  slots: Record<RadioGroupSlots, string>;
  classNames: SlotsToClasses<RadioGroupSlots>;
  groupState: RadioGroupState;
  getGroupProps: () => any;
  getLabelProps: () => any;
  getWrapperProps: () => any;
  getDescriptionProps: () => any;
  getErrorMessageProps: () => any;
};

Radio Usage Example:

import { RadioGroup, Radio } from "@nextui-org/react";

function RadioExample() {
  const [selected, setSelected] = useState("london");

  return (
    <RadioGroup
      label="Select your favorite city"
      value={selected}
      onValueChange={setSelected}
      orientation="horizontal"
    >
      <Radio value="buenos-aires">Buenos Aires</Radio>
      <Radio value="sydney">Sydney</Radio>
      <Radio value="san-francisco">San Francisco</Radio>
      <Radio value="london">London</Radio>
      <Radio value="tokyo">Tokyo</Radio>
    </RadioGroup>
  );
}

Switch

Toggle switch component for boolean states with customizable appearance and behavior.

interface SwitchProps {
  /** Switch label content */
  children?: React.ReactNode;
  /** Whether switch is selected */
  isSelected?: boolean;
  /** Default selection state */
  defaultSelected?: boolean;
  /** Switch value */
  value?: string;
  /** Switch name attribute */
  name?: string;
  /** Switch size */
  size?: "sm" | "md" | "lg";
  /** Color theme */
  color?: "default" | "primary" | "secondary" | "success" | "warning" | "danger";
  /** Custom start content */
  startContent?: React.ReactNode;
  /** Custom end content */
  endContent?: React.ReactNode;
  /** Custom thumb icon */
  thumbIcon?: React.ReactNode | ((props: SwitchThumbIconProps) => React.ReactNode);
  /** Whether switch is required */
  isRequired?: boolean;
  /** Whether switch is read-only */
  isReadOnly?: boolean;
  /** Whether switch is disabled */
  isDisabled?: boolean;
  /** Disable animations */
  disableAnimation?: boolean;
  /** Custom CSS class */
  className?: string;
  /** Slot-based styling */
  classNames?: SlotsToClasses<SwitchSlots>;
  /** Selection change handler */
  onValueChange?: (isSelected: boolean) => void;
}

type SwitchSlots = 
  | "base" | "wrapper" | "thumb" | "startContent" 
  | "endContent" | "thumbIcon" | "label";

interface SwitchThumbIconProps {
  /** Icon data attributes */
  "data-selected"?: string;
  /** Whether switch is selected */
  isSelected?: boolean;
  /** Custom CSS class */
  className?: string;
}

function Switch(props: SwitchProps): JSX.Element;

/**
 * Hook for Switch state management
 */
function useSwitch(props: SwitchProps): {
  Component: React.ElementType;
  slots: Record<SwitchSlots, string>;
  classNames: SlotsToClasses<SwitchSlots>;
  isSelected: boolean;
  isPressed: boolean;
  isFocused: boolean;
  getBaseProps: () => any;
  getWrapperProps: () => any;
  getInputProps: () => any;
  getLabelProps: () => any;
  getThumbProps: () => any;
  getStartContentProps: () => any;
  getEndContentProps: () => any;
  getThumbIconProps: () => any;
};

Switch Usage Examples:

import { Switch } from "@nextui-org/react";
import { MoonIcon, SunIcon } from "@heroicons/react/24/solid";

function SwitchExamples() {
  return (
    <div className="space-y-4">
      {/* Basic switch */}
      <Switch defaultSelected>Airplane mode</Switch>

      {/* Switch with icons */}
      <Switch
        defaultSelected
        size="lg"
        color="success"
        startContent={<SunIcon />}
        endContent={<MoonIcon />}
      >
        Dark mode
      </Switch>

      {/* Switch with custom thumb icon */}
      <Switch
        defaultSelected
        size="lg"
        color="secondary"
        thumbIcon={({ isSelected, className }) =>
          isSelected ? (
            <SunIcon className={className} />
          ) : (
            <MoonIcon className={className} />
          )
        }
      >
        Theme toggle
      </Switch>
    </div>
  );
}

Slider

Range slider component for selecting numeric values within a defined range.

interface SliderProps {
  /** Slider label */
  label?: React.ReactNode;
  /** Current slider value(s) */
  value?: SliderValue;
  /** Default value for uncontrolled mode */
  defaultValue?: SliderValue;
  /** Minimum value */
  minValue?: number;
  /** Maximum value */
  maxValue?: number;
  /** Step increment */
  step?: number;
  /** Format options for value display */
  formatOptions?: Intl.NumberFormatOptions;
  /** Slider size */
  size?: "sm" | "md" | "lg";
  /** Color theme */
  color?: "foreground" | "primary" | "secondary" | "success" | "warning" | "danger";
  /** Fill offset for range sliders */
  fillOffset?: number;
  /** Step marks configuration */
  marks?: SliderStepMark[];
  /** Whether to hide thumb labels */
  hideThumb?: boolean;
  /** Whether to hide value label */
  hideValue?: boolean;
  /** Show steps as marks */
  showSteps?: boolean;
  /** Show tooltip on hover/focus */
  showTooltip?: boolean;
  /** Show outline on focus */
  showOutline?: boolean;
  /** Disable thumb scale animation */
  disableThumbScale?: boolean;
  /** Whether slider is required */
  isRequired?: boolean;
  /** Whether slider is disabled */
  isDisabled?: boolean;
  /** Slider orientation */
  orientation?: "horizontal" | "vertical";
  /** Tooltip properties */
  tooltipProps?: Partial<TooltipProps>;
  /** Custom thumb renderer */
  renderThumb?: (props: SliderRenderThumbProps) => React.ReactNode;
  /** Custom label renderer */
  renderLabel?: (props: SliderRenderLabelProps) => React.ReactNode;
  /** Custom value renderer */
  renderValue?: (props: SliderRenderValueProps) => React.ReactNode;
  /** Custom CSS class */
  className?: string;
  /** Slot-based styling */
  classNames?: SlotsToClasses<SliderSlots>;
  /** Value change handler */
  onChange?: (value: SliderValue) => void;
  /** Value change end handler */
  onChangeEnd?: (value: SliderValue) => void;
}

type SliderValue = number | number[];

interface SliderStepMark {
  /** Step value */
  value: number;
  /** Step label */
  label?: React.ReactNode;
}

interface SliderRenderThumbProps {
  /** Thumb index for multi-thumb sliders */
  index?: number;
  /** Current value */
  value?: number;
  /** Value as percentage */
  valueLabel?: string;
  /** Whether thumb has focus */
  isFocused?: boolean;
  /** Whether thumb is being dragged */
  isDragging?: boolean;
  /** Whether slider is disabled */
  isDisabled?: boolean;
  /** Thumb props */
  getThumbProps: (props?: any) => any;
}

interface SliderRenderLabelProps {
  /** Current value(s) */
  value?: SliderValue;
  /** Formatted value text */
  valueLabel?: string;
  /** Whether slider has focus */
  isFocused?: boolean;
  /** Whether slider is disabled */
  isDisabled?: boolean;
}

interface SliderRenderValueProps extends SliderRenderLabelProps {}

type SliderSlots = 
  | "base" | "labelWrapper" | "label" | "value" | "trackWrapper"
  | "track" | "filler" | "thumb" | "mark" | "step";

function Slider(props: SliderProps): JSX.Element;

/**
 * Hook for Slider state management
 */
function useSlider(props: SliderProps): {
  Component: React.ElementType;
  slots: Record<SliderSlots, string>;
  classNames: SlotsToClasses<SliderSlots>;
  state: SliderState;
  getBaseProps: () => any;
  getLabelWrapperProps: () => any;
  getLabelProps: () => any;
  getValueProps: () => any;
  getTrackWrapperProps: () => any;
  getTrackProps: () => any;
  getFillerProps: () => any;
  getThumbProps: (index?: number) => any;
  getMarkProps: (mark: SliderStepMark, index: number) => any;
  getStepProps: (step: number, index: number) => any;
};

Slider Usage Examples:

import { Slider } from "@nextui-org/react";

function SliderExamples() {
  const [value, setValue] = useState(40);
  const [rangeValue, setRangeValue] = useState([100, 500]);

  return (
    <div className="space-y-8">
      {/* Basic slider */}
      <Slider
        label="Temperature"
        step={1}
        minValue={0}
        maxValue={100}
        value={value}
        onChange={setValue}
        className="max-w-md"
        formatOptions={{style: "unit", unit: "celsius"}}
      />

      {/* Range slider */}
      <Slider
        label="Price Range"
        step={50}
        minValue={0}
        maxValue={1000}
        value={rangeValue}
        onChange={setRangeValue}
        className="max-w-md"
        formatOptions={{style: "currency", currency: "USD"}}
      />

      {/* Slider with steps */}
      <Slider
        label="Volume"
        step={10}
        minValue={0}
        maxValue={100}
        defaultValue={30}
        showSteps
        showTooltip
        showOutline
        className="max-w-md"
        marks={[
          {value: 20, label: "20%"},
          {value: 50, label: "50%"},
          {value: 80, label: "80%"},
        ]}
      />
    </div>
  );
}

Textarea

A multi-line text input component with auto-resize capabilities and enhanced styling options.

interface TextAreaProps {
  /** Input label */
  label?: React.ReactNode;
  /** Current textarea value */
  value?: string;
  /** Default textarea value */
  defaultValue?: string;
  /** Input placeholder text */
  placeholder?: string;
  /** Helper description text */
  description?: React.ReactNode;
  /** Error message */
  errorMessage?: React.ReactNode | ((v: ValidationResult) => React.ReactNode);
  /** Validation function */
  validate?: (value: string) => ValidationError | true | null | undefined;
  /** Validation behavior */
  validationBehavior?: "aria" | "native";
  /** Whether textarea is required */
  isRequired?: boolean;
  /** Whether textarea is read-only */
  isReadOnly?: boolean;
  /** Whether textarea is disabled */
  isDisabled?: boolean;
  /** Whether textarea is invalid */
  isInvalid?: boolean;
  /** Auto focus on mount */
  autoFocus?: boolean;
  /** Textarea size */
  size?: "sm" | "md" | "lg";
  /** Border radius */
  radius?: "none" | "sm" | "md" | "lg" | "full";
  /** Visual variant */
  variant?: "flat" | "bordered" | "underlined" | "faded";
  /** Color theme */
  color?: "default" | "primary" | "secondary" | "success" | "warning" | "danger";
  /** Label placement */
  labelPlacement?: "inside" | "outside" | "outside-left";
  /** Whether textarea takes full width */
  fullWidth?: boolean;
  /** Minimum number of visible text lines */
  minRows?: number;
  /** Maximum number of visible text lines */
  maxRows?: number;
  /** Show clear button */
  isClearable?: boolean;
  /** Disable animations */
  disableAnimation?: boolean;
  /** Disable auto resize */
  disableAutosize?: boolean;
  /** Cached row height for performance */
  cacheMeasurements?: boolean;
  /** Custom CSS class */
  className?: string;
  /** Slot-based styling */
  classNames?: SlotsToClasses<InputSlots>;
  /** Value change handler */
  onValueChange?: (value: string) => void;
  /** Clear handler */
  onClear?: () => void;
}

function Textarea(props: TextAreaProps): JSX.Element;

Textarea Usage Examples:

import { Textarea, Button, Card, CardBody } from "@nextui-org/react";

function TextareaExamples() {
  const [value, setValue] = useState("");
  const [message, setMessage] = useState("");

  return (
    <Card className="max-w-lg">
      <CardBody className="space-y-4">
        {/* Basic textarea */}
        <Textarea
          label="Description" 
          placeholder="Enter your description"
          value={value}
          onValueChange={setValue}
        />

        {/* Textarea with validation */}
        <Textarea
          isRequired
          label="Message"
          placeholder="Write your message here..."
          description="Minimum 10 characters required"
          value={message}
          onValueChange={setMessage}
          minRows={3}
          maxRows={8}
          validate={(value) => {
            if (value.length < 10) {
              return "Message must be at least 10 characters long";
            }
            return true;
          }}
          errorMessage={(validation) => 
            validation.isInvalid ? validation.validationErrors[0] : undefined
          }
        />

        {/* Disabled auto-resize textarea */}
        <Textarea
          label="Fixed Size"
          placeholder="This textarea doesn't auto-resize"
          disableAutosize
          minRows={4}
          variant="bordered"
          color="secondary"
        />

        {/* Textarea with clear functionality */}
        <Textarea
          label="Clearable Content"
          placeholder="Type something and clear it"
          isClearable
          variant="underlined"
        />

        <Button 
          color="primary" 
          isDisabled={message.length < 10}
          className="w-full"
        >
          Submit Message
        </Button>
      </CardBody>
    </Card>
  );
}

Input OTP

A specialized input component for One-Time Password entry with individual character segments.

interface InputOTPProps {
  /** Number of OTP digits */
  length?: number;
  /** Current OTP value */
  value?: string;
  /** Default OTP value */
  defaultValue?: string;
  /** Input placeholder for each digit */
  placeholder?: string;
  /** Whether input is required */
  isRequired?: boolean;
  /** Whether input is disabled */
  isDisabled?: boolean;
  /** Whether input is invalid */
  isInvalid?: boolean;
  /** Input size */
  size?: "sm" | "md" | "lg";
  /** Border radius */
  radius?: "none" | "sm" | "md" | "lg" | "full";
  /** Visual variant */
  variant?: "flat" | "bordered" | "underlined" | "faded";
  /** Color theme */
  color?: "default" | "primary" | "secondary" | "success" | "warning" | "danger";
  /** Whether to allow only numeric input */
  allowedKeys?: RegExp;
  /** Custom CSS class */
  className?: string;
  /** Slot-based styling */
  classNames?: SlotsToClasses<InputOTPSlots>;
  /** Value change handler */
  onValueChange?: (value: string) => void;
  /** Complete handler (when all digits filled) */
  onComplete?: (value: string) => void;
}

type InputOTPSlots = "base" | "segmentWrapper" | "segment" | "helperWrapper";

function InputOTP(props: InputOTPProps): JSX.Element;

/**
 * Hook for InputOTP state management
 */
function useInputOTP(props: InputOTPProps): {
  Component: React.ElementType;
  slots: Record<InputOTPSlots, string>;
  classNames: SlotsToClasses<InputOTPSlots>;
  getInputOTPProps: () => any;
  getSegmentProps: (index: number) => any;
};

Input OTP Usage Examples:

import { InputOTP, Card, CardHeader, CardBody, Button } from "@nextui-org/react";

function InputOTPExamples() {
  const [otp, setOtp] = useState("");
  const [verificationOTP, setVerificationOTP] = useState("");

  const handleComplete = (value: string) => {
    console.log("OTP completed:", value);
    // Handle OTP verification
  };

  return (
    <div className="space-y-6 max-w-sm mx-auto">
      <Card>
        <CardHeader>
          <h3>Email Verification</h3>
        </CardHeader>
        <CardBody className="space-y-4">
          <p className="text-sm text-default-500">
            Enter the 6-digit code sent to your email
          </p>
          
          <InputOTP
            length={6}
            value={otp}
            onValueChange={setOtp}
            onComplete={handleComplete}
            placeholder="0"
          />
          
          <Button 
            color="primary"
            isDisabled={otp.length !== 6}
            className="w-full"
          >
            Verify Code
          </Button>
        </CardBody>
      </Card>

      <Card>
        <CardHeader>
          <h3>Custom Styled OTP</h3>
        </CardHeader>
        <CardBody className="space-y-4">
          <InputOTP
            length={4}
            value={verificationOTP}
            onValueChange={setVerificationOTP}
            variant="bordered"
            color="secondary"
            size="lg"
            radius="sm"
            allowedKeys={/^[0-9]$/}
          />
          
          <p className="text-xs text-default-400">
            Only numeric digits allowed
          </p>
        </CardBody>
      </Card>
    </div>
  );
}

Input Component Types

// Common input types
type InputSize = "sm" | "md" | "lg";
type InputVariant = "flat" | "bordered" | "underlined" | "faded";
type InputColor = "default" | "primary" | "secondary" | "success" | "warning" | "danger";
type LabelPlacement = "inside" | "outside" | "outside-left";
type ValidationBehavior = "aria" | "native";

// Validation types
type ValidationError = string | string[];

interface ValidationResult {
  isInvalid: boolean;
  validationErrors: string[];
  validationDetails: ValidationDetails;
}

interface ValidationDetails {
  [key: string]: any;
}

// Selection types
type Selection = "all" | Set<React.Key>;

// Group state interfaces
interface CheckboxGroupState {
  readonly selectedKeys: Set<string>;
  readonly isDisabled: boolean;
  readonly isReadOnly: boolean;
  readonly isRequired: boolean;
  readonly isInvalid: boolean;
  readonly value: string[];
  addValue(value: string): void;
  removeValue(value: string): void;
  toggleValue(value: string): void;
  clearValue(): void;
}

interface RadioGroupState {
  readonly selectedValue: string | null;
  readonly isDisabled: boolean;
  readonly isReadOnly: boolean;
  readonly isRequired: boolean;
  readonly isInvalid: boolean;
  setSelectedValue(value: string): void;
}

interface SliderState {
  readonly values: number[];
  readonly focusedThumb: number | undefined;
  readonly isDisabled: boolean;
  getThumbValue(index: number): number;
  setThumbValue(index: number, value: number): void;
  incrementThumb(index: number, stepSize?: number): void;
  decrementThumb(index: number, stepSize?: number): void;
}

docs

core-system.md

data-display.md

date-time.md

feedback.md

forms.md

index.md

inputs.md

interactions.md

layout.md

navigation.md

overlays.md

utilities.md

tile.json