Join our Discord Community

React Counter Button

React counter button with animated number display and increment/decrement controls. Framer Motion creates sliding number transitions with TypeScript and shadcn/ui.

Building numeric input interactions?

Join our Discord community for help from other developers.


Counter inputs are everywhere—quantity selectors, settings panels, form controls. But most are just basic input fields with boring +/- buttons. Static. Lifeless. No visual feedback. Meanwhile, users expect smooth animations and satisfying interactions that make adjusting numbers feel engaging. This React component gives you animated counters with smooth digit transitions, spring physics, and tactile button feedback that make every increment delightful.

Loading component...

Built for React applications with TypeScript and Next.js. Uses Framer Motion for physics-based animations and the SlidingNumber component for smooth digit transitions. The numbers don't just change—they slide with momentum and bounce. Button interactions provide tactile feedback with scale animations. Perfect for shadcn/ui design systems with consistent styling patterns.

Why most counters feel mechanical

Developers just increment a number and update the display. Maybe they add a basic hover state if they're feeling generous. The problem? Users lose visual context during the transition. Numbers just snap to new values without any sense of motion or direction. The buttons feel disconnected from the action they trigger. It's functional but not engaging.

This component uses animated digit sliding that shows direction and momentum. The spring animations follow natural physics, creating anticipation and satisfaction. Button interactions provide immediate visual feedback before the number even changes. The layout automatically adjusts to accommodate different digit counts with smooth transitions.

The controlled state pattern means you get full control over value validation, limits, and step increments while the component handles all the complex animation orchestration automatically.

Installation

npx shadcn@latest add https://www.shadcn.io/registry/counter.json
npx shadcn@latest add https://www.shadcn.io/registry/counter.json
pnpm dlx shadcn@latest add https://www.shadcn.io/registry/counter.json
bunx shadcn@latest add https://www.shadcn.io/registry/counter.json

Examples

Style Variations

Different sizes and styling options for various UI contexts:

Loading component...

Value Ranges

Counters with different constraints and increment behaviors:

Loading component...

Features

  • Animated digit transitions using SlidingNumber component for smooth value changes
  • Spring physics buttons with hover and tap animations using Framer Motion
  • Layout animations automatically resizing container for different digit counts
  • Controlled state pattern for external validation, limits, and step increments
  • Customizable styling with flexible button and number display configuration
  • TypeScript definitions with complete interface definitions and prop validation
  • shadcn/ui integration using Button components and consistent design tokens
  • Accessibility support with proper button semantics and keyboard navigation
  • Performance optimized with hardware-accelerated animations and efficient renders

Use Cases

This free open source React component works perfectly for:

  • E-commerce quantity - Product quantity selectors built with Next.js
  • Settings panels - Numeric configuration options using TypeScript
  • Form steppers - Numeric input controls with validation and limits
  • Gaming interfaces - Score counters and statistics with animated updates
  • Dashboard controls - Interactive numeric widgets with smooth feedback
  • Booking interfaces - Guest count, room selectors with visual clarity
  • Shopping carts - Item quantity adjustment with immediate feedback
  • Pagination controls - Page number selection with smooth transitions

API Reference

Counter

The main component for animated numeric input with increment/decrement buttons.

PropTypeDefaultDescription
numbernumberrequiredCurrent counter value to display
setNumber(number: number) => voidrequiredFunction to update the counter value
slidingNumberPropsOmit<SlidingNumberProps, 'number'>-Props passed to the SlidingNumber component
buttonPropsOmit<React.ComponentProps<typeof Button>, 'onClick'>-Props passed to both increment and decrement buttons
transitionTransition{type: 'spring', bounce: 0, stiffness: 300, damping: 30}Motion transition for layout animations
minnumber-Minimum allowed value (external validation)
maxnumber-Maximum allowed value (external validation)
stepnumber1Increment/decrement step size
disabledbooleanfalseDisables both buttons and interactions

SlidingNumber Integration

The component uses SlidingNumber for smooth digit transitions:

PropTypeDefaultDescription
classNamestring-CSS classes for number display styling
durationnumber0.3Animation duration for digit transitions
staggernumber0.05Delay between multiple digit animations

Button Styling Specifications

ElementDefault StyleHover EffectActive Effect
Buttonbg-background borderopacity-80scale-95
Containerrounded-lg border--
Layoutflex items-center gap-2-layout transition

Common gotchas

State synchronization issues: The component uses controlled state, so ensure your setNumber function properly updates the state. Asynchronous state updates can cause animation glitches if not handled correctly.

Large number performance: Very large numbers (6+ digits) can impact animation performance due to multiple sliding elements. Consider debouncing rapid increments or using simpler animations for large values.

Layout shift prevention: The component uses layout animations to prevent jumps when digit count changes. Ensure parent containers have stable dimensions to avoid cascading layout shifts.

Validation timing: Implement min/max validation in your setNumber function rather than trying to prevent the component from receiving invalid values. This ensures smooth user feedback during validation.

Rapid clicking behavior: Fast clicking can queue multiple animations. The component handles this gracefully, but consider debouncing or rate limiting for better UX with very fast interactions.

Custom step increments: For non-standard increments (like 5 or 10), implement the logic in your setNumber handler rather than trying to modify the component's increment behavior directly.

You might also like

Explore other interactive button components for React applications:

Questions developers actually ask