Skip to content
WingoUI
ComponentsTemplatesDocsPricingAI agentsBlogChangelogContact
Components
Buttons & Actions
ButtonButton GroupCopy ButtonDelete ButtonTheme ToggleToggleToggle Group
Inputs
Avatar UploadCalendarCheckboxColor PickerComboboxCountry SelectCron PickerCurrency InputDate PickerDate Range PickerDate Time PickerDuration PickerEmail InputEmoji PickerFile UploadFilter BuilderInputInput GroupListboxMasked InputMention InputMonth PickerMulti SelectNumber InputOTP InputPassword InputPhone InputRadio GroupRatingSearch InputSegmented ControlSelectSignature PadSliderSwitchTag InputTextareaTime PickerTimezone SelectTree Select
Forms
Address InputBooking WidgetCSV ImportFieldForm WizardInline EditInvoice line itemsRich Text EditorSchema Builder
Navigation
Back To TopBounce SidebarBreadcrumbCommand MenuGlobal SearchGooey NavHook SidebarNav MenuNav TabsPaginationProximity SidebarScroll ProgressSidebarStepsTable Of ContentsTabsTopbarUser MenuWorkspace Switcher
Overlays
Alert DialogContext MenuDialogDrawerDropdown MenuFamily DrawerHover CardPopoverShare DialogSheetShortcuts DialogTooltipTour
Feedback
AlertBannerCookie ConsentEmoji ReactionEmpty StateNotification BellNotification CenterProgressRoute ProgressSetup ChecklistSkeletonSpinnerToast
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 chartRadar chartRadial barSparklineStat CardTrackerTrend badge
Layout
AccordionApp ShellCardCollapsibleDetail LayoutEntity HeaderPage HeaderScroll AreaSeparatorSettings LayoutSplit ViewToolbar
Media
Audio PlayerCarouselCSV ViewerDOCX EditorDOCX ViewerExcel ViewerFile SystemImage compareImage CropperImage GalleryImage LightboxLocation MapPDF ViewerPowerPoint ViewerQR CodeStep PlayerVideo Player
AI Kit
Agent Status CardChat MessageChat ThreadChat WidgetConversation ListFluid OrbGrid RevealMatrix OrbModel PickerPrompt InputReasoning IndicatorRule BuilderSuggestion ChipsTool Call TimelineUsage MeterVoice InputWorkflow Canvas
Text & Effects
Background PatternGravity LettersMarqueeTerminalText AnimateText Rotate
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
Marketing Sections
App Download SectionBlog Cards SectionCTA SectionFAQ SectionFeature GridFeature ShowcaseHero SectionIntegrations SectionLogo CloudMarketing FooterMarketing HeaderMarketing SectionNewsletter SectionPricing SectionStats SectionSteps SectionTeam SectionTestimonials SectionTimeline SectionVideo Section
Blocks
Admin Dashboard PageAdmin ShellAI Chat PageAPI Keys PageAutomation Builder PageCheckout PageCRM Contact PageCRM Pipeline PageError PagesInbox PageInvoice PageKPI DashboardListing Detail PageLogin PageMarketplace Home PageMarketplace Search PageMarketplace ShellMobile App HomeOnboarding FlowOrder History PagePost Listing WizardPricing PageProfile PageRegister PageSettings PageUsers Admin Page
Templates
About PageAcademy PageAccessibility PageAffiliate PageAgency PageAI Product PageAppointment Booking PageBlog PageBlog Post PageBug Bounty PageCareers PageChangelog PageCommunity PageCompare PageContact PageCustomer Story PageCustomers PageDemo Booking PageDevelopers PageDocs Home PageDownload PageEnterprise PageEvents PageExperts PageFAQ PageFeature PageGlossary PageHelp Article PageHelp Center PageHome Services PageImpact PageIntegration Detail PageIntegrations PageJob Detail PageLanding PageLaunch PageLegal PageManifesto PagePortfolio PagePress PageProduct Tour PagePromo PageReal Estate PageReferral PageResearch Report PageRestaurant PageRoadmap PageROI Calculator PageSecurity PageSolutions PageStartups PageStatus PageStorefront PageSwitch PageTemplate Gallery PageTravel PageWaitlist PageYear in Review Page
Hooks & Utilities
AI ChatChart kitCommerceDate utilsFile exportFile typesFiltersForm validationHapticsInvoicingMotion presetsNavigationNumber formatRelative timeRomanian locationsSpreadsheetText matchTonesUIProvideruseClipboarduseConsentuseControllableStateuseCooldownuseDebounceuseKeyboardInsetuseLocaleuseLongPressuseMediaControlsuseMediaQueryuseOverflowItemsusePersistedStateuseScrollEdgesuseScrollStateuseSelectionuseShortcutuseStickToBottom
GalleryTheme

AI Kit

Suggestion Chips

AI Kit

Suggestion Chips React component for Tailwind CSS v4

Rule BuilderTool Call Timeline
Live props
Content
title
showIcons
showDescriptions
Appearance
variant
size
radius
tone
color
Layout
layout
columns
align
bleed
maxAll
State
loading
skeletonCount4
disabled
Behavior
animate
Code
import { SuggestionChips } from "@/components/ui/suggestion-chips"

<SuggestionChips />
  1. Home
  2. Components
  3. AI Kit
  4. Suggestion Chips
Pro

Suggestion Chips React component for Tailwind CSS v4

v1.0.0·Added in 1.0.0

React suggestion chips for AI chat: prompts people tap instead of typing, as pills under a composer, welcome cards or follow-up rows.

Tap or click a suggestion and onSelect hands it to the app, which sends or inserts its prompt; nothing stays selected. Pills and cards dip on a quick spring when pressed and tint on hover; follow-up rows tint and nudge their arrow. On a phone the pills (below 768px) and the cards (below 640px) sit in one row that swipes, snaps per item, runs to the screen edges and fades where more is waiting, with 44px targets; on a desktop they wrap or form a grid. With max set, a +N pill (or Show more under cards and rows) reveals the rest in place and turns into Show less; focus moves to the first revealed suggestion. More ideas spins its icon until your onRefresh promise settles, then only the new suggestions stagger in. The whole group is one Tab stop: Left and Right move between pills and cards (Up and Down between rows of a wrapped or grid layout, and through the list variant), Home and End jump to the ends, Enter or Space picks. While a reply streams, disabled dims everything and blocks picks but keeps focus where it was. Reduced motion turns the stagger and slides into short fades.

Suggestion Chips is a Pro React component in the React AI components category, written in TypeScript for React 19 and Tailwind CSS v4. It installs as source with npx wingo-ui@latest add suggestion-chips, together with Skeleton, useLocale, useScrollEdges, AI Chat, Motion presets and 3 more and the npm packages motion and lucide-react.

Add to a project

Requirements: React 19 and Tailwind CSS v4, in Next.js (App Router or Pages), Vite or React Router. Installation guide · Next.js setup · Vite setup

npx wingo-ui@latest add suggestion-chips

Suggestion Chips is part of Pro, with 298 more Pro items: $8 a month or $150 once. 14-day refund before you download any Pro item. See plans

Usage

Import SuggestionChips from @/components/ui/suggestion-chips.

import { CalendarDays, ChartColumn, Mail, Receipt } from "lucide-react"
import { SuggestionChip, SuggestionChips, type ChatSuggestion } from "@/components/ui/suggestion-chips"

const suggestions: ChatSuggestion[] = [
  { id: "overdue", label: "Summarize overdue invoices", description: "What is left to collect this month", icon: <Receipt /> },
  { id: "follow-up", label: "Write a follow-up email", description: "For offer #OF-2026-118", icon: <Mail /> },
  { id: "q3", label: "Compare Q3 collections", description: "July, August and September", icon: <ChartColumn /> },
  { id: "meeting", label: "Prepare Monday's meeting", description: "Agenda and the week's numbers", icon: <CalendarDays /> },
]

export function WelcomeSuggestions({ onSend }: { onSend: (text: string) => void }) {
  return (
    <SuggestionChips
      variant="card"
      title="Try"
      suggestions={suggestions}
      onSelect={(suggestion) => onSend(suggestion.prompt ?? suggestion.label)}
    />
  )
}

// one pill, card or row in your own layout: same look, press and tooltip, without the roving focus
export function PinnedSuggestion({ onSend }: { onSend: (text: string) => void }) {
  return <SuggestionChip variant="card" suggestion={suggestions[0]} onSelect={(s) => onSend(s.prompt ?? s.label)} />
}

Props

  • suggestions*
    ChatSuggestion[]

    The suggestions, keyed by id, in order: { id, label, prompt?, description?, icon?, group? } (ChatSuggestion from ai-chat, re-exported here). prompt is what the app should send, defaulting to label. An empty list renders nothing unless loading. Long labels truncate (pill) or clamp to two lines (card) and show the full text as a tooltip.

  • titledefault ""
    ReactNode

    An eyebrow above the suggestions, like "Try" or "Continue with". It also names the group for screen readers (labels.group does when it is empty).

  • showIconsdefault true
    boolean

    Shows each suggestion's icon: before the label on a pill, in a tinted tile on a card (a Sparkles when the suggestion has none), and as the leading glyph of a row (a reply arrow when it has none).

  • showDescriptionsdefault true
    boolean

    Shows the description under the label on cards (two lines) and rows. Pills never show it.

  • variantdefault "chip"
    "chip" | "card" | "list"

    chip: pills, the classic row under an empty composer. card: tiles with an icon, a label and a two-line description for a new chat's welcome screen. list: full-width rows with a trailing arrow, for follow-ups under an answer or a prompt library.

  • sizedefault "md"
    "sm" | "md" | "lg"

    Pills 32 / 36 / 40px tall with 13 / 14 / 15px text (44px on touch screens), cards at least 64 / 76 / 88px tall and 216 / 240 / 264px wide in a rail, rows 40 / 44 / 48px.

  • radiusdefault "full"
    "none" | "sm" | "md" | "lg" | "full"

    Corner shape. Pills use the button's radius per size (full is a pill), cards the surface radius (12 / 16 / 24px, full is 24px) with the icon tile following along, rows the pill radius capped at 12px.

  • tonedefault "neutral"
    "neutral" | "brand" | "success" | "warning" | "danger" | "info"

    Colors the icons (and card tiles) and the hover and pressed tint. neutral keeps icons muted and tints with the foreground; the pills themselves always stay a calm gray.

  • colordefault ""
    string

    Any CSS color. Replaces the tone for the icons, the tiles and the tint. Leave empty to use the tone.

  • layoutdefault "auto"
    "auto" | "wrap" | "scroll" | "grid"

    auto: pills swipe in one row below 768px and wrap above; cards swipe below 640px and form a grid above. wrap, scroll and grid force one arrangement at every width. The list variant always stacks.

  • columnsdefault "2"
    2 | 3 | 4

    Grid columns from 640px. A narrower container drops columns so a card never gets squeezed below about 170px: three columns need 544px of room, four need 736px.

  • aligndefault "start"
    "start" | "center"

    Where wrapped pills, the eyebrow and the card footer sit. center suits a welcome screen with a centered greeting.

  • bleeddefault true
    boolean

    The swiping row runs 16px into the page gutter, so items slide off the screen edge instead of stopping at a hard cut; list rows reach 8px into it, so their text lines up with the eyebrow while the hover highlight extends outward. Turn it off inside a card or a panel without that much padding.

  • maxdefault 0
    number

    Shows at most this many; the rest wait behind a +N pill (chip) or Show more (card, list) that reveals them in place and turns into Show less. 0 shows all, and a max at or above the count shows no +N.

  • loadingdefault false
    boolean

    Skeleton pills, cards or rows in the variant's exact shape while suggestions load; the group is aria-busy and says so to screen readers once.

  • skeletonCountdefault 4
    number

    How many skeletons loading shows.

  • disableddefault false
    boolean

    Dims every suggestion to 50% and blocks picks, for while a reply streams. Items stay focusable (aria-disabled), so keyboard focus is never thrown back to the page.

  • animatedefault true
    boolean

    Staggers suggestions in (40ms apart, all in within 0.3s) when they mount in the browser and when the set changes; suggestions that stay keep their place. Server-rendered html already shows the final state. Reduced motion fades without offsets.

  • onSelect
    (suggestion: ChatSuggestion) => void

    Called with the picked suggestion; send or insert suggestion.prompt ?? suggestion.label. Not called while disabled. The component keeps no selection.

  • onRefresh
    () => (void | Promise<unknown>)

    Adds a trailing More ideas pill (or row, or a button under cards). Its icon spins until the returned promise settles and always finishes the turn it is on; then pass the new suggestions and only the new ids stagger in.

  • labels
    Partial<SuggestionChipsLabels>

    Every string, merged over the English defaults: group "Suggestions" (the group's name without a title), refresh "More ideas", more (count, formatted) => "+3", showMore "Show more", showLess "Show less", loading "Loading suggestions". The count is formatted in the UIProvider locale.

  • classNames
    Partial<Record<"rail" | "chip" | "icon" | "label" | "description" | "arrow" | "title" | "more" | "refresh" | "footer", string>>

    Extra classes for the parts: the rail (the scroller, wrap or grid), every chip, card or row, their icon, label, description and trailing arrow, the eyebrow, the +N and refresh controls, and the footer under cards.

  • className
    string

    Extra classes for the root group, merged last. Override the tone vars here, e.g. [--tone-soft-foreground:purple].

Parts

  • SuggestionChip

    component

    One suggestion on its own, for a single starter card or a chip placed by hand. Same look and press as the chips in the group.

    • suggestion*
      ChatSuggestion

      The suggestion to show: label, prompt, description and icon.

    • onSelect
      (suggestion: ChatSuggestion) => void

      Called on a tap or Enter.

    • variantdefault "chip"
      "chip" | "card" | "list"

      A pill, a card with a description, or a full-width row.

    • sizedefault "md"
      "sm" | "md" | "lg"

      Height, padding and type size.

    • radiusdefault "full"
      "none" | "sm" | "md" | "lg" | "full"

      Corner shape.

    • tonedefault "neutral"
      Tone

      Semantic color of the icon and the hover tint.

    • showIcondefault true
      boolean

      Shows the suggestion's icon.

    • showDescriptiondefault true
      boolean

      Shows the description on cards and rows.

    • disableddefault false
      boolean

      Dims the chip and blocks it.

  • DEFAULT_SUGGESTION_CHIPS_LABELS

    constant

    The English copy: group "Suggestions", refresh "More ideas", more "+3", showMore, showLess and loading. Spread it into labels to translate a few keys.

  • ChatSuggestion

    type

    One suggestion, shared with the AI chat kit (lib/ai-chat): id, label, prompt (defaults to label), description, icon and group.

Examples

Welcome cards

variant="card" columns={3}: three across with room to spare, two in a narrow box like this one, a swipe rail on phones.

Follow-ups

variant="list" under an answer. Picking one disables the rows while the reply streams.

Phone rail

layout="scroll" in a 390px frame: the rail bleeds to the edges, snaps per chip and fades where more is waiting.

Refresh

onRefresh returns a promise; the icon spins until it settles and finishes its turn.

Tones and custom color

Brand icons on calm gray pills, an info-toned card grid and a violet follow-up list.

Overflow and loading

max={3} folds the rest behind +3; loading shows skeletons in each variant's shape.

Sizes and radius

32, 36 and 40px pills (44px on touch) with the button's radius scale.

SuggestionChip in your own layout

The same pill and card one at a time, with tone and disabled per chip.

Dependencies

motionlucide-reactskeletonuse-localeuse-scroll-edgesai-chatmotionnumber-formattonesui-config

Files

  • components/ui/suggestion-chips.tsx

FAQ

Is the React Suggestion Chips component free?

The preview, props and docs are free; copying the source needs a Pro plan. See plans.

How do I install Suggestion Chips?

Run npx wingo-ui@latest add suggestion-chips. It also adds the Wingo UI items it builds on (Skeleton, useLocale, useScrollEdges, AI Chat, Motion presets and 3 more) and the npm packages motion and lucide-react. With shadcn, add the @wingo-ui registry with your API key, then run npx shadcn@latest add @wingo-ui/suggestion-chips.

How does Suggestion Chips behave on phones?

On a phone the pills (below 768px) and the cards (below 640px) sit in one row that swipes, snaps per item, runs to the screen edges and fades where more is waiting, with 44px targets; on a desktop they wrap or form a grid.

See also

TagButton GroupEmpty StateAI ChatlibFluid Orb

Used in

Chat ThreadChat WidgetAI Chat Page

More React AI components

Tool Call TimelineUsage MeterGrid RevealMatrix OrbWorkflow CanvasVoice Input
All 17 React AI components

Articles using this component

  • React Prompt Input: Enter, IME, Files, Stop and Voice

    Building UI with AI agents · Oct 16, 2026 · 10 min read

PreviousRule BuilderNext Tool Call Timeline

Hi Emma!How can I help today?

onSelect: none yet · max: all · animate: on