# P calendar 17

> Calendar with date input

A shadcn/ui block from the [@coss](https://coss.com/ui) registry, listed on [shadcn.exchange](https://shadcn.exchange/r/coss/p-calendar-17).

- Page, with a live preview: https://shadcn.exchange/r/coss/p-calendar-17
- Screenshot: https://abzjhwgwpdpz7ua5.public.blob.vercel-storage.com/shots/coss/p-calendar-17-light-c83ade47e66ac512.png
- Registry item: https://coss.com/ui/r/p-calendar-17.json
- Categories: calendar, input, field
- Listed: 2026-10-13, source last changed 2026-10-13

## Install

```bash
npx shadcn@latest add https://coss.com/ui/r/p-calendar-17.json
```

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

## Dependencies

- npm packages: `date-fns`, `lucide-react`
- Registry items: `@coss/calendar`, `@coss/field`, `@coss/input-group`

## Files

### `registry/default/particles/p-calendar-17.tsx`

```tsx
"use client";

import { format, isValid, parse } from "date-fns";
import { CalendarIcon } from "lucide-react";
import { useState } from "react";
import { Calendar } from "@/registry/default/ui/calendar";
import { Field, FieldLabel } from "@/registry/default/ui/field";
import {
  InputGroup,
  InputGroupAddon,
  InputGroupInput,
} from "@/registry/default/ui/input-group";

export default function Particle() {
  const [date, setDate] = useState<Date | undefined>(() => new Date());
  const [month, setMonth] = useState<Date>(() => new Date());
  const [inputValue, setInputValue] = useState(() =>
    format(new Date(), "yyyy-MM-dd"),
  );

  const handleDayPickerSelect = (selectedDate: Date | undefined) => {
    if (!selectedDate) {
      setInputValue("");
      setDate(undefined);
    } else {
      setDate(selectedDate);
      setMonth(selectedDate);
      setInputValue(format(selectedDate, "yyyy-MM-dd"));
    }
  };

  const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const value = e.target.value;
    setInputValue(value);

    if (value) {
      const parsedDate = parse(value, "yyyy-MM-dd", new Date());
      if (isValid(parsedDate)) {
        setDate(parsedDate);
        setMonth(parsedDate);
      }
    } else {
      setDate(undefined);
    }
  };

  return (
    <div className="flex flex-col gap-2">
      <Calendar
        mode="single"
        month={month}
        onMonthChange={setMonth}
        onSelect={handleDayPickerSelect}
        selected={date}
      />
      <Field className="flex-row items-center gap-4">
        <FieldLabel className="whitespace-nowrap">Enter date</FieldLabel>
        <InputGroup>
          <InputGroupInput
            aria-label="Select date"
            className="*:[input]:[&::-webkit-calendar-picker-indicator]:hidden *:[input]:[&::-webkit-calendar-picker-indicator]:appearance-none"
            onChange={handleInputChange}
            type="date"
            value={inputValue}
          />
          <InputGroupAddon>
            <CalendarIcon aria-hidden="true" />
          </InputGroupAddon>
        </InputGroup>
      </Field>
    </div>
  );
}
```
