Skip to content
Harness Design System Harness Design System Harness Design System

Select

The Select component provides a dropdown interface for selecting a single value from a list of options. It supports both controlled and uncontrolled modes, async loading states, search functionality, and integrates seamlessly with form validation.

Usage

import { Select } from "@harnessio/ui/components";
//...
return (
<Select
options={[
{ label: "One", value: "one" },
{ label: "Two", value: "two" },
{ label: "Three", value: "three" },
{ label: "Four", value: "four", disabled: true },
]}
defaultValue="three"
onChange={(value) => console.log(value)}
/>
)

Suffix Example

The Select component can be customized with a suffix element that appears on the right side of the input.

Form Integration

The Select component integrates seamlessly with form elements like labels, captions, and validation messages.

Search Functionality

Enable client-side search filtering to help users find options quickly in large or structured lists.

Async Loading

Options can be loaded asynchronously by passing a function that returns a Promise.

Disabled States

Both the entire select and individual options can be disabled.

Loading States

The Select component provides clear loading indicators for different scenarios.

Complex Option Labels

Options can have ReactNode labels for rich content display.

Custom Option Renderer

Customize how individual options are rendered using the optionRenderer prop. This allows advanced layouts or UI elements for each option.

Grouped Options and Separators

Sizes

The Select component supports two sizes: default and sm. The default size is suitable for most use cases, while the sm size is useful for compact layouts.

API Reference

Select

The Select component is the main component for creating dropdown selections.

<Select
options={options} // Array of options or async function
value={value} // [OPTIONAL] controlled value
defaultValue // [OPTIONAL] default value for uncontrolled mode
onChange={onChange} // [OPTIONAL] change handler
disabled // [OPTIONAL] disable the select
onScrollEnd={onScroll} // [OPTIONAL] infinite scroll callback
placeholder="Select..." // [OPTIONAL] placeholder text
isLoading // [OPTIONAL] loading state
allowSearch // [OPTIONAL] enable search
onSearch={customSearch} // [OPTIONAL] custom search function
optionRenderer={renderer} // [OPTIONAL] custom option renderer
// Form integration props
id="my-select" // [OPTIONAL] HTML id
label="Label" // [OPTIONAL] form label
error="Error message" // [OPTIONAL] error message
warning="Warning" // [OPTIONAL] warning message
caption="Help text" // [OPTIONAL] caption text
optional // [OPTIONAL] mark as optional
theme="default" // [OPTIONAL] theme variant
className="custom-class" // [OPTIONAL] custom className
/>
Prop
Required
Default
Type
optionstrueSelectOption<T>[] | () => Promise<SelectOption<T>[]>
valuefalseT
defaultValuefalseT
onChangefalse(value: T) => void
onSelectedChangefalse(event: ChangeEvent<HTMLInputElement>) => void
disabledfalsefalseboolean
onScrollEndfalse() => void
sizefalse'md''sm' | 'md'
placeholderfalse'Select an option'string
isLoadingfalsefalseboolean
idfalseAuto-generatedstring
namefalsestring
labelfalsestring
suffixfalseReactNode
themefalse'default''default' | 'danger' | 'warning'
captionfalsestring
errorfalsestring
warningfalsestring
optionalfalsefalseboolean
allowSearchfalsefalseboolean
onSearchfalseFilters by label containing query(query: string) => SelectOption<T>[]
searchValuefalsestring
optionRendererfalse(option: ValueOption<T>) => SelectItemType
headerfalseReactNode
footerfalseReactNode
contentWidthfalse'auto''triggerWidth' | 'auto'
rootClassNamefalsestring
triggerClassNamefalsestring
contentClassNamefalse''string

SelectOption

The SelectOption interface defines the shape of each option in the select dropdown.

type SelectOption<T = string> =
| {
label: string | ReactNode;
value: T;
disabled?: boolean;
}
| {
label: string;
options: Array<
| {
label: string | ReactNode;
value: T;
disabled?: boolean;
}
| "-"
>;
}
| "-";
Prop
Required
Default
Type
labeltruestring | ReactNode
valuetrueT
disabledfalsefalseboolean

Behavior

  • When options is a promise-returning function, the component shows a loading spinner while fetching
  • The dropdown shows a loading spinner at the bottom when isLoading is true and there are existing options (for infinite scroll)
  • Search input appears at the top of the dropdown when allowSearch is true
  • The default search implementation filters options by checking if the label contains the query (case-insensitive)
  • Search query is cleared when the dropdown closes or an option is selected
  • Form validation states (error, warning) automatically set the appropriate theme
  • The component supports generic types for option values, not limited to strings
  • If optionRenderer is provided, it overrides the default option rendering logic. This can be used to inject custom components such as avatars, icons, or descriptions for each option.

Accessibility

  • The Select component uses semantic HTML with proper ARIA attributes
  • Keyboard navigation is fully supported (Arrow keys, Enter, Escape)
  • Screen readers announce the selected value and available options
  • The trigger button is properly labeled when used with the label prop
  • Focus management follows WCAG guidelines
  • Search input receives focus automatically when the dropdown opens with search enabled