Кастомизация календаря

Библиотека MUI предоставляет компонент DatePicker и CalendarPicker для работы с календарными элементами. Их гибкость позволяет настраивать внешний вид, поведение и логику взаимодействия с пользователем. Рассмотрим ключевые аспекты кастомизации.


Основные компоненты

  • DatePicker – компонент для выбора даты с возможностью встроенной валидации и отображения текста в TextField.
  • CalendarPicker – более низкоуровневый компонент, показывающий только календарь без поля ввода. Используется для полной кастомизации визуальной части календаря.
import * as React from 'react';
import TextField from '@mui/material/TextField';
import { LocalizationProvider, DatePicker } from '@mui/x-date-pickers';
import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns';

function BasicDatePicker() {
  const [value, setValue] = React.useState(null);

  return (
    <LocalizationProvider dateAdapter={AdapterDateFns}>
      <DatePicker
        label="Выберите дату"
        value={value}
        onCha nge={(newValue) => setValue(newValue)}
        renderInput={(params) => <TextField {...params} />}
      />
    </LocalizationProvider>
  );
}

Кастомизация внешнего вида

MUI использует систему sx и styled, позволяя изменять стили на любом уровне компонента:

import { styled } from '@mui/material/styles';
import { CalendarPicker } from '@mui/x-date-pickers/CalendarPicker';

const CustomCalendar = styled(CalendarPicker)(({ theme }) => ({
  '& .MuiPickersDay-root': {
    borderRadius: '50%',
    color: theme.palette.primary.main,
  },
  '& .Mui-selected': {
    backgroundColor: theme.palette.secondary.main,
    color: theme.palette.common.white,
  },
  '& .MuiPickersDay-today': {
    border: `2px solid ${theme.palette.error.main}`,
  },
}));
  • .MuiPickersDay-root – базовые ячейки календаря.
  • .Mui-selected – выбранная дата.
  • .MuiPickersDay-today – текущая дата.

С помощью этих селекторов можно полностью изменить визуальный стиль календаря, включая цвета, размеры и формы.


Ограничение диапазона дат

Компоненты MUI поддерживают свойства minDate и maxDate для ограничения выбора дат:

<DatePicker
  label="Выберите дату"
  value={value}
  onCha nge={(newValue) => setValue(newValue)}
  minDate={new Date('2024-01-01')}
  maxDate={new Date('2024-12-31')}
  renderInput={(params) => <TextField {...params} />}
/>

Можно также запретить выбор определённых дней недели с помощью shouldDisableDate:

<DatePicker
  value={value}
  onCha nge={(newValue) => setValue(newValue)}
  shouldDisableDate={(date) => date.getDay() === 0 || date.getDay() === 6} // отключаем выходные
  renderInput={(params) => <TextField {...params} />}
/>

Форматирование отображаемой даты

Свойство inputFormat позволяет задавать формат даты в поле ввода. Используется в связке с адаптером даты (AdapterDateFns, AdapterMoment и др.):

<DatePicker
  label="Дата в формате день/месяц/год"
  value={value}
  onCha nge={(newValue) => setValue(newValue)}
  inputFormat="dd/MM/yyyy"
  renderInput={(params) => <TextField {...params} />}
/>

Локализация календаря

Для отображения дат на разных языках используется Adapter с локализацией:

import { ru } from 'date-fns/locale';

<LocalizationProvider dateAdapter={AdapterDateFns} locale={ru}>
  <DatePicker
    label="Дата на русском"
    value={value}
    onCha nge={(newValue) => setValue(newValue)}
    renderInput={(params) => <TextField {...params} />}
  />
</LocalizationProvider>

Кастомные компоненты внутри календаря

CalendarPicker поддерживает замену некоторых частей компонента через пропсы components и componentsProps:

import ArrowForwardIosIcon from '@mui/icons-material/ArrowForwardIos';
import ArrowBackIosNewIcon from '@mui/icons-material/ArrowBackIosNew';

<CalendarPicker
  date={value}
  onCha nge={(newValue) => setValue(newValue)}
  components={{
    LeftArrowButton: ArrowBackIosNewIcon,
    RightArrowButton: ArrowForwardIosIcon,
  }}
/>

Это позволяет полностью контролировать навигационные элементы, кнопки и другие интерактивные элементы.


Работа с событиями

Календарь поддерживает события выбора даты и изменения месяца:

  • onChange – вызывается при выборе даты.
  • onMonthChange – вызывается при переходе между месяцами.
  • onYearChange – вызывается при изменении года.
<CalendarPicker
  date={value}
  onCha nge={(newValue) => setValue(newValue)}
  onMonthCha nge={(newMonth) => console.log('Сменился месяц:', newMonth)}
/>

Интеграция с формами

DatePicker легко интегрируется с формами через библиотеки react-hook-form или formik:

import { Controller, useForm } from 'react-hook-form';

const { control, handleSubmit } = useForm({
  defaultValues: { date: null },
});

<Controller
  name="date"
  control={control}
  render={({ field }) => (
    <DatePicker
      {...field}
      renderInput={(params) => <TextField {...params} />}
    />
  )}
/>

Это позволяет использовать календарь как полноценное поле формы с валидацией и контролем состояния.


Анимации и переходы

Компоненты MUI поддерживают встроенные анимации Material UI. Для более сложных анимаций можно использовать TransitionComponent:

import Grow from '@mui/material/Grow';

<DatePicker
  value={value}
  onCha nge={(newValue) => setValue(newValue)}
  TransitionComponent={Grow}
  renderInput={(params) => <TextField {...params} />}
/>

Это добавляет плавное появление календаря при открытии.


Резюме возможностей кастомизации

  • Стилизация через sx, styled и CSS-классы.
  • Ограничение диапазона дат и блокировка отдельных дней.
  • Форматирование и локализация отображения дат.
  • Подмена встроенных компонентов и навигационных кнопок.
  • Интеграция с формами и управление событиями выбора.
  • Настройка анимаций и переходов для интерактивных элементов.

Эти инструменты позволяют создавать календарные интерфейсы, полностью соответствующие требованиям дизайна и UX приложения.