Claude
Skills
Sign in
Back

date-pickers

Included with Lifetime
$97 forever

MUI X Date/Time Pickers setup, configuration, and form integration

General

What this skill does


# MUI X Date Pickers

## Package Installation

```bash
# Core package (free)
npm install @mui/x-date-pickers

# Pro package (requires license — DateRangePicker, DateTimeRangePicker, etc.)
npm install @mui/x-date-pickers-pro

# Choose ONE date adapter:
npm install dayjs                    # recommended — smallest, fastest
npm install date-fns                 # most popular in React ecosystem
npm install luxon                    # feature-rich, immutable
npm install moment                   # legacy; avoid for new projects
```

## Date Adapters

### dayjs (recommended)

dayjs is the recommended adapter: smallest bundle (~7 KB), fastest parse, covers all picker features.

```tsx
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';

// Wrap your app root (or page root) — every picker must be a descendant
export default function App() {
  return (
    <LocalizationProvider dateAdapter={AdapterDayjs}>
      <MyRoutes />
    </LocalizationProvider>
  );
}
```

### date-fns

```tsx
import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns';
import { enUS } from 'date-fns/locale';   // import locale from date-fns/locale, NOT date-fns

<LocalizationProvider dateAdapter={AdapterDateFns} adapterLocale={enUS}>
  <MyRoutes />
</LocalizationProvider>
```

### luxon

```tsx
import { AdapterLuxon } from '@mui/x-date-pickers/AdapterLuxon';

<LocalizationProvider dateAdapter={AdapterLuxon} adapterLocale="en-US">
  <MyRoutes />
</LocalizationProvider>
```

## Core Picker Components

### DatePicker

```tsx
import { DatePicker } from '@mui/x-date-pickers/DatePicker';
import dayjs, { Dayjs } from 'dayjs';
import { useState } from 'react';

function BasicDatePicker() {
  const [value, setValue] = useState<Dayjs | null>(dayjs('2024-01-15'));

  return (
    <DatePicker
      label="Select date"
      value={value}
      onChange={(newValue) => setValue(newValue)}
    />
  );
}
```

### TimePicker

```tsx
import { TimePicker } from '@mui/x-date-pickers/TimePicker';

function BasicTimePicker() {
  const [value, setValue] = useState<Dayjs | null>(dayjs().hour(10).minute(30));

  return (
    <TimePicker
      label="Select time"
      value={value}
      onChange={(newValue) => setValue(newValue)}
      ampm={false}                      // 24-hour format
      views={['hours', 'minutes']}      // omit 'seconds' if not needed
    />
  );
}
```

### DateTimePicker

```tsx
import { DateTimePicker } from '@mui/x-date-pickers/DateTimePicker';

function BasicDateTimePicker() {
  const [value, setValue] = useState<Dayjs | null>(null);

  return (
    <DateTimePicker
      label="Date and time"
      value={value}
      onChange={(newValue) => setValue(newValue)}
      format="DD/MM/YYYY HH:mm"
      ampm={false}
    />
  );
}
```

### DateRangePicker (Pro — requires license)

```tsx
import { DateRangePicker } from '@mui/x-date-pickers-pro/DateRangePicker';
import { DateRange } from '@mui/x-date-pickers-pro';
import { LicenseInfo } from '@mui/x-license';

// Set license key once at app entry point
LicenseInfo.setLicenseKey('your-license-key');

function BookingPicker() {
  const [value, setValue] = useState<DateRange<Dayjs>>([null, null]);

  return (
    <DateRangePicker
      value={value}
      onChange={(newValue) => setValue(newValue)}
      localeText={{ start: 'Check-in', end: 'Check-out' }}
    />
  );
}
```

### DateTimeRangePicker (Pro)

```tsx
import { DateTimeRangePicker } from '@mui/x-date-pickers-pro/DateTimeRangePicker';

function EventTimePicker() {
  const [value, setValue] = useState<DateRange<Dayjs>>([null, null]);

  return (
    <DateTimeRangePicker
      value={value}
      onChange={setValue}
      localeText={{ start: 'Event start', end: 'Event end' }}
    />
  );
}
```

## Slots and slotProps (v6 API)

`slots` replaces `components`; `slotProps` replaces `componentsProps`. Always use the new API.

### textField slot

```tsx
import TextField from '@mui/material/TextField';

<DatePicker
  label="Birthday"
  value={value}
  onChange={setValue}
  slots={{
    textField: TextField,
  }}
  slotProps={{
    textField: {
      variant: 'outlined',
      fullWidth: true,
      helperText: 'MM/DD/YYYY',
      size: 'small',
      required: true,
    },
  }}
/>
```

### actionBar slot

```tsx
// Available actions: 'clear' | 'today' | 'cancel' | 'accept'
<DatePicker
  value={value}
  onChange={setValue}
  slotProps={{
    actionBar: {
      actions: ['clear', 'today', 'cancel', 'accept'],
    },
  }}
/>
```

### toolbar slot

```tsx
import { DatePickerToolbar } from '@mui/x-date-pickers/DatePicker';

<DatePicker
  value={value}
  onChange={setValue}
  slots={{
    toolbar: (props) => (
      <DatePickerToolbar
        {...props}
        toolbarFormat="DD MMMM YYYY"
        toolbarPlaceholder="—"
      />
    ),
  }}
/>
```

### day slot (custom day rendering)

```tsx
import { PickersDay, PickersDayProps } from '@mui/x-date-pickers/PickersDay';
import Badge from '@mui/material/Badge';

interface ServerDayProps extends PickersDayProps<Dayjs> {
  highlightedDays?: number[];
}

function ServerDay({ highlightedDays = [], day, outsideCurrentMonth, ...other }: ServerDayProps) {
  const isHighlighted = !outsideCurrentMonth && highlightedDays.includes(day.date());

  return (
    <Badge key={day.toString()} overlap="circular" badgeContent={isHighlighted ? '🔵' : undefined}>
      <PickersDay {...other} outsideCurrentMonth={outsideCurrentMonth} day={day} />
    </Badge>
  );
}

// Usage
<DatePicker
  slots={{ day: ServerDay }}
  slotProps={{ day: { highlightedDays: [1, 5, 10, 15, 20] } as any }}
  value={value}
  onChange={setValue}
/>
```

## Validation

### minDate / maxDate

```tsx
<DatePicker
  label="Future only (max 1 year)"
  minDate={dayjs()}
  maxDate={dayjs().add(1, 'year')}
  value={value}
  onChange={setValue}
/>

// Restrict to a specific year range
<DatePicker
  minDate={dayjs('2000-01-01')}
  maxDate={dayjs('2030-12-31')}
  value={value}
  onChange={setValue}
/>
```

### shouldDisableDate

```tsx
// Disable weekends
<DatePicker
  shouldDisableDate={(day) => day.day() === 0 || day.day() === 6}
  value={value}
  onChange={setValue}
/>

// Disable a list of holiday dates
const holidays = [dayjs('2024-12-25'), dayjs('2024-01-01'), dayjs('2024-07-04')];
<DatePicker
  shouldDisableDate={(day) => holidays.some((h) => h.isSame(day, 'day'))}
  value={value}
  onChange={setValue}
/>

// Combined: no past dates, no weekends
<DatePicker
  shouldDisableDate={(day) => {
    const isWeekend = day.day() === 0 || day.day() === 6;
    const isPast = day.isBefore(dayjs(), 'day');
    return isWeekend || isPast;
  }}
  value={value}
  onChange={setValue}
/>
```

### shouldDisableTime

```tsx
// Business hours only: 8am–6pm
<TimePicker
  shouldDisableTime={(value, view) => {
    if (view === 'hours') return value < 8 || value > 18;
    return false;
  }}
  value={value}
  onChange={setValue}
/>

// Exclude lunch 12–13 and only 15-minute intervals
<TimePicker
  shouldDisableTime={(value, view) => {
    if (view === 'hours') return value === 12 || value === 13;
    if (view === 'minutes') return value % 15 !== 0;
    return false;
  }}
  value={value}
  onChange={setValue}
/>
```

### onError callback

```tsx
const [errorMsg, setErrorMsg] = useState<string | null>(null);

<DatePicker
  value={value}
  onChange={setValue}
  minDate={dayjs('2020-01-01')}
  maxDate={dayjs('2030-12-31')}
  onError={(reason) => {
    const messages: Record<string, string> = {
      minDate: 'Date must be on or after January 1, 2020',
      maxDate: 'Date must be before 2031',
      invalidDate: 'Please enter a valid date',
      disablePast: 'Past dates are not allowed',
      shouldDisableDate: 'This date is unavailable',
    };
    setErrorMsg(reason ? (messages[reason] ?? 'Invalid date') : null);
  }}
  slotProps={{
    textField: {
      error: !!errorMsg,
      helperText: errorMsg,
    },
  }}
/>
```

##

Related in General