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

Buttons & Actions

Toggle Group

Buttons & Actions

Toggle Group React component for Tailwind CSS v4

ToggleAvatar Upload
Live props
Behavior
type
deselectable
loop
Appearance
variant
size
radius
tone
color
Layout
orientation
fullWidth
attached
Content
iconOnly
aria-label
State
disabled
Code
import { ToggleGroup } from "@/components/ui/toggle-group"

<ToggleGroup />
  1. Home
  2. Components
  3. Buttons & Actions
  4. Toggle Group
Pro

Toggle Group React component for Tailwind CSS v4

v1.0.0·Added in 1.0.0

A React toggle group: a row of toggles where one or several stay pressed, for formatting, alignment, view switches and filters.

Click or tap an item and it stays pressed. In single mode the highlight slides over to the new item on a smooth spring and the old one lets go; in multiple mode each item pops its own highlight in and out. Every item dips a little while your finger is down. The group is one tab stop: arrow keys move along it (wrapping around unless loop is off), Home and End jump to the ends, Space or Enter presses. Icon-only items name themselves in a tooltip on hover or keyboard focus, with the shortcut hint next to the name; on a phone a long press shows it without pressing the item. On touch the medium size is 44px tall and the small one keeps a 44px hit area.

Toggle Group is a Pro React component in the React button components category, written in TypeScript for React 19 and Tailwind CSS v4. It installs as source with npx wingo-ui@latest add toggle-group, together with Tooltip, Motion presets, Tones, useControllableState and UIProvider and the npm packages @radix-ui/react-toggle-group and motion.

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 toggle-group

Toggle Group 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 ToggleGroup from @/components/ui/toggle-group.

import { AlignCenter, AlignLeft, AlignRight, Bold, Italic, Underline } from "lucide-react"
import { ToggleGroup, ToggleGroupSeparator } from "@/components/ui/toggle-group"

export function EditorToolbar({ align, onAlignChange }: { align: string; onAlignChange: (value: string) => void }) {
  return (
    <div role="toolbar" aria-label="Editor" className="flex items-center gap-1">
      <ToggleGroup
        type="multiple"
        iconOnly
        defaultValue={["bold"]}
        aria-label="Formatting"
        options={[
          { value: "bold", label: "Bold", icon: <Bold />, shortcut: "mod+b" },
          { value: "italic", label: "Italic", icon: <Italic />, shortcut: "mod+i" },
          { value: "underline", label: "Underline", icon: <Underline />, shortcut: "mod+u" },
        ]}
      />
      <ToggleGroupSeparator />
      <ToggleGroup
        iconOnly
        value={align}
        onValueChange={onAlignChange}
        aria-label="Alignment"
        options={[
          { value: "left", label: "Left", icon: <AlignLeft /> },
          { value: "center", label: "Center", icon: <AlignCenter /> },
          { value: "right", label: "Right", icon: <AlignRight /> },
        ]}
      />
    </div>
  )
}

Props

  • typedefault "single"
    "single" | "multiple"

    single: one item stays pressed and the value is a string (an alignment, a view). multiple: any number stay pressed and the value is a string[] (bold, italic, filters).

  • options
    ToggleGroupOption[]

    { value: string; label: ReactNode; icon?: ReactNode; disabled?: boolean; tooltip?: ReactNode; shortcut?: string }. The shortcut is a hint shown in the tooltip and set as aria-keyshortcuts; bind it yourself with useShortcut. Values that disappear from the list are dropped from the value.

  • value
    string | string[]

    Controlled value, typed by type: a string for single (empty for none), a string[] for multiple.

  • defaultValue
    string | string[]

    Starting value while uncontrolled: "" or [] when omitted.

  • onValueChange
    (value: string | string[]) => void

    Fires with the new value, typed by type: a string for single ("" when cleared), a string[] for multiple.

  • deselectabledefault false
    boolean

    single only: clicking the pressed item clears the value. Off by default, since an alignment or a view always has one.

  • variantdefault "ghost"
    "ghost" | "outline" | "soft"

    ghost: transparent items for toolbars, pressed ones get the selected tint. outline: items joined into one bordered control with hairlines between them. soft: a tinted track where the pressed item becomes a solid fill.

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

    Height 32 / 40 / 48px with matching padding, type and icon size; icon-only items are square. On touch screens md grows to 44px and sm keeps a 44px hit area.

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

    Corner shape, scaled with the size like the button's. full turns the group into a pill.

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

    Color of the pressed items. neutral is the gray selected tint (a black or white fill on soft); the other tones tint the highlight and color the text.

  • colordefault ""
    string

    Any CSS color for the pressed items; replaces the tone. Leave empty to use the tone.

  • orientationdefault "horizontal"
    "horizontal" | "vertical"

    The direction of the row and of the arrow keys. Vertical items align their labels to the start.

  • iconOnlydefault false
    boolean

    Shows only the icons in square items. Each label becomes the item's aria-label and its tooltip (with the shortcut hint).

  • fullWidthdefault false
    boolean

    Items share the width of the container, the usual layout for a view switch on a phone.

  • attacheddefault true
    boolean

    outline only: items share their borders as one control. Off: they stand apart as separate chips with a gap; add flex-wrap through className to let them wrap.

  • loopdefault true
    boolean

    Arrow keys wrap from the last item to the first and back. Off: they stop at the ends.

  • disableddefault false
    boolean

    Dims the whole group and blocks it. A single option can be disabled through its disabled field.

  • aria-labeldefault ""
    string

    The group's name for screen readers, like Alignment. Needed when no visible label sits next to it.

  • classNames
    Partial<Record<"item" | "highlight" | "icon" | "label", string>>

    Extra classes for every item, the pressed highlight, the icon wrapper and the label wrapper.

  • className
    string

    Extra classes for the group itself, merged last.

Parts

  • ToggleGroupRoot

    component

    The group without options, for custom layouts: the same props as ToggleGroup minus options, with ToggleGroupItem and ToggleGroupSeparator children. Props: ToggleGroupRootProps<T>.

  • ToggleGroupItem

    component

    One item; children is the label. Takes every button prop too. Props: { value: string; icon?: ReactNode; tooltip?: ReactNode; shortcut?: string; disabled?: boolean; children?: ReactNode }.

  • ToggleGroupSeparator

    component

    A hairline between clusters inside a group or between two groups in a toolbar; it runs across the group's direction unless you set orientation. Props: { orientation?: "horizontal" | "vertical" }.

  • ToggleGroupOption

    type

    One item of options: value, label, icon, disabled, tooltip (hover, focus and long press) and shortcut (a mod+k hint shown in the tooltip and set as aria-keyshortcuts; bind it with useShortcut).

  • ToggleGroupValue

    type

    The value type: a string for type="single", a string[] for type="multiple".

Examples

Variants

ghost for toolbars, outline for one bordered control, soft for a track with a solid pressed fill.

View switch

Single, soft and full width, with icons and labels: the highlight slides as the view changes.

Quick filters

type="multiple" with attached={false}: outline chips that wrap, each popping its own highlight in and out.

Vertical tool palette

Parts with a separator; icon-only items show their name and shortcut in a tooltip on the right. With focus in the palette, the letter keys pick a tool.

Sizes and radii

32, 40 and 48px; the outline row runs from square corners to a pill.

Tones

Brand for the billing period, success for the channels that are on.

Dependencies

@radix-ui/react-toggle-groupmotiontooltipmotiontonesuse-controllable-stateui-config

Files

  • components/ui/toggle-group.tsx

FAQ

Is the React Toggle Group component free?

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

How do I install Toggle Group?

Run npx wingo-ui@latest add toggle-group. It also adds the Wingo UI items it builds on (Tooltip, Motion presets, Tones, useControllableState and UIProvider) and the npm packages @radix-ui/react-toggle-group and motion. With shadcn, add the @wingo-ui registry with your API key, then run npx shadcn@latest add @wingo-ui/toggle-group.

How does Toggle Group behave on phones?

Icon-only items name themselves in a tooltip on hover or keyboard focus, with the shortcut hint next to the name; on a phone a long press shows it without pressing the item.

See also

ToggleSegmented ControlTooltipTabs

Used in

Cron PickerImage GalleryAgency PageRestaurant PageTravel Page

More React button components

Delete ButtonButtonButton GroupCopy ButtonTheme Toggle
All 7 React button components

Articles using this component

  • React Segmented Control: iOS Thumb, Drag and When to Use It

    Mobile UI in React · Oct 9, 2026 · 8 min read

PreviousToggleNext Avatar Upload

Listing · New York

A 2-bedroom apartment by Central Park, renovated in 2025, fully furnished. Rent $2,400.00 a month, available from Oct 1, 2026.

value="left"One alignment always stays pressed. Arrow keys wrap around.