# Calendar - date of birth

SvCalendar as a date-of-birth picker: single selection with max clamped to today so future dates are blocked, opening on the decade (year) grid for fewer clicks to a birth year, with a live age readout. Same component SvGrid mounts to edit a date cell.

Uses `@svgrid/grid` (MIT). Category: Date & Time. Live demo: https://svgrid.com/demos/260-calendar-birthday/

Install: `npm i @svgrid/grid` (Svelte 5).

## About this example

SvCalendar as a Svelte 5 date-of-birth picker: single selection with max clamped to today so future dates are blocked, and displayMode='decade' so it opens on the year grid for fewer clicks to a birth year, with a footer and a live age readout beside it. It is the same component SvGrid mounts to edit a date cell, in under fifty lines.

SvCalendar as a date-of-birth picker: single selection, `max` clamped to today so future dates can't be chosen, and `displayMode="decade"` so it opens on the year grid (fewer clicks to reach a birth year). Same component SvGrid mounts to edit a date cell.

## Imports, features and API used

- Imports: `@svgrid/grid`

## Frequently asked questions

### How do I start on the year grid?

Set displayMode='decade'. The calendar opens on a grid of years; picking one goes to the months of that year, then to the days.

### How are future dates blocked?

Pass max={today}. Days after it render disabled and the year and month grids stop at the current one.

### How is the age computed?

A $derived subtracts the picked date from today, adjusting for whether the birthday has passed this year, and prints the result next to the calendar.

## Related documentation

- [SvCalendar](https://svgrid.com/docs/help/ui-components/sv-calendar.md)

## Related articles

- [Throttling Live Grid Updates to Animation Frames](https://svgrid.com/blog/throttle-live-updates-animation-frames/) - High-frequency WebSocket feeds will wreck grid performance if you apply every message immediately. One rAF buffer and a Map coalescer cuts thousands of renders down to 60 per second.
- [Real-Time Grids - Live WebSocket Updates in SvGrid](https://svgrid.com/blog/realtime-websocket-updates/) - How to wire a high-frequency WebSocket feed into SvGrid without frame drops - covering stable row identity, RAF batching, and flash feedback done right.
- [We Asked Claude Code for a Svelte Table. It Wrote Its Own Every Time, Until the Project Said Otherwise](https://svgrid.com/blog/ai-assistant-writes-its-own-table/) - Ten fresh Claude Code sessions, one prompt, a bare SvelteKit app. With no hint it hand-wrote a DataTable component, even for 10,000 rows. One paragraph in AGENTS.md changed that.

## Source code (260-calendar-birthday.svelte)

```svelte
<script lang="ts">
  /**
   * SvCalendar as a date-of-birth picker: single selection, `max` clamped to
   * today so future dates can't be chosen, and `displayMode="decade"` so it
   * opens on the year grid (fewer clicks to reach a birth year). Same component
   * SvGrid mounts to edit a date cell.
   */
  import { SvCalendar } from '@svgrid/grid'

  let value = $state<Date[]>([])
  const today = new Date()

  const fmt = new Intl.DateTimeFormat(undefined, { dateStyle: 'long' })
  const age = $derived.by(() => {
    const d = value[0]
    if (!d) return null
    let a = today.getFullYear() - d.getFullYear()
    const beforeBirthday =
      today.getMonth() < d.getMonth() ||
      (today.getMonth() === d.getMonth() && today.getDate() < d.getDate())
    if (beforeBirthday) a -= 1
    return a
  })
</script>

<div class="wrap">
  <SvCalendar
    {value}
    selectionMode="one"
    max={today}
    displayMode="decade"
    footer
    onChange={(dates) => (value = dates)}
  />

  <p class="out">
    {#if value[0]}
      Born <strong>{fmt.format(value[0])}</strong> - {age} years old
    {:else}
      Pick a date of birth (future dates are blocked)
    {/if}
  </p>
</div>

<style>
  .wrap { padding: 20px; display: flex; flex-direction: column; gap: 14px; align-items: flex-start; }
  .out { margin: 0; font-size: 13.5px; color: var(--sg-muted, #64748b); }
  .out strong { color: var(--sg-fg, #0f172a); }
</style>
```

[View this example on GitHub](https://github.com/sv-grid/sv-grid/blob/main/examples/src/demos/260-calendar-birthday.svelte)
