Skip to content

Commit

Permalink
feat: darkMode
Browse files Browse the repository at this point in the history
  • Loading branch information
Dup4 committed Aug 9, 2022
1 parent 35c7f99 commit 6cce279
Show file tree
Hide file tree
Showing 17 changed files with 412 additions and 219 deletions.
4 changes: 2 additions & 2 deletions .prettierrc
@@ -1,5 +1,5 @@
{
"trailingComma": "all",
"bracketSpacing": false,
"bracketSameLine": true,
"bracketSpacing": true,
"bracketSameLine": true
}
1 change: 1 addition & 0 deletions .vscode/settings.json
Expand Up @@ -11,6 +11,7 @@
"esmo",
"esno",
"mathjax",
"Mkdist",
"mkdocs",
"nextui",
"nprogress",
Expand Down
6 changes: 4 additions & 2 deletions examples/mathjax-render-react-example/package.json
Expand Up @@ -10,15 +10,17 @@
"dependencies": {
"@nextui-org/react": "1.0.0-beta.7",
"@tailwindcss/typography": "^0.5.4",
"classname": "^0.0.0",
"@types/classnames": "^2.3.1",
"classnames": "^2.3.1",
"mathjax-render": "workspace:*",
"mathjax-render-react": "workspace:*",
"next": "12.2.4",
"next-themes": "^0.2.0",
"nprogress": "^0.2.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"tailwindcss": "^3.1.8"
"tailwindcss": "^3.1.8",
"use-delayed-render": "^0.0.7"
},
"devDependencies": {
"@types/node": "17.0.39",
Expand Down
114 changes: 114 additions & 0 deletions examples/mathjax-render-react-example/src/components/Container.tsx
@@ -0,0 +1,114 @@
import Head from "next/head";
import { useRouter } from "next/router";
import { useState, useEffect } from "react";
import { useTheme } from "next-themes";
import NextLink from "next/link";
import cn from "classnames";

import Footer from "@components/Footer";
import MobileMenu from "@components/MobileMenu";

// eslint-disable-next-line @typescript-eslint/no-explicit-any
function NavItem({ href, text }: any) {
const router = useRouter();
const isActive = router.asPath === href;

return (
<NextLink href={href}>
<a
className={cn(
isActive
? "font-semibold text-gray-800 dark:text-gray-200"
: "font-normal text-gray-600 dark:text-gray-400",
"hidden md:inline-block p-1 sm:px-3 sm:py-2 rounded-lg hover:bg-gray-200 dark:hover:bg-gray-800 transition-all",
)}>
<span className="capsize">{text}</span>
</a>
</NextLink>
);
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
export default function Container(props: any) {
const [mounted, setMounted] = useState(false);
const { resolvedTheme, setTheme } = useTheme();

// After mounting, we have access to the theme
useEffect(() => setMounted(true), []);

const hostName = "https://mathjax-render.vercel.app";

const { children, ...customMeta } = props;
const router = useRouter();
const meta = {
title: "MathJax Render",
description: `Mathjax Render.`,
image: "/favicon.ico",
type: "website",
...customMeta,
};

return (
<div className="bg-gray-50 dark:bg-gray-900">
<Head>
<title>{meta.title}</title>
<meta name="robots" content="follow, index" />
<meta content={meta.description} name="description" />
<meta property="og:url" content={`${hostName}${router.asPath}`} />
<link rel="canonical" href={`${hostName}${router.asPath}`} />
<meta property="og:type" content={meta.type} />
<meta property="og:site_name" content="MathJax Render" />
<meta property="og:description" content={meta.description} />
<meta property="og:title" content={meta.title} />
<meta property="og:image" content={meta.image} />
</Head>
<div className="flex flex-col justify-center px-8">
<nav className="flex items-center justify-between w-full relative max-w-2xl border-gray-200 dark:border-gray-700 mx-auto pt-8 pb-8 sm:pb-16 text-gray-900 bg-gray-50 dark:bg-gray-900 bg-opacity-60 dark:text-gray-100">
<div className="ml-[-0.60rem]">
<MobileMenu />
<NavItem href="/" text="Home" />
<NavItem href="/reference" text="Reference" />
</div>
<button
aria-label="Toggle Dark Mode"
type="button"
className="w-9 h-9 bg-gray-200 rounded-lg dark:bg-gray-600 flex items-center justify-center hover:ring-2 ring-gray-300 transition-all"
onClick={() =>
setTheme(resolvedTheme === "dark" ? "light" : "dark")
}>
{mounted && (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
className="w-5 h-5 text-gray-800 dark:text-gray-200">
{resolvedTheme === "dark" ? (
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z"
/>
) : (
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z"
/>
)}
</svg>
)}
</button>
</nav>
</div>
<main
id="skip"
className="flex flex-col justify-center px-8 bg-gray-50 dark:bg-gray-900">
{children}
<Footer />
</main>
</div>
);
}
60 changes: 60 additions & 0 deletions examples/mathjax-render-react-example/src/components/Footer.tsx
@@ -0,0 +1,60 @@
import Link from "next/link";
import ImageWithTheme from "./ImageWithTheme";

// eslint-disable-next-line @typescript-eslint/no-explicit-any
const ExternalLink = ({ href, children }: any) => (
<a
className="text-gray-500 hover:text-gray-600 transition"
target="_blank"
rel="noopener noreferrer"
href={href}>
{children}
</a>
);

export default function Footer() {
return (
<>
<footer className="flex flex-col justify-center items-start max-w-2xl mx-auto w-full mb-8">
<hr className="w-full border-1 border-gray-200 dark:border-gray-800 mb-8" />
<div className="w-full max-w-2xl grid grid-cols-1 gap-4 pb-16 sm:grid-cols-3">
<div className="flex flex-col space-y-4">
<Link href="/">
<a className="text-gray-500 hover:text-gray-600 transition">
Home
</a>
</Link>
</div>
<div className="flex flex-col space-y-4">
<ExternalLink href="https://github.com/Dup4/mathjax-render">
GitHub
</ExternalLink>
</div>
<div className="flex flex-col space-y-4">
<Link href="/reference">
<a className="text-gray-500 hover:text-gray-600 transition">
Reference
</a>
</Link>
</div>
</div>
<div>
<a
href="https://vercel.com"
target="_blank"
rel="noopener noreferrer">
Powered by{" "}
<span>
<ImageWithTheme
alt="Vercel Logo"
light="/vercel-light.svg"
dark="/vercel-dark.svg"
width={72}
height={16}></ImageWithTheme>
</span>
</a>
</div>
</footer>
</>
);
}
@@ -1,13 +1,14 @@
import Image from 'next/image';
import { useTheme } from 'next-themes';
import Image from "next/image";
import { useTheme } from "next-themes";

// eslint-disable-next-line @typescript-eslint/no-explicit-any
export default function ImageWithTheme(props: any) {
const { theme } = useTheme();

return (
<Image
alt={props.alt}
src={theme === 'light' ? props.light : props.dark}
src={theme === "light" ? props.light : props.dark}
{...props}
/>
);
Expand Down
116 changes: 116 additions & 0 deletions examples/mathjax-render-react-example/src/components/MobileMenu.tsx
@@ -0,0 +1,116 @@
import cn from "classnames";
import Link from "next/link";
import useDelayedRender from "use-delayed-render";
import { useState, useEffect } from "react";

import styles from "@styles/mobile-menu.module.css";

export default function MobileMenu() {
const [isMenuOpen, setIsMenuOpen] = useState(false);
const { mounted: isMenuMounted, rendered: isMenuRendered } = useDelayedRender(
isMenuOpen,
{
enterDelay: 20,
exitDelay: 300,
},
);

function toggleMenu() {
if (isMenuOpen) {
setIsMenuOpen(false);
document.body.style.overflow = "";
} else {
setIsMenuOpen(true);
document.body.style.overflow = "hidden";
}
}

useEffect(() => {
return function cleanup() {
document.body.style.overflow = "";
};
}, []);

return (
<>
<button
className={cn(styles.burger, "visible md:hidden")}
aria-label="Toggle menu"
type="button"
onClick={toggleMenu}>
<MenuIcon data-hide={isMenuOpen} />
<CrossIcon data-hide={!isMenuOpen} />
</button>
{isMenuMounted && (
<ul
className={cn(
styles.menu,
"flex flex-col absolute bg-gray-100 dark:bg-gray-900",
isMenuRendered && styles.menuRendered,
)}>
<li
className="border-b border-gray-300 dark:border-gray-700 text-gray-900 dark:text-gray-100 text-sm font-semibold"
style={{ transitionDelay: "150ms" }}>
<Link href="/">
<a className="flex w-auto pb-4">Home</a>
</Link>
</li>
<li
className="border-b border-gray-300 dark:border-gray-700 text-gray-900 dark:text-gray-100 text-sm font-semibold"
style={{ transitionDelay: "175ms" }}>
<Link href="/reference">
<a className="flex w-auto pb-4">Reference</a>
</Link>
</li>
</ul>
)}
</>
);
}

function MenuIcon(props: JSX.IntrinsicElements["svg"]) {
return (
<svg
className="h-5 w-5 absolute text-gray-900 dark:text-gray-100"
width="20"
height="20"
viewBox="0 0 20 20"
fill="none"
{...props}>
<path
d="M2.5 7.5H17.5"
stroke="currentColor"
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
d="M2.5 12.5H17.5"
stroke="currentColor"
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
);
}

function CrossIcon(props: JSX.IntrinsicElements["svg"]) {
return (
<svg
className="h-5 w-5 absolute text-gray-900 dark:text-gray-100"
viewBox="0 0 24 24"
width="24"
height="24"
stroke="currentColor"
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
fill="none"
shapeRendering="geometricPrecision"
{...props}>
<path d="M18 6L6 18" />
<path d="M6 6l12 12" />
</svg>
);
}

1 comment on commit 6cce279

@vercel
Copy link

@vercel vercel bot commented on 6cce279 Aug 9, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

mathjax-render – ./

mathjax-render-git-main-dup4.vercel.app
mathjax-render-dup4.vercel.app
mathjax-render.vercel.app

Please sign in to comment.