mirror of
https://github.com/kremalicious/portfolio.git
synced 2025-01-03 10:25:00 +01:00
theme switcher
This commit is contained in:
parent
f9960a1d40
commit
d37bafb379
@ -31,6 +31,7 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"parser": "babel-eslint",
|
||||||
"parserOptions": {
|
"parserOptions": {
|
||||||
"sourceType": "module",
|
"sourceType": "module",
|
||||||
"ecmaFeatures": {
|
"ecmaFeatures": {
|
||||||
|
@ -3,20 +3,29 @@
|
|||||||
.availability {
|
.availability {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
background: rgba($brand-light, .8);
|
|
||||||
border-radius: .25rem;
|
border-radius: .25rem;
|
||||||
color: $brand-grey-light;
|
color: $text-color-light;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
padding: $spacer / 2;
|
padding: $spacer / 2;
|
||||||
display: block;
|
display: block;
|
||||||
transition: opacity .2s ease-out;
|
transition: opacity .2s ease-out;
|
||||||
|
|
||||||
|
.dark & {
|
||||||
|
color: $text-color-light--dark;
|
||||||
|
}
|
||||||
|
|
||||||
p { margin-bottom: 0; }
|
p { margin-bottom: 0; }
|
||||||
|
|
||||||
&.available {
|
&.available {
|
||||||
|
background: rgba($brand-light, .8);
|
||||||
color: $brand-main;
|
color: $brand-main;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
bottom: $spacer;
|
bottom: $spacer;
|
||||||
|
|
||||||
|
.dark & {
|
||||||
|
background: rgba($body-background-color--dark, .8);
|
||||||
|
color: $brand-light;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
|
@ -39,8 +39,6 @@
|
|||||||
|
|
||||||
&:hover,
|
&:hover,
|
||||||
&:focus {
|
&:focus {
|
||||||
background: $brand-light;
|
|
||||||
|
|
||||||
.icon {
|
.icon {
|
||||||
fill: $brand-cyan;
|
fill: $brand-cyan;
|
||||||
}
|
}
|
||||||
|
60
src/components/molecules/ThemeSwitch.jsx
Normal file
60
src/components/molecules/ThemeSwitch.jsx
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
import React, { Component } from 'react'
|
||||||
|
import { ReactComponent as Day } from '../../images/day.svg'
|
||||||
|
import { ReactComponent as Night } from '../../images/night.svg'
|
||||||
|
import './ThemeSwitch.scss'
|
||||||
|
|
||||||
|
class ThemeSwitch extends Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props)
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
dark: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
this.toggleTheme()
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidUpdate() {
|
||||||
|
this.toggleTheme()
|
||||||
|
}
|
||||||
|
|
||||||
|
isDark = () => this.state.dark === true
|
||||||
|
|
||||||
|
toggleState = () => {
|
||||||
|
this.setState({ dark: !this.isDark() })
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleTheme = () => {
|
||||||
|
document.body.classList.toggle('dark', this.state.dark)
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<aside className="themeswitch">
|
||||||
|
<label className="checkbox">
|
||||||
|
<span className="checkbox__label">Toggle Night Mode</span>
|
||||||
|
<input
|
||||||
|
onClick={this.toggleState}
|
||||||
|
type="checkbox"
|
||||||
|
name="toggle"
|
||||||
|
value="toggle"
|
||||||
|
aria-describedby="toggle"
|
||||||
|
/>
|
||||||
|
<span
|
||||||
|
id="toggle"
|
||||||
|
className="checkbox__faux-container"
|
||||||
|
aria-live="assertive"
|
||||||
|
>
|
||||||
|
<Day className={this.state.dark ? 'icon' : 'icon active'} />
|
||||||
|
<span className="checkbox__faux" />
|
||||||
|
<Night className={this.state.dark ? 'icon active' : 'icon'} />
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
</aside>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ThemeSwitch
|
95
src/components/molecules/ThemeSwitch.scss
Normal file
95
src/components/molecules/ThemeSwitch.scss
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
@import 'variables';
|
||||||
|
|
||||||
|
.themeswitch {
|
||||||
|
position: absolute;
|
||||||
|
top: $spacer / 2;
|
||||||
|
right: $spacer;
|
||||||
|
z-index: 10;
|
||||||
|
opacity: .6;
|
||||||
|
|
||||||
|
.dark & {
|
||||||
|
opacity: .8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
width: .8rem;
|
||||||
|
height: .8rem;
|
||||||
|
fill: $brand-grey-light;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
margin-top: -.1rem;
|
||||||
|
width: .7rem;
|
||||||
|
height: .7rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
fill: $brand-grey;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark & {
|
||||||
|
fill: $brand-grey;
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
fill: $brand-grey-light;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkbox__faux-container {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkbox__faux {
|
||||||
|
display: block;
|
||||||
|
position: relative;
|
||||||
|
width: 1.15rem;
|
||||||
|
height: .61rem;
|
||||||
|
border: .05rem solid $brand-grey-light;
|
||||||
|
border-radius: 15rem;
|
||||||
|
margin-left: $spacer / 3;
|
||||||
|
margin-right: $spacer / 3;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: .025rem;
|
||||||
|
left: .05rem;
|
||||||
|
width: .5rem;
|
||||||
|
height: .5rem;
|
||||||
|
background-color: $brand-grey;
|
||||||
|
border-radius: 15rem;
|
||||||
|
transition: transform .2s $easing;
|
||||||
|
transform: translate3d(0, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkbox {
|
||||||
|
position: relative;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
[type="checkbox"],
|
||||||
|
.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 {
|
||||||
|
+ .checkbox__faux-container {
|
||||||
|
.checkbox__faux {
|
||||||
|
&::after {
|
||||||
|
transform: translate3d(100%, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -3,7 +3,7 @@
|
|||||||
.footer {
|
.footer {
|
||||||
padding: $spacer * 2;
|
padding: $spacer * 2;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
color: $brand-grey-light;
|
color: $text-color-light;
|
||||||
|
|
||||||
&,
|
&,
|
||||||
small {
|
small {
|
||||||
@ -14,6 +14,10 @@
|
|||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
margin-bottom: $spacer;
|
margin-bottom: $spacer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.dark & {
|
||||||
|
color: $text-color-light--dark;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.footer__actions {
|
.footer__actions {
|
||||||
@ -25,7 +29,11 @@
|
|||||||
padding: 0 $spacer / 4;
|
padding: 0 $spacer / 4;
|
||||||
font-size: $font-size-small;
|
font-size: $font-size-small;
|
||||||
margin-left: $spacer;
|
margin-left: $spacer;
|
||||||
color: $brand-grey-light;
|
color: $text-color-light;
|
||||||
|
|
||||||
|
.dark & {
|
||||||
|
color: $text-color-light--dark;
|
||||||
|
}
|
||||||
|
|
||||||
&:first-child {
|
&:first-child {
|
||||||
margin-left: 0;
|
margin-left: 0;
|
||||||
|
@ -4,6 +4,7 @@ import PropTypes from 'prop-types'
|
|||||||
import { FadeIn } from '../atoms/Animations'
|
import { FadeIn } from '../atoms/Animations'
|
||||||
import Social from '../molecules/Social'
|
import Social from '../molecules/Social'
|
||||||
import Availability from '../molecules/Availability'
|
import Availability from '../molecules/Availability'
|
||||||
|
import ThemeSwitch from '../molecules/ThemeSwitch'
|
||||||
import { ReactComponent as Logo } from '../../images/logo.svg'
|
import { ReactComponent as Logo } from '../../images/logo.svg'
|
||||||
import './Header.scss'
|
import './Header.scss'
|
||||||
|
|
||||||
@ -17,6 +18,7 @@ class Header extends Component {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<header className={classes}>
|
<header className={classes}>
|
||||||
|
<ThemeSwitch />
|
||||||
<FadeIn>
|
<FadeIn>
|
||||||
<Link className="header__name" to={'/'}>
|
<Link className="header__name" to={'/'}>
|
||||||
<Logo className="header__logo" />
|
<Logo className="header__logo" />
|
||||||
|
@ -39,6 +39,10 @@
|
|||||||
font-size: $font-size-large;
|
font-size: $font-size-large;
|
||||||
color: $brand-grey;
|
color: $brand-grey;
|
||||||
|
|
||||||
|
.dark & {
|
||||||
|
color: $brand-grey-light;
|
||||||
|
}
|
||||||
|
|
||||||
span {
|
span {
|
||||||
opacity: .4;
|
opacity: .4;
|
||||||
}
|
}
|
||||||
@ -54,13 +58,7 @@
|
|||||||
height: auto;
|
height: auto;
|
||||||
|
|
||||||
@media (min-width: 30rem) {
|
@media (min-width: 30rem) {
|
||||||
margin-top: $spacer;
|
padding-top: $spacer * 2;
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header__title,
|
|
||||||
.header__description {
|
|
||||||
color: $brand-grey-light;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.header__title {
|
.header__title {
|
||||||
@ -72,6 +70,15 @@
|
|||||||
font-size: $font-size-base;
|
font-size: $font-size-base;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.header__title,
|
||||||
|
.header__description {
|
||||||
|
color: $brand-grey-light;
|
||||||
|
|
||||||
|
.dark & {
|
||||||
|
color: $brand-grey;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.header__logo {
|
.header__logo {
|
||||||
width: 1rem;
|
width: 1rem;
|
||||||
height: 1rem;
|
height: 1rem;
|
||||||
@ -81,6 +88,8 @@
|
|||||||
|
|
||||||
.header__name {
|
.header__name {
|
||||||
pointer-events: all;
|
pointer-events: all;
|
||||||
|
display: inline-block;
|
||||||
|
width: auto;
|
||||||
|
|
||||||
&:hover,
|
&:hover,
|
||||||
&:focus {
|
&:focus {
|
||||||
@ -95,11 +104,19 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.header__title {
|
.header__title {
|
||||||
color: $brand-main;
|
color: $color-headings;
|
||||||
|
|
||||||
|
.dark & {
|
||||||
|
color: $color-headings--dark;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.header__description {
|
.header__description {
|
||||||
color: $brand-grey;
|
color: $text-color;
|
||||||
|
|
||||||
|
.dark & {
|
||||||
|
color: $text-color--dark;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
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 |
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 |
@ -19,7 +19,7 @@ html {
|
|||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
background: $brand-light;
|
background: $body-background-color;
|
||||||
font-family: $font-family-base;
|
font-family: $font-family-base;
|
||||||
font-weight: $font-weight-base;
|
font-weight: $font-weight-base;
|
||||||
font-size: $font-size-base;
|
font-size: $font-size-base;
|
||||||
@ -29,6 +29,12 @@ body {
|
|||||||
font-feature-settings: 'liga', 'kern';
|
font-feature-settings: 'liga', 'kern';
|
||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
-moz-osx-font-smoothing: grayscale;
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
transition: background .2s ease-out;
|
||||||
|
|
||||||
|
&.dark {
|
||||||
|
background: $body-background-color--dark;
|
||||||
|
color: $text-color--dark;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
p,
|
p,
|
||||||
@ -40,19 +46,6 @@ ol {
|
|||||||
// Headings
|
// Headings
|
||||||
/////////////////////////////////////
|
/////////////////////////////////////
|
||||||
|
|
||||||
h1,
|
|
||||||
h2,
|
|
||||||
h3,
|
|
||||||
h4,
|
|
||||||
h5,
|
|
||||||
h6 {
|
|
||||||
font-family: $font-family-headings;
|
|
||||||
line-height: $line-height-headings;
|
|
||||||
color: $color-headings;
|
|
||||||
font-weight: $font-weight-headings;
|
|
||||||
margin: 0 0 $spacer;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
font-size: $font-size-h1;
|
font-size: $font-size-h1;
|
||||||
}
|
}
|
||||||
@ -77,6 +70,23 @@ h6 {
|
|||||||
font-size: $font-size-h6;
|
font-size: $font-size-h6;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
h3,
|
||||||
|
h4,
|
||||||
|
h5,
|
||||||
|
h6 {
|
||||||
|
font-family: $font-family-headings;
|
||||||
|
line-height: $line-height-headings;
|
||||||
|
color: $color-headings;
|
||||||
|
font-weight: $font-weight-headings;
|
||||||
|
margin: 0 0 $spacer;
|
||||||
|
|
||||||
|
.dark & {
|
||||||
|
color: $color-headings--dark;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Links
|
// Links
|
||||||
/////////////////////////////////////
|
/////////////////////////////////////
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
$typekit: 'dtg3zui';
|
$typekit: 'dtg3zui';
|
||||||
$projectImageMaxWidth: 1200px;
|
$projectImageMaxWidth: 1200px;
|
||||||
|
$easing: cubic-bezier(.75, 0, .08, 1);
|
||||||
|
|
||||||
// Colors
|
// Colors
|
||||||
/////////////////////////////////////
|
/////////////////////////////////////
|
||||||
@ -13,12 +14,22 @@ $brand-grey-light: lighten($brand-grey, 15%);
|
|||||||
$brand-grey-dimmed: lighten($brand-grey, 50%);
|
$brand-grey-dimmed: lighten($brand-grey, 50%);
|
||||||
|
|
||||||
|
|
||||||
|
// Backgrounds
|
||||||
|
/////////////////////////////////////
|
||||||
|
|
||||||
|
$body-background-color: $brand-light;
|
||||||
|
$body-background-color--dark: darken($brand-grey, 30%);
|
||||||
|
|
||||||
|
|
||||||
// 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: $brand-grey-light;
|
||||||
|
$text-color-light--dark: $brand-grey;
|
||||||
|
|
||||||
|
|
||||||
// Typography
|
// Typography
|
||||||
/////////////////////////////////////
|
/////////////////////////////////////
|
||||||
@ -48,7 +59,9 @@ $font-family-monospace : Menlo, Monaco, Consolas, 'Courier New', monospace;
|
|||||||
$font-family-headings : 'brandon-grotesque', 'Avenir Next', 'Helvetica Neue',Helvetica,Arial,sans-serif;
|
$font-family-headings : 'brandon-grotesque', 'Avenir Next', 'Helvetica Neue',Helvetica,Arial,sans-serif;
|
||||||
$font-weight-headings : 400;
|
$font-weight-headings : 400;
|
||||||
$line-height-headings : 1.1;
|
$line-height-headings : 1.1;
|
||||||
|
|
||||||
$color-headings: $brand-main;
|
$color-headings: $brand-main;
|
||||||
|
$color-headings--dark: lighten($color-headings, 10%);
|
||||||
|
|
||||||
// Components spacing
|
// Components spacing
|
||||||
/////////////////////////////////////
|
/////////////////////////////////////
|
||||||
|
@ -20,7 +20,6 @@
|
|||||||
|
|
||||||
.project__description {
|
.project__description {
|
||||||
font-size: $font-size-base;
|
font-size: $font-size-base;
|
||||||
color: $brand-grey;
|
|
||||||
margin-bottom: $spacer * 3;
|
margin-bottom: $spacer * 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user