wip: theme

api-as-package
pegasust 2022-11-20 04:37:35 +00:00
parent df126da2a6
commit 70f7b14a67
5 changed files with 322 additions and 275 deletions

View File

@ -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>

View File

@ -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;

View File

View File

View File

@ -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>
); );
}; };