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

Inputs

Slider

Inputs

Slider React component for Tailwind CSS v4

Signature PadSwitch
Live props
Field
label
description
error
required
invalid
disabled
readOnly
name
Behavior
min
max
step
minStepsBetweenThumbs0
Appearance
size
tone
color
marks
showMarkLabels
showValue
showValueLabel
Layout
orientation
inverted
Content
locale
prefix
suffix
Code
import { Slider } from "@/components/ui/slider"

<Slider />
  1. Home
  2. Components
  3. Inputs
  4. Slider
Pro

Slider React component for Tailwind CSS v4

v1.0.0·Added in 1.0.0

A React slider for a number or a range: any number of thumbs, labelled marks, a value bubble, vertical mode, tones and finger-sized thumbs.

Drag a thumb or tap anywhere on the track to jump there; the thumb grows a little under the finger and a bubble with the formatted value rides above it, never under the finger. With a mouse the thumb shows a soft halo and its bubble on hover. Tab to a thumb for a focus ring and the bubble, then use the arrow keys for one step, Shift+arrow or PageUp / PageDown for ten, and Home / End for the ends; a range has one tab stop per thumb and they never cross. Tap a mark's label (New, Like new, 25 km) to send the nearest thumb there. On a phone each thumb has a 44px target, the whole row answers to a tap, and a sideways drag never scrolls the page. The playground filter counts the matching listings live and Reset puts both sliders back.

Slider is a Pro React component in the React input components category, written in TypeScript for React 19 and Tailwind CSS v4. It installs as source with npx wingo-ui@latest add slider, together with UIProvider, Field, useControllableState, useLocale, Motion presets and 2 more and the npm packages @radix-ui/react-slider 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 slider

Slider 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 Slider from @/components/ui/slider.

import { useState } from "react"
import { Slider } from "@/components/ui/slider"

const usd = { style: "currency", currency: "USD", maximumFractionDigits: 0 } as const

export function PriceFilter({ onApply }: { onApply: (range: number[]) => void }) {
  const [price, setPrice] = useState([500, 2000])
  return (
    <div className="flex flex-col gap-6">
      <Slider
        label="Price"
        value={price}
        onValueChange={setPrice}
        onValueCommit={onApply}
        min={0}
        max={5000}
        step={50}
        minStepsBetweenThumbs={2}
        locale="en-US"
        format={usd}
        showValueLabel
      />
      <Slider
        label="Search radius"
        defaultValue={[25]}
        min={5}
        max={100}
        step={5}
        suffix="km"
        marks={[5, 25, 50, 75, 100].map((value) => ({ value, label: `${value} km` }))}
        showValueLabel
      />
    </div>
  )
}

Props

  • labeldefault ""
    ReactNode

    The field label. One thumb is labelled by it directly (a click on it focuses the thumb); two or more thumbs are named as a group by it and each thumb gets its own name from thumbLabels.

  • descriptiondefault ""
    ReactNode

    Helper text under the slider, linked to every thumb with aria-describedby. The error takes its place while it shows.

  • errordefault ""
    ReactNode

    Replaces the description with the animated error, turns the range red and sets aria-invalid on the thumbs.

  • requireddefault false
    boolean

    The required mark after the label. A slider always holds a value, so it only marks the field.

  • invaliddefault false
    boolean

    The red range and aria-invalid without a message, for forms that show the error elsewhere.

  • disableddefault false
    boolean

    Dims to 50%, takes the thumbs out of the tab order and ignores every drag and tap. A disabled FieldGroup disables it too.

  • readOnlydefault false
    boolean

    Shows the value and keeps the thumbs focusable (so the value can be read), but ignores drags, taps and keys.

  • mindefault 0
    number

    The lowest value. The playground shows its dollar sample (0 to 5,000, step 50) while min, max and step are all at their defaults.

  • maxdefault 100
    number

    The highest value. A max at or below min falls back to min + step.

  • stepdefault 1
    number

    The distance between values, for drags and arrow keys. A step that does not divide the range still reaches max: a drag past the middle of the last gap lands on it.

  • minStepsBetweenThumbsdefault 0
    number

    How many steps a range keeps between its thumbs. The playground names the gap under the slider.

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

    Track 4 / 6 / 8px, thumb 16 / 20 / 24px, and the value label's type. Every thumb gets a 44px hit area on touch screens.

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

    The range fill and the hover halo. neutral is black in light mode and white in dark mode.

  • colordefault ""
    string

    Any CSS color for the range; replaces the tone. Marks inside the range pick a readable dot color on their own.

  • marksdefault false
    boolean | number[] | SliderMark[]

    Dots on the track. true puts one on every step when there are 20 steps or fewer, else five evenly spaced; number[] places them; SliderMark[] ({ value, label }) adds a label under each. Marks outside min..max are ignored.

  • showMarkLabelsdefault false
    boolean

    Writes the formatted value under every mark that has no label of its own. The label under a thumb's value turns to the text color.

  • showValuedefault "auto"
    "auto" | "always" | "never"

    The value bubble above each thumb (beside it when vertical). auto shows it while dragging, on hover and on keyboard focus; always keeps it up and, under a label, makes room for it so it never covers the label row.

  • showValueLabeldefault false
    boolean

    The formatted value at the end of the label row: "$1,250", or both ends of a range joined by an en dash, with a shared unit written once after the second number. Without a label it gets a row of its own.

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

    vertical stands 180px tall with the mark labels beside the track and the bubble to the side. Size it with classNames.box.

  • inverteddefault false
    boolean

    Fills from the other end: right to left, or top to bottom when vertical. Arrow keys follow.

  • localedefault ""
    string

    Locale for every number shown (any BCP 47 tag). Empty uses the nearest LocaleProvider, then the page's language (en-US on the server). The demo passes en-US while it is empty.

  • prefixdefault ""
    string

    A simple unit before the number when there is no format: "~", "$". Letters get a space ("USD 50"), symbols do not ("$50"). The demo drops its dollar format while one is set.

  • suffixdefault ""
    string

    A simple unit after the number when there is no format: "km", "%", "m²". Letters get a non-breaking space ("50 km"), symbols do not ("50%").

  • format
    Intl.NumberFormatOptions

    Intl options for the bubble, the value label and the mark labels. Dollars: { style: "currency", currency: "USD", maximumFractionDigits: 0 }. Without it numbers keep the step's decimals.

  • formatValue
    (value: number) => ReactNode

    Replaces the formatted number everywhere it shows, e.g. a word per step (New, Like new, Good, Worn). A string result is also what screen readers hear.

  • formatValueLabel
    (values: number[]) => ReactNode

    Replaces the whole value label, e.g. "Any" when the range covers everything.

  • thumbLabels
    string[]

    Each thumb's aria-label. Two thumbs default to "Minimum" and "Maximum", one thumb to the field label (or aria-label), three or more to "Value 1 of 3"…

  • value
    number[]

    The controlled values, one per thumb. A value outside min..max is drawn at the edge and never corrected behind your back.

  • defaultValue
    number[]

    The uncontrolled start, clamped into the range once. Defaults to the middle of min..max ([50] for 0..100). Two numbers make a range.

  • onValueChange
    (value: number[]) => void

    Every change while dragging, tapping or pressing keys.

  • onValueCommit
    (value: number[]) => void

    When a drag, a tap or a key press ends: the moment to fetch results or save.

  • namedefault ""
    string

    Form field name. Inside a <form> each thumb submits a hidden input (name[] for ranges), and a form reset puts the thumbs back.

  • id
    string

    The thumb's id (the group's for ranges). Defaults to useId(); the label points at it.

  • fieldProps
    Partial<FieldProps>

    Anything else for the Field wrapper: optional, labelAction, orientation, labelWidth, hideLabel.

  • classNames
    Partial<Record<"box" | "root" | "track" | "range" | "thumb" | "mark" | "markLabel" | "value" | "valueLabel" | "field" | "label" | "description" | "error", string>>

    Extra classes for the inner parts: box (the slider and its mark labels; size a vertical slider here), the radix root, track, range, thumbs, mark dots and labels, the bubble, the value label and the field parts.

  • className
    string

    Classes for the outermost element: the Field root when the slider has a label, description or error, else the slider's box.

Examples

Value always on

showValue="always" keeps the bubble up, like a volume control. The icons jump to the ends.

Range with a minimum gap

minStepsBetweenThumbs keeps the two ends apart; the shared unit is written once in the value label.

Labelled scale

SliderMark labels under the track and formatValue for the bubble. Tap a word to jump there.

Vertical

orientation="vertical" with mark labels beside the track, driving a picture of the block.

Sizes, tones and a custom color

Track 4 / 6 / 8px and thumb 16 / 20 / 24px; any tone or CSS color for the range, marks adapt.

Two locales

The same range through Intl: 500 – 2.000 lei in ro-RO next to $500 – $2,000 in en-US.

Invalid

The range turns red and the error slides in; drag the ends apart and it slides away.

Price histogram

A bare range under a histogram that shares its tone, the classic marketplace price filter.

Dependencies

@radix-ui/react-slidermotionui-configfielduse-controllable-stateuse-localemotionnumber-formattones

Files

  • components/ui/slider.tsx

FAQ

Is the React Slider component free?

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

How do I install Slider?

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

How does Slider behave on phones?

On a phone each thumb has a 44px target, the whole row answers to a tap, and a sideways drag never scrolls the page.

See also

FieldNumber formatlibuseLocalehookToneslib

Used in

Video PlayerImage CropperLocation MapAudio PlayerFilter panelGanttPrice rangeAccessibility PageAffiliate PageAI Product PageCompare PageExperts Page

and 6 more.

More React input components

SwitchMasked InputSegmented ControlDate Range PickerCheckboxCombobox
All 40 React input components

Articles using this component

  • Tailwind Touch Manipulation: touch-action for Every Control

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

PreviousSignature PadNext Switch

Filters

Bikes · New York

Price
Min$500
Max$2,000
25 km
5 km25 km50 km75 km100 km