
Research
/Security News
Fake imToken Chrome Extension Steals Seed Phrases via Phishing Redirects
Mixed-script homoglyphs and a lookalike domain mimic imToken’s import flow to capture mnemonics and private keys.
@highlight-ui/select
Advanced tools
Feature-rich select control.
Collects user information by displaying a list, triggered by click action, allowing single or multiple selection.
Using npm:
npm install @highlight-ui/select
Using yarn:
yarn add @highlight-ui/select
Using pnpm:
pnpm install @highlight-ui/select
Once the package is installed, you can import the library:
import { Select } from '@highlight-ui/select';
import React from 'react';
import { Select, SelectOption } from '@highlight-ui/select';
export default function SingleSelectExample() {
const [selectedOptions, setSelectedOptions] = useState<SelectOption[]>([]);
return (
<Select
triggerLabel="Pick a name"
selectedOptions={selectedOptions}
onSelect={setSelectedOptions}
options={[
{ label: 'Genesis', value: '23095' },
{ label: 'Destinee', value: '26211' },
]}
/>
);
}
import React from 'react';
import { Select, SelectOption } from '@highlight-ui/select';
export default function MultiSelectExample() {
const [selectedOptions, setSelectedOptions] = useState<SelectOption[]>([]);
return (
<Select
multiple
triggerLabel="Pick a name"
selectedOptions={selectedOptions}
onSelect={setSelectedOptions}
options={[
{ label: 'Genesis', value: '23095' },
{ label: 'Destinee', value: '26211' },
]}
/>
);
}
The following sections highlight new features that can be enabled via props.
When the content is open, a search input will be visible if the searchable prop is set to true and the number of options is equal or above the number as provided through the minOptionsToDisplaySearch prop.
By default enableNewSearchInput will be false. Below is a comparison of what it renders, based on its value.
enableNewSearchInput | Component | Comments |
|---|---|---|
false | DefaultSearchInput | Wrapper with role="search" containing a <label> which groups an <Icon> and <input> |
true | SearchInput | Uses the <TextInput> component with an <Icon> as prefix |
By default enableFlowTriggers will be false. Below is a comparison of what it renders, based on its value.
enableFlowTriggers | multiple | Component | Comments |
|---|---|---|---|
false | false | DefaultTrigger or Custom renderTrigger() | <button> showing the selected option (by default) or a custom element |
false | true | DefaultSearchInput or Custom renderTrigger() | <button> showing the selected options count and clear icon (by default) or a custom element |
true | false | InputTrigger | <InputContainer> component with an <IconButton> as suffix, showing the selected option |
true | true | MultiInputTrigger | <InputContainer> component with an <IconButton> as suffix, showing the selected options as <SelectChip>s and clear icon |
This example focus on loading options asynchronously.
In real-world example, in the onListVisibilityChange handler hardcoded options would be replaced by API call.
import React from 'react';
import { Select, SelectOption } from '@highlight-ui/select';
const initialOptions: SelectOption[] = [
{ label: 'Genesis', value: '23095' },
{ label: 'Destinee', value: '26211' },
{ label: 'Chyna', value: '86910' },
{ label: 'Alexie', value: '49249' },
{ label: 'Natalie', value: '18694' },
];
export default function AsyncExample() {
const [selectedOptions, setSelectedOptions] = useState<SelectOption[]>([]);
const [options, setOptions] = useState([]);
const [isLoading, setIsLoading] = useState(false);
return (
<Select
triggerLabel="Pick a name"
selectedOptions={selectedOptions}
onSelect={setSelectedOptions}
searchable
isLoading={isLoading}
minOptionsToDisplaySearch={1}
onListVisibilityChange={(visible) => {
if (visible) {
setIsLoading(true);
// mocks API call. Should be replaced with network request
setTimeout(() => {
setOptions(initialOptions);
setIsLoading(false);
}, 3000);
}
}}
options={options}
/>
);
}
Option groups provide a way to visually group multiple options. Groups are determined by specifying a group title in each option.
import React from 'react';
import { Select, SelectOption } from '@highlight-ui/select';
export default function OptionGroupsExample() {
const [selectedOptions, setSelectedOptions] = useState<SelectOption[]>([]);
return (
<Select
triggerLabel="Pick a name"
selectedOptions={selectedOptions}
onSelect={setSelectedOptions}
options={[
{ label: 'Genesis', value: '23095', group: 'One' },
{ label: 'Destinee', value: '26211', group: 'Two' },
]}
/>
);
}
Four different option types are supported:
Option types are determined by specifying optionType prop.
Additionally, each option type has its own props which are specified in each option.
import React from 'react';
import { Select, SelectOption } from '@highlight-ui/select';
export default function OptionTypesExample() {
const [selectedOptions, setSelectedOptions] = useState<SelectOption[]>([]);
return (
<Select
triggerLabel="Pick a name"
selectedOptions={selectedOptions}
onSelect={setSelectedOptions}
optionType="colored"
options={[
{ label: 'Genesis', value: '23095', color: 'red' },
{ label: 'Destinee', value: '26211', color: 'green' },
]}
/>
);
}
In addition to the label, value and group, these props are used to define option type:
| Prop | Type | Option type | Description |
|---|---|---|---|
disabled | boolean | all | Should the option be disabled or enabled |
metadata | ComponentMetadata | all | Object used for testing. Contains testId and actionName |
subLabel | string | multi-line and avatar | Smaller, descriptive text used below main label |
avatar | string | avatar | URL used to fetch avatar image |
imageLoading | eager or lazy | avatar | Specifies how browser will load avatar image |
Select has a support for options dynamically created by user.
import React from 'react';
import { Select, SelectOption } from '@highlight-ui/select';
export default function CreatableOptionExample() {
const [selectedOptions, setSelectedOptions] = useState<SelectOption[]>([]);
const [options, setOptions] = useState([
{
label: 'Genesis',
value: '23095',
},
]);
return (
<Select
triggerLabel="Pick a name"
selectedOptions={selectedOptions}
onSelect={setSelectedOptions}
creatableOptions={{
createButtonProps: {
label: 'Add',
loading: false,
},
inputProps: {
placeholder: 'Create a new one',
},
onCreate: (item) => {
setOptions([...options, { label: item.value, value: item.value }]);
},
}}
options={options}
/>
);
}
⚠️ Submit footer cannot be used alongside creatable options.
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
createButtonProps.label | string | Yes | Text used in the submit button | |
createButtonProps.loading | boolean | No | false | Defines if the submit button will be in loading state |
createButtonProps.metadata | ComponentMetadata | No | null | Object used for testing. Contains testId and actionName |
inputProps.placeholder | string | No | null | Placeholder used in search bar |
inputProps.metadata | ComponentMetadata | No | null | Object used for testing. Contains testId and actionName |
onCreate | function(item: SelectOption): void | Yes | null | Function called whenever new option is created |
Select has a support for submit footer.It provides distinction between selected and submitted options. This means that changes in selected options can be discarded.
import React from 'react';
import { Select, SelectOption } from '@highlight-ui/select';
export default function SubmitFooterExample() {
const [selectedOptions, setSelectedOptions] = useState<SelectOption[]>([]);
const [submittedOptions, setSubmittedOptions] = useState<SelectOption[]>([]);
return (
<Select
triggerLabel="Pick a name"
selectedOptions={selectedOptions}
onSelect={setSelectedOptions}
multiple
options={[
{ label: 'Genesis', value: '23095' },
{ label: 'Destinee', value: '26211' },
]}
submitOptions={{
onCancel: () => setSelectedOptions(submittedOptions),
onSubmit: (options) => setSubmittedOptions(options),
}}
/>
);
}
⚠ Creatable options cannot be used alongside submit footer.
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
submitOptions.onSubmit | function(options: SelectOption[]): void | Yes | Function called whenever the submit button is pressed | |
submitOptions.onCancel | function(): void | Yes | Function called whenever the cancel button is pressed | |
submitOptions.submitLabel | string | No | 'Apply' | Label used in the submit button |
submitOptions.cancelLabel | string | No | 'Cancel' | Label used in the cancel button |
ℹ️ Whenever SelectOption is used, there is an option to extend this interface and provide your own metadata.
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
options | SelectOption[] | Yes | List of objects | |
onSelect | function(values: SelectOption[]): void | Yes | Gets called each time an option is selected | |
selectedOptions | SelectOption[] | Yes | List of selected options | |
className | string | No | null | Class name to apply to the element |
listClassName | string | No | null | Class name to apply to the List element |
closeOnSelect | boolean | No | false | Should the options list disappear by each selection? |
disabled | boolean | No | false | Should trigger be enabled or disabled |
selectAllLabel | string | No | 'Select all' | Label for Select all functionality when multiple prop is true |
metadata | ComponentMetadata | No | null | Object used for testing. Contains testId and actionName |
onSearchChange | function(search: string): void | No | null | Gets called whenever text is typed in search bar |
onListVisibilityChange | function(visible: boolean): void | No | null | Gets called whenever the visibility of the select's list has changed |
emptyStateLabel | string | No | 'Nothing to display' | Label for displaying the empty state of the Select list |
renderEmptyState | function(props: SelectEmptyStateProps): ReactNode | No | null | Function to return custom empty options list message |
renderTrigger | function(props: SelectTriggerProps & ref: RefCallback): ReactNode | No | null | Function to return a custom trigger |
optionType | single-line or colored or multi-line or avatar | No | 'single-line' | String specifying the option type that should be rendered. |
variant | inline or full-width | No | 'inline' | inline when used outside forms and full-width when used inside forms |
searchable | boolean | No | true | Determines whether or not a search input should be rendered in the select list |
searchAutofocus | boolean | No | true | Whether or not the search field should get the focus automatically each time the list opens up |
searchInitialValue | string | No | null | Initial search field value |
searchNoResultsLabel | string | No | 'No results for' | No search results message |
searchPlaceholder | string | No | 'Search' | No search results message |
minOptionsToDisplaySearch | number | No | 8 | If Select is searchable search input will render if the number of options is more or equal to this number. |
triggerLabel | string | No | null | Label being shown by default on the trigger button |
outline | default or warning or error | No | 'default' | String specifying the outline that should be rendered |
autoFocus | boolean | No | false | Automatically focus the Select's trigger on mount |
triggerId | string | No | null | HTML id attribute asssigned to trigger component |
creatableOptions | CreatableOptionsProps | No | null | Options used for creatable option feature |
isClearable | boolean | No | false | Defines wether to render the clearing x button |
highlightedText | string | No | null | Highlights this text in the options list only when the Select is not searchable. |
isLoading | boolean | No | false | Display the loading state of the list |
submitOptions | SubmitOptions | No | null | Options used for the submit button |
enableFlowTriggers | boolean | No | false | Allow toggling between original and new trigger |
enableNewSearchInput | boolean | No | false | Allow toggling between original and new search input |
limitTwoRows | boolean | No | true | Limit selected chips to only display two rows. Only applicable to multi-select. |
enableSubLabelSearch | boolean | No | false | Search in subLabel text when optionType is multi-line |
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
label | string | No | null | Label shown in the empty |
Select tries to mimic native HTML select a11y features as best as possible.
This is well-known to be a notoriously hard job There are some smaller deviation to native select's behaviour:
This example serves as starting point on how you can use Select component as part of your tests.
Some of the props are already defined in the SelectWrapper since they are mandatory but they can be overriden by sending props to the renderSelectWrapper function.
import React, { useState } from 'react';
import { render } from '@testing-library/react';
import { Select, SelectOption } from '@highlight-ui/select';
type Optional<T, K extends keyof T> = Omit<T, K> & Partial<T>;
type SelectWrapperProps = Optional<
SelectProps<SelectOption>,
'selectedOptions' | 'onSelect' | 'options'
>;
function SelectWrapper(props: SelectWrapperProps) {
const [selectedOptions, setSelectedOptions] = useState<SelectOption[]>([]);
return (
<Select
selectedOptions={selectedOptions}
onSelect={setSelectedOptions}
options={[
{ label: 'Genesis', value: '23095', color: 'red' },
{ label: 'Destinee', value: '26211', color: 'green' },
]}
{...props}
/>
);
}
describe('SelectTest', () => {
const renderSelectWrapper = (props: SelectWrapperProps) => {
return render(<SelectWrapper {...props} />);
};
it('test description', () => {
renderSelectWrapper({});
// write your expect here
});
});
Select component's flexibility is used to implement a number of different components:
For picking a color from a color palette, color-picker should be used.
For picking unselectable menu item which will open URL or call custom callback, look at the dropdown-menu
Please visit personio.design.
If you're interested in contributing, please visit our contribution page.
FAQs
Select component for the Highlight UI library
The npm package @highlight-ui/select receives a total of 3,148 weekly downloads. As such, @highlight-ui/select popularity was classified as popular.
We found that @highlight-ui/select demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 10 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
/Security News
Mixed-script homoglyphs and a lookalike domain mimic imToken’s import flow to capture mnemonics and private keys.

Security News
Latio’s 2026 report recognizes Socket as a Supply Chain Innovator and highlights our work in 0-day malware detection, SCA, and auto-patching.

Company News
Join Socket for live demos, rooftop happy hours, and one-on-one meetings during BSidesSF and RSA 2026 in San Francisco.