a bit of styling
This commit is contained in:
parent
aa820d4910
commit
59a7849173
11 changed files with 75 additions and 14 deletions
1
.tokeignore
Normal file
1
.tokeignore
Normal file
|
@ -0,0 +1 @@
|
||||||
|
package-lock.json
|
0
lib/datascript.ts
Normal file
0
lib/datascript.ts
Normal 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;
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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>
|
||||||
);
|
);
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
7
src/widgets/Button.module.scss
Normal file
7
src/widgets/Button.module.scss
Normal 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
8
src/widgets/Button.tsx
Normal 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
13
src/widgets/InputBox.tsx
Normal 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} />;
|
||||||
|
}
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>
|
||||||
|
|
Loading…
Reference in a new issue