Vanilla Calendar Pro: календарь выбора даты с примерами
Бесплатная мастерская Vanilla Calendar Pro без регистрации: обычный выбор даты, период, несколько дней, дата со временем и готовые сценарии. Настройте язык, ограничения и оформление, проверьте результат в браузере и скачайте исходный проект. Разбираем подключение к HTML, React и Vue, неполный диапазон, недоступные дни и часовые пояса.
Выбор даты нужен в заявке на консультацию, фильтре отчёта, форме бронирования и расписании. В одном случае достаточно одного дня, в другом нужен период, а в третьем — дата вместе со временем. Vanilla Calendar Pro позволяет собрать эти варианты на одном компоненте и использовать его в обычной HTML-странице, React, Vue или другом интерфейсе.
Ниже работает бесплатная мастерская календаря без регистрации: переключайте примеры, выбирайте даты, меняйте ограничения и оформление, затем забирайте код и исходный проект. Настройки и выбор обрабатываются в браузере. Это демонстрация компонента; реальные заявки, запись клиентов и серверное бронирование здесь не создаются.
Соберите календарь для своего интерфейса
Попробуйте выбор даты, диапазона или времени. Настройте язык, оформление и ограничения, затем заберите код своего примера.
Без регистрации
Календарь — Vanilla Calendar Pro, Юрий Уваров и участники проекта. Мастерская и пояснения — ae-nekrasov.ru. Настройки и выбранные даты обрабатываются в браузере.
Что такое Vanilla Calendar Pro и где он пригодится
Vanilla Calendar Pro — компонент выбора даты и времени на TypeScript без зависимости от конкретного фреймворка. Он управляет собственными DOM-элементами, а ваше приложение получает выбранные значения через обработчики. Библиотека распространяется по лицензии MIT; уведомления об авторстве и лицензии следует сохранять при распространении её кода.
Для простой формы сначала рассмотрите стандартный <input type="date">. Кастомный календарь полезен, когда требуется единый внешний вид, несколько выбранных дат, диапазон, ограничения доступности или календарь прямо внутри страницы. В таком случае компонент помогает организовать выбор, а правила конкретного сервиса вы задаёте сами.
В мастерской и примерах зафиксирована версия 3.4.0. В ней дополнительные возможности подключаются расширениями: например, время — через time, несколько месяцев — через months. Это особенно важно при переносе примеров из старых публикаций. Изменения и переход на 3.4.0.
Как пользоваться мастерской на этой странице
В верхней части панели есть семь сценариев: «Одна дата», «Диапазон», «Несколько дат», «Дата и время», «Поле формы», «Рабочие дни» и «Два месяца». Начните с подходящего примера, затем измените язык, начало недели и тему. Результат выбора находится рядом с календарём: так удобно проверять, какие данные получит ваше приложение.
Ограничения добавляйте по одному. Например, сначала задайте минимальную дату, затем исключите выходные и одну конкретную дату. Проверьте как доступный день, так и заблокированный. Для диапазона посмотрите, что происходит до выбора второй границы и при попытке пройти через недоступные дни.
После настройки скопируйте пример подключения. Исходный проект пригодится для самостоятельного запуска и дальнейших изменений. Экспорт настроек помогает сохранить выбранный вариант; он не создаёт расписание сотрудников и не синхронизирует доступность с другим календарём.
Первый пример: русский календарь и выбранная дата
Следующий пример рассчитан на проект с TypeScript и сборщиком, например Vite. Установите закреплённую версию пакета:
npm install vanilla-calendar-pro@3.4.0
Добавьте контейнер и место для результата в HTML:
<div id="appointment-calendar"></div>
<p id="appointment-date" aria-live="polite">Дата не выбрана</p>
В модуле TypeScript подключите календарь и основные стили:
import { Calendar } from "vanilla-calendar-pro";
import "vanilla-calendar-pro/styles/core.css";
const output = document.querySelector("#appointment-date");
if (!(output instanceof HTMLElement)) {
throw new Error("Не найден элемент для результата");
}
const calendar = new Calendar("#appointment-calendar", {
locale: "ru",
firstWeekday: 1,
selectionDatesMode: "single",
onClickDate(self) {
output.textContent = self.context.selectedDates[0]
?? "Дата не выбрана";
},
});
calendar.init();
locale: "ru" задаёт русские названия, а firstWeekday: 1 начинает неделю с понедельника. Значение в обработчике берётся из self.context.selectedDates. Даже при выборе одного дня библиотека возвращает массив: пустой результат нужно учитывать. Подключите этот модуль после появления контейнеров в документе. Официальное описание локализации.
Диапазон и несколько отдельных дат — разные задачи
Период подходит для отчёта «с 12 по 18 число». Несколько отдельных дат — для занятий по выбранным дням, например 12, 15 и 18 числа. Не подменяйте одно другим: три занятия не должны превращаться в непрерывную неделю.
Для периода создайте контейнер <div id="report-calendar"></div> и календарь с режимом multiple-ranged. Здесь добавлено ограничение на учебный месяц:
import { Calendar } from "vanilla-calendar-pro";
import "vanilla-calendar-pro/styles/core.css";
const reportCalendar = new Calendar("#report-calendar", {
locale: "ru",
firstWeekday: 1,
selectionDatesMode: "multiple-ranged",
enableEdgeDatesOnly: true,
enableDateToggle: false,
dateMin: "2026-11-01",
dateMax: "2026-11-30",
});
reportCalendar.init();
Для отдельных дней используйте режим multiple. В приведённом примере enableEdgeDatesOnly: true оставляет в context.selectedDates только границы периода. Пустой массив означает отсутствие выбора, одна дата — ожидание конца, две — обе выбранные границы. Настройка enableDateToggle: false позволяет вторым нажатием на тот же день получить однодневный период с двумя одинаковыми границами. Показывайте подсказку «выберите конец периода» до завершения и не считайте продолжительность по длине массива.
Заранее решите, включается ли конечная дата. В отчёте период обычно включает оба дня. В бронировании дата выезда может не считаться занятой ночью. Подпись около результата должна объяснять именно правило вашего сервиса.
Дата и время: пример записи на встречу
Для выбора времени в ESM-проекте нужны расширение time, его регистрация и стили. Пример ниже использует контейнер <div id="meeting-calendar"></div> и результат <p id="meeting-result" aria-live="polite"></p>.
import { Calendar, time } from "vanilla-calendar-pro";
import "vanilla-calendar-pro/styles/core.css";
import "vanilla-calendar-pro/styles/time.css";
const result = document.querySelector("#meeting-result");
if (!(result instanceof HTMLElement)) {
throw new Error("Не найден результат встречи");
}
function showMeeting(self: Calendar, isError = false) {
const output = result;
if (!(output instanceof HTMLElement)) return;
if (isError) {
output.textContent = "Проверьте введённое время";
return;
}
const date = self.context.selectedDates[0];
output.textContent = date
? `${date} · ${self.context.selectedTime}`
: "Выберите дату встречи";
}
const meetingCalendar = new Calendar("#meeting-calendar", {
extensions: [time],
locale: "ru",
firstWeekday: 1,
selectionDatesMode: "single",
selectionTimeMode: 24,
selectedTime: "10:00",
timeStepMinute: 15,
onInit(self) { showMeeting(self); },
onClickDate(self) { showMeeting(self); },
onChangeTime(self, _event, isError) {
showMeeting(self, isError);
},
});
meetingCalendar.init();
Шаг минут делает управление удобнее, но бизнес-правило «запись только каждые 15 минут» проверяйте отдельно, включая ручной ввод. Свободные часы для выбранного дня должны поступать из вашей системы записи. Сам календарь не знает о перерывах, занятости специалиста и параллельных заявках. Подключение времени, обработчики изменения.
Недоступные дни, границы и проверка заявки
Настройки dateMin и dateMax ограничивают даты выбора. disableWeekdays: [0, 6] исключает воскресенье и субботу; disableDates: ["2026-11-04"] блокирует отдельный день. Это иллюстративные ограничения, а не готовый производственный календарь праздников.
Для непрерывного периода проверяйте все включённые дни, а не только начало и конец. Например, свободные понедельник и пятница не означают, что между ними доступна среда. Если ваши правила запрещают такой период, покажите причину возле результата и не разрешайте отправку до исправления.
Окончательную проверку выполняет сервер при отправке заявки: допустимость дат, время, часовой пояс и актуальная доступность. Между открытием формы и отправкой другой человек мог занять тот же слот. Интерфейс должен сохранить введённые данные, объяснить конфликт и предложить новый выбор. Ограничения отдельных дней.
Календарная дата, время и часовой пояс
Строка 2026-11-12 — календарный день. Для отчёта её обычно достаточно хранить как дату без часового пояса. Значение 10:00 — время на часах; само по себе оно не определяет момент встречи. Для записи укажите, например, «10:00, время Москвы», а в данных сохраните выбранную дату, время и зону Europe/Moscow.
Не превращайте дату без времени в UTC-метку просто ради форматирования: new Date("2026-11-12") трактует такую строку как UTC, и вывод в другой зоне может показать предыдущий день. Для календарных дат используйте подход, который сохраняет день; для реального момента встречи выполняйте осмысленное преобразование с известной зоной. Различие строк даты и даты со временем у MDN.
Подключение к React, Vue и жизненному циклу страницы
В обычной странице создайте экземпляр после появления контейнера. В React используйте DOM-ссылку и создавайте календарь внутри эффекта, а при очистке эффекта вызывайте calendar.destroy(). В Vue создавайте его в onMounted и удаляйте в onBeforeUnmount. Фреймворк управляет внешним контейнером, библиотека — его содержимым.
Не создавайте новый экземпляр при каждом рендере компонента. Для изменения настроек есть set() и update(); при обновлении учитывайте, нужно ли сохранять уже выбранные пользователем значения. Расширения регистрируются при создании и не добавляются через последующее изменение настроек. Если экземпляр больше не нужен, destroy() завершает его работу. Методы экземпляра, пример интеграции с Vue.
В приложении с серверным рендерингом запускайте DOM-календарь на клиенте. Выбранные значения передавайте в состояние приложения через обработчики; не считывайте их из случайных элементов отрисованной сетки.
Тема, мобильная версия и понятное управление
Выбирайте тему под реальный фон формы и проверяйте контраст выбранных, доступных и заблокированных дней. Не различайте состояния только цветом: подпись результата и доступные названия элементов помогают понять выбор. Размер текста и кнопок должен оставаться удобным на телефоне.
Два месяца рядом удобны для длинного периода, но на узком экране лучше показать один месяц или расположить их вертикально. Для нескольких месяцев в 3.4.0 подключается расширение months и его стили; режим задаётся параметрами type: "multiple" и displayMonthsCount: 2. Проверьте переход между месяцами, выбор с клавиатуры и возврат фокуса после закрытия календаря у поля.
Один язык календарной сетки не переводит все подсказки вашего приложения. Подписи полей, сообщения о неполном периоде, ошибки и обозначение часового пояса оформляйте согласованно.
Что проверить перед использованием в своём проекте
Пройдите обычный сценарий и граничные случаи: пустой выбор, один день, смена месяца и года, неполный период, недоступный день внутри диапазона, ручное изменение времени и сброс. Затем повторите работу на телефоне и клавиатурой. Пользователь должен понимать текущий результат и причину запрета без чтения документации библиотеки.
Сохраните версии зависимостей в проекте и lock-файл, а обновление сначала проверяйте отдельно. В скачиваемом примере есть рабочая основа мастерской и инструкция запуска. Настройте форму под собственные правила, соедините её с серверной проверкой и только после этого используйте для настоящей записи. Официальная документация Vanilla Calendar Pro поможет расширить календарь дополнительными возможностями.

