v2
424c17b ยท 1 year ago 26 commits
  1import * as React from "react"
  2import * as SelectPrimitive from "@radix-ui/react-select"
  3import { Check, ChevronDown } from "lucide-react"
  4
  5import { cn } from "@/lib/utils"
  6
  7const Select = SelectPrimitive.Root
  8
  9const SelectGroup = SelectPrimitive.Group
 10
 11const SelectValue = SelectPrimitive.Value
 12
 13const SelectTrigger = React.forwardRef<
 14  React.ElementRef<typeof SelectPrimitive.Trigger>,
 15  React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger>
 16>(({ className, children, ...props }, ref) => (
 17  <SelectPrimitive.Trigger
 18    ref={ref}
 19    className={cn(
 20      "flex h-10 w-full items-center justify-between rounded-md border border-input bg-transparent px-3 py-2 text-sm placeholder:text-muted-foreground focus:outline-none disabled:cursor-not-allowed disabled:opacity-50",
 21      className
 22    )}
 23    {...props}
 24  >
 25    {children}
 26    <SelectPrimitive.Icon asChild>
 27      <ChevronDown className="h-4 w-4 opacity-50" />
 28    </SelectPrimitive.Icon>
 29  </SelectPrimitive.Trigger>
 30))
 31SelectTrigger.displayName = SelectPrimitive.Trigger.displayName
 32
 33const SelectContent = React.forwardRef<
 34  React.ElementRef<typeof SelectPrimitive.Content>,
 35  React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content>
 36>(({ className, children, position = "popper", ...props }, ref) => (
 37  <SelectPrimitive.Portal>
 38    <SelectPrimitive.Content
 39      ref={ref}
 40      className={cn(
 41        "relative z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
 42        position === "popper" &&
 43          "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
 44        className
 45      )}
 46      position={position}
 47      {...props}
 48    >
 49      <SelectPrimitive.Viewport
 50        className={cn(
 51          "p-1",
 52          position === "popper" &&
 53            "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"
 54        )}
 55      >
 56        {children}
 57      </SelectPrimitive.Viewport>
 58    </SelectPrimitive.Content>
 59  </SelectPrimitive.Portal>
 60))
 61SelectContent.displayName = SelectPrimitive.Content.displayName
 62
 63const SelectLabel = React.forwardRef<
 64  React.ElementRef<typeof SelectPrimitive.Label>,
 65  React.ComponentPropsWithoutRef<typeof SelectPrimitive.Label>
 66>(({ className, ...props }, ref) => (
 67  <SelectPrimitive.Label
 68    ref={ref}
 69    className={cn("py-1.5 pl-8 pr-2 text-sm font-semibold", className)}
 70    {...props}
 71  />
 72))
 73SelectLabel.displayName = SelectPrimitive.Label.displayName
 74
 75const SelectItem = React.forwardRef<
 76  React.ElementRef<typeof SelectPrimitive.Item>,
 77  React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item>
 78>(({ className, children, ...props }, ref) => (
 79  <SelectPrimitive.Item
 80    ref={ref}
 81    className={cn(
 82      "relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
 83      className
 84    )}
 85    {...props}
 86  >
 87    <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
 88      <SelectPrimitive.ItemIndicator>
 89        <Check className="h-4 w-4" />
 90      </SelectPrimitive.ItemIndicator>
 91    </span>
 92
 93    <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
 94  </SelectPrimitive.Item>
 95))
 96SelectItem.displayName = SelectPrimitive.Item.displayName
 97
 98const SelectSeparator = React.forwardRef<
 99  React.ElementRef<typeof SelectPrimitive.Separator>,
100  React.ComponentPropsWithoutRef<typeof SelectPrimitive.Separator>
101>(({ className, ...props }, ref) => (
102  <SelectPrimitive.Separator
103    ref={ref}
104    className={cn("-mx-1 my-1 h-px bg-muted", className)}
105    {...props}
106  />
107))
108SelectSeparator.displayName = SelectPrimitive.Separator.displayName
109
110export {
111  Select,
112  SelectGroup,
113  SelectValue,
114  SelectTrigger,
115  SelectContent,
116  SelectLabel,
117  SelectItem,
118  SelectSeparator,
119}