diff --git a/source/app.tsx b/source/app.tsx index a46508c..2807755 100644 --- a/source/app.tsx +++ b/source/app.tsx @@ -1,11 +1,16 @@ -// Third-party imports. import {Component} from "preact"; +import {BigDate, Calendar} from "./components/exports.js"; +import {DateWrapper} from "./date/date.js"; export class App extends Component { render() { + const today = new DateWrapper(new Date()); + return ( <>

Today is:

+ + ); } diff --git a/source/components/calendar.tsx b/source/components/calendar.tsx new file mode 100644 index 0000000..6bae9b2 --- /dev/null +++ b/source/components/calendar.tsx @@ -0,0 +1,82 @@ +import {Component} from "preact"; +import {type SharedProps} from "./shared.js"; + +export class Calendar extends Component { + render() { + const {today} = this.props; + + const dayNames = ["", "MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN"]; + const currentWeekDayName = dayNames[today.dayOfTheWeek()]; + + // Create the row with the names of the day. + const dayNameRow = dayNames.map((name) => { + const classes = [ + currentWeekDayName === name ? "current-week-day-name" : "", + name === "" ? "week-number" : "week-day-name", + ]; + return

{name}

; + }); + + // Create the start of the calendar and set it to the first day of the + // month. + const start = today.clone(); + start.date.setDate(1); + + // Subtract the amount of days in the week we are in from the start. + // Add 1 to account for Monday starting at 1. + const subtractDays = -start.dayOfTheWeek() + 1; + + // If the subtraction ends up being 0 it means the first day of the month is + // a Monday, in which case we want to subtract a whole week instead. + start.addDays(subtractDays === 0 ? -7 : subtractDays); + + const weekRows = []; + + // Loop over 6 weeks to include in the calendar. + for (let weekCounter = 0; weekCounter < 6; weekCounter++) { + // Get the current week and add the week we're in to it. + const currentWeek = start.week() + weekCounter; + + // Clone the start date and add the amount of weeks we've looped over. + const weekDay = start.clone(); + weekDay.addDays(weekCounter * 7); + + const currentWeekClasses = [ + today.week() === weekDay.week() ? "current-week" : "", + "week-number", + ]; + + // Add the week number as the first column of the grid. + weekRows.push( +

{currentWeek}

, + ); + + // Loop over each day in the week. + for (let dayCounter = 0; dayCounter < 7; dayCounter++) { + // Create CSS classes for the current day, weekday and month. + const classes = [ + today.iso().startsWith(weekDay.iso().slice(0, 10)) + ? "current-day" + : "", + today.week() === weekDay.week() ? "current-week-day" : "", + today.date.getMonth() === weekDay.date.getMonth() + ? "current-month" + : "other-month", + ]; + + // Add the new week day to the list and advance it by a day. + weekRows.push( +

{weekDay.paddedDay()}

, + ); + weekDay.addDays(1); + } + } + + return ( +
+ {dayNameRow} + {weekRows} +
+ ); + } +} diff --git a/source/components/exports.ts b/source/components/exports.ts new file mode 100644 index 0000000..8fe1e81 --- /dev/null +++ b/source/components/exports.ts @@ -0,0 +1,2 @@ +export * from "./big-date.js"; +export * from "./calendar.js"; diff --git a/source/global.scss b/source/global.scss new file mode 100644 index 0000000..03ef560 --- /dev/null +++ b/source/global.scss @@ -0,0 +1,97 @@ +blockquote, +code, +h1, +h2, +h3, +h4, +h5, +li, +ol, +p, +pre, +ul { + margin: 0; + padding: 0; +} + +html { + font-size: 62.5%; +} + +body { + --base: #24273a; + --surface-0: #363a4f; + --subtext-0: #a5adcb; + --overlay-0: #6e738d; + --text: #cad3f5; + --spacing-1: 32px; + + background-color: var(--base); + color: var(--text); + font-size: 2rem; +} + +.preact-root { + border: 2px solid var(--overlay-0); + min-height: 100vh; + min-width: 100vw; +} + +.calendar, +.big-date, +.subtitle { + margin-left: var(--spacing-1); +} + +.subtitle { + margin-top: var(--spacing-1); +} + +.big-date { + font-size: 4rem; + + .dash { + color: var(--overlay-0); + } +} + +.calendar { + border: 2px solid var(--text); + display: inline-grid; + font-family: monospace; + grid-template-columns: repeat(8, 1fr); + width: fit-content; + + p { + padding: 4px; + } + + .current-week, + .current-week-day { + background-color: var(--surface-0); + } + + .current-day, + .current-week-day-name { + background-color: var(--text); + color: var(--base); + } + + .current-month, + .current-week, + .current-week-day-name { + font-weight: bold; + } + + .other-month { + color: var(--overlay-0); + } + + .week-day-name { + border-bottom: 2px solid var(--text); + } + + .week-number { + border-right: 2px solid var(--text); + } +}