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

Feedback

Progress

Feedback

Progress React component for Tailwind CSS v4

Notification CenterRoute Progress
Live props
State
value64
max
bufferNone
Appearance
variant
segments5
size
tone
color
radius
striped
thicknessBy size
Content
label
description
showValue
valueFormat
Layout
labelPosition
Behavior
animated
locale
Code
import { Progress } from "@/components/ui/progress"

<Progress />
  1. Home
  2. Components
  3. Feedback
  4. Progress
Free

Progress React component for Tailwind CSS v4

v1.0.0·Added in 1.0.0

A React progress bar, stepped bar or ring for uploads and quotas, determinate or indeterminate, with a label, value, tones and thresholds.

It is read, not operated: it never takes focus. Every value change glides on a spring from where the bar was, with no re-render per frame; the first paint already shows the final value. Without a value the bar slides endlessly (the ring spins), and a value arriving later glides on from there. With thresholds a quota bar turns amber, then red, as it fills. Screen readers hear a progressbar named by the label, described by the description, with the value as a percent. Under reduced motion values jump, stripes stop and the indeterminate bar pulses in place. In the playground, press Simulate to run an import from 0 to 100% in uneven steps. The same markup works on a phone; the header wraps under 240px.

Progress is a free React component in the React feedback components category, written in TypeScript for React 19 and Tailwind CSS v4. It installs as source with npx wingo-ui@latest add progress, together with useLocale, Motion presets, Number format, Tones and UIProvider and the npm packages @radix-ui/react-progress 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 progress

Usage

Import Progress from @/components/ui/progress.

import { Progress, ProgressRing } from "@/components/ui/progress"

export function ClientImport({ done, total }: { done: number; total: number }) {
  return (
    <div className="flex flex-col gap-4">
      <Progress
        label="Importing clients"
        description={`${done} of ${total} rows`}
        value={done}
        max={total}
        showValue
      />
      <Progress
        label="Storage"
        value={7.2}
        max={10}
        thresholds={{ warning: 80, danger: 95 }}
        showValue
        formatValue={(value, max) => `${value} GB of ${max} GB`}
      />
      <ProgressRing value={68} tone="brand" showValue aria-label="Monthly goal" />
    </div>
  )
}

Props

  • valuedefault 64
    number | null

    The current value, from 0 to max. Omit it (or pass null, NaN) for the indeterminate state: a sliding bar or a spinning arc. Values outside 0..max are clamped for drawing. The playground starts at a sample 64; the component's default is null.

  • maxdefault 100
    number

    The value that means done. 0 or less renders the indeterminate state.

  • variantdefault "linear"
    "linear" | "segmented" | "ring"

    linear: one bar. segmented: equal steps (onboarding, password strength, stories); a fractional value fills a segment partly. ring: a circle for KPIs and compact rows.

  • segmentsdefault 5
    number

    Segmented only: how many equal steps. 2,5 of 5 shows two full segments and one half.

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

    Linear track 2 / 4 / 6 / 8px (xs is the hairline for a refreshing list); ring 24 / 32 / 48 / 64px with a 3 / 3 / 4 / 6px stroke. The xs ring shows its value beside it.

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

    The fill color. The track stays a neutral tint. A finished upload does not turn green on its own: pass success when it should.

  • colordefault ""
    string

    Any CSS color for the fill; replaces the tone. Empty uses the tone.

  • radiusdefault "full"
    "none" | "sm" | "full"

    Ends of the linear and segmented bars: square, 2px or a pill.

  • labeldefault ""
    ReactNode

    Above the bar, or beside the ring with labelPosition side. Names the progressbar for screen readers (else pass aria-label).

  • descriptiondefault ""
    ReactNode

    Under the bar in small muted text, e.g. "2.4 MB of 12 MB". Linked with aria-describedby.

  • showValuedefault false
    boolean

    Shows the formatted value at the end of the header row (linear) or in the center of the ring.

  • valueFormatdefault "percent"
    "percent" | "fraction" | "value"

    How the value reads: "64%", "32 / 50" or "32", in the locale ("64 %" in de-DE).

  • labelPositiondefault "top"
    "top" | "side"

    Ring only: top stacks label, ring and description; side puts the text to the right of the ring (KPI rows).

  • stripeddefault false
    boolean

    Linear only: moving diagonal stripes on the fill while it is below max. They stop under reduced motion.

  • animateddefault true
    boolean

    Value changes glide on a spring. Off, the bar jumps straight to the new value.

  • localedefault ""
    string

    Intl locale for the value. Empty uses the UIProvider locale, then the page language.

  • thresholds
    { warning?: number; danger?: number }

    Quotas: at or above warning % the fill turns warning, at danger % danger. Compares percentages, not raw values. Wins over tone and color.

  • bufferdefault 0
    number

    Linear only: a lighter second bar behind the fill, in the same units as value (media buffering, uploaded vs processed). Glides on the same spring. Omitted (0 in the playground) draws none.

  • thicknessdefault 0
    number

    Ring only: the stroke width in px. 0 uses 3 / 3 / 4 / 6px by size.

  • formatValue
    (value: number, max: number) => ReactNode

    Replaces valueFormat, e.g. "7.2 GB of 10 GB".

  • getValueLabel
    (value: number, max: number) => string

    The aria-valuetext. Defaults to the percent in the locale.

  • children
    ReactNode

    Ring only: replaces the centered value (an icon, a figure in your own style).

  • classNames
    Partial<Record<"header" | "label" | "value" | "track" | "indicator" | "segment" | "ring" | "description", string>>

    Extra classes for the inner parts.

  • className
    string

    Extra classes for the root, merged last. Other props (aria-label, aria-labelledby, aria-describedby) reach the progressbar.

Parts

  • ProgressRing

    component

    The bare ring for other components (a stat card, an avatar, a file row). Same value props as Progress, children in the center (centered text shrinks to fit) and its own global defaults under progress-ring. Pass it an aria-label.

    • valuedefault "null"
      number | null

      The current value; null spins the ring as indeterminate.

    • maxdefault 100
      number

      The value that fills the ring.

    • sizedefault "md"
      "xs" | "sm" | "md" | "lg" | number

      24 / 32 / 48 / 64px, or any px number.

    • thickness
      number

      Stroke width in px; 3 / 3 / 4 / 6px by size when left out.

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

      The ring color from the design tokens.

    • color
      string

      Any CSS color; replaces the tone.

    • showValuedefault false
      boolean

      Prints the formatted value in the center.

    • valueFormatdefault "percent"
      "percent" | "fraction" | "value"

      How the centered value reads: "68%", "34 / 50" or "34".

    • animateddefault true
      boolean

      Value changes glide on a spring; false jumps.

    • classNames
      Partial<Record<"ring" | "content", string>>

      Extra classes for the svg ring and the centered content.

Examples

Upload rows

Small bars with the size in MB, a finished file in success and one still processing.

Storage quota

Thresholds at 80% and 95% turn the bar amber, then red. Drag the slider.

Rings as KPIs

labelPosition side puts the label and the description next to the ring.

Segmented onboarding

Four steps with a fraction value; each step glides into the next. Try Back and Continue.

Indeterminate

No value: a sliding bar, a spinning arc and an xs hairline on top of a refreshing card.

Sizes, tones, stripes

xs to lg, every tone, a custom color, stripes with a buffer and rings with an icon.

Dependencies

@radix-ui/react-progressmotionuse-localemotionnumber-formattonesui-config

Files

  • components/ui/progress.tsx

FAQ

Is the React Progress component free?

Yes. The source is free and needs no account: copy it from the Code tab or install it with the CLI.

How do I install Progress?

Run npx wingo-ui@latest add progress. It also adds the Wingo UI items it builds on (useLocale, Motion presets, Number format, Tones and UIProvider) and the npm packages @radix-ui/react-progress and motion. With shadcn, run npx shadcn@latest add https://wingo-ui.com/r/progress.json.

How does Progress behave on phones?

The same markup works on a phone; the header wraps under 240px.

See also

SpinnerRoute ProgressScroll ProgressFile UploadStepsSkeleton

Used in

Avatar UploadOnboarding FlowFile managerStat CardCart drawerData TableDeal PipelineReviewsCSV ImportTourSetup ChecklistCalendar View

and 13 more.

More React feedback components

BannerCookie ConsentEmpty StateNotification BellNotification CenterEmoji Reaction
All 13 React feedback components

Articles using this component

  • Onboarding Checklist UI: The Get Started Card in React

    Build it: screens and apps · Nov 6, 2026 · 9 min read

PreviousNotification CenterNext Route Progress

Import clients from CSV

acme-clients-2026.csv · 1,240 rows

Importing clients
794 of 1,240 rows
value=64

Press Simulate to watch every step glide on a spring