select/01-select-basic-select
A simple dropdown select component with options. Use this for form inputs and user choices.
Loading interactive preview
Dropdown select component for choosing from multiple options.
import { Select } from 'ui-lab-components/select';
export function Example() {
return (
<Select>
<Select.Trigger>
<Select.Value placeholder="Select an option" />
</Select.Trigger>
<Select.Content>
<Select.List>
<Select.Item value="option1" textValue="Option 1">Option 1</Select.Item>
<Select.Item value="option2" textValue="Option 2">Option 2</Select.Item>
<Select.Item value="option3" textValue="Option 3">Option 3</Select.Item>
</Select.List>
</Select.Content>
</Select>
);
}A simple dropdown select component with options. Use this for form inputs and user choices.
import { Select } from 'ui-lab-components/select';
export const metadata = {
title: 'Basic Select',
description: 'A simple dropdown select component with options. Use this for form inputs and user choices.'
};
export default function Example() {
return (
<Select>
<Select.Trigger>
<Select.Value placeholder="Select an option" />
</Select.Trigger>
<Select.Content>
<Select.Item value="option1" textValue="Option 1">Option 1</Select.Item>
<Select.Item value="option2" textValue="Option 2">Option 2</Select.Item>
<Select.Item value="option3" textValue="Option 3">Option 3</Select.Item>
</Select.Content>
</Select>
);
}
A filterable select component with search input. Type to filter through a large list of options.
import { Select, Searchable } from 'ui-lab-components/select';
export const metadata = {
title: 'Searchable Select',
description: 'A filterable select component with search input. Type to filter through a large list of options.'
};
const countries = [
{ value: 'us', label: 'United States' },
{ value: 'ca', label: 'Canada' },
{ value: 'mx', label: 'Mexico' },
{ value: 'br', label: 'Brazil' },
{ value: 'ar', label: 'Argentina' },
{ value: 'uk', label: 'United Kingdom' },
{ value: 'fr', label: 'France' },
{ value: 'de', label: 'Germany' },
{ value: 'it', label: 'Italy' },
{ value: 'es', label: 'Spain' },
{ value: 'pt', label: 'Portugal' },
{ value: 'nl', label: 'Netherlands' },
{ value: 'be', label: 'Belgium' },
{ value: 'ch', label: 'Switzerland' },
{ value: 'at', label: 'Austria' },
{ value: 'se', label: 'Sweden' },
{ value: 'no', label: 'Norway' },
{ value: 'dk', label: 'Denmark' },
{ value: 'fi', label: 'Finland' },
{ value: 'pl', label: 'Poland' },
{ value: 'jp', label: 'Japan' },
{ value: 'cn', label: 'China' },
{ value: 'kr', label: 'South Korea' },
{ value: 'in', label: 'India' },
{ value: 'au', label: 'Australia' },
{ value: 'nz', label: 'New Zealand' },
];
export default function Example() {
return (
<Select>
<Searchable.Input placeholder="Search countries..." />
<Select.Content>
{countries.map((country) => (
<Select.Item key={country.value} value={country.value} textValue={country.label}>
{country.label}
</Select.Item>
))}
</Select.Content>
</Select>
);
}
Button trigger reveals a searchable country list with flags and dial codes inside the dropdown content.
"use client";
import { useState } from 'react';
import { Select, Searchable } from 'ui-lab-components/select';
export const metadata = {
title: 'Country Selector',
description: 'Button trigger reveals a searchable country list with flags and dial codes inside the dropdown content.'
};
const countries = [
{ value: "us", label: "United States", flag: "🇺🇸", code: "+1" },
{ value: "gb", label: "United Kingdom", flag: "🇬🇧", code: "+44" },
{ value: "de", label: "Germany", flag: "🇩🇪", code: "+49" },
{ value: "fr", label: "France", flag: "🇫🇷", code: "+33" },
{ value: "jp", label: "Japan", flag: "🇯🇵", code: "+81" },
{ value: "kr", label: "South Korea", flag: "🇰🇷", code: "+82" },
{ value: "cn", label: "China", flag: "🇨🇳", code: "+86" },
{ value: "in", label: "India", flag: "🇮🇳", code: "+91" },
{ value: "br", label: "Brazil", flag: "🇧🇷", code: "+55" },
{ value: "au", label: "Australia", flag: "🇦🇺", code: "+61" },
{ value: "ca", label: "Canada", flag: "🇨🇦", code: "+1" },
{ value: "mx", label: "Mexico", flag: "🇲🇽", code: "+52" },
];
export default function Example() {
const [country, setCountry] = useState<string | number | null>("us");
const selected = countries.find(c => c.value === country);
return (
<Select
selectedKey={country}
label={selected?.label}
onSelectionChange={setCountry}
className="w-72"
>
<Select.Trigger>
<Select.Value
placeholder="Choose a country..."
icon={selected && <span className="text-sm">{selected.flag}</span>}
/>
</Select.Trigger>
<Searchable.Content searchPlaceholder="Search countries...">
{countries.map((c) => (
<Select.Item key={c.value} value={c.value} textValue={c.label} icon={<span className="text-md">{c.flag}</span>}>
<div className="flex items-center justify-between w-full">
<span>{c.label}</span>
<span className="ml-2 text-sm text-foreground-400">{c.code}</span>
</div>
</Select.Item>
))}
</Searchable.Content>
</Select>
);
}
A multi-select that renders current values as dismissible chips and lets users add more items from the dropdown.
"use client";
import { useMemo, useState } from 'react';
import { Badge } from 'ui-lab-components/badge';
import { Flex } from 'ui-lab-components/flex';
import { Select, Searchable } from 'ui-lab-components/select';
export const metadata = {
title: 'Chip Multi-Pick',
description: 'A multi-select that renders the active values as dismissible chips and lets users add more items from the dropdown.',
};
const options = [
{ value: 'design', label: 'Design Systems' },
{ value: 'frontend', label: 'Frontend' },
{ value: 'product', label: 'Product' },
{ value: 'docs', label: 'Documentation' },
{ value: 'api', label: 'API' },
{ value: 'qa', label: 'QA' },
{ value: 'ops', label: 'Operations' },
{ value: 'research', label: 'Research' },
];
export default function Example() {
const [selectedKeys, setSelectedKeys] = useState<Array<string | number>>(['design', 'frontend']);
const selectedSet = useMemo(() => new Set(selectedKeys), [selectedKeys]);
const selectedOptions = useMemo(
() => options.filter((option) => selectedSet.has(option.value)),
[selectedSet]
);
return (
<Select
mode="multiple"
selectedKeys={selectedKeys}
onSelectionChange={setSelectedKeys}
className="w-full max-w-xl"
label={selectedOptions.map((option) => option.label).join(', ')}
>
<Select.Trigger>
<Select.Value>
{() => (
<Flex gap="xs" wrap align-center>
{selectedOptions.length > 0 ? (
selectedOptions.map((option) => (
<Badge
key={option.value}
dismissible
onDismiss={() => setSelectedKeys((prev) => prev.filter((value) => value !== option.value))}
pill
>
{option.label}
</Badge>
))
) : (
<span className="text-foreground-400">Choose one or more teams</span>
)}
</Flex>
)}
</Select.Value>
</Select.Trigger>
<Searchable.Content searchPlaceholder="Search teams...">
<Select.List>
{options.map((option) => (
<Select.Item
key={option.value}
value={option.value}
textValue={option.label}
description={selectedSet.has(option.value) ? 'Selected' : 'Click to add to chips'}
>
{option.label}
</Select.Item>
))}
</Select.List>
</Searchable.Content>
</Select>
);
}