# V calendar 13

> Week Picker

A shadcn/ui block from the [@cnippet](https://ui.cnippet.dev/) registry, listed on [shadcn.exchange](https://shadcn.exchange/r/cnippet/v-calendar-13).

- Page, with a live preview: https://shadcn.exchange/r/cnippet/v-calendar-13
- Screenshot: https://abzjhwgwpdpz7ua5.public.blob.vercel-storage.com/shots/cnippet/v-calendar-13-light-e62385a5941c4e1f.png
- Registry item: https://ui.cnippet.dev/r/v-calendar-13.json
- Categories: calendar
- Listed: 2026-10-13, source last changed 2026-10-13

## Install

```bash
npx shadcn@latest add https://ui.cnippet.dev/r/v-calendar-13.json
```

Run it in a project that has shadcn/ui set up. It adds the files below and installs what they depend on.

## Dependencies

- Registry items: `@cnippet/calendar`

## Files

### `registry/default/variants/v-calendar-13.tsx`

```tsx
"use client";

import * as React from "react";
import type { DateRange } from "react-day-picker";
import { Calendar } from "@/registry/default/ui/calendar";

// Snaps a date to the Monday–Sunday ISO week containing it.
function isoWeekRange(date: Date): DateRange {
  const d = new Date(date);
  d.setHours(0, 0, 0, 0);
  const day = d.getDay();
  const diffToMonday = day === 0 ? -6 : 1 - day;
  const from = new Date(d);
  from.setDate(d.getDate() + diffToMonday);
  const to = new Date(from);
  to.setDate(from.getDate() + 6);
  return { from, to };
}

function formatWeekLabel(range: DateRange): string {
  const { from, to } = range;
  if (!from || !to) return "";
  const sameYear = from.getFullYear() === to.getFullYear();
  const sameMonth = sameYear && from.getMonth() === to.getMonth();
  const fromStr = from.toLocaleDateString("en-US", {
    day: "numeric",
    month: "short",
  });
  const toStr = to.toLocaleDateString("en-US", {
    day: "numeric",
    month: sameMonth ? undefined : "short",
    year: "numeric",
  });
  return `${fromStr} – ${toStr}`;
}

export default function Particle() {
  const [week, setWeek] = React.useState<DateRange>(isoWeekRange(new Date()));

  function handleSelect(range: DateRange | undefined) {
    // react-day-picker provides `from` as the newly clicked day;
    // snap the whole selection to that day's ISO week.
    if (range?.from) setWeek(isoWeekRange(range.from));
  }

  return (
    <div className="flex flex-col gap-3">
      <Calendar
        ISOWeek
        mode="range"
        onSelect={handleSelect}
        selected={week}
        showWeekNumber
      />
      <div className="rounded-lg border px-4 py-3 text-sm">
        {week.from ? (
          <p>
            Week selected:{" "}
            <span className="font-semibold">{formatWeekLabel(week)}</span>
          </p>
        ) : (
          <p className="text-muted-foreground">
            Click any day to select its full week.
          </p>
        )}
      </div>
    </div>
  );
}
```
