Light

Component Selection

Quick reference for choosing the right component when multiple options exist.


Overlay Components: Dialog vs Sheet vs Drawer

When to Use Each

ComponentUse ForPositionSize
DialogFocused tasks, confirmations, formsCenterFixed width
SheetSupplementary content, filters, panelsSide (right/left)Partial width
DrawerMobile navigation, bottom panelsBottom/SideVariable

Decision Flow

Need to interrupt user for focused action?
├── Yes → Is it a simple confirmation?
│         ├── Yes → AlertDialog
│         └── No → Dialog
└── No → Is it supplementary/contextual content?
          ├── Yes → Does it need significant space?
          │         ├── Yes → Sheet
          │         └── No → Popover
          └── No → Is it mobile navigation?
                    ├── Yes → Drawer
                    └── No → Consider inline content

Specific Use Cases

Use CaseComponent
Delete confirmationAlertDialog
Edit profile formDialog
Create new item formDialog
Filter panelSheet
Detail previewSheet
Mobile menuDrawer
Settings panelSheet
Quick actionsPopover or DropdownMenu

Feedback Components: Alert vs Toast vs Dialog

When to Use Each

ComponentUse ForPersistenceUser Action
Toast (Sonner)Non-blocking feedbackAuto-dismissOptional
AlertImportant inline noticesPersistentOptional
AlertDialogCritical confirmationsBlockingRequired

Decision Flow

Is immediate user action required?
├── Yes → Is it destructive/irreversible?
│         ├── Yes → AlertDialog with confirm
│         └── No → AlertDialog or Dialog
└── No → Should it persist until dismissed?
          ├── Yes → Alert (inline)
          └── No → Toast (Sonner)

Feedback Severity Hierarchy

Feedback TypeUse ForComponent
Toast (success)Non-blocking confirmationsSonner
Toast (error)Recoverable errorsSonner
Inline alertImportant notices in contextAlert
Form errorField validationInput error state + text styling
DialogCritical confirmations, destructive actionsDialog
Full pageBlocking errors, 404/500Dedicated layout with Empty

State Combination Patterns

// Loading → Error
{isLoading && <Skeleton />}
{error && <Alert variant="destructive">...</Alert>}
{data && <Content />}

// Loading → Empty
{isLoading && <Skeleton />}
{!isLoading && data.length === 0 && <EmptyState />}
{!isLoading && data.length > 0 && <DataTable data={data} />}

Specific Use Cases

Use CaseComponent
"Changes saved"Toast (success)
"Error saving" (recoverable)Toast (error)
"Session expired"Alert or Dialog
"Delete this item?"AlertDialog
"Unsaved changes"AlertDialog
Form validation errorInline error text
Important system noticeAlert

Selection Components: Select vs Combobox vs RadioGroup

When to Use Each

ComponentBest ForSearchableMulti-select
Select5-15 predefined optionsNoNo
ComboboxMany options, needs searchYesOptional
RadioGroup2-5 mutually exclusive optionsNoNo
CheckboxIndependent boolean choicesNoYes (multiple)

Decision Flow

How many options?
├── 2-5 options → Are they mutually exclusive?
│                 ├── Yes → RadioGroup
│                 └── No → Multiple Checkboxes
├── 5-15 options → Select
└── 15+ options → Combobox (searchable)

Need to select multiple?
├── Yes → Is it a short list?
│         ├── Yes → Checkbox group
│         └── No → Multi-select Combobox
└── No → Select, Combobox, or RadioGroup

Specific Use Cases

Use CaseComponent
Gender selection (M/F/Other)RadioGroup
Country selectionCombobox
State/provinceSelect
Assign users to taskMulti-select Combobox
Notification preferencesCheckboxes
Payment methodRadioGroup
TimezoneCombobox
Status filterSelect

Text Input Components: Input vs Textarea vs Rich Text

When to Use Each

ComponentBest ForLines
InputSingle-line text1
TextareaMulti-line plain text2-10
Rich Text EditorFormatted contentVariable

Decision Flow

Is the content single-line?
├── Yes → Input (with appropriate type)
└── No → Does it need formatting?
          ├── Yes → Rich Text Editor
          └── No → Textarea

Input Types

Data TypeInput TypeExtra
Emailtype="email"Built-in validation
Passwordtype="password"Toggle visibility
Phonetype="tel"Pattern validation
Numbertype="number"Min/max constraints
Searchtype="search"With search icon
URLtype="url"Built-in validation

Navigation Components: Tabs vs Accordion vs Stepper

When to Use Each

ComponentBest ForContent Visibility
TabsParallel content sectionsOne at a time
AccordionFAQ, collapsible sectionsMultiple possible
StepperSequential processOne at a time

Decision Flow

Is this a multi-step process?
├── Yes → Stepper or multi-page wizard
└── No → Are sections peer-level content?
          ├── Yes → Is space limited?
          │         ├── Yes → Tabs
          │         └── No → Separate cards
          └── No → Is it Q&A or details?
                    ├── Yes → Accordion
                    └── No → Tabs or separate sections

Specific Use Cases

Use CaseComponent
Account/Password settingsTabs
FAQ pageAccordion
Checkout flowStepper
Product detailsTabs
File/folder treeCollapsible tree
Code preview/outputTabs

Button Variants

When to Use Each Variant

VariantUse ForVisual Weight
defaultPrimary actionHighest
secondarySupporting actionMedium
outlineNeutral/cancel actionsLow
ghostToolbar/subtle actionsLowest
destructiveDelete/remove actionsHigh (danger)
linkNavigation-like actionsLowest

Decision Flow

Is this the main action on the page?
├── Yes → default (primary)
└── No → Is it destructive?
          ├── Yes → destructive
          └── No → Is it a cancel/dismiss?
                    ├── Yes → outline
                    └── No → Is it in a toolbar?
                              ├── Yes → ghost
                              └── No → secondary

Button Pairing Rules

Primary ActionSecondary Action
defaultoutline
destructiveoutline
defaultghost

Rule: Never pair two default buttons side by side.


Menu Components: DropdownMenu vs ContextMenu vs Menubar

When to Use Each

ComponentTriggerPosition
DropdownMenuClick buttonBelow trigger
ContextMenuRight-clickAt cursor
MenubarClick menu labelApp-level navigation
CommandKeyboard shortcut (⌘K)Center modal

Decision Flow

How is the menu triggered?
├── Click on button → DropdownMenu
├── Right-click → ContextMenu
├── Keyboard shortcut → Command (palette)
└── App navigation bar → Menubar

Data Display: Table vs DataTable vs List

When to Use Each

ComponentBest ForFeatures
TableSimple data displayBasic
DataTableInteractive dataSort, filter, paginate
Card listVisual itemsImages, rich content

Decision Flow

Is the data tabular (rows/columns)?
├── Yes → Needs sorting/filtering?
│         ├── Yes → DataTable (with TanStack)
│         └── No → Table
└── No → Is each item visually rich?
          ├── Yes → Card grid/list
          └── No → Simple list

Tooltip vs Popover vs HoverCard

When to Use Each

ComponentContentTriggerPersistence
TooltipBrief text labelHoverDisappears on leave
HoverCardRich previewHoverDisappears on leave
PopoverInteractive contentClickUntil dismissed

Decision Flow

Is the content interactive (buttons, links)?
├── Yes → Popover
└── No → Is it a rich preview?
          ├── Yes → HoverCard
          └── No → Tooltip

Specific Use Cases

Use CaseComponent
Icon button labelTooltip
User profile previewHoverCard
Date pickerPopover
Color pickerPopover
Abbreviation explanationTooltip
Link previewHoverCard

Quick Reference Table

NeedUse
Centered modal for formsDialog
Side panel for filtersSheet
Mobile menuDrawer
Confirmation before deleteAlertDialog
Success notificationToast
Important notice in contextAlert
3 choices, pick oneRadioGroup
Many choices, searchableCombobox
Medium list, no searchSelect
Multi-line textTextarea
Sequential stepsStepper
Parallel sectionsTabs
Collapsible Q&AAccordion
Main actionButton default
Cancel actionButton outline
Subtle helper textTooltip
Rich preview on hoverHoverCard
Interactive menuPopover

Last updated: February 4, 2026