wip
This commit is contained in:
parent
59a7849173
commit
f375c25a48
7 changed files with 366 additions and 229 deletions
0
lib/ScrollContainer.module.scss
Normal file
0
lib/ScrollContainer.module.scss
Normal file
102
lib/ScrollContainer.tsx
Normal file
102
lib/ScrollContainer.tsx
Normal file
|
@ -0,0 +1,102 @@
|
|||
import {
|
||||
ForwardedRef,
|
||||
forwardRef,
|
||||
useCallback,
|
||||
useEffect,
|
||||
useState,
|
||||
} from "react";
|
||||
import styles from "./ScrollContainer.module.scss";
|
||||
import { subMonths } from "date-fns";
|
||||
|
||||
interface ScrollContainerProps<T> {
|
||||
direction: "horizontal" | "vertical";
|
||||
|
||||
/** A list of things managed */
|
||||
list: T[];
|
||||
|
||||
generatePreviousObject: () => void;
|
||||
generateNextObject: () => void;
|
||||
}
|
||||
/**
|
||||
* Generic infinite scrolling container
|
||||
*/
|
||||
function ScrollContainer<T>(
|
||||
{ direction, list }: ScrollContainerProps<T>,
|
||||
ref: ForwardedRef<HTMLDivElement>
|
||||
) {
|
||||
const [resetScrollToEl, setResetScrollToEl] = useState<
|
||||
[HTMLElement, number] | null
|
||||
>(null);
|
||||
|
||||
// Viewport state
|
||||
const [viewportSize, setViewportSize] = useState<[number, number]>([0, 0]);
|
||||
const [viewportWidth, viewportHeight] = viewportSize;
|
||||
const viewportMetric =
|
||||
direction === "horizontal" ? viewportWidth : viewportHeight;
|
||||
|
||||
// Scroll element state
|
||||
const [scrollyEl, setScrollyEl] = useState<HTMLDivElement | null>(null);
|
||||
const scrollyRef = useCallback((node: HTMLDivElement) => {
|
||||
if (node) {
|
||||
setScrollyEl(node);
|
||||
setViewportSize([node.clientWidth, node.clientHeight]);
|
||||
}
|
||||
}, []);
|
||||
|
||||
// Add resize observer on the viewport
|
||||
useEffect(() => {
|
||||
const observer = new ResizeObserver((entries) => {
|
||||
if (entries && scrollyEl) {
|
||||
setViewportSize([scrollyEl.clientWidth, scrollyEl.clientHeight]);
|
||||
}
|
||||
});
|
||||
|
||||
if (scrollyEl) observer.observe(scrollyEl);
|
||||
|
||||
return () => {
|
||||
if (scrollyEl) observer.unobserve(scrollyEl);
|
||||
};
|
||||
}, [scrollyEl]);
|
||||
|
||||
// Add intersection observer to tell when we scrolled too far
|
||||
useEffect(() => {
|
||||
if (!scrollyEl) return;
|
||||
|
||||
const children: HTMLElement[] = [...scrollyEl.children];
|
||||
const firstChild = children[0];
|
||||
const lastChild = children[children.length - 1];
|
||||
|
||||
const observer = new IntersectionObserver((entries) => {
|
||||
if (viewportMetric === 0) return;
|
||||
let newList = [...list];
|
||||
|
||||
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);
|
||||
newList = [prevMonth, ...monthsShown];
|
||||
newList = 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);
|
||||
});
|
||||
});
|
||||
|
||||
return <div className={styles.scrollyEl} ref={scrollyRef}></div>;
|
||||
}
|
||||
|
||||
export default forwardRef(ScrollContainer);
|
|
@ -22,31 +22,3 @@
|
|||
gap: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.daysOfWeek {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(7, 1fr);
|
||||
|
||||
div {
|
||||
flex-grow: 1;
|
||||
text-align: right;
|
||||
font-weight: 100;
|
||||
border-bottom: 1px solid gray;
|
||||
padding: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.scrollyPart {
|
||||
flex-grow: 1;
|
||||
|
||||
overflow-y: scroll; /* Add the ability to scroll the y axis */
|
||||
|
||||
/* Hide the scrollbar for Internet Explorer, Edge and Firefox */
|
||||
-ms-overflow-style: none; /* Internet Explorer and Edge */
|
||||
scrollbar-width: none; /* Firefox */
|
||||
|
||||
/* Hide the scrollbar for Chrome, Safari and Opera */
|
||||
&::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,225 +1,75 @@
|
|||
import { forwardRef, useCallback, useEffect, useRef, useState } from "react";
|
||||
import { Dispatch, SetStateAction, createContext, useState } from "react";
|
||||
import styles from "./Calendar.module.scss";
|
||||
import {
|
||||
addDays,
|
||||
addMonths,
|
||||
differenceInWeeks,
|
||||
isSameMonth,
|
||||
startOfMonth,
|
||||
subMonths,
|
||||
} from "date-fns";
|
||||
import Month from "./Month";
|
||||
import { monthNameOf, weekBoundsOfMonth } from "lib/month";
|
||||
import { useJournals } from "lib/queries";
|
||||
import ToggleSwitch from "src/widgets/ToggleSwitch";
|
||||
import InputBox from "src/widgets/InputBox";
|
||||
import Button from "src/widgets/Button";
|
||||
import MonthCalendar from "./MonthCalendar";
|
||||
|
||||
const daysOfWeek = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
||||
const NUM_MONTHS_SHOWN = 5;
|
||||
interface ICalendarContext {
|
||||
onDateClick: (_: Date) => void;
|
||||
setCurrentTitle: Dispatch<SetStateAction<JSX.Element>>;
|
||||
}
|
||||
|
||||
export const CalendarContext = createContext<ICalendarContext>(null!);
|
||||
|
||||
interface CalendarProps {
|
||||
onDateClick?: (_: Date) => void;
|
||||
onDateClick: (_: Date) => void;
|
||||
}
|
||||
|
||||
export default function Calendar({ onDateClick }: CalendarProps) {
|
||||
const now = new Date();
|
||||
const [currentTitle, setCurrentTitle] = useState<JSX.Element>(<></>);
|
||||
|
||||
const [viewportHeight, setViewportHeight] = useState(0);
|
||||
const [scrollyEl, setScrollyEl] = useState<HTMLDivElement | null>(null);
|
||||
const [resetScrollToEl, setResetScrollToEl] = useState<
|
||||
[HTMLElement, number] | null
|
||||
>(null);
|
||||
|
||||
const range = [-2, -1, 0, 1, 2];
|
||||
const [monthsShown, setMonthsShown] = useState(
|
||||
range.map((x) => addMonths(startOfMonth(now), x))
|
||||
);
|
||||
const centerMonth = monthsShown[2];
|
||||
|
||||
const startDate = monthsShown[0];
|
||||
const endDate = monthsShown[NUM_MONTHS_SHOWN - 1];
|
||||
|
||||
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();
|
||||
|
||||
setFirstLoad(false);
|
||||
}
|
||||
}
|
||||
}, [firstLoad, scrollyEl, viewportHeight]);
|
||||
|
||||
const scrollyRef = useCallback((node: HTMLDivElement) => {
|
||||
if (node) {
|
||||
setScrollyEl(node);
|
||||
setViewportHeight(node.clientHeight);
|
||||
}
|
||||
}, []);
|
||||
|
||||
// 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]);
|
||||
|
||||
// Add intersection observer to tell when we scrolled too far up or down
|
||||
useEffect(() => {
|
||||
if (!scrollyEl) return;
|
||||
|
||||
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) => {
|
||||
let newMonthsShown = monthsShown;
|
||||
let scrollUp = false;
|
||||
|
||||
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);
|
||||
};
|
||||
}, [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]);
|
||||
|
||||
console.log("SCROLLY REF IS", scrollyRef);
|
||||
|
||||
// The calendar should always show 6 rows
|
||||
const dateCellHeight = viewportHeight / 6;
|
||||
|
||||
const monthName = monthNameOf(centerMonth);
|
||||
|
||||
// useEffect(() => {
|
||||
// middleMonthEl?.scrollIntoView();
|
||||
// }, [middleMonthRef]);
|
||||
const scrollToToday = () => {};
|
||||
|
||||
const [searchQuery, setSearchQuery] = useState("");
|
||||
|
||||
const [currentLayout, setCurrentLayout] = useState("Month");
|
||||
const [currentMode, setCurrentMode] = useState("Month");
|
||||
const [currentView, setCurrentView] = useState("Calendar");
|
||||
|
||||
const contextValue = { onDateClick, setCurrentTitle };
|
||||
|
||||
return (
|
||||
<div className={styles.calendar}>
|
||||
<div className={styles.header}>
|
||||
<div className={styles.title}>
|
||||
<div>
|
||||
<b>{monthName}</b>
|
||||
{centerMonth.getFullYear()}
|
||||
</div>
|
||||
<CalendarContext.Provider value={contextValue}>
|
||||
<div className={styles.calendar}>
|
||||
<div className={styles.header}>
|
||||
<div className={styles.title}>
|
||||
<div>{currentTitle}</div>
|
||||
|
||||
<div>
|
||||
<InputBox
|
||||
value={searchQuery}
|
||||
setValue={setSearchQuery}
|
||||
placeholder="Search..."
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className={styles.controlButtons}>
|
||||
<Button>Today</Button>
|
||||
|
||||
<ToggleSwitch
|
||||
options={["Week", "Month", "Year"]}
|
||||
value={currentLayout}
|
||||
setValue={setCurrentLayout}
|
||||
/>
|
||||
|
||||
<ToggleSwitch
|
||||
options={["Calendar", "Graph"]}
|
||||
value={currentView}
|
||||
setValue={setCurrentView}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={styles.daysOfWeek}>
|
||||
{daysOfWeek.map((day) => (
|
||||
<div key={day} className={styles.dayOfWeek}>
|
||||
{day}
|
||||
<div>
|
||||
<InputBox
|
||||
value={searchQuery}
|
||||
setValue={setSearchQuery}
|
||||
placeholder="Search..."
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
|
||||
<div className={styles.controlButtons}>
|
||||
<Button>Today</Button>
|
||||
|
||||
<ToggleSwitch
|
||||
options={["Week", "Month", "Year"]}
|
||||
value={currentMode}
|
||||
setValue={setCurrentMode}
|
||||
/>
|
||||
|
||||
<ToggleSwitch
|
||||
options={["Calendar", "Graph"]}
|
||||
value={currentView}
|
||||
setValue={setCurrentView}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={styles.scrollyPart} ref={scrollyRef}>
|
||||
{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 (
|
||||
<Month
|
||||
key={month.toString()}
|
||||
{...props}
|
||||
ref={ref}
|
||||
onDateClick={onDateClick}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
<ActualCalendar mode={currentMode} />
|
||||
</div>
|
||||
</div>
|
||||
</CalendarContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
function ActualCalendar({ mode }) {
|
||||
switch (mode) {
|
||||
default:
|
||||
return <MonthCalendar />;
|
||||
}
|
||||
}
|
||||
|
|
27
src/calendar/MonthCalendar.module.scss
Normal file
27
src/calendar/MonthCalendar.module.scss
Normal file
|
@ -0,0 +1,27 @@
|
|||
.daysOfWeek {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(7, 1fr);
|
||||
|
||||
div {
|
||||
flex-grow: 1;
|
||||
text-align: right;
|
||||
font-weight: 100;
|
||||
border-bottom: 1px solid gray;
|
||||
padding: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.scrollyPart {
|
||||
flex-grow: 1;
|
||||
|
||||
overflow-y: scroll; /* Add the ability to scroll the y axis */
|
||||
|
||||
/* Hide the scrollbar for Internet Explorer, Edge and Firefox */
|
||||
-ms-overflow-style: none; /* Internet Explorer and Edge */
|
||||
scrollbar-width: none; /* Firefox */
|
||||
|
||||
/* Hide the scrollbar for Chrome, Safari and Opera */
|
||||
&::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
}
|
178
src/calendar/MonthCalendar.tsx
Normal file
178
src/calendar/MonthCalendar.tsx
Normal file
|
@ -0,0 +1,178 @@
|
|||
import { useCallback, useContext, useEffect, useState } from "react";
|
||||
import styles from "./MonthCalendar.module.scss";
|
||||
import {
|
||||
addMonths,
|
||||
differenceInWeeks,
|
||||
isSameMonth,
|
||||
startOfMonth,
|
||||
subMonths,
|
||||
} from "date-fns";
|
||||
import { monthNameOf, weekBoundsOfMonth } from "lib/month";
|
||||
import Month from "./Month";
|
||||
import { CalendarContext } from "./Calendar";
|
||||
|
||||
const daysOfWeek = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
||||
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<HTMLDivElement | null>(null);
|
||||
const scrollyRef = useCallback((node: HTMLDivElement) => {
|
||||
if (node) {
|
||||
setScrollyEl(node);
|
||||
setViewportHeight(node.clientHeight);
|
||||
}
|
||||
}, []);
|
||||
|
||||
const range = [-2, -1, 0, 1, 2];
|
||||
const [monthsShown, setMonthsShown] = useState(
|
||||
range.map((x) => addMonths(startOfMonth(now), x))
|
||||
);
|
||||
const centerMonth = monthsShown[2];
|
||||
|
||||
useEffect(() => {
|
||||
setCurrentTitle(
|
||||
<>
|
||||
<b>{monthNameOf(centerMonth)}</b>
|
||||
{centerMonth.getFullYear()}
|
||||
</>
|
||||
);
|
||||
}, [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();
|
||||
|
||||
setFirstLoad(false);
|
||||
}
|
||||
}
|
||||
}, [firstLoad, scrollyEl, viewportHeight]);
|
||||
|
||||
// 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]);
|
||||
|
||||
// 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 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);
|
||||
};
|
||||
}, [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 (
|
||||
<>
|
||||
<div className={styles.daysOfWeek}>
|
||||
{daysOfWeek.map((day) => (
|
||||
<div key={day} className={styles.dayOfWeek}>
|
||||
{day}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className={styles.scrollyPart} ref={scrollyRef}>
|
||||
{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 (
|
||||
<Month
|
||||
key={month.toString()}
|
||||
{...props}
|
||||
ref={ref}
|
||||
onDateClick={onDateClick}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
8
src/calendar/WeekCalendar.tsx
Normal file
8
src/calendar/WeekCalendar.tsx
Normal file
|
@ -0,0 +1,8 @@
|
|||
import { useContext } from "react";
|
||||
import { CalendarContext } from "./Calendar";
|
||||
|
||||
export default function WeekCalendar() {
|
||||
const { onDateClick, setCurrentTitle } = useContext(CalendarContext);
|
||||
|
||||
return <></>;
|
||||
}
|
Loading…
Reference in a new issue