Shadcn Select Examples - 13+ Variants with React Hook Form Integration

Complete guide to shadcn select component with 13 production-ready variations: grouped options, icons, async data loading, React Hook Form integration, controlled state, searchable, disabled states. TypeScript code examples for React and Next.js forms.

AshFull-stack developer and UI/UX enthusiast.
Published 1/29/2026
15 min read
shadcn/uiReactNext.jsSelect ComponentDropdownForm ComponentsReact Hook FormTypeScriptTailwind CSSRadix UIForm ValidationFrontend Development
Shadcn Select Examples - 13+ Variants with React Hook Form Integration

When a form starts getting real, the select input matters. It's never just "pick something from a dropdown." You want something that looks clean, works on keyboard, handles long lists, and doesn't feel like a dated HTML <select>.

That's exactly why I use shadcn select.

It's a customizable dropdown component built on top of Radix UI, with Tailwind CSS for styling. In simple terms, it gives you a React select component that's accessible and easy to control without fighting default browser styling.

If you're building forms with multiple fields - location picks, settings, filters, categories, type selectors - the stock browser select quickly becomes limiting. The shadcn/select component keeps the structure predictable and lets you style and extend everything using just classNames.

In this guide, I'll show you practical shadcn select examples ranging from a basic dropdown to searchable options, grouped lists, icons, async data, and "controlled" versions for React forms.

Tested with: React 19.x, Next.js 16.x

Prerequisites

Before using the shadcn select component, there are a few basics your project should have in place.

You need:

  • React 19
  • Tailwind CSS configured
  • Radix UI primitives (installed automatically through shadcn/ui)
  • Next.js is recommended but optional

If you don't have shadcn/ui yet, initialize it:

bash

Then install the select component:

bash

That's it. This brings in the Radix primitives and the shadcn select component structure, so all the examples in this guide will work without extra setup.

You don't need a specific framework. These shadcn select examples work in:

  • Next.js
  • Vite
  • Remix
  • Astro (React mode)
  • Any React project using Tailwind

Once this is ready, we can move on to a basic implementation.

Basic Implementation

Once the select component is added, the structure is predictable. You import the pieces you need and compose them together. No hidden magic. No wrappers you can't control.

Here's the simplest working shadcn select example.

What you see: A clean dropdown that opens on click, supports keyboard navigation, and closes on selection. Focus management and accessibility are handled by Radix.

A few things worth noting if you're new to the shadcn select component:

  • SelectTrigger - Controls the clickable area.
  • SelectValue - Shows the selected option or placeholder.
  • SelectContent - Renders the dropdown menu.
  • SelectItem - Defines each option.

This structure stays the same in every variation that follows. Whether you add icons, grouping, search, or a controlled state, everything builds on this base.

Variations of shadcn select

Now we're at the part that actually matters in day-to-day work.

The base select is fine, but real products rarely stop there. Forms grow. Data changes. UX expectations go up. That's where variations come in.

Below are different select patterns I've used while building real forms - some inspired by open-source shadcn components, some shaped by product needs. Each one solves a slightly different problem, but all of them stick to the same underlying structure.

Let's start with the most common one.

1. Default Select

This is the plain, no-frills shadcn select version. Clean dropdown. Clear labels. Nothing fancy.

When to use: Most forms. Settings pages. Filters. Anywhere a simple choice is enough.

Key changes from base:

  • No extra styling beyond width.
  • Uses placeholder text for clarity.
  • Keeps interaction predictable.

2. Shadcn Select with Grouped Options

Once your list grows, flat options stop scaling. Grouping keeps things readable.

When to use: Environment selectors, region pickers, categories, roles, permissions.

Why this matters:

  • Reduces cognitive load
  • Scales without UI clutter
  • Still keyboard-accessible

3. Controlled Select (Form / State Driven)

You'll need this the moment the value affects anything else.

Selected: viewer

When to use: Forms, conditional rendering, permissions, filters synced with URL or API.

Key point: This turns shadcn select into a proper controlled React component.

4. Select with Icons (Improves Scan Speed)

Icons help when options represent states, types, or actions.

When to use: Roles, statuses, visibility levels, filters.

Pro tip: Icons should add meaning. If they don't, drop them.

5. Select Integrated with React Hook Form

When you use shadcn select inside real forms, you quickly notice that it isn't a native <select>. Because of that, form libraries like React Hook Form don't pick up its value automatically. This pattern shows how to wire the select component correctly so form state and validation stay in sync.

When to use: When building forms with React Hook Form (or similar libraries) and you need reliable control over the select value.

Key changes:

  • Value is synced manually using onValueChange
  • Works around non-native select behavior
  • Keeps form state predictable and debuggable

6. Async / Dynamic Select (API Data)

In real products, select options often come from an API or CMS. This pattern shows how to render shadcn select options dynamically once data is available.

When to use: When select options depend on API responses or external data.

Key changes:

  • Options rendered from state
  • Works with async data sources
  • Same select structure

7. Disabled Select (Feature Gating)

Sometimes a select should be visible but not interactive. This pattern is useful for plan limits, onboarding steps, or locked features.

When to use: Subscription gating, permission-based access, or incomplete flows.

Key changes:

  • Uses the disabled prop
  • No dropdown content required
  • Visual state handled automatically

8. Select with Default Value

When editing existing data, you often need the select to load with a pre-selected value.

When to use: Edit forms, saved preferences, settings pages.

Key changes:

  • Uses defaultValue
  • No controlled state needed
  • Works well for static defaults

9. Controlled Select (Full State Control)

This variation gives you full control over the select value using React state.

Priority: low

When to use: Filters, synced UI state, URL-based selections.

Key changes:

  • Uses value and onValueChange
  • Fully controlled component
  • Predictable behavior

10. Select with Icons

Icons help users scan options faster when choices represent roles, types, or states.

When to use: Role selectors, status filters, visibility controls.

Key changes:

  • Icons added inside SelectItem
  • Better visual recognition
  • No logic changes

11. Select with Long Lists (Scrollable Content)

Large option lists need scroll behavior to stay usable.

When to use: Country lists, tags, categories, large datasets.

Key changes:

  • max-h added to content
  • Scroll enabled automatically
  • Prevents layout overflow

12. Mobile-Friendly Select

On smaller screens, select triggers should stay compact and easy to tap.

When to use: Mobile-first layouts, responsive forms, compact UIs.

Key changes:

  • Full-width trigger on small screens
  • Responsive sizing
  • Same behavior across breakpoints

13. Animated Select (Subtle Open / Close Transitions)

By default, shadcn select opens instantly. In some interfaces, adding a small animation makes the dropdown feel smoother without hurting usability. This pattern uses Tailwind's data-state attributes exposed by Radix.

Frequently Asked Questions

Conclusion

The select component looks simple until you start using it in real forms. Once you deal with dynamic data, form libraries, permissions, or UX polish, the differences start to matter. That's where shadcn select works well. It gives you a predictable structure and leaves the control in your hands.

What I like about this component is that every variation builds on the same base. Whether you're wiring it to React Hook Form, loading options from an API, adding icons, or animating the dropdown, the mental model doesn't change. You're not fighting abstractions or hidden behavior.

Use these patterns as building blocks. Pick the ones that fit your use case, adjust the styling, and move on. That's the strength of shadcn ui select - flexible enough for production work, without becoming opinionated or heavy.

Tested with: 19.x

Related Articles

Create Next App