Календарь событий

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

Инициализация сетки

Для начала необходимо создать HTML-контейнер, в котором будут располагаться события. Каждое событие представлено отдельной карточкой:

<div id="calendar-grid">
  <div class="event-item" data-date="2026-03-11" data-category="work">Совещание команды</div>
  <div class="event-item" data-date="2026-03-12" data-category="personal">Встреча с другом</div>
  <div class="event-item" data-date="2026-03-15" data-category="work">Презентация проекта</div>
</div>

Подключение Muuri и инициализация сетки осуществляется следующим образом:

const grid = new Muuri('#calendar-grid', {
  dragEnabled: true,
  layout: {
    rounding: false
  }
});
  • dragEnabled: true — позволяет перетаскивать карточки событий между позициями.
  • layout.rounding: false — отключает округление координат для более точного позиционирования, что важно при отображении времени и дат.

Сортировка событий

Для календаря сортировка событий по дате является ключевой функциональностью. Muuri поддерживает кастомные функции сортировки:

grid.sort((a, b) => {
  const dateA = new Date(a.getElement().dataset.date);
  const dateB = new Date(b.getElement().dataset.date);
  return dateA - dateB;
});

Особенности сортировки:

  • Можно использовать любые поля данных карточки (data-date, data-category) для динамического упорядочивания.
  • Muuri поддерживает повторное применение сортировки после добавления новых элементов, что позволяет календарю оставаться актуальным при динамическом обновлении событий.

Фильтрация по категориям

Фильтрация позволяет показывать только определённые типы событий. Например, рабочие или личные:

function filterByCategory(category) {
  grid.filter(item => {
    return item.getElement().dataset.category === category || category === 'all';
  });
}

// Пример вызова:
filterByCategory('work'); // Показывает только рабочие события

Важные моменты фильтрации:

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

Динамическое добавление и удаление событий

Muuri обеспечивает удобный API для работы с элементами, добавляемыми в реальном времени:

// Добавление нового события
const newItem = document.createElement('div');
newItem.className = 'event-item';
newItem.dataset.date = '2026-03-20';
newItem.dataset.category = 'personal';
newItem.textContent = 'Йога-класс';

grid.add(newItem);

// Удаление события
const itemToRemove = grid.getItems().find(item => item.getElement().dataset.date === '2026-03-12');
grid.remove(itemToRemove, { removeElements: true });
  • removeElements: true гарантирует, что элемент будет удалён из DOM вместе с сеткой.
  • При добавлении элементов сетка автоматически перераспределяет карточки с анимацией, что обеспечивает плавный пользовательский опыт.

Анимация и реакция на изменение размеров

Muuri умеет адаптироваться к изменениям размеров контейнера или карточек:

window.addEventListener('resize', () => {
  grid.refreshItems().layout();
});
  • refreshItems() обновляет внутренние данные о позициях всех элементов.
  • layout() инициирует анимацию перемещения элементов в новые позиции.

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

Настройка внешнего вида и взаимодействия

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

.event-item {
  padding: 12px;
  margin: 8px;
  background-color: #f0f0f0;
  border-radius: 8px;
  cursor: grab;
  transition: transform 0.3s ease, box-shadow 0.3s ease;
}

.event-item[data-category="work"] {
  background-color: #cce5ff;
}

.event-item[data-category="personal"] {
  background-color: #d4edda;
}

.event-item.muuri-item-dragging {
  z-index: 999;
  cursor: grabbing;
  box-shadow: 0 8px 16px rgba(0,0,0,0.3);
}
  • Класс .muuri-item-dragging используется библиотекой Muuri автоматически при перетаскивании, что позволяет добавлять визуальные эффекты.
  • Можно применять разные цвета, тени и размеры для визуальной дифференциации типов событий.

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

Muuri легко сочетается с календарными библиотеками или собственными интерфейсами для отображения дат:

  • Использование data-date как ключевого атрибута позволяет синхронизировать события с внешним календарем (например, день недели или месяц).
  • Динамическая фильтрация по диапазону дат позволяет реализовать отображение событий за текущую неделю или месяц.

События сетки Muuri

Muuri предоставляет события для отслеживания действий пользователя:

grid.on('dragEnd', (item) => {
  console.log('Событие перемещено:', item.getElement().textContent);
});

grid.on('layoutEnd', () => {
  console.log('Сетка обновлена');
});
  • dragEnd позволяет синхронизировать изменения с сервером или локальным хранилищем.
  • layoutEnd полезно для выполнения действий после завершения анимации, например, обновления индикаторов времени или подсветки событий.

Вывод

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

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

Такой подход создаёт интерактивный, адаптивный и визуально привлекательный календарь событий, который легко масштабируется и поддерживается в реальном времени.