Os calendários se tornaram uma parte indispensável das aplicações web modernas, pois permitem que os usuários organizem, programem e acompanhem eventos de forma fluida. Se você está construindo uma ferramenta de gerenciamento de projetos, um aplicativo de agendamento de eventos ou uma suíte de produtividade pessoal, um componente de calendário personalizado pode melhorar muito a experiência do usuário. Embora existam várias bibliotecas de calendário pré-construídas, criar seu próprio componente pode oferecer a flexibilidade para atender a requisitos específicos de design e funcionalidade.
Neste tutorial, exploraremos como construir um componente semelhante ao Google Calendar usando JavaScript. Ao final deste guia, você terá um calendário totalmente funcional com recursos interativos e uma compreensão mais profunda de como construir componentes reutilizáveis para suas aplicações web. Quer você seja um desenvolvedor buscando adicionar um toque único ao seu projeto ou alguém ansioso para aprender o funcionamento interno das funcionalidades de calendário, este passo a passo será inestimável. Vamos começar!
Visão Geral
Vamos criar um componente de calendário com os seguintes recursos:
- Eixo do Tempo: Uma linha do tempo vertical de 12h à 23h.
- Blocos de Evento: Eventos renderizados dinamicamente com posicionamento e altura adequados com base em seus horários de início e fim.
- Tratamento de Sobreposição: Eventos que se sobrepõem no tempo aparecerão lado a lado.
Aqui está como você pode criar este componente passo a passo.
Guia Passo a Passo
1. Configurar o HTML e Estilos Básicos
Começamos criando uma estrutura HTML mínima para o calendário. O layout inclui uma linha do tempo e um contêiner para os eventos.
<div class="calendar">
<div class="calendar-time">
<ul id="timelist" class="calendar-timelist"></ul>
</div>
<div id="events" class="calendar-events"></div>
</div>
Adicione CSS básico para estilizar o calendário:
.calendar {
display: flex;
width: 500px;
margin: 20px auto;
position: relative;
}
.event {
background: #039be5;
border: 1px solid white;
border-radius: 5px;
position: absolute;
box-sizing: border-box;
color: white;
overflow: hidden;
padding: 3px;
}
.calendar-time {
border-right: 1px solid #ccc;
width: 100px;
}
.calendar-timelist {
list-style: none;
padding: 0;
margin: 0;
text-align: right;
padding-right: 20px;
}
.calendar-timelist li {
height: 60px;
box-sizing: border-box;
width: 100%;
}
.calendar-events {
flex-grow: 1;
position: relative;
}
2. Criar a Classe JavaScript para o Calendário
Defina uma classe Calendário
para encapsular toda a funcionalidade.
Construtor
O construtor inicializa o calendário renderizando a linha do tempo e os eventos:
class Calendar {
constructor(data) {
// Render the timeline on the Y-axis
this.renderTime();
// Render the event blocks
this.renderEvents(data);
}
renderTime() {
let timeHTML = Array.from({ length: 24 }, (_, i) => `<li>${this.to12HourFormat(i)}</li>`).join("");
document.getElementById("timelist").innerHTML = timeHTML;
}
renderEvents(data) {
let groupedEvents = this.groupEvents(data);
let eventData = this.calculateEventStyles(groupedEvents);
let eventHTML = eventData
.map(
(e) =>
`<div class="event" style="top: ${e.top}px; height: ${e.height}px; width: ${e.width}%; left: ${e.left}%; z-index: ${e.zIndex};">
<strong>${e.title}</strong><br>${e.time}
</div>`
)
.join("");
document.getElementById("events").innerHTML = eventHTML;
}
to12HourFormat(hour) {
if (hour === 0) return "12 AM";
if (hour < 12) return `${hour} AM`;
if (hour === 12) return "12 PM";
return `${hour - 12} PM`;
}
}
3. Lidar com Sobreposições e Posicionamento de Eventos
Precisamos de lógica para lidar com eventos sobrepostos. Isso é alcançado agrupando e calculando posições apropriadas.
Agrupar Eventos por Hora de Início
groupEvents(data) {
let groups = [];
data.forEach((event) => {
let hour = parseInt(event.start.split(":")[0], 10);
if (!groups[hour]) groups[hour] = [];
groups[hour].push(event);
});
return groups;
}
Calcular Estilos de Eventos
Para cada grupo, calcule o top
, height
, width
e left
do evento com base no tempo e sobreposição.
calculateEventStyles(groups) {
let eventData = [];
groups.forEach((group) => {
let columns = [];
group.forEach((event) => {
let { start, end } = event;
let [sh, sm] = start.split(":").map(Number);
let [eh, em] = end.split(":").map(Number);
let top = sh * 60 + sm; // Convert start time to minutes
let height = (eh * 60 + em) - top; // Calculate duration in minutes
let left = columns.findIndex((col) => col.end <= start);
if (left === -1) {
left = columns.length;
columns.push({ end });
} else {
columns[left].end = end;
}
eventData.push({
title: event.name,
time: `${this.to12HourFormat(sh)} - ${this.to12HourFormat(eh)}`,
top,
height,
left: (left * 100) / columns.length,
width: 100 / columns.length,
zIndex: left,
});
});
});
return eventData;
}
4. Exemplo de Dados e Inicialização
Defina seus dados de evento e inicialize o Calendário
:
const events = [
{ name: "Meeting with Donna", start: "09:00", end: "10:30" },
{ name: "Project Sync", start: "10:00", end: "11:00" },
{ name: "Lunch Break", start: "12:00", end: "13:00" },
{ name: "Client Call", start: "11:30", end: "12:30" },
];
new Calendar(events);
5. Exemplo de Código Completo
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="styles.css">
<title>Calendar Component</title>
</head>
<body>
<div class="calendar">
<div class="calendar-time">
<ul id="timelist" class="calendar-timelist"></ul>
</div>
<div id="events" class="calendar-events"></div>
</div>
<script src="script.js"></script>
</body>
</html>
Conclusão
Esta abordagem utiliza JavaScript puro para gerar dinamicamente um componente semelhante ao Google Calendar. Ao dividir o problema em renderização de tempo, agrupamento de eventos e cálculo de estilos, é possível construir componentes escaláveis e interativos. Você pode experimentar o código para adicionar recursos como eventos arrastáveis ou estilos adicionais!
Source:
https://dzone.com/articles/building-a-google-calendar-like-component-using-javascript