YaVendio Registry
Components

YA Select

A dropdown select component for choosing from a list of options, built on Radix UI primitives

The YaSelect is a dropdown select component in the YaVendio Design System. Built on Radix UI Select primitives, it provides full keyboard navigation, accessibility, and custom styling with portal-based positioning.

Quick Start

pnpm dlx shadcn@latest add @yavendio/ya-select
npx shadcn@latest add @yavendio/ya-select
yarn dlx shadcn@latest add @yavendio/ya-select
import {
  YaSelect,
  YaSelectTrigger,
  YaSelectValue,
  YaSelectContent,
  YaSelectItem,
} from '@/components/ui/ya-select'

export default function Example() {
  return (
    <YaSelect>
      <YaSelectTrigger>
        <YaSelectValue placeholder="Select an option..." />
      </YaSelectTrigger>
      <YaSelectContent>
        <YaSelectItem value="option1">Option 1</YaSelectItem>
        <YaSelectItem value="option2">Option 2</YaSelectItem>
        <YaSelectItem value="option3">Option 3</YaSelectItem>
      </YaSelectContent>
    </YaSelect>
  )
}

Basic Select

Sizes

Two sizes for different use cases.

SizeHeightUsage
md40pxMost use cases, default
sm32pxCompact UIs, tables, toolbars
<YaSelect>
  <YaSelectTrigger size="md">
    <YaSelectValue placeholder="Medium size" />
  </YaSelectTrigger>
  <YaSelectContent>...</YaSelectContent>
</YaSelect>

<YaSelect>
  <YaSelectTrigger size="sm">
    <YaSelectValue placeholder="Small size" />
  </YaSelectTrigger>
  <YaSelectContent>...</YaSelectContent>
</YaSelect>

With Groups and Labels

Use groups to organize options logically.

import {
  YaSelect,
  YaSelectTrigger,
  YaSelectValue,
  YaSelectContent,
  YaSelectItem,
  YaSelectGroup,
  YaSelectLabel,
  YaSelectSeparator,
} from '@/components/ui/ya-select'

<YaSelect>
  <YaSelectTrigger>
    <YaSelectValue placeholder="Choose..." />
  </YaSelectTrigger>
  <YaSelectContent>
    <YaSelectGroup>
      <YaSelectLabel>Fruits</YaSelectLabel>
      <YaSelectItem value="apple">Apple</YaSelectItem>
      <YaSelectItem value="banana">Banana</YaSelectItem>
    </YaSelectGroup>
    <YaSelectSeparator />
    <YaSelectGroup>
      <YaSelectLabel>Vegetables</YaSelectLabel>
      <YaSelectItem value="carrot">Carrot</YaSelectItem>
      <YaSelectItem value="broccoli">Broccoli</YaSelectItem>
    </YaSelectGroup>
  </YaSelectContent>
</YaSelect>

States

Please select a valid priority

Disabled

<YaSelect disabled>
  <YaSelectTrigger>
    <YaSelectValue placeholder="Disabled select" />
  </YaSelectTrigger>
  <YaSelectContent>...</YaSelectContent>
</YaSelect>

Features:

  • Reduced opacity (50%)
  • Non-interactive

Destructive

Use for validation errors.

Please select a valid category

<YaSelect>
  <YaSelectTrigger destructive>
    <YaSelectValue placeholder="Select a category" />
  </YaSelectTrigger>
  <YaSelectContent>...</YaSelectContent>
</YaSelect>

Features:

  • Red border
  • Combine with error message for validation feedback

Controlled Component

Use value and onValueChange for controlled behavior.

Make a selection

import { useState } from 'react'

export default function ControlledExample() {
  const [selected, setSelected] = useState('')

  return (
    <YaSelect value={selected} onValueChange={setSelected}>
      <YaSelectTrigger>
        <YaSelectValue placeholder="Select a framework" />
      </YaSelectTrigger>
      <YaSelectContent>
        <YaSelectItem value="react">React</YaSelectItem>
        <YaSelectItem value="vue">Vue</YaSelectItem>
        <YaSelectItem value="angular">Angular</YaSelectItem>
      </YaSelectContent>
    </YaSelect>
  )
}

Examples

Validation Example

import { useState } from 'react'

export default function ValidationExample() {
  const [value, setValue] = useState('')
  const [error, setError] = useState('')

  const handleSubmit = () => {
    if (!value) {
      setError('Please select a priority level')
    } else {
      setError('')
    }
  }

  return (
    <div className="flex flex-col gap-4">
      <YaSelect
        value={value}
        onValueChange={(val) => {
          setValue(val)
          setError('')
        }}
      >
        <YaSelectTrigger destructive={!!error}>
          <YaSelectValue placeholder="Select priority" />
        </YaSelectTrigger>
        <YaSelectContent>
          <YaSelectItem value="low">Low</YaSelectItem>
          <YaSelectItem value="medium">Medium</YaSelectItem>
          <YaSelectItem value="high">High</YaSelectItem>
        </YaSelectContent>
      </YaSelect>
      {error && <p className="text-xs text-destructive">{error}</p>}
      <YaButton onClick={handleSubmit}>Submit</YaButton>
    </div>
  )
}

Form with Multiple Selects

Compact Selection Row

<div className="flex gap-4 items-end">
  <YaSelect>
    <YaSelectTrigger size="sm">
      <YaSelectValue placeholder="Sort by" />
    </YaSelectTrigger>
    <YaSelectContent>
      <YaSelectItem value="date">Date</YaSelectItem>
      <YaSelectItem value="name">Name</YaSelectItem>
    </YaSelectContent>
  </YaSelect>

  <YaSelect>
    <YaSelectTrigger size="sm">
      <YaSelectValue placeholder="Order" />
    </YaSelectTrigger>
    <YaSelectContent>
      <YaSelectItem value="asc">Ascending</YaSelectItem>
      <YaSelectItem value="desc">Descending</YaSelectItem>
    </YaSelectContent>
  </YaSelect>
</div>

Component API

YaSelect (Root)

The root component that provides context.

PropTypeDefaultDescription
valuestring-Controlled value
defaultValuestring-Default value (uncontrolled)
onValueChange(value: string) => void-Callback when value changes
openboolean-Controlled open state
onOpenChange(open: boolean) => void-Callback when open state changes
disabledbooleanfalseDisable the select
requiredbooleanfalseMark as required
namestring-Name for form submission

YaSelectTrigger

The button that opens the select dropdown.

PropTypeDefaultDescription
size'md' | 'sm''md'Trigger size
destructivebooleanfalseApply error styling
classNamestring-Additional classes

YaSelectValue

Displays the selected value or placeholder.

PropTypeDefaultDescription
placeholderstring-Placeholder text

YaSelectContent

The dropdown content container. Uses Portal for positioning.

PropTypeDefaultDescription
position'popper' | 'item-aligned''popper'Positioning mode
sideOffsetnumber4Distance from trigger
classNamestring-Additional classes

YaSelectItem

An individual option in the select.

PropTypeDefaultDescription
valuestringrequiredItem value
disabledbooleanfalseDisable the item
iconReactNode-Optional icon
classNamestring-Additional classes

YaSelectGroup

Groups related items together.

YaSelectLabel

Label for a group of items.

YaSelectSeparator

Visual separator between items or groups.

Accessibility

Best Practices

DoDon't
Use clear, concise labels for optionsUse vague or unclear option labels
Order options logicallyRandom ordering of options
Include a descriptive placeholderSkip the placeholder
Use destructive prop for validation errorsCustom red styling without the prop
Use sm size for dense interfacesForce large selects in toolbars
Group related options with labelsMix unrelated options without structure

TypeScript

import {
  YaSelect,
  YaSelectTrigger,
  YaSelectValue,
  YaSelectContent,
  YaSelectItem,
  YaSelectGroup,
  YaSelectLabel,
  YaSelectSeparator,
} from '@/components/ui/ya-select'

On this page