a bit of styling

This commit is contained in:
Michael Zhang 2023-08-23 22:24:44 -05:00
parent aa820d4910
commit 59a7849173
11 changed files with 75 additions and 14 deletions

1
.tokeignore Normal file
View file

@ -0,0 +1 @@
package-lock.json

0
lib/datascript.ts Normal file
View file

View file

@ -4,6 +4,7 @@ import {
addDays, addDays,
addMonths, addMonths,
differenceInWeeks, differenceInWeeks,
isSameMonth,
startOfMonth, startOfMonth,
subMonths, subMonths,
} from "date-fns"; } from "date-fns";
@ -11,6 +12,8 @@ import Month from "./Month";
import { monthNameOf, weekBoundsOfMonth } from "lib/month"; import { monthNameOf, weekBoundsOfMonth } from "lib/month";
import { useJournals } from "lib/queries"; import { useJournals } from "lib/queries";
import ToggleSwitch from "src/widgets/ToggleSwitch"; import ToggleSwitch from "src/widgets/ToggleSwitch";
import InputBox from "src/widgets/InputBox";
import Button from "src/widgets/Button";
const daysOfWeek = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; const daysOfWeek = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
const NUM_MONTHS_SHOWN = 5; const NUM_MONTHS_SHOWN = 5;
@ -24,15 +27,15 @@ export default function Calendar({ onDateClick }: CalendarProps) {
const [viewportHeight, setViewportHeight] = useState(0); const [viewportHeight, setViewportHeight] = useState(0);
const [scrollyEl, setScrollyEl] = useState<HTMLDivElement | null>(null); const [scrollyEl, setScrollyEl] = useState<HTMLDivElement | null>(null);
const [centerMonth, setCenterMonth] = useState(startOfMonth(now));
const [resetScrollToEl, setResetScrollToEl] = useState< const [resetScrollToEl, setResetScrollToEl] = useState<
[HTMLElement, number] | null [HTMLElement, number] | null
>(null); >(null);
const range = [-2, -1, 0, 1, 2]; const range = [-2, -1, 0, 1, 2];
const [monthsShown, setMonthsShown] = useState( const [monthsShown, setMonthsShown] = useState(
range.map((x) => addMonths(centerMonth, x)) range.map((x) => addMonths(startOfMonth(now), x))
); );
const centerMonth = monthsShown[2];
const startDate = monthsShown[0]; const startDate = monthsShown[0];
const endDate = monthsShown[NUM_MONTHS_SHOWN - 1]; const endDate = monthsShown[NUM_MONTHS_SHOWN - 1];
@ -144,6 +147,8 @@ export default function Calendar({ onDateClick }: CalendarProps) {
// middleMonthEl?.scrollIntoView(); // middleMonthEl?.scrollIntoView();
// }, [middleMonthRef]); // }, [middleMonthRef]);
const [searchQuery, setSearchQuery] = useState("");
const [currentLayout, setCurrentLayout] = useState("Month"); const [currentLayout, setCurrentLayout] = useState("Month");
const [currentView, setCurrentView] = useState("Calendar"); const [currentView, setCurrentView] = useState("Calendar");
@ -156,7 +161,17 @@ export default function Calendar({ onDateClick }: CalendarProps) {
{centerMonth.getFullYear()} {centerMonth.getFullYear()}
</div> </div>
<div>
<InputBox
value={searchQuery}
setValue={setSearchQuery}
placeholder="Search..."
/>
</div>
<div className={styles.controlButtons}> <div className={styles.controlButtons}>
<Button>Today</Button>
<ToggleSwitch <ToggleSwitch
options={["Week", "Month", "Year"]} options={["Week", "Month", "Year"]}
value={currentLayout} value={currentLayout}
@ -191,6 +206,7 @@ export default function Calendar({ onDateClick }: CalendarProps) {
month, month,
dateGridHeight, dateGridHeight,
dateCellHeight, dateCellHeight,
isActive: isSameMonth(centerMonth, month),
}; };
const ref = undefined; const ref = undefined;
// (month === currentlyShownMonth && middleMonthRef) || undefined; // (month === currentlyShownMonth && middleMonthRef) || undefined;

View file

@ -14,6 +14,13 @@
border-width: 1px 0 0 1px; border-width: 1px 0 0 1px;
border-color: lightgray; border-color: lightgray;
border-style: solid; border-style: solid;
color: var(--disabled-text-color);
transition: color 0.1s ease-out;
}
.active .dateCell {
color: var(--normal-text-color);
} }
.dateNumber { .dateNumber {

View file

@ -15,13 +15,14 @@ import { journalFmt, useJournals } from "lib/queries";
interface MonthProps { interface MonthProps {
month: Date; month: Date;
isActive: boolean;
dateGridHeight: number; dateGridHeight: number;
dateCellHeight: number; dateCellHeight: number;
onDateClick?: (_: Date) => void; onDateClick?: (_: Date) => void;
} }
function Month( function Month(
{ month, dateGridHeight, dateCellHeight, onDateClick }: MonthProps, { month, dateGridHeight, isActive, dateCellHeight, onDateClick }: MonthProps,
ref ref
) { ) {
const now = new Date(); const now = new Date();
@ -46,7 +47,7 @@ function Month(
return ( return (
<> <>
<div <div
className={styles.dateGrid} className={classNames(styles.dateGrid, isActive && styles.active)}
// style={{ height: `${dateGridHeight}px` }} // style={{ height: `${dateGridHeight}px` }}
style={{ gridTemplateRows: `repeat(${numWeeks}, ${dateCellHeight}px)` }} style={{ gridTemplateRows: `repeat(${numWeeks}, ${dateCellHeight}px)` }}
ref={ref} ref={ref}
@ -76,7 +77,7 @@ function Month(
</div> </div>
<div className={styles.dateCellBody}> <div className={styles.dateCellBody}>
<p>j: {JSON.stringify(hasJournal)}</p> <p>{hasJournal && "journal"}</p>
</div> </div>
</div> </div>
); );

View file

@ -1,8 +1,12 @@
:root { :root {
--text-color: black; --normal-text-color: black;
--disabled-text-color: #aaa;
--border-radius: 6px;
@media (prefers-color-scheme: dark) { @media (prefers-color-scheme: dark) {
--text-color: white; --normal-text-color: white;
--disabled-text-color: #666;
} }
} }
@ -16,5 +20,5 @@ body,
padding: 0; padding: 0;
font-family: sans-serif; font-family: sans-serif;
color: var(--text-color); color: var(--normal-text-color);
} }

View file

@ -0,0 +1,7 @@
.button {
cursor: pointer;
border-radius: var(--border-radius);
border: none;
padding: 4px 12px;
background-color: lightgray;
}

8
src/widgets/Button.tsx Normal file
View file

@ -0,0 +1,8 @@
import { HTMLProps } from "react";
import styles from "./Button.module.scss";
export interface ButtonProps extends HTMLProps<HTMLButtonElement> {}
export default function Button({ children }: ButtonProps) {
return <button className={styles.button}>{children}</button>;
}

13
src/widgets/InputBox.tsx Normal file
View file

@ -0,0 +1,13 @@
import { HTMLProps } from "react";
interface InputBoxProps extends HTMLProps<HTMLInputElement> {
setValue: (_: string) => any;
}
export default function InputBox({ setValue, ...props }: InputBoxProps) {
const newOnChange = (evt) => {
setValue(evt.target.value);
};
return <input onChange={newOnChange} {...props} />;
}

View file

@ -1,19 +1,23 @@
.toggleSwitch { .toggleSwitch {
display: flex; display: flex;
gap: 6px; gap: 2px;
border-radius: 9999px; border-radius: var(--border-radius);
background-color: lightgray; background-color: lightgray;
font-size: 14px; font-size: 14px;
padding: 4px; padding: 0;
} }
.option { .option {
border-radius: 9999px; border-radius: var(--border-radius);
border: none;
background-color: inherit;
padding: 4px 12px; padding: 4px 12px;
cursor: pointer; cursor: pointer;
&.selected { &.selected {
background-color: gray; background-color: gray;
color: white;
} }
} }

View file

@ -19,13 +19,13 @@ export default function ToggleSwitch({
{options.map((option) => { {options.map((option) => {
const isSelected = option === value; const isSelected = option === value;
return ( return (
<div <button
key={option} key={option}
className={classNames(styles.option, isSelected && styles.selected)} className={classNames(styles.option, isSelected && styles.selected)}
onClick={() => setValue(option)} onClick={() => setValue(option)}
> >
{option} {option}
</div> </button>
); );
})} })}
</div> </div>