Devie UI
Version: 2026-02-14

The Select component provides a dropdown menu for selecting a single value from a list of options. It extends Base UI's Select with consistent styling that matches the design system.

Installation

Here is the component implementation code that you can copy to your project:

// https://devie-ui.com/components/select
// https://base-ui.com/react/components/select
 
import { Select as BaseSelect } from "@base-ui/react/select";
import clsx from "clsx";
import { Check, ChevronDown } from "lucide-react";
import type React from "react";
import styles from "./Select.module.scss";
 
const Root = BaseSelect.Root;
 
function Trigger({ className, ...props }: BaseSelect.Trigger.Props) {
  return (
    <BaseSelect.Trigger
      className={clsx(styles.trigger, className)}
      {...props}
    />
  );
}
 
function Value({ className, ...props }: BaseSelect.Value.Props) {
  return (
    <BaseSelect.Value className={clsx(styles.value, className)} {...props} />
  );
}
 
function Icon({ className, children, ...props }: BaseSelect.Icon.Props) {
  return (
    <BaseSelect.Icon className={clsx(styles.icon, className)} {...props}>
      {children || <ChevronDown size={16} />}
    </BaseSelect.Icon>
  );
}
 
const Portal = BaseSelect.Portal;
 
function Positioner({ className, ...props }: BaseSelect.Positioner.Props) {
  return (
    <BaseSelect.Positioner
      className={clsx(styles.positioner, className)}
      {...props}
    />
  );
}
 
function Popup({ className, ...props }: BaseSelect.Popup.Props) {
  return (
    <BaseSelect.Popup className={clsx(styles.popup, className)} {...props} />
  );
}
 
function List({ className, ...props }: BaseSelect.List.Props) {
  return (
    <BaseSelect.List className={clsx(styles.list, className)} {...props} />
  );
}
 
function Item({ className, ...props }: BaseSelect.Item.Props) {
  return (
    <BaseSelect.Item className={clsx(styles.item, className)} {...props} />
  );
}
 
function ItemIndicator({
  className,
  children,
  ...props
}: BaseSelect.ItemIndicator.Props) {
  return (
    <BaseSelect.ItemIndicator
      className={clsx(styles.itemIndicator, className)}
      {...props}
    >
      {children || <Check size={16} strokeWidth={1.5} />}
    </BaseSelect.ItemIndicator>
  );
}
 
function ItemText({ className, ...props }: BaseSelect.ItemText.Props) {
  return (
    <BaseSelect.ItemText
      className={clsx(styles.itemText, className)}
      {...props}
    />
  );
}
 
function Arrow({ className, ...props }: BaseSelect.Arrow.Props) {
  return (
    <BaseSelect.Arrow className={clsx(styles.arrow, className)} {...props} />
  );
}
 
function ScrollUpArrow({
  className,
  ...props
}: BaseSelect.ScrollUpArrow.Props) {
  return (
    <BaseSelect.ScrollUpArrow
      className={clsx(styles.scrollArrow, className)}
      {...props}
    />
  );
}
 
function ScrollDownArrow({
  className,
  ...props
}: BaseSelect.ScrollDownArrow.Props) {
  return (
    <BaseSelect.ScrollDownArrow
      className={clsx(styles.scrollArrow, className)}
      {...props}
    />
  );
}
 
const Backdrop = BaseSelect.Backdrop;
 
function Group({ className, ...props }: BaseSelect.Group.Props) {
  return (
    <BaseSelect.Group className={clsx(styles.group, className)} {...props} />
  );
}
 
function GroupLabel({ className, ...props }: BaseSelect.GroupLabel.Props) {
  return (
    <BaseSelect.GroupLabel
      className={clsx(styles.groupLabel, className)}
      {...props}
    />
  );
}
 
function Separator({ className, ...props }: BaseSelect.Separator.Props) {
  return (
    <BaseSelect.Separator
      className={clsx(styles.separator, className)}
      {...props}
    />
  );
}
 
const Select = {
  Root,
  Trigger,
  Value,
  Icon,
  Portal,
  Backdrop,
  Positioner,
  Popup,
  List,
  Arrow,
  ScrollUpArrow,
  ScrollDownArrow,
  Item,
  ItemIndicator,
  ItemText,
  Group,
  GroupLabel,
  Separator,
};
 
namespace Select {
  export namespace Root {
    export type Props<Value> = BaseSelect.Root.Props<Value>;
    export type ChangeEventDetails = BaseSelect.Root.ChangeEventDetails;
    export type ChangeEventReason = BaseSelect.Root.ChangeEventReason;
  }
  export namespace Trigger {
    export type Props = BaseSelect.Trigger.Props;
    export type State = BaseSelect.Trigger.State;
  }
  export namespace Value {
    export type Props = React.ComponentProps<typeof BaseSelect.Value>;
  }
  export namespace Icon {
    export type Props = BaseSelect.Icon.Props;
  }
  export namespace Portal {
    export type Props = BaseSelect.Portal.Props;
  }
  export namespace Backdrop {
    export type Props = BaseSelect.Backdrop.Props;
  }
  export namespace Positioner {
    export type Props = BaseSelect.Positioner.Props;
    export type State = BaseSelect.Positioner.State;
  }
  export namespace Popup {
    export type Props = BaseSelect.Popup.Props;
  }
  export namespace List {
    export type Props = BaseSelect.List.Props;
  }
  export namespace Arrow {
    export type Props = BaseSelect.Arrow.Props;
  }
  export namespace ScrollUpArrow {
    export type Props = BaseSelect.ScrollUpArrow.Props;
  }
  export namespace ScrollDownArrow {
    export type Props = BaseSelect.ScrollDownArrow.Props;
  }
  export namespace Item {
    export type Props = BaseSelect.Item.Props;
    export type State = BaseSelect.Item.State;
  }
  export namespace ItemIndicator {
    export type Props = BaseSelect.ItemIndicator.Props;
  }
  export namespace ItemText {
    export type Props = BaseSelect.ItemText.Props;
  }
  export namespace Group {
    export type Props = BaseSelect.Group.Props;
  }
  export namespace GroupLabel {
    export type Props = BaseSelect.GroupLabel.Props;
  }
  export namespace Separator {
    export type Props = BaseSelect.Separator.Props;
  }
}
 
export default Select;

Use Cases

Simple select

A basic select with a placeholder and a list of options. The trigger shows the selected value or the placeholder when nothing is selected.

Grouped options

Use Select.Group and Select.GroupLabel to organize options into logical groups. Add Select.Separator between groups for visual distinction.

Disabled state

The select can be disabled entirely using the disabled prop on the Root, or individual items can be disabled using the disabled prop on each Item.