Vercel wordmark
Tremor is joining Vercel.

Inputs

Select

List of user-selectable options, triggered by a button.

Installation

  1. 1

    Install dependencies:

    npm install @radix-ui/react-select
  2. 2

    Add component:

    Copy and paste the code into your project’s component directory. Do not forget to update the import paths.
    // Tremor Select [v1.0.0]
    import React from "react"import * as SelectPrimitives from "@radix-ui/react-select"import {  RiArrowDownSLine,  RiArrowUpSLine,  RiCheckLine,  RiExpandUpDownLine,} from "@remixicon/react"
    import { cx, focusInput, hasErrorInput } from "@/lib/utils"
    const Select = SelectPrimitives.RootSelect.displayName = "Select"
    const SelectGroup = SelectPrimitives.GroupSelectGroup.displayName = "SelectGroup"
    const SelectValue = SelectPrimitives.ValueSelectValue.displayName = "SelectValue"
    const selectTriggerStyles = [  cx(    // base    "group/trigger flex w-full select-none items-center justify-between gap-2 truncate rounded-md border px-3 py-2 shadow-xs outline-hidden transition sm:text-sm",    // border color    "border-gray-300 dark:border-gray-800",    // text color    "text-gray-900 dark:text-gray-50",    // placeholder    "data-placeholder:text-gray-500 dark:data-placeholder:text-gray-500",    // background color    "bg-white dark:bg-gray-950",    // hover    "hover:bg-gray-50 dark:hover:bg-gray-950/50",    // disabled    "data-disabled:bg-gray-100 data-disabled:text-gray-400",    "dark:data-disabled:border-gray-700 dark:data-disabled:bg-gray-800 dark:data-disabled:text-gray-500",    focusInput,    // invalid (optional)    // "dark:aria-invalid:ring-red-400/20 aria-invalid:ring-2 aria-invalid:ring-red-200 aria-invalid:border-red-500 invalid:ring-2 invalid:ring-red-200 invalid:border-red-500"  ),]
    const SelectTrigger = React.forwardRef<  React.ElementRef<typeof SelectPrimitives.Trigger>,  React.ComponentPropsWithoutRef<typeof SelectPrimitives.Trigger> & {    hasError?: boolean  }>(({ className, hasError, children, ...props }, forwardedRef) => {  return (    <SelectPrimitives.Trigger      ref={forwardedRef}      className={cx(        selectTriggerStyles,        hasError ? hasErrorInput : "",        className,      )}      tremor-id="tremor-raw"      {...props}    >      <span className="truncate">{children}</span>      <SelectPrimitives.Icon asChild>        <RiExpandUpDownLine          className={cx(            // base            "size-4 shrink-0",            // text color            "text-gray-400 dark:text-gray-600",            // disabled            "group-data-disabled/trigger:text-gray-300 dark:group-data-disabled/trigger:text-gray-600",          )}        />      </SelectPrimitives.Icon>    </SelectPrimitives.Trigger>  )})
    SelectTrigger.displayName = "SelectTrigger"
    const SelectScrollUpButton = React.forwardRef<  React.ElementRef<typeof SelectPrimitives.ScrollUpButton>,  React.ComponentPropsWithoutRef<typeof SelectPrimitives.ScrollUpButton>>(({ className, ...props }, forwardedRef) => (  <SelectPrimitives.ScrollUpButton    ref={forwardedRef}    className={cx(      "flex cursor-default items-center justify-center py-1",      className,    )}    {...props}  >    <RiArrowUpSLine className="size-3 shrink-0" aria-hidden="true" />  </SelectPrimitives.ScrollUpButton>))SelectScrollUpButton.displayName = SelectPrimitives.ScrollUpButton.displayName
    const SelectScrollDownButton = React.forwardRef<  React.ElementRef<typeof SelectPrimitives.ScrollDownButton>,  React.ComponentPropsWithoutRef<typeof SelectPrimitives.ScrollDownButton>>(({ className, ...props }, forwardedRef) => (  <SelectPrimitives.ScrollDownButton    ref={forwardedRef}    className={cx(      "flex cursor-default items-center justify-center py-1",      className,    )}    {...props}  >    <RiArrowDownSLine className="size-3 shrink-0" aria-hidden="true" />  </SelectPrimitives.ScrollDownButton>))SelectScrollDownButton.displayName =  SelectPrimitives.ScrollDownButton.displayName
    const SelectContent = React.forwardRef<  React.ElementRef<typeof SelectPrimitives.Content>,  React.ComponentPropsWithoutRef<typeof SelectPrimitives.Content>>(  (    {      className,      position = "popper",      children,      sideOffset = 8,      collisionPadding = 10,      ...props    },    forwardedRef,  ) => (    <SelectPrimitives.Portal>      <SelectPrimitives.Content        ref={forwardedRef}        className={cx(          // base          "relative z-50 overflow-hidden rounded-md border shadow-xl shadow-black/[2.5%]",          // widths          "min-w-[calc(var(--radix-select-trigger-width)-2px)] max-w-[95vw]",          // heights          "max-h-(--radix-select-content-available-height)",          // background color          "bg-white dark:bg-gray-950",          // text color          "text-gray-900 dark:text-gray-50",          // border color          "border-gray-200 dark:border-gray-800",          // transition          "will-change-[transform,opacity]",          // "data-[state=open]:animate-slide-down-and-fade",          "data-[state=closed]:animate-hide",          "data-[side=bottom]:animate-slide-down-and-fade data-[side=left]:animate-slide-left-and-fade data-[side=right]:animate-slide-right-and-fade data-[side=top]:animate-slide-up-and-fade",          className,        )}        sideOffset={sideOffset}        position={position}        collisionPadding={collisionPadding}        {...props}      >        <SelectScrollUpButton />        <SelectPrimitives.Viewport          className={cx(            "p-1",            position === "popper" &&            "h-[var(--radix-select-trigger-height)] w-full min-w-[calc(var(--radix-select-trigger-width))]",          )}        >          {children}        </SelectPrimitives.Viewport>        <SelectScrollDownButton />      </SelectPrimitives.Content>    </SelectPrimitives.Portal>  ),)
    SelectContent.displayName = "SelectContent"
    const SelectGroupLabel = React.forwardRef<  React.ElementRef<typeof SelectPrimitives.Label>,  React.ComponentPropsWithoutRef<typeof SelectPrimitives.Label>>(({ className, ...props }, forwardedRef) => (  <SelectPrimitives.Label    ref={forwardedRef}    className={cx(      // base      "px-3 py-2 text-xs font-medium tracking-wide",      // text color      "text-gray-500 dark:text-gray-500",      className,    )}    {...props}  />))
    SelectGroupLabel.displayName = "SelectGroupLabel"
    const SelectItem = React.forwardRef<  React.ElementRef<typeof SelectPrimitives.Item>,  React.ComponentPropsWithoutRef<typeof SelectPrimitives.Item>>(({ className, children, ...props }, forwardedRef) => {  return (    <SelectPrimitives.Item      ref={forwardedRef}      className={cx(        // base        "grid cursor-pointer grid-cols-[1fr_20px] gap-x-2 rounded-sm px-3 py-2 outline-hidden transition-colors data-[state=checked]:font-semibold sm:text-sm",        // text color        "text-gray-900 dark:text-gray-50",        // disabled        "data-disabled:pointer-events-none data-disabled:text-gray-400 data-disabled:hover:bg-none dark:data-disabled:text-gray-600",        // focus        "focus-visible:bg-gray-100 dark:focus-visible:bg-gray-900",        // hover        "hover:bg-gray-100 dark:hover:bg-gray-900",        className,      )}      {...props}    >      <SelectPrimitives.ItemText className="flex-1 truncate">        {children}      </SelectPrimitives.ItemText>      <SelectPrimitives.ItemIndicator>        <RiCheckLine          className="size-5 shrink-0 text-gray-800 dark:text-gray-200"          aria-hidden="true"        />      </SelectPrimitives.ItemIndicator>    </SelectPrimitives.Item>  )})
    SelectItem.displayName = "SelectItem"
    const SelectSeparator = React.forwardRef<  React.ElementRef<typeof SelectPrimitives.Separator>,  React.ComponentPropsWithoutRef<typeof SelectPrimitives.Separator>>(({ className, ...props }, forwardedRef) => (  <SelectPrimitives.Separator    ref={forwardedRef}    className={cx(      // base      "-mx-1 my-1 h-px",      // background color      "bg-gray-300 dark:bg-gray-700",      className,    )}    {...props}  />))
    SelectSeparator.displayName = "SelectSeparator"
    export {  Select,  SelectContent,  SelectGroup,  SelectGroupLabel,  SelectItem,  SelectSeparator,  SelectTrigger,  SelectValue,}
    
  3. 3

    Update globals.css

    @theme {  --animate-hide: hide 150ms cubic-bezier(0.16, 1, 0.3, 1);  --animate-slide-down-and-fade: slideDownAndFade 150ms cubic-bezier(0.16, 1, 0.3, 1);  --animate-slide-left-and-fade: slideLeftAndFade 150ms cubic-bezier(0.16, 1, 0.3, 1);  --animate-slide-up-and-fade: slideUpAndFade 150ms cubic-bezier(0.16, 1, 0.3, 1);  --animate-slide-right-and-fade: slideRightAndFade 150ms cubic-bezier(0.16, 1, 0.3, 1);
      @keyframes hide {    from {      opacity: 1;    }    to {      opacity: 0;    }  }  @keyframes slideDownAndFade {    from {      opacity: 0;      transform: translateY(-6px);    }    to {      opacity: 1;      transform: translateY(0);    }  }  @keyframes slideLeftAndFade {    from {      opacity: 0;      transform: translateX(6px);    }    to {      opacity: 1;      transform: translateX(0);    }  }  @keyframes slideUpAndFade {    from {      opacity: 0;      transform: translateY(6px);    }    to {      opacity: 1;      transform: translateY(0);    }  }  @keyframes slideRightAndFade {    from {      opacity: 0;      transform: translateX(-6px);    }    to {      opacity: 1;      transform: translateX(0);    }  }}
    

Example: Select with label

Example: Select with defaultValue

Example: Select with disabled state

Example: Select with disabled select item

Example: Select with groups

Example: Select with scroll and custom height

Example: Select with Dialog

Example: Select with error state

To style the Select for an error state, use the hasError prop.

Example: Select with icons

Example: Controlled select

Selected key:

API Reference: Select

This component uses the Radix UI API.

API Reference: SelectTrigger

This component uses the Radix UI API.

hasError
boolean
Style for erroneous input.

Default: false

API Reference: SelectValue

This component uses the Radix UI API.

API Reference: SelectContent

This component uses the Radix UI API.

API Reference: SelectItem

This component uses the Radix UI API.

API Reference: SelectGroupLabel

This component uses the Radix UI API.

API Reference: SelectLabel

This component uses the Radix UI API.

API Reference: SelectSeparator

This component uses the Radix UI API.