Параметр mainCalendar

Поведение календаря при отображении нескольких месяцев одновременно требует механизма определения активного или «основного» календаря. В конфигурации Pikaday этот механизм реализуется через параметр, задающий индекс главного календарного блока внутри группы отображаемых месяцев.

При включённом режиме мульти-месячного отображения (через numberOfMonths) библиотека создаёт несколько календарных панелей, расположенных горизонтально. Каждая панель соответствует отдельному месяцу, а навигация по стрелкам переключает диапазон сразу для всех панелей. Однако взаимодействие пользователя, включая фокус, клавиатурную навигацию и выделение даты, обычно привязывается к одной из этих панелей — основной.

Основной календарь определяет:

  • в какой панели отображается фокус при открытии;
  • куда помещается активная дата при навигации с клавиатуры;
  • какая панель получает первичное событие выделения;
  • как распределяется логика прокрутки при переходе между месяцами.

При значении numberOfMonths: 1 различие между панелями отсутствует, поэтому параметр основного календаря не оказывает видимого эффекта. Его поведение проявляется только при количестве месяцев больше одного.

Индексация и логика выбора панели

Индекс основного календаря задаётся числом, начиная с нуля. Первая панель в списке месяцев имеет индекс 0, вторая — 1 и так далее. При этом логика не зависит от календарного месяца как такового — только от позиции панели в DOM-структуре компонента.

Пример конфигурации:

const picker = new Pikaday({
    numberOfMonths: 3,
    mainCalendar: 1
});

В этом случае центральная логика взаимодействия будет привязана ко второй панели (с индексом 1), даже если отображаются три последовательных месяца.

Такой подход используется в интерфейсах, где центральный месяц должен быть активным по умолчанию, а соседние служат для контекста (например, диапазон выбора дат или планирование событий).

Поведение при открытии календаря

При инициализации виджета происходит установка начального фокуса. Если задан параметр основного календаря, библиотека выполняет следующие шаги:

  • вычисляет DOM-элемент соответствующей панели;
  • устанавливает на неё внутренний фокус навигации;
  • определяет стартовую позицию курсора выбора даты внутри этой панели;
  • синхронизирует отображение выделенного дня с логикой defaultDate, если она задана.

Если параметр не задан, используется поведение по умолчанию — активной считается первая панель (0 индекс).

Взаимодействие с клавиатурной навигацией

Клавиатурная навигация внутри календаря (стрелки, Enter, PageUp/PageDown) опирается на текущий активный календарь. Это особенно важно при мульти-месячной структуре, поскольку переход между месяцами может происходить как внутри одной панели, так и с перескоком между панелями.

При установленном основном календаре:

  • стрелки перемещают выделение внутри активной панели;
  • при выходе за границы месяца возможен переход в соседнюю панель;
  • PageUp/PageDown изменяют месяц относительно всей группы, но фокус возвращается в основной календарь.

Такое поведение предотвращает «размытие» фокуса между несколькими календарями и сохраняет предсказуемую навигацию.

Связь с рендерингом и структурой DOM

При генерации интерфейса Pikaday создаёт контейнер, внутри которого каждая панель месяца представляет собой отдельный блок. Основной календарь не выделяется отдельным классом в стандартной разметке, но логически связан с индексом, который используется при обработке событий.

Типичная структура выглядит следующим образом:

  • контейнер календаря

    • панель месяца 0
    • панель месяца 1
    • панель месяца 2

Индекс основной панели используется внутри логики событий:

  • обработка кликов по датам;
  • определение активного месяца;
  • синхронизация состояния выделения.

Взаимодействие с выбором диапазона дат

При использовании календаря для выбора диапазона (например, start/end date сценарии) основной календарь влияет на начальную точку взаимодействия. Это особенно заметно при следующих условиях:

  • диапазон начинается с даты, находящейся вне центральной панели;
  • пользователь открывает календарь без предварительного выбора;
  • требуется визуальный фокус на середине диапазона.

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

Поведение при смене месяцев

При навигации между месяцами через стрелки:

  • все панели сдвигаются синхронно;
  • индекс основной панели остаётся неизменным;
  • активный фокус пересчитывается относительно новой даты в рамках основной панели.

Если основной календарь установлен в среднюю панель при numberOfMonths: 3, то при переходе на следующий месяц логика сохраняет центрированное поведение, а не смещает фокус к первому или последнему элементу группы.

Влияние на позиционирование и отображение

Хотя параметр основного календаря напрямую не управляет позиционированием всплывающего окна, он косвенно влияет на восприятие расположения, поскольку:

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

Особенно это заметно в интерфейсах с ограниченной шириной, где календарь может частично сдвигаться в зависимости от активной панели.

Сценарии использования

Механизм выбора основной панели применяется в следующих типах интерфейсов:

  • диапазонные селекторы дат (booking, фильтры);
  • финансовые дашборды с несколькими месяцами анализа;
  • планировщики событий с контекстом соседних месяцев;
  • формы с предзаполненным средним периодом.

В каждом случае основной календарь служит точкой фокуса, вокруг которой строится пользовательское взаимодействие.

Согласование с состоянием выбранной даты

Если заранее установлена выбранная дата через defaultDate или setDate, библиотека сопоставляет её с соответствующей панелью. При этом:

  • если дата попадает в основной календарь, фокус остаётся там;
  • если дата вне диапазона основной панели, происходит пересчёт активной области;
  • при множественных месяцах возможен автоматический сдвиг отображения.

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

Поведение при динамическом изменении numberOfMonths

При изменении количества отображаемых месяцев после инициализации:

  • индекс основной панели пересчитывается относительно нового диапазона;
  • если старый индекс выходит за пределы, он нормализуется;
  • активный фокус переходит в ближайшую допустимую панель.

Пример:

  • было: numberOfMonths = 3, mainCalendar = 2
  • стало: numberOfMonths = 2

В этом случае основная панель будет скорректирована до 1, поскольку индекс 2 больше недоступен.

Особенности интеграции с пользовательскими шаблонами

При кастомизации шаблонов рендеринга календаря важно учитывать, что логика основного календаря остаётся внутренней и не всегда отражается в DOM напрямую. Поэтому:

  • нельзя полагаться на CSS-селекторы для определения основной панели;
  • события клика следует интерпретировать через API календаря;
  • стилизация активного месяца должна привязываться к состоянию, а не к порядковому номеру.

В сложных интерфейсах часто добавляют визуальное выделение центральной панели вручную, синхронизируя его с индексом основного календаря через события onDraw или onOpen.

Поведение в сценариях повторного рендера

При повторной отрисовке календаря (например, после изменения диапазона дат):

  • основной календарь остаётся прежним, если индекс валиден;
  • при изменении структуры месяцев происходит перераспределение активного состояния;
  • фокус пересчитывается без потери выбранной даты.

Это обеспечивает стабильность интерфейса при частых обновлениях состояния компонента.