Refactor and minor fixes
This commit is contained in:
parent
2dc9c45642
commit
fe75f9af88
31 changed files with 187 additions and 193 deletions
|
|
@ -4,14 +4,16 @@ import './header.scss';
|
|||
export const generate = ({
|
||||
name,
|
||||
about,
|
||||
photo,
|
||||
}: {
|
||||
name: string;
|
||||
about: Array<string>;
|
||||
photo: html;
|
||||
}): html => `
|
||||
<section id="about">
|
||||
<div class="picture"></div>
|
||||
${photo}
|
||||
<div class="placeholder"></div>
|
||||
<h1>${name}</h1>
|
||||
${about.map((t) => `<p>${t}</p>`).join('\n')}
|
||||
${about.map((t) => `<p>${t}</p>`).join('')}
|
||||
</section>
|
||||
`;
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import { createElement } from '../../helper/create-element';
|
||||
import { Image } from '../basics/image/image';
|
||||
import { html } from '../../types/html';
|
||||
import { PageElement } from '../page-element';
|
||||
import { PageThemeSwitcher } from '../theme-switcher/theme-switcher';
|
||||
import { generate } from './header.html';
|
||||
import { PageThemeSwitcher } from './theme-switcher/theme-switcher';
|
||||
|
||||
export class PageHeader extends PageElement {
|
||||
public constructor({
|
||||
|
|
@ -11,12 +11,10 @@ export class PageHeader extends PageElement {
|
|||
about,
|
||||
}: {
|
||||
name: string;
|
||||
photo: Image;
|
||||
photo: html;
|
||||
about: Array<string>;
|
||||
}) {
|
||||
super(createElement(generate({ name, about })));
|
||||
|
||||
this.attachElementByReplacing('.picture', photo);
|
||||
super(createElement(generate({ name, about, photo })));
|
||||
this.attachElement(new PageThemeSwitcher());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
6
src/page/header/theme-switcher/theme-switcher.html.ts
Normal file
6
src/page/header/theme-switcher/theme-switcher.html.ts
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
import { html } from '../../../types/html';
|
||||
import './theme-switcher.scss';
|
||||
|
||||
export const generate = (): html => `
|
||||
<input id="theme-switcher" aria-label="color-theme-switch" type="checkbox" name="switch-theme"/>
|
||||
`;
|
||||
89
src/page/header/theme-switcher/theme-switcher.scss
Normal file
89
src/page/header/theme-switcher/theme-switcher.scss
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
@use '../../../style/mixins' as *;
|
||||
|
||||
#theme-switcher {
|
||||
@include on-large-screen {
|
||||
position: absolute;
|
||||
top: calc(-1 * var(--small-margin));
|
||||
right: calc(-1 * (50vw - var(--body-width) / 2) + var(--normal-margin));
|
||||
transform: translateY(-100%);
|
||||
}
|
||||
|
||||
@include on-small-screen {
|
||||
position: relative;
|
||||
margin-top: var(--normal-margin);
|
||||
}
|
||||
|
||||
background-color: var(--accent-color);
|
||||
cursor: pointer;
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
|
||||
$size: var(--icon-size);
|
||||
width: calc(2 * #{$size});
|
||||
height: $size;
|
||||
$icon-size: calc(0.7 * #{$size});
|
||||
$margin: calc((#{$size} - #{$icon-size}) / 2);
|
||||
|
||||
border-radius: 1000px;
|
||||
box-shadow: inset 0 0 10px 2px rgba(0, 0, 0, 0.175), inset 0 0 1px rgba(0, 0, 0, 0.4);
|
||||
|
||||
&:before {
|
||||
// moon + sun
|
||||
@include square($icon-size);
|
||||
}
|
||||
|
||||
&:after {
|
||||
// sun blocking moon
|
||||
@include square(calc(#{$icon-size} * 0.8));
|
||||
}
|
||||
|
||||
&:before,
|
||||
&:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
display: block;
|
||||
border-radius: 1000px;
|
||||
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
|
||||
transition: transform var(--transition-time), background-color var(--transition-time);
|
||||
}
|
||||
|
||||
&:not(:checked) {
|
||||
&:before {
|
||||
transform: translateY(-50%) translateX(calc(3 * #{$margin} + #{$icon-size}));
|
||||
|
||||
animation: shine 3s linear alternate infinite;
|
||||
background-color: var(--sun-color);
|
||||
@keyframes shine {
|
||||
from {
|
||||
filter: brightness(1.01);
|
||||
box-shadow: 0 0 4px 2px var(--sun-color);
|
||||
}
|
||||
|
||||
to {
|
||||
filter: brightness(1.1);
|
||||
box-shadow: 0 0 15px 2px var(--sun-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:after {
|
||||
background-color: transparent;
|
||||
transform: translateY(-50%) translateX(calc(#{$size} * 2 - #{$icon-size}));
|
||||
}
|
||||
}
|
||||
|
||||
&:checked {
|
||||
&:before {
|
||||
background-color: var(--normal-text-color);
|
||||
transform: translateY(-50%) translateX($margin);
|
||||
}
|
||||
|
||||
&:after {
|
||||
background-color: var(--accent-color);
|
||||
transform: translateY(-50%) translateX(calc(#{$margin} + #{$icon-size} * 0.33));
|
||||
}
|
||||
}
|
||||
}
|
||||
62
src/page/header/theme-switcher/theme-switcher.ts
Normal file
62
src/page/header/theme-switcher/theme-switcher.ts
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
import { createElement } from '../../../helper/create-element';
|
||||
import {
|
||||
turnOffAnimations,
|
||||
turnOnAnimations,
|
||||
} from '../../../style/animations/animations';
|
||||
import {
|
||||
isSystemLevelDarkModeEnabled,
|
||||
turnOnDarkMode,
|
||||
turnOnLightMode,
|
||||
} from '../../../style/dark-mode/dark-mode';
|
||||
import { PageElement } from '../../page-element';
|
||||
import { generate } from './theme-switcher.html';
|
||||
|
||||
export class PageThemeSwitcher extends PageElement {
|
||||
private static readonly localStorageKey = 'dark-mode';
|
||||
|
||||
public constructor() {
|
||||
super(createElement(generate()));
|
||||
|
||||
const storedIsDark = PageThemeSwitcher.loadFromLocalStorage();
|
||||
const isDark = storedIsDark !== null ? storedIsDark : isSystemLevelDarkModeEnabled();
|
||||
|
||||
if (isDark) {
|
||||
(this.htmlRoot as HTMLInputElement).checked = true;
|
||||
turnOffAnimations();
|
||||
turnOnDarkMode();
|
||||
turnOnAnimations();
|
||||
} else {
|
||||
turnOnLightMode();
|
||||
}
|
||||
|
||||
this.htmlRoot.onchange = this.handleThemeChange.bind(this);
|
||||
|
||||
this.handleThemeChange();
|
||||
}
|
||||
|
||||
private handleThemeChange() {
|
||||
const isDark = (this.htmlRoot as HTMLInputElement).checked;
|
||||
if (isDark) {
|
||||
turnOnDarkMode();
|
||||
} else {
|
||||
turnOnLightMode();
|
||||
}
|
||||
|
||||
PageThemeSwitcher.saveToLocalStorage(isDark);
|
||||
}
|
||||
|
||||
private static saveToLocalStorage(darkModeEnabled: boolean) {
|
||||
localStorage?.setItem(
|
||||
PageThemeSwitcher.localStorageKey,
|
||||
JSON.stringify(darkModeEnabled)
|
||||
);
|
||||
}
|
||||
|
||||
private static loadFromLocalStorage(): boolean | null {
|
||||
try {
|
||||
return JSON.parse(localStorage!.getItem(PageThemeSwitcher.localStorageKey)!);
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue