CentercodeDitto
DittoPorygonAPI

CardPicker

Single-choice selection widget with icon cards, search, and categories

Overview

CardPicker provides an intuitive single-choice selection interface with options displayed as horizontal icon cards. Users can search, filter by category, and toggle between compact and full views. Ideal for selecting project types, templates, or element types.

Key Features

  • Search across labels, descriptions, and hidden metadata
  • Category filtering with dropdown selector
  • Compact/Full view toggle (auto-hidden without descriptions)
  • Customizable colors per option via Tailwind classes
  • Badge support for labels like New, Popular, Beta
  • Keyboard navigation with arrow keys and Enter to select

Interactive Examples

Basic Usage

Simple card selection with search

Survey
Popular
Poll
Discussion
Bug Report
Feature Idea
New
NPS Score
Selected: survey

With Categories

Filter options by category using the dropdown

Survey
Popular
Poll
Discussion
Bug Report
Feature Idea
New
NPS Score
Selected: None

Multi-Select

Enable multiple selections with the multiple prop

Set multiple=true to allow selecting multiple options. A checkbox indicator appears on each card.

Survey
Popular
Poll
Discussion
Bug Report
Feature Idea
New
NPS Score
Selected (2): survey, poll

Multi-Select Required

With required, at least one option must remain selected

When multiple=true and required=true, users cannot deselect the last remaining item.

Beta Test
Usability Study
Focus Group
Selected (1): beta

Scrolling

With many options, the picker scrolls within a fixed height

This example has 22 options with a maxHeight of 350px, forcing the content to scroll.

Survey
Poll
Discussion
Bug Report
Feature Idea
NPS Score
Image Upload
Video
File Attachment
Folder
Email
Notification
Settings
Favorite
Bookmark
Calendar Event
Location
Photo Capture
Voice Recording
Audio Player
Gamification
Challenge
Selected: None

Full View Mode

Full view shows descriptions with 2 columns on desktop

Set defaultViewMode="full" to show descriptions by default. Users can toggle between compact and full views.

Survey
Popular

Structured questionnaire with multiple question types

Poll

Quick single-question vote

Discussion

Open-ended forum thread for detailed feedback

Bug Report

Structured issue reporting with severity levels

Feature Idea
New

Capture and prioritize user suggestions

NPS Score

Net Promoter Score measurement

Selected: None

Optional Selection

Click the selected item again to deselect it

When required=false, clicking the selected item again will deselect it.

Beta Test
Usability Study
Focus Group
Selected: beta

In Dialog

CardPicker works seamlessly inside dialogs

Dialog selected: None

Custom Colors

Items can have unique colors via colorClass prop

Each option can have a colorClassprop with Tailwind classes to style the icon and selection border.

Survey
Popular
Poll
Discussion
Bug Report
Feature Idea
New
NPS Score

Empty State

What users see when no options match their search

Try searching for something that doesn't exist to see the empty state.

No element types match your search

Interfaces

CardPickerOption

PropTypeDescription
idstringUnique identifier for the option
labelstringDisplay label for the option
descriptionstring?Optional description shown in Full view mode
metastring?Hidden searchable text for synonyms and keywords
iconIconDefinitionFont Awesome icon to display
categoriesstring[]?Category IDs this option belongs to
badgestring?Optional badge text (e.g., New, Popular)
colorClassstring?Tailwind classes for icon and border colors

CardPickerCategory

PropTypeDescription
idstringUnique identifier for the category
labelstringDisplay label for the category dropdown

Props Reference

PropTypeDefaultDescription
optionsCardPickerOption[]requiredArray of options to display
valuestring | null-Currently selected option ID (controlled)
onChange(value: string | null) => void-Callback when selection changes
categoriesCardPickerCategory[][]Categories for dropdown filter
requiredbooleantrueWhen false, clicking selected item deselects it
size'sm' | 'default' | 'lg''default'Card size variant
defaultViewMode'compact' | 'full''compact'Initial view mode (compact hides descriptions)
showViewTogglebooleantrueShow view mode toggle button (auto-hidden without descriptions)
maxHeightnumber500Maximum height in pixels before scrolling
inDialogbooleanfalseEnable dialog mode (fixed height behavior)
searchPlaceholderstring'Search...'Placeholder text for search input
emptyMessagestring'No options...'Message shown when no options match search
disabledbooleanfalseDisable all interactions

Usage

import { CardPicker, type CardPickerOption, type CardPickerCategory } from '@/ui/components';
import { faClipboardList, faSquarePollVertical } from '@fortawesome/duotone-regular-svg-icons';

// Define your options
const options: CardPickerOption[] = [
  {
    id: 'survey',
    label: 'Survey',
    description: 'Structured questionnaire',
    meta: 'questionnaire form', // Hidden searchable text
    icon: faClipboardList,
    categories: ['feedback'],
    badge: 'Popular',
    colorClass: 'text-blue-500 border-blue-500',
  },
  {
    id: 'poll',
    label: 'Poll',
    description: 'Quick single-question vote',
    icon: faSquarePollVertical,
    categories: ['feedback'],
    colorClass: 'text-purple-500 border-purple-500',
  },
];

// Optional categories for filtering
const categories: CardPickerCategory[] = [
  { id: 'feedback', label: 'Feedback' },
  { id: 'research', label: 'Research' },
];

// Basic usage
const [selected, setSelected] = useState<string | null>(null);

<CardPicker
  options={options}
  value={selected}
  onChange={setSelected}
/>

// With all options
<CardPicker
  options={options}
  value={selected}
  onChange={setSelected}
  categories={categories}
  required={false}
  size="default"
  defaultViewMode="full"
  showViewToggle={true}
  maxHeight={500}
  searchPlaceholder="Search elements..."
  emptyMessage="No elements match your search"
/>