Skip to content

Commit 514090d

Browse files
committed
Add clickable font cycling on clock face
Clock face cycles between DM Serif Display, Abril Fatface, Instrument Serif and thin Inter on click. Selection persists via new useLocal hook backed by localStorage. Also nudges arrow border and fullscreen icon size.
1 parent 8890ec6 commit 514090d

6 files changed

Lines changed: 55 additions & 5 deletions

File tree

‎frontend/index.html‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
1111
<link rel="alternate icon" href="/favicon.ico" />
1212
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
13-
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=Space+Grotesk:wght@400;500;600&display=swap" rel="stylesheet" />
13+
<link href="https://fonts.googleapis.com/css2?family=Abril+Fatface&family=DM+Serif+Display&family=Instrument+Serif&family=Inter:wght@300;400;500;600;700&family=Space+Grotesk:wght@400;500;600&display=swap" rel="stylesheet" />
1414
<link href="https://fonts.googleapis.com/icon?family=Material+Icons+Outlined" rel="stylesheet" />
1515
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet" />
1616
<title>halo</title>

‎frontend/src/App.tsx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ const App = () => {
184184
}}
185185
onClick={toggleFullscreen}
186186
>
187-
<Icon size={22}>{!fullscreen ? "fullscreen" : "fullscreen_exit"}</Icon>
187+
<Icon size={20}>{!fullscreen ? "fullscreen" : "fullscreen_exit"}</Icon>
188188
</button>
189189
<div
190190
css={{

‎frontend/src/components/Arrow.tsx‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ const Arrow: React.FC<ArrowProps> = ({ className, deg }) => {
2727
height: "inherit",
2828
width: "inherit",
2929
borderRadius: "100%",
30-
border: `1px solid ${theme.colors.text.main}`,
31-
opacity: 0.5,
30+
border: `2px solid ${theme.colors.text.main}`,
31+
opacity: 0.75,
3232
}}
3333
/>
3434
<div

‎frontend/src/components/CurrentTime.tsx‎

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,29 @@ import { fi } from "date-fns/locale/fi";
44
import React, { memo } from "react";
55

66
import useCurrentTime from "../hooks/useCurrentTime";
7+
import useLocal from "../hooks/useLocal";
78

89
type CurrentTimeProps = {} & React.HTMLAttributes<HTMLDivElement>;
910

11+
const DISPLAY_FONTS = [
12+
{ family: '"DM Serif Display", Georgia, serif', weight: 400 },
13+
{ family: '"Abril Fatface", Georgia, serif', weight: 400 },
14+
{ family: '"Instrument Serif", Georgia, serif', weight: 400 },
15+
{ family: '"Inter", system-ui, sans-serif', weight: 300 },
16+
];
17+
1018
const CurrentTime: React.FC<CurrentTimeProps> = ({ className }) => {
1119
const theme = useTheme();
1220
const currentTime = useCurrentTime();
21+
const [fontIndex, setFontIndex] = useLocal("clockFontIndex", 0);
22+
const displayFont = DISPLAY_FONTS[fontIndex] ?? DISPLAY_FONTS[0];
1323

1424
const hh = format(currentTime, "HH");
1525
const mm = format(currentTime, "mm");
1626
const ss = format(currentTime, "ss");
1727

28+
const cycleFont = () => setFontIndex((i) => (i + 1) % DISPLAY_FONTS.length);
29+
1830
return (
1931
<div
2032
className={className}
@@ -25,15 +37,19 @@ const CurrentTime: React.FC<CurrentTimeProps> = ({ className }) => {
2537
}}
2638
>
2739
<div
40+
onClick={cycleFont}
2841
css={{
42+
fontFamily: displayFont.family,
2943
fontSize: "7em",
3044
lineHeight: 1,
31-
fontWeight: 400,
45+
fontWeight: displayFont.weight,
3246
letterSpacing: "-0.02em",
3347
fontVariantNumeric: "tabular-nums",
3448
display: "flex",
3549
alignItems: "baseline",
3650
gap: "0.05em",
51+
cursor: "pointer",
52+
userSelect: "none",
3753
}}
3854
>
3955
<span>{hh}</span>

‎frontend/src/hooks/useLocal.ts‎

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { useCallback, useState } from "react";
2+
3+
const useLocal = <T>(key: string, initialValue: T) => {
4+
const [value, setValue] = useState<T>(() => {
5+
try {
6+
const raw = localStorage.getItem(key);
7+
return raw !== null ? (JSON.parse(raw) as T) : initialValue;
8+
} catch {
9+
return initialValue;
10+
}
11+
});
12+
13+
const set = useCallback(
14+
(next: T | ((prev: T) => T)) => {
15+
setValue((prev) => {
16+
const resolved =
17+
typeof next === "function" ? (next as (p: T) => T)(prev) : next;
18+
try {
19+
localStorage.setItem(key, JSON.stringify(resolved));
20+
} catch {
21+
/* ignore quota / disabled storage */
22+
}
23+
return resolved;
24+
});
25+
},
26+
[key],
27+
);
28+
29+
return [value, set] as const;
30+
};
31+
32+
export default useLocal;

‎frontend/src/themes.ts‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ declare module "@emotion/react" {
1515
fonts: {
1616
body: string;
1717
heading: string;
18+
display: string;
1819
};
1920
colors: {
2021
body: string;
@@ -64,6 +65,7 @@ declare module "@emotion/react" {
6465
const fonts = {
6566
body: '"Inter", system-ui, sans-serif',
6667
heading: '"Space Grotesk", "Inter", sans-serif',
68+
display: '"Abril Fatface", "Space Grotesk", monospace',
6769
};
6870

6971
const typography = {

0 commit comments

Comments
 (0)