# NumberTicker

> Animated number counter with easing, triggered on viewport entry.

- Package: `fancy-ui-svelte` (Svelte 5 + Tailwind CSS v4)
- Category: Text & Typography
- Tags: text, counter, animation, number, scroll, statistics
- Docs: https://fancy-ui.rama.app/docs/components/number-ticker
- Source: https://github.com/RamaHerbin/fancy-ui/tree/main/src/lib/fancy-ui/number-ticker

## Import

```svelte
<script lang="ts">
  import { NumberTicker } from 'fancy-ui-svelte';
</script>
```

Setup (once per project): `npm install fancy-ui-svelte`, then add `@import "fancy-ui-svelte/tailwind.css";` after `@import "tailwindcss";` in your main CSS file. Full guide: https://fancy-ui.rama.app/llms.txt

React: `import { NumberTicker } from 'fancy-ui-react';` (same prop names; `class` becomes `className`, snippets become `ReactNode`).

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `value` | `number` | `0` | Target number to animate to |
| `direction` | `"up" \| "down"` | `"up"` | Animation direction: "up" counts 0→value, "down" counts value→0 |
| `duration` | `number` | `1000` | Animation duration in ms |
| `delay` | `number` | `0` | Delay before animation starts in ms |
| `decimalPlaces` | `number` | `0` | Number of decimal places to display |

## Examples

### Basic Usage

```svelte
<script lang="ts">
	import { NumberTicker } from "fancy-ui-svelte";
	import ReplayButton from "$lib/components/ReplayButton.svelte";

	let replayKey = $state(0);
</script>

<div class="relative">
	<ReplayButton onclick={() => replayKey++} />
	{#key replayKey}
		<div class="flex items-center gap-16">
			<div class="text-center">
				<NumberTicker value={1234} class="text-6xl font-bold" />
				<p class="text-muted-foreground mt-2 text-sm">Users</p>
			</div>
			<div class="text-center">
				<NumberTicker value={567} class="text-6xl font-bold" />
				<p class="text-muted-foreground mt-2 text-sm">Projects</p>
			</div>
		</div>
	{/key}
</div>
```

### Decimal Places

Control decimal precision.

```svelte
<script lang="ts">
	import { NumberTicker } from "fancy-ui-svelte";
	import ReplayButton from "$lib/components/ReplayButton.svelte";

	let replayKey = $state(0);
</script>

<div class="relative text-center">
	<ReplayButton onclick={() => replayKey++} />
	{#key replayKey}
		<span class="text-muted-foreground text-4xl font-bold">$</span>
		<NumberTicker value={99.99} decimalPlaces={2} class="text-6xl font-bold" />
	{/key}
</div>
```

### Count Down

Animate from high to low.

```svelte
<script lang="ts">
	import { NumberTicker } from "fancy-ui-svelte";
	import ReplayButton from "$lib/components/ReplayButton.svelte";

	let replayKey = $state(0);
</script>

<div class="relative">
	<ReplayButton onclick={() => replayKey++} />
	{#key replayKey}
		<NumberTicker value={100} direction="down" class="text-6xl font-bold" />
	{/key}
</div>
```

### With Delay

Add a start delay.

```svelte
<script lang="ts">
	import { NumberTicker } from "fancy-ui-svelte";
	import ReplayButton from "$lib/components/ReplayButton.svelte";

	let replayKey = $state(0);
</script>

<div class="relative">
	<ReplayButton onclick={() => replayKey++} />
	{#key replayKey}
		<NumberTicker value={9999} delay={500} duration={2000} class="text-6xl font-bold" />
	{/key}
</div>
```

### Interactive Playground

```svelte
<script lang="ts">
	import { NumberTicker } from "fancy-ui-svelte";
	import PropsPlayground from "$lib/components/PropsPlayground.svelte";
</script>

<PropsPlayground
	controls={[
		{ key: "value", type: "range", label: "Value", min: 0, max: 100000, step: 100 },
		{ key: "duration", type: "range", label: "Duration (ms)", min: 200, max: 5000, step: 100 },
		{ key: "delay", type: "range", label: "Delay (ms)", min: 0, max: 2000, step: 100 },
		{ key: "decimalPlaces", type: "range", label: "Decimal Places", min: 0, max: 4, step: 1 },
		{
			key: "direction",
			type: "select",
			label: "Direction",
			options: [
				{ value: "up", label: "Up" },
				{ value: "down", label: "Down" },
			],
		},
	]}
	initialValues={{ value: 1234, duration: 1000, delay: 0, decimalPlaces: 0, direction: "up" }}
>
	{#snippet preview(values)}
		<div class="flex items-center justify-center rounded-xl p-12">
			<NumberTicker
				value={values.value as number}
				duration={values.duration as number}
				delay={values.delay as number}
				decimalPlaces={values.decimalPlaces as number}
				direction={values.direction as "up" | "down"}
				class="text-6xl font-bold"
			/>
		</div>
	{/snippet}
</PropsPlayground>
```
