# V date picker 9

> Delivery Date Selector

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

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

## Install

```bash
npx shadcn@latest add https://ui.cnippet.dev/r/v-date-picker-9.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/date-picker`

## Files

### `registry/default/variants/v-date-picker-9.tsx`

```tsx
//biome-ignore-all lint/style/noNonNullAssertion:<>

"use client";

import { addDays, format, isWeekend, startOfDay } from "date-fns";
import { PackageIcon, TruckIcon, ZapIcon } from "lucide-react";
import { useState } from "react";
import { cn } from "@/lib/utils";
import { Badge } from "@/registry/default/ui/badge";
import { Button } from "@/registry/default/ui/button";
import { Calendar } from "@/registry/default/ui/calendar";
import {
  Popover,
  PopoverPopup,
  PopoverTrigger,
} from "@/registry/default/ui/popover";

type ShippingMethod = "standard" | "express";

const METHODS = [
  {
    description: "3–5 business days",
    icon: TruckIcon,
    id: "standard" as ShippingMethod,
    label: "Standard",
    minDays: 3,
    price: "Free",
  },
  {
    description: "1–2 business days",
    icon: ZapIcon,
    id: "express" as ShippingMethod,
    label: "Express",
    minDays: 1,
    price: "$9.99",
  },
];

function nextBusinessDay(from: Date, minDays: number): Date {
  let d = addDays(startOfDay(from), minDays);
  while (isWeekend(d)) d = addDays(d, 1);
  return d;
}

export default function Particle() {
  const today = new Date();
  const [method, setMethod] = useState<ShippingMethod>("standard");
  const [date, setDate] = useState<Date | undefined>();

  const selected = METHODS.find((m) => m.id === method)!;
  const earliest = nextBusinessDay(today, selected.minDays);
  const latest = nextBusinessDay(
    today,
    selected.minDays + (method === "standard" ? 2 : 1),
  );

  const handleMethodChange = (id: ShippingMethod) => {
    setMethod(id);
    setDate(undefined);
  };

  const deliveryStart = date ?? earliest;
  const deliveryEnd = date
    ? addDays(date, method === "standard" ? 2 : 1)
    : latest;

  return (
    <div className="w-full max-w-sm space-y-4 rounded-xl border bg-background p-4 shadow-sm">
      <div className="flex items-center gap-2">
        <PackageIcon
          aria-hidden="true"
          className="size-4 text-muted-foreground"
        />
        <h3 className="font-semibold text-sm">Choose Delivery</h3>
      </div>

      <div className="grid grid-cols-2 gap-2">
        {METHODS.map((m) => (
          <button
            className={cn(
              "flex flex-col items-start rounded-lg border p-3 text-left transition-colors",
              method === m.id
                ? "border-primary bg-primary/5"
                : "border-input hover:bg-accent",
            )}
            key={m.id}
            onClick={() => handleMethodChange(m.id)}
            type="button"
          >
            <div className="flex w-full items-center justify-between">
              <m.icon
                aria-hidden="true"
                className="size-4 text-muted-foreground"
              />
              <Badge variant={m.id === "express" ? "info" : "outline"}>
                {m.price}
              </Badge>
            </div>
            <p className="mt-2 font-medium text-sm">{m.label}</p>
            <p className="text-muted-foreground text-xs">{m.description}</p>
          </button>
        ))}
      </div>

      <Popover>
        <PopoverTrigger
          render={<Button className="w-full justify-start" variant="outline" />}
        >
          <PackageIcon aria-hidden="true" />
          {date
            ? `Deliver on ${format(date, "EEE, MMM dd")}`
            : `Earliest: ${format(earliest, "EEE, MMM dd")}`}
        </PopoverTrigger>
        <PopoverPopup>
          <Calendar
            disabled={[
              { before: earliest },
              { after: addDays(today, 30) },
              ...(method === "standard"
                ? [{ dayOfWeek: [0, 6] as (0 | 1 | 2 | 3 | 4 | 5 | 6)[] }]
                : []),
            ]}
            mode="single"
            onSelect={setDate}
            selected={date}
          />
        </PopoverPopup>
      </Popover>

      <p className="text-center text-muted-foreground text-xs">
        Estimated delivery:{" "}
        <span className="font-medium text-foreground">
          {format(deliveryStart, "EEE, MMM dd")} –{" "}
          {format(deliveryEnd, "EEE, MMM dd")}
        </span>
      </p>

      <Button className="w-full">Confirm Delivery</Button>
    </div>
  );
}
```
