Refactor components to simplify them
This commit is contained in:
parent
3cf5b14913
commit
077ed9d3bf
36 changed files with 202 additions and 216 deletions
|
|
@ -20,5 +20,6 @@
|
|||
font-size: 0.9rem;
|
||||
font-style: italic;
|
||||
padding: 0 8px 8px 8px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,15 +1,11 @@
|
|||
import { createElement } from '../../../helper/create-element';
|
||||
import { url } from '../../../types/url';
|
||||
import { PageElement } from '../../page-element';
|
||||
import { generate } from './image-anchor.html';
|
||||
|
||||
export const ImageAnchorFactory = (
|
||||
svg: string,
|
||||
title: string,
|
||||
{ shouldDownload = false }: { shouldDownload?: boolean } = {}
|
||||
) =>
|
||||
class ImageAnchor extends PageElement {
|
||||
public constructor(href: url) {
|
||||
super(createElement(generate({ href, svg, title, shouldDownload })));
|
||||
}
|
||||
};
|
||||
export const ImageAnchorFactory =
|
||||
(
|
||||
svg: string,
|
||||
title: string,
|
||||
{ shouldDownload = false }: { shouldDownload?: boolean } = {}
|
||||
) =>
|
||||
(href: url) =>
|
||||
generate({ href, svg, title, shouldDownload });
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ export class Preview extends PageElement {
|
|||
this.query('.start-button').addEventListener('click', this.loadContent.bind(this));
|
||||
}
|
||||
|
||||
public setParent(parent: PageElement) {
|
||||
protected setParent(parent: PageElement) {
|
||||
new IntersectionObserver((e) => {
|
||||
if (!e[0].isIntersecting) {
|
||||
this.unloadContent();
|
||||
|
|
|
|||
|
|
@ -1,9 +0,0 @@
|
|||
import { PageElement } from '../page-element';
|
||||
|
||||
export class Body extends PageElement {
|
||||
constructor(...children: Array<PageElement>) {
|
||||
super(document.body, children);
|
||||
children.forEach((c) => this.attachElement(c));
|
||||
this.setParent();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
import { html } from '../../types/html';
|
||||
import './content.scss';
|
||||
|
||||
export const generate = (): html => `
|
||||
<div class="content"></div>
|
||||
`;
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
@use '../../style/mixins' as *;
|
||||
|
||||
.content {
|
||||
text-align: left;
|
||||
}
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
import { createElement } from '../../helper/create-element';
|
||||
|
||||
import { generate } from './content.html';
|
||||
import { PageElement } from '../page-element';
|
||||
|
||||
export class PageContent extends PageElement {
|
||||
public constructor(content: Array<string>) {
|
||||
super(createElement(generate()));
|
||||
content.map((t) => {
|
||||
const p = createElement(`<p>${t}</p>`);
|
||||
this.htmlRoot.appendChild(p);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +1,17 @@
|
|||
import { html } from '../../types/html';
|
||||
import './header.scss';
|
||||
|
||||
export const generate = (name: string): html => `
|
||||
export const generate = ({
|
||||
name,
|
||||
about,
|
||||
}: {
|
||||
name: string;
|
||||
about: Array<string>;
|
||||
}): html => `
|
||||
<section id="about">
|
||||
<div class="picture"></div>
|
||||
<div class="placeholder"></div>
|
||||
<h1>${name}</h1>
|
||||
${about.map((t) => `<p>${t}</p>`).join('\n')}
|
||||
</section>
|
||||
`;
|
||||
|
|
|
|||
|
|
@ -1,16 +1,22 @@
|
|||
import { createElement } from '../../helper/create-element';
|
||||
import { Image } from '../basics/image/image';
|
||||
import { PageContent } from '../content/content';
|
||||
import { PageElement } from '../page-element';
|
||||
import { PageThemeSwitcher } from '../theme-switcher/theme-switcher';
|
||||
import { generate } from './header.html';
|
||||
|
||||
export class PageHeader extends PageElement {
|
||||
public constructor(header: { name: string; photo: Image; about: Array<string> }) {
|
||||
super(createElement(generate(header.name)));
|
||||
public constructor({
|
||||
name,
|
||||
photo,
|
||||
about,
|
||||
}: {
|
||||
name: string;
|
||||
photo: Image;
|
||||
about: Array<string>;
|
||||
}) {
|
||||
super(createElement(generate({ name, about })));
|
||||
|
||||
this.attachElementByReplacing('.picture', header.photo);
|
||||
this.attachElement(new PageContent(header.about));
|
||||
this.attachElementByReplacing('.picture', photo);
|
||||
this.attachElement(new PageThemeSwitcher());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { createElement } from '../../helper/create-element';
|
||||
import { PageElement } from '../page-element';
|
||||
import { generate } from './image-viewer.html';
|
||||
import { createElement } from '../../helper/create-element';
|
||||
|
||||
export class PageImageViewer extends PageElement {
|
||||
public constructor() {
|
||||
|
|
@ -9,7 +9,7 @@ export class PageImageViewer extends PageElement {
|
|||
document.body.addEventListener('click', (event: MouseEvent) => {
|
||||
if (
|
||||
event.target instanceof HTMLImageElement &&
|
||||
!event.target.attributes['image-viewer-ignore']
|
||||
!(event.target.attributes['image-viewer-ignore'] as boolean | undefined)
|
||||
) {
|
||||
this.showImage(event.target);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,11 @@ export abstract class PageElement {
|
|||
protected children: Array<PageElement> = []
|
||||
) {}
|
||||
|
||||
public attachToDOM(target: HTMLElement) {
|
||||
target.appendChild(this.htmlRoot);
|
||||
this.setParent(null);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
protected setParent(parent?: PageElement | null): void {
|
||||
this.children.forEach((c) => c.setParent(this));
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
import { html } from '../../../types/html';
|
||||
import { Image } from '../../basics/image/image';
|
||||
import { Preview } from '../../basics/preview/preview';
|
||||
import { Video } from '../../basics/video/video';
|
||||
|
||||
export interface TimelineElementParameters {
|
||||
date: string;
|
||||
figure: Image | Video | Preview;
|
||||
title: string;
|
||||
description: string;
|
||||
more: Array<string>;
|
||||
links: Array<html>;
|
||||
}
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
import info from '../../../../static/icons/info.svg';
|
||||
import { titleToFragment } from '../../../helper/title-to-fragment';
|
||||
import { html } from '../../../types/html';
|
||||
import { TimelineElementParameters } from './timeline-element';
|
||||
import { TimelineElementParameters } from './timeline-element-parameters';
|
||||
import './timeline-element.scss';
|
||||
|
||||
export const generate = (
|
||||
{ date, title, description, more }: TimelineElementParameters,
|
||||
{ date, title, description, more, links }: TimelineElementParameters,
|
||||
showMore: string
|
||||
): html => `
|
||||
<section id="${titleToFragment(title)}" class="timeline-element">
|
||||
|
|
@ -22,7 +22,14 @@ export const generate = (
|
|||
|
||||
<p class="description">${description}</p>
|
||||
|
||||
${more ? '<div class="more"></div>' : ''}
|
||||
${
|
||||
more
|
||||
? `
|
||||
<div class="more">
|
||||
${more.map((t) => `<p>${t}</p>`).join('\n')}
|
||||
</div>`
|
||||
: ''
|
||||
}
|
||||
|
||||
<div class="buttons">
|
||||
${
|
||||
|
|
@ -32,6 +39,7 @@ export const generate = (
|
|||
<p>${showMore}</p>
|
||||
</div>`
|
||||
}
|
||||
${links.join('')}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -85,7 +85,6 @@
|
|||
}
|
||||
|
||||
.card {
|
||||
text-align: center;
|
||||
box-shadow: var(--shadow);
|
||||
border-radius: var(--border-radius);
|
||||
z-index: 1;
|
||||
|
|
@ -108,27 +107,31 @@
|
|||
margin-top: var(--small-margin);
|
||||
}
|
||||
|
||||
h2 > a {
|
||||
@include sub-title-font();
|
||||
text-decoration: none;
|
||||
position: relative;
|
||||
h2 {
|
||||
text-align: center;
|
||||
|
||||
&:before {
|
||||
content: '#';
|
||||
position: absolute;
|
||||
left: -0.5ch;
|
||||
top: 0;
|
||||
opacity: 0;
|
||||
transform: translateX(-100%);
|
||||
transition: opacity var(--transition-time);
|
||||
}
|
||||
> a {
|
||||
@include sub-title-font();
|
||||
text-decoration: none;
|
||||
position: relative;
|
||||
|
||||
&:hover:before {
|
||||
opacity: 0.5;
|
||||
&:before {
|
||||
content: '#';
|
||||
position: absolute;
|
||||
left: -0.5ch;
|
||||
top: 0;
|
||||
opacity: 0;
|
||||
transform: translateX(-100%);
|
||||
transition: opacity var(--transition-time);
|
||||
}
|
||||
|
||||
&:hover:before {
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
& > p {
|
||||
.description {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
|
|
@ -138,7 +141,7 @@
|
|||
height: 0;
|
||||
transition: height var(--transition-time);
|
||||
|
||||
.content p {
|
||||
> p {
|
||||
margin-top: var(--line-height);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,20 +1,8 @@
|
|||
import { createElement } from '../../../helper/create-element';
|
||||
import { Image } from '../../basics/image/image';
|
||||
import { Preview } from '../../basics/preview/preview';
|
||||
import { Video } from '../../basics/video/video';
|
||||
import { PageContent } from '../../content/content';
|
||||
import { PageElement } from '../../page-element';
|
||||
import { TimelineElementParameters } from './timeline-element-parameters';
|
||||
import { generate } from './timeline-element.html';
|
||||
|
||||
export interface TimelineElementParameters {
|
||||
date: string;
|
||||
figure: Image | Video | Preview;
|
||||
title: string;
|
||||
description: string;
|
||||
more: Array<string>;
|
||||
links: Array<PageElement>;
|
||||
}
|
||||
|
||||
export class PageTimelineElement extends PageElement {
|
||||
private isOpen = false;
|
||||
private more: HTMLElement;
|
||||
|
|
@ -25,17 +13,12 @@ export class PageTimelineElement extends PageElement {
|
|||
private readonly showLess: string
|
||||
) {
|
||||
super(createElement(generate(timelineElement, showMore)));
|
||||
const content = new PageContent(timelineElement.more);
|
||||
this.children = [content];
|
||||
this.isOpen = false;
|
||||
this.more = this.query('.more');
|
||||
this.more.appendChild(content.htmlRoot);
|
||||
addEventListener('resize', this.handleResize.bind(this));
|
||||
|
||||
this.query('.info-button').addEventListener('click', this.toggleOpen.bind(this));
|
||||
this.attachElementByReplacing('.figure', timelineElement.figure);
|
||||
timelineElement.links.forEach((l) => this.attachElementAsChildOf('.buttons', l));
|
||||
|
||||
this.isOpen = false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
import { createElement } from '../../helper/create-element';
|
||||
import { PageElement } from '../page-element';
|
||||
import {
|
||||
PageTimelineElement,
|
||||
TimelineElementParameters,
|
||||
} from './timeline-element/timeline-element';
|
||||
import { PageTimelineElement } from './timeline-element/timeline-element';
|
||||
import { TimelineElementParameters } from './timeline-element/timeline-element-parameters';
|
||||
import { generate } from './timeline.html';
|
||||
|
||||
export class PageTimeline extends PageElement {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue