feat: implement theme toggle switch

This commit is contained in:
Stevan Freeborn
2023-04-20 23:36:52 -05:00
parent 8eb224e018
commit 88d4c1c339
10 changed files with 138 additions and 70 deletions
+1
View File
@@ -2,6 +2,7 @@
"typescript.tsdk": "node_modules\\typescript\\lib", "typescript.tsdk": "node_modules\\typescript\\lib",
"typescript.enablePromptUseWorkspaceTsdk": true, "typescript.enablePromptUseWorkspaceTsdk": true,
"cSpell.words": [ "cSpell.words": [
"atrule",
"BCDR", "BCDR",
"configparser", "configparser",
"DDTHH", "DDTHH",
+1 -2
View File
@@ -76,7 +76,7 @@
.dropdownSelect { .dropdownSelect {
color: #64adac; color: #64adac;
background-color: #05254a; background-color: inherit;
border: none; border: none;
border-radius: 5px; border-radius: 5px;
cursor: pointer; cursor: pointer;
@@ -90,7 +90,6 @@
} }
.selectItem { .selectItem {
background-color: #05254a;
color: #64adac; color: #64adac;
cursor: pointer; cursor: pointer;
font-weight: bold; font-weight: bold;
@@ -1,3 +1,8 @@
.wrapper {
display: flex;
width: 100%;
}
.container { .container {
display: flex; display: flex;
width: 100%; width: 100%;
@@ -6,10 +11,4 @@
align-items: center; align-items: center;
margin: 0 auto; margin: 0 auto;
overflow-y: auto; overflow-y: auto;
}
.divider {
width: 100%;
height: 1px;
background-color: #848586;
} }
+29
View File
@@ -0,0 +1,29 @@
'use client';
import { themes, useThemeContext } from '../theme';
import { DocSection, DocsStructure } from '../types/types';
import Main from './Main';
import NavBar from './NavBar';
import styles from './Page.module.css';
import SideBar from './SideBar';
export default function Page({
version,
versionSections,
}: {
version: DocsStructure;
versionSections: DocSection[];
}) {
const { theme } = useThemeContext();
const themeStyles = themes[theme];
return (
<div className={styles.wrapper} style={themeStyles}>
<SideBar version={version} />
<div className={styles.container}>
<NavBar version={version} />
<Main versionSections={versionSections} />
</div>
</div>
);
}
+74 -22
View File
@@ -3,9 +3,9 @@
flex-direction: column; flex-direction: column;
height: 100%; height: 100%;
border-right: 1px solid #848586; border-right: 1px solid #848586;
padding: 1rem; padding: 0 1rem;
overflow: auto; overflow: auto;
scrollbar-color: transparent #0b3766; background-color: inherit;
} }
@media screen and (max-width: 1000px) { @media screen and (max-width: 1000px) {
@@ -14,27 +14,20 @@
} }
} }
.container::-webkit-scrollbar {
background-color: transparent;
}
.container::-webkit-scrollbar-thumb {
background-color: transparent;
border-radius: 10px;
}
.container:hover::-webkit-scrollbar-thumb {
background-color: #0b3766;
}
.container::-webkit-scrollbar-corner {
background-color: transparent;
}
.link { .link {
text-decoration: none; text-decoration: none;
} }
.titleContainer {
position: sticky;
top: 0;
display: flex;
align-items: center;
justify-content: space-between;
background-color: inherit;
padding-top: 1rem;
}
.title { .title {
font-size: 1rem; font-size: 1rem;
white-space: nowrap; white-space: nowrap;
@@ -43,7 +36,6 @@
.onspring { .onspring {
font-weight: bold; font-weight: bold;
color: white;
} }
.api { .api {
@@ -73,11 +65,10 @@
.link, .link,
.activeLink { .activeLink {
text-decoration: none; text-decoration: none;
color: #a3acb9;
} }
.link:hover { .link:hover {
color: white; color: #64adac;
} }
.activeLink { .activeLink {
@@ -100,4 +91,65 @@
.chevron { .chevron {
margin-left: 0.5rem; margin-left: 0.5rem;
}
.switch {
position: relative;
display: inline-block;
width: 60px;
height: 20px;
margin-bottom: 1rem;
}
.switch input {
opacity: 0;
width: 0;
height: 0;
}
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
-webkit-transition: .4s;
transition: .4s;
}
.slider:before {
text-align: center;
position: absolute;
content: "";
height: 12px;
width: 12px;
left: 4px;
bottom: 4px;
background-color: white;
-webkit-transition: .4s;
transition: .4s;
}
input:checked+.slider {
background-color: #05254a;
}
input:focus+.slider {
box-shadow: 0 0 1px #05254a;
}
input:checked+.slider:before {
-webkit-transform: translateX(40px);
-ms-transform: translateX(40px);
transform: translateX(40px);
}
.slider.round {
border-radius: 34px;
}
.slider.round:before {
border-radius: 50%;
} }
+6 -3
View File
@@ -97,7 +97,7 @@ export default function SideBar({
return ( return (
<div className={styles.container}> <div className={styles.container}>
<div> <div className={styles.titleContainer}>
<Link href="/" className={styles.link}> <Link href="/" className={styles.link}>
<h1 className={styles.title}> <h1 className={styles.title}>
<span className={styles.onspring}> <span className={styles.onspring}>
@@ -106,14 +106,17 @@ export default function SideBar({
<span className={styles.api}>API</span> <span className={styles.api}>API</span>
</h1> </h1>
</Link> </Link>
<label className="switch"> <label className={styles.switch}>
<input <input
title="Toggle dark mode"
onChange={() => onChange={() =>
setTheme(theme === 'light' ? 'dark' : 'light') setTheme(theme === 'light' ? 'dark' : 'light')
} }
type="checkbox" type="checkbox"
/> />
<span className="slider round"></span> <span
className={`${styles.slider} ${styles.round}`}
></span>
</label> </label>
</div> </div>
<ListTree docs={version.docs} /> <ListTree docs={version.docs} />
+3 -8
View File
@@ -15,15 +15,10 @@ body {
font-family: 'Roboto', sans-serif; font-family: 'Roboto', sans-serif;
font-size: 16px; font-size: 16px;
line-height: 1.5; line-height: 1.5;
color: white;
background-color: #05254a;
display: flex; display: flex;
} }
.container { a {
display: flex; text-decoration: none;
flex-direction: column; color: inherit;
height: 100%;
width: 100%;
min-width: 0;
} }
+6 -11
View File
@@ -1,22 +1,17 @@
import { versionTwo } from '@/docs/version_002/docsStructure'; import { versionTwo } from '@/docs/version_002/docsStructure';
import Main from './components/Main'; import Page from './components/Page';
import NavBar from './components/NavBar';
import SideBar from './components/SideBar';
import { loadSections } from './lib/markdoc'; import { loadSections } from './lib/markdoc';
export default function Page() { export default function VersionTwo() {
const versionTwoSections = loadSections( const versionTwoSections = loadSections(
versionTwo.version, versionTwo.version,
versionTwo.docs versionTwo.docs
); );
return ( return (
<> <Page
<SideBar version={versionTwo} /> version={versionTwo}
<div className="container"> versionSections={versionTwoSections}
<NavBar version={versionTwo} /> />
<Main versionSections={versionTwoSections} />
</div>
</>
); );
} }
+7 -7
View File
@@ -7,8 +7,6 @@ import {
useState, useState,
} from 'react'; } from 'react';
const ThemeContext = createContext({});
const darkTheme = { const darkTheme = {
color: 'white', color: 'white',
backgroundColor: '#05254a', backgroundColor: '#05254a',
@@ -19,17 +17,14 @@ const lightTheme = {
backgroundColor: 'white', backgroundColor: 'white',
}; };
export const themes = { const ThemeContext = createContext({});
dark: darkTheme,
light: lightTheme,
} as { [key: string]: { [key: string]: string } };
export const ThemeContextProvider = ({ export const ThemeContextProvider = ({
children, children,
}: { }: {
children: ReactNode; children: ReactNode;
}) => { }) => {
const [theme, setTheme] = useState('light'); const [theme, setTheme] = useState('dark');
return ( return (
<ThemeContext.Provider value={{ theme, setTheme }}> <ThemeContext.Provider value={{ theme, setTheme }}>
@@ -38,5 +33,10 @@ export const ThemeContextProvider = ({
); );
}; };
export const themes = {
dark: darkTheme,
light: lightTheme,
} as { [key: string]: { [key: string]: string } };
export const useThemeContext: any = () => export const useThemeContext: any = () =>
useContext(ThemeContext); useContext(ThemeContext);
+6 -11
View File
@@ -1,22 +1,17 @@
import { versionOne } from '@/docs/version_001/docsStructure'; import { versionOne } from '@/docs/version_001/docsStructure';
import Main from '../components/Main'; import Page from '../components/Page';
import NavBar from '../components/NavBar';
import SideBar from '../components/SideBar';
import { loadSections } from '../lib/markdoc'; import { loadSections } from '../lib/markdoc';
export default function Page() { export default function VersionOne() {
const versionOneSections = loadSections( const versionOneSections = loadSections(
versionOne.version, versionOne.version,
versionOne.docs versionOne.docs
); );
return ( return (
<> <Page
<SideBar version={versionOne} /> version={versionOne}
<div className="container"> versionSections={versionOneSections}
<NavBar version={versionOne} /> />
<Main versionSections={versionOneSections} />
</div>
</>
); );
} }