Base ComponentsSelect

Select

A dropdown menu for selecting one or more options.

Installation

Implement this component in your project using Yumma CSS, Base UI, and Motion.

pnpm add @base-ui/react motion

Examples

Basic

"use client";
import { Field } from "@base-ui/react/field";
import { Select } from "@base-ui/react/select";
import { CaretUpDownIcon, CheckIcon } from "@phosphor-icons/react";
import { AnimatePresence, motion } from "motion/react";
import * as React from "react";
const itemClass = (state: { highlighted: boolean }) =>
`d-f ai-c g-2 py-2 px-3 fs-sm us-none c-p br-1 mx-1 c-slate-10 ${
state.highlighted ? "bg-silver-1" : "h:bg-silver-1"
}`;
export default function ExampleSelect() {
const [open, setOpen] = React.useState(false);
return (
<Field.Root className="d-f fd-c g-2">
<label
htmlFor="select-status"
className="fs-sm fw-600 c-slate-10 us-none"
>
Status
</label>
<Select.Root defaultValue={null} open={open} onOpenChange={setOpen}>
<Select.Trigger
id="select-status"
className={`d-f ai-c jc-sb h-10 min-w-40 g-3 bw-1 bc-silver-3 br-2 bg-white px-3 c-slate-10 us-none c-p fv:os-s fv:ow-2 fv:oo-2 fv:oc-indigo-6 ${
open ? "bg-silver-1" : "h:bg-silver-1"
}`}
>
<Select.Value>
{(value) =>
value
? statuses.find((s) => s.value === value)?.label
: "Select status..."
}
</Select.Value>
<Select.Icon className="d-f c-slate-8">
<CaretUpDownIcon size={16} />
</Select.Icon>
</Select.Trigger>
<AnimatePresence>
{open && (
<Select.Portal>
<Select.Positioner sideOffset={6} className="ow-0 us-none zi-10">
<Select.Popup
render={
<motion.div
initial={{ opacity: 0, scale: 0.95 }}
animate={{ opacity: 1, scale: 1 }}
exit={{ opacity: 0, scale: 0.95 }}
transition={{ duration: 0.15, ease: "easeOut" }}
/>
}
className="bw-1 bc-silver-2 br-2 bg-white bsh-lg py-1"
style={{ minWidth: "var(--anchor-width)" }}
>
<Select.List className="p-r o-a">
{statuses.map(({ label, value }) => (
<Select.Item
key={value}
value={value}
className={itemClass}
>
<Select.ItemIndicator className="d-f ai-c">
<CheckIcon size={14} weight="bold" />
</Select.ItemIndicator>
<Select.ItemText>{label}</Select.ItemText>
</Select.Item>
))}
</Select.List>
</Select.Popup>
</Select.Positioner>
</Select.Portal>
)}
</AnimatePresence>
</Select.Root>
</Field.Root>
);
}
const statuses = [
{ label: "Draft", value: "draft" },
{ label: "In Review", value: "in-review" },
{ label: "Published", value: "published" },
{ label: "Archived", value: "archived" },
];

API Reference

Check out the Base UI documentation for more information.