Refactor and minor fixes

This commit is contained in:
Andras Schmelczer 2022-09-21 21:57:58 +02:00
parent 2dc9c45642
commit fe75f9af88
No known key found for this signature in database
GPG key ID: 0EA1BC97D0AB076E
31 changed files with 187 additions and 193 deletions

View file

@ -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>
`;

View file

@ -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());
}
}

View 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"/>
`;

View 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));
}
}
}

View 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;
}
}
}