mirror of
https://github.com/shadcn-ui/ui.git
synced 2026-06-26 22:26:05 +00:00
* feat: add phosphor icons to base ui * feat_ add phosphor to blocks * feat: add phosphor to radix blocks * feat: add phosphor to radix ui * feat: add phosphor to radix example * feat: add missing phosphor icons * fix: rename broken icons * chore: format files * fix: add missing phosphor icons * chore: build registry --------- Co-authored-by: shadcn <m@shadcn.com>
679 lines
18 KiB
TypeScript
679 lines
18 KiB
TypeScript
"use client"
|
|
|
|
import {
|
|
Example,
|
|
ExampleWrapper,
|
|
} from "@/registry/bases/base/components/example"
|
|
import { Button } from "@/registry/bases/base/ui/button"
|
|
import {
|
|
Dialog,
|
|
DialogContent,
|
|
DialogDescription,
|
|
DialogHeader,
|
|
DialogTitle,
|
|
DialogTrigger,
|
|
} from "@/registry/bases/base/ui/dialog"
|
|
import {
|
|
Field,
|
|
FieldDescription,
|
|
FieldError,
|
|
FieldLabel,
|
|
} from "@/registry/bases/base/ui/field"
|
|
import { Input } from "@/registry/bases/base/ui/input"
|
|
import {
|
|
Item,
|
|
ItemContent,
|
|
ItemDescription,
|
|
ItemTitle,
|
|
} from "@/registry/bases/base/ui/item"
|
|
import {
|
|
NativeSelect,
|
|
NativeSelectOption,
|
|
} from "@/registry/bases/base/ui/native-select"
|
|
import {
|
|
Select,
|
|
SelectContent,
|
|
SelectGroup,
|
|
SelectItem,
|
|
SelectLabel,
|
|
SelectSeparator,
|
|
SelectTrigger,
|
|
SelectValue,
|
|
} from "@/registry/bases/base/ui/select"
|
|
import { IconPlaceholder } from "@/app/(create)/components/icon-placeholder"
|
|
|
|
export default function SelectExample() {
|
|
return (
|
|
<ExampleWrapper>
|
|
<SelectBasic />
|
|
<SelectWithIcons />
|
|
<SelectWithGroups />
|
|
<SelectLargeList />
|
|
<SelectMultiple />
|
|
<SelectSizes />
|
|
<SelectPlan />
|
|
<SelectWithButton />
|
|
<SelectItemAligned />
|
|
<SelectWithField />
|
|
<SelectInvalid />
|
|
<SelectInline />
|
|
<SelectDisabled />
|
|
<SelectInDialog />
|
|
</ExampleWrapper>
|
|
)
|
|
}
|
|
|
|
function SelectBasic() {
|
|
const items = [
|
|
{ label: "Select a fruit", value: null },
|
|
{ label: "Apple", value: "apple" },
|
|
{ label: "Banana", value: "banana" },
|
|
{ label: "Blueberry", value: "blueberry" },
|
|
{ label: "Grapes", value: "grapes" },
|
|
{ label: "Pineapple", value: "pineapple" },
|
|
]
|
|
return (
|
|
<Example title="Basic">
|
|
<Select items={items}>
|
|
<SelectTrigger>
|
|
<SelectValue />
|
|
</SelectTrigger>
|
|
<SelectContent>
|
|
<SelectGroup>
|
|
{items.map((item) => (
|
|
<SelectItem key={item.value} value={item.value}>
|
|
{item.label}
|
|
</SelectItem>
|
|
))}
|
|
</SelectGroup>
|
|
</SelectContent>
|
|
</Select>
|
|
</Example>
|
|
)
|
|
}
|
|
|
|
function SelectWithIcons() {
|
|
const items = [
|
|
{
|
|
label: (
|
|
<>
|
|
<IconPlaceholder
|
|
lucide="ChartLineIcon"
|
|
tabler="IconChartLine"
|
|
hugeicons="Chart03Icon"
|
|
phosphor="ChartLineIcon"
|
|
/>
|
|
Chart Type
|
|
</>
|
|
),
|
|
value: null,
|
|
},
|
|
{
|
|
label: (
|
|
<>
|
|
<IconPlaceholder
|
|
lucide="ChartLineIcon"
|
|
tabler="IconChartLine"
|
|
hugeicons="Chart03Icon"
|
|
phosphor="ChartLineIcon"
|
|
/>
|
|
Line
|
|
</>
|
|
),
|
|
value: "line",
|
|
},
|
|
{
|
|
label: (
|
|
<>
|
|
<IconPlaceholder
|
|
lucide="ChartBarIcon"
|
|
tabler="IconChartBar"
|
|
hugeicons="Chart03Icon"
|
|
phosphor="ChartBarIcon"
|
|
/>
|
|
Bar
|
|
</>
|
|
),
|
|
value: "bar",
|
|
},
|
|
{
|
|
label: (
|
|
<>
|
|
<IconPlaceholder
|
|
lucide="ChartPieIcon"
|
|
tabler="IconChartPie"
|
|
hugeicons="Chart03Icon"
|
|
phosphor="ChartPieIcon"
|
|
/>
|
|
Pie
|
|
</>
|
|
),
|
|
value: "pie",
|
|
},
|
|
]
|
|
return (
|
|
<Example title="With Icons">
|
|
<div className="flex flex-col gap-4">
|
|
<Select items={items}>
|
|
<SelectTrigger size="sm">
|
|
<SelectValue />
|
|
</SelectTrigger>
|
|
<SelectContent>
|
|
<SelectGroup>
|
|
{items.map((item) => (
|
|
<SelectItem key={item.value} value={item.value}>
|
|
{item.label}
|
|
</SelectItem>
|
|
))}
|
|
</SelectGroup>
|
|
</SelectContent>
|
|
</Select>
|
|
<Select items={items}>
|
|
<SelectTrigger size="default">
|
|
<SelectValue />
|
|
</SelectTrigger>
|
|
<SelectContent>
|
|
<SelectGroup>
|
|
{items.map((item) => (
|
|
<SelectItem key={item.value} value={item.value}>
|
|
{item.label}
|
|
</SelectItem>
|
|
))}
|
|
</SelectGroup>
|
|
</SelectContent>
|
|
</Select>
|
|
</div>
|
|
</Example>
|
|
)
|
|
}
|
|
|
|
function SelectWithGroups() {
|
|
const fruits = [
|
|
{ label: "Apple", value: "apple" },
|
|
{ label: "Banana", value: "banana" },
|
|
{ label: "Blueberry", value: "blueberry" },
|
|
]
|
|
const vegetables = [
|
|
{ label: "Carrot", value: "carrot" },
|
|
{ label: "Broccoli", value: "broccoli" },
|
|
{ label: "Spinach", value: "spinach" },
|
|
]
|
|
const allItems = [
|
|
{ label: "Select a fruit", value: null },
|
|
...fruits,
|
|
...vegetables,
|
|
]
|
|
return (
|
|
<Example title="With Groups & Labels">
|
|
<Select items={allItems}>
|
|
<SelectTrigger>
|
|
<SelectValue />
|
|
</SelectTrigger>
|
|
<SelectContent>
|
|
<SelectGroup>
|
|
<SelectLabel>Fruits</SelectLabel>
|
|
{fruits.map((item) => (
|
|
<SelectItem key={item.value} value={item.value}>
|
|
{item.label}
|
|
</SelectItem>
|
|
))}
|
|
</SelectGroup>
|
|
<SelectSeparator />
|
|
<SelectGroup>
|
|
<SelectLabel>Vegetables</SelectLabel>
|
|
{vegetables.map((item) => (
|
|
<SelectItem key={item.value} value={item.value}>
|
|
{item.label}
|
|
</SelectItem>
|
|
))}
|
|
</SelectGroup>
|
|
</SelectContent>
|
|
</Select>
|
|
</Example>
|
|
)
|
|
}
|
|
|
|
function SelectLargeList() {
|
|
const items = [
|
|
{ label: "Select an item", value: null },
|
|
...Array.from({ length: 100 }).map((_, i) => ({
|
|
label: `Item ${i}`,
|
|
value: `item-${i}`,
|
|
})),
|
|
]
|
|
return (
|
|
<Example title="Large List">
|
|
<Select items={items}>
|
|
<SelectTrigger>
|
|
<SelectValue />
|
|
</SelectTrigger>
|
|
<SelectContent>
|
|
<SelectGroup>
|
|
{items.map((item) => (
|
|
<SelectItem key={item.value} value={item.value}>
|
|
{item.label}
|
|
</SelectItem>
|
|
))}
|
|
</SelectGroup>
|
|
</SelectContent>
|
|
</Select>
|
|
</Example>
|
|
)
|
|
}
|
|
|
|
function SelectSizes() {
|
|
const items = [
|
|
{ label: "Select a fruit", value: null },
|
|
{ label: "Apple", value: "apple" },
|
|
{ label: "Banana", value: "banana" },
|
|
{ label: "Blueberry", value: "blueberry" },
|
|
]
|
|
return (
|
|
<Example title="Sizes">
|
|
<div className="flex flex-col gap-4">
|
|
<Select items={items}>
|
|
<SelectTrigger size="sm">
|
|
<SelectValue />
|
|
</SelectTrigger>
|
|
<SelectContent>
|
|
<SelectGroup>
|
|
{items.map((item) => (
|
|
<SelectItem key={item.value} value={item.value}>
|
|
{item.label}
|
|
</SelectItem>
|
|
))}
|
|
</SelectGroup>
|
|
</SelectContent>
|
|
</Select>
|
|
<Select items={items}>
|
|
<SelectTrigger size="default">
|
|
<SelectValue />
|
|
</SelectTrigger>
|
|
<SelectContent>
|
|
<SelectGroup>
|
|
{items.map((item) => (
|
|
<SelectItem key={item.value} value={item.value}>
|
|
{item.label}
|
|
</SelectItem>
|
|
))}
|
|
</SelectGroup>
|
|
</SelectContent>
|
|
</Select>
|
|
</div>
|
|
</Example>
|
|
)
|
|
}
|
|
|
|
function SelectWithButton() {
|
|
const items = [
|
|
{ label: "Select a fruit", value: null },
|
|
{ label: "Apple", value: "apple" },
|
|
{ label: "Banana", value: "banana" },
|
|
{ label: "Blueberry", value: "blueberry" },
|
|
]
|
|
return (
|
|
<Example title="With Button">
|
|
<div className="flex flex-col gap-4">
|
|
<div className="flex items-center gap-2">
|
|
<Select items={items}>
|
|
<SelectTrigger size="sm">
|
|
<SelectValue />
|
|
</SelectTrigger>
|
|
<SelectContent>
|
|
<SelectGroup>
|
|
{items.map((item) => (
|
|
<SelectItem key={item.value} value={item.value}>
|
|
{item.label}
|
|
</SelectItem>
|
|
))}
|
|
</SelectGroup>
|
|
</SelectContent>
|
|
</Select>
|
|
<Button variant="outline" size="sm">
|
|
Submit
|
|
</Button>
|
|
</div>
|
|
<div className="flex items-center gap-2">
|
|
<Select items={items}>
|
|
<SelectTrigger>
|
|
<SelectValue />
|
|
</SelectTrigger>
|
|
<SelectContent>
|
|
<SelectGroup>
|
|
{items.map((item) => (
|
|
<SelectItem key={item.value} value={item.value}>
|
|
{item.label}
|
|
</SelectItem>
|
|
))}
|
|
</SelectGroup>
|
|
</SelectContent>
|
|
</Select>
|
|
<Button variant="outline">Submit</Button>
|
|
</div>
|
|
</div>
|
|
</Example>
|
|
)
|
|
}
|
|
|
|
function SelectItemAligned() {
|
|
const items = [
|
|
{ label: "Select a fruit", value: null },
|
|
{ label: "Apple", value: "apple" },
|
|
{ label: "Banana", value: "banana" },
|
|
{ label: "Blueberry", value: "blueberry" },
|
|
{ label: "Grapes", value: "grapes", disabled: true },
|
|
{ label: "Pineapple", value: "pineapple" },
|
|
]
|
|
return (
|
|
<Example title="Item Aligned">
|
|
<Select items={items}>
|
|
<SelectTrigger>
|
|
<SelectValue />
|
|
</SelectTrigger>
|
|
<SelectContent alignItemWithTrigger={true}>
|
|
<SelectGroup>
|
|
{items.map((item) => (
|
|
<SelectItem
|
|
key={item.value}
|
|
value={item.value}
|
|
disabled={item.disabled}
|
|
>
|
|
{item.label}
|
|
</SelectItem>
|
|
))}
|
|
</SelectGroup>
|
|
</SelectContent>
|
|
</Select>
|
|
</Example>
|
|
)
|
|
}
|
|
|
|
function SelectWithField() {
|
|
const items = [
|
|
{ label: "Select a fruit", value: null },
|
|
{ label: "Apple", value: "apple" },
|
|
{ label: "Banana", value: "banana" },
|
|
{ label: "Blueberry", value: "blueberry" },
|
|
{ label: "Grapes", value: "grapes" },
|
|
{ label: "Pineapple", value: "pineapple" },
|
|
]
|
|
return (
|
|
<Example title="With Field">
|
|
<Field>
|
|
<FieldLabel htmlFor="select-fruit">Favorite Fruit</FieldLabel>
|
|
<Select items={items}>
|
|
<SelectTrigger id="select-fruit">
|
|
<SelectValue />
|
|
</SelectTrigger>
|
|
<SelectContent>
|
|
<SelectGroup>
|
|
{items.map((item) => (
|
|
<SelectItem key={item.value} value={item.value}>
|
|
{item.label}
|
|
</SelectItem>
|
|
))}
|
|
</SelectGroup>
|
|
</SelectContent>
|
|
</Select>
|
|
<FieldDescription>
|
|
Choose your favorite fruit from the list.
|
|
</FieldDescription>
|
|
</Field>
|
|
</Example>
|
|
)
|
|
}
|
|
|
|
function SelectInvalid() {
|
|
const items = [
|
|
{ label: "Select a fruit", value: null },
|
|
{ label: "Apple", value: "apple" },
|
|
{ label: "Banana", value: "banana" },
|
|
{ label: "Blueberry", value: "blueberry" },
|
|
{ label: "Grapes", value: "grapes" },
|
|
{ label: "Pineapple", value: "pineapple" },
|
|
]
|
|
return (
|
|
<Example title="Invalid">
|
|
<div className="flex flex-col gap-4">
|
|
<Select items={items}>
|
|
<SelectTrigger aria-invalid="true">
|
|
<SelectValue />
|
|
</SelectTrigger>
|
|
<SelectContent>
|
|
<SelectGroup>
|
|
{items.map((item) => (
|
|
<SelectItem key={item.value} value={item.value}>
|
|
{item.label}
|
|
</SelectItem>
|
|
))}
|
|
</SelectGroup>
|
|
</SelectContent>
|
|
</Select>
|
|
<Field data-invalid>
|
|
<FieldLabel htmlFor="select-fruit-invalid">Favorite Fruit</FieldLabel>
|
|
<Select items={items}>
|
|
<SelectTrigger id="select-fruit-invalid" aria-invalid>
|
|
<SelectValue />
|
|
</SelectTrigger>
|
|
<SelectContent>
|
|
<SelectGroup>
|
|
{items.map((item) => (
|
|
<SelectItem key={item.value} value={item.value}>
|
|
{item.label}
|
|
</SelectItem>
|
|
))}
|
|
</SelectGroup>
|
|
</SelectContent>
|
|
</Select>
|
|
<FieldError errors={[{ message: "Please select a valid fruit." }]} />
|
|
</Field>
|
|
</div>
|
|
</Example>
|
|
)
|
|
}
|
|
|
|
function SelectInline() {
|
|
const items = [
|
|
{ label: "Filter", value: null },
|
|
{ label: "All", value: "all" },
|
|
{ label: "Active", value: "active" },
|
|
{ label: "Inactive", value: "inactive" },
|
|
]
|
|
return (
|
|
<Example title="Inline with Input & NativeSelect">
|
|
<div className="flex items-center gap-2">
|
|
<Input placeholder="Search..." className="flex-1" />
|
|
<Select items={items}>
|
|
<SelectTrigger className="w-[140px]">
|
|
<SelectValue />
|
|
</SelectTrigger>
|
|
<SelectContent>
|
|
<SelectGroup>
|
|
{items.map((item) => (
|
|
<SelectItem key={item.value} value={item.value}>
|
|
{item.label}
|
|
</SelectItem>
|
|
))}
|
|
</SelectGroup>
|
|
</SelectContent>
|
|
</Select>
|
|
<NativeSelect className="w-[140px]">
|
|
<NativeSelectOption value="">Sort by</NativeSelectOption>
|
|
<NativeSelectOption value="name">Name</NativeSelectOption>
|
|
<NativeSelectOption value="date">Date</NativeSelectOption>
|
|
<NativeSelectOption value="status">Status</NativeSelectOption>
|
|
</NativeSelect>
|
|
</div>
|
|
</Example>
|
|
)
|
|
}
|
|
|
|
function SelectDisabled() {
|
|
const items = [
|
|
{ label: "Select a fruit", value: null },
|
|
{ label: "Apple", value: "apple" },
|
|
{ label: "Banana", value: "banana" },
|
|
{ label: "Blueberry", value: "blueberry" },
|
|
{ label: "Grapes", value: "grapes", disabled: true },
|
|
{ label: "Pineapple", value: "pineapple" },
|
|
]
|
|
return (
|
|
<Example title="Disabled">
|
|
<Select items={items} disabled>
|
|
<SelectTrigger>
|
|
<SelectValue />
|
|
</SelectTrigger>
|
|
<SelectContent>
|
|
<SelectGroup>
|
|
{items.map((item) => (
|
|
<SelectItem
|
|
key={item.value}
|
|
value={item.value}
|
|
disabled={item.disabled}
|
|
>
|
|
{item.label}
|
|
</SelectItem>
|
|
))}
|
|
</SelectGroup>
|
|
</SelectContent>
|
|
</Select>
|
|
</Example>
|
|
)
|
|
}
|
|
|
|
const plans = [
|
|
{
|
|
name: "Starter",
|
|
description: "Perfect for individuals getting started.",
|
|
},
|
|
{
|
|
name: "Professional",
|
|
description: "Ideal for growing teams and businesses.",
|
|
},
|
|
{
|
|
name: "Enterprise",
|
|
description: "Advanced features for large organizations.",
|
|
},
|
|
]
|
|
|
|
function SelectPlan() {
|
|
return (
|
|
<Example title="Subscription Plan">
|
|
<Select
|
|
defaultValue={plans[0]}
|
|
itemToStringValue={(plan: (typeof plans)[number]) => plan.name}
|
|
>
|
|
<SelectTrigger className="h-auto! w-72">
|
|
<SelectValue>
|
|
{(value: (typeof plans)[number]) => <SelectPlanItem plan={value} />}
|
|
</SelectValue>
|
|
</SelectTrigger>
|
|
<SelectContent>
|
|
<SelectGroup>
|
|
{plans.map((plan) => (
|
|
<SelectItem key={plan.name} value={plan}>
|
|
<SelectPlanItem plan={plan} />
|
|
</SelectItem>
|
|
))}
|
|
</SelectGroup>
|
|
</SelectContent>
|
|
</Select>
|
|
</Example>
|
|
)
|
|
}
|
|
|
|
function SelectPlanItem({ plan }: { plan: (typeof plans)[number] }) {
|
|
return (
|
|
<Item size="xs" className="w-full p-0">
|
|
<ItemContent className="gap-0">
|
|
<ItemTitle>{plan.name}</ItemTitle>
|
|
<ItemDescription className="text-xs">
|
|
{plan.description}
|
|
</ItemDescription>
|
|
</ItemContent>
|
|
</Item>
|
|
)
|
|
}
|
|
|
|
function SelectMultiple() {
|
|
const items = [
|
|
{ label: "Apple", value: "apple" },
|
|
{ label: "Banana", value: "banana" },
|
|
{ label: "Blueberry", value: "blueberry" },
|
|
{ label: "Grapes", value: "grapes" },
|
|
{ label: "Pineapple", value: "pineapple" },
|
|
{ label: "Strawberry", value: "strawberry" },
|
|
{ label: "Watermelon", value: "watermelon" },
|
|
]
|
|
return (
|
|
<Example title="Multiple Selection">
|
|
<Select items={items} multiple defaultValue={[]}>
|
|
<SelectTrigger className="w-72">
|
|
<SelectValue>
|
|
{(value: string[]) => {
|
|
if (value.length === 0) {
|
|
return "Select fruits"
|
|
}
|
|
if (value.length === 1) {
|
|
return items.find((item) => item.value === value[0])?.label
|
|
}
|
|
return `${value.length} fruits selected`
|
|
}}
|
|
</SelectValue>
|
|
</SelectTrigger>
|
|
<SelectContent>
|
|
<SelectGroup>
|
|
{items.map((item) => (
|
|
<SelectItem key={item.value} value={item.value}>
|
|
{item.label}
|
|
</SelectItem>
|
|
))}
|
|
</SelectGroup>
|
|
</SelectContent>
|
|
</Select>
|
|
</Example>
|
|
)
|
|
}
|
|
|
|
function SelectInDialog() {
|
|
const items = [
|
|
{ label: "Select a fruit", value: null },
|
|
{ label: "Apple", value: "apple" },
|
|
{ label: "Banana", value: "banana" },
|
|
{ label: "Blueberry", value: "blueberry" },
|
|
{ label: "Grapes", value: "grapes" },
|
|
{ label: "Pineapple", value: "pineapple" },
|
|
]
|
|
return (
|
|
<Example title="In Dialog">
|
|
<Dialog>
|
|
<DialogTrigger render={<Button variant="outline" />}>
|
|
Open Dialog
|
|
</DialogTrigger>
|
|
<DialogContent>
|
|
<DialogHeader>
|
|
<DialogTitle>Select Example</DialogTitle>
|
|
<DialogDescription>
|
|
Use the select below to choose a fruit.
|
|
</DialogDescription>
|
|
</DialogHeader>
|
|
<Select items={items}>
|
|
<SelectTrigger>
|
|
<SelectValue />
|
|
</SelectTrigger>
|
|
<SelectContent>
|
|
<SelectGroup>
|
|
{items.map((item) => (
|
|
<SelectItem key={item.value} value={item.value}>
|
|
{item.label}
|
|
</SelectItem>
|
|
))}
|
|
</SelectGroup>
|
|
</SelectContent>
|
|
</Select>
|
|
</DialogContent>
|
|
</Dialog>
|
|
</Example>
|
|
)
|
|
}
|