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.
Powered by
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.
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:
Value Ranges
Counters with different constraints and increment behaviors:
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.
Prop | Type | Default | Description |
---|---|---|---|
number | number | required | Current counter value to display |
setNumber | (number: number) => void | required | Function to update the counter value |
slidingNumberProps | Omit<SlidingNumberProps, 'number'> | - | Props passed to the SlidingNumber component |
buttonProps | Omit<React.ComponentProps<typeof Button>, 'onClick'> | - | Props passed to both increment and decrement buttons |
transition | Transition | {type: 'spring', bounce: 0, stiffness: 300, damping: 30} | Motion transition for layout animations |
min | number | - | Minimum allowed value (external validation) |
max | number | - | Maximum allowed value (external validation) |
step | number | 1 | Increment/decrement step size |
disabled | boolean | false | Disables both buttons and interactions |
SlidingNumber Integration
The component uses SlidingNumber for smooth digit transitions:
Prop | Type | Default | Description |
---|---|---|---|
className | string | - | CSS classes for number display styling |
duration | number | 0.3 | Animation duration for digit transitions |
stagger | number | 0.05 | Delay between multiple digit animations |
Button Styling Specifications
Element | Default Style | Hover Effect | Active Effect |
---|---|---|---|
Button | bg-background border | opacity-80 | scale-95 |
Container | rounded-lg border | - | - |
Layout | flex 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:
Input Button
Buttons that transform into input fields
Icon Button
Animated icon buttons with particle burst effects
Liquid Button
Animated buttons with fluid fill effects
Flip Button
3D flip animations with smooth physics transitions
Questions developers actually ask
React Corner Accent Button
React button with animated corner accents and sliding background effect. Features expanding corners and smooth transitions with TypeScript and shadcn/ui.
React Flip Button
React flip button with 3D animations that reveal hidden messages on hover. Smooth transitions and customizable directions with TypeScript and shadcn/ui.