Select
A Select, often referred to as a dropdown, allows users to choose a single option from a pop-up list. When used with optional placeholder text, the user can also return the Select to a "nothing selected" state.
Design guidance
When and how to use this
Use a Select when the user needs to make a single choice from a list of
options. Selects are particularly useful for longer lists of options, or cases
where you want to save space as compared to a group of Radio
buttons. A
Select is also useful in cases where a user can optionally decide not to
choose anything.
When to consider something else
For cases where a user needs to choose one and only one of 2-3 options, or cases
where it's beneficial to the user to see all of the options before interacting
with the field, you might consider using a group of Radio
buttons instead of a
Select.
Figma
Drag in a Select Field
from the Compositions section in the Form Controls v2
library in the Assets pane in your Figma file. A Select component is nested
within, which provides 3 size variants. Default
has a 48px height, and should
cover nearly all use cases. We do also offer Small
(32px) and Tiny
(24px),
but these should be reserved for especially compact UI designs. Options for
displaying an icon in the Select, and all states (Idle
, Focus
,
Disabled
, and so on) are also available. You can also drag in a Select on
its own from the Components section, but we recommend using the Field
composition in most cases.
React
Select composes Chakra's Select. We offer size variants that align with
those in TextInput
. As with TextInput
, we recommend wrapping your Select
in a Field
to get a <label>
element and error
display below the field (if
an error is present), which will also trigger isInvalid
on the Select.
Prop | Description |
---|---|
size | Sets the size of the Select and its associated label. Use small or tiny only for especially compact interfaces. |
width | Select defaults to a width of 100% . Set width: auto and display: inline-block or use flexbox to layout a Select with automatic width. The isTruncated prop defaults to true for cases when the option label contents do not fit in the allotted width. |
placeholder | Sets placeholder text for the Select. |
isDisabled | If true the Select will be disabled. |
isInvalid | If true the Select will be invalid and its aria-invalid will be set to true |
Bootstrap
Bootstrap provides styles for Select and accompanying <label>
elements,
using the .form-select
and .form-label
classes. We match Figma and React
size variants via .form-select-sm
and .form-select-tiny
. Using Bootstrap's
.form-select-lg
maps to our default (48px height) variant.
Class | Description |
---|---|
.form-select and .form-label | Invokes Bootstrap theme styles for text inputs and labels. |
.form-select-sm and form-select-tiny | Reproduces the small (32px height, default 16/24 text) and tiny (24px height, 14/20 text) size variants found in Figma and React |
React Native
Select is built with Tamagui and provides a dropdown interface with trigger, sheet, and items for iOS and Android platforms.
Usage
import React, { useState } from 'react';import { Select } from '@hoverinc/design-system-react-native';const App = () => { const [value, setValue] = useState<string>(); const data = [ { label: 'Option 1', value: 'option1' }, { label: 'Option 2', value: 'option2' }, { label: 'Option 3', value: 'option3' }, ]; return ( <Select data={data} onValueChange={setValue} value={value} label="Choose an option" /> );};
Custom Trigger
For more control over the trigger appearance, you can use a custom trigger. The custom trigger will automatically receive disabled state when the Select is disabled:
import { iconChevronDown } from '@hoverinc/icons/native';import React, { useState } from 'react';import { Button, Heading, Icon, Select, XStack } from '@hoverinc/design-system-react-native';const App = () => { const [value, setValue] = useState<string>(); const data = [ { label: 'Howard Snowden', value: 'howard' }, { label: 'Harold Sawyer', value: 'harold' }, { label: 'Harrison Sullivan', value: 'harrison' }, ]; return ( <Select data={data} onValueChange={setValue} value={value} trigger={ <Button variant="secondary" size="large"> {value ? data.find(item => item.value === value)?.label : 'Select structure'} </Button> } /> );};
Size Variants
The Select component supports two size variants for the sheet:
// Auto size - fits content (default for custom triggers)<Select size="auto" data={data} label="Auto Size" />// Full size - expands to 100% height (default for basic usage)<Select size="full" data={data} label="Full Size" />
Disabled State
When the Select is disabled, the disabled state is automatically propagated to custom triggers:
// The Button will automatically receive disabled={true} when Select is disabled<Select data={data} isDisabled={true} trigger={<Button>Custom Trigger</Button>}/>
Controlled vs Uncontrolled
The Select component supports both controlled and uncontrolled usage:
// Controlledconst [value, setValue] = useState<string>();<Select value={value} onValueChange={setValue} data={data} />// Uncontrolled<Select defaultValue="option1" data={data} />