Thrive Design System

Components

Select Searchable

A searchable select component with single or multiple selection, keyboard navigation, and tag-based display for selected items.

Installation

npm install @thrivecart/ui
yarn add @thrivecart/ui
pnpm add @thrivecart/ui
bun add @thrivecart/ui

Usage

import { SelectSearchable } from '@thrivecart/ui';

Single Select

const [value, setValue] = useState('');

<SelectSearchable
  items={frameworks}
  placeholder="Select a framework..."
  value={value}
  onChange={setValue}
/>

Multiple Select

const [value, setValue] = useState<string[]>([]);

<SelectSearchable
  items={tags}
  multiple
  placeholder="Add tags..."
  value={value}
  onChange={setValue}
/>

Examples

Basic

Single Select

Search and pick one item from the list

const [value, setValue] = useState('');

<SelectSearchable
items={frameworks}
placeholder="Select a framework..."
searchPlaceholder="Search frameworks..."
value={value}
onChange={setValue}
/>

Country Picker

Country Picker

Search through a long list of countries

const [value, setValue] = useState('');

<SelectSearchable
items={countries}
placeholder="Select a country..."
searchPlaceholder="Search countries..."
value={value}
onChange={setValue}
/>

Multiple with Tags

Multiple Selection

Select multiple items displayed as removable tags

const [value, setValue] = useState(['vip', 'high-value']);

<SelectSearchable
items={tags}
multiple
placeholder="Add tags..."
searchPlaceholder="Search tags..."
value={value}
onChange={setValue}
/>

Team Assignment

Team Members

Assign multiple people with descriptions and overflow indicator

const [value, setValue] = useState([]);

<SelectSearchable
items={teamMembers}
multiple
placeholder="Assign team members..."
searchPlaceholder="Search people..."
value={value}
onChange={setValue}
/>

Max Visible Tags

Max Tags

Limit visible tags in the trigger — overflow shows a count indicator

const [value, setValue] = useState(['vip', 'high-value', 'returning', 'enterprise']);

<SelectSearchable
items={tags}
multiple
maxTags={2}
placeholder="Add tags..."
searchPlaceholder="Search tags..."
value={value}
onChange={setValue}
/>

Max Selections

Max Number

Limit the total number of items that can be selected

const [value, setValue] = useState([]);

<SelectSearchable
items={teamMembers}
multiple
maxNumber={3}
placeholder="Pick up to 3 people..."
searchPlaceholder="Search people..."
value={value}
onChange={setValue}
/>

With Descriptions

Items with Descriptions

Each option shows a secondary description line

<SelectSearchable
items={[
  { label: 'Next.js', value: 'next', description: 'React framework by Vercel' },
  { label: 'SvelteKit', value: 'sveltekit', description: 'Svelte meta-framework' },
  { label: 'Nuxt', value: 'nuxt', description: 'Vue.js framework' },
]}
placeholder="Pick a framework..."
emptyMessage="No frameworks match your search."
value={value}
onChange={setValue}
/>

Disabled

Disabled

Select in a non-interactive disabled state

<SelectSearchable
items={frameworks}
placeholder="Disabled select..."
disabled
/>

Indicator Styles

The indicator prop controls how selected items are shown in the dropdown. Use 'check' (default) for a checkmark on the right, or 'checkbox' for a checkbox on the left.

When to use check (default):

  • Standard single-select dropdowns (country picker, status selector)
  • Multi-select where tags in the trigger already communicate selection state
  • Simpler, cleaner look for lists where toggling is secondary

When to use checkbox:

  • Data table column visibility toggles
  • Permission or feature toggles where on/off state must be obvious
  • Settings panels where every item is independently togglable
  • Any list where the user mentally models items as "checked" or "unchecked"

Checkbox — Column Visibility

Data Table Columns

Toggle visible columns in a data table using checkbox indicator

const [value, setValue] = useState(['name', 'email', 'total', 'status']);

<SelectSearchable
items={tableColumns}
multiple
indicator="checkbox"
placeholder="Toggle columns..."
searchPlaceholder="Search columns..."
value={value}
onChange={setValue}
/>

Checkbox — Permissions

Role Permissions

Assign permissions to a role with clear on/off state

const [value, setValue] = useState(['view-dashboard', 'access-reports']);

<SelectSearchable
items={permissions}
multiple
indicator="checkbox"
placeholder="Assign permissions..."
searchPlaceholder="Search permissions..."
value={value}
onChange={setValue}
/>

Custom Items

Use labelKey, valueKey, and descriptionKey when your items have different property names.

const products = [
  { name: 'Pro Plan', id: 'pro', info: 'Best for growing businesses' },
  { name: 'Enterprise', id: 'enterprise', info: 'For large organizations' },
];

<SelectSearchable
  items={products}
  labelKey="name"
  valueKey="id"
  descriptionKey="info"
  placeholder="Select a plan..."
  value={value}
  onChange={setValue}
/>

Best Practices

Use for long lists

Search is most valuable when there are 10+ options. For short lists, use a standard Select.

Provide helpful placeholders

Use descriptive placeholder and searchPlaceholder text so users know what to expect.

Don't use for actions

This is for selecting values, not triggering actions. Use DropdownMenu for action menus.

Props

PropTypeDefaultDescription
itemsT[]-Array of items to display
multiplebooleanfalseEnable multi-select mode
valuestring | string[]-Selected value(s) — string for single, string[] for multiple
onChange(value) => void-Callback when selection changes
placeholderstring'Select...'Trigger placeholder text
searchPlaceholderstring'Search...'Search input placeholder
emptyMessagestring'No results found'Message shown when no items match search
labelKeykeyof T'label'Property name for the display label
valueKeykeyof T'value'Property name for the item value
descriptionKeykeyof T'description'Property name for optional description
indicator'check' | 'checkbox''check'check = checkmark on right, checkbox = checkbox on left
maxTagsnumber0Max visible tags in trigger (multiple only). 0 = show all
maxNumbernumber-Max number of items that can be selected (multiple only)
disabledbooleanfalseDisable the select
classNamestring-Additional className for the trigger

Keyboard Navigation

KeyAction
Arrow DownHighlight next item
Arrow UpHighlight previous item
EnterSelect highlighted item
EscapeClose the popover
Type to filterFilters items in real-time

Accessibility

  • Uses aria-haspopup="listbox" with aria-expanded on the trigger.
  • The dropdown list uses role="listbox" with role="option" on each item.
  • Each option has aria-selected for screen readers.
  • Full keyboard navigation with arrow keys and enter to select.
  • Search input auto-focuses when the popover opens.