Select
Select provides a dropdown interface for choosing from predefined options. It supports single and multi-selection modes, disabled states, validation, and customizable styling.
Source
LLM docs
Package
Examples
5
Properties
71
Playground
Basics
Simple single-value select with helper copy and live selection feedback.
Loading demo…
import { Select } from '@plocks/ui'
import { sports } from '../data'
export function Demo() {
return (
<Select
label="Favorite sport"
description="Choose your favorite sport"
placeholder="Choose a sport"
options={sports}
/>
)
}Variants
Select accepts the same variant prop as <Input> — default, filled, outline, unstyled — and shares the underlying input styles, so the trigger reads consistently with text inputs in the same form.Loading demo…
import { useState } from 'react'
import { Block, Select } from '@plocks/ui'
import { sports } from '../data'
const variants = [
{ variant: 'default', label: 'Default' },
{ variant: 'filled', label: 'Filled' },
{ variant: 'outline', label: 'Outline' },
{ variant: 'unstyled', label: 'Unstyled' },
] as const
export function Demo() {
const [value, setValue] = useState<string | null>(null)
return (
<Block flex>
{variants.map(({ variant, label }) => (
<Select
key={variant}
variant={variant}
label={label}
placeholder="Pick one…"
options={sports}
value={value}
onChange={(v) => setValue(v as string | null)}
/>
))}
</Block>
)
}Custom rendering
Render each option with additional detail and selection styling using
renderOption.Loading demo…
import { useState } from 'react'
import { Block, Icon, Select, Text, useTheme } from '@plocks/ui'
import { detailedSports, type DetailedSport } from '../data'
export function Demo() {
const theme = useTheme()
const [value, setValue] = useState<string | null>(detailedSports[0].value)
const accent = theme.colorScheme === 'dark' ? theme.colors.primary[5] : theme.colors.primary[6]
return (
<Block w={400}>
<Select
label="Choose a sport"
placeholder="Pick a sport"
options={detailedSports}
value={value}
onChange={(selected) => setValue(selected as string)}
renderOption={(option, active, selected) => {
const { emoji, name, description } = option as DetailedSport
return (
<Block
direction="row"
align="center"
gap={12}
style={{
padding: 12,
borderLeftWidth: 3,
borderLeftColor: active || selected ? accent : 'transparent',
backgroundColor: selected ? theme.colors.primary[0] : undefined,
}}
>
<Text size="3xl">{emoji}</Text>
<Block direction="column" style={{ flex: 1 }} gap={0}>
<Text fw={selected ? '900' : '600'}>{name}</Text>
<Text size="sm" c="secondary">
{description}
</Text>
</Block>
{selected ? <Icon name="check" size={16} color={accent} /> : null}
</Block>
)
}}
/>
</Block>
)
}Disabled states
Disable individual options or the full control to reflect availability.
Loading demo…
import { useState } from 'react'
import { Block, Select } from '@plocks/ui'
import { sports } from '../data'
// One option is taken out of play to show the per-option disabled state next to
// the whole-field one.
const options = sports.map((option) =>
option.value === 'basketball' ? { ...option, label: 'Basketball (disabled)', disabled: true } : option,
)
export function Demo() {
const [value, setValue] = useState<string | null>(sports[0].value)
return (
<Block flex direction="row">
<Select
label="Disabled option example"
options={options}
value={value}
onChange={(val) => setValue(val as string)}
/>
<Select label="Entire select disabled" options={options} value={value} disabled />
</Block>
)
}Persistent menu
Keep the dropdown open after each choice for quick comparisons.
Loading demo…
import { useState } from 'react'
import { Select } from '@plocks/ui'
import { sports } from '../data'
export function Demo() {
const [value, setValue] = useState<string | null>(null)
return (
<Select
label="Persistent menu"
description="Menu doesn't close on option press"
options={sports}
value={value}
onChange={(val) => setValue(val as string)}
closeOnSelect={false}
/>
)
}React Native design for iOS, Android, and Web.
Quick Links
Resources