diff --git a/src/EventGroupingHtmlRenderer/DayRenderer.ts b/src/EventGroupingHtmlRenderer/DayRenderer.ts
index 2c40bc0..bf1e180 100644
--- a/src/EventGroupingHtmlRenderer/DayRenderer.ts
+++ b/src/EventGroupingHtmlRenderer/DayRenderer.ts
@@ -1,5 +1,7 @@
+import { Event } from "../types";
import { DayGrouping } from "../EventGrouping";
import Renderer from "./Renderer";
+import GroupDayRenderer from "./GroupRenderer/GroupDayRenderer";
export default class DayRenderer extends Renderer {
constructor(eventGrouping: DayGrouping) {
@@ -7,21 +9,11 @@ export default class DayRenderer extends Renderer {
this.container.className += " scale-day";
}
- protected renderDateAsIcon(eventDate, groupIndex): HTMLSpanElement {
- const html = document.createElement("span");
- html.className = "icon";
-
- 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;
+ protected renderGroups(
+ group: Event[],
+ groupDate: Date,
+ groupIndex: number
+ ): HTMLDivElement {
+ return new GroupDayRenderer(group, groupDate, groupIndex).render();
}
}
diff --git a/src/EventGroupingHtmlRenderer/GroupRenderer/GroupDayRenderer.ts b/src/EventGroupingHtmlRenderer/GroupRenderer/GroupDayRenderer.ts
new file mode 100644
index 0000000..8ffe374
--- /dev/null
+++ b/src/EventGroupingHtmlRenderer/GroupRenderer/GroupDayRenderer.ts
@@ -0,0 +1,32 @@
+import { Event } from "../../types";
+import { DayGrouping } from "../../EventGrouping";
+
+import GroupRenderer from "./GroupRenderer";
+
+export default class GroupDayRenderer extends GroupRenderer {
+ constructor(group: Event[], groupDate: Date, groupIndex: number) {
+ super(group, groupDate, groupIndex);
+
+ if (DayGrouping.isToday(groupDate)) {
+ this.highlightGroup();
+ }
+ }
+
+ protected renderDateAsIcon(eventDate, groupIndex): HTMLSpanElement {
+ const html = document.createElement("span");
+ html.className = "icon";
+
+ 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;
+ }
+}
diff --git a/src/EventGroupingHtmlRenderer/GroupRenderer/GroupMonthRenderer.ts b/src/EventGroupingHtmlRenderer/GroupRenderer/GroupMonthRenderer.ts
new file mode 100644
index 0000000..9167211
--- /dev/null
+++ b/src/EventGroupingHtmlRenderer/GroupRenderer/GroupMonthRenderer.ts
@@ -0,0 +1,37 @@
+import { Event } from "../../types";
+import { MonthGrouping } from "../../EventGrouping";
+
+import GroupRenderer from "./GroupRenderer";
+
+export default class GroupMonthRenderer extends GroupRenderer {
+ constructor(group: Event[], groupDate: Date, groupIndex: number) {
+ super(group, groupDate, groupIndex);
+
+ if (MonthGrouping.isThisMonth(groupDate)) {
+ this.highlightGroup();
+ }
+ }
+
+ protected renderDateAsIcon(eventDate, groupIndex): HTMLSpanElement {
+ const html = document.createElement("span");
+ html.className = "icon";
+
+ // 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;
+ }
+}
diff --git a/src/EventGroupingHtmlRenderer/GroupRenderer/GroupRenderer.ts b/src/EventGroupingHtmlRenderer/GroupRenderer/GroupRenderer.ts
new file mode 100644
index 0000000..cda8360
--- /dev/null
+++ b/src/EventGroupingHtmlRenderer/GroupRenderer/GroupRenderer.ts
@@ -0,0 +1,108 @@
+import { Event } from "../../types";
+import { generateRandomColor } from "../../utilities";
+import { format } from "date-fns";
+
+export default abstract class GroupRenderer {
+ protected container: HTMLDivElement;
+ protected group: Event[];
+ protected groupDate: Date;
+ protected groupIndex: number;
+
+ protected abstract renderDateAsIcon(
+ eventDate: Date,
+ groupIndex: number
+ ): HTMLSpanElement;
+
+ constructor(group: Event[], groupDate: Date, groupIndex: number) {
+ this.container = document.createElement("div");
+ this.container.className = "group";
+ this.group = group;
+ this.groupDate = groupDate;
+ this.groupIndex = groupIndex;
+ }
+
+ highlightGroup(): void {
+ this.container.className += " highlight";
+ }
+
+ render(): HTMLDivElement {
+ if (this.group.length) {
+ const htmlHoverCard = this.renderHoverCard(this.group);
+ this.container.appendChild(htmlHoverCard);
+ }
+
+ let htmlGroupIcon: HTMLSpanElement;
+ // only need to render icon from first event in group
+ const event = this.group[0];
+
+ if (event) {
+ htmlGroupIcon = this.renderIcon(event);
+ this.container.className += " icon";
+ if (event.bgColor) {
+ this.container.style.backgroundColor = event.bgColor;
+ } else {
+ const randomColor = generateRandomColor();
+ this.container.style.backgroundColor = `rgb(${randomColor.r}, ${randomColor.g}, ${randomColor.b})`;
+ }
+ } else {
+ htmlGroupIcon = this.renderDateAsIcon(this.groupDate, this.groupIndex);
+ }
+
+ this.container.appendChild(htmlGroupIcon);
+
+ return this.container;
+ }
+
+ renderIcon(event: Event | undefined): HTMLSpanElement {
+ const html = document.createElement("span");
+ html.className = "event";
+
+ if (event.icon) {
+ html.textContent = event.icon;
+ }
+
+ return html;
+ }
+
+ renderHoverCard(events: Event[]): HTMLDivElement {
+ const html = document.createElement("div");
+ html.className = "hover-card";
+
+ const htmlMonthYear = document.createElement("p");
+ htmlMonthYear.className = "month-year";
+ htmlMonthYear.textContent = events[0].date.toLocaleDateString(undefined, {
+ year: "numeric",
+ month: "long",
+ });
+
+ html.appendChild(htmlMonthYear);
+
+ const cardDetails = events.map((event) => {
+ if (!event) {
+ return;
+ }
+
+ const htmlEvent = document.createElement("div");
+ htmlEvent.className = "event";
+ const htmlEventDate = document.createElement("p");
+ htmlEventDate.className = "date";
+ htmlEventDate.textContent = format(event.date, "EEEE do");
+ const htmlEventTitle = document.createElement("p");
+ htmlEventTitle.className = "title";
+ htmlEventTitle.textContent = event.title;
+ const htmlEventText = document.createElement("p");
+ htmlEventText.className = "text";
+ htmlEventText.textContent = event.text;
+
+ htmlEvent.appendChild(htmlEventDate);
+ htmlEvent.appendChild(htmlEventTitle);
+ htmlEvent.appendChild(htmlEventText);
+
+ return htmlEvent;
+ });
+
+ cardDetails.forEach((cardDetail) => html.appendChild(cardDetail));
+
+ return html;
+ }
+}
diff --git a/src/EventGroupingHtmlRenderer/GroupRenderer/GroupWeekRenderer.ts b/src/EventGroupingHtmlRenderer/GroupRenderer/GroupWeekRenderer.ts
new file mode 100644
index 0000000..523890f
--- /dev/null
+++ b/src/EventGroupingHtmlRenderer/GroupRenderer/GroupWeekRenderer.ts
@@ -0,0 +1,36 @@
+import { Event } from "../../types";
+import { WeekGrouping } from "../../EventGrouping";
+
+import GroupRenderer from "./GroupRenderer";
+
+export default class GroupWeekRenderer extends GroupRenderer {
+ constructor(group: Event[], groupDate: Date, groupIndex: number) {
+ super(group, groupDate, groupIndex);
+
+ if (WeekGrouping.isThisWeek(groupDate)) {
+ this.highlightGroup();
+ }
+ }
+
+ protected renderDateAsIcon(eventDate, groupIndex): HTMLSpanElement {
+ const html = document.createElement("span");
+ html.className = "icon";
+
+ const week = WeekGrouping.getWeek(eventDate);
+
+ if (week === 1) {
+ html.textContent = eventDate.toLocaleDateString(undefined, {
+ year: "numeric",
+ });
+ html.className += " primary";
+ } else {
+ html.textContent = week.toString();
+ }
+
+ if (WeekGrouping.isThisWeek(eventDate)) {
+ html.className += " highlighted";
+ }
+
+ return html;
+ }
+}
diff --git a/src/EventGroupingHtmlRenderer/MonthRenderer.ts b/src/EventGroupingHtmlRenderer/MonthRenderer.ts
index cc89ec0..6af3334 100644
--- a/src/EventGroupingHtmlRenderer/MonthRenderer.ts
+++ b/src/EventGroupingHtmlRenderer/MonthRenderer.ts
@@ -1,5 +1,7 @@
+import { Event } from "../types";
import { MonthGrouping } from "../EventGrouping";
import Renderer from "./Renderer";
+import GroupMonthRenderer from "./GroupRenderer/GroupMonthRenderer";
export default class MonthRenderer extends Renderer {
constructor(eventGrouping: MonthGrouping) {
@@ -7,26 +9,13 @@ export default class MonthRenderer extends Renderer {
this.container.className += " scale-month";
}
- protected renderDateAsIcon(eventDate, groupIndex): HTMLSpanElement {
- const html = document.createElement("span");
- html.className = "icon";
+ protected renderGroups(
+ group: Event[],
+ groupDate: Date,
+ groupIndex: number
+ ): HTMLDivElement {
+ const monthGroup = new GroupMonthRenderer(group, groupDate, groupIndex);
- // 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;
+ return monthGroup.render();
}
}
diff --git a/src/EventGroupingHtmlRenderer/Renderer.ts b/src/EventGroupingHtmlRenderer/Renderer.ts
index 0fdb0a7..dfc6a69 100644
--- a/src/EventGroupingHtmlRenderer/Renderer.ts
+++ b/src/EventGroupingHtmlRenderer/Renderer.ts
@@ -1,13 +1,12 @@
-import { format } from "date-fns";
-import { generateRandomColor } from "../utilities";
import EventGrouping from "../EventGrouping/EventGrouping";
import { Event } from "../types";
export default abstract class Renderer {
- protected abstract renderDateAsIcon(
- eventDate: Date,
+ protected abstract renderGroups(
+ group: Event[],
+ groupDate: Date,
groupIndex: number
- ): HTMLSpanElement;
+ ): HTMLDivElement;
protected container: HTMLDivElement;
protected eventGrouping: EventGrouping;
@@ -18,95 +17,16 @@ export default abstract class Renderer {
this.eventGrouping = eventGrouping;
}
- protected renderGroups(): HTMLDivElement[] {
- return this.eventGrouping.groups.map((group, index) => {
- const html = document.createElement("div");
- html.className = "group";
+ protected _renderGroups(): HTMLDivElement[] {
+ return this.eventGrouping.groups.map((group: Event[], index: number) => {
+ const groupDate = this.eventGrouping.getDateFromGroupIndex(index);
- 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;
+ return this.renderGroups(group, groupDate, index);
});
}
- protected renderHoverCard(events: Event[]): HTMLDivElement {
- const html = document.createElement("div");
- html.className = "hover-card";
-
- const htmlMonthYear = document.createElement("p");
- htmlMonthYear.className = "month-year";
- htmlMonthYear.textContent = events[0].date.toLocaleDateString(undefined, {
- year: "numeric",
- month: "long",
- });
-
- html.appendChild(htmlMonthYear);
-
- const cardDetails = events.map((event) => {
- if (!event) {
- return;
- }
-
- const htmlEvent = document.createElement("div");
- htmlEvent.className = "event";
- const htmlEventDate = document.createElement("p");
- htmlEventDate.className = "date";
- htmlEventDate.textContent = format(event.date, "EEEE do");
- const htmlEventTitle = document.createElement("p");
- htmlEventTitle.className = "title";
- htmlEventTitle.textContent = event.title;
- const htmlEventText = document.createElement("p");
- htmlEventText.className = "text";
- htmlEventText.textContent = event.text;
-
- htmlEvent.appendChild(htmlEventDate);
- htmlEvent.appendChild(htmlEventTitle);
- htmlEvent.appendChild(htmlEventText);
-
- return htmlEvent;
- });
-
- cardDetails.forEach((cardDetail) => html.appendChild(cardDetail));
-
- return html;
- }
-
- 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(): HTMLDivElement {
- const groups = this.renderGroups();
+ const groups = this._renderGroups();
groups.forEach((group) => this.container.appendChild(group));
diff --git a/src/EventGroupingHtmlRenderer/WeekRenderer.ts b/src/EventGroupingHtmlRenderer/WeekRenderer.ts
index 3c7da81..ddae6c5 100644
--- a/src/EventGroupingHtmlRenderer/WeekRenderer.ts
+++ b/src/EventGroupingHtmlRenderer/WeekRenderer.ts
@@ -1,7 +1,7 @@
-import { getWeek } from "date-fns";
-
+import { Event } from "../types";
import { WeekGrouping } from "../EventGrouping";
import Renderer from "./Renderer";
+import GroupWeekRenderer from "./GroupRenderer/GroupWeekRenderer";
export default class WeekRenderer extends Renderer {
constructor(eventGrouping: WeekGrouping) {
@@ -9,21 +9,11 @@ export default class WeekRenderer extends Renderer {
this.container.className += " scale-week";
}
- protected renderDateAsIcon(eventDate, groupIndex): HTMLSpanElement {
- const html = document.createElement("span");
- html.className = "icon";
-
- const week = getWeek(eventDate);
-
- if (week === 1) {
- html.textContent = eventDate.toLocaleDateString(undefined, {
- year: "numeric",
- });
- html.className += " primary";
- } else {
- html.textContent = week.toString();
- }
-
- return html;
+ protected renderGroups(
+ group: Event[],
+ groupDate: Date,
+ groupIndex: number
+ ): HTMLDivElement {
+ return new GroupWeekRenderer(group, groupDate, groupIndex).render();
}
}
diff --git a/src/event-calendar.css b/src/event-calendar.css
index f5dda4b..1acc8c2 100644
--- a/src/event-calendar.css
+++ b/src/event-calendar.css
@@ -8,13 +8,17 @@
width: 36px;
height: 26px;
margin: 0 4px 4px 0;
- border-top: 10px solid rgba(255, 140, 140, 0.5);
+ border-top: 10px solid rgba(255, 140, 140, 1);
border-right: 1px solid rgba(20, 20, 20, 0.7);
border-bottom: 1px solid rgba(20, 20, 20, 0.7);
border-left: 1px solid rgba(20, 20, 20, 0.2);
border-radius: 4px;
}
+.event-calendar .group.highlight {
+ border-top: 10px solid rgba(255, 223, 65, 1);
+}
+
.event-calendar .group .icon {
font-size: 15px;
text-align: center;