WingoUI
Buttons & Actions
ButtonButton GroupCopy ButtonDelete ButtonTheme ToggleToggleToggle Group
Inputs
Avatar UploadCalendarCheckboxColor PickerComboboxCron PickerCurrency InputDate PickerDate Range PickerDate Time PickerDuration PickerFile UploadFilter BuilderInputInput GroupListboxMasked InputMention InputMonth PickerMulti SelectNumber InputOTP InputPassword InputPhone InputRadio GroupRatingSearch InputSegmented ControlSelectSignature PadSliderSwitchTag InputTextareaTime Picker
Forms
Address InputCSV ImportFieldForm WizardInline EditInvoice line itemsRich Text Editor
Navigation
Back To TopBounce SidebarBreadcrumbCommand MenuGlobal SearchGooey NavHook SidebarNav MenuNav TabsPaginationProximity SidebarScroll ProgressSidebarStepsTable Of ContentsTabsTopbarUser MenuWorkspace Switcher
Overlays
Alert DialogContext MenuDialogDrawerDropdown MenuFamily DrawerHover CardPopoverSheetShortcuts DialogTooltipTour
Feedback
AlertBannerCookie ConsentEmoji ReactionEmpty StateNotification BellNotification CenterProgressRoute ProgressSkeletonSpinnerToast
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 chartRadial barSparklineStat CardTrackerTrend badge
Layout
AccordionApp ShellCardCollapsibleDetail LayoutEntity HeaderPage HeaderScroll AreaSeparatorSettings LayoutSplit ViewToolbar
Media
Audio PlayerCarouselImage CropperImage LightboxLocation MapQR CodeStep PlayerVideo Player
AI Kit
Agent Status CardChat MessageChat ThreadConversation ListFluid OrbGrid RevealMatrix OrbModel PickerPrompt InputReasoning IndicatorRule BuilderSuggestion ChipsTool Call TimelineUsage MeterVoice InputWorkflow Canvas
Text & Effects
Gravity Letters
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
Blocks
Admin Dashboard PageAdmin ShellAI Chat PageAutomation Builder PageCheckout PageCRM Contact PageCRM Pipeline PageError PagesInbox PageInvoice PageKPI DashboardListing Detail PageLogin PageMarketplace Home PageMarketplace Search PageMarketplace ShellMobile App HomeOnboarding FlowPost Listing WizardPricing PageRegister PageSettings PageUsers Admin Page
Hooks & Utilities
AI ChatChart kitCommerceDate utilsFile exportFile typesFiltersForm validationHapticsInvoicingMotion presetsNavigationNumber formatRelative timeRomanian locationsSpreadsheetText matchTonesUIProvideruseClipboarduseConsentuseControllableStateuseCooldownuseDebounceuseKeyboardInsetuseLocaleuseLongPressuseMediaControlsuseMediaQueryuseOverflowItemsusePersistedStateuseScrollEdgesuseScrollStateuseSelectionuseShortcutuseStickToBottom
GalleryThemeCredits

Commerce

Quantity stepper

CommerceQuantity stepper
Product galleryReviews
Live props
State
defaultValue1
loading
disabled
Behavior
min
max
step
stockNot tracked
lowStockThreshold5
removable
addToCart
editable
holdToRepeat
haptics
Content
suffix
locale
aria-label
Appearance
size
variant
radius
tone
color
Code
import { QuantityStepper } from "@/components/ui/quantity-stepper"

<QuantityStepper />
Pro

v1.0.0·Added in 1.0.0

The minus, value, plus control of carts and product pages, with stock hints, hold to repeat, rolling digits and an Add to cart morph.

Tap or click minus and plus to change the quantity; the new number rolls in from below when it grows and from above when it shrinks. Hold a button and it repeats after 400ms, speeding up, and stops at the limit; on a phone a finger that starts to scroll never changes the value. Pressing past a limit shakes the control (and buzzes on a phone), and at the maximum a line under it says why. With removable, minus turns into a trash button at the minimum; with addToCart the control starts as an Add to cart button that morphs into the stepper and collapses back from the first step. Keyboard: Tab reaches the value (one stop), Up and Down step, Page Up and Page Down move 10 steps, Home and End jump to the minimum and maximum, Delete removes the line at the minimum when removable. With editable, type a number and press Enter or leave the field (Escape drops what was typed); it is snapped to the step and clamped, and pressing plus or minus right after typing steps from the typed number. While the cart syncs a spinner replaces the digits, and a failed save rolls back with a message.

Add to a project

npx wingo-ui@latest add quantity-stepper

Pro item: the CLI needs a Pro account. See plans

Dependencies

motionlucide-reactbuttonspinneruse-controllable-stateuse-localehapticsmotionnumber-formattonesui-config

Files

  • components/ui/quantity-stepper.tsx

See also

Number InputButtonPriceHapticslib
PreviousProduct galleryNext Reviews
Your cart
iPhone 14 case, silicone, Midnight$29.90
1
$29.90012345678901234567890012345678901234567890.012345678901234567890012345678901234567890
value=1 · last none yetmin=1 max=99 step=1 lowStockThreshold=5holdToRepeat=true haptics=true tone=neutral color=none

Hold + to repeat; press past a limit to feel it stop