# PaginationDot

> Slug: `pagination-dot` · Category: Navigation

## When to use
- A compact dot-based page/slide indicator for carousels, onboarding flows, or hero rotators.
- When the page count is small (typically 2–8 visible at once) and a numeric pager would be overkill.

## When NOT to use
- For data tables or lists with many pages — use a numeric pager pattern instead.
- For a multi-step form/checkout — use `StepIndicator`.
- For app-level navigation between sections — use `Tabs`/`Subnavigation`.

## Variants & decision tree
There is one visual treatment with two configuration knobs:
- **`count` ≤ `maxVisible`** → all dots rendered, no overflow markers.
- **`count` > `maxVisible`** → window of `maxVisible` dots; the first/last visible dot becomes an "overflow" dot when more dots exist beyond the window.

Use `startIndex` to slide the window and `activeIndex` to mark the current page. Clamp `startIndex` so the window stays inside `[0, count - maxVisible]`.

## States
- Active dot (`activeIndex`) gets `aria-current="true"`.
- Overflow dots get a visual indicator and an extended `aria-label` ("…more available").
- Force-state props (`hover`, `focused`, `pressed`) target index `3` only — visual testing only.
- `inverse` swaps to dark-background styling.

## Props
| Prop | Type | Default | Description |
|---|---|---|---|
| `count` | `number` | — | Total number of dots (min 2). |
| `startIndex` | `number` | — | First visible dot in the window. |
| `activeIndex` | `number` | — | Currently active dot. |
| `maxVisible` | `number` | — | Max dots visible at once. |
| `onDotClick` | `(index: number) => void` | — | Called with the clicked dot's index. |
| `inverse` | `boolean` | inherited | Dark-background styling. |
| `className` | `string` | — | Extra class on root `<nav>`. |

## Usage examples
```tsx
const [activeIndex, setActiveIndex] = useState(0);
const total = slides.length;
const maxVisible = 5;
const startIndex = Math.max(0, Math.min(activeIndex - 2, total - maxVisible));

<PaginationDot
  count={total}
  maxVisible={maxVisible}
  startIndex={startIndex}
  activeIndex={activeIndex}
  onDotClick={setActiveIndex}
/>
```

## Composition
Pair with a carousel or slide container. Manage slide state externally; `PaginationDot` is purely presentational + click-bridge.

## Accessibility
- Renders a `<nav aria-label="Pagination navigation">` with a `<ol role="list">`.
- Each dot is a `<button>` with `aria-label="Go to slide N of M"`.
- Active dot uses `aria-current="true"`. Don't add a redundant `role` or label.

## Do / Don't
- Do keep `maxVisible` small (≤ 8) so dots remain tap-friendly.
- Do recompute `startIndex` so `activeIndex` stays inside the window.
- Don't use for navigation that has names — use `Tabs` so users see labels.
- Don't render fewer than 2 dots; the component clamps to `Math.max(count, 2)`.
