pnpm dlx dreamy add selectBasic usage of Select.
<Select.Root>
<Select.Trigger placeholder="Select a favorite fruit" />
<Select.Content>
<Select.Item value="strawberry">Strawberry</Select.Item>
<Select.Item value="banana">Banana</Select.Item>
<Select.Item value="orange">Orange</Select.Item>
</Select.Content>
</Select.Root>Select comes with 4 different sizes.
<Select.Root width="xs" size={"xs"}>
<Select.Trigger placeholder="Select a favorite fruit" />
<Select.Content>
<Select.Item value="strawberry">Strawberry</Select.Item>
<Select.Item value="banana">Banana</Select.Item>
<Select.Item value="orange">Orange</Select.Item>
</Select.Content>
</Select.Root>
<Select.Root width="xs" size={"sm"}>
<Select.Trigger placeholder="Select a favorite fruit" />
<Select.Content>
<Select.Item value="strawberry">Strawberry</Select.Item>
<Select.Item value="banana">Banana</Select.Item>
<Select.Item value="orange">Orange</Select.Item>
</Select.Content>
</Select.Root>
<Select.Root width="xs" size={"md"}>
<Select.Trigger placeholder="Select a favorite fruit" />
<Select.Content>
<Select.Item value="strawberry">Strawberry</Select.Item>
<Select.Item value="banana">Banana</Select.Item>
<Select.Item value="orange">Orange</Select.Item>
</Select.Content>
</Select.Root>
<Select.Root width="xs" size={"lg"}>
<Select.Trigger placeholder="Select a favorite fruit" />
<Select.Content>
<Select.Item value="strawberry">Strawberry</Select.Item>
<Select.Item value="banana">Banana</Select.Item>
<Select.Item value="orange">Orange</Select.Item>
</Select.Content>
</Select.Root>Select can be used in outline or solid variant.
<Select.Root width="xs" variant={"outline"}>
<Select.Trigger placeholder="Select a favorite fruit" />
<Select.Content>
<Select.Item value="strawberry">Strawberry</Select.Item>
<Select.Item value="banana">Banana</Select.Item>
<Select.Item value="orange">Orange</Select.Item>
</Select.Content>
</Select.Root>
<Select.Root width="xs" variant={"solid"}>
<Select.Trigger placeholder="Select a favorite fruit" />
<Select.Content>
<Select.Item value="strawberry">Strawberry</Select.Item>
<Select.Item value="banana">Banana</Select.Item>
<Select.Item value="orange">Orange</Select.Item>
</Select.Content>
</Select.Root>You can customize the background color of the selected item. This will only apply if selectedStrategy is set to both or background.
primary
success
warning
info
error
none
{["primary", "success", "warning", "info", "error", "none"].map((scheme) => (
<>
<Text>{scheme}</Text>
<Select.Root width="xs" selectedItemBackgroundScheme={scheme} defaultValue="strawberry">
<Select.Trigger placeholder="Select a favorite fruit" />
<Select.Content>
<Select.Item value="strawberry">Strawberry</Select.Item>
<Select.Item value="banana">Banana</Select.Item>
<Select.Item value="orange">Orange</Select.Item>
</Select.Content>
</Select.Root>
</>
))}export function ControlledSelect() {
const [value, setValue] = useState<string>("strawberry");
return (
<Select.Root
value={value}
onChangeValue={setValue}
width="xs"
>
<Select.Trigger
placeholder="Select a favorite fruit"
/>
<Select.Content>
<Select.Item value="strawberry">Strawberry</Select.Item>
<Select.Item value="banana">Banana</Select.Item>
<Select.Item value="orange">Orange</Select.Item>
</Select.Content>
</Select.Root>
);
}You can customize how the selected value is marked as selected.
both
checkmark
background
<Wrapper>
{["both", "checkmark", "background"].map((strategy) => (
<>
<Text>{strategy}</Text>
<Select.Root
key={strategy}
selectedStrategy={strategy}
width="xs"
>
<Select.Trigger placeholder="Select a favorite fruit" />
<Select.Content>
<Select.Item value="strawberry">Strawberry</Select.Item>
<Select.Item value="banana">Banana</Select.Item>
<Select.Item value="orange">Orange</Select.Item>
</Select.Content>
</Select.Root>
</>
))}
</Wrapper>You can place icons, custom children in the Select.Item to indicate the type of the option.
<Select.Root width="xs">
<Select.Trigger placeholder="Select a favorite fruit" />
<Select.Content>
<Select.Item value="cherry">
<HStack>
<LuCherry />
<Text>Cherry</Text>
</HStack>
</Select.Item>
<Select.Item value="banana">
<HStack>
<LuBanana />
<Text>Banana</Text>
</HStack>
</Select.Item>
<Select.Item value="orange">
<HStack>
<LuCitrus />
<Text>Orange</Text>
</HStack>
</Select.Item>
</Select.Content>
</Select.Root>Single icon is useful if you want to have global icon for a trigger, instead of having it on each item.
<Select.Root width="xs">
<Select.Trigger placeholder="Select a favorite fruit" icon={<LuCherry />} />
<Select.Content>
<Select.Item value="cherry">Cherry</Select.Item>
<Select.Item value="banana">Banana</Select.Item>
<Select.Item value="orange">Orange</Select.Item>
</Select.Content>
</Select.Root>Pass isClearable prop to enable clear button.
<Select.Root width="xs" isClearable>
<Select.Trigger placeholder="Select a favorite fruit" />
<Select.Content>
<Select.Item value="cherry">Cherry</Select.Item>
<Select.Item value="banana">Banana</Select.Item>
<Select.Item value="orange">Orange</Select.Item>
</Select.Content>
</Select.Root>You can use the isMultiple prop to allow multiple selection. Now onChangeValue will return an array of values, instead of a single string value.
export function MultipleSelect() {
return (
<Select.Root width="xs" isMultiple>
<Select.Trigger placeholder="Select a favorite fruit" />
<Select.Content>
<Select.Item value="strawberry">Strawberry</Select.Item>
<Select.Item value="banana">Banana</Select.Item>
<Select.Item value="orange">Orange</Select.Item>
</Select.Content>
</Select.Root>
);
}You can change the text that Select displays when multiple keys are selected by using multipleSelectedText prop in Select.Trigger.
export function MultipleSelect() {
return (
<Select.Root width="xs" isMultiple>
<Select.Trigger
placeholder="Select a favorite fruit"
multipleSelectedText={(selectedKeys) => `${selectedKeys.join(", ")}`}
/>
<Select.Content>
<Select.Item value="strawberry">Strawberry</Select.Item>
<Select.Item value="banana">Banana</Select.Item>
<Select.Item value="orange">Orange</Select.Item>
</Select.Content>
</Select.Root>
);
}You can fetch data when the Select is opened.
export function AsyncSelect() {
const [isLoading, setIsLoading] = useState(true);
const [fruits, setFruits] = useState<string[]>([]);
function fetchFruits() {
if (fruits.length > 0) return;
fetch("/api/fake-select-data") // slowed by 1 second
.then((res) => res.json())
.then(setFruits)
.finally(() => setIsLoading(false));
}
return (
<Select.Root width="xs" onOpen={fetchFruits}>
<Select.Trigger placeholder="Select a favorite fruit" />
<Select.Content>
{isLoading && (
<Spinner
color="primary"
py={4}
/>
)}
{fruits.map((fruit) => (
<Select.Item
key={fruit}
value={fruit}
>
{fruit}
</Select.Item>
))}
</Select.Content>
</Select.Root>
);
}For better performance with large lists (100+ items), use Select.VirtualContent instead of Select.Content. It only renders visible items, significantly improving rendering performance and reducing memory usage.
<Select.Root width="xs">
<Select.Trigger placeholder="Select a number" />
<Select.VirtualContent>
{Array.from({ length: 250 }).map((_, index) => (
<Select.Item
key={index}
value={index.toString()}
>
Item {index + 1}
</Select.Item>
))}
</Select.VirtualContent>
</Select.Root>Props
estimatedItemHeight- Estimated height of each item in pixels. Used for virtualization calculations. For different select sizes the values will be:xs:26,sm:28,md:32,lg:40. Default:32overscan- Number of items to render outside the visible area. Higher values reduce flickering during fast scrolling but increase initial render cost. Default:5maxHeight- Maximum height of the virtualized list container in pixels. Default:300
<Select.Root width="xs">
<Select.Trigger placeholder="Select a number" />
<Select.VirtualContent
maxHeight={400}
estimatedItemHeight={36}
overscan={10}
>
{largeItemsList.map((item) => (
<Select.Item
key={item.value}
value={item.value}
>
{item.label}
</Select.Item>
))}
</Select.VirtualContent>
</Select.Root>Note: Selected items are always rendered (even when scrolled out of view) to ensure the trigger can display the selected value correctly.
You can customize whether the Select should close when an item is selected. Defalult is true for non-multiple select, false for multiple select.
<Select.Root width="xs" closeOnSelect={false}>
<Select.Trigger placeholder="Select a favorite fruit" />
<Select.Content>
<Select.Item value="strawberry">Strawberry</Select.Item>
<Select.Item value="banana">Banana</Select.Item>
<Select.Item value="orange">Orange</Select.Item>
</Select.Content>
</Select.Root>You can disable the animation of the Select by setting the reduceMotion prop to true. You'll see no difference now if your device has currently reduced motion enabled globally.
<Select.Root width="xs" reduceMotion>
<Select.Trigger placeholder="Select a favorite fruit" />
<Select.Content>
<Select.Item value="strawberry">Strawberry</Select.Item>
<Select.Item value="banana">Banana</Select.Item>
<Select.Item value="orange">Orange</Select.Item>
</Select.Content>
</Select.Root>