or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

ai-advanced.mddata-display.mdform-components.mdindex.mdinput-selection.mdlayout-navigation.mdloading-progress.mdmodal-overlay.mdtheming-customization.mdtiles-layout.md
tile.json

input-selection.mddocs/

Input & Selection Components

Specialized input and selection components providing advanced interaction patterns, file handling, and binary controls with consistent Carbon Design System styling.

Capabilities

Toggle Component

Binary state control component distinct from Switch, offering user-friendly on/off selection with customizable labels.

/**
 * Binary toggle component with custom labels for on/off states
 */
interface ToggleProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'aria-labelledby' | 'aria-checked' | 'type' | 'role' | 'id' | 'size' | 'onClick' | 'onToggle'> {
  /** Reference another element's id for labeling this toggle */
  'aria-labelledby'?: string;
  /** Unique identifier for the underlying button (required) */
  id: string;
  /** Label for the "off" position */
  labelA?: string;
  /** Label for the "on" position */
  labelB?: string;
  /** Main label text for screen readers */
  labelText?: string;
  /** Hide label but replace side labels with labelText */
  hideLabel?: boolean;
  /** Click/keyboard event handler */
  onClick?: React.MouseEventHandler<HTMLDivElement> | React.KeyboardEventHandler<HTMLDivElement>;
  /** Toggle state change callback */
  onToggle?: (checked: boolean) => void;
  /** Toggle size variant */
  size?: 'sm' | 'md';
  /** Read-only state */
  readOnly?: boolean;
  /** Default toggle state */
  defaultToggled?: boolean;
  /** Controlled toggle state */
  toggled?: boolean;
  /** Disabled state */
  disabled?: boolean;
  /** Additional CSS classes */
  className?: string;
}

Usage Examples:

import { Toggle } from "@carbon/react";

// Basic toggle
<Toggle 
  id="basic-toggle" 
  labelText="Enable notifications"
  defaultToggled={false}
/>

// Custom labels
<Toggle
  id="feature-toggle"
  labelA="Disabled"
  labelB="Enabled"
  labelText="Feature toggle"
  onToggle={(checked) => console.log('Toggled:', checked)}
/>

// Small size with controlled state
<Toggle
  id="small-toggle"
  size="sm"
  toggled={isEnabled}
  onToggle={setIsEnabled}
  readOnly={isReadOnly}
/>

Slider Component

Range input component with single or dual handle support, validation, and customizable formatting.

/**
 * Range slider with single or dual handle support
 */
interface SliderProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'onChange' | 'onBlur'>, TranslateWithId<TranslationKey, { correctedValue?: string }> {
  /** Aria label for the input */
  ariaLabelInput?: string;
  /** Aria label for upper handle (dual handle mode) */
  unstable_ariaLabelInputUpper?: string;
  /** Child elements */
  children?: React.ReactNode;
  /** CSS class name */
  className?: string;
  /** Disabled state */
  disabled?: boolean;
  /** Label formatter function */
  formatLabel?: (value: number, label: string | undefined) => string;
  /** Hide number input box */
  hideTextInput?: boolean;
  /** Input element ID */
  id?: string;
  /** Input type attribute */
  inputType?: string;
  /** Invalid state */
  invalid?: boolean;
  /** Invalid state message */
  invalidText?: React.ReactNode;
  /** Slider label */
  labelText?: React.ReactNode;
  /** Hide label visually */
  hideLabel?: boolean;
  /** Maximum value (required) */
  max: number;
  /** Maximum value label */
  maxLabel?: string;
  /** Minimum value (required) */
  min: number;
  /** Minimum value label */
  minLabel?: string;
  /** Input name attribute */
  name?: string;
  /** Upper handle name (dual handle mode) */
  unstable_nameUpper?: string;
  /** Blur event handler */
  onBlur?: (data: { value: string; handlePosition: HandlePosition | undefined }) => void;
  /** Value change callback */
  onChange?: (data: { value: SliderProps['value']; valueUpper: SliderProps['unstable_valueUpper'] }) => void;
  /** Input key up handler */
  onInputKeyUp?: React.KeyboardEventHandler<HTMLInputElement>;
  /** Handle release callback */
  onRelease?: (data: { value: SliderProps['value']; valueUpper: SliderProps['unstable_valueUpper'] }) => void;
  /** Read-only state */
  readOnly?: boolean;
  /** Required field */
  required?: boolean;
  /** Step increment */
  step?: number;
  /** Shift+arrow key step multiplier */
  stepMultiplier?: number;
  /** Current value (required) */
  value: number;
  /** Upper bound value (dual handle mode) */
  unstable_valueUpper?: number;
  /** Warning state */
  warn?: boolean;
  /** Warning message */
  warnText?: React.ReactNode;
}

/**
 * Slider loading skeleton
 */
interface SliderSkeletonProps {
  /** Hide text input in skeleton */
  hideLabel?: boolean;
}

Usage Examples:

import { Slider, SliderSkeleton } from "@carbon/react";

// Basic slider
<Slider
  min={0}
  max={100}
  value={25}
  labelText="Volume"
  onChange={({ value }) => setValue(value)}
/>

// Range slider with dual handles
<Slider
  min={0}
  max={1000}
  value={200}
  unstable_valueUpper={800}
  labelText="Price range"
  minLabel="$0"
  maxLabel="$1000"
  formatLabel={(value, label) => `$${value}${label ? ` ${label}` : ''}`}
  onChange={({ value, valueUpper }) => setPriceRange([value, valueUpper])}
/>

// Slider with validation
<Slider
  min={0}
  max={10}
  value={value}
  step={0.5}
  invalid={value < 2}
  invalidText="Minimum value is 2"
  hideTextInput={true}
/>

// Loading skeleton
<SliderSkeleton />

ExpandableSearch Component

Search component with expand/collapse behavior for space-efficient interfaces.

/**
 * Search component with expandable behavior
 */
interface ExpandableSearchProps extends SearchProps {
  /** Blur event handler */
  onBlur?: (event: React.FocusEvent<HTMLInputElement>) => void;
  /** Value change handler */
  onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;
  /** Expand event handler */
  onExpand?: () => void;
  /** Key down handler */
  onKeyDown?: (event: React.KeyboardEvent<HTMLInputElement>) => void;
  /** Default input value */
  defaultValue?: string;
  /** Controlled expanded state */
  isExpanded?: boolean;
}

Usage Examples:

import { ExpandableSearch } from "@carbon/react";

// Basic expandable search
<ExpandableSearch
  labelText="Search products"
  placeholder="Type to search..."
  onChange={(event) => setSearchValue(event.target.value)}
/>

// Controlled expanded state
<ExpandableSearch
  isExpanded={isSearchExpanded}
  onExpand={() => setIsSearchExpanded(true)}
  onBlur={() => setIsSearchExpanded(false)}
  defaultValue={initialSearchTerm}
/>

File Upload Components

Comprehensive file upload system with drag-and-drop support, validation, and progress tracking.

/**
 * Complete file upload component with integrated file management
 */
interface FileUploaderProps extends React.HTMLAttributes<HTMLSpanElement> {
  /** Accepted file types */
  accept?: string[];
  /** Upload button style */
  buttonKind?: 'primary' | 'secondary' | 'danger' | 'ghost' | 'danger--primary' | 'danger--ghost' | 'danger--tertiary' | 'tertiary';
  /** Button label for screen readers */
  buttonLabel?: string;
  /** CSS class name */
  className?: string;
  /** Disabled state */
  disabled?: boolean;
  /** File status indicator (required) */
  filenameStatus: 'edit' | 'complete' | 'uploading';
  /** Icon description for screen readers */
  iconDescription?: string;
  /** Description text */
  labelDescription?: string;
  /** Title text */
  labelTitle?: string;
  /** Multiple file selection */
  multiple?: boolean;
  /** Input name attribute */
  name?: string;
  /** File change event handler */
  onChange?: (event: any, data?: FileChangeData) => void;
  /** Click event handler */
  onClick?: (event: any) => void;
  /** File deletion handler */
  onDelete?: (event: any, data?: FileDeleteData) => void;
  /** Component size */
  size?: 'sm' | 'small' | 'md' | 'field' | 'lg';
}

/**
 * File upload button component
 */
interface FileUploaderButtonProps extends Omit<React.HTMLAttributes<HTMLButtonElement>, 'onChange' | 'tabIndex'> {
  /** Accepted file types */
  accept?: string[];
  /** Button style variant */
  buttonKind?: 'primary' | 'secondary' | 'danger' | 'ghost' | 'danger--primary' | 'danger--ghost' | 'danger--tertiary' | 'tertiary';
  /** CSS class name */
  className?: string;
  /** Disable label updates */
  disableLabelChanges?: boolean;
  /** Disabled state */
  disabled?: boolean;
  /** Input ID */
  id?: string;
  /** Button label text */
  labelText?: React.ReactNode;
  /** Multiple file selection */
  multiple?: boolean;
  /** Input name */
  name?: string;
  /** Change handler */
  onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;
  /** Click handler */
  onClick?: (event: React.MouseEvent<HTMLButtonElement>) => void;
  /** Accessibility role */
  role?: string;
  /** Button size */
  size?: 'sm' | 'small' | 'field' | 'md' | 'lg';
}

/**
 * Drag-and-drop file upload container
 */
interface FileUploaderDropContainerProps extends Omit<React.HTMLAttributes<HTMLButtonElement>, 'tabIndex'> {
  /** Accepted file types */
  accept?: string[];
  /** CSS class name */
  className?: string;
  /** Disabled state */
  disabled?: boolean;
  /** Input ID */
  id?: string;
  /** Label text */
  labelText?: string;
  /** Multiple file selection */
  multiple?: boolean;
  /** Input name */
  name?: string;
  /** File addition handler */
  onAddFiles?: (event: React.SyntheticEvent<HTMLElement>, content: { addedFiles: File[] }) => void;
  /** Click handler */
  onClick?: () => void;
  /** File type validation pattern */
  pattern?: string;
  /** Inner button ref */
  innerRef?: React.Ref<HTMLButtonElement>;
}

/**
 * Individual file item component
 */
interface FileUploaderItemProps extends React.HTMLAttributes<HTMLSpanElement> {
  /** Error message body */
  errorBody?: string;
  /** Error message subject */
  errorSubject?: string;
  /** Status icon description */
  iconDescription?: string;
  /** Invalid file state */
  invalid?: boolean;
  /** File name */
  name?: string;
  /** File addition handler */
  onAddFiles?: (event: React.ChangeEvent<HTMLInputElement>) => void;
  /** File deletion handler */
  onDelete?: (event: React.SyntheticEvent<HTMLElement>, opts: { uuid: string }) => void;
  /** Component size */
  size?: 'sm' | 'md' | 'lg';
  /** File status */
  status?: 'uploading' | 'edit' | 'complete';
  /** Unique identifier */
  uuid?: string;
}

/**
 * File status indicator component
 */
interface FilenameProps extends Omit<React.HTMLAttributes<HTMLElement> & React.SVGAttributes<React.ReactSVGElement>, 'tabIndex' | 'type'> {
  /** Error description ID */
  'aria-describedby'?: string;
  /** Icon description */
  iconDescription?: string;
  /** Invalid state */
  invalid?: boolean;
  /** File name */
  name?: string;
  /** Upload status */
  status?: 'edit' | 'complete' | 'uploading';
  /** Tab index */
  tabIndex?: number;
}

/**
 * File uploader handle for imperative operations
 */
interface FileUploaderHandle {
  /** Clear all files */
  clearFiles: () => void;
  /** Get current files (with feature flag) */
  getCurrentFiles?: () => FileItem[];
}

/**
 * File change data structure
 */
interface FileChangeData {
  /** Newly added files */
  addedFiles: FileItem[];
  /** Removed files */
  removedFiles: FileItem[];
  /** Current file list */
  currentFiles: FileItem[];
  /** Type of change */
  action: 'add' | 'remove' | 'clear';
}

/**
 * File deletion data structure
 */
interface FileDeleteData {
  /** Deleted file info */
  deletedFile: FileItem;
  /** Remaining files */
  remainingFiles: FileItem[];
}

Usage Examples:

import { 
  FileUploader, 
  FileUploaderButton, 
  FileUploaderDropContainer, 
  FileUploaderItem, 
  Filename 
} from "@carbon/react";

// Complete file uploader
<FileUploader
  accept={['.jpg', '.png', '.pdf']}
  buttonLabel="Add files"
  labelTitle="Upload documents"
  labelDescription="Only .jpg, .png and .pdf files at 500mb or less"
  filenameStatus="edit"
  multiple
  onChange={(event, data) => {
    console.log('Files changed:', data?.currentFiles);
  }}
  onDelete={(event, data) => {
    console.log('File deleted:', data?.deletedFile);
  }}
/>

// Standalone upload button
<FileUploaderButton
  buttonKind="primary"
  labelText="Choose files"
  multiple
  accept={['image/*']}
  onChange={(event) => {
    const files = Array.from(event.target.files || []);
    handleFileSelection(files);
  }}
/>

// Drag-and-drop container
<FileUploaderDropContainer
  accept={['.csv', '.xlsx']}
  labelText="Drag and drop files here or click to upload"
  multiple
  onAddFiles={(event, { addedFiles }) => {
    setFiles(prevFiles => [...prevFiles, ...addedFiles]);
  }}
/>

// Individual file item
<FileUploaderItem
  name="document.pdf"
  status="complete"
  uuid="file-123"
  invalid={false}
  onDelete={(event, { uuid }) => {
    removeFile(uuid);
  }}
/>

// File status indicator
<Filename
  name="upload.jpg"
  status="uploading"
  iconDescription="Uploading file"
/>

Import Paths

// Main components
import { 
  Toggle, 
  Slider, 
  SliderSkeleton, 
  ExpandableSearch,
  FileUploader,
  FileUploaderButton,
  FileUploaderDropContainer,
  FileUploaderItem,
  Filename
} from "@carbon/react";

// Type definitions
import type {
  ToggleProps,
  SliderProps,
  SliderSkeletonProps,
  FileUploaderProps,
  FileUploaderButtonProps,
  FileUploaderDropContainerProps,
  FileUploaderItemProps,
  FilenameProps,
  FileUploaderHandle,
  FileChangeData,
  FileDeleteData
} from "@carbon/react";

Component Relationships

File Upload System: FileUploader orchestrates FileUploaderButton, FileUploaderItem, and Filename components. FileUploaderDropContainer provides an alternative drag-and-drop interface.

Toggle vs Switch: Toggle is a binary control with customizable labels and different interaction patterns compared to Switch, which is a simple on/off control.

Slider Capabilities: Supports both single-value and range (dual-handle) modes with extensive validation and formatting options.

ExpandableSearch Behavior: Automatically expands on focus and collapses when empty and loses focus, with escape key support for clearing/collapsing.