# DatePicker

## Description

A comprehensive date and time selection component built on Flatpickr with extensive customization options. Supports single date selection, date ranges, time selection, inline display, and custom positioning. Includes advanced features like custom time pickers, date parsing, and keyboard navigation for flexible date/time input scenarios.

## Aliases

- DatePicker
- DateSelector
- Calendar
- DateInput
- DateTimePicker

## Props Breakdown

**Extends:** ControlledFormComponentProps<DatePickerValue> (form field integration)

| Prop | Type | Default | Required | Description |
|------|------|---------|----------|-------------|
| `value` | `DatePickerValue` | - | No | Current selected date(s) - string, Date, or array |
| `onChange` | `(value: DatePickerValue) => void` | - | No | Callback fired when date selection changes |
| `minDate` | `string \| Date` | - | No | Minimum selectable date |
| `maxDate` | `string \| Date` | - | No | Maximum selectable date |
| `enableTime` | `boolean` | `false` | No | Enable time selection in addition to date |
| `enableRange` | `boolean` | `false` | No | Enable selecting date ranges (start and end) |
| `defaultDate` | `string \| Date` | - | No | Initially displayed date when picker opens |
| `dateFormat` | `string` | - | No | Display format for selected dates (Flatpickr format) |
| `onOpen` | `(dates: Date[], dateStr: string) => void` | - | No | Callback fired when picker opens |
| `onClose` | `(dates: Date[], dateStr: string) => void` | - | No | Callback fired when picker closes |
| `inline` | `boolean` | `false` | No | Render picker inline instead of as popup |
| `noCalendar` | `boolean` | `false` | No | Hide calendar for time-only selection |
| `position` | `DatePickerPosition` | `'auto'` | No | Positioning of the picker popup |
| `parseDate` | `(date: string, format?: string) => Date` | - | No | Custom date parsing function |
| `allowInput` | `boolean` | `false` | No | Allow manual typing in input field |
| `placeholder` | `string` | - | No | Placeholder text for input |
| `leadingIcon` | `ReactNode` | - | No | Icon displayed before input |
| `trailingIcon` | `ReactNode` | - | No | Icon displayed after input |
| `className` | `string` | - | No | Additional CSS class names |

## Examples

### Basic Date Picker
```tsx
import { DatePicker, FormField } from '@delightui/components';

function BasicExample() {
  const [selectedDate, setSelectedDate] = useState(null);

  return (
    <FormField label="Select Date">
      <DatePicker
        value={selectedDate}
        onChange={setSelectedDate}
        placeholder="Choose a date..."
        leadingIcon={<Icon icon="Calendar" />}
      />
    </FormField>
  );
}
```

### Date Range Picker
```tsx
function DateRangeExample() {
  const [dateRange, setDateRange] = useState([]);

  return (
    <div className="date-range-form">
      <FormField label="Select Date Range">
        <DatePicker
          value={dateRange}
          onChange={setDateRange}
          enableRange={true}
          placeholder="Select start and end dates..."
          dateFormat="Y-m-d"
          leadingIcon={<Icon icon="DateRange" />}
        />
      </FormField>
      
      {dateRange.length === 2 && (
        <div className="range-display">
          <Text type="BodySmall">
            From: {dateRange[0]?.toLocaleDateString()} 
            To: {dateRange[1]?.toLocaleDateString()}
          </Text>
        </div>
      )}
    </div>
  );
}
```

### Date and Time Picker
```tsx
function DateTimeExample() {
  const [dateTime, setDateTime] = useState(null);

  return (
    <FormField label="Appointment Date & Time">
      <DatePicker
        value={dateTime}
        onChange={setDateTime}
        enableTime={true}
        dateFormat="Y-m-d H:i"
        placeholder="Select date and time..."
        leadingIcon={<Icon icon="Schedule" />}
      />
    </FormField>
  );
}
```

### Time Only Picker
```tsx
function TimeOnlyExample() {
  const [time, setTime] = useState(null);

  return (
    <FormField label="Meeting Time">
      <DatePicker
        value={time}
        onChange={setTime}
        enableTime={true}
        noCalendar={true}
        dateFormat="H:i"
        placeholder="Select time..."
        leadingIcon={<Icon icon="AccessTime" />}
      />
    </FormField>
  );
}
```

### Inline Calendar
```tsx
function InlineCalendarExample() {
  const [selectedDate, setSelectedDate] = useState(new Date());

  return (
    <div className="inline-calendar-container">
      <Text type="Heading5">Choose Your Date</Text>
      
      <DatePicker
        value={selectedDate}
        onChange={setSelectedDate}
        inline={true}
        dateFormat="F j, Y"
      />
      
      {selectedDate && (
        <div className="selected-date-display">
          <Text>Selected: {selectedDate.toLocaleDateString()}</Text>
        </div>
      )}
    </div>
  );
}
```

### Booking System Date Picker
```tsx
function BookingSystemExample() {
  const [checkIn, setCheckIn] = useState(null);
  const [checkOut, setCheckOut] = useState(null);

  const today = new Date();
  const maxDate = new Date();
  maxDate.setFullYear(today.getFullYear() + 1);

  const handleCheckInChange = (date) => {
    setCheckIn(date);
    // Clear check-out if it's before new check-in
    if (checkOut && date && new Date(date) >= new Date(checkOut)) {
      setCheckOut(null);
    }
  };

  return (
    <div className="booking-form">
      <div className="date-inputs">
        <FormField label="Check-in Date" required>
          <DatePicker
            value={checkIn}
            onChange={handleCheckInChange}
            minDate={today}
            maxDate={maxDate}
            placeholder="Select check-in..."
            leadingIcon={<Icon icon="CheckIn" />}
          />
        </FormField>

        <FormField label="Check-out Date" required>
          <DatePicker
            value={checkOut}
            onChange={setCheckOut}
            minDate={checkIn ? new Date(new Date(checkIn).getTime() + 86400000) : today}
            maxDate={maxDate}
            placeholder="Select check-out..."
            leadingIcon={<Icon icon="CheckOut" />}
            disabled={!checkIn}
          />
        </FormField>
      </div>

      {checkIn && checkOut && (
        <div className="stay-summary">
          <Text type="Heading6">Stay Summary</Text>
          <Text>
            {Math.ceil((new Date(checkOut) - new Date(checkIn)) / (1000 * 60 * 60 * 24))} nights
          </Text>
        </div>
      )}
    </div>
  );
}
```

### Event Scheduler
```tsx
function EventSchedulerExample() {
  const [eventDate, setEventDate] = useState(null);
  const [startTime, setStartTime] = useState(null);
  const [endTime, setEndTime] = useState(null);

  const businessHours = {
    minTime: '09:00',
    maxTime: '18:00'
  };

  return (
    <Form className="event-form">
      <FormField label="Event Date" required>
        <DatePicker
          value={eventDate}
          onChange={setEventDate}
          minDate={new Date()}
          placeholder="Select event date..."
          leadingIcon={<Icon icon="Event" />}
        />
      </FormField>

      <div className="time-fields">
        <FormField label="Start Time" required>
          <DatePicker
            value={startTime}
            onChange={setStartTime}
            enableTime={true}
            noCalendar={true}
            dateFormat="H:i"
            placeholder="Start time..."
            leadingIcon={<Icon icon="PlayArrow" />}
          />
        </FormField>

        <FormField label="End Time" required>
          <DatePicker
            value={endTime}
            onChange={setEndTime}
            enableTime={true}
            noCalendar={true}
            dateFormat="H:i"
            placeholder="End time..."
            leadingIcon={<Icon icon="Stop" />}
            minDate={startTime}
          />
        </FormField>
      </div>

      <Button 
        actionType="submit"
        disabled={!eventDate || !startTime || !endTime}
      >
        Schedule Event
      </Button>
    </Form>
  );
}
```

### Deadline Tracker
```tsx
function DeadlineTrackerExample() {
  const [deadlines, setDeadlines] = useState([
    { id: 1, title: 'Project Proposal', date: '2024-02-15' },
    { id: 2, title: 'Final Report', date: '2024-03-01' }
  ]);
  const [newDeadline, setNewDeadline] = useState({ title: '', date: null });

  const addDeadline = () => {
    if (newDeadline.title && newDeadline.date) {
      setDeadlines(prev => [...prev, {
        id: Date.now(),
        title: newDeadline.title,
        date: newDeadline.date
      }]);
      setNewDeadline({ title: '', date: null });
    }
  };

  const getDaysUntil = (date) => {
    const today = new Date();
    const deadlineDate = new Date(date);
    const diffTime = deadlineDate - today;
    const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
    return diffDays;
  };

  return (
    <div className="deadline-tracker">
      <div className="add-deadline">
        <Text type="Heading5">Add New Deadline</Text>
        
        <FormField label="Task Title">
          <Input
            value={newDeadline.title}
            onChange={(e) => setNewDeadline(prev => ({ ...prev, title: e.target.value }))}
            placeholder="Enter task title..."
          />
        </FormField>

        <FormField label="Due Date">
          <DatePicker
            value={newDeadline.date}
            onChange={(date) => setNewDeadline(prev => ({ ...prev, date }))}
            minDate={new Date()}
            placeholder="Select due date..."
            leadingIcon={<Icon icon="Today" />}
          />
        </FormField>

        <Button onClick={addDeadline}>Add Deadline</Button>
      </div>

      <div className="deadlines-list">
        <Text type="Heading5">Upcoming Deadlines</Text>
        
        {deadlines.map(deadline => {
          const daysUntil = getDaysUntil(deadline.date);
          const isOverdue = daysUntil < 0;
          const isUrgent = daysUntil <= 3 && daysUntil >= 0;

          return (
            <Card 
              key={deadline.id} 
              className={`deadline-card ${isOverdue ? 'overdue' : isUrgent ? 'urgent' : ''}`}
            >
              <Text type="Heading6">{deadline.title}</Text>
              <Text type="BodySmall">
                Due: {new Date(deadline.date).toLocaleDateString()}
              </Text>
              <Text type="BodySmall" className="days-until">
                {isOverdue 
                  ? `${Math.abs(daysUntil)} days overdue`
                  : daysUntil === 0 
                    ? 'Due today!' 
                    : `${daysUntil} days remaining`
                }
              </Text>
            </Card>
          );
        })}
      </div>
    </div>
  );
}
```

### Birthday Reminder
```tsx
function BirthdayReminderExample() {
  const [birthdate, setBirthdate] = useState(null);
  const [name, setName] = useState('');

  const calculateAge = (birthdate) => {
    if (!birthdate) return null;
    const today = new Date();
    const birth = new Date(birthdate);
    let age = today.getFullYear() - birth.getFullYear();
    const monthDiff = today.getMonth() - birth.getMonth();
    
    if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birth.getDate())) {
      age--;
    }
    
    return age;
  };

  const getNextBirthday = (birthdate) => {
    if (!birthdate) return null;
    const today = new Date();
    const birth = new Date(birthdate);
    const thisYear = today.getFullYear();
    let nextBirthday = new Date(thisYear, birth.getMonth(), birth.getDate());
    
    if (nextBirthday < today) {
      nextBirthday.setFullYear(thisYear + 1);
    }
    
    return nextBirthday;
  };

  const maxDate = new Date();
  const minDate = new Date();
  minDate.setFullYear(maxDate.getFullYear() - 120);

  return (
    <div className="birthday-form">
      <Text type="Heading4">Birthday Reminder</Text>
      
      <FormField label="Name" required>
        <Input
          value={name}
          onChange={(e) => setName(e.target.value)}
          placeholder="Enter name..."
        />
      </FormField>

      <FormField label="Date of Birth" required>
        <DatePicker
          value={birthdate}
          onChange={setBirthdate}
          maxDate={maxDate}
          minDate={minDate}
          placeholder="Select birthdate..."
          leadingIcon={<Icon icon="Cake" />}
          dateFormat="F j, Y"
        />
      </FormField>

      {name && birthdate && (
        <Card className="birthday-info">
          <Text type="Heading6">{name}'s Birthday Info</Text>
          <div className="info-grid">
            <div>
              <Text type="BodySmall">Age:</Text>
              <Text>{calculateAge(birthdate)} years old</Text>
            </div>
            <div>
              <Text type="BodySmall">Next Birthday:</Text>
              <Text>{getNextBirthday(birthdate)?.toLocaleDateString()}</Text>
            </div>
            <div>
              <Text type="BodySmall">Days Until:</Text>
              <Text>
                {Math.ceil((getNextBirthday(birthdate) - new Date()) / (1000 * 60 * 60 * 24))} days
              </Text>
            </div>
          </div>
        </Card>
      )}
    </div>
  );
}
```

### Custom Date Format Picker
```tsx
function CustomFormatExample() {
  const [date, setDate] = useState(null);
  const [format, setFormat] = useState('Y-m-d');

  const formats = [
    { value: 'Y-m-d', label: 'YYYY-MM-DD', example: '2024-02-15' },
    { value: 'F j, Y', label: 'Month Day, Year', example: 'February 15, 2024' },
    { value: 'd/m/Y', label: 'DD/MM/YYYY', example: '15/02/2024' },
    { value: 'm/d/Y', label: 'MM/DD/YYYY', example: '02/15/2024' },
    { value: 'l, F j, Y', label: 'Full Date', example: 'Thursday, February 15, 2024' }
  ];

  const customParseDate = (dateStr, format) => {
    // Custom parsing logic based on format
    return new Date(dateStr);
  };

  return (
    <div className="custom-format-picker">
      <Text type="Heading5">Custom Date Format</Text>
      
      <FormField label="Date Format">
        <Select value={format} onChange={setFormat}>
          {formats.map(fmt => (
            <Option key={fmt.value} value={fmt.value}>
              <div className="format-option">
                <Text>{fmt.label}</Text>
                <Text type="BodySmall" className="format-example">
                  {fmt.example}
                </Text>
              </div>
            </Option>
          ))}
        </Select>
      </FormField>

      <FormField label="Select Date">
        <DatePicker
          value={date}
          onChange={setDate}
          dateFormat={format}
          parseDate={customParseDate}
          placeholder={`Enter date in ${format} format...`}
          allowInput={true}
          leadingIcon={<Icon icon="DateRange" />}
        />
      </FormField>

      {date && (
        <div className="date-preview">
          <Text type="BodySmall">Selected Date:</Text>
          <Text>{new Date(date).toLocaleDateString()}</Text>
        </div>
      )}
    </div>
  );
}
```