mirror of
https://github.com/kremalicious/blog.git
synced 2025-01-05 03:15:07 +01:00
add dark mode
This commit is contained in:
parent
dd7c294185
commit
8a0f3fc02e
@ -38,7 +38,8 @@ module.exports = {
|
|||||||
withWebp: true,
|
withWebp: true,
|
||||||
linkImagesToOriginal: true,
|
linkImagesToOriginal: true,
|
||||||
showCaptions: true,
|
showCaptions: true,
|
||||||
backgroundColor: '#e7eef4'
|
backgroundColor: 'transparent',
|
||||||
|
disableBgImageOnAlpha: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -208,6 +209,14 @@ module.exports = {
|
|||||||
exclude: ['/page/*', '/tags/*']
|
exclude: ['/page/*', '/tags/*']
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
resolve: 'gatsby-plugin-use-dark-mode',
|
||||||
|
options: {
|
||||||
|
classNameDark: 'dark',
|
||||||
|
classNameLight: 'light',
|
||||||
|
minify: true
|
||||||
|
}
|
||||||
|
},
|
||||||
'gatsby-plugin-webpack-size',
|
'gatsby-plugin-webpack-size',
|
||||||
'gatsby-plugin-react-helmet',
|
'gatsby-plugin-react-helmet',
|
||||||
'gatsby-plugin-catch-links',
|
'gatsby-plugin-catch-links',
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
"not op_mini all"
|
"not op_mini all"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"classnames": "^2.2.6",
|
||||||
"dms2dec": "^1.1.0",
|
"dms2dec": "^1.1.0",
|
||||||
"fast-exif": "^1.0.1",
|
"fast-exif": "^1.0.1",
|
||||||
"fraction.js": "^4.0.12",
|
"fraction.js": "^4.0.12",
|
||||||
@ -46,6 +47,7 @@
|
|||||||
"gatsby-plugin-sitemap": "^2.2.16",
|
"gatsby-plugin-sitemap": "^2.2.16",
|
||||||
"gatsby-plugin-svgr": "^2.0.2",
|
"gatsby-plugin-svgr": "^2.0.2",
|
||||||
"gatsby-plugin-typescript": "^2.1.11",
|
"gatsby-plugin-typescript": "^2.1.11",
|
||||||
|
"gatsby-plugin-use-dark-mode": "^1.1.2",
|
||||||
"gatsby-plugin-webpack-size": "^1.0.0",
|
"gatsby-plugin-webpack-size": "^1.0.0",
|
||||||
"gatsby-redirect-from": "^0.2.1",
|
"gatsby-redirect-from": "^0.2.1",
|
||||||
"gatsby-remark-autolink-headers": "^2.1.13",
|
"gatsby-remark-autolink-headers": "^2.1.13",
|
||||||
@ -76,6 +78,7 @@
|
|||||||
"remark": "^11.0.1",
|
"remark": "^11.0.1",
|
||||||
"remark-react": "^6.0.0",
|
"remark-react": "^6.0.0",
|
||||||
"slugify": "^1.3.4",
|
"slugify": "^1.3.4",
|
||||||
|
"use-dark-mode": "^2.3.1",
|
||||||
"web3": "^1.2.1"
|
"web3": "^1.2.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@ -85,6 +88,7 @@
|
|||||||
"@svgr/webpack": "^4.3.3",
|
"@svgr/webpack": "^4.3.3",
|
||||||
"@testing-library/jest-dom": "^4.1.0",
|
"@testing-library/jest-dom": "^4.1.0",
|
||||||
"@testing-library/react": "^9.2.0",
|
"@testing-library/react": "^9.2.0",
|
||||||
|
"@types/classnames": "^2.2.9",
|
||||||
"@types/jest": "^24.0.18",
|
"@types/jest": "^24.0.18",
|
||||||
"@types/node": "^12.7.8",
|
"@types/node": "^12.7.8",
|
||||||
"@types/react": "^16.9.4",
|
"@types/react": "^16.9.4",
|
||||||
|
@ -22,22 +22,31 @@
|
|||||||
/////////////////////////////////////
|
/////////////////////////////////////
|
||||||
|
|
||||||
.document {
|
.document {
|
||||||
@include transition;
|
|
||||||
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding-top: ($spacer * 2);
|
padding-top: ($spacer * 2);
|
||||||
background-color: $page-background-color;
|
background-color: $body-background-color;
|
||||||
border-top: 1px solid rgba(255, 255, 255, 0.7);
|
border-top: 1px solid rgba(255, 255, 255, 0.7);
|
||||||
border-bottom: 1px solid rgba(255, 255, 255, 0.7);
|
border-bottom: 1px solid rgba(255, 255, 255, 0.7);
|
||||||
padding-bottom: $spacer * 2;
|
padding-bottom: $spacer * 2;
|
||||||
box-shadow: 0 1px 4px rgba($brand-main, 0.1),
|
box-shadow: 0 1px 4px rgba($brand-main, 0.1),
|
||||||
0 -1px 4px rgba($brand-main, 0.2);
|
0 -1px 4px rgba($brand-main, 0.2);
|
||||||
transform: translate3d(0, 0, 0);
|
transform: translate3d(0, 0, 0);
|
||||||
|
transition: 0.4s $easing;
|
||||||
|
transition-property: transform, background;
|
||||||
|
|
||||||
:global(.has-menu-open) & {
|
:global(.has-menu-open) & {
|
||||||
transform: translate3d(0, ($spacer * 3), 0);
|
transform: translate3d(0, ($spacer * 3), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
:global(.dark) & {
|
||||||
|
background-color: $body-background-color--dark;
|
||||||
|
color: $text-color--dark;
|
||||||
|
border-top-color: darken($brand-grey, 15%);
|
||||||
|
border-bottom-color: darken($brand-grey, 15%);
|
||||||
|
box-shadow: 0 1px 4px darken($brand-main, 10%),
|
||||||
|
0 -1px 4px darken($brand-main, 15%);
|
||||||
|
}
|
||||||
|
|
||||||
@media (min-width: $screen-sm) and (min-height: 500px) {
|
@media (min-width: $screen-sm) and (min-height: 500px) {
|
||||||
margin-top: $spacer * 2.65;
|
margin-top: $spacer * 2.65;
|
||||||
margin-bottom: $spacer * 19; // height of footer
|
margin-bottom: $spacer * 19; // height of footer
|
||||||
|
@ -13,6 +13,10 @@
|
|||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
|
||||||
|
:global(.dark) & {
|
||||||
|
background: darken($body-background-color--dark, 2%);
|
||||||
|
}
|
||||||
|
|
||||||
@media (min-width: $screen-md) {
|
@media (min-width: $screen-md) {
|
||||||
margin-left: -100%;
|
margin-left: -100%;
|
||||||
margin-right: -18%;
|
margin-right: -18%;
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
top: 10%;
|
top: 10%;
|
||||||
padding: $spacer / 3 $spacer;
|
padding: $spacer / 3 $spacer;
|
||||||
background: rgba($link-color, 0.85);
|
background: rgba($link-color, 0.85);
|
||||||
color: #fff;
|
color: #fff !important;
|
||||||
text-shadow: 0 1px 0 #000;
|
text-shadow: 0 1px 0 #000;
|
||||||
left: 0;
|
left: 0;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
|
@ -9,6 +9,10 @@
|
|||||||
color: $color-headings;
|
color: $color-headings;
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
margin-bottom: $spacer;
|
margin-bottom: $spacer;
|
||||||
|
|
||||||
|
:global(.dark) & {
|
||||||
|
color: $color-headings--dark;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.hentry__title__link {
|
.hentry__title__link {
|
||||||
|
@ -15,6 +15,10 @@
|
|||||||
-webkit-overflow-scrolling: touch;
|
-webkit-overflow-scrolling: touch;
|
||||||
height: 91vh;
|
height: 91vh;
|
||||||
|
|
||||||
|
:global(.dark) & {
|
||||||
|
background: rgba($body-background-color--dark, 0.95);
|
||||||
|
}
|
||||||
|
|
||||||
ul {
|
ul {
|
||||||
@include breakoutviewport;
|
@include breakoutviewport;
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ export default function Search({ lng }: { lng: string }) {
|
|||||||
{searchOpen && (
|
{searchOpen && (
|
||||||
<>
|
<>
|
||||||
<Helmet>
|
<Helmet>
|
||||||
<body className="hasSearchOpen" />
|
<html className="hasSearchOpen" lang="en" />
|
||||||
</Helmet>
|
</Helmet>
|
||||||
|
|
||||||
<CSSTransition
|
<CSSTransition
|
||||||
|
@ -11,6 +11,10 @@
|
|||||||
margin-left: $spacer / 2;
|
margin-left: $spacer / 2;
|
||||||
border-left: 1px solid $brand-grey-dimmed;
|
border-left: 1px solid $brand-grey-dimmed;
|
||||||
|
|
||||||
|
:global(.dark) & {
|
||||||
|
border-left-color: darken($body-background-color--dark, 5%);
|
||||||
|
}
|
||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
|
@ -22,18 +22,22 @@
|
|||||||
flex: 1 1 20%;
|
flex: 1 1 20%;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
padding: $spacer / 1.5;
|
padding: $spacer / 1.5;
|
||||||
border-bottom: 1px solid $brand-grey-dimmed;
|
border-bottom: 1px dashed $brand-grey-dimmed;
|
||||||
|
|
||||||
&:first-child {
|
&:first-child {
|
||||||
flex-basis: 100%;
|
flex-basis: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
:global(.dark) & {
|
||||||
|
border-bottom-color: $brand-grey;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: $screen-sm) {
|
@media (min-width: $screen-sm) {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
|
|
||||||
span {
|
span {
|
||||||
border-left: 1px solid $brand-grey-dimmed;
|
border-left: 1px dashed $brand-grey-dimmed;
|
||||||
border-bottom: 0;
|
border-bottom: 0;
|
||||||
padding: $spacer;
|
padding: $spacer;
|
||||||
|
|
||||||
@ -45,6 +49,10 @@
|
|||||||
&:first-child {
|
&:first-child {
|
||||||
border-left: 0;
|
border-left: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
:global(.dark) & {
|
||||||
|
border-left-color: $brand-grey;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,9 @@ const MAPBOX_ACCESS_TOKEN =
|
|||||||
const retina =
|
const retina =
|
||||||
typeof window !== 'undefined' && window.devicePixelRatio >= 2 ? '@2x' : ''
|
typeof window !== 'undefined' && window.devicePixelRatio >= 2 ? '@2x' : ''
|
||||||
|
|
||||||
|
const isDarkMode =
|
||||||
|
typeof window !== 'undefined' && document.body.classList.contains('dark')
|
||||||
|
|
||||||
const mapbox = (mapboxId: string, accessToken: string) => (
|
const mapbox = (mapboxId: string, accessToken: string) => (
|
||||||
x: string,
|
x: string,
|
||||||
y: string,
|
y: string,
|
||||||
@ -50,7 +53,7 @@ export default function ExifMap({
|
|||||||
zoom={zoom}
|
zoom={zoom}
|
||||||
height={160}
|
height={160}
|
||||||
attribution={false}
|
attribution={false}
|
||||||
provider={providers['light']}
|
provider={isDarkMode ? providers['dark'] : providers['light']}
|
||||||
metaWheelZoom={true}
|
metaWheelZoom={true}
|
||||||
metaWheelZoomWarning={'META+wheel to zoom'}
|
metaWheelZoomWarning={'META+wheel to zoom'}
|
||||||
>
|
>
|
||||||
|
@ -14,6 +14,10 @@
|
|||||||
animation: fadein 0.3s;
|
animation: fadein 0.3s;
|
||||||
padding: $spacer;
|
padding: $spacer;
|
||||||
|
|
||||||
|
:global(.dark) & {
|
||||||
|
background: rgba($body-background-color--dark, 0.95);
|
||||||
|
}
|
||||||
|
|
||||||
@media (min-width: $screen-sm) {
|
@media (min-width: $screen-sm) {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
@ -24,7 +28,7 @@
|
|||||||
|
|
||||||
.modal__content {
|
.modal__content {
|
||||||
outline: 0;
|
outline: 0;
|
||||||
background: transparent;
|
background: $body-background-color;
|
||||||
position: relative;
|
position: relative;
|
||||||
border-radius: $border-radius;
|
border-radius: $border-radius;
|
||||||
border: 1px solid rgba($brand-grey-light, 0.4);
|
border: 1px solid rgba($brand-grey-light, 0.4);
|
||||||
@ -32,6 +36,11 @@
|
|||||||
padding: 0 $spacer / 2 $spacer / 2;
|
padding: 0 $spacer / 2 $spacer / 2;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
|
|
||||||
|
:global(.dark) & {
|
||||||
|
background: $body-background-color--dark;
|
||||||
|
box-shadow: 0 5px 30px rgba(darken($brand-main, 20%), 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
@media (min-width: $screen-md) {
|
@media (min-width: $screen-md) {
|
||||||
max-width: $screen-sm;
|
max-width: $screen-sm;
|
||||||
padding: 0 $spacer $spacer;
|
padding: 0 $spacer $spacer;
|
||||||
|
@ -35,7 +35,7 @@
|
|||||||
text-align: right;
|
text-align: right;
|
||||||
padding: $spacer / 3;
|
padding: $spacer / 3;
|
||||||
background: rgba($link-color, 0.85);
|
background: rgba($link-color, 0.85);
|
||||||
color: #fff;
|
color: #fff !important;
|
||||||
text-shadow: 0 1px 0 #000;
|
text-shadow: 0 1px 0 #000;
|
||||||
left: 0;
|
left: 0;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
|
@ -43,5 +43,9 @@
|
|||||||
padding: $padding-base-horizontal;
|
padding: $padding-base-horizontal;
|
||||||
display: block;
|
display: block;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|
||||||
|
:global(.dark) & {
|
||||||
|
text-shadow: 0 -1px 0 rgba(#000, 0.5);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ export default function Menu() {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Helmet>
|
<Helmet>
|
||||||
<body className={menuOpen ? 'has-menu-open' : null} />
|
<html className={menuOpen ? 'has-menu-open' : null} lang="en" />
|
||||||
</Helmet>
|
</Helmet>
|
||||||
<Hamburger onClick={toggleMenu} />
|
<Hamburger onClick={toggleMenu} />
|
||||||
<ul className={styles.menu}>{MenuItems}</ul>
|
<ul className={styles.menu}>{MenuItems}</ul>
|
||||||
|
@ -13,6 +13,10 @@
|
|||||||
margin-bottom: $spacer / 2;
|
margin-bottom: $spacer / 2;
|
||||||
color: $brand-grey;
|
color: $brand-grey;
|
||||||
text-transform: capitalize;
|
text-transform: capitalize;
|
||||||
|
|
||||||
|
:global(.dark) & {
|
||||||
|
color: $brand-grey-light;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
header {
|
header {
|
||||||
@ -20,6 +24,7 @@
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
margin-bottom: $spacer;
|
margin-bottom: $spacer;
|
||||||
|
|
||||||
|
// stylelint-disable-next-line no-descending-specificity
|
||||||
h4 {
|
h4 {
|
||||||
font-size: $font-size-large;
|
font-size: $font-size-large;
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
@ -28,6 +33,10 @@
|
|||||||
|
|
||||||
p {
|
p {
|
||||||
color: $brand-grey-light;
|
color: $brand-grey-light;
|
||||||
|
|
||||||
|
:global(.dark) & {
|
||||||
|
color: $brand-grey;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
84
src/components/molecules/ThemeSwitch.module.scss
Normal file
84
src/components/molecules/ThemeSwitch.module.scss
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
@import 'variables';
|
||||||
|
@import 'mixins';
|
||||||
|
|
||||||
|
.themeSwitch {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
margin-right: $spacer;
|
||||||
|
opacity: 0.75;
|
||||||
|
bottom: -0.1rem;
|
||||||
|
|
||||||
|
svg {
|
||||||
|
width: 0.8rem;
|
||||||
|
height: 0.8rem;
|
||||||
|
margin-top: -0.05rem;
|
||||||
|
fill: $brand-grey-light;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
margin-top: -0.1rem;
|
||||||
|
width: 0.7rem;
|
||||||
|
height: 0.7rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkboxContainer {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
$knob-size: 8px;
|
||||||
|
$knob-space: 1px;
|
||||||
|
|
||||||
|
.checkboxFake {
|
||||||
|
display: block;
|
||||||
|
position: relative;
|
||||||
|
width: ($knob-size + ($knob-space * 2)) * 2;
|
||||||
|
height: $knob-size + ($knob-space * 4);
|
||||||
|
border: 1px solid $brand-grey-light;
|
||||||
|
border-radius: 15rem;
|
||||||
|
margin-left: $spacer / 3;
|
||||||
|
margin-right: $spacer / 3;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: $knob-space;
|
||||||
|
left: $knob-space;
|
||||||
|
width: $knob-size;
|
||||||
|
height: $knob-size;
|
||||||
|
background-color: $brand-grey-light;
|
||||||
|
border-radius: 15rem;
|
||||||
|
transition: transform 0.2s $easing;
|
||||||
|
transform: translate3d(0, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkbox {
|
||||||
|
position: relative;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
[type='checkbox'],
|
||||||
|
.label {
|
||||||
|
width: 1px;
|
||||||
|
height: 1px;
|
||||||
|
border: 0;
|
||||||
|
clip: rect(0 0 0 0);
|
||||||
|
margin: -1px;
|
||||||
|
overflow: hidden;
|
||||||
|
padding: 0;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
[type='checkbox'] {
|
||||||
|
&:checked {
|
||||||
|
+ .checkboxContainer {
|
||||||
|
.checkboxFake {
|
||||||
|
&::after {
|
||||||
|
transform: translate3d(100%, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
24
src/components/molecules/ThemeSwitch.test.tsx
Normal file
24
src/components/molecules/ThemeSwitch.test.tsx
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import { render, fireEvent, cleanup } from '@testing-library/react'
|
||||||
|
import ThemeSwitch from './ThemeSwitch'
|
||||||
|
|
||||||
|
describe('ThemeSwitch', () => {
|
||||||
|
afterEach(cleanup)
|
||||||
|
|
||||||
|
it('renders correctly', () => {
|
||||||
|
const { container } = render(<ThemeSwitch />)
|
||||||
|
const switchContainer = container.querySelector('aside')
|
||||||
|
expect(switchContainer).toBeInTheDocument()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('checkbox can be changed', () => {
|
||||||
|
const { container } = render(<ThemeSwitch />)
|
||||||
|
|
||||||
|
const toggle = container.querySelector('input')
|
||||||
|
const label = container.querySelector('label')
|
||||||
|
expect(toggle.checked).toBeFalsy()
|
||||||
|
fireEvent.click(label)
|
||||||
|
fireEvent.change(toggle, { target: { checked: true } })
|
||||||
|
expect(toggle.checked).toBeTruthy()
|
||||||
|
})
|
||||||
|
})
|
55
src/components/molecules/ThemeSwitch.tsx
Normal file
55
src/components/molecules/ThemeSwitch.tsx
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import useDarkMode from 'use-dark-mode'
|
||||||
|
|
||||||
|
import { ReactComponent as Day } from '../../images/day.svg'
|
||||||
|
import { ReactComponent as Night } from '../../images/night.svg'
|
||||||
|
import styles from './ThemeSwitch.module.scss'
|
||||||
|
|
||||||
|
const ThemeToggle = () => (
|
||||||
|
<span id="toggle" className={styles.checkboxContainer} aria-live="assertive">
|
||||||
|
<Day />
|
||||||
|
<span className={styles.checkboxFake} />
|
||||||
|
<Night />
|
||||||
|
</span>
|
||||||
|
)
|
||||||
|
|
||||||
|
const ThemeToggleInput = ({
|
||||||
|
isDark,
|
||||||
|
toggleDark
|
||||||
|
}: {
|
||||||
|
isDark: boolean
|
||||||
|
toggleDark(): void
|
||||||
|
}) => (
|
||||||
|
<input
|
||||||
|
onChange={toggleDark}
|
||||||
|
type="checkbox"
|
||||||
|
name="toggle"
|
||||||
|
value="toggle"
|
||||||
|
aria-describedby="toggle"
|
||||||
|
checked={isDark}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
|
||||||
|
export default function ThemeSwitch() {
|
||||||
|
const darkMode = useDarkMode(false, {
|
||||||
|
classNameDark: 'dark',
|
||||||
|
classNameLight: 'light'
|
||||||
|
})
|
||||||
|
|
||||||
|
return (
|
||||||
|
<aside className={styles.themeSwitch}>
|
||||||
|
<label
|
||||||
|
htmlFor="toggle"
|
||||||
|
className={styles.checkbox}
|
||||||
|
onClick={darkMode.toggle}
|
||||||
|
>
|
||||||
|
<span className={styles.label}>Toggle Dark Mode</span>
|
||||||
|
<ThemeToggleInput
|
||||||
|
isDark={darkMode.value}
|
||||||
|
toggleDark={darkMode.toggle}
|
||||||
|
/>
|
||||||
|
<ThemeToggle />
|
||||||
|
</label>
|
||||||
|
</aside>
|
||||||
|
)
|
||||||
|
}
|
@ -15,7 +15,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.header__content {
|
.headerContent {
|
||||||
@include breakoutviewport;
|
@include breakoutviewport;
|
||||||
|
|
||||||
position: relative;
|
position: relative;
|
||||||
@ -31,56 +31,28 @@
|
|||||||
// Logo
|
// Logo
|
||||||
/////////////////////////////////////
|
/////////////////////////////////////
|
||||||
|
|
||||||
.logo {
|
|
||||||
display: block;
|
|
||||||
background-image: url('../../images/logo.png');
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-position: left top;
|
|
||||||
width: 47px;
|
|
||||||
height: 31px;
|
|
||||||
|
|
||||||
@media (min-width: $screen-sm) {
|
|
||||||
width: 183px;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (-webkit-min-device-pixel-ratio: 1.25), (min-resolution: 120dpi) {
|
|
||||||
background-image: url('../../images/logo@2x.png');
|
|
||||||
background-size: 183px 62px;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (-webkit-min-device-pixel-ratio: 3), (min-resolution: 344dpi) {
|
|
||||||
background-image: url('../../images/logo@3x.png');
|
|
||||||
background-size: 183px 62px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
margin-top: $spacer / 5;
|
margin-top: $spacer / 5;
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
// display toned down logo
|
|
||||||
// by default
|
|
||||||
@extend .logo;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header__logo {
|
svg {
|
||||||
@include hide-text;
|
fill: $brand-grey-light;
|
||||||
// repeat logo
|
width: 160px;
|
||||||
// but display hover version
|
height: 30px;
|
||||||
@extend .logo;
|
margin: 0;
|
||||||
|
transition: 0.2s $easing;
|
||||||
background-position: left bottom;
|
|
||||||
|
|
||||||
// hide by default
|
|
||||||
opacity: 0;
|
|
||||||
// show smooooothly on hover
|
|
||||||
&:hover {
|
|
||||||
opacity: 1;
|
|
||||||
transform: none;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&:active {
|
a {
|
||||||
top: 0;
|
display: block;
|
||||||
box-shadow: none;
|
@include hide-text;
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:focus {
|
||||||
|
svg {
|
||||||
|
fill: $brand-cyan;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,8 @@ import { Link } from 'gatsby'
|
|||||||
import Container from '../atoms/Container'
|
import Container from '../atoms/Container'
|
||||||
import Search from '../Search'
|
import Search from '../Search'
|
||||||
import Menu from '../molecules/Menu'
|
import Menu from '../molecules/Menu'
|
||||||
|
import ThemeSwitch from '../molecules/ThemeSwitch'
|
||||||
|
import { ReactComponent as Logo } from '../../images/logo.svg'
|
||||||
|
|
||||||
import styles from './Header.module.scss'
|
import styles from './Header.module.scss'
|
||||||
|
|
||||||
@ -10,14 +12,15 @@ export default function Header() {
|
|||||||
return (
|
return (
|
||||||
<header role="banner" className={styles.header}>
|
<header role="banner" className={styles.header}>
|
||||||
<Container>
|
<Container>
|
||||||
<div className={styles.header__content}>
|
<div className={styles.headerContent}>
|
||||||
<h1 className={styles.title}>
|
<h1 className={styles.title}>
|
||||||
<Link className={styles.header__logo} to="/">
|
<Link to="/">
|
||||||
kremalicious
|
<Logo /> kremalicious
|
||||||
</Link>
|
</Link>
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<nav role="navigation" className={styles.nav}>
|
<nav role="navigation" className={styles.nav}>
|
||||||
|
<ThemeSwitch />
|
||||||
<Search lng="en" />
|
<Search lng="en" />
|
||||||
<Menu />
|
<Menu />
|
||||||
</nav>
|
</nav>
|
||||||
|
3
src/images/day.svg
Normal file
3
src/images/day.svg
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="21" height="21" viewBox="0 0 21 21">
|
||||||
|
<path d="M1001,1344.5 C1001,1347.53669 998.535313,1350 995.5,1350 C992.459875,1350 990,1347.53669 990,1344.5 C990,1341.46331 992.459875,1339 995.5,1339 C998.535313,1339 1001,1341.46331 1001,1344.5 Z M995.5,1336.484 C994.633125,1336.484 993.81625,1336.69175 993.035,1337 L993,1337 L995.5,1334 L998,1337 L997.96125,1337 C997.181875,1336.691 996.365,1336.484 995.5,1336.484 Z M995.5,1352.516 C996.365,1352.516 997.181875,1352.30825 997.96125,1352 L998,1352 L995.5,1355 L993,1352 L993.035,1352 C993.81625,1352.309 994.633125,1352.516 995.5,1352.516 Z M1003.516,1344.5 C1003.516,1343.63562 1003.3045,1342.81562 1003,1342.03625 L1003,1342 L1006,1344.5 L1003,1347 L1003,1346.96375 C1003.30525,1346.18438 1003.516,1345.36438 1003.516,1344.5 Z M987.484,1344.5 C987.484,1345.36438 987.69025,1346.18438 988,1346.96375 L988,1347 L985,1344.5 L988,1342 L988,1342.03625 C987.6895,1342.81562 987.484,1343.63562 987.484,1344.5 Z M1001.34229,1350.34229 C1002.03819,1349.65134 1002.55304,1348.85785 1002.96959,1348.0297 L1003,1348 L1003,1352 L999,1352 L999.028289,1351.97242 C999.856436,1351.55233 1000.65205,1351.03819 1001.34229,1350.34229 Z M989.657001,1338.65771 C988.961103,1339.34866 988.447666,1340.14215 988.028289,1340.9703 L988,1341 L988,1337 L992,1337 L991.966761,1337.02758 C991.137907,1337.44767 990.348656,1337.96181 989.657001,1338.65771 Z M989.657709,1350.343 C990.349364,1351.0389 991.138614,1351.55304 991.966761,1351.97242 L992,1352 L988,1352 L988,1348 L988.028289,1348.0297 C988.448373,1348.85856 988.96181,1349.65205 989.657709,1350.343 Z M1001.34229,1338.657 C1000.65205,1337.9611 999.856436,1337.44696 999.028289,1337.02758 L999,1337 L1003,1337 L1003,1341 L1002.96959,1340.9703 C1002.55304,1340.14144 1002.03819,1339.34795 1001.34229,1338.657 Z" transform="translate(-985 -1334)"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.8 KiB |
Binary file not shown.
Before Width: | Height: | Size: 10 KiB |
3
src/images/logo.svg
Normal file
3
src/images/logo.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 20 KiB |
Binary file not shown.
Before Width: | Height: | Size: 21 KiB |
Binary file not shown.
Before Width: | Height: | Size: 37 KiB |
3
src/images/night.svg
Normal file
3
src/images/night.svg
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="17" viewBox="0 0 18 17">
|
||||||
|
<path d="M1057.35991,1345.6935 C1052.91908,1345.6935 1049.32216,1342.19489 1049.32216,1337.88132 C1049.32216,1336.46068 1049.74141,1335.14652 1050.42369,1334 C1046.72047,1335.03741 1044,1338.31568 1044,1342.24655 C1044,1347.00713 1047.97006,1350.86789 1052.86864,1350.86789 C1056.91247,1350.86789 1060.28811,1348.22007 1061.35547,1344.62446 C1060.17313,1345.28549 1058.82157,1345.6935 1057.35991,1345.6935 Z" transform="translate(-1044 -1334)"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 539 B |
@ -97,6 +97,14 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
border-bottom: 1px dashed #fff;
|
border-bottom: 1px dashed #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
:global(.dark) & {
|
||||||
|
border-bottom-color: darken($brand-main, 25%);
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
border-bottom-color: darken($brand-grey, 12%);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin divider-top() {
|
@mixin divider-top() {
|
||||||
@ -114,6 +122,14 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
border-bottom: 1px dashed #fff;
|
border-bottom: 1px dashed #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
:global(.dark) & {
|
||||||
|
border-top-color: darken($brand-main, 25%);
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
border-bottom-color: darken($brand-grey, 12%);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Heading band
|
// Heading band
|
||||||
@ -124,6 +140,10 @@
|
|||||||
background: rgba(255, 255, 255, 0.5);
|
background: rgba(255, 255, 255, 0.5);
|
||||||
padding: ($spacer/2) $spacer ($spacer/2) 100%;
|
padding: ($spacer/2) $spacer ($spacer/2) 100%;
|
||||||
margin-left: -100%;
|
margin-left: -100%;
|
||||||
|
|
||||||
|
:global(.dark) & {
|
||||||
|
background: darken($body-background-color--dark, 2%);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Layout breakout
|
// Layout breakout
|
||||||
@ -224,6 +244,11 @@
|
|||||||
border-radius: $border-radius;
|
border-radius: $border-radius;
|
||||||
box-shadow: 0 1px 3px rgba($brand-grey, 0.2);
|
box-shadow: 0 1px 3px rgba($brand-grey, 0.2);
|
||||||
|
|
||||||
|
:global(.dark) & {
|
||||||
|
box-shadow: 0 3px 5px rgba(darken($brand-main, 20%), 0.15),
|
||||||
|
0 5px 16px rgba(darken($brand-main, 20%), 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
@media (min-width: $screen-sm) {
|
@media (min-width: $screen-sm) {
|
||||||
border: 2px solid transparent;
|
border: 2px solid transparent;
|
||||||
}
|
}
|
||||||
|
@ -23,15 +23,13 @@ $alert-error: #f2dede;
|
|||||||
$body-background-color: $brand-light;
|
$body-background-color: $brand-light;
|
||||||
$body-background-color--dark: darken($brand-grey, 22%);
|
$body-background-color--dark: darken($brand-grey, 22%);
|
||||||
|
|
||||||
$page-background-color: $brand-light;
|
|
||||||
|
|
||||||
// Text Colors
|
// Text Colors
|
||||||
/////////////////////////////////////
|
/////////////////////////////////////
|
||||||
|
|
||||||
$text-color: $brand-grey;
|
$text-color: $brand-grey;
|
||||||
$text-color-light: $brand-grey-light;
|
$text-color-light: $brand-grey-light;
|
||||||
|
|
||||||
$text-color--dark: lighten($brand-grey-light, 5%);
|
$text-color--dark: lighten($brand-grey-light, 10%);
|
||||||
$text-color-light--dark: lighten($brand-grey-light, 5%);
|
$text-color-light--dark: lighten($brand-grey-light, 5%);
|
||||||
|
|
||||||
$link-color: $brand-cyan;
|
$link-color: $brand-cyan;
|
||||||
|
@ -13,7 +13,6 @@ html,
|
|||||||
body {
|
body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
background: $body-background-color;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
html {
|
html {
|
||||||
@ -32,7 +31,8 @@ body {
|
|||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
-moz-osx-font-smoothing: grayscale;
|
-moz-osx-font-smoothing: grayscale;
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
transition: background 0.6s $easing;
|
transition: background 0.4s $easing;
|
||||||
|
background: $body-background-color;
|
||||||
|
|
||||||
// handling long text, like URLs
|
// handling long text, like URLs
|
||||||
overflow-wrap: break-word;
|
overflow-wrap: break-word;
|
||||||
@ -82,6 +82,26 @@ button {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Links
|
||||||
|
/////////////////////////////////////
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: $link-color;
|
||||||
|
text-decoration: none;
|
||||||
|
transition: 0.2s ease-out;
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:focus {
|
||||||
|
outline: 0;
|
||||||
|
color: $link-color-hover;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
transition: none;
|
||||||
|
color: $link-color-active;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Headings
|
// Headings
|
||||||
/////////////////////////////////////
|
/////////////////////////////////////
|
||||||
|
|
||||||
@ -153,38 +173,19 @@ h5,
|
|||||||
h6 {
|
h6 {
|
||||||
font-family: $font-family-headings;
|
font-family: $font-family-headings;
|
||||||
line-height: $line-height-headings;
|
line-height: $line-height-headings;
|
||||||
color: $color-headings;
|
|
||||||
font-weight: $font-weight-headings;
|
font-weight: $font-weight-headings;
|
||||||
letter-spacing: -0.02em;
|
letter-spacing: -0.02em;
|
||||||
|
|
||||||
.dark & {
|
// stylelint-disable no-descending-specificity
|
||||||
color: $color-headings--dark;
|
&,
|
||||||
}
|
a {
|
||||||
}
|
|
||||||
|
|
||||||
// Links
|
|
||||||
/////////////////////////////////////
|
|
||||||
|
|
||||||
a {
|
|
||||||
color: $link-color;
|
|
||||||
text-decoration: none;
|
|
||||||
transition: 0.2s ease-out;
|
|
||||||
|
|
||||||
h1 &,
|
|
||||||
h2 &,
|
|
||||||
h3 & {
|
|
||||||
color: $color-headings;
|
color: $color-headings;
|
||||||
}
|
}
|
||||||
|
// stylelint-enable no-descending-specificity
|
||||||
|
|
||||||
&:hover,
|
.dark &,
|
||||||
&:focus {
|
.dark & a {
|
||||||
outline: 0;
|
color: $color-headings--dark;
|
||||||
color: $link-color-hover;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:active {
|
|
||||||
transition: none;
|
|
||||||
color: $link-color-active;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -215,6 +216,10 @@ figcaption {
|
|||||||
font-style: italic;
|
font-style: italic;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin-top: -($spacer / $line-height);
|
margin-top: -($spacer / $line-height);
|
||||||
|
|
||||||
|
.dark & {
|
||||||
|
color: $brand-grey-light;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lists
|
// Lists
|
||||||
|
Loading…
Reference in New Issue
Block a user