mirror of
https://github.com/DerTyp7/explainegy-nextjs.git
synced 2025-10-29 21:02:13 +01:00
d
This commit is contained in:
@@ -3,35 +3,50 @@ import PropTypes from "prop-types";
|
|||||||
import ReactMarkdown from "react-markdown";
|
import ReactMarkdown from "react-markdown";
|
||||||
import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
|
import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
|
||||||
import oneDark from "react-syntax-highlighter/dist/esm/styles/prism/one-dark";
|
import oneDark from "react-syntax-highlighter/dist/esm/styles/prism/one-dark";
|
||||||
import LoadMarkdown from "./articles/[categoryName]/[articleName]/LoadMarkdown";
|
import oneLight from "react-syntax-highlighter/dist/esm/styles/prism/one-light";
|
||||||
|
import styles from "../styles/modules/markdown.module.scss";
|
||||||
|
import remarkGfm from "remark-gfm";
|
||||||
|
import remarkGemoji from "remark-gemoji";
|
||||||
|
import remarkStringify from "remark-stringify";
|
||||||
|
import { useState, useEffect } from "react";
|
||||||
|
import { useLocalStorage } from "usehooks-ts";
|
||||||
export default function Markdown({ value }: { value: any }) {
|
export default function Markdown({ value }: { value: any }) {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<ReactMarkdown
|
<ReactMarkdown
|
||||||
// eslint-disable-next-line react/no-children-prop
|
className={styles.markdown}
|
||||||
children={value}
|
//@ts-ignore
|
||||||
|
remarkPlugins={[remarkGfm, remarkGemoji, remarkStringify]}
|
||||||
components={{
|
components={{
|
||||||
code({ node, inline, className, children, ...props }) {
|
code({ node, inline, className, children, ...props }) {
|
||||||
const match = /language-(\w+)/.exec(className || "");
|
const match = /language-(\w+)/.exec(className || "");
|
||||||
return !inline && match ? (
|
return !inline ? (
|
||||||
<SyntaxHighlighter
|
<>
|
||||||
// eslint-disable-next-line react/no-children-prop
|
<div className={styles.toolbar}>
|
||||||
children={String(children).replace(/\n$/, "")}
|
<div
|
||||||
style={oneDark}
|
onClick={() => {
|
||||||
language={match[1]}
|
navigator.clipboard.writeText(String(children).replace(/\n$/, ""));
|
||||||
PreTag="div"
|
}}
|
||||||
{...props}
|
className={styles.copyBtn}
|
||||||
/>
|
>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
|
||||||
|
<path d="M502.6 70.63l-61.25-61.25C435.4 3.371 427.2 0 418.7 0H255.1c-35.35 0-64 28.66-64 64l.0195 256C192 355.4 220.7 384 256 384h192c35.2 0 64-28.8 64-64V93.25C512 84.77 508.6 76.63 502.6 70.63zM464 320c0 8.836-7.164 16-16 16H255.1c-8.838 0-16-7.164-16-16L239.1 64.13c0-8.836 7.164-16 16-16h128L384 96c0 17.67 14.33 32 32 32h47.1V320zM272 448c0 8.836-7.164 16-16 16H63.1c-8.838 0-16-7.164-16-16L47.98 192.1c0-8.836 7.164-16 16-16H160V128H63.99c-35.35 0-64 28.65-64 64l.0098 256C.002 483.3 28.66 512 64 512h192c35.2 0 64-28.8 64-64v-32h-47.1L272 448z" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<SyntaxHighlighter style={oneDark} language={match ? match[1] : ""} PreTag="div" {...props}>
|
||||||
|
{String(children).replace(/\n$/, "")}
|
||||||
|
</SyntaxHighlighter>
|
||||||
|
</>
|
||||||
) : (
|
) : (
|
||||||
<code className={className} {...props}>
|
<code>{children}</code>
|
||||||
{children}
|
|
||||||
</code>
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
/>
|
>
|
||||||
<LoadMarkdown />
|
{value}
|
||||||
|
</ReactMarkdown>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ export default function AdminArticlesCreate() {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const fetchCategoryOptions = async () => {
|
const fetchCategoryOptions = async () => {
|
||||||
const result: Response = await fetch(urlJoin(apiUrl, `categories`), {
|
const result: Response = await fetch(urlJoin(apiUrl, `categories`), {
|
||||||
cache: "force-cache",
|
cache: "no-cache",
|
||||||
next: { revalidate: 60 * 1 },
|
next: { revalidate: 60 * 1 },
|
||||||
});
|
});
|
||||||
console.log();
|
console.log();
|
||||||
|
|||||||
@@ -1,41 +0,0 @@
|
|||||||
"use client";
|
|
||||||
import React from "react";
|
|
||||||
import { useEffect } from "react";
|
|
||||||
|
|
||||||
import Prism from "prismjs";
|
|
||||||
import "../../../../styles/prism_themes/prism-one-dark.css";
|
|
||||||
//import "../../../styles/prism_themes/prism-one-light.css";
|
|
||||||
|
|
||||||
export default function LoadMarkdown() {
|
|
||||||
useEffect(() => {
|
|
||||||
document.querySelectorAll("pre").forEach((pre) => {
|
|
||||||
if (pre.classList.length < 1) {
|
|
||||||
pre.classList.add("language-");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
document.querySelectorAll("code").forEach((c) => {
|
|
||||||
if (c.classList.length < 1) {
|
|
||||||
c.classList.add("language-");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
document.querySelectorAll("blockquote").forEach((bq) => {
|
|
||||||
bq.classList.add("blockquote");
|
|
||||||
});
|
|
||||||
|
|
||||||
document.querySelectorAll("li").forEach((li) => {
|
|
||||||
let paragraphText = "";
|
|
||||||
li.querySelectorAll("p").forEach((p) => {
|
|
||||||
paragraphText = p.innerHTML;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (paragraphText != "") {
|
|
||||||
li.innerHTML = paragraphText;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Prism.highlightAll();
|
|
||||||
}, []);
|
|
||||||
return <div></div>;
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
import "../../../../styles/markdown.scss";
|
|
||||||
export default function Layout({ children }) {
|
export default function Layout({ children }) {
|
||||||
return <div>{children}</div>;
|
return <div>{children}</div>;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { marked } from "marked";
|
|||||||
import ContentTable from "./ContentTable";
|
import ContentTable from "./ContentTable";
|
||||||
import Sidebar from "./Sidebar";
|
import Sidebar from "./Sidebar";
|
||||||
import styles from "../../../../styles/modules/Article.module.scss";
|
import styles from "../../../../styles/modules/Article.module.scss";
|
||||||
import LoadMarkdown from "./LoadMarkdown";
|
|
||||||
import { Article, Category, ContentTableEntry } from "@prisma/client";
|
import { Article, Category, ContentTableEntry } from "@prisma/client";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import urlJoin from "url-join";
|
import urlJoin from "url-join";
|
||||||
@@ -23,15 +23,11 @@ export async function GetArticle(articleName: string): Promise<any> {
|
|||||||
return result.json();
|
return result.json();
|
||||||
}
|
}
|
||||||
|
|
||||||
function ParseMarkdown(markdown: string): string {
|
|
||||||
let result = marked.parse(markdown);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
//* MAIN
|
//* MAIN
|
||||||
export default async function ArticlePage({ params }: { params: { articleName: string; categoryName: string } }) {
|
export default async function ArticlePage({ params }: { params: { articleName: string; categoryName: string } }) {
|
||||||
const articleName: string = params.articleName.toLowerCase().replaceAll("%20", " ");
|
const articleName: string = params.articleName.toLowerCase().replaceAll("%20", " ");
|
||||||
const article: ArticleWithIncludes = await GetArticle(articleName);
|
const article: ArticleWithIncludes = await GetArticle(articleName);
|
||||||
|
|
||||||
const dateUpdated: Date = new Date(article.dateUpdated);
|
const dateUpdated: Date = new Date(article.dateUpdated);
|
||||||
const dateCreated: Date = new Date(article.dateCreated);
|
const dateCreated: Date = new Date(article.dateCreated);
|
||||||
const dateOptions: Intl.DateTimeFormatOptions = { month: "long", day: "numeric", year: "numeric" };
|
const dateOptions: Intl.DateTimeFormatOptions = { month: "long", day: "numeric", year: "numeric" };
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ export default async function CategoryPage({ params }: { params: { categoryName:
|
|||||||
{
|
{
|
||||||
return (
|
return (
|
||||||
<Link key={i} href={`/articles/${category.name}/${a.name}`}>
|
<Link key={i} href={`/articles/${category.name}/${a.name}`}>
|
||||||
{a.name}
|
{a.title}
|
||||||
</Link>
|
</Link>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -85,7 +85,7 @@ export default async function CategoryPage({ params }: { params: { categoryName:
|
|||||||
{
|
{
|
||||||
return (
|
return (
|
||||||
<Link key={i} href={`/articles/${category.name}/${a.name}`}>
|
<Link key={i} href={`/articles/${category.name}/${a.name}`}>
|
||||||
{a.name}
|
{a.title}
|
||||||
</Link>
|
</Link>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import Link from "next/link";
|
|||||||
|
|
||||||
async function getCategories(): Promise<Category[]> {
|
async function getCategories(): Promise<Category[]> {
|
||||||
const result: Response = await fetch(urlJoin(apiUrl, `categories`), {
|
const result: Response = await fetch(urlJoin(apiUrl, `categories`), {
|
||||||
cache: "force-cache",
|
cache: "no-cache",
|
||||||
next: { revalidate: 3600 },
|
next: { revalidate: 3600 },
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
6118
package-lock.json
generated
6118
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
10
package.json
10
package.json
@@ -31,11 +31,19 @@
|
|||||||
"react-select": "^5.7.0",
|
"react-select": "^5.7.0",
|
||||||
"react-syntax-highlighter": "^15.5.0",
|
"react-syntax-highlighter": "^15.5.0",
|
||||||
"reflect-metadata": "^0.1.13",
|
"reflect-metadata": "^0.1.13",
|
||||||
|
"remark-code-blocks": "^2.0.1",
|
||||||
|
"remark-codesandbox": "^0.10.1",
|
||||||
|
"remark-emoji": "^3.0.2",
|
||||||
|
"remark-gemoji": "^7.0.1",
|
||||||
|
"remark-gfm": "^3.0.1",
|
||||||
|
"remark-stringify": "^10.0.2",
|
||||||
"sass": "^1.57.0",
|
"sass": "^1.57.0",
|
||||||
"typescript": "4.9.4",
|
"typescript": "4.9.4",
|
||||||
"url-join": "^5.0.0"
|
"url-join": "^5.0.0",
|
||||||
|
"usehooks-ts": "^2.9.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@fec/remark-a11y-emoji": "^3.1.0",
|
||||||
"@types/node": "^18.11.17",
|
"@types/node": "^18.11.17",
|
||||||
"@types/prismjs": "^1.26.0",
|
"@types/prismjs": "^1.26.0",
|
||||||
"prisma": "^4.8.0"
|
"prisma": "^4.8.0"
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import { Request, Response } from "express";
|
import { Request, Response } from "express";
|
||||||
import prisma from "../../../lib/prisma";
|
import prisma from "../../../lib/prisma";
|
||||||
import { Article, Prisma, ContentTableEntry } from '@prisma/client';
|
import { Prisma, ContentTableEntry } from '@prisma/client';
|
||||||
import { ResponseError } from "../../../types/responseErrors";
|
import { ResponseError } from "../../../types/responseErrors";
|
||||||
|
import { getUrlSafeString } from "../../../app/utils";
|
||||||
|
|
||||||
type ArticleWithIncludes = Prisma.ArticleGetPayload<{ include: { contentTableEntries: true, category: true, image: true } }>
|
type ArticleWithIncludes = Prisma.ArticleGetPayload<{ include: { contentTableEntries: true, category: true, image: true } }>
|
||||||
|
|
||||||
@@ -13,8 +14,8 @@ function sortContentTableEntries(entries: ContentTableEntry[]): ContentTableEntr
|
|||||||
export default async function handler(req: Request, res: Response) {
|
export default async function handler(req: Request, res: Response) {
|
||||||
res.setHeader("Content-Type", "application/json");
|
res.setHeader("Content-Type", "application/json");
|
||||||
|
|
||||||
const articleName: string = req.query.articleName.toString();
|
const articleName: string = getUrlSafeString(req.query.articleName.toString())
|
||||||
|
console.log(articleName)
|
||||||
await prisma.article
|
await prisma.article
|
||||||
.findUnique({ where: { name: articleName }, include: { category: true, contentTableEntries: true, image: true } })
|
.findUnique({ where: { name: articleName }, include: { category: true, contentTableEntries: true, image: true } })
|
||||||
.then((result: ArticleWithIncludes) => {
|
.then((result: ArticleWithIncludes) => {
|
||||||
|
|||||||
@@ -1,113 +0,0 @@
|
|||||||
// This file contains the markdown styles
|
|
||||||
|
|
||||||
.markdown {
|
|
||||||
padding: 0 10px 0 10px;
|
|
||||||
color: var(--md-color-font);
|
|
||||||
|
|
||||||
hr {
|
|
||||||
border: 1px solid var(--md-color-hr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Texts */
|
|
||||||
h1,
|
|
||||||
h2,
|
|
||||||
h3,
|
|
||||||
h4,
|
|
||||||
h5,
|
|
||||||
h6 {
|
|
||||||
color: var(--md-color-headline);
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
margin-top: 1em;
|
|
||||||
line-height: 1.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Images */
|
|
||||||
img {
|
|
||||||
max-width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Code */
|
|
||||||
code {
|
|
||||||
background-color: #282c34;
|
|
||||||
padding: 5px;
|
|
||||||
border-radius: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
pre {
|
|
||||||
overflow: auto;
|
|
||||||
word-wrap: normal;
|
|
||||||
white-space: pre;
|
|
||||||
display: block;
|
|
||||||
|
|
||||||
code {
|
|
||||||
display: block;
|
|
||||||
font-size: 1em;
|
|
||||||
text-indent: 0;
|
|
||||||
white-space: inherit;
|
|
||||||
background-color: transparent;
|
|
||||||
padding: 0px;
|
|
||||||
border-radius: 0px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Lists */
|
|
||||||
ul,
|
|
||||||
ol {
|
|
||||||
list-style: inside;
|
|
||||||
li {
|
|
||||||
display: list-item;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ul {
|
|
||||||
list-style-type: circle;
|
|
||||||
}
|
|
||||||
|
|
||||||
ol {
|
|
||||||
list-style-type: decimal;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Blockquotes */
|
|
||||||
.blockquote {
|
|
||||||
border-left: 5px solid var(--md-color-blockquote-border);
|
|
||||||
padding-left: 20px;
|
|
||||||
background-color: var(--md-color-blockquote-background);
|
|
||||||
}
|
|
||||||
/* Table */
|
|
||||||
table {
|
|
||||||
border-radius: 5px;
|
|
||||||
border-collapse: collapse;
|
|
||||||
width: 100%;
|
|
||||||
display: table;
|
|
||||||
overflow: auto;
|
|
||||||
|
|
||||||
thead,
|
|
||||||
tbody {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
thead th:nth-child(odd) {
|
|
||||||
color: #ffffff;
|
|
||||||
background: var(--md-color-table-col-odd-background);
|
|
||||||
}
|
|
||||||
tr {
|
|
||||||
background: var(--md-color-table-row-odd-background);
|
|
||||||
}
|
|
||||||
tr:nth-child(even) {
|
|
||||||
background: var(--md-color-table-row-even-background);
|
|
||||||
}
|
|
||||||
th,
|
|
||||||
td {
|
|
||||||
text-align: center;
|
|
||||||
padding: 8px;
|
|
||||||
}
|
|
||||||
td {
|
|
||||||
border-right: 1px solid #ffffff00;
|
|
||||||
}
|
|
||||||
th {
|
|
||||||
color: #ffffff;
|
|
||||||
background: var(--md-color-table-col-even-background);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
141
styles/modules/markdown.module.scss
Normal file
141
styles/modules/markdown.module.scss
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
// This file contains the markdown styles
|
||||||
|
|
||||||
|
.markdown {
|
||||||
|
padding: 0 10px 0 10px;
|
||||||
|
color: var(--md-color-font);
|
||||||
|
|
||||||
|
.toolbar {
|
||||||
|
background-color: red;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: flex-end;
|
||||||
|
padding: 0 10px;
|
||||||
|
position: relative;
|
||||||
|
.copyBtn {
|
||||||
|
height: 30px;
|
||||||
|
width: 30px;
|
||||||
|
margin-top: 15px;
|
||||||
|
cursor: pointer;
|
||||||
|
position: absolute;
|
||||||
|
transition-delay: 2s, 4ms;
|
||||||
|
transition: all 50ms ease-in-out;
|
||||||
|
|
||||||
|
svg {
|
||||||
|
fill: #bdbdbd;
|
||||||
|
transition: all 50ms linear;
|
||||||
|
&:hover {
|
||||||
|
fill: var(--color-accent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hr {
|
||||||
|
border: 1px solid var(--md-color-hr);
|
||||||
|
margin: 20px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Texts */
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
h3,
|
||||||
|
h4,
|
||||||
|
h5,
|
||||||
|
h6 {
|
||||||
|
color: var(--md-color-headline);
|
||||||
|
margin: 20px 0 10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin: 0px 0 10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Images */
|
||||||
|
img {
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Code */
|
||||||
|
code {
|
||||||
|
background-color: #282c34;
|
||||||
|
padding: 5px;
|
||||||
|
border-radius: 5px;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre {
|
||||||
|
overflow: auto;
|
||||||
|
word-wrap: normal;
|
||||||
|
white-space: pre;
|
||||||
|
display: block;
|
||||||
|
|
||||||
|
code {
|
||||||
|
display: block;
|
||||||
|
font-size: 1em;
|
||||||
|
text-indent: 0;
|
||||||
|
white-space: inherit;
|
||||||
|
background-color: transparent;
|
||||||
|
padding: 0px;
|
||||||
|
border-radius: 0px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Lists */
|
||||||
|
ul,
|
||||||
|
ol {
|
||||||
|
list-style: inside;
|
||||||
|
li {
|
||||||
|
display: list-item;
|
||||||
|
line-height: 1.5em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style-type: circle;
|
||||||
|
}
|
||||||
|
|
||||||
|
ol {
|
||||||
|
list-style-type: decimal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Blockquotes */
|
||||||
|
.blockquote {
|
||||||
|
border-left: 5px solid var(--md-color-blockquote-border);
|
||||||
|
padding-left: 20px;
|
||||||
|
background-color: var(--md-color-blockquote-background);
|
||||||
|
}
|
||||||
|
/* Table */
|
||||||
|
table {
|
||||||
|
border-radius: 5px;
|
||||||
|
border-collapse: collapse;
|
||||||
|
width: 100%;
|
||||||
|
display: table;
|
||||||
|
overflow: auto;
|
||||||
|
|
||||||
|
thead,
|
||||||
|
tbody {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
thead th:nth-child(odd) {
|
||||||
|
color: #ffffff;
|
||||||
|
background: var(--md-color-table-col-odd-background);
|
||||||
|
}
|
||||||
|
tr {
|
||||||
|
background: var(--md-color-table-row-odd-background);
|
||||||
|
}
|
||||||
|
tr:nth-child(even) {
|
||||||
|
background: var(--md-color-table-row-even-background);
|
||||||
|
}
|
||||||
|
th,
|
||||||
|
td {
|
||||||
|
text-align: center;
|
||||||
|
padding: 8px;
|
||||||
|
}
|
||||||
|
td {
|
||||||
|
border-right: 1px solid #ffffff00;
|
||||||
|
}
|
||||||
|
th {
|
||||||
|
color: #ffffff;
|
||||||
|
background: var(--md-color-table-col-even-background);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,40 +17,33 @@ body {
|
|||||||
|
|
||||||
/* Headings */
|
/* Headings */
|
||||||
h1 {
|
h1 {
|
||||||
font-size: calc($font-size-default + $font-size-headline-step * 6);
|
font-size: 2rem;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
letter-spacing: $font-letter-spacing-headline-large;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
// 5 skipped on purpose
|
font-size: 1.7rem;
|
||||||
font-size: calc($font-size-default + $font-size-headline-step * 4);
|
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
letter-spacing: $font-letter-spacing-headline-medium;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
h3 {
|
h3 {
|
||||||
font-size: calc($font-size-default + $font-size-headline-step * 3);
|
font-size: 1.5rem;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
letter-spacing: $font-letter-spacing-headline-small;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
h4 {
|
h4 {
|
||||||
font-size: calc($font-size-default + $font-size-headline-step * 2);
|
font-size: 1.4rem;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
letter-spacing: $font-letter-spacing-headline-small;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
h5 {
|
h5 {
|
||||||
font-size: calc($font-size-default + $font-size-headline-step * 1);
|
font-size: 1.2rem;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
letter-spacing: $font-letter-spacing-headline-small;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
h6 {
|
h6 {
|
||||||
font-size: $font-size-default;
|
font-size: 1.1rem;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
letter-spacing: 1.25px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* General Texts */
|
/* General Texts */
|
||||||
|
|||||||
@@ -1,12 +1,8 @@
|
|||||||
// This file stores all SCSS variables in one place to simplify the use of variables throughout the project.
|
// This file stores all SCSS variables in one place to simplify the use of variables throughout the project.
|
||||||
|
|
||||||
/* Typography */
|
/* Typography */
|
||||||
$font-size-default: 1em;
|
$font-size-default: 1rem;
|
||||||
$font-size-headline-step: 0.12em;
|
$font-letter-spacing-default: 0.1rem;
|
||||||
$font-letter-spacing-default: 1px;
|
|
||||||
$font-letter-spacing-headline-large: 2px;
|
|
||||||
$font-letter-spacing-headline-medium: 1.5px;
|
|
||||||
$font-letter-spacing-headline-small: 1.25px;
|
|
||||||
|
|
||||||
/* Tutorial Page */
|
/* Tutorial Page */
|
||||||
$tutorial-grid-sticky-top: 60px;
|
$tutorial-grid-sticky-top: 60px;
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
"isolatedModules": true,
|
"isolatedModules": true,
|
||||||
|
"noImplicitThis": true,
|
||||||
"jsx": "preserve",
|
"jsx": "preserve",
|
||||||
"plugins": [
|
"plugins": [
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user