# Counter

> An odometer-style number whose digits roll to every new value with springy motion blur, and that formats currency, percentages, separators and locales.

An odometer-style number. Every digit rolls on a spring to its new value, blurs while it spins fast, and slides in or out as the number grows or shrinks. Formatting comes from `Intl.NumberFormat`, so currency, percentages, compact notation, units, separators and non-Latin numerals all work. On first scroll into view every digit spins once and lands. Switch scenes in the panel, then press the buttons to change the numbers.

<demo-counter>



</demo-counter>

## Installation

```bash
npx shadcn-vue@latest add "https://nxui.geoql.in/r/counter.json"
```

## Usage

```vue
<script setup lang="ts">
  import { ref } from 'vue';
  import Counter from '~/components/ui/counter/Counter.vue';

  const revenue = ref(48203.17);
</script>

<template>
  <Counter
    :value="revenue"
    :format="{ style: 'currency', currency: 'USD' }"
    :decimals="2"
    :font-size="52"
    :font-weight="600"
  />

  <!-- Countdown tile: padded digits on a background -->
  <Counter
    :value="9"
    :min-digits="2"
    direction="down"
    :fade="0"
    :gap="6"
    :digit-style="{
      padding: '0.18em 0.14em',
      borderRadius: '0.18em',
      background: 'var(--secondary)',
    }"
  />
</template>
```

## Props

<table>
<thead>
  <tr>
    <th>
      Prop
    </th>
    
    <th>
      Type
    </th>
    
    <th>
      Default
    </th>
    
    <th>
      Description
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        value
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0
      </code>
    </td>
    
    <td>
      The number to show. Digits roll to every new value
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        locale
      </code>
    </td>
    
    <td>
      <code>
        string | string[]
      </code>
    </td>
    
    <td>
      <code>
        'en-US'
      </code>
    </td>
    
    <td>
      Locale used for separators, symbols and numerals
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        format
      </code>
    </td>
    
    <td>
      <code>
        Intl.NumberFormatOptions
      </code>
    </td>
    
    <td>
      —
    </td>
    
    <td>
      Formatting options such as currency, percent, units or compact notation
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        decimals
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      —
    </td>
    
    <td>
      Fixed number of decimal places. Leave it out to use the format defaults
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        min-digits
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      Pads the whole part with leading zeros
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        prefix
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      —
    </td>
    
    <td>
      Text shown before the number (or use the <code>
        prefix
      </code>
      
       slot)
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        suffix
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      —
    </td>
    
    <td>
      Text shown after the number (or use the <code>
        suffix
      </code>
      
       slot)
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        direction
      </code>
    </td>
    
    <td>
      <code>
        'auto' | 'up' | 'down' | 'shortest'
      </code>
    </td>
    
    <td>
      <code>
        'auto'
      </code>
    </td>
    
    <td>
      Which way digits roll. Auto rolls up as the number grows and down as it shrinks
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        duration
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.7
      </code>
    </td>
    
    <td>
      Roughly how long a roll takes (seconds)
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        bounce
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.2
      </code>
    </td>
    
    <td>
      How much digits overshoot before settling, 0–0.9
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        stagger
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.04
      </code>
    </td>
    
    <td>
      Delay between neighbouring digits (seconds), so changes ripple from the right
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        motion-blur
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      Blurs digits along their path while they spin fast
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        intro
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      Spins every digit once and lands it when the counter first scrolls into view
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        fade
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.3
      </code>
    </td>
    
    <td>
      How far (em) digits roll beyond the text before fading out. <code>
        0
      </code>
      
       clips at the edge
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        font-size
      </code>
    </td>
    
    <td>
      <code>
        number | string
      </code>
    </td>
    
    <td>
      <code>
        100
      </code>
    </td>
    
    <td>
      Font size in px, or any CSS size such as <code>
        inherit
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        font-weight
      </code>
    </td>
    
    <td>
      <code>
        number | string
      </code>
    </td>
    
    <td>
      <code>
        'inherit'
      </code>
    </td>
    
    <td>
      Font weight of the number
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        text-color
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        'inherit'
      </code>
    </td>
    
    <td>
      Color of the number
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        gap
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0
      </code>
    </td>
    
    <td>
      Space between digits and symbols (px)
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        padding
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0
      </code>
    </td>
    
    <td>
      Extra height (px) added to each digit, which also spaces out rolling digits
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        tabular
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      Keeps every digit the same width. When off, widths ease between digits as they roll
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        digit-style
      </code>
    </td>
    
    <td>
      <code>
        StyleValue
      </code>
    </td>
    
    <td>
      —
    </td>
    
    <td>
      Styles for each digit box, for example a tile background with padding and radius
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        class
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        ''
      </code>
    </td>
    
    <td>
      Extra classes for the root
    </td>
  </tr>
</tbody>
</table>

## Slots

<table>
<thead>
  <tr>
    <th>
      Slot
    </th>
    
    <th>
      Description
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        prefix
      </code>
    </td>
    
    <td>
      Content shown before the number. Overrides <code>
        prefix
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        suffix
      </code>
    </td>
    
    <td>
      Content shown after the number. Overrides <code>
        suffix
      </code>
    </td>
  </tr>
</tbody>
</table>

## Accessibility

- Screen readers get the fully formatted value (with prefix and suffix) from a visually hidden label; the rolling digits are `aria-hidden`.
- With `prefers-reduced-motion: reduce` digits jump straight to their value and the intro spin is skipped.
- The digit row reads left to right even in right-to-left pages, so numbers never mirror.
- Ported from [React Bits](https://reactbits.dev/components/counter) by David Haz.
