Skip to content

Commit 44fab7f

Browse files
author
Jose R Felix
committed
feat: add dark mode and update fule structure
1 parent 2aac474 commit 44fab7f

29 files changed

+766
-2126
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ Start off your writing journey with this Next.js markdown blog template.
1313
- Absolute imports.
1414
- SEO friendly.
1515
- Markdown code highlighting with [react-syntax-highlighter](https://www.npmjs.com/package/react-syntax-highlighter) and [PrismJs](https://prismjs.com/).
16+
- Dark Mode
17+
- WebP image support
1618

1719
## 🚀 Getting Started
1820

@@ -57,7 +59,7 @@ To learn more about Tailwind CSS, take a look at the following resources:
5759

5860
- [ ] Add Sitemap
5961
- [ ] Add RSS Feed
60-
- [ ] Dark Mode
62+
- [x] Dark Mode
6163
- [x] Add support for WebP images
6264
- [x] Add SEO Component
6365
- [x] Add Dynamic Site Metadata

assets/base.css

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
a:hover {
2+
@apply underline;
3+
}
4+
5+
span,
6+
p {
7+
@apply font-light;
8+
}

assets/components.css

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
.blur {
2+
-webkit-filter: blur(5px);
3+
filter: blur(5px);
4+
transition: filter 500ms ease-in, -webkit-filter 500ms ease-in;
5+
}
6+
7+
.blur.lazyloaded {
8+
-webkit-filter: blur(0);
9+
filter: blur(0);
10+
}

assets/main.css

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
@tailwind base;
2+
@tailwind components;
3+
@tailwind utilities;
4+
5+
@layer base {
6+
@import "./base.css";
7+
8+
a {
9+
@apply text-neon-orange dark:text-yellow-500;
10+
}
11+
}
12+
13+
@layer components {
14+
@import "./components.css";
15+
}

components/Layout.js

Lines changed: 0 additions & 37 deletions
This file was deleted.

components/Bio.js renamed to components/common/Bio/Bio.js

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
11
import clsx from "clsx";
22

3-
import Image from "./Image";
4-
import { getSiteMetaData } from "utils/helpers";
3+
import { Image } from "..";
4+
import { getSiteMetaData } from "@utils/helpers";
55

6-
export default function Bio({ className }) {
6+
export function Bio({ className }) {
77
const { author, social } = getSiteMetaData();
88

99
return (
1010
<div className={clsx(`flex items-center`, className)}>
1111
<Image
1212
className="flex-shrink-0 mb-0 mr-3 rounded-full w-14 h-14"
13-
src={require("../content/assets/profile.png")}
14-
webpSrc={require("../content/assets/profile.png?webp")}
15-
previewSrc={require("../content/assets/profile.png?lqip")}
13+
src={require("../../../content/assets/profile.png")}
14+
webpSrc={require("../../../content/assets/profile.png?webp")}
15+
previewSrc={require("../../../content/assets/profile.png?lqip")}
1616
alt="Profile"
1717
/>
18+
1819
<p className="text-base leading-7">
1920
Written by <b className="font-semibold">{author.name}</b>{" "}
2021
{author.summary}{" "}

components/common/Bio/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from "./Bio";

components/Image.js renamed to components/common/Image/Image.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import "lazysizes";
22

3-
export default function Image({ alt, src, previewSrc, webpSrc, className }) {
3+
export function Image({ alt, src, previewSrc, webpSrc, className }) {
44
return (
55
<picture className={className}>
66
<source type="image/webp" data-srcset={webpSrc} />
77
<source type="image/png" data-srcset={src} />
88
<img
9-
className={`lazyload blur-up ${className}`}
9+
className={`lazyload blur ${className}`}
1010
alt={alt}
1111
src={previewSrc}
1212
/>

components/common/Image/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from "./Image";

components/common/Layout/Layout.js

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
import { useState, useEffect } from "react";
2+
import clsx from "clsx";
3+
import Link from "next/link";
4+
import { useRouter } from "next/router";
5+
import { DarkModeSwitch } from "react-toggle-dark-mode";
6+
import { useTheme } from "next-themes";
7+
8+
export function Layout({ children }) {
9+
return (
10+
<div className="w-full min-h-screen dark:bg-gray-700 dark:text-white">
11+
<div className="max-w-screen-sm px-4 py-12 mx-auto antialiased font-body">
12+
<Header />
13+
<main>{children}</main>
14+
<footer className="text-lg font-light">
15+
© {new Date().getFullYear()}, Built with{" "}
16+
<a href="https://nextjs.org/">Next.js</a>
17+
&#128293;
18+
</footer>
19+
</div>
20+
</div>
21+
);
22+
}
23+
24+
const Header = () => {
25+
const { theme, setTheme } = useTheme();
26+
const { pathname } = useRouter();
27+
const [mounted, setMounted] = useState(false);
28+
29+
useEffect(() => setMounted(true), []);
30+
31+
const toggleDarkMode = (checked) => {
32+
const isDarkMode = checked;
33+
34+
if (isDarkMode) setTheme("dark");
35+
else setTheme("light");
36+
};
37+
38+
const isRoot = pathname === "/";
39+
const isDarkMode = theme === "dark";
40+
41+
if (!mounted) return null;
42+
43+
return (
44+
<header
45+
className={clsx("flex items-center justify-between ", {
46+
"mb-8": isRoot,
47+
"mb-2": !isRoot,
48+
})}
49+
>
50+
<div className={"max-w-md"}>
51+
{isRoot ? <LargeTitle /> : <SmallTitle />}
52+
</div>
53+
<DarkModeSwitch
54+
checked={isDarkMode}
55+
onChange={toggleDarkMode}
56+
className={isRoot ? 28 : 24}
57+
/>
58+
</header>
59+
);
60+
};
61+
62+
const LargeTitle = () => (
63+
<h1>
64+
<Link href="/">
65+
<a
66+
className={clsx(
67+
"text-3xl font-black leading-none text-black no-underline font-display",
68+
"sm:text-5xl",
69+
"dark:text-white"
70+
)}
71+
>
72+
Next.Js Starter Blog
73+
</a>
74+
</Link>
75+
</h1>
76+
);
77+
78+
const SmallTitle = () => (
79+
<h1>
80+
<Link href="/">
81+
<a
82+
className={clsx(
83+
"text-2xl font-black text-black no-underline font-display",
84+
"dark:text-white"
85+
)}
86+
>
87+
Next.Js Starter Blog
88+
</a>
89+
</Link>
90+
</h1>
91+
);

components/common/Layout/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from "./Layout";

components/Seo.js renamed to components/common/Seo/Seo.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import Head from "next/head";
2-
import { getSiteMetaData } from "utils/helpers";
32

4-
export default function SEO({ title, description = "" }) {
3+
import { getSiteMetaData } from "@utils/helpers";
4+
5+
export function SEO({ title, description = "" }) {
56
const siteMetadata = getSiteMetaData();
67

78
const metaDescription = description || siteMetadata.description;

components/common/Seo/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from "./Seo";

components/common/index.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export * from "./Bio";
2+
export * from "./Image";
3+
export * from "./Layout";
4+
export * from "./Seo";

config/seo.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"siteMetadata": {
3+
"title": "Next.js Starter Blog",
4+
"author": {
5+
"name": "Jose Felix",
6+
"summary": "who works building clean user interfaces with React."
7+
},
8+
"description": "A blog created with Next.js and Tailwind.css",
9+
"siteUrl": "https://nextjs-starter-blog-demo.netlify.app/",
10+
"language": "en-US",
11+
"social": {
12+
"twitter": "Jose_R_Felix"
13+
}
14+
}
15+
}

jsconfig.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
{
22
"compilerOptions": {
3-
"baseUrl": "."
3+
"baseUrl": ".",
4+
"paths": {
5+
"@components/*": ["components/*"],
6+
"@utils/*": ["utils/*"],
7+
"@assets/*": ["assets/*"],
8+
"@config/*": ["config/*"]
9+
}
410
}
511
}

next.config.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
const withPlugins = require("next-compose-plugins");
21
const optimizedImages = require("next-optimized-images");
32

4-
module.exports = withPlugins([optimizedImages]);
3+
module.exports = optimizedImages;

package.json

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,22 +14,25 @@
1414
"imagemin-optipng": "^8.0.0",
1515
"lazysizes": "^5.2.2",
1616
"lqip-loader": "^2.2.1",
17-
"next": "10.0.0",
18-
"next-compose-plugins": "^2.2.0",
17+
"next": "10.0.2",
18+
"next-compose-plugins": "^2.2.1",
1919
"next-optimized-images": "^2.6.2",
20-
"postcss-preset-env": "^6.7.0",
20+
"next-themes": "^0.0.10",
2121
"react": "17.0.1",
2222
"react-dom": "17.0.1",
23-
"react-markdown": "^5.0.2",
24-
"react-syntax-highlighter": "^15.2.1",
23+
"react-markdown": "^5.0.3",
24+
"react-syntax-highlighter": "^15.3.0",
25+
"react-toggle-dark-mode": "^1.0.3",
2526
"typeface-merriweather": "^1.1.13",
2627
"typeface-open-sans": "^1.1.13",
2728
"webp-loader": "^0.6.0"
2829
},
2930
"devDependencies": {
30-
"@tailwindcss/typography": "^0.2.0",
31+
"@tailwindcss/typography": "^0.3.1",
32+
"autoprefixer": "^10.0.2",
3133
"gray-matter": "^4.0.2",
32-
"tailwindcss": "^1.9.6"
34+
"postcss": "^8.1.8",
35+
"tailwindcss": "^2.0.1"
3336
},
3437
"license": "MIT",
3538
"repository": {

pages/_app.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
1-
import "styles/global.css";
1+
import { ThemeProvider } from "next-themes";
2+
3+
import "@assets/main.css";
24

35
import "typeface-open-sans";
46
import "typeface-merriweather";
57

68
export default function MyApp({ Component, pageProps }) {
7-
return <Component {...pageProps} />;
9+
return (
10+
<ThemeProvider defaultTheme="system" attribute="class">
11+
<Component {...pageProps} />
12+
</ThemeProvider>
13+
);
814
}

pages/_document.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import Document, { Head, Main, NextScript, Html } from "next/document";
22

3-
import { getSiteMetaData } from "utils/helpers";
3+
import { getSiteMetaData } from "@utils/helpers";
44

55
export default class MyDocument extends Document {
66
render() {

pages/index.js

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
import Link from "next/link";
22

3-
import Layout from "components/Layout";
4-
import Bio from "components/Bio";
5-
import SEO from "components/Seo";
6-
import { getSortedPosts } from "utils/posts";
3+
import { Layout, Bio, SEO } from "@components/common";
4+
import { getSortedPosts } from "@utils/posts";
75

86
export default function Home({ posts }) {
97
return (
@@ -15,7 +13,7 @@ export default function Home({ posts }) {
1513
<header className="mb-2">
1614
<h3 className="mb-2">
1715
<Link href={"/post/[slug]"} as={`/post/${slug}`}>
18-
<a className="text-4xl font-bold text-orange-600 font-display">
16+
<a className="text-4xl font-bold text-yellow-600 font-display">
1917
{title}
2018
</a>
2119
</Link>

0 commit comments

Comments
 (0)