wip: theme
parent
df126da2a6
commit
70f7b14a67
|
@ -1,6 +1,6 @@
|
||||||
import { ReactNode } from "react"
|
import { ReactNode } from "react"
|
||||||
|
|
||||||
export const Section: React.FC<{children?: ReactNode}> = ({children}) => <section className="text-gray-700">{children}</section>
|
export const Section: React.FC<{children?: ReactNode}> = ({children}) => <section className="text-gray-700 max-w-4xl">{children}</section>
|
||||||
export const UL: React.FC<{ children?: ReactNode }> = ({ children }) => <ul className="list-disc list-inside">{children}</ul>
|
export const UL: React.FC<{ children?: ReactNode }> = ({ children }) => <ul className="list-disc list-inside">{children}</ul>
|
||||||
|
|
||||||
export const SectionHeader: React.FC<{ text?: string, children?: ReactNode }> = ({ text, children }) => <div>
|
export const SectionHeader: React.FC<{ text?: string, children?: ReactNode }> = ({ text, children }) => <div>
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
import { Head } from "next/document";
|
|
||||||
import { Main } from "next/document";
|
|
||||||
import { NextScript } from "next/document";
|
|
||||||
import { Html } from "next/document";
|
|
||||||
import React from "react";
|
|
||||||
|
|
||||||
const document = () => <Html>
|
|
||||||
<Head />
|
|
||||||
<body className="scrollbar-track-gray-50 scrollbar-thumb-amber-400">
|
|
||||||
<Main />
|
|
||||||
<NextScript />
|
|
||||||
</body>
|
|
||||||
</Html>
|
|
||||||
|
|
||||||
export default document;
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { type NextPage } from "next";
|
import { type NextPage } from "next";
|
||||||
import Head from "next/head";
|
import Head from "next/head";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import React from "react";
|
import React, { useContext, useEffect, useState } from "react";
|
||||||
import { cva } from "class-variance-authority";
|
import { cva } from "class-variance-authority";
|
||||||
import type { VariantProps } from "class-variance-authority";
|
import type { VariantProps } from "class-variance-authority";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
|
@ -34,15 +34,42 @@ const circle = cva("absolute rounded-full border -z-10", {
|
||||||
pulse: "animate-pulse",
|
pulse: "animate-pulse",
|
||||||
ping: "animate-ping",
|
ping: "animate-ping",
|
||||||
},
|
},
|
||||||
|
theme: {
|
||||||
|
light: "",
|
||||||
|
dark: "",
|
||||||
|
},
|
||||||
color: {
|
color: {
|
||||||
back: "border-pink-50",
|
back: "",
|
||||||
fore: "border-amber-300",
|
fore: "",
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
compoundVariants: [
|
||||||
|
{
|
||||||
|
theme: "light",
|
||||||
|
color: "back",
|
||||||
|
className: "border-pink-50"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
theme: "light",
|
||||||
|
color: "fore",
|
||||||
|
className: "border-amber-300"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
theme: "dark",
|
||||||
|
color: "back",
|
||||||
|
className: "border-violet-300"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
theme: "dark",
|
||||||
|
color: "fore",
|
||||||
|
className: "border-amber-400"
|
||||||
|
},
|
||||||
|
],
|
||||||
defaultVariants: {
|
defaultVariants: {
|
||||||
size: 0,
|
size: 0,
|
||||||
animate: "none",
|
animate: "none",
|
||||||
color: "back"
|
color: "back",
|
||||||
|
theme: "light"
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -247,7 +274,7 @@ const About = () => {
|
||||||
Aspiring software engineer with intense drive and curiosity in software development.
|
Aspiring software engineer with intense drive and curiosity in software development.
|
||||||
</span>
|
</span>
|
||||||
</Section>
|
</Section>
|
||||||
<Section className="max-w-4xl">
|
<Section>
|
||||||
My computer infrastructure consists of:
|
My computer infrastructure consists of:
|
||||||
<UL>
|
<UL>
|
||||||
<li>24 home CPU cores</li>
|
<li>24 home CPU cores</li>
|
||||||
|
@ -324,9 +351,43 @@ const Navbar = () => <div className="flex justify-center items-center w-full z-5
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
type Theme = "dark" | "light";
|
||||||
|
|
||||||
|
const ThemeContext = React.createContext<{
|
||||||
|
theme: Theme,
|
||||||
|
systemTheme: Theme,
|
||||||
|
setThemePreference(theme: Theme): void,
|
||||||
|
} | undefined>(undefined);
|
||||||
|
const ThemeProvider: React.FC<{ children: React.ReactNode, prefer?: "light" | "dark" }> = ({ children, prefer }) => {
|
||||||
|
const pref = prefer ?? "light";
|
||||||
|
const [systemTheme, setSystemTheme] = useState<Theme>(pref);
|
||||||
|
const [themePref, setThemePref] = useState<Theme | undefined>(undefined);
|
||||||
|
// add a listener to system preference on which theme
|
||||||
|
// TODO: is there another way that remove event listener faster?
|
||||||
|
useEffect(() => {
|
||||||
|
console.log("useEffect called");
|
||||||
|
type EventType = { matches: boolean };
|
||||||
|
const onThemeChange = (event: EventType) => {
|
||||||
|
const newColorScheme = event.matches ? "dark" : "light";
|
||||||
|
setSystemTheme(newColorScheme);
|
||||||
|
};
|
||||||
|
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', onThemeChange);
|
||||||
|
return () => {
|
||||||
|
console.log("useEffect unmount");
|
||||||
|
window.matchMedia('(prefers-color-scheme: dark)').removeEventListener("change", onThemeChange)
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
return <ThemeContext.Provider value={{
|
||||||
|
theme: themePref ?? systemTheme,
|
||||||
|
systemTheme: systemTheme,
|
||||||
|
setThemePreference: setThemePref,
|
||||||
|
}}>{children}</ThemeContext.Provider>
|
||||||
|
}
|
||||||
|
const useTheme = () => useContext(ThemeContext);
|
||||||
|
|
||||||
const Home: NextPage = () => {
|
const Home: NextPage = () => {
|
||||||
return (
|
return (
|
||||||
|
<ThemeProvider>
|
||||||
<main className="overflow-x-hidden z-0 flex flex-col overflow-y-scroll h-screen
|
<main className="overflow-x-hidden z-0 flex flex-col overflow-y-scroll h-screen
|
||||||
items-center bg-pink-50/20 min-h-screen antialiased snap-y snap-proximity
|
items-center bg-pink-50/20 min-h-screen antialiased snap-y snap-proximity
|
||||||
scrollbar-track-gray-200 scrollbar-thumb-amber-300/50 scrollbar-thin"> {/*vimium users cry if snap-mandatory*/}
|
scrollbar-track-gray-200 scrollbar-thumb-amber-300/50 scrollbar-thin"> {/*vimium users cry if snap-mandatory*/}
|
||||||
|
@ -352,6 +413,7 @@ const Home: NextPage = () => {
|
||||||
<Projects />
|
<Projects />
|
||||||
</section>
|
</section>
|
||||||
</main>
|
</main>
|
||||||
|
</ThemeProvider>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue