Usage
Select component allows user to pick one option from the given data
,
use this component when you need to create custom value selection which is not possible with NativeSelect:
Bare minimum usage example:
<Selectlabel="Your favorite framework/library"placeholder="Pick one"data={[{ value: 'react', label: 'React' },{ value: 'ng', label: 'Angular' },{ value: 'svelte', label: 'Svelte' },{ value: 'vue', label: 'Vue' },]}/>
Controlled
import { useState } from 'react';import { Select } from '@mantine/core';function Demo() {const [value, setValue] = useState('');return <Select value={value} onChange={setValue} />;}
Note that Select value should always be either string or null:
// Incorrect, will have bugs<Select data={[{ value: 1, label: '1' }]} value={1} />// Correct, works as expected<Select data={[{ value: '1', label: '1' }]} value="1" />
Data prop
Select support two different data formats:
- An array of strings – use when you do not need to customize item component or display
label
different thanvalue
- An array of objects with required
value
andlabel
properties and any other additional properties
// Data as an array of strings, will be mapped to// [// { value: 'React', label: 'React' },// { value: 'Angular', label: 'Angular' },// { value: 'Svelte', label: 'Svelte' },// { value: 'Vue', label: 'Vue' },// ]<Select data={['React', 'Angular', 'Svelte', 'Vue']} />// Data as an array of objects:// Minimal example (same as first example above)<Select data={[{ value: 'React', label: 'React' },{ value: 'Angular', label: 'Angular' },{ value: 'Svelte', label: 'Svelte' },{ value: 'Vue', label: 'Vue' },]} />// Additional data properties for custom item component (see documentation below)<SelectitemComponent={({ value, label, image, name }) => /* Your custom item component with data properties */}data={[{value: 'bob@handsome.inc',label: 'bob@handsome.inc',image: 'image-link',name: 'Bob Handsome',},{value: 'bill@outlook.com',label: 'bill@outlook.com',image: 'image-link',name: 'Bill Rataconda',},{value: 'amy@wong.cn',label: 'amy@wong.cn',image: 'image-link',name: 'Amy Wong',},]}/>
Searchable
Set searchable
prop to enable search in select and nothingFound
prop to provide label that will be shown when no options were found:
<Selectlabel="Your favorite framework/library"placeholder="Pick one"searchablenothingFound="No options"data={[{ value: 'react', label: 'React' },{ value: 'ng', label: 'Angular' },{ value: 'svelte', label: 'Svelte' },{ value: 'vue', label: 'Vue' },]}/>
Clearable
Set clearable
prop to enable clearing select value.
When prop is true and value is selected clear button will replace chevron in right section:
<Selectlabel="Your favorite framework/library"placeholder="Pick one"clearabledata={data}/><Selectlabel="Your favorite framework/library"placeholder="Pick one"searchableclearabledata={data}/>
Large data set
When dropdown height is exceeded dropdown becomes scrollable, to change max-height set maxDropdownHeight
prop with value in px:
const data = Array(50).fill(0).map((_, index) => ({value: `${index}`,label: `Item ${index}`,}));<Selectlabel="What item is the best?"placeholder="Pick one"searchablenothingFound="No options"maxDropdownHeight={280}data={data}/>
Custom item component
You can change select item component and filtering logic that is used in search. To do so you will need to:
- Add extra props to
data
objects - Create
filter
function which determines whether item should be added to the search results - Provide
itemComponent
which will consumedata
objects
// Minimum data for default autocomplete used in previous examples[{ value: 'react', label: 'React' },{ value: 'ng', label: 'Angular' },{ value: 'svelte', label: 'Svelte' },{ value: 'vue', label: 'Vue' },];
You can add any other fields to your data:
[{value: 'bob@handsome.inc',image: 'image-link',label: 'bob@handsome.inc',name: 'Bob Handsome',},{value: 'bill@outlook.com',image: 'image-link',label: 'bill@outlook.com',name: 'Bill Rataconda',},{ value: 'amy@wong.cn', image: 'image-link', label: 'amy@wong.cn', name: 'Amy Wong' },];
Based on this data shape you can create custom filter
function and itemComponent
:
import { Group, Avatar, Text, Select } from '@mantine/core';const data = [{ value: 'bob@handsome.inc', image: 'image-link', label: 'bob@handsome.inc', name: 'Bob Handsome' },{ value: 'bill@outlook.com', image: 'image-link', label: 'bill@outlook.com', name: 'Bill Rataconda' },{ value: 'amy@wong.cn', image: 'image-link', label: 'amy@wong.cn', name: 'Amy Wong' },];function SelectItem({ image, label, name, elementRef, ...others }) {return (<div ref={elementRef} {...others}><Group><Avatar src={image} radius="xl" /><div><Text>{name}</Text><Text size="xs" color="blue">{label}</Text></div></Group></div>);}function Demo() {return (<Selectlabel="Choose employee of the month"placeholder="Pick one"itemComponent={AutoCompleteItem}data={data}searchablenothingFound="Nobody here"filter={(value, item) =>item.name.toLowerCase().includes(value.toLowerCase().trim()) ||item.email.toLowerCase().includes(value.toLowerCase().trim())}/>);}
Animations
By default dropdown animations are turned off to increase responsiveness. You can enable them by setting optional props:
transition
– premade transition name or custom transition styles object, see Transition component for all available optionstransitionDuration
– transition duration in ms, defaults to 0transitionTimingFunction
– defaults totheme.transitionTimingFunction
<Selecttransition="pop-top-left"transitionDuration={80}transitionTimingFunction="ease"/>
With icon
You can use any React node as icon:
<Select icon={<HashIcon />} />
Invalid state and error
// Error as boolean – red border color<Select error />// Error as React node – red border color and message below input<Select error="Pick at least one item" />
Disabled state
<Select disabled />
Right section
You can replace icon in right section with rightSection
prop.
Note that in this case clearable
option will not work and will need to handle it yourself:
<Select rightSection={<ChevronDownIcon />} />
Input props
Component supports all props from Input and InputWrapper components:
<Selectplaceholder="Pick one"label="Your favorite framework/library"requireddata={[{ value: 'react', label: 'React' },{ value: 'ng', label: 'Angular' },{ value: 'svelte', label: 'Svelte' },{ value: 'vue', label: 'Vue' },]}/>
Get element ref
You can get input ref by passing elementRef
prop to Select component:
import { useRef } from 'react';import { Select } from '@mantine/core';function Demo() {const ref = useRef(null);return <Select elementRef={ref} />;}
Server side rendering
Component uses use-id hook to generate unique ids and aria- attributes,
provide static id
prop to prevent props mismatch:
<Select /> // -> random id generated both on client and server, props mismatch warning<Select id="my-select" /> // -> id is static, no mismatches
Accessibility
Provide aria-label
in case you use component without label for screen reader support:
<Select label="My select" />; // -> ok, select and label is connected<Select />; // not ok, select is not labeled<Select aria-label="My select" />; // -> ok, label is not visible but will be announced by screen reader
If you use clearable
option set clearButtonLabel
:
<Select clearable clearButtonLabel="Clear select field" />