Select
Displays a collapsible menu with a list of selectable options.
First release: 1.0.0 Latest update: July 1, 2025 Current version: 1.0.0
Import
import { PlusSelect } from '@plusui/react';import { PlusSelectComponent } from '@plusui/angular';import { PlusSelect } from '@plusui/vue';import PlusSelect from '@plusui/svelte';<script src="https://cdn.jsdelivr.net/npm/@plusui/core"></script>Package
@plusui/react@plusui/angular@plusui/vue@plusui/svelte@plusui/coreDocs
Changelog
Select Changelog
Recent changes and updates for the select component
v1.0.0
Resolved dropdown positioning and z-index issues.
- Fixed issues where the select dropdown would be overlapped by other elements or misaligned.
- This change is part of the "Form System Critical Fixes" EPIC (#72).
Added Select component with dropdown
- Customizable dropdown with floating UI
- Multiple selection support
- Search and filter functionality
- Keyboard navigation
- Accessibility with ARIA attributes
The Select (plus-select) component provides a dropdown menu (plus-select-item) allowing users to choose one option from a list. It leverages Floating UI for intelligent positioning of the menu.
Anatomy
Section titled “Anatomy”
Basic Example
Section titled “Basic Example”A simple select component with several options. The value displayed corresponds to the text property or the slotted content of the selected plus-select-item.
import { PlusSelect, PlusSelectItem } from '@plusui/react';
export default () => { const handleSelect = (event: CustomEvent<{ selectedItem: any }>) => { console.log('Selected item:', event.detail.selectedItem.value, event.detail.selectedItem.textContent); };
return ( <PlusSelect label="Choose an option" placeholder="Select..." onPlusSelectSelectedItem={handleSelect}> <PlusSelectItem value="1">Option 1</PlusSelectItem> <PlusSelectItem value="2" selected>Option 2</PlusSelectItem> <PlusSelectItem value="3">Option 3</PlusSelectItem> </PlusSelect> );};import { Component } from '@angular/core';
@Component({ selector: 'app-select-basic', template: ` <plus-select label="Choose an option" placeholder="Select..." (plus-select-selected-item)="handleSelect($event)"> <plus-select-item value="1">Option 1</plus-select-item> <plus-select-item value="2" selected>Option 2</plus-select-item> <plus-select-item value="3">Option 3</plus-select-item> </plus-select> `})export class SelectBasicComponent { handleSelect(event: any) { console.log('Selected item:', event.detail.selectedItem.value, event.detail.selectedItem.textContent); }}<template> <plus-select label="Choose an option" placeholder="Select..." @plus-select-selected-item="handleSelect"> <plus-select-item value="1">Option 1</plus-select-item> <plus-select-item value="2" selected>Option 2</plus-select-item> <plus-select-item value="3">Option 3</plus-select-item> </plus-select></template>
<script setup>const handleSelect = (event) => { console.log('Selected item:', event.detail.selectedItem.value, event.detail.selectedItem.textContent);};</script><script> function handleSelect(event) { console.log('Selected item:', event.detail.selectedItem.value, event.detail.selectedItem.textContent); }</script>
<plus-select label="Choose an option" placeholder="Select..." on:plus-select-selected-item={handleSelect}> <plus-select-item value="1">Option 1</plus-select-item> <plus-select-item value="2" selected>Option 2</plus-select-item> <plus-select-item value="3">Option 3</plus-select-item></plus-select><plus-select label="Choose an option" placeholder="Select..." id="basic-select"> <plus-select-item value="1">Option 1</plus-select-item> <plus-select-item value="2" selected>Option 2</plus-select-item> <plus-select-item value="3">Option 3</plus-select-item></plus-select>
<script> document.querySelector('plus-select').addEventListener('plus-select-selected-item', (event) => { console.log('Selected item:', event.detail.selectedItem.value, event.detail.selectedItem.textContent); });</script>Control the size using the size prop.
import { PlusSelect, PlusSelectItem } from '@plusui/react';
export default () => { return ( <> <PlusSelect size="sm" placeholder="Small"> <PlusSelectItem value="1"> Option 1 </PlusSelectItem> </PlusSelect> <PlusSelect size="md" placeholder="Medium"> <PlusSelectItem value="1"> Option 1 </PlusSelectItem> </PlusSelect> <PlusSelect size="lg" placeholder="Large"> <PlusSelectItem value="1"> Option 1 </PlusSelectItem> </PlusSelect> </> );};import { Component } from '@angular/core';
@Component({ selector: 'app-example', template: ` <plus-select size="sm" placeholder="Small"> <plus-select-item value="1"> Option 1 </plus-select-item> </plus-select> <plus-select size="md" placeholder="Medium"> <plus-select-item value="1"> Option 1 </plus-select-item> </plus-select> <plus-select size="lg" placeholder="Large"> <plus-select-item value="1"> Option 1 </plus-select-item> </plus-select> `})export class ExampleComponent {}<template> <plus-select size="sm" placeholder="Small"> <plus-select-item value="1"> Option 1 </plus-select-item> </plus-select> <plus-select size="md" placeholder="Medium"> <plus-select-item value="1"> Option 1 </plus-select-item> </plus-select> <plus-select size="lg" placeholder="Large"> <plus-select-item value="1"> Option 1 </plus-select-item> </plus-select></template><plus-select size="sm" placeholder="Small"> <plus-select-item value="1"> Option 1 </plus-select-item></plus-select><plus-select size="md" placeholder="Medium"> <plus-select-item value="1"> Option 1 </plus-select-item></plus-select><plus-select size="lg" placeholder="Large"> <plus-select-item value="1"> Option 1 </plus-select-item></plus-select><plus-select size="sm" placeholder="Small"> <plus-select-item value="1"> Option 1 </plus-select-item></plus-select><plus-select size="md" placeholder="Medium"> <plus-select-item value="1"> Option 1 </plus-select-item></plus-select><plus-select size="lg" placeholder="Large"> <plus-select-item value="1"> Option 1 </plus-select-item></plus-select>Label & Caption
Section titled “Label & Caption”Use label for the select title and caption for hint text below.
import { PlusSelect, PlusSelectItem } from '@plusui/react';
export default () => { return ( <> <PlusSelect label="Country" caption="Select your country of residence"> <PlusSelectItem value="us"> United States </PlusSelectItem> <PlusSelectItem value="ca"> Canada </PlusSelectItem> </PlusSelect> </> );};import { Component } from '@angular/core';
@Component({ selector: 'app-example', template: ` <plus-select label="Country" caption="Select your country of residence"> <plus-select-item value="us"> United States </plus-select-item> <plus-select-item value="ca"> Canada </plus-select-item> </plus-select> `})export class ExampleComponent {}<template> <plus-select label="Country" caption="Select your country of residence"> <plus-select-item value="us"> United States </plus-select-item> <plus-select-item value="ca"> Canada </plus-select-item> </plus-select></template><plus-select label="Country" caption="Select your country of residence"> <plus-select-item value="us"> United States </plus-select-item> <plus-select-item value="ca"> Canada </plus-select-item></plus-select><plus-select label="Country" caption="Select your country of residence"> <plus-select-item value="us"> United States </plus-select-item> <plus-select-item value="ca"> Canada </plus-select-item></plus-select>Placeholder
Section titled “Placeholder”The placeholder is shown when no item is selected.
import { PlusSelect, PlusSelectItem } from '@plusui/react';
export default () => { return ( <> <PlusSelect placeholder="Select a fruit..."> <PlusSelectItem value="apple"> Apple </PlusSelectItem> <PlusSelectItem value="banana"> Banana </PlusSelectItem> </PlusSelect> </> );};import { Component } from '@angular/core';
@Component({ selector: 'app-example', template: ` <plus-select placeholder="Select a fruit..."> <plus-select-item value="apple"> Apple </plus-select-item> <plus-select-item value="banana"> Banana </plus-select-item> </plus-select> `})export class ExampleComponent {}<template> <plus-select placeholder="Select a fruit..."> <plus-select-item value="apple"> Apple </plus-select-item> <plus-select-item value="banana"> Banana </plus-select-item> </plus-select></template><plus-select placeholder="Select a fruit..."> <plus-select-item value="apple"> Apple </plus-select-item> <plus-select-item value="banana"> Banana </plus-select-item></plus-select><plus-select placeholder="Select a fruit..."> <plus-select-item value="apple"> Apple </plus-select-item> <plus-select-item value="banana"> Banana </plus-select-item></plus-select>Disabled & Readonly
Section titled “Disabled & Readonly”Use disabled to prevent all interaction or readonly to prevent changing the selection.
import { PlusSelect, PlusSelectItem } from '@plusui/react';
export default () => { return ( <> <PlusSelect placeholder="Disabled" disabled> <PlusSelectItem value="1"> Option 1 </PlusSelectItem> </PlusSelect> <PlusSelect placeholder="Readonly" readonly> <PlusSelectItem value="1" selected> Option 1 </PlusSelectItem> <PlusSelectItem value="2"> Option 2 </PlusSelectItem> </PlusSelect> </> );};import { Component } from '@angular/core';
@Component({ selector: 'app-example', template: ` <plus-select placeholder="Disabled" disabled> <plus-select-item value="1"> Option 1 </plus-select-item> </plus-select> <plus-select placeholder="Readonly" readonly> <plus-select-item value="1" selected> Option 1 </plus-select-item> <plus-select-item value="2"> Option 2 </plus-select-item> </plus-select> `})export class ExampleComponent {}<template> <plus-select placeholder="Disabled" disabled> <plus-select-item value="1"> Option 1 </plus-select-item> </plus-select> <plus-select placeholder="Readonly" readonly> <plus-select-item value="1" selected> Option 1 </plus-select-item> <plus-select-item value="2"> Option 2 </plus-select-item> </plus-select></template><plus-select placeholder="Disabled" disabled> <plus-select-item value="1"> Option 1 </plus-select-item></plus-select><plus-select placeholder="Readonly" readonly> <plus-select-item value="1" selected> Option 1 </plus-select-item> <plus-select-item value="2"> Option 2 </plus-select-item></plus-select><plus-select placeholder="Disabled" disabled> <plus-select-item value="1"> Option 1 </plus-select-item></plus-select><plus-select placeholder="Readonly" readonly> <plus-select-item value="1" selected> Option 1 </plus-select-item> <plus-select-item value="2"> Option 2 </plus-select-item></plus-select>Error State
Section titled “Error State”Set error to indicate validation errors. Often combined with caption.
import { PlusSelect, PlusSelectItem } from '@plusui/react';
export default () => { return ( <> <PlusSelect label="Required Field" error="true" caption="This field is required"> <PlusSelectItem value="1"> Option 1 </PlusSelectItem> </PlusSelect> </> );};import { Component } from '@angular/core';
@Component({ selector: 'app-example', template: ` <plus-select label="Required Field" error="true" caption="This field is required"> <plus-select-item value="1"> Option 1 </plus-select-item> </plus-select> `})export class ExampleComponent {}<template> <plus-select label="Required Field" error="true" caption="This field is required"> <plus-select-item value="1"> Option 1 </plus-select-item> </plus-select></template><plus-select label="Required Field" error="true" caption="This field is required"> <plus-select-item value="1"> Option 1 </plus-select-item></plus-select><plus-select label="Required Field" error="true" caption="This field is required"> <plus-select-item value="1"> Option 1 </plus-select-item></plus-select>Clearable
Section titled “Clearable”Allows the user to deselect the current option.
import { PlusSelect, PlusSelectItem } from '@plusui/react';
export default () => { return ( <> <PlusSelect placeholder="Select..." clearable="true"> <PlusSelectItem value="1" selected> Option 1 </PlusSelectItem> <PlusSelectItem value="2"> Option 2 </PlusSelectItem> </PlusSelect> </> );};import { Component } from '@angular/core';
@Component({ selector: 'app-example', template: ` <plus-select placeholder="Select..." clearable="true"> <plus-select-item value="1" selected> Option 1 </plus-select-item> <plus-select-item value="2"> Option 2 </plus-select-item> </plus-select> `})export class ExampleComponent {}<template> <plus-select placeholder="Select..." clearable="true"> <plus-select-item value="1" selected> Option 1 </plus-select-item> <plus-select-item value="2"> Option 2 </plus-select-item> </plus-select></template><plus-select placeholder="Select..." clearable="true"> <plus-select-item value="1" selected> Option 1 </plus-select-item> <plus-select-item value="2"> Option 2 </plus-select-item></plus-select><plus-select placeholder="Select..." clearable="true"> <plus-select-item value="1" selected> Option 1 </plus-select-item> <plus-select-item value="2"> Option 2 </plus-select-item></plus-select>Disabled Items
Section titled “Disabled Items”Set the disabled attribute on individual plus-select-item components to prevent their selection.
import { PlusSelect, PlusSelectItem } from '@plusui/react';
export default () => { return ( <> <PlusSelect placeholder="Select..."> <PlusSelectItem value="1"> Enabled Option </PlusSelectItem> <PlusSelectItem value="2" disabled> Disabled Option </PlusSelectItem> <PlusSelectItem value="3"> Another Enabled </PlusSelectItem> </PlusSelect> </> );};import { Component } from '@angular/core';
@Component({ selector: 'app-example', template: ` <plus-select placeholder="Select..."> <plus-select-item value="1"> Enabled Option </plus-select-item> <plus-select-item value="2" disabled> Disabled Option </plus-select-item> <plus-select-item value="3"> Another Enabled </plus-select-item> </plus-select> `})export class ExampleComponent {}<template> <plus-select placeholder="Select..."> <plus-select-item value="1"> Enabled Option </plus-select-item> <plus-select-item value="2" disabled> Disabled Option </plus-select-item> <plus-select-item value="3"> Another Enabled </plus-select-item> </plus-select></template><plus-select placeholder="Select..."> <plus-select-item value="1"> Enabled Option </plus-select-item> <plus-select-item value="2" disabled> Disabled Option </plus-select-item> <plus-select-item value="3"> Another Enabled </plus-select-item></plus-select><plus-select placeholder="Select..."> <plus-select-item value="1"> Enabled Option </plus-select-item> <plus-select-item value="2" disabled> Disabled Option </plus-select-item> <plus-select-item value="3"> Another Enabled </plus-select-item></plus-select>Visual Sections
Section titled “Visual Sections”Layout & Spacing
Section titled “Layout & Spacing”
Light & Dark Mode
Section titled “Light & Dark Mode”
Accessibility (a11y)
Section titled “Accessibility (a11y)”- Keyboard Behavior:
- When the select trigger (
plus-input) has focus:Enter,Space,ArrowDown,ArrowUp: Opens the dropdown menu and focuses the selected item (or first/last if none selected).
- When the dropdown menu (
role="listbox") is open:ArrowDown: Moves focus to the next item. Wraps around.ArrowUp: Moves focus to the previous item. Wraps around.Home: Moves focus to the first non-disabled item.End: Moves focus to the last non-disabled item.EnterorSpace: Selects the focused item and closes the menu.Escape: Closes the menu without changing the selection.Tab: Closes the menu and moves focus to the next focusable element.
- When the select trigger (
- Screen Reader:
- The select trigger uses
role="combobox",aria-haspopup="listbox", andaria-expandedindicates the menu state. - The dropdown menu uses
role="listbox". - Each
plus-select-itemusesrole="option",aria-selectedindicates selection, andaria-disabledindicates the disabled state. - An accessible name for the combobox should be provided via the
labelprop oraria-label/aria-labelledby. - Item labels are derived from the
textprop or slotted content.
- The select trigger uses
- Required Developer Actions:
- Provide an accessible label for the
plus-selectcomponent using thelabelprop oraria-label. - Ensure each
plus-select-itemhas meaningful content (using thetextprop or default slot) to serve as its accessible name.
- Provide an accessible label for the
API Reference
Section titled “API Reference”plus-select
Section titled “plus-select”Properties
Section titled “Properties”| Name | Type | Default | Description | Required |
|---|---|---|---|---|
size | 'sm' | 'md' | 'lg' | 'md' | Size of the select button. | No |
placeholder | string | '' | Placeholder text when no item is selected. | No |
label | string | '' | Label text for the select. | No |
error | boolean | false | Indicates if the select is in an error state. | No |
disabled | boolean | false | Disables the select, preventing interaction. | No |
required | boolean | false | Marks the select as required. | No |
readonly | boolean | false | Makes the select read-only, preventing changes. | No |
caption | string | undefined | Caption text displayed below the select. | No |
clearable | boolean | false | Enables a clear button to reset the selection. | No |
Events
Section titled “Events”| Name | Payload Type | Description |
|---|---|---|
plus-select-open | CustomEvent<void> | Emitted when the select menu is opened. |
plus-select-close | CustomEvent<void> | Emitted when the select menu is closed. |
plus-select-selected-item | CustomEvent<{ selectedItem: PlusSelectItem }> | Emitted when an item is selected. |
| Name | Description |
|---|---|
(default) | Content for the select trigger button (overrides default). |
suffix | Content for the right side of the trigger button. |
select-item | Contains the plus-select-item elements for the menu. |
CSS Shadow Parts
Section titled “CSS Shadow Parts”| Name | Description |
|---|---|
base | The component’s base wrapper (div). |
select | The select trigger (plus-input). |
select-box | The select list container (div). |
plus-select-item
Section titled “plus-select-item”Properties
Section titled “Properties”| Name | Type | Default | Description | Required |
|---|---|---|---|---|
size | 'sm' | 'md' | 'lg' | 'md' | Size of the select item (usually inherited from plus-select). | No |
disabled | boolean | false | Disables the item, preventing selection. | No |
selected | boolean | false | Indicates if the item is currently selected (managed by parent). | No |
text | string | undefined | Text content override. If set, used for display and aria-label. | No |
value | string | '' | The value associated with this item. | Yes |
Events
Section titled “Events”Selection events are handled by the parent plus-select component (plus-select-selected-item).
| Name | Description |
|---|---|
(default) | The content displayed inside the item (text, icons, etc.). |
CSS Shadow Parts
Section titled “CSS Shadow Parts”| Name | Description |
|---|---|
base | The component’s base wrapper (div). |
item | The listbox item element (plus-list-box-item). |
CSS Custom Properties
Section titled “CSS Custom Properties”| Name | Description |
|---|---|
--i-bg-default | Default background color. |
--i-bg-hovered | Background color when hovered. |
--i-bg-pressed | Background color when pressed. |
--i-text-color | Text color. |
--i-selected-bg | Background color when selected. |
Join the Community
Plus UI is built by the community. Join us on our platforms to contribute, get help, and stay up to date.