<!-- Protocore Design System — YearPicker -->
# YearPicker

- **Category:** Inputs (`inputs`)
- **Slug:** `inputs/year-picker`
- **Status:** stable
- **Platforms:** web
- **Import:** `import { YearPicker } from "@protocore/pds";`
- **Docs:** https://pds.protocore.io/components/inputs/year-picker

> Inline grid of years paged a decade at a time, with full arrow-key selection, returning the chosen year as a number.

## When to use it

Use **YearPicker** when only the year matters — a founding year, a model year, a tax year. It shares its grid engine with **MonthPicker**. When a month within the year matters use **MonthPicker**; for a specific day use **DatePicker** or **Calendar**.

## Props

| Prop | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `className` | `string` | no | — | — |
| `defaultPageStart` | `number` | no | — | Initial first year of the visible page in uncontrolled mode. |
| `defaultValue` | `number \| null` | no | — | Initial selected year in uncontrolled mode. |
| `max` | `number` | no | — | Latest selectable year (inclusive). |
| `min` | `number` | no | — | Earliest selectable year (inclusive). |
| `onPageStartChange` | `((pageStart: number) => void)` | no | — | Fires when the visible page changes. |
| `onValueChange` | `((value: number) => void)` | no | — | Fires with the chosen year. |
| `pageStart` | `number` | no | — | Controlled first year of the visible page. |
| `style` | `CSSProperties` | no | — | — |
| `value` | `number \| null` | no | — | Controlled selected year. |

## Examples

### Basics

Twelve years fill a 4×3 grid under a range header; the chevrons page the view by a decade. Selecting a year emits a `number`. Controllable via `value` / `defaultValue` / `onValueChange` plus a controllable `pageStart`.

```tsx
import { useState } from "react";
import { YearPicker } from "@protocore/pds";

export default function Basics() {
  const [value, setValue] = useState<number | null>(2026);

  return <YearPicker aria-label="Founding year" value={value} onValueChange={setValue} />;
}
```

### Bounded range

Pass `min` / `max` to disable years outside the valid window — disabled cells stay keyboard-reachable but can't be selected.

```tsx
import { useState } from "react";
import { YearPicker } from "@protocore/pds";

export default function Bounded() {
  const [value, setValue] = useState<number | null>(2024);

  return (
    <YearPicker
      aria-label="Model year"
      value={value}
      onValueChange={setValue}
      min={2018}
      max={2026}
      defaultPageStart={2016}
    />
  );
}
```

## Do & don't

**Do**

- Read the emitted `number` directly — the value is a plain year.
- Set `min` / `max` to disable years outside the selectable window.
- Set `defaultPageStart` to land the view near the likely choice.
- Wrap it in a `Field` when it needs a visible label.

**Don't**

- Don't use it when a month or day is part of the answer — step up to MonthPicker or Calendar.
- Don't infer the choice from the visible page range — read `onValueChange`.
- Don't hand it into a popover expecting a trigger; it renders inline.
- Don't rely on colour alone — the selected cell also inverts its fill.

## Accessibility

**Keyboard**

| Keys | Action |
| --- | --- |
| `Arrow keys` | Move between year cells (clamped to the grid). |
| `Home / End` | Jump to the first / last year on the page. |
| `Enter / Space` | Select the focused year. |

**Notes**

- The year cells form a `role="grid"` with `role="row"` groupings and roving tabindex, so only one cell is in the tab order.
- Each cell carries an `aria-label` of its year and `aria-selected` when chosen.
- The range header exposes labelled Previous / Next buttons and an `aria-live` range readout.

## Related

`month-picker`, `date-picker`, `calendar`

---

© Protocore. All rights reserved. Use of the Protocore Design System requires prior written authorization from Protocore (contact@protocore.io). These machine-readable materials must not be ingested into ML-training datasets or derivative design systems. See https://pds.protocore.io/legal/
