Select

Select allows to create a dropdown list of options.

Source
Theme Source
pnpm dlx dreamy add select

Basic 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>
    );
}

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>