- AccordionNew
- Alert
- Alert DialogNew
- AutocompleteNew
- AvatarNew
- Badge
- Breadcrumb
- Button
- CalendarNew
- CardNew
- Checkbox
- Checkbox GroupNew
- CollapsibleNew
- ComboboxNew
- CommandNew
- Context MenuNew
- Date PickerNew
- DialogNew
- DrawerNew
- EmptyNew
- FieldNew
- FieldsetNew
- FormNew
- FrameNew
- GroupNew
- Input
- Input GroupNew
- KbdNew
- Label
- MenuNew
- MeterNew
- Number Field
- OTP FieldNew
- Pagination
- PopoverNew
- Preview CardNew
- Progress
- Radio Group
- Scroll AreaNew
- Select
- Separator
- SheetNew
- SkeletonNew
- Slider
- Spinner
- StepperNew
- Switch
- Table
- TabsNew
- Textarea
- ToastNew
- ToggleNew
- Toggle GroupNew
- ToolbarNew
- Tooltip
Select
A common form component for choosing a predefined value in a dropdown menu.
import {
Select,
SelectItem,
SelectPopup,
SelectTrigger,
SelectValue,
} from "mako-ui/components/select";
const items = [
{ label: "Next.js", value: "next" },
{ label: "Vite", value: "vite" },
{ label: "Astro", value: "astro" },
];
export default function Particle() {
return (
<Select defaultValue="next" items={items}>
<SelectTrigger aria-label="Select framework">
<SelectValue />
</SelectTrigger>
<SelectPopup>
{items.map(({ label, value }) => (
<SelectItem key={value} value={value}>
{label}
</SelectItem>
))}
</SelectPopup>
</Select>
);
}
Usage
import {
Select,
SelectItem,
SelectPopup,
SelectLabel,
SelectTrigger,
SelectValue,
} from "mako-ui/components/select"const items = [
{ label: "Select framework", value: null },
{ label: "Next.js", value: "next" },
{ label: "Vite", value: "vite" },
{ label: "Astro", value: "astro" },
]
<Select items={items}>
<SelectTrigger>
<SelectValue />
</SelectTrigger>
<SelectPopup>
<SelectLabel>Frameworks</SelectLabel>
{items.map((item) => (
<SelectItem key={item.value} value={item}>
{item.label}
</SelectItem>
))}
</SelectPopup>
</Select>API Reference
Select
Root component.
SelectTrigger
Trigger button that opens the select dropdown.
| Prop | Type | Default | Description |
|---|---|---|---|
size | "sm" | "default" | "lg" | "default" | Controls the size of the trigger |
SelectValue
Displays the selected value.
SelectPopup
Popup container for select options. Also exported as SelectContent.
| Prop | Type | Default | Description |
|---|---|---|---|
alignItemWithTrigger | boolean | true | Aligns the selected item with the trigger |
sideOffset | number | 4 | Distance from the trigger in pixels |
portalProps | PortalProps | - | Props forwarded to the internal portal (keepMounted, container, etc.) |
SelectItem
Individual select option. Includes built-in indicator.
SelectGroup
Groups related select items.
SelectLabel
Label for all options in the popup. Clicking it focuses the select trigger without opening the popup.
SelectGroupLabel
Label for a select group.
SelectSeparator
Visual separator between items.
SelectButton
A standalone button styled like a SelectTrigger. Use it as a render prop on other trigger components (e.g., ComboboxTrigger, MenuTrigger) to give them select-like appearance.
| Prop | Type | Default | Description |
|---|---|---|---|
size | "sm" | "default" | "lg" | "default" | Controls the size of the button |
import { SelectButton } from "mako-ui/components/select"<ComboboxTrigger render={<SelectButton />}>
<ComboboxValue placeholder="Select a fruit" />
</ComboboxTrigger>Examples
For accessible labelling and validation, prefer using the Field component to wrap selects. See the related example: Select field.
Small Size
import {
Select,
SelectItem,
SelectPopup,
SelectTrigger,
SelectValue,
} from "mako-ui/components/select";
const items = [
{ label: "Next.js", value: "next" },
{ label: "Vite", value: "vite" },
{ label: "Astro", value: "astro" },
];
export default function Particle() {
return (
<Select items={items}>
<SelectTrigger size="sm" aria-label="Select framework">
<SelectValue placeholder="Select framework" />
</SelectTrigger>
<SelectPopup>
{items.map(({ label, value }) => (
<SelectItem key={value} value={value}>
{label}
</SelectItem>
))}
</SelectPopup>
</Select>
);
}
Large Size
import {
Select,
SelectItem,
SelectPopup,
SelectTrigger,
SelectValue,
} from "mako-ui/components/select";
const items = [
{ label: "Next.js", value: "next" },
{ label: "Vite", value: "vite" },
{ label: "Astro", value: "astro" },
];
export default function Particle() {
return (
<Select items={items}>
<SelectTrigger size="lg" aria-label="Select framework">
<SelectValue placeholder="Select framework" />
</SelectTrigger>
<SelectPopup>
{items.map(({ label, value }) => (
<SelectItem key={value} value={value}>
{label}
</SelectItem>
))}
</SelectPopup>
</Select>
);
}
Disabled
import {
Select,
SelectItem,
SelectPopup,
SelectTrigger,
SelectValue,
} from "mako-ui/components/select";
const items = [
{ label: "Next.js", value: "next" },
{ label: "Vite", value: "vite" },
{ label: "Astro", value: "astro" },
];
export default function Particle() {
return (
<Select items={items}>
<SelectTrigger disabled aria-label="Select framework">
<SelectValue placeholder="Select framework" />
</SelectTrigger>
<SelectPopup>
{items.map(({ label, value }) => (
<SelectItem key={value} value={value}>
{label}
</SelectItem>
))}
</SelectPopup>
</Select>
);
}
Without Item Alignment
import {
Select,
SelectItem,
SelectPopup,
SelectTrigger,
SelectValue,
} from "mako-ui/components/select";
const items = [
{ label: "Next.js", value: "next" },
{ label: "Vite", value: "vite" },
{ label: "Astro", value: "astro" },
];
export default function Particle() {
return (
<Select items={items}>
<SelectTrigger aria-label="Select framework">
<SelectValue placeholder="Select framework" />
</SelectTrigger>
<SelectPopup alignItemWithTrigger={false}>
{items.map(({ label, value }) => (
<SelectItem key={value} value={value}>
{label}
</SelectItem>
))}
</SelectPopup>
</Select>
);
}
With Groups
import {
Select,
SelectGroup,
SelectGroupLabel,
SelectItem,
SelectPopup,
SelectSeparator,
SelectTrigger,
SelectValue,
} from "mako-ui/components/select";
const frontend = [
{ label: "Next.js", value: "next" },
{ label: "Vite", value: "vite" },
{ label: "Astro", value: "astro" },
];
const backend = [
{ label: "Express", value: "express" },
{ label: "NestJS", value: "nestjs" },
{ label: "Fastify", value: "fastify" },
{ label: "Django", value: "django" },
{ label: "Flask", value: "flask" },
{ label: "Rails", value: "rails" },
];
export default function Particle() {
return (
<Select items={[...frontend, ...backend]}>
<SelectTrigger aria-label="Select framework">
<SelectValue placeholder="Select framework" />
</SelectTrigger>
<SelectPopup>
<SelectGroup>
<SelectGroupLabel>Frontend</SelectGroupLabel>
{frontend.map(({ label, value }) => (
<SelectItem key={value} value={value}>
{label}
</SelectItem>
))}
</SelectGroup>
<SelectSeparator />
<SelectGroup>
<SelectGroupLabel>Backend</SelectGroupLabel>
{backend.map(({ label, value }) => (
<SelectItem key={value} value={value}>
{label}
</SelectItem>
))}
</SelectGroup>
</SelectPopup>
</Select>
);
}
With Label
import {
Select,
SelectItem,
SelectLabel,
SelectPopup,
SelectTrigger,
SelectValue,
} from "mako-ui/components/select";
const items = [
{ label: "Apple", value: "apple" },
{ label: "Banana", value: "banana" },
{ label: "Orange", value: "orange" },
];
export default function Particle() {
return (
<Select defaultValue={items[0]} items={items}>
<SelectLabel>Fruits</SelectLabel>
<SelectTrigger aria-label="Select fruit">
<SelectValue />
</SelectTrigger>
<SelectPopup>
{items.map((item) => (
<SelectItem key={item.value} value={item}>
{item.label}
</SelectItem>
))}
</SelectPopup>
</Select>
);
}
Multiple Selection
"use client";
import {
Select,
SelectItem,
SelectPopup,
SelectTrigger,
SelectValue,
} from "mako-ui/components/select";
const languages = {
cpp: "C++",
csharp: "C#",
go: "Go",
java: "Java",
javascript: "JavaScript",
php: "PHP",
python: "Python",
rust: "Rust",
swift: "Swift",
typescript: "TypeScript",
};
type Language = keyof typeof languages;
const values = Object.keys(languages) as Language[];
function renderValue(value: Language[]) {
if (value.length === 0) {
return "Select languages…";
}
const firstLanguage = value[0] ? languages[value[0]] : "";
const additionalLanguages =
value.length > 1 ? ` (+${value.length - 1} more)` : "";
return firstLanguage + additionalLanguages;
}
export default function Particle() {
return (
<Select defaultValue={["javascript", "typescript"]} multiple>
<SelectTrigger aria-label="Select languages">
<SelectValue>{renderValue}</SelectValue>
</SelectTrigger>
<SelectPopup alignItemWithTrigger={false}>
{values.map((value) => (
<SelectItem key={value} value={value}>
{languages[value]}
</SelectItem>
))}
</SelectPopup>
</Select>
);
}
With Icon
import { CableIcon } from "lucide-react";
import {
Select,
SelectItem,
SelectPopup,
SelectTrigger,
SelectValue,
} from "mako-ui/components/select";
const items = [
{ label: "Next.js", value: "next" },
{ label: "Vite", value: "vite" },
{ label: "Astro", value: "astro" },
];
export default function Particle() {
return (
<Select defaultValue="next" items={items}>
<SelectTrigger aria-label="Select framework with icon">
<CableIcon aria-hidden="true" />
<SelectValue />
</SelectTrigger>
<SelectPopup alignItemWithTrigger={false}>
{items.map(({ label, value }) => (
<SelectItem key={value} value={value}>
{label}
</SelectItem>
))}
</SelectPopup>
</Select>
);
}
Options with Icon
"use client";
import { Code2Icon, GlobeIcon, LayersIcon, ZapIcon } from "lucide-react";
import {
Select,
SelectItem,
SelectPopup,
SelectTrigger,
SelectValue,
} from "mako-ui/components/select";
const items = [
{ icon: LayersIcon, label: "Components", value: "components" },
{ icon: ZapIcon, label: "Performance", value: "performance" },
{ icon: GlobeIcon, label: "Network", value: "network" },
{ icon: Code2Icon, label: "Development", value: "development" },
];
export default function Particle() {
return (
<Select defaultValue={items[0]} itemToStringValue={(item) => item.value}>
<SelectTrigger aria-label="Select category">
<SelectValue>
{(item) => (
<span className="flex items-center gap-2">
<item.icon />
<span className="truncate">{item.label}</span>
</span>
)}
</SelectValue>
</SelectTrigger>
<SelectPopup>
{items.map((item) => (
<SelectItem key={item.value} value={item}>
<span className="flex items-center gap-2">
<item.icon />
<span className="truncate">{item.label}</span>
</span>
</SelectItem>
))}
</SelectPopup>
</Select>
);
}
With Object Values
"use client";
import {
Select,
SelectItem,
SelectPopup,
SelectTrigger,
SelectValue,
} from "mako-ui/components/select";
const items = [
{ description: "npx create-next-app", label: "Next.js", value: "next" },
{ description: "npm create vite@latest", label: "Vite", value: "vite" },
{ description: "npm create astro@latest", label: "Astro", value: "astro" },
{ description: "npx create-remix", label: "Remix", value: "remix" },
];
export default function Particle() {
return (
<Select defaultValue={items[0]} itemToStringValue={(item) => item.value}>
<SelectTrigger
className="py-1"
aria-label="Select framework with command"
>
<SelectValue>
{(item) => (
<span className="flex flex-col">
<span className="truncate">{item.label}</span>
<span className="truncate text-muted-foreground text-xs">
{item.description}
</span>
</span>
)}
</SelectValue>
</SelectTrigger>
<SelectPopup>
{items.map((item) => (
<SelectItem key={item.value} value={item}>
<span className="flex flex-col">
<span className="truncate">{item.label}</span>
<span className="truncate text-muted-foreground text-xs">
{item.description}
</span>
</span>
</SelectItem>
))}
</SelectPopup>
</Select>
);
}
SelectButton with Combobox
Use SelectButton as a render prop on ComboboxTrigger to create a combobox that looks like a select.
"use client";
import {
Combobox,
ComboboxEmpty,
ComboboxInput,
ComboboxItem,
ComboboxList,
ComboboxPopup,
ComboboxTrigger,
ComboboxValue,
} from "mako-ui/components/combobox";
import { SelectButton } from "mako-ui/components/select";
import { MagnifyingGlass } from "mako-ui/icons/magnifying-glass";
const items = [
{ label: "Apple", value: "apple" },
{ label: "Banana", value: "banana" },
{ label: "Orange", value: "orange" },
{ label: "Grape", value: "grape" },
{ label: "Strawberry", value: "strawberry" },
{ label: "Mango", value: "mango" },
{ label: "Pineapple", value: "pineapple" },
{ label: "Kiwi", value: "kiwi" },
{ label: "Peach", value: "peach" },
{ label: "Pear", value: "pear" },
];
export default function Particle() {
return (
<Combobox items={items}>
<ComboboxTrigger aria-label="Select a fruit" render={<SelectButton />}>
<ComboboxValue placeholder="Select a fruit" />
</ComboboxTrigger>
<ComboboxPopup aria-label="Select a fruit">
<div className="border-b p-2">
<ComboboxInput
className="rounded-md before:rounded-[calc(var(--radius-md)-1px)]"
placeholder="Search fruits..."
showTrigger={false}
startAddon={<MagnifyingGlass />}
/>
</div>
<ComboboxEmpty>No items found.</ComboboxEmpty>
<ComboboxList>
{(item) => (
<ComboboxItem key={item.value} value={item}>
{item.label}
</ComboboxItem>
)}
</ComboboxList>
</ComboboxPopup>
</Combobox>
);
}
Form Integration
"use client";
import { Button } from "mako-ui/components/button";
import {
Field,
FieldDescription,
FieldError,
FieldLabel,
} from "mako-ui/components/field";
import { Form } from "mako-ui/components/form";
import {
Select,
SelectItem,
SelectPopup,
SelectTrigger,
SelectValue,
} from "mako-ui/components/select";
import type { FormEvent } from "react";
import { useState } from "react";
const items = [
{ label: "Next.js", value: "next" },
{ label: "Vite", value: "vite" },
{ label: "Astro", value: "astro" },
];
function stringValue(formData: FormData, name: string): string {
const value = formData.get(name);
return typeof value === "string" ? value : "";
}
export default function Particle() {
const [loading, setLoading] = useState(false);
const onSubmit = async (e: FormEvent<HTMLFormElement>) => {
e.preventDefault();
const formData = new FormData(e.currentTarget);
setLoading(true);
await new Promise((r) => setTimeout(r, 800));
setLoading(false);
alert(`Framework: ${stringValue(formData, "framework")}`);
};
return (
<Form className="flex w-full max-w-64 flex-col gap-4" onSubmit={onSubmit}>
<Field>
<FieldLabel>Framework</FieldLabel>
<Select items={items} name="framework" required>
<SelectTrigger aria-label="Select framework">
<SelectValue placeholder="Select a framework" />
</SelectTrigger>
<SelectPopup>
{items.map(({ label, value }) => (
<SelectItem key={value} value={value}>
{label}
</SelectItem>
))}
</SelectPopup>
</Select>
<FieldDescription>Pick your favorite.</FieldDescription>
<FieldError>Please select a value.</FieldError>
</Field>
<Button loading={loading} type="submit">
Submit
</Button>
</Form>
);
}
On This Page