WingoUI
Buttons & Actions
ButtonButton GroupCopy ButtonDelete ButtonTheme ToggleToggleToggle Group
Inputs
Avatar UploadCalendarCheckboxColor PickerComboboxCron PickerCurrency InputDate PickerDate Range PickerDate Time PickerDuration PickerFile UploadFilter BuilderInputInput GroupListboxMasked InputMention InputMonth PickerMulti SelectNumber InputOTP InputPassword InputPhone InputRadio GroupRatingSearch InputSegmented ControlSelectSignature PadSliderSwitchTag InputTextareaTime Picker
Forms
Address InputCSV ImportFieldForm WizardInline EditInvoice line itemsRich Text Editor
Navigation
Back To TopBounce SidebarBreadcrumbCommand MenuGlobal SearchGooey NavHook SidebarNav MenuNav TabsPaginationProximity SidebarScroll ProgressSidebarStepsTable Of ContentsTabsTopbarUser MenuWorkspace Switcher
Overlays
Alert DialogContext MenuDialogDrawerDropdown MenuFamily DrawerHover CardPopoverSheetShortcuts DialogTooltipTour
Feedback
AlertBannerCookie ConsentEmoji ReactionEmpty StateNotification BellNotification CenterProgressRoute ProgressSkeletonSpinnerToast
Data Display
Approval FlowAvatarBadgeCalendar ViewCode BlockComment ThreadContact cardCountdownDescription ListDiff ViewerFile ListFile managerFolderGanttJSON ViewerKbdLog ViewerMarkdownPresenceSchedulerTagTimelineTree View
Tables & Lists
Audit LogData TableDeal PipelineEditable GridKanbanListMembers tablePermissions MatrixTableTask ListVirtual List
Charts & Stats
Animated CounterArea chartBar chartDonut chartFunnel chartGaugeGitHub ActivityHeatmap calendarLeaderboardLine chartRadial barSparklineStat CardTrackerTrend badge
Layout
AccordionApp ShellCardCollapsibleDetail LayoutEntity HeaderPage HeaderScroll AreaSeparatorSettings LayoutSplit ViewToolbar
Media
Audio PlayerCarouselImage CropperImage LightboxLocation MapQR CodeStep PlayerVideo Player
AI Kit
Agent Status CardChat MessageChat ThreadConversation ListFluid OrbGrid RevealMatrix OrbModel PickerPrompt InputReasoning IndicatorRule BuilderSuggestion ChipsTool Call TimelineUsage MeterVoice InputWorkflow Canvas
Text & Effects
Gravity Letters
Mobile
Action SheetBottom Tab BarFABHaptic ButtonHero HeaderInstall PromptLarge Title HeaderNotification BannerOnboarding CarouselPicker WheelPull To RefreshSlide To ConfirmSticky CTA BarSwipe DeckSwipeable Tabs
Commerce
Cart drawerCategory pickerCheckout stepsCoupon inputFavorite buttonFilter panelListing cardListing gridOrder trackerPricePrice rangePricing tableProduct galleryQuantity stepperReviewsSeller card
Blocks
Admin Dashboard PageAdmin ShellAI Chat PageAutomation Builder PageCheckout PageCRM Contact PageCRM Pipeline PageError PagesInbox PageInvoice PageKPI DashboardListing Detail PageLogin PageMarketplace Home PageMarketplace Search PageMarketplace ShellMobile App HomeOnboarding FlowPost Listing WizardPricing PageRegister PageSettings PageUsers Admin Page
Hooks & Utilities
AI ChatChart kitCommerceDate utilsFile exportFile typesFiltersForm validationHapticsInvoicingMotion presetsNavigationNumber formatRelative timeRomanian locationsSpreadsheetText matchTonesUIProvideruseClipboarduseConsentuseControllableStateuseCooldownuseDebounceuseKeyboardInsetuseLocaleuseLongPressuseMediaControlsuseMediaQueryuseOverflowItemsusePersistedStateuseScrollEdgesuseScrollStateuseSelectionuseShortcutuseStickToBottom
GalleryThemeCredits

Commerce

Category picker

CommerceCategory picker
Cart drawerCheckout steps
Live props
State
defaultValue
defaultQuery
Appearance
variant
iconStyle
size
tone
color
Layout
columnsAuto
Behavior
selectableParents
search
locale
Content
showCounts
Code
import { CategoryPicker } from "@/components/ui/category-picker"

<CategoryPicker />
Pro

v1.0.0·Added in 1.0.0

Browse and pick a category from a tree: icon tiles, drill-down rows with a back button, counts, search across levels and a field.

Tap a tile or a row with subcategories and the next level slides in from the right; the back button (or the breadcrumb under the title, which folds its middle four levels deep) slides you back out. Tap a leaf to pick it: it tints and a check draws in, and parents on the way to your choice carry a small dot. With selectableParents the first row of a level, “All in Electronics”, picks the whole branch. Type in the search to find a category at any depth: matches are highlighted, exact words and leaves come first (then the busier category), each row shows its path, and clearing the search (its X, Escape, the back button, or the Clear search button under “No categories found”) returns to the level you were on. The field shows the picked path in a form box and opens the picker in a popover on desktop and in a full-height bottom sheet on phones, where the sheet's title row doubles as the picker's header (the level's name and the back button appear in it as you drill in); picking a leaf closes it and returns focus to the field. Keyboard: Tab reaches the back button, the search and one item per level; in the grid the arrows move in two dimensions, in lists Up and Down move, Right opens a parent and Left goes back; Home, End, Page Up and Page Down jump; Enter or Space opens or picks; Backspace outside the search goes up; Escape clears the search, then goes up a level, and at the top closes the field's overlay. In the search, Down moves into the list and Enter picks the first match. After a drill focus lands on the first item, after going back on the parent you came from. On phones tiles sit three to a row, rows are 56px and the back button is 44px; the search only takes focus by itself on a mouse or trackpad so the keyboard never covers the tree. Under reduced motion levels cross-fade instead of sliding.

Add to a project

npx wingo-ui@latest add category-picker

Pro item: the CLI needs a Pro account. See plans

Dependencies

lucide-reactmotionbuttonfieldinputpopoveruse-controllable-stateuse-localeuse-media-querymotionnavigationnumber-formattext-matchtonesui-config

Files

  • components/ui/category-picker.tsx

See also

Filter panelListing gridTree ViewListboxPopover
PreviousCart drawerNext Checkout steps

All categories

value: "" · no category picked