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

Charts & Stats

Bar chart

Charts & Stats

Bar chart React component for Tailwind CSS v4

Area chartDonut chart
Live props
Layout
height240px
orientation
showGrid
showXAxis
showYAxis
yAxisSide
showLegend
legendPosition
Appearance
type
radius
barSize24px
barGap2px
categoryGap0.3
showValues
highlightLast
surface
Content
valueFormat
currency
locale
label
description
Behavior
legendToggle
showTooltip
tooltipMode
animated
State
loading
Code
import { BarChart } from "@/components/ui/bar-chart"

<BarChart />
  1. Home
  2. Components
  3. Charts & Stats
  4. Bar chart
Pro

Bar chart React component for Tailwind CSS v4

v1.0.0·Added in 1.0.0

Compares categories or periods as columns or horizontal bars, grouped, stacked or 100%, with negatives below a clear zero line.

The bars grow out of the zero line the first time the chart scrolls into view, one category a beat after the other; value labels fade in after their bar. Move the mouse over the plot and the whole column (or row, when horizontal) under it lights up with a soft band while a readout lists every visible series in it (stacked charts add a total, 100% charts add each share). On a phone, tap a column to pin the readout above the plot, drag sideways to scrub (a vertical drag still scrolls the page), tap it again or anywhere outside to clear it. With the keyboard, Tab to the plot: Left / Right walk the categories (Up / Down for horizontal bars), Home / End jump to the ends, PageUp / PageDown move by ten, Enter fires onDatumClick for the first visible series and Escape clears; a live region reads each category. Click or tap a legend entry to hide its series (the rest regroup and the axis rescales with a glide), hover or focus one to highlight it. Switching between grouped, stacked and 100% glides every bar to its new place.

Bar chart is a Pro React component in the React chart and stat components category, written in TypeScript for React 19 and Tailwind CSS v4. It installs as source with npx wingo-ui@latest add bar-chart, together with Chart kit, Motion presets, UIProvider and useLocale and the npm package 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 bar-chart

Bar chart 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 BarChart from @/components/ui/bar-chart.

import { BarChart } from "@/components/ui/bar-chart"

const data = [
  { month: "2026-07", collected: 106300, expenses: 72400 },
  { month: "2026-08", collected: 97500, expenses: 69900 },
  { month: "2026-09", collected: 128450, expenses: 81200 },
]

export function MonthlyCollections() {
  return (
    <BarChart
      data={data}
      xKey="month"
      series={[
        { key: "collected", label: "Collected" },
        { key: "expenses", label: "Expenses" },
      ]}
      valueFormat="currency"
      currency="USD"
      label="Collected vs. expenses per month"
    />
  )
}

Props

  • data*
    ChartDatum[]

    One row per category, in drawing order: { month: "2026-09", collected: 128450, expenses: 81200 }. Negative values grow down (or left) from zero.

  • xKeydefault "date"
    string

    The row key for the categories. ISO days ("2026-09-24") and months ("2026-09") print as local dates; other strings print as they are.

  • series
    BarChartSeries[]

    Which keys to draw, in color and stack order: { key, label?, color?, name? }. Inferred from the numeric keys of the first rows when omitted.

  • colors
    string[]

    Per-position palette overrides: a slot ("series-3"), a tone ("neutral", "success") or any CSS color.

  • heightdefault 240
    number

    Plot height in px, reserved before the chart measures so nothing jumps.

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

    horizontal puts the categories in a label column on the left (at most 40% of the width, long names end in an ellipsis; the tooltip and table keep the full text). The better choice on phones with long names.

  • typedefault "grouped"
    "grouped" | "stacked" | "percent"

    grouped sets the series side by side, stacked piles them (negatives below zero), percent piles their shares to 100%.

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

    Corner radius of the data end: 0 / 2 / 4 / 6px or half the thickness. The base stays square; stacks round only their outermost segment.

  • barSizedefault 24
    number

    Maximum bar thickness in px. Bars shrink to fit narrow plots instead of overlapping.

  • barGapdefault 2
    number

    Px between the bars of one group and between stacked segments, painted in the surface color.

  • categoryGapdefault 0.3
    number

    The share of each category's band left empty between groups.

  • showValuesdefault false
    boolean

    A value at each bar's tip (grouped), the total at each stack's end (stacked) or the share inside each segment (percent). Every label uses one form: full amounts when they all fit, else the compact form; when they still collide every k-th category is labelled, counted back from the newest. A label with no room goes inside its bar or is skipped, never clipped; bars thinner than 14px carry none.

  • getBarColor
    (datum: ChartDatum, series: ResolvedChartSeries, index: number) => (string | undefined)

    A color per bar (a slot, a tone or any CSS color): "danger" for negatives, "brand" for the current month. undefined keeps the series color.

  • highlightLastdefault false
    boolean

    Dims every category but the last to 45%, for the current-period look. The inspected category lights up too.

  • valueFormatdefault "number"
    ChartValueFormat = "number" | "compact" | "currency" | "percent"

    How values print in the tooltip, ticks, value labels and table. Percent takes whole numbers (12.4 -> "12,4 %").

  • currencydefault "USD"
    string

    ISO 4217 code for valueFormat currency, printed with the narrow symbol ("$128,450").

  • decimals
    number

    Fraction digits in the tooltip, labels and table; auto by magnitude when unset. Ticks stay short.

  • formatValue
    (value: number, context: { series: string; kind: "tooltip" | "tick" | "label" | "table" }) => string

    Replaces the built-in value formatting everywhere.

  • formatX
    (value: unknown, context: "axis" | "tooltip" | "table") => string

    Replaces the category label formatting (short on the axis, long in the tooltip and table).

  • localedefault ""
    string

    Locale for numbers and dates. Empty uses the UIProvider / LocaleProvider locale.

  • yDomaindefault "["auto", "auto"]"
    BarChartDomain = [number | "auto", number | "auto"]

    Fixed value bounds; zero is always included. Ignored by percent (always 0 to 100%).

  • showGriddefault true
    boolean

    Hairlines at the value ticks (horizontal lines, or vertical ones for horizontal bars).

  • showXAxisdefault true
    boolean

    The labels under the plot: categories (thinned so they never collide), or value ticks for horizontal bars.

  • showYAxisdefault true
    boolean

    The labels beside the plot: compact value ticks ("$128K"), or the category column for horizontal bars.

  • yAxisSidedefault "start"
    "start" | "end"

    end puts the value ticks on the right, finance style (vertical bars; horizontal bars keep categories on the left).

  • showLegenddefault true
    boolean

    The legend; it only renders with two or more series (one series is named by the card title).

  • legendPositiondefault "top"
    "top" | "bottom"

    Legend above or below the plot.

  • legendToggledefault true
    boolean

    Legend entries are buttons that hide and show their series. The last visible series cannot be hidden.

  • showTooltipdefault true
    boolean

    The floating readout. When off, the band, keyboard and screen reader announcements still work.

  • tooltipModedefault "auto"
    "auto" | "float" | "fixed"

    float rides beside the inspected bars, fixed pins above the plot (never under a finger); auto is fixed on touch screens.

  • referenceLines
    { value: number; label?: string; color?: string }[]

    Dashed target or average lines with a label ("Target $120,000"); always inside the value range.

  • animateddefault true
    boolean

    Bars grow on first view and glide on data, type and legend changes. Reduced motion always shows the final state.

  • loadingdefault false
    boolean

    A bar-shaped skeleton in the plot's box.

  • emptyState
    ReactNode

    Replaces the built-in empty state (shown when data is empty or every value is null).

  • labeldefault ""
    string

    Accessible name of the figure and caption of its data table. Empty joins the series names.

  • descriptiondefault ""
    string

    A one-sentence takeaway for screen readers ("September brought the highest collections of the year").

  • surfacedefault ""
    string

    The color behind the chart, used for label halos. Empty uses the surface token; set it when the chart sits on a card.

  • hiddenSeries
    string[]

    Hidden series keys when you control legend toggling; pair with onHiddenSeriesChange.

  • defaultHiddenSeries
    string[]

    Series keys hidden at first, when the legend toggles on its own.

  • onHiddenSeriesChange
    (keys: string[]) => void

    Called when a legend entry hides or shows a series.

  • activeIndex
    number | null

    The inspected category index when you control it, so two charts can share one highlight.

  • defaultActiveIndex
    number | null

    The category inspected at first (a pinned readout), uncontrolled.

  • onActiveIndexChange
    (index: number | null) => void

    Called as the highlighted category changes (mouse, touch or keyboard) and with null when it clears.

  • onDatumClick
    (event: { index: number; datum: ChartDatum; series?: string }) => void

    A click or tap on a category (series is the bar under the pointer, else the first visible series) or Enter on the inspected one.

  • labels
    Partial<BarChartLabels>

    Strings: empty, loading, table, total, inspectHint, inspectHintVertical, showSeries, hideSeries, category (Category, the table's first column).

  • classNames
    Partial<Record<BarChartSlot, string>>

    Classes for legend, plot, tooltip, table, grid, xAxis, yAxis, bar, band, value, category, referenceLine and inspect.

Parts

  • DEFAULT_BAR_CHART_LABELS

    constant

    The English strings the chart uses (empty and loading text, the data table and its Category column, the keyboard hints for both orientations, show and hide series). Spread it and override what you translate.

  • BarChartLabels

    type

    The shape of labels: the chart kit's shared strings plus category and inspectHintVertical.

  • BarChartSeries

    type

    One bar key: { key, label?, color?, name? }, in color and stack order.

Examples

Negative values

Cash-flow variation: bars grow down from zero, getBarColor paints them by sign.

Horizontal, long names

Categories in a label column with compact value labels at the tips.

Stacked with totals

Invoices by status per month, the total above each stack.

Current period

highlightLast on 12 weeks of orders in the neutral ink.

100% stacked

Channel shares per quarter with the share inside each segment.

Loading and empty

The skeleton and the empty state in the plot's box.

Phone, 360px

Horizontal bars with the pinned touch readout.

Dependencies

motionchart-kitmotionui-configuse-locale

Files

  • components/ui/bar-chart.tsx

FAQ

Is the React Bar chart component free?

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

How do I install Bar chart?

Run npx wingo-ui@latest add bar-chart. It also adds the Wingo UI items it builds on (Chart kit, Motion presets, UIProvider and useLocale) and the npm package motion. With shadcn, add the @wingo-ui registry with your API key, then run npx shadcn@latest add @wingo-ui/bar-chart.

How does Bar chart behave on phones?

On a phone, tap a column to pin the readout above the plot, drag sideways to scrub (a vertical drag still scrolls the page), tap it again or anywhere outside to clear it.

See also

Chart kitlibLine chartArea chartFunnel chartDonut chart

Used in

KPI Dashboard

More React chart and stat components

Radar chartTrend badgeGaugeGitHub ActivityAnimated CounterRadial bar
All 16 React chart and stat components

Articles using this component

  • React Funnel Chart: Conversion, Drop-off and Cohorts

    Component guides · Nov 6, 2026 · 9 min read

  • React Charts Tailwind: 4 Charts and a Kit for Any Theme

    Component guides · Oct 19, 2026 · 10 min read

PreviousArea chartNext Donut chart

Collected vs. expenses per month

Summit CRM, January – September 2026, in dollars

Collected, Expenses
CategoryCollectedExpenses
January 202684,20061,300
February 202691,80064,900
March 202688,40070,100
April 2026102,60068,800
May 2026110,90074,200
June 202698,70079,600
July 2026106,30072,400
August 202697,50069,900
September 2026128,45081,200

tooltip: auto · legend toggle: on · grow-in: on · clicked: none