From af97f17a2c2074bcaf615b5edea01c3fd4f47f5b Mon Sep 17 00:00:00 2001 From: Michael Zhang Date: Thu, 24 Aug 2023 13:40:56 -0400 Subject: [PATCH] type check --- lib/ScrollContainer.tsx | 23 +++-- src/calendar/Calendar.tsx | 5 +- src/calendar/Month.tsx | 4 +- src/calendar/MonthCalendar.tsx | 170 +++++++++----------------------- src/calendar/MonthCalendar2.tsx | 101 ------------------- src/widgets/InputBox.tsx | 4 +- 6 files changed, 68 insertions(+), 239 deletions(-) delete mode 100644 src/calendar/MonthCalendar2.tsx diff --git a/lib/ScrollContainer.tsx b/lib/ScrollContainer.tsx index 6e9547a..601ec20 100644 --- a/lib/ScrollContainer.tsx +++ b/lib/ScrollContainer.tsx @@ -1,4 +1,11 @@ -import { Fragment, useCallback, useContext, useEffect, useState } from "react"; +import { + Fragment, + Key, + useCallback, + useContext, + useEffect, + useState, +} from "react"; import styles from "./ScrollContainer.module.scss"; import classNames from "classnames"; import { getWeek } from "date-fns"; @@ -87,8 +94,8 @@ function ScrollContainer({ // Identify the middle month const el = scrollyEl.children[middleIdx]; if (el) { - const date = new Date(el.dataset.isodate!); - console.log("first run, scrolling into view", date.getMonth()); + // const date = new Date(el.dataset.isodate!); + // console.log("first run, scrolling into view", date.getMonth()); el.scrollIntoView(); setFirstLoad(false); @@ -111,8 +118,8 @@ function ScrollContainer({ // entry.intersectionRect.width * entry.intersectionRect.height; // if (intersectionArea === 0) continue; - const date = new Date(entry.target.dataset.isodate!); - console.log("intersected with", weekString(date), entry); + // const date = new Date(entry.target.dataset.isodate!); + // console.log("intersected with", weekString(date), entry); if (entry.target === firstChild) { const newResetScrollToEl = { @@ -140,9 +147,9 @@ function ScrollContainer({ } }); - const firstDate = new Date(firstChild.dataset.isodate!); - const lastDate = new Date(lastChild.dataset.isodate!); - console.log("observing", weekString(firstDate), weekString(lastDate)); + // const firstDate = new Date(firstChild.dataset.isodate!); + // const lastDate = new Date(lastChild.dataset.isodate!); + // console.log("observing", weekString(firstDate), weekString(lastDate)); observer.observe(firstChild); observer.observe(lastChild); diff --git a/src/calendar/Calendar.tsx b/src/calendar/Calendar.tsx index b913316..8f9bbd6 100644 --- a/src/calendar/Calendar.tsx +++ b/src/calendar/Calendar.tsx @@ -6,7 +6,6 @@ import Button from "src/widgets/Button"; import MonthCalendar from "./MonthCalendar"; import WeekCalendar from "./WeekCalendar"; import { usePersistentState } from "lib/persistentState"; -import MonthCalendar2 from "./MonthCalendar2"; export enum CalendarMode { Week = "Week", @@ -109,10 +108,10 @@ interface ActualCalendarProps { function ActualCalendar({ mode }: ActualCalendarProps) { switch (mode) { case CalendarMode.Month: - return ; + return ; case CalendarMode.Week: return ; case CalendarMode.Year: - return ; + return ; } } diff --git a/src/calendar/Month.tsx b/src/calendar/Month.tsx index acc5185..ba07bd6 100644 --- a/src/calendar/Month.tsx +++ b/src/calendar/Month.tsx @@ -1,4 +1,4 @@ -import { forwardRef } from "react"; +import { ForwardedRef, forwardRef } from "react"; import styles from "./Month.module.scss"; import { addDays, @@ -23,7 +23,7 @@ interface MonthProps { function Month( { month, dateGridHeight, isActive, dateCellHeight, onDateClick }: MonthProps, - ref + ref: ForwardedRef ) { const now = new Date(); const monthName = month.toLocaleString("default", { month: "long" }); diff --git a/src/calendar/MonthCalendar.tsx b/src/calendar/MonthCalendar.tsx index 1c75688..849241d 100644 --- a/src/calendar/MonthCalendar.tsx +++ b/src/calendar/MonthCalendar.tsx @@ -1,4 +1,5 @@ -import { useCallback, useContext, useEffect, useState } from "react"; +import { useContext, useEffect, useState } from "react"; +import { CalendarContext } from "./Calendar"; import styles from "./MonthCalendar.module.scss"; import { addMonths, @@ -9,31 +10,25 @@ import { } from "date-fns"; import { daysOfWeek, monthNameOf, weekBoundsOfMonth } from "lib/date"; import Month from "./Month"; -import { CalendarContext } from "./Calendar"; +import ScrollContainer from "lib/ScrollContainer"; const NUM_MONTHS_SHOWN = 5; export default function MonthCalendar() { - const { onDateClick, setCurrentTitle } = useContext(CalendarContext); const now = new Date(); - - const [resetScrollToEl, setResetScrollToEl] = useState< - [HTMLElement, number] | null - >(null); - const [viewportHeight, setViewportHeight] = useState(0); - const [scrollyEl, setScrollyEl] = useState(null); - const scrollyRef = useCallback((node: HTMLDivElement) => { - if (node) { - setScrollyEl(node); - setViewportHeight(node.clientHeight); - } - }, []); + const { onDateClick, setCurrentTitle, viewportHeight } = useContext( + CalendarContext + ); const range = [-2, -1, 0, 1, 2]; const [monthsShown, setMonthsShown] = useState( range.map((x) => addMonths(startOfMonth(now), x)) ); const centerMonth = monthsShown[2]; + console.log( + monthNameOf(centerMonth), + monthsShown.map((x) => monthNameOf(x)) + ); useEffect(() => { setCurrentTitle( @@ -44,98 +39,41 @@ export default function MonthCalendar() { ); }, [centerMonth]); - // Scroll to today on first load - const [firstLoad, setFirstLoad] = useState(true); - useEffect(() => { - if (firstLoad && scrollyEl && viewportHeight > 0) { - // Identify the middle month - const el = scrollyEl.querySelector( - `[data-isodate="${centerMonth.toISOString()}"]` - ); - if (el) { - console.log("first run, scrolling into view", el); - el.scrollIntoView(false); + const generatePreviousObject = (el: HTMLElement) => { + const date = new Date(el.dataset.isodate!); + const prevMonth = subMonths(date, 1); + const newWeeksShown = [prevMonth, ...monthsShown]; + setMonthsShown(newWeeksShown.slice(0, NUM_MONTHS_SHOWN)); + }; - setFirstLoad(false); - } - } - }, [firstLoad, scrollyEl, viewportHeight]); + const generateNextObject = (el: HTMLElement) => { + const date = new Date(el.dataset.isodate!); + const nextMonth = addMonths(date, 1); + const newWeeksShown = [...monthsShown, nextMonth]; + setMonthsShown(newWeeksShown.slice(-NUM_MONTHS_SHOWN)); + }; - // Add resize observer on the viewport - useEffect(() => { - const observer = new ResizeObserver((entries) => { - if (entries && scrollyEl) setViewportHeight(scrollyEl.clientHeight); - }); - - if (scrollyEl) observer.observe(scrollyEl); - - return () => { - if (scrollyEl) observer.unobserve(scrollyEl); - }; - }, [scrollyEl]); + const keyOf = (month: Date) => month.toISOString(); // The calendar should always show 6 rows const dateCellHeight = viewportHeight / 6; - // Add intersection observer to tell when we scrolled too far up or down - useEffect(() => { - if (!scrollyEl) return; + const renderItem = (month: Date) => { + // How many rows will this month take up? + const [startWeek, endWeek] = weekBoundsOfMonth(month); + const numWeeks = differenceInWeeks(endWeek, startWeek); + const dateGridHeight = dateCellHeight * numWeeks; - const children: HTMLElement[] = [...scrollyEl.children]; - if (children.length !== NUM_MONTHS_SHOWN) throw new Error("wtf"); - const firstChild = children[0]; - const lastChild = children[NUM_MONTHS_SHOWN - 1]; - - const observer = new IntersectionObserver((entries) => { - if (viewportHeight === 0) return; - let newMonthsShown = monthsShown; - - for (const entry of entries) { - if (!entry.isIntersecting) continue; - - if (entry.target === firstChild) { - console.log("intersected"); - const firstChildDate = new Date(firstChild.dataset.isodate!); - const prevMonth = subMonths(firstChildDate, 1); - newMonthsShown = [prevMonth, ...monthsShown]; - newMonthsShown = newMonthsShown.slice(0, NUM_MONTHS_SHOWN); - - setResetScrollToEl([ - firstChild, - scrollyEl.scrollTop - firstChild.offsetTop, - ]); - } else if (entry.target === lastChild) { - const lastChildDate = new Date(lastChild.dataset.isodate!); - const nextMonth = addMonths(lastChildDate, 1); - newMonthsShown = [...monthsShown, nextMonth]; - newMonthsShown = newMonthsShown.slice(-NUM_MONTHS_SHOWN); - } - } - - setMonthsShown(newMonthsShown); - }); - - console.log("observing", firstChild, lastChild); - observer.observe(firstChild); - observer.observe(lastChild); - - return () => { - observer.unobserve(firstChild); - observer.unobserve(lastChild); + const props = { + month, + dateGridHeight, + dateCellHeight, + isActive: isSameMonth(centerMonth, month), }; - }, [monthsShown, scrollyEl]); - - useEffect(() => { - if (!resetScrollToEl) return; - if (!scrollyEl) return; - - console.log("current scroll top", scrollyEl.scrollTop); - console.log("params", resetScrollToEl); - const [el, height] = resetScrollToEl; - scrollyEl.scrollTop = el.offsetTop + height; - console.log("new scroll top", scrollyEl.scrollTop, el.offsetTop + height); - setResetScrollToEl(null); - }, [resetScrollToEl, scrollyEl]); + return ( + + ); + }; return ( <> @@ -147,30 +85,16 @@ export default function MonthCalendar() { ))} -
- {monthsShown.map((month) => { - // How many rows will this month take up? - const [startWeek, endWeek] = weekBoundsOfMonth(month); - const numWeeks = differenceInWeeks(endWeek, startWeek); - const dateGridHeight = dateCellHeight * numWeeks; - - const props = { - month, - dateGridHeight, - dateCellHeight, - isActive: isSameMonth(centerMonth, month), - }; - const ref = undefined; - // (month === currentlyShownMonth && middleMonthRef) || undefined; - return ( - - ); - })} +
+
); diff --git a/src/calendar/MonthCalendar2.tsx b/src/calendar/MonthCalendar2.tsx deleted file mode 100644 index d18f386..0000000 --- a/src/calendar/MonthCalendar2.tsx +++ /dev/null @@ -1,101 +0,0 @@ -import { useContext, useEffect, useState } from "react"; -import { CalendarContext } from "./Calendar"; -import styles from "./MonthCalendar.module.scss"; -import { - addMonths, - differenceInWeeks, - isSameMonth, - startOfMonth, - subMonths, -} from "date-fns"; -import { daysOfWeek, monthNameOf, weekBoundsOfMonth } from "lib/date"; -import Month from "./Month"; -import ScrollContainer from "lib/ScrollContainer"; - -const NUM_MONTHS_SHOWN = 5; - -export default function MonthCalendar2() { - const now = new Date(); - const { onDateClick, setCurrentTitle, viewportHeight } = useContext( - CalendarContext - ); - - const range = [-2, -1, 0, 1, 2]; - const [monthsShown, setMonthsShown] = useState( - range.map((x) => addMonths(startOfMonth(now), x)) - ); - const centerMonth = monthsShown[2]; - console.log( - monthNameOf(centerMonth), - monthsShown.map((x) => monthNameOf(x)) - ); - - useEffect(() => { - setCurrentTitle( - <> - {monthNameOf(centerMonth)} - {centerMonth.getFullYear()} - - ); - }, [centerMonth]); - - const generatePreviousObject = (el: HTMLElement) => { - const date = new Date(el.dataset.isodate!); - const prevMonth = subMonths(date, 1); - const newWeeksShown = [prevMonth, ...monthsShown]; - setMonthsShown(newWeeksShown.slice(0, NUM_MONTHS_SHOWN)); - }; - - const generateNextObject = (el: HTMLElement) => { - const date = new Date(el.dataset.isodate!); - const nextMonth = addMonths(date, 1); - const newWeeksShown = [...monthsShown, nextMonth]; - setMonthsShown(newWeeksShown.slice(-NUM_MONTHS_SHOWN)); - }; - - const keyOf = (month: Date) => month.toISOString(); - - // The calendar should always show 6 rows - const dateCellHeight = viewportHeight / 6; - - const renderItem = (month: Date) => { - // How many rows will this month take up? - const [startWeek, endWeek] = weekBoundsOfMonth(month); - const numWeeks = differenceInWeeks(endWeek, startWeek); - const dateGridHeight = dateCellHeight * numWeeks; - - const props = { - month, - dateGridHeight, - dateCellHeight, - isActive: isSameMonth(centerMonth, month), - }; - return ( - - ); - }; - - return ( - <> -
- {daysOfWeek.map((day) => ( -
- {day} -
- ))} -
- -
- -
- - ); -} diff --git a/src/widgets/InputBox.tsx b/src/widgets/InputBox.tsx index 0633bf9..a7705a9 100644 --- a/src/widgets/InputBox.tsx +++ b/src/widgets/InputBox.tsx @@ -1,11 +1,11 @@ -import { HTMLProps } from "react"; +import { ChangeEvent, HTMLProps } from "react"; interface InputBoxProps extends HTMLProps { setValue: (_: string) => any; } export default function InputBox({ setValue, ...props }: InputBoxProps) { - const newOnChange = (evt) => { + const newOnChange = (evt: ChangeEvent) => { setValue(evt.target.value); };