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 size={"xs"}>
    <SelectTrigger maxW="xs" placeholder="Select a favorite fruit" />
    <SelectContent>
        <SelectItem value="strawberry">Strawberry</SelectItem>
        <SelectItem value="banana">Banana</SelectItem>
        <SelectItem value="orange">Orange</SelectItem>
    </SelectContent>
</Select>
<Select size={"sm"}>
    <SelectTrigger maxW="xs" placeholder="Select a favorite fruit" />
    <SelectContent>
        <SelectItem value="strawberry">Strawberry</SelectItem>
        <SelectItem value="banana">Banana</SelectItem>
        <SelectItem value="orange">Orange</SelectItem>
    </SelectContent>
</Select>
<Select size={"md"}>
    <SelectTrigger maxW="xs" placeholder="Select a favorite fruit" />
    <SelectContent>
        <SelectItem value="strawberry">Strawberry</SelectItem>
        <SelectItem value="banana">Banana</SelectItem>
        <SelectItem value="orange">Orange</SelectItem>
    </SelectContent>
</Select>
<Select size={"lg"}>
    <SelectTrigger maxW="xs" 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 variant={"outline"}>
    <SelectTrigger maxW="xs" placeholder="Select a favorite fruit" />
    <SelectContent>
        <SelectItem value="strawberry">Strawberry</SelectItem>
        <SelectItem value="banana">Banana</SelectItem>
        <SelectItem value="orange">Orange</SelectItem>
    </SelectContent>
</Select>
<Select variant={"solid"}>
    <SelectTrigger maxW="xs" 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 selectedItemBackgroundScheme={scheme} defaultValue="strawberry">
            <SelectTrigger maxW="xs" 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}
        >
            <SelectTrigger
                maxW="xs"
                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}
            >
                <SelectTrigger
                    maxW="xs"
                    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 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 isMultiple>
            <SelectTrigger
                maxW="xs"
                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 isMultiple>
            <SelectTrigger
                maxW="xs"
                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 onOpen={fetchFruits}>
            <SelectTrigger
                maxW="xs"
                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 closeOnSelect={false}>
    <SelectTrigger maxW="xs" 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 reduceMotion>
    <SelectTrigger maxW="xs" placeholder="Select a favorite fruit" />
    <SelectContent>
        <SelectItem value="strawberry">Strawberry</SelectItem>
        <SelectItem value="banana">Banana</SelectItem>
        <SelectItem value="orange">Orange</SelectItem>
    </SelectContent>
</Select>