Files
upstream-mirror 1416db152c
All checks were successful
Release / Create Version PR or Publish Stable Release (push) Has been skipped
Release / Publish Prerelease to NPM (push) Has been skipped
Monitor Registries / Monitor registry health (push) Has been skipped
snapshot of https://github.com/shadcn-ui/ui.git (main, 2026-09-15; blobs > 131072B omitted)
2026-09-15 22:44:43 +05:00

298 lines
7.0 KiB
TypeScript

"use client"
import * as React from "react"
import { cn } from "cn"
import {
Button as ButtonPrimitive,
composeRenderProps,
Header as HeaderPrimitive,
ListBoxItem as ListBoxItemPrimitive,
ListBox as ListBoxPrimitive,
ListBoxSection as ListBoxSectionPrimitive,
Popover as PopoverPrimitive,
SearchField,
Select as SelectPrimitive,
SelectValue as SelectValuePrimitive,
Separator as SeparatorPrimitive,
type ListBoxProps,
type SearchFieldProps,
type ListBoxSectionProps as SelectGroupProps,
type SelectProps,
type SelectValueProps,
} from "react-aria-components"
import {
InputGroup,
InputGroupAddon,
InputGroupInput,
} from "@/registry/bases/aria/ui/input-group"
import { IconPlaceholder } from "@/app/(create)/components/icon-placeholder"
function Select<T extends object, M extends "single" | "multiple" = "single">({
className,
...props
}: SelectProps<T, M>) {
return (
<SelectPrimitive
data-slot="select"
className={cn("w-fit", className)}
{...props}
/>
)
}
function SelectGroup<T extends object>({
className,
...props
}: SelectGroupProps<T>) {
return (
<ListBoxSectionPrimitive
data-slot="select-group"
className={cn("cn-select-group", className)}
{...props}
/>
)
}
function SelectValue<T extends object>({
className,
children,
...props
}: SelectValueProps<T>) {
return (
<SelectValuePrimitive
data-slot="select-value"
className={cn("cn-select-value cn-select-value-aria", className)}
{...props}
>
{typeof children === "function"
? children
: ({ selectedItems, selectedText, defaultChildren }) =>
selectedItems.length > 1 ? selectedText : defaultChildren}
</SelectValuePrimitive>
)
}
function SelectTrigger({
className,
size = "default",
children,
...props
}: Omit<React.ComponentProps<typeof ButtonPrimitive>, "children"> & {
children?: React.ReactNode
size?: "sm" | "default"
}) {
return (
<ButtonPrimitive
data-slot="select-trigger"
data-size={size}
className={cn(
"cn-select-trigger flex w-full items-center justify-between whitespace-nowrap outline-none disabled:cursor-not-allowed disabled:opacity-50 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center [&_svg]:pointer-events-none [&_svg]:shrink-0",
className
)}
{...props}
>
{children}
<IconPlaceholder
lucide="ChevronDownIcon"
tabler="IconSelector"
hugeicons="UnfoldMoreIcon"
phosphor="CaretDownIcon"
remixicon="RiArrowDownSLine"
className="cn-select-trigger-icon pointer-events-none"
/>
</ButtonPrimitive>
)
}
function SelectContent({
className,
children,
placement = "bottom",
offset = 4,
crossOffset = 0,
...props
}: Omit<
React.ComponentProps<typeof PopoverPrimitive>,
"className" | "children"
> & {
className?: string
children?: React.ReactNode
}) {
return (
<SelectPopover
className={className}
placement={placement}
offset={offset}
crossOffset={crossOffset}
{...props}
>
<SelectList>{children}</SelectList>
</SelectPopover>
)
}
function SelectPopover({
className,
children,
placement = "bottom start",
offset = 4,
crossOffset = 0,
...props
}: Omit<
React.ComponentProps<typeof PopoverPrimitive>,
"className" | "children"
> & {
className?: string
children?: React.ReactNode
}) {
return (
<PopoverPrimitive
data-slot="select-content"
placement={placement}
offset={offset}
crossOffset={crossOffset}
className={cn(
"cn-select-content-aria cn-menu-target cn-menu-translucent cn-menu-translucent-aria relative isolate z-50 w-(--trigger-width) origin-(--trigger-anchor-point) overflow-hidden",
className
)}
{...props}
>
{children}
</PopoverPrimitive>
)
}
function SelectList<T extends object>({
className,
...props
}: ListBoxProps<T>) {
return (
<ListBoxPrimitive
data-slot="select-list"
className={cn(
"group/select-list max-h-[inherit] overflow-x-hidden overflow-y-auto p-0 outline-hidden",
className
)}
{...props}
/>
)
}
function SelectInput({ className, ...props }: SearchFieldProps) {
return (
<SearchField
{...props}
autoFocus
data-slot="select-input-wrapper"
className={cn("p-1 pb-0", className)}
>
<InputGroup>
<InputGroupInput
data-slot="select-input"
className="[&::-webkit-search-cancel-button]:hidden"
/>
<InputGroupAddon>
<IconPlaceholder
lucide="SearchIcon"
tabler="IconSearch"
hugeicons="SearchIcon"
phosphor="MagnifyingGlassIcon"
remixicon="RiSearchLine"
className="cn-command-input-icon"
/>
</InputGroupAddon>
</InputGroup>
</SearchField>
)
}
function SelectLabel({
className,
...props
}: React.ComponentProps<typeof HeaderPrimitive>) {
return (
<HeaderPrimitive
data-slot="select-label"
className={cn("cn-select-label", className)}
{...props}
/>
)
}
function SelectItem({
className,
children,
...props
}: React.ComponentProps<typeof ListBoxItemPrimitive>) {
return (
<ListBoxItemPrimitive
data-slot="select-item"
textValue={typeof children === "string" ? children : undefined}
className={cn(
"cn-select-item cn-select-item-aria relative flex w-full cursor-default items-center outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0",
className
)}
{...props}
>
{composeRenderProps(children, (children, { isSelected }) => (
<>
<span className="cn-select-item-text shrink-0 whitespace-nowrap">
{children}
</span>
<span className="cn-select-item-indicator">
{isSelected ? (
<IconPlaceholder
lucide="CheckIcon"
tabler="IconCheck"
hugeicons="Tick02Icon"
phosphor="CheckIcon"
remixicon="RiCheckLine"
className="cn-select-item-indicator-icon pointer-events-none"
/>
) : null}
</span>
</>
))}
</ListBoxItemPrimitive>
)
}
function SelectSeparator({
className,
...props
}: React.ComponentProps<typeof SeparatorPrimitive>) {
return (
<SeparatorPrimitive
data-slot="select-separator"
className={cn("cn-select-separator pointer-events-none", className)}
{...props}
/>
)
}
function SelectEmpty({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="select-empty"
className={cn("cn-select-empty-aria", className)}
{...props}
/>
)
}
export {
Select,
SelectContent,
SelectGroup,
SelectInput,
SelectItem,
SelectLabel,
SelectList,
SelectPopover,
SelectSeparator,
SelectTrigger,
SelectValue,
SelectEmpty,
}