Select

Select allows to create a dropdown list of options.

Source
Theme Source
  • Select - The Select component with context.
  • SelectTrigger - The trigger for the Select.
  • SelectContent - The content for the Select as popover.
  • SelectItem - The item for the Select.
import { 
	Select,
    SelectItem,
    SelectContent,
    SelectTrigger
 } from "@dreamy-ui/react";

Basic usage of Select.

<Select>
    <SelectTrigger placeholder="Select a favorite fruit" />
    <SelectContent>
        <SelectItem value="strawberry">Strawberry</SelectItem>
        <SelectItem value="banana">Banana</SelectItem>
        <SelectItem value="orange">Orange</SelectItem>
    </SelectContent>
</Select>

Select comes with 4 different sizes.

<Select width="xs" size={"xs"}>
    <SelectTrigger placeholder="Select a favorite fruit" />
    <SelectContent>
        <SelectItem value="strawberry">Strawberry</SelectItem>
        <SelectItem value="banana">Banana</SelectItem>
        <SelectItem value="orange">Orange</SelectItem>
    </SelectContent>
</Select>
<Select width="xs" size={"sm"}>
    <SelectTrigger placeholder="Select a favorite fruit" />
    <SelectContent>
        <SelectItem value="strawberry">Strawberry</SelectItem>
        <SelectItem value="banana">Banana</SelectItem>
        <SelectItem value="orange">Orange</SelectItem>
    </SelectContent>
</Select>
<Select width="xs" size={"md"}>
    <SelectTrigger placeholder="Select a favorite fruit" />
    <SelectContent>
        <SelectItem value="strawberry">Strawberry</SelectItem>
        <SelectItem value="banana">Banana</SelectItem>
        <SelectItem value="orange">Orange</SelectItem>
    </SelectContent>
</Select>
<Select width="xs" size={"lg"}>
    <SelectTrigger placeholder="Select a favorite fruit" />
    <SelectContent>
        <SelectItem value="strawberry">Strawberry</SelectItem>
        <SelectItem value="banana">Banana</SelectItem>
        <SelectItem value="orange">Orange</SelectItem>
    </SelectContent>
</Select>

Select can be used in outline or solid variant.

<Select width="xs" variant={"outline"}>
    <SelectTrigger placeholder="Select a favorite fruit" />
    <SelectContent>
        <SelectItem value="strawberry">Strawberry</SelectItem>
        <SelectItem value="banana">Banana</SelectItem>
        <SelectItem value="orange">Orange</SelectItem>
    </SelectContent>
</Select>
<Select width="xs" variant={"solid"}>
    <SelectTrigger placeholder="Select a favorite fruit" />
    <SelectContent>
        <SelectItem value="strawberry">Strawberry</SelectItem>
        <SelectItem value="banana">Banana</SelectItem>
        <SelectItem value="orange">Orange</SelectItem>
    </SelectContent>
</Select>

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 width="xs" selectedItemBackgroundScheme={scheme} defaultValue="strawberry">
            <SelectTrigger placeholder="Select a favorite fruit" />
            <SelectContent>
                <SelectItem value="strawberry">Strawberry</SelectItem>
                <SelectItem value="banana">Banana</SelectItem>
                <SelectItem value="orange">Orange</SelectItem>
            </SelectContent>
        </Select>
    </>
))}
export function ControlledSelect() {
    const [value, setValue] = useState<string>("strawberry");
 
    return (
        <Select
            value={value}
            onChangeValue={setValue}
            width="xs"
        >
            <SelectTrigger
                placeholder="Select a favorite fruit"
            />
            <SelectContent>
                <SelectItem value="strawberry">Strawberry</SelectItem>
                <SelectItem value="banana">Banana</SelectItem>
                <SelectItem value="orange">Orange</SelectItem>
            </SelectContent>
        </Select>
    );
}

You can customize how the selected value is marked as selected.

both

checkmark

background

<Wrapper>
    {["both", "checkmark", "background"].map((strategy) => (
        <>
            <Text>{strategy}</Text>
            <Select
                key={strategy}
                selectedStrategy={strategy}
                width="xs"
            >
                <SelectTrigger placeholder="Select a favorite fruit" />
                <SelectContent>
                    <SelectItem value="strawberry">Strawberry</SelectItem>
                    <SelectItem value="banana">Banana</SelectItem>
                    <SelectItem value="orange">Orange</SelectItem>
                </SelectContent>
            </Select>
        </>
    ))}
</Wrapper>

You can place icons, custom children in the SelectItem to indicate the type of the option.

<Select width="xs">
    <SelectTrigger placeholder="Select a favorite fruit" />
    <SelectContent>
        <SelectItem value="cherry">
            <HStack>
                <LuCherry />
                <Text>Cherry</Text>
            </HStack>
        </SelectItem>
        <SelectItem value="banana">
            <HStack>
                <LuBanana />
                <Text>Banana</Text>
            </HStack>
        </SelectItem>
        <SelectItem value="orange">
            <HStack>
                <LuCitrus />
                <Text>Orange</Text>
            </HStack>
        </SelectItem>
    </SelectContent>
</Select>

Single icon is useful if you want to have global icon for a trigger, instead of having it on each item.

<Select width="xs">
    <SelectTrigger placeholder="Select a favorite fruit" icon={<LuCherry />} />
    <SelectContent>
        <SelectItem value="cherry">Cherry</SelectItem>
        <SelectItem value="banana">Banana</SelectItem>
        <SelectItem value="orange">Orange</SelectItem>
    </SelectContent>
</Select>

Pass isClearable prop to enable clear button.

<Select width="xs" isClearable>
    <SelectTrigger placeholder="Select a favorite fruit" />
    <SelectContent>
        <SelectItem value="cherry">Cherry</SelectItem>
        <SelectItem value="banana">Banana</SelectItem>
        <SelectItem value="orange">Orange</SelectItem>
    </SelectContent>
</Select>

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 width="xs" isMultiple>
            <SelectTrigger placeholder="Select a favorite fruit" />
            <SelectContent>
                <SelectItem value="strawberry">Strawberry</SelectItem>
                <SelectItem value="banana">Banana</SelectItem>
                <SelectItem value="orange">Orange</SelectItem>
            </SelectContent>
        </Select>
    );
}

You can change the text that Select displays when multiple keys are selected by using multipleSelectedText prop in SelectTrigger.

export function MultipleSelect() {
    return (
        <Select width="xs" isMultiple>
            <SelectTrigger
                placeholder="Select a favorite fruit"
                multipleSelectedText={(selectedKeys) => `${selectedKeys.join(", ")}`}
            />
            <SelectContent>
                <SelectItem value="strawberry">Strawberry</SelectItem>
                <SelectItem value="banana">Banana</SelectItem>
                <SelectItem value="orange">Orange</SelectItem>
            </SelectContent>
        </Select>
    );
}

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 width="xs" onOpen={fetchFruits}>
            <SelectTrigger placeholder="Select a favorite fruit" />
            <SelectContent>
                {isLoading && (
                    <Spinner
                        color="primary"
                        py={4}
                    />
                )}
                {fruits.map((fruit) => (
                    <SelectItem
                        key={fruit}
                        value={fruit}
                    >
                        {fruit}
                    </SelectItem>
                ))}
            </SelectContent>
        </Select>
    );
}

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 width="xs" closeOnSelect={false}>
    <SelectTrigger placeholder="Select a favorite fruit" />
    <SelectContent>
        <SelectItem value="strawberry">Strawberry</SelectItem>
        <SelectItem value="banana">Banana</SelectItem>
        <SelectItem value="orange">Orange</SelectItem>
    </SelectContent>
</Select>

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 width="xs" reduceMotion>
    <SelectTrigger placeholder="Select a favorite fruit" />
    <SelectContent>
        <SelectItem value="strawberry">Strawberry</SelectItem>
        <SelectItem value="banana">Banana</SelectItem>
        <SelectItem value="orange">Orange</SelectItem>
    </SelectContent>
</Select>