From f76bc143cc491e2d5ae74c64894e07bfb7e26bec Mon Sep 17 00:00:00 2001
From: Brad Garropy
Date: Tue, 27 Apr 2021 23:28:25 -0500
Subject: [PATCH] dark mode. (#205)
---
gatsby-config.js | 14 +
package-lock.json | 259 ++++++++++++++++++
package.json | 2 +
src/components/ColorTheme/ColorTheme.js | 48 ++++
src/components/ColorTheme/ColorTheme.test.js | 30 ++
src/components/ColorTheme/index.js | 1 +
src/components/Hamburger/Hamburger.js | 7 +-
src/components/Hamburger/Hamburger.test.js | 17 +-
src/components/Header/Header.js | 14 +-
src/components/Header/Header.test.js | 7 +
src/components/Hero/Hero.js | 5 +-
src/components/LatestVideos/LatestVideos.js | 7 +-
src/components/Layout/Layout.js | 5 +-
src/components/LinkButton/LinkButton.js | 6 +-
src/components/Logo/Logo.js | 1 +
.../MobileNavigation/MobileNavigation.js | 15 +-
.../MobileNavigation/MobileNavigation.test.js | 79 +++---
src/components/Navigation/Navigation.js | 3 +-
src/components/Now/Now.js | 6 +-
src/components/Podcast/Podcast.js | 15 +-
src/components/PostList/PostList.js | 1 +
src/components/PostMeta/PostMeta.js | 2 +-
src/components/PostSearchBar/PostSearchBar.js | 3 +-
src/components/PostTitle/PostTitle.js | 2 +-
src/components/Project/Project.js | 7 +-
src/components/SocialLink/SocialLink.js | 3 +-
src/context/App.js | 3 +
src/context/index.js | 1 +
src/hooks/index.js | 1 +
src/hooks/useApp.js | 9 +
src/pages/404.js | 5 +-
src/pages/blog.js | 5 +-
src/pages/contact.js | 5 +-
src/pages/hire-me.js | 5 +-
src/pages/index.js | 5 +-
src/pages/now.js | 5 +-
src/pages/resume.js | 5 +-
src/pages/sponsors.js | 10 +-
src/pages/uses.js | 5 +-
src/styles/GlobalStyles.js | 21 +-
src/styles/partials.js | 3 +-
src/svg/moon.svg | 14 +
src/svg/sun.svg | 14 +
src/templates/now.js | 5 +-
src/templates/post.js | 5 +-
src/templates/topic.js | 5 +-
src/test-utils/file.js | 1 +
src/test-utils/generators.js | 12 +
src/test-utils/mocks.js | 8 +
49 files changed, 566 insertions(+), 145 deletions(-)
create mode 100644 src/components/ColorTheme/ColorTheme.js
create mode 100644 src/components/ColorTheme/ColorTheme.test.js
create mode 100644 src/components/ColorTheme/index.js
create mode 100644 src/context/index.js
create mode 100644 src/hooks/useApp.js
create mode 100644 src/svg/moon.svg
create mode 100644 src/svg/sun.svg
create mode 100644 src/test-utils/file.js
create mode 100644 src/test-utils/generators.js
diff --git a/gatsby-config.js b/gatsby-config.js
index 40e6ecd2..66bd9ab4 100644
--- a/gatsby-config.js
+++ b/gatsby-config.js
@@ -190,6 +190,20 @@ const config = {
{
resolve: "@bradgarropy/gatsby-plugin-seo",
},
+ {
+ resolve: "gatsby-plugin-react-svg",
+ options: {
+ rule: {
+ include: /svg/,
+ },
+ },
+ },
+ {
+ resolve: "gatsby-plugin-layout",
+ options: {
+ component: require.resolve("./src/components/Layout/Layout.js"),
+ },
+ },
],
}
diff --git a/package-lock.json b/package-lock.json
index 543c3801..613578cd 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -21,7 +21,9 @@
"gatsby-plugin-catch-links": "^3.0.0",
"gatsby-plugin-google-analytics": "^3.0.0",
"gatsby-plugin-image": "^1.0.1",
+ "gatsby-plugin-layout": "^2.4.0",
"gatsby-plugin-react-helmet": "^4.0.0",
+ "gatsby-plugin-react-svg": "^3.0.1",
"gatsby-plugin-sharp": "^3.0.1",
"gatsby-plugin-sitemap": "^3.0.0",
"gatsby-plugin-styled-components": "^4.0.0",
@@ -17843,6 +17845,20 @@
"react-dom": "^16.9.0 || ^17.0.0"
}
},
+ "node_modules/gatsby-plugin-layout": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/gatsby-plugin-layout/-/gatsby-plugin-layout-2.4.0.tgz",
+ "integrity": "sha512-NXX+bMDWmsb8r/GE5GHG1rSpypYCi7wUEuWf1ceDRafpEO8Bo4jI2Sx777vunTUgWLq6SN92EgUBm6d8D5AcfQ==",
+ "dependencies": {
+ "@babel/runtime": "^7.12.5"
+ },
+ "engines": {
+ "node": ">=12.13.0"
+ },
+ "peerDependencies": {
+ "gatsby": "^3.0.0-next.0"
+ }
+ },
"node_modules/gatsby-plugin-page-creator": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/gatsby-plugin-page-creator/-/gatsby-plugin-page-creator-3.3.0.tgz",
@@ -17879,6 +17895,17 @@
"react-helmet": "^5.1.3 || ^6.0.0"
}
},
+ "node_modules/gatsby-plugin-react-svg": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/gatsby-plugin-react-svg/-/gatsby-plugin-react-svg-3.0.1.tgz",
+ "integrity": "sha512-bjVSCAOeRWmf5a96/BL81sHITGFV/2Ql+IwP3ET5O5BZYOpt0f7QVCspkvCj0hsy4BJgCgANpzFstuaxUNsojA==",
+ "dependencies": {
+ "svg-react-loader": "^0.4.4"
+ },
+ "peerDependencies": {
+ "gatsby": "^3.0.0 || ^2.0.0"
+ }
+ },
"node_modules/gatsby-plugin-sharp": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/gatsby-plugin-sharp/-/gatsby-plugin-sharp-3.3.0.tgz",
@@ -31185,6 +31212,11 @@
}
]
},
+ "node_modules/ramda": {
+ "version": "0.21.0",
+ "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.21.0.tgz",
+ "integrity": "sha1-oAGr7bP/YQd9T/HVd9RN536NCjU="
+ },
"node_modules/randomatic": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz",
@@ -32756,6 +32788,11 @@
"aproba": "^1.1.1"
}
},
+ "node_modules/rx": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/rx/-/rx-4.1.0.tgz",
+ "integrity": "sha1-pfE/957zt0D+MKqAP7CfmIBdR4I="
+ },
"node_modules/rx-lite": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz",
@@ -35047,6 +35084,107 @@
"node": ">=8"
}
},
+ "node_modules/svg-react-loader": {
+ "version": "0.4.6",
+ "resolved": "https://registry.npmjs.org/svg-react-loader/-/svg-react-loader-0.4.6.tgz",
+ "integrity": "sha512-HVEypjWQsQuJdBIPzXGxpmQsQts7QwfQuYgK1rah6BVCMoLNSCh/ESKVNd7/tHq8DkWYHHTyaUMDA1FjqZYrgA==",
+ "dependencies": {
+ "css": "2.2.4",
+ "loader-utils": "1.1.0",
+ "ramda": "0.21.0",
+ "rx": "4.1.0",
+ "traverse": "0.6.6",
+ "xml2js": "0.4.17"
+ }
+ },
+ "node_modules/svg-react-loader/node_modules/big.js": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz",
+ "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/svg-react-loader/node_modules/css": {
+ "version": "2.2.4",
+ "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz",
+ "integrity": "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==",
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "source-map": "^0.6.1",
+ "source-map-resolve": "^0.5.2",
+ "urix": "^0.1.0"
+ }
+ },
+ "node_modules/svg-react-loader/node_modules/emojis-list": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz",
+ "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=",
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/svg-react-loader/node_modules/json5": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz",
+ "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=",
+ "bin": {
+ "json5": "lib/cli.js"
+ }
+ },
+ "node_modules/svg-react-loader/node_modules/loader-utils": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz",
+ "integrity": "sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0=",
+ "dependencies": {
+ "big.js": "^3.1.3",
+ "emojis-list": "^2.0.0",
+ "json5": "^0.5.0"
+ },
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/svg-react-loader/node_modules/source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/svg-react-loader/node_modules/source-map-resolve": {
+ "version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz",
+ "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==",
+ "dependencies": {
+ "atob": "^2.1.2",
+ "decode-uri-component": "^0.2.0",
+ "resolve-url": "^0.2.1",
+ "source-map-url": "^0.4.0",
+ "urix": "^0.1.0"
+ }
+ },
+ "node_modules/svg-react-loader/node_modules/xml2js": {
+ "version": "0.4.17",
+ "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.17.tgz",
+ "integrity": "sha1-F76T6q4/O3eTWceVtBlwWogX6Gg=",
+ "dependencies": {
+ "sax": ">=0.6.0",
+ "xmlbuilder": "^4.1.0"
+ }
+ },
+ "node_modules/svg-react-loader/node_modules/xmlbuilder": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-4.2.1.tgz",
+ "integrity": "sha1-qlijBBoGb5DqoWwvU4n/GfP0YaU=",
+ "dependencies": {
+ "lodash": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
"node_modules/svgo": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz",
@@ -35765,6 +35903,11 @@
"node": ">=8"
}
},
+ "node_modules/traverse": {
+ "version": "0.6.6",
+ "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.6.tgz",
+ "integrity": "sha1-y99WD9e5r2MlAv7UD5GMFX6pcTc="
+ },
"node_modules/trim": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz",
@@ -53028,6 +53171,14 @@
"prop-types": "^15.7.2"
}
},
+ "gatsby-plugin-layout": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/gatsby-plugin-layout/-/gatsby-plugin-layout-2.4.0.tgz",
+ "integrity": "sha512-NXX+bMDWmsb8r/GE5GHG1rSpypYCi7wUEuWf1ceDRafpEO8Bo4jI2Sx777vunTUgWLq6SN92EgUBm6d8D5AcfQ==",
+ "requires": {
+ "@babel/runtime": "^7.12.5"
+ }
+ },
"gatsby-plugin-page-creator": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/gatsby-plugin-page-creator/-/gatsby-plugin-page-creator-3.3.0.tgz",
@@ -53051,6 +53202,14 @@
"@babel/runtime": "^7.12.5"
}
},
+ "gatsby-plugin-react-svg": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/gatsby-plugin-react-svg/-/gatsby-plugin-react-svg-3.0.1.tgz",
+ "integrity": "sha512-bjVSCAOeRWmf5a96/BL81sHITGFV/2Ql+IwP3ET5O5BZYOpt0f7QVCspkvCj0hsy4BJgCgANpzFstuaxUNsojA==",
+ "requires": {
+ "svg-react-loader": "^0.4.4"
+ }
+ },
"gatsby-plugin-sharp": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/gatsby-plugin-sharp/-/gatsby-plugin-sharp-3.3.0.tgz",
@@ -63118,6 +63277,11 @@
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
"integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="
},
+ "ramda": {
+ "version": "0.21.0",
+ "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.21.0.tgz",
+ "integrity": "sha1-oAGr7bP/YQd9T/HVd9RN536NCjU="
+ },
"randomatic": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz",
@@ -64340,6 +64504,11 @@
"aproba": "^1.1.1"
}
},
+ "rx": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/rx/-/rx-4.1.0.tgz",
+ "integrity": "sha1-pfE/957zt0D+MKqAP7CfmIBdR4I="
+ },
"rx-lite": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz",
@@ -66198,6 +66367,91 @@
}
}
},
+ "svg-react-loader": {
+ "version": "0.4.6",
+ "resolved": "https://registry.npmjs.org/svg-react-loader/-/svg-react-loader-0.4.6.tgz",
+ "integrity": "sha512-HVEypjWQsQuJdBIPzXGxpmQsQts7QwfQuYgK1rah6BVCMoLNSCh/ESKVNd7/tHq8DkWYHHTyaUMDA1FjqZYrgA==",
+ "requires": {
+ "css": "2.2.4",
+ "loader-utils": "1.1.0",
+ "ramda": "0.21.0",
+ "rx": "4.1.0",
+ "traverse": "0.6.6",
+ "xml2js": "0.4.17"
+ },
+ "dependencies": {
+ "big.js": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz",
+ "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q=="
+ },
+ "css": {
+ "version": "2.2.4",
+ "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz",
+ "integrity": "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==",
+ "requires": {
+ "inherits": "^2.0.3",
+ "source-map": "^0.6.1",
+ "source-map-resolve": "^0.5.2",
+ "urix": "^0.1.0"
+ }
+ },
+ "emojis-list": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz",
+ "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k="
+ },
+ "json5": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz",
+ "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE="
+ },
+ "loader-utils": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz",
+ "integrity": "sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0=",
+ "requires": {
+ "big.js": "^3.1.3",
+ "emojis-list": "^2.0.0",
+ "json5": "^0.5.0"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
+ },
+ "source-map-resolve": {
+ "version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz",
+ "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==",
+ "requires": {
+ "atob": "^2.1.2",
+ "decode-uri-component": "^0.2.0",
+ "resolve-url": "^0.2.1",
+ "source-map-url": "^0.4.0",
+ "urix": "^0.1.0"
+ }
+ },
+ "xml2js": {
+ "version": "0.4.17",
+ "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.17.tgz",
+ "integrity": "sha1-F76T6q4/O3eTWceVtBlwWogX6Gg=",
+ "requires": {
+ "sax": ">=0.6.0",
+ "xmlbuilder": "^4.1.0"
+ }
+ },
+ "xmlbuilder": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-4.2.1.tgz",
+ "integrity": "sha1-qlijBBoGb5DqoWwvU4n/GfP0YaU=",
+ "requires": {
+ "lodash": "^4.0.0"
+ }
+ }
+ }
+ },
"svgo": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz",
@@ -66780,6 +67034,11 @@
"punycode": "^2.1.1"
}
},
+ "traverse": {
+ "version": "0.6.6",
+ "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.6.tgz",
+ "integrity": "sha1-y99WD9e5r2MlAv7UD5GMFX6pcTc="
+ },
"trim": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz",
diff --git a/package.json b/package.json
index a80068e6..23075c26 100644
--- a/package.json
+++ b/package.json
@@ -51,7 +51,9 @@
"gatsby-plugin-catch-links": "^3.0.0",
"gatsby-plugin-google-analytics": "^3.0.0",
"gatsby-plugin-image": "^1.0.1",
+ "gatsby-plugin-layout": "^2.4.0",
"gatsby-plugin-react-helmet": "^4.0.0",
+ "gatsby-plugin-react-svg": "^3.0.1",
"gatsby-plugin-sharp": "^3.0.1",
"gatsby-plugin-sitemap": "^3.0.0",
"gatsby-plugin-styled-components": "^4.0.0",
diff --git a/src/components/ColorTheme/ColorTheme.js b/src/components/ColorTheme/ColorTheme.js
new file mode 100644
index 00000000..5ea546c4
--- /dev/null
+++ b/src/components/ColorTheme/ColorTheme.js
@@ -0,0 +1,48 @@
+import {useApp} from "hooks"
+import {useEffect} from "react"
+import styled from "styled-components"
+import Moon from "svg/moon.svg"
+import Sun from "svg/sun.svg"
+
+const ThemeToggle = styled.button`
+ cursor: pointer;
+ border: none;
+ background: none;
+ padding: 0rem;
+ height: 1.5rem;
+`
+
+const ColorTheme = () => {
+ const {theme, setTheme} = useApp()
+ const label = theme === "light" ? "dark" : "light"
+
+ useEffect(() => {
+ const root = document.documentElement
+
+ root.style.setProperty(
+ "--background",
+ theme === "light" ? "var(--white)" : "var(--black)",
+ )
+
+ root.style.setProperty(
+ "--text",
+ theme === "light" ? "var(--black)" : "var(--white)",
+ )
+ }, [theme])
+
+ const onClick = () => {
+ if (theme === "light") {
+ setTheme("dark")
+ } else {
+ setTheme("light")
+ }
+ }
+
+ return (
+
+ {theme === "light" ? : }
+
+ )
+}
+
+export default ColorTheme
diff --git a/src/components/ColorTheme/ColorTheme.test.js b/src/components/ColorTheme/ColorTheme.test.js
new file mode 100644
index 00000000..81ca4dce
--- /dev/null
+++ b/src/components/ColorTheme/ColorTheme.test.js
@@ -0,0 +1,30 @@
+import {render, screen} from "@testing-library/react"
+import userEvent from "@testing-library/user-event"
+import ColorTheme from "components/ColorTheme"
+import {useApp} from "hooks"
+import {generateAppCtx} from "test-utils/generators"
+
+const mockAppCtxLight = generateAppCtx({theme: "light"})
+const mockAppCtxDark = generateAppCtx({theme: "dark"})
+
+jest.mock("hooks")
+
+test("toggles dark mode", () => {
+ useApp.mockReturnValue(mockAppCtxLight)
+
+ render()
+
+ userEvent.click(screen.getByLabelText("dark"))
+ expect(mockAppCtxLight.setTheme).toHaveBeenCalledTimes(1)
+ expect(mockAppCtxLight.setTheme).toHaveBeenCalledWith("dark")
+})
+
+test("toggles light mode", () => {
+ useApp.mockReturnValue(mockAppCtxDark)
+
+ render()
+
+ userEvent.click(screen.getByLabelText("light"))
+ expect(mockAppCtxDark.setTheme).toHaveBeenCalledTimes(1)
+ expect(mockAppCtxDark.setTheme).toHaveBeenCalledWith("light")
+})
diff --git a/src/components/ColorTheme/index.js b/src/components/ColorTheme/index.js
new file mode 100644
index 00000000..a048cf80
--- /dev/null
+++ b/src/components/ColorTheme/index.js
@@ -0,0 +1 @@
+export {default} from "./ColorTheme"
diff --git a/src/components/Hamburger/Hamburger.js b/src/components/Hamburger/Hamburger.js
index 4ed90975..5c81c44d 100644
--- a/src/components/Hamburger/Hamburger.js
+++ b/src/components/Hamburger/Hamburger.js
@@ -1,10 +1,10 @@
import {faBars} from "@fortawesome/free-solid-svg-icons"
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome"
-import {AppContext} from "context/App"
-import {useContext} from "react"
+import {useApp} from "hooks"
import styled from "styled-components"
const HamburgerWrapper = styled(FontAwesomeIcon)`
+ color: var(--text);
display: none;
cursor: pointer;
font-size: 1.5rem;
@@ -15,8 +15,7 @@ const HamburgerWrapper = styled(FontAwesomeIcon)`
`
const Hamburger = () => {
- const appContext = useContext(AppContext)
- const {setOpen} = appContext
+ const {setOpen} = useApp()
const onClick = () => {
setOpen(true)
diff --git a/src/components/Hamburger/Hamburger.test.js b/src/components/Hamburger/Hamburger.test.js
index 06c27968..c514a2cf 100644
--- a/src/components/Hamburger/Hamburger.test.js
+++ b/src/components/Hamburger/Hamburger.test.js
@@ -1,20 +1,17 @@
import {render, screen} from "@testing-library/react"
import userEvent from "@testing-library/user-event"
-import {AppContext} from "context/App"
+import {useApp} from "hooks"
+import {generateAppCtx} from "test-utils/generators"
import Hamburger from "./Hamburger"
-const mockAppCtx = {
- open: false,
- setOpen: jest.fn(),
-}
+const mockAppCtx = generateAppCtx()
+
+jest.mock("hooks")
+useApp.mockReturnValue(mockAppCtx)
test("opens mobile menu", () => {
- render(
-
-
- ,
- )
+ render()
userEvent.click(screen.getByLabelText("menu"))
expect(mockAppCtx.setOpen).toHaveBeenCalledTimes(1)
diff --git a/src/components/Header/Header.js b/src/components/Header/Header.js
index f5f85719..766c76a2 100644
--- a/src/components/Header/Header.js
+++ b/src/components/Header/Header.js
@@ -1,7 +1,7 @@
+import ColorTheme from "components/ColorTheme"
import Logo from "components/Logo"
import MobileNavigation from "components/MobileNavigation"
import Navigation from "components/Navigation"
-import {AppProvider} from "context/App"
import {Link} from "gatsby"
import styled from "styled-components"
@@ -17,6 +17,13 @@ const HeaderWrapper = styled.header`
}
`
+const Right = styled.div`
+ display: grid;
+ grid-auto-flow: column;
+ column-gap: 2rem;
+ align-items: center;
+`
+
const Header = () => {
return (
@@ -24,10 +31,11 @@ const Header = () => {
-
+
-
+
+
)
}
diff --git a/src/components/Header/Header.test.js b/src/components/Header/Header.test.js
index b1e15c17..ee4fe085 100644
--- a/src/components/Header/Header.test.js
+++ b/src/components/Header/Header.test.js
@@ -1,7 +1,14 @@
import {render, screen} from "@testing-library/react"
+import {useApp} from "hooks"
+import {generateAppCtx} from "test-utils/generators"
import Header from "./Header"
+const mockAppCtx = generateAppCtx()
+
+jest.mock("hooks")
+useApp.mockReturnValue(mockAppCtx)
+
test("shows logo", () => {
render()
expect(screen.getByLabelText("bg"))
diff --git a/src/components/Hero/Hero.js b/src/components/Hero/Hero.js
index 2281ad7b..c2df9b88 100644
--- a/src/components/Hero/Hero.js
+++ b/src/components/Hero/Hero.js
@@ -22,9 +22,8 @@ const HeroImage = styled(Link)`
.hero-image {
border-radius: 100%;
box-sizing: border-box;
- border: 7px solid var(--black);
- background-color: var(--black);
- transition: all 300ms !important;
+ border: 7px solid var(--text);
+ background-color: var(--text);
:hover {
transform: rotate(-2deg);
diff --git a/src/components/LatestVideos/LatestVideos.js b/src/components/LatestVideos/LatestVideos.js
index b0cd71a0..4f18d97f 100644
--- a/src/components/LatestVideos/LatestVideos.js
+++ b/src/components/LatestVideos/LatestVideos.js
@@ -22,10 +22,9 @@ const Thumbnail = styled.div`
.thumbnail {
box-sizing: border-box;
border-radius: 0.3rem;
- border: 3px solid var(--black);
- background-color: var(--black);
- box-shadow: 3px 3px 0 var(--black);
- transition: all 300ms !important;
+ border: 3px solid var(--text);
+ background-color: var(--text);
+ box-shadow: 3px 3px 0 var(--text);
}
.thumbnail:hover {
diff --git a/src/components/Layout/Layout.js b/src/components/Layout/Layout.js
index 350e8881..d369e62b 100644
--- a/src/components/Layout/Layout.js
+++ b/src/components/Layout/Layout.js
@@ -1,5 +1,6 @@
import Footer from "components/Footer"
import Header from "components/Header"
+import {AppProvider} from "context"
import PropTypes from "prop-types"
import styled from "styled-components"
import GlobalStyles from "styles/GlobalStyles"
@@ -24,7 +25,7 @@ const Content = styled.main`
const Layout = ({children}) => {
return (
- <>
+
@@ -32,7 +33,7 @@ const Layout = ({children}) => {
{children}
- >
+
)
}
diff --git a/src/components/LinkButton/LinkButton.js b/src/components/LinkButton/LinkButton.js
index 276af54f..228999c7 100644
--- a/src/components/LinkButton/LinkButton.js
+++ b/src/components/LinkButton/LinkButton.js
@@ -8,13 +8,12 @@ const button = css`
color: var(--black);
padding: 0.5rem 0.75rem;
border-radius: 0.3rem;
- transition: all 300ms;
border: 2px solid var(--black);
- box-shadow: 3px 3px 0 var(--black);
+ box-shadow: 3px 3px 0 var(--text);
margin-bottom: 5px;
&.reverse {
- box-shadow: -3px 3px 0 var(--black);
+ box-shadow: -3px 3px 0 var(--text);
}
:hover {
@@ -23,6 +22,7 @@ const button = css`
}
&.disabled {
+ color: var(--grey);
cursor: default;
border: 2px solid var(--grey);
box-shadow: 3px 3px 0 var(--grey);
diff --git a/src/components/Logo/Logo.js b/src/components/Logo/Logo.js
index bb716fed..cb37d57b 100644
--- a/src/components/Logo/Logo.js
+++ b/src/components/Logo/Logo.js
@@ -3,6 +3,7 @@ import styled from "styled-components"
const LogoWrapper = styled.svg`
display: inline-block;
width: 50px;
+ fill: var(--text);
`
const Logo = () => (
diff --git a/src/components/MobileNavigation/MobileNavigation.js b/src/components/MobileNavigation/MobileNavigation.js
index 3fe9af4e..14a535a8 100644
--- a/src/components/MobileNavigation/MobileNavigation.js
+++ b/src/components/MobileNavigation/MobileNavigation.js
@@ -1,13 +1,12 @@
import {faTimes} from "@fortawesome/free-solid-svg-icons"
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome"
import Hamburger from "components/Hamburger"
-import {AppContext} from "context/App"
import {Link} from "gatsby"
-import {useContext} from "react"
+import {useApp} from "hooks"
import styled from "styled-components"
const MobileNavigationWrapper = styled.div`
- background: var(--white);
+ background: var(--background);
position: fixed;
top: 0;
right: 0;
@@ -21,6 +20,7 @@ const MobileNavigationWrapper = styled.div`
`
const CloseIcon = styled(FontAwesomeIcon)`
+ color: var(--text);
margin: 1.25rem;
cursor: pointer;
justify-self: end;
@@ -35,12 +35,15 @@ const MobileNavigationLinks = styled.div`
`
const MobileNavigationLink = styled(Link)`
- color: var(--black);
+ color: var(--text);
+
+ :hover {
+ color: var(--primary);
+ }
`
const MobileNavigation = () => {
- const appContext = useContext(AppContext)
- const {open, setOpen} = appContext
+ const {open, setOpen} = useApp()
const onClick = () => {
setOpen(false)
diff --git a/src/components/MobileNavigation/MobileNavigation.test.js b/src/components/MobileNavigation/MobileNavigation.test.js
index bd66d900..5bb8a1ea 100644
--- a/src/components/MobileNavigation/MobileNavigation.test.js
+++ b/src/components/MobileNavigation/MobileNavigation.test.js
@@ -1,62 +1,53 @@
import {render, screen} from "@testing-library/react"
import userEvent from "@testing-library/user-event"
-import {AppContext} from "context/App"
+import {useApp} from "hooks"
+import {generateAppCtx} from "test-utils/generators"
import MobileNavigation from "./MobileNavigation"
-const mockAppCtxOpen = {
- open: true,
- setOpen: jest.fn(),
-}
+const mockAppCtxOpen = generateAppCtx({open: true})
+const mockAppCtxClosed = generateAppCtx({open: false})
-const mockAppCtxClosed = {
- open: false,
- setOpen: jest.fn(),
-}
+jest.mock("hooks")
const links = ["blog", "now", "uses", "hire me", "contact"]
-test("shows hamburger", () => {
- render(
-
-
- ,
- )
+describe("closed mobile navigation", () => {
+ beforeEach(() => {
+ useApp.mockReturnValue(mockAppCtxClosed)
+ })
- expect(screen.getByLabelText("menu"))
-})
+ test("shows hamburger", () => {
+ render()
+ expect(screen.getByLabelText("menu"))
+ })
-test("shows menu", () => {
- render(
-
-
- ,
- )
+ test("opens navigation", () => {
+ render()
- expect(screen.getByLabelText("close"))
- links.forEach(link => expect(screen.getByText(link)))
+ userEvent.click(screen.getByLabelText("menu"))
+ expect(mockAppCtxClosed.setOpen).toHaveBeenCalledTimes(1)
+ expect(mockAppCtxClosed.setOpen).toHaveBeenCalledWith(true)
+ })
})
-test("opens navigation", () => {
- render(
-
-
- ,
- )
+describe("open mobile navigation", () => {
+ beforeEach(() => {
+ useApp.mockReturnValue(mockAppCtxOpen)
+ })
- userEvent.click(screen.getByLabelText("menu"))
- expect(mockAppCtxClosed.setOpen).toHaveBeenCalledTimes(1)
- expect(mockAppCtxClosed.setOpen).toHaveBeenCalledWith(true)
-})
+ test("shows menu", () => {
+ render()
+
+ expect(screen.getByLabelText("close"))
+ links.forEach(link => expect(screen.getByText(link)))
+ })
-test("closes navigation", () => {
- render(
-
-
- ,
- )
+ test("closes navigation", () => {
+ render()
- userEvent.click(screen.getByLabelText("close"))
- expect(mockAppCtxOpen.setOpen).toHaveBeenCalledTimes(1)
- expect(mockAppCtxOpen.setOpen).toHaveBeenCalledWith(false)
+ userEvent.click(screen.getByLabelText("close"))
+ expect(mockAppCtxOpen.setOpen).toHaveBeenCalledTimes(1)
+ expect(mockAppCtxOpen.setOpen).toHaveBeenCalledWith(false)
+ })
})
diff --git a/src/components/Navigation/Navigation.js b/src/components/Navigation/Navigation.js
index da4e0739..e104bc9d 100644
--- a/src/components/Navigation/Navigation.js
+++ b/src/components/Navigation/Navigation.js
@@ -5,6 +5,7 @@ const NavigationWrapper = styled.nav`
display: grid;
grid-auto-flow: column;
column-gap: 1.25rem;
+ color: var(--text);
@media (max-width: 600px) {
display: none;
@@ -12,7 +13,7 @@ const NavigationWrapper = styled.nav`
`
const NavigationLink = styled(Link)`
- color: var(--black);
+ color: var(--text);
:hover {
color: var(--primary);
diff --git a/src/components/Now/Now.js b/src/components/Now/Now.js
index bdbe771d..f24f2092 100644
--- a/src/components/Now/Now.js
+++ b/src/components/Now/Now.js
@@ -8,9 +8,7 @@ const Header = styled.div`
display: flex;
align-items: baseline;
justify-content: space-between;
-`
-
-const Date = styled.span`
+ color: var(--text);
text-transform: lowercase;
`
@@ -39,7 +37,7 @@ const Now = ({now, newer, older}) => {
<>
🧭 now
- {frontmatter.date}
+ {frontmatter.date}
diff --git a/src/components/Podcast/Podcast.js b/src/components/Podcast/Podcast.js
index 19fa17fe..6a83bec8 100644
--- a/src/components/Podcast/Podcast.js
+++ b/src/components/Podcast/Podcast.js
@@ -18,7 +18,7 @@ const PodcastWrapper = styled.div`
const Description = styled.div`
display: grid;
justify-items: start;
- color: var(--black);
+ color: var(--text);
`
const Badge = styled.span`
@@ -29,7 +29,8 @@ const Badge = styled.span`
font-size: 1.5rem;
border-radius: 0.5rem;
padding: 0.5rem 1rem;
- border: 3px solid var(--black);
+ color: var(--text);
+ border: 3px solid var(--text);
`
const Hosts = styled.div`
@@ -50,9 +51,10 @@ const Hosts = styled.div`
`
const Host = styled(Link)`
- color: var(--black);
+ color: var(--text);
:hover {
+ color: var(--text);
text-shadow: 2px 2px var(--primary);
}
`
@@ -65,10 +67,9 @@ const CoverImage = styled(Link)`
.cover-image {
box-sizing: border-box;
border-radius: 0.5rem;
- border: 2px solid var(--black);
- background-color: var(--black);
- box-shadow: 3px 3px 0 var(--black);
- transition: all 300ms !important;
+ border: 2px solid var(--text);
+ background-color: var(--text);
+ box-shadow: 3px 3px 0 var(--text);
}
.cover-image:hover {
diff --git a/src/components/PostList/PostList.js b/src/components/PostList/PostList.js
index d9b9a433..c18ad94d 100644
--- a/src/components/PostList/PostList.js
+++ b/src/components/PostList/PostList.js
@@ -3,6 +3,7 @@ import PropTypes from "prop-types"
import styled from "styled-components"
const NoPosts = styled.div`
+ color: var(--text);
font-style: italic;
font-size: 1.25rem;
diff --git a/src/components/PostMeta/PostMeta.js b/src/components/PostMeta/PostMeta.js
index bb61b61d..85ba8185 100644
--- a/src/components/PostMeta/PostMeta.js
+++ b/src/components/PostMeta/PostMeta.js
@@ -9,7 +9,7 @@ const PostMetaWrapper = styled.div`
}
a {
- color: rgba(0, 0, 0, 0.8);
+ color: var(--text);
:hover {
color: var(--primary);
diff --git a/src/components/PostSearchBar/PostSearchBar.js b/src/components/PostSearchBar/PostSearchBar.js
index 4918c4b1..00f34498 100644
--- a/src/components/PostSearchBar/PostSearchBar.js
+++ b/src/components/PostSearchBar/PostSearchBar.js
@@ -14,9 +14,8 @@ const StyledSearch = styled.input`
font-family: "Open Sans", sans-serif;
border: 3px solid var(--black);
border-radius: 0.3rem;
- box-shadow: 3px 3px 0 var(--black);
+ box-shadow: 3px 3px 0 var(--text);
color: var(--black);
- transition: all 300ms;
::placeholder {
color: var(--darkGrey);
diff --git a/src/components/PostTitle/PostTitle.js b/src/components/PostTitle/PostTitle.js
index 66af0b9d..d9bde6dc 100644
--- a/src/components/PostTitle/PostTitle.js
+++ b/src/components/PostTitle/PostTitle.js
@@ -15,7 +15,7 @@ const PostTitleWrapper = styled.div`
}
a {
- color: var(--black);
+ color: var(--text);
:hover {
color: var(--primary);
diff --git a/src/components/Project/Project.js b/src/components/Project/Project.js
index 091d1036..441a7219 100644
--- a/src/components/Project/Project.js
+++ b/src/components/Project/Project.js
@@ -5,14 +5,15 @@ import styled from "styled-components"
const ProjectWrapper = styled(Link)`
padding: 1.125rem;
border-radius: 0.3rem;
- border: 3px solid var(--black);
- box-shadow: 3px 3px 0 var(--black);
+ border: 3px solid var(--text);
+ box-shadow: 3px 3px 0 var(--text);
display: grid;
row-gap: 0.5rem;
align-content: space-between;
- color: var(--black);
+ color: var(--text);
:hover {
+ color: var(--text);
box-shadow: none;
}
`
diff --git a/src/components/SocialLink/SocialLink.js b/src/components/SocialLink/SocialLink.js
index 770b2f43..041719d1 100644
--- a/src/components/SocialLink/SocialLink.js
+++ b/src/components/SocialLink/SocialLink.js
@@ -13,8 +13,7 @@ import styled from "styled-components"
const FontAwesomeIconWrapper = styled(FontAwesomeIcon)`
font-size: 2.5rem;
- color: rgba(0, 0, 0, 0.8);
- transition: all 300ms;
+ color: var(--text);
:hover {
color: var(--primary);
diff --git a/src/context/App.js b/src/context/App.js
index ccb90832..cfa0cb78 100644
--- a/src/context/App.js
+++ b/src/context/App.js
@@ -5,10 +5,13 @@ const AppContext = createContext()
const AppProvider = ({children}) => {
const [open, setOpen] = useState(false)
+ const [theme, setTheme] = useState("light")
const context = {
open,
setOpen,
+ theme,
+ setTheme,
}
return {children}
diff --git a/src/context/index.js b/src/context/index.js
new file mode 100644
index 00000000..7e5903d9
--- /dev/null
+++ b/src/context/index.js
@@ -0,0 +1 @@
+export * from "./App"
diff --git a/src/hooks/index.js b/src/hooks/index.js
index 91b944b2..def3be0f 100644
--- a/src/hooks/index.js
+++ b/src/hooks/index.js
@@ -1,3 +1,4 @@
+export {default as useApp} from "hooks/useApp"
export {default as useLatestPosts} from "hooks/useLatestPosts"
export {default as useLatestVideos} from "hooks/useLatestVideos"
export {default as useMeta} from "hooks/useMeta"
diff --git a/src/hooks/useApp.js b/src/hooks/useApp.js
new file mode 100644
index 00000000..bb1bcd33
--- /dev/null
+++ b/src/hooks/useApp.js
@@ -0,0 +1,9 @@
+import {AppContext} from "context"
+import {useContext} from "react"
+
+const useApp = () => {
+ const appCtx = useContext(AppContext)
+ return appCtx
+}
+
+export default useApp
diff --git a/src/pages/404.js b/src/pages/404.js
index 803db1f1..3cc4c07d 100644
--- a/src/pages/404.js
+++ b/src/pages/404.js
@@ -1,14 +1,13 @@
import SEO from "@bradgarropy/gatsby-plugin-seo"
import FourOhFour from "components/FourOhFour"
-import Layout from "components/Layout"
const NotFoundPage = () => {
return (
-
+ <>
-
+ >
)
}
diff --git a/src/pages/blog.js b/src/pages/blog.js
index a4d5dd1f..b9e4fa22 100644
--- a/src/pages/blog.js
+++ b/src/pages/blog.js
@@ -1,5 +1,4 @@
import SEO from "@bradgarropy/gatsby-plugin-seo"
-import Layout from "components/Layout"
import PostList from "components/PostList"
import PostSearchBar from "components/PostSearchBar"
import {usePosts} from "hooks"
@@ -17,14 +16,14 @@ const BlogPage = () => {
}
return (
-
+ <>
-
+ >
)
}
diff --git a/src/pages/contact.js b/src/pages/contact.js
index 38b10a19..3c0575e1 100644
--- a/src/pages/contact.js
+++ b/src/pages/contact.js
@@ -1,5 +1,4 @@
import SEO from "@bradgarropy/gatsby-plugin-seo"
-import Layout from "components/Layout"
import {graphql} from "gatsby"
import PropTypes from "prop-types"
import styled from "styled-components"
@@ -27,11 +26,11 @@ const ContactPage = ({data}) => {
const {html} = data.contact
return (
-
+ <>
-
+ >
)
}
diff --git a/src/pages/hire-me.js b/src/pages/hire-me.js
index f8059f69..c68744ca 100644
--- a/src/pages/hire-me.js
+++ b/src/pages/hire-me.js
@@ -1,5 +1,4 @@
import SEO from "@bradgarropy/gatsby-plugin-seo"
-import Layout from "components/Layout"
import {graphql} from "gatsby"
import PropTypes from "prop-types"
import styled from "styled-components"
@@ -16,11 +15,11 @@ const HireMePage = ({data}) => {
const {html} = data.hireMe
return (
-
+ <>
-
+ >
)
}
diff --git a/src/pages/index.js b/src/pages/index.js
index 46e87c70..5ebf44db 100644
--- a/src/pages/index.js
+++ b/src/pages/index.js
@@ -3,7 +3,6 @@ import FeaturedProjects from "components/FeaturedProjects"
import Hero from "components/Hero"
import LatestPosts from "components/LatestPosts"
import LatestVideos from "components/LatestVideos"
-import Layout from "components/Layout"
import Podcast from "components/Podcast"
import Section from "components/Section"
import {useMeta} from "hooks"
@@ -23,7 +22,7 @@ const IndexPage = () => {
const meta = useMeta()
return (
-
+ <>
@@ -45,7 +44,7 @@ const IndexPage = () => {
-
+ >
)
}
diff --git a/src/pages/now.js b/src/pages/now.js
index 5ea02362..3b65493f 100644
--- a/src/pages/now.js
+++ b/src/pages/now.js
@@ -1,5 +1,4 @@
import SEO from "@bradgarropy/gatsby-plugin-seo"
-import Layout from "components/Layout"
import Now from "components/Now"
import {graphql} from "gatsby"
import PropTypes from "prop-types"
@@ -8,7 +7,7 @@ const NowPage = ({data}) => {
const {node, next, previous} = data.nows.edges[0]
return (
-
+ <>
{
newer={previous?.frontmatter.date}
older={next?.frontmatter.date}
/>
-
+ >
)
}
diff --git a/src/pages/resume.js b/src/pages/resume.js
index cd8dfc73..997c05fb 100644
--- a/src/pages/resume.js
+++ b/src/pages/resume.js
@@ -1,5 +1,4 @@
import SEO from "@bradgarropy/gatsby-plugin-seo"
-import Layout from "components/Layout"
import {graphql} from "gatsby"
import PropTypes from "prop-types"
import styled from "styled-components"
@@ -25,11 +24,11 @@ const ResumePage = ({data}) => {
const {html} = data.resume
return (
-
+ <>
-
+ >
)
}
diff --git a/src/pages/sponsors.js b/src/pages/sponsors.js
index 5ee90846..4457ee64 100644
--- a/src/pages/sponsors.js
+++ b/src/pages/sponsors.js
@@ -1,6 +1,5 @@
import Link from "@bradgarropy/gatsby-link"
import SEO from "@bradgarropy/gatsby-plugin-seo"
-import Layout from "components/Layout"
import Section from "components/Section"
import {useSponsors} from "hooks"
import styled from "styled-components"
@@ -40,9 +39,8 @@ const Avatar = styled.img`
width: 6rem;
margin: 0rem;
border-radius: 50%;
- border: 5px solid var(--black);
- background-color: var(--black);
- transition: all 300ms;
+ border: 5px solid var(--text);
+ background-color: var(--text);
:hover {
transform: rotate(-2deg);
@@ -55,7 +53,7 @@ const SponsorsPage = () => {
const sponsors = useSponsors()
return (
-
+ <>
@@ -101,7 +99,7 @@ const SponsorsPage = () => {
))}
-
+ >
)
}
diff --git a/src/pages/uses.js b/src/pages/uses.js
index 744411d9..7a229a38 100644
--- a/src/pages/uses.js
+++ b/src/pages/uses.js
@@ -1,5 +1,4 @@
import SEO from "@bradgarropy/gatsby-plugin-seo"
-import Layout from "components/Layout"
import {graphql} from "gatsby"
import PropTypes from "prop-types"
import styled from "styled-components"
@@ -13,11 +12,11 @@ const UsesPage = ({data}) => {
const {html} = data.uses
return (
-
+ <>
-
+ >
)
}
diff --git a/src/styles/GlobalStyles.js b/src/styles/GlobalStyles.js
index c592466b..fc3973ac 100644
--- a/src/styles/GlobalStyles.js
+++ b/src/styles/GlobalStyles.js
@@ -9,8 +9,10 @@ const GlobalStyles = createGlobalStyle`
--white: #ffffff;
--purple: #c792ea;
- /* palette */
+ /* intentions */
--primary: var(--purple);
+ --text: var(--black);
+ --background: var(--white);
/* highlighting */
--grvsc-line-highlighted-background-color: #c792ea66;
@@ -18,12 +20,17 @@ const GlobalStyles = createGlobalStyle`
--grvsc-line-highlighted-border-width: 4px;
}
+ * {
+ transition: all 300ms !important;
+ }
+
html {
margin: 0rem;
padding: 0rem;
}
body {
+ background: var(--background);
font-family: "Open Sans", sans-serif;
font-weight: 400;
font-size: 16px;
@@ -35,14 +42,14 @@ const GlobalStyles = createGlobalStyle`
h1, h2, h3, h4, h5, h6 {
font-family: "Montserrat", sans-serif;
font-weight: 600;
- color: var(--black);
+ color: var(--text);
margin-top: 1.75rem;
margin-bottom: 1.75rem;
line-height: 1.5;
}
p {
- color: rgba(0, 0, 0, 0.8);
+ color: var(--text);
line-height: 1.75;
margin-top: 1.75rem;
margin-bottom: 1.75rem;
@@ -62,13 +69,16 @@ const GlobalStyles = createGlobalStyle`
a {
color: var(--primary);
text-decoration: none;
- transition: all 300ms;
:hover {
color: rgba(0, 0, 0, 0.8);
}
}
+ .anchor {
+ fill: var(--text);
+ }
+
img {
display: block;
max-width: 100%;
@@ -82,10 +92,11 @@ const GlobalStyles = createGlobalStyle`
}
ul {
- color: rgba(0, 0, 0, 0.8);
+ color: var(--text);
}
table {
+ color: var(--text);
margin: 1.75rem auto;
}
diff --git a/src/styles/partials.js b/src/styles/partials.js
index f72bf7c2..f116436c 100644
--- a/src/styles/partials.js
+++ b/src/styles/partials.js
@@ -2,10 +2,11 @@ const {css} = require("styled-components")
const link = css`
a:not(.anchor) {
- color: rgba(0, 0, 0, 0.8);
+ color: var(--text);
box-shadow: inset 0 -2px var(--primary);
:hover {
+ color: var(--text);
box-shadow: inset 0 -25px 0 var(--primary);
}
}
diff --git a/src/svg/moon.svg b/src/svg/moon.svg
new file mode 100644
index 00000000..aeb78dbf
--- /dev/null
+++ b/src/svg/moon.svg
@@ -0,0 +1,14 @@
+
diff --git a/src/svg/sun.svg b/src/svg/sun.svg
new file mode 100644
index 00000000..54bcd1d4
--- /dev/null
+++ b/src/svg/sun.svg
@@ -0,0 +1,14 @@
+
diff --git a/src/templates/now.js b/src/templates/now.js
index 95a72814..a3339cd1 100644
--- a/src/templates/now.js
+++ b/src/templates/now.js
@@ -1,5 +1,4 @@
import SEO from "@bradgarropy/gatsby-plugin-seo"
-import Layout from "components/Layout"
import Now from "components/Now"
import {graphql} from "gatsby"
import PropTypes from "prop-types"
@@ -9,10 +8,10 @@ const NowTemplate = ({data, pageContext}) => {
const {newer, older} = pageContext
return (
-
+ <>
-
+ >
)
}
diff --git a/src/templates/post.js b/src/templates/post.js
index 38e1b248..b860e104 100644
--- a/src/templates/post.js
+++ b/src/templates/post.js
@@ -1,5 +1,4 @@
import SEO from "@bradgarropy/gatsby-plugin-seo"
-import Layout from "components/Layout"
import Post from "components/Post"
import {graphql} from "gatsby"
import PropTypes from "prop-types"
@@ -9,11 +8,11 @@ const PostTemplate = ({data}) => {
const {frontmatter} = post
return (
-
+ <>
-
+ >
)
}
diff --git a/src/templates/topic.js b/src/templates/topic.js
index c9d32c46..e21e1c9e 100644
--- a/src/templates/topic.js
+++ b/src/templates/topic.js
@@ -1,5 +1,4 @@
import SEO from "@bradgarropy/gatsby-plugin-seo"
-import Layout from "components/Layout"
import PostList from "components/PostList"
import TopicMeta from "components/TopicMeta"
import {graphql} from "gatsby"
@@ -11,12 +10,12 @@ const TopicTemplate = ({pageContext, data}) => {
const posts = data.allMarkdownRemark.edges.map(edge => edge.node)
return (
-
+ <>
-
+ >
)
}
diff --git a/src/test-utils/file.js b/src/test-utils/file.js
new file mode 100644
index 00000000..5eaf89ef
--- /dev/null
+++ b/src/test-utils/file.js
@@ -0,0 +1 @@
+export default "test-file-stub"
diff --git a/src/test-utils/generators.js b/src/test-utils/generators.js
new file mode 100644
index 00000000..98bb9e9c
--- /dev/null
+++ b/src/test-utils/generators.js
@@ -0,0 +1,12 @@
+import {mockAppCtx} from "test-utils/mocks"
+
+const generateAppCtx = overrides => {
+ const appCtx = {
+ ...mockAppCtx,
+ ...overrides,
+ }
+
+ return appCtx
+}
+
+export {generateAppCtx}
diff --git a/src/test-utils/mocks.js b/src/test-utils/mocks.js
index 5a7a2fd6..06ab78f8 100644
--- a/src/test-utils/mocks.js
+++ b/src/test-utils/mocks.js
@@ -304,7 +304,15 @@ const mockSponsorsQuery = {
},
}
+const mockAppCtx = {
+ open: false,
+ setOpen: jest.fn(),
+ theme: "light",
+ setTheme: jest.fn(),
+}
+
export {
+ mockAppCtx,
mockMeta,
mockMetaQuery,
mockPodcast,