Build / Molecules
Select
A dropdown built on the native <select>.
Native on purpose: it gets platform keyboard behaviour, mobile pickers, and
screen reader support for free. The chevron is a real <svg> rather than a
CSS background-image, so automated contrast checks can still resolve the
control's background colour.
import { Select } from '@meetcard/deck'Example
<Select label="Card type" options={[{ value: 'work', label: 'Work' }]} />Stories
Source
const Default = () => <div style={{ maxWidth: 320 }}>
<Select
label="Card type"
options={[
{ value: 'work', label: 'Work' },
{ value: 'personal', label: 'Personal' },
{ value: 'event', label: 'Event' },
]}
onChange={fn()} />
</div>;A placeholder gives an empty select a meaningful initial state.
Source
const WithPlaceholder = () => <div style={{ maxWidth: 320 }}>
<Select
label="Card type"
options={[
{ value: 'work', label: 'Work' },
{ value: 'personal', label: 'Personal' },
{ value: 'event', label: 'Event' },
]}
onChange={fn()}
placeholder="Choose a type…"
defaultValue="" />
</div>;With a description, when the options need context the labels cannot carry.
Source
const WithDescription = () => <div style={{ maxWidth: 320 }}>
<Select
label="Card type"
options={[
{ value: 'work', label: 'Work' },
{ value: 'personal', label: 'Personal' },
{ value: 'event', label: 'Event' },
]}
onChange={fn()}
description="Determines which details are shared by default." />
</div>;In error. aria-invalid is set and the message is announced.
Source
const WithError = () => <div style={{ maxWidth: 320 }}>
<Select
label="Card type"
options={[
{ value: 'work', label: 'Work' },
{ value: 'personal', label: 'Personal' },
{ value: 'event', label: 'Event' },
]}
onChange={fn()}
error="Choose a card type to continue" />
</div>;Disabled, with its value shown.
Source
const Disabled = () => <div style={{ maxWidth: 320 }}>
<Select
label="Card type"
options={[
{ value: 'work', label: 'Work' },
{ value: 'personal', label: 'Personal' },
{ value: 'event', label: 'Event' },
]}
onChange={fn()}
disabled />
</div>;One option unavailable, left in the list so it is clear it exists.
Source
const WithDisabledOption = () => <div style={{ maxWidth: 320 }}>
<Select
label="Card type"
options={[...options, { value: 'team', label: 'Team (Pro only)', disabled: true }]}
onChange={fn()} />
</div>;Regression guard. The chevron is a real <svg>, not a CSS
background-image — if it were, axe could not resolve the control's
background color and would report an inconclusive contrast result.
Source
const ChevronIsNotABackgroundImage = () => <div style={{ maxWidth: 320 }}>
<Select
label="Card type"
options={[
{ value: 'work', label: 'Work' },
{ value: 'personal', label: 'Personal' },
{ value: 'event', label: 'Event' },
]}
onChange={fn()} />
</div>;Props
| Prop | Type | Default | Description |
|---|---|---|---|
labelrequired | ReactNode | — | — |
optionsrequired | SelectItem[] | — | Plain options, or SelectOptionGroups to render native <optgroup>s. |
description | ReactNode | — | — |
error | ReactNode | — | — |
fieldClassName | string | — | — |
hideLabel | boolean | false | — |
placeholder | string | — | Renders a non-selectable first option, for empty-state selects. |
size | 'sm' | 'md' | 'lg' | 'md' | — |
Also accepts everything from Omit, so id, data-* and event handlers pass straight through.