Added EventGroupingHtmlRenderer initial concept
This commit is contained in:
parent
4ff914596b
commit
b719a2c391
27
src/EventGroupingHtmlRenderer/DayRenderer.ts
Normal file
27
src/EventGroupingHtmlRenderer/DayRenderer.ts
Normal file
@ -0,0 +1,27 @@
|
||||
import EventGrouping from "../EventGrouping";
|
||||
import Renderer from "./Renderer";
|
||||
|
||||
export default class DayRenderer extends Renderer {
|
||||
constructor(eventGrouping: EventGrouping) {
|
||||
super(eventGrouping);
|
||||
this.container.className += " scale-day";
|
||||
}
|
||||
|
||||
protected renderDateAsIcon(eventDate, groupIndex): HTMLSpanElement {
|
||||
const html = document.createElement("span");
|
||||
html.className = "event";
|
||||
|
||||
const dayInMonth = eventDate.getDate();
|
||||
|
||||
if (dayInMonth === 1) {
|
||||
html.textContent = eventDate
|
||||
.toLocaleDateString(undefined, { month: "long" })
|
||||
.slice(0, 3);
|
||||
html.className += " primary";
|
||||
} else {
|
||||
html.textContent = dayInMonth.toString();
|
||||
}
|
||||
|
||||
return html;
|
||||
}
|
||||
}
|
||||
32
src/EventGroupingHtmlRenderer/MonthRenderer.ts
Normal file
32
src/EventGroupingHtmlRenderer/MonthRenderer.ts
Normal file
@ -0,0 +1,32 @@
|
||||
import EventGrouping from "../EventGrouping";
|
||||
import Renderer from "./Renderer";
|
||||
|
||||
export default class MonthRenderer extends Renderer {
|
||||
constructor(eventGrouping: EventGrouping) {
|
||||
super(eventGrouping);
|
||||
this.container.className += " scale-month";
|
||||
}
|
||||
|
||||
protected renderDateAsIcon(eventDate, groupIndex): HTMLSpanElement {
|
||||
const html = document.createElement("span");
|
||||
html.className = "event";
|
||||
|
||||
// unlike getDate(), getMonth is 0 based
|
||||
const month = eventDate.getMonth() + 1;
|
||||
|
||||
if (month === 1) {
|
||||
html.textContent = eventDate.toLocaleDateString(undefined, {
|
||||
year: "numeric",
|
||||
});
|
||||
html.className += " primary";
|
||||
} else {
|
||||
html.textContent = eventDate
|
||||
.toLocaleDateString(undefined, {
|
||||
month: "long",
|
||||
})
|
||||
.slice(0, 3);
|
||||
}
|
||||
|
||||
return html;
|
||||
}
|
||||
}
|
||||
101
src/EventGroupingHtmlRenderer/Renderer.ts
Normal file
101
src/EventGroupingHtmlRenderer/Renderer.ts
Normal file
@ -0,0 +1,101 @@
|
||||
import { generateRandomColor } from "../utilities";
|
||||
import EventGrouping from "../EventGrouping";
|
||||
import { Event } from "../types";
|
||||
|
||||
export default abstract class Renderer {
|
||||
protected abstract renderDateAsIcon(
|
||||
eventDate: Date,
|
||||
groupIndex: number
|
||||
): HTMLSpanElement;
|
||||
|
||||
protected container: HTMLDivElement;
|
||||
protected eventGrouping: EventGrouping;
|
||||
|
||||
protected constructor(eventGrouping: EventGrouping) {
|
||||
this.container = document.createElement("div");
|
||||
this.container.className = "event-calendar";
|
||||
this.eventGrouping = eventGrouping;
|
||||
}
|
||||
|
||||
protected renderGroups(): HTMLDivElement[] {
|
||||
return this.eventGrouping.groups.map((group, index) => {
|
||||
const html = document.createElement("div");
|
||||
html.className = "group";
|
||||
|
||||
if (group.length) {
|
||||
const htmlHoverCard = this.renderHoverCard(group);
|
||||
html.appendChild(htmlHoverCard);
|
||||
}
|
||||
|
||||
let htmlGroupIcon: HTMLSpanElement;
|
||||
// only need to render icon from first event in group
|
||||
const event = group[0];
|
||||
|
||||
if (event) {
|
||||
htmlGroupIcon = this.renderIcon(event);
|
||||
html.className += " icon";
|
||||
if (event.bgColor) {
|
||||
html.style.backgroundColor = event.bgColor;
|
||||
} else {
|
||||
const randomColor = generateRandomColor();
|
||||
html.style.backgroundColor = `rgb(${randomColor.r}, ${randomColor.g}, ${randomColor.b})`;
|
||||
}
|
||||
} else {
|
||||
const eventDate = this.eventGrouping.getDateFromGroupIndex(index);
|
||||
htmlGroupIcon = this.renderDateAsIcon(eventDate, index);
|
||||
}
|
||||
|
||||
html.appendChild(htmlGroupIcon);
|
||||
|
||||
return html;
|
||||
});
|
||||
}
|
||||
|
||||
protected renderHoverCard(events: Event[]): HTMLDivElement {
|
||||
const htmlHoverCard = document.createElement("div");
|
||||
htmlHoverCard.className = "hover-card";
|
||||
|
||||
const cardDetails = events.map((event) => {
|
||||
if (!event) {
|
||||
return;
|
||||
}
|
||||
|
||||
const htmlEvent = document.createElement("div");
|
||||
const htmlDateText = document.createElement("p");
|
||||
htmlDateText.textContent = event.date.toLocaleDateString();
|
||||
const htmlEventTitle = document.createElement("p");
|
||||
htmlEventTitle.textContent = event.title;
|
||||
const htmlEventText = document.createElement("p");
|
||||
htmlEventText.textContent = event.text;
|
||||
|
||||
htmlEvent.appendChild(htmlDateText);
|
||||
htmlEvent.appendChild(htmlEventTitle);
|
||||
htmlEvent.appendChild(htmlEventText);
|
||||
|
||||
return htmlEvent;
|
||||
});
|
||||
|
||||
cardDetails.forEach((cardDetail) => htmlHoverCard.appendChild(cardDetail));
|
||||
|
||||
return htmlHoverCard;
|
||||
}
|
||||
|
||||
protected renderIcon(event: Event | undefined): HTMLSpanElement {
|
||||
const html = document.createElement("span");
|
||||
html.className = "event";
|
||||
|
||||
if (event.icon) {
|
||||
html.textContent = event.icon;
|
||||
}
|
||||
|
||||
return html;
|
||||
}
|
||||
|
||||
public render() {
|
||||
const groups = this.renderGroups();
|
||||
|
||||
groups.forEach((group) => this.container.appendChild(group));
|
||||
|
||||
return this.container;
|
||||
}
|
||||
}
|
||||
28
src/EventGroupingHtmlRenderer/WeekRenderer.ts
Normal file
28
src/EventGroupingHtmlRenderer/WeekRenderer.ts
Normal file
@ -0,0 +1,28 @@
|
||||
import { getWeek } from "date-fns";
|
||||
import EventGrouping from "../EventGrouping";
|
||||
import Renderer from "./Renderer";
|
||||
|
||||
export default class WeekRenderer extends Renderer {
|
||||
constructor(eventGrouping: EventGrouping) {
|
||||
super(eventGrouping);
|
||||
this.container.className += " scale-week";
|
||||
}
|
||||
|
||||
protected renderDateAsIcon(eventDate, groupIndex): HTMLSpanElement {
|
||||
const html = document.createElement("span");
|
||||
html.className = "event";
|
||||
|
||||
const week = getWeek(eventDate);
|
||||
|
||||
if (week === 1) {
|
||||
html.textContent = eventDate.toLocaleDateString(undefined, {
|
||||
year: "numeric",
|
||||
});
|
||||
html.className += " primary";
|
||||
} else {
|
||||
html.textContent = week.toString();
|
||||
}
|
||||
|
||||
return html;
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user