Styling styling styling

This commit is contained in:
Daniel Kluge 2022-10-23 17:23:05 +02:00
parent 6f4ba59faf
commit 62c5ef0c25
3 changed files with 146 additions and 37 deletions

View File

@ -1,5 +1,5 @@
import Icon from "@mdi/react"; import Icon from "@mdi/react";
import { mdiBash, mdiLanguageCpp, mdiLanguageCsharp, mdiLanguageJava, mdiLanguageJavascript, mdiLanguagePhp, mdiLanguagePython, mdiLanguageRust, mdiLanguageTypescript, mdiReact } from "@mdi/js"; import { mdiBash, mdiLanguageCpp, mdiLanguageCsharp, mdiLanguageJava, mdiLanguageJavascript, mdiLanguagePhp, mdiLanguagePython, mdiLanguageRust, mdiLanguageTypescript, mdiReact, mdiTranslateVariant } from "@mdi/js";
import { Android, Arduino, CssThree, Espressif, Express, Html5, Linux, Sass, Springboot, Windows } from "@icons-pack/react-simple-icons"; import { Android, Arduino, CssThree, Espressif, Express, Html5, Linux, Sass, Springboot, Windows } from "@icons-pack/react-simple-icons";
export interface Skill { export interface Skill {
@ -13,10 +13,17 @@ export interface AdditionalSkill {
icon?: JSX.Element; icon?: JSX.Element;
} }
export interface CardColors {
background: string;
bars: string;
heading: string;
}
export interface SkillCard { export interface SkillCard {
title: string; title: string;
skillBars: Skill[]; skillBars: Skill[];
additional?: AdditionalSkill[]; additional?: AdditionalSkill[];
colors?: CardColors;
} }
export interface SkillSet { export interface SkillSet {
@ -25,119 +32,137 @@ export interface SkillSet {
} }
export const skills = (sizeCardIcons?: string, sizeBadgeIcons?: string): SkillSet => { export const skills = (sizeCardIcons?: string, sizeBadgeIcons?: string): SkillSet => {
sizeCardIcons = sizeCardIcons || "2em";
sizeBadgeIcons = sizeBadgeIcons || "1em";
return { return {
cards: [{ cards: [{
title: "Programming Languages", title: "Programming Languages",
skillBars: [{ skillBars: [{
name: "TypeScript", name: "TypeScript",
icon: <Icon path={mdiLanguageTypescript} size={sizeCardIcons || "2em"} />, icon: <Icon path={mdiLanguageTypescript} size={sizeCardIcons} />,
pct: 100 pct: 100
}, { }, {
name: "JavaScript", name: "JavaScript",
icon: <Icon path={mdiLanguageJavascript} size={sizeCardIcons || "2em"} />, icon: <Icon path={mdiLanguageJavascript} size={sizeCardIcons} />,
pct: 100 pct: 100
}, { }, {
name: "Java", name: "Java",
icon: <Icon path={mdiLanguageJava} size={sizeCardIcons || "2em"} />, icon: <Icon path={mdiLanguageJava} size={sizeCardIcons} />,
pct: 80 pct: 80
}, { }, {
name: "Python 3", name: "Python 3",
icon: <Icon path={mdiLanguagePython} size={sizeCardIcons || "2em"} />, icon: <Icon path={mdiLanguagePython} size={sizeCardIcons} />,
pct: 95 pct: 95
}, { }, {
name: "PHP", name: "PHP",
icon: <Icon path={mdiLanguagePhp} size={sizeCardIcons || "2em"} />, icon: <Icon path={mdiLanguagePhp} size={sizeCardIcons} />,
pct: 50 pct: 50
}, { }, {
name: "Bash", name: "Bash",
icon: <Icon path={mdiBash} size={sizeCardIcons || "2em"} />, icon: <Icon path={mdiBash} size={sizeCardIcons} />,
pct: 60 pct: 60
}, { }, {
name: "C/C++", name: "C/C++",
icon: <Icon path={mdiLanguageCpp} size={sizeCardIcons || "2em"} />, icon: <Icon path={mdiLanguageCpp} size={sizeCardIcons} />,
pct: 60 pct: 60
}, { }, {
name: "Rust", name: "Rust",
icon: <Icon path={mdiLanguageRust} size={sizeCardIcons || "2em"} />, icon: <Icon path={mdiLanguageRust} size={sizeCardIcons} />,
pct: 80 pct: 80
}, { }, {
name: "C#", name: "C#",
icon: <Icon path={mdiLanguageCsharp} size={sizeCardIcons || "2em"} />, icon: <Icon path={mdiLanguageCsharp} size={sizeCardIcons} />,
pct: 40 pct: 40
}] }],
/*colors: {
background: "#690000",
bars: "#fff",
heading: "#fff"
}*/
}, { }, {
title: "Web Technologies", title: "Web Technologies",
skillBars: [{ skillBars: [{
name: "TypeScript", name: "TypeScript",
icon: <Icon path={mdiLanguageTypescript} size={sizeCardIcons || "2em"} />, icon: <Icon path={mdiLanguageTypescript} size={sizeCardIcons} />,
pct: 100 pct: 100
}, { }, {
name: "JavaScript", name: "JavaScript",
icon: <Icon path={mdiLanguageJavascript} size={sizeCardIcons || "2em"} />, icon: <Icon path={mdiLanguageJavascript} size={sizeCardIcons} />,
pct: 100 pct: 100
}, { }, {
name: "React", name: "React",
icon: <Icon path={mdiReact} size={sizeCardIcons || "2em"} />, icon: <Icon path={mdiReact} size={sizeCardIcons} />,
pct: 80 pct: 80
}, { }, {
name: "HTML5", name: "HTML5",
icon: <Html5 size={sizeCardIcons || "2em"} />, icon: <Html5 size={sizeCardIcons} />,
pct: 80 pct: 80
}, { }, {
name: "CSS3", name: "CSS3",
icon: <CssThree size={sizeCardIcons || "2em"} />, icon: <CssThree size={sizeCardIcons} />,
pct: 90 pct: 90
}], }],
additional: [{ additional: [{
name: "Express", name: "Express",
icon: <Express size={sizeBadgeIcons || "1em"} /> icon: <Express size={sizeBadgeIcons} />
}, { }, {
name: "Sass", name: "Sass",
icon: <Sass size={sizeBadgeIcons || "1em"} /> icon: <Sass size={sizeBadgeIcons} />
}, { }, {
name: "Spring Boot", name: "Spring Boot",
icon: <Springboot size={sizeBadgeIcons || "1em"} /> icon: <Springboot size={sizeBadgeIcons} />
}] }],
/*colors: {
background: "#2196f3",
bars: "#217fff",
heading: "#2043ff"
}*/
}, { }, {
title: "Embedded Programming", title: "Embedded Programming",
skillBars: [{ skillBars: [{
name: "C/C++", name: "C/C++",
icon: <Icon path={mdiLanguageCpp} size={sizeCardIcons || "2em"} />, icon: <Icon path={mdiLanguageCpp} size={sizeCardIcons} />,
pct: 60 pct: 60
}], }],
additional: [{ additional: [{
name: "Arduino", name: "Arduino",
icon: <Arduino size={sizeBadgeIcons || "1em"} /> icon: <Arduino size={sizeBadgeIcons} />
}, { }, {
name: "ESP", name: "ESP",
icon: <Espressif size={sizeBadgeIcons || "1em"} /> icon: <Espressif size={sizeBadgeIcons} />
}] }],
/*colors: {
background: "#EA8585",
bars: "#E53E3E",
heading: "#661C1C"
}*/
}, { }, {
title: "Operating Systems", title: "Operating Systems",
skillBars: [], skillBars: [],
additional: [{ additional: [{
name: "Windows", name: "Windows",
icon: <Windows size={sizeBadgeIcons || "1em"} /> icon: <Windows size={sizeBadgeIcons} />
}, { }, {
name: "Linux", name: "Linux",
icon: <Linux size={sizeBadgeIcons || "1em"} /> icon: <Linux size={sizeBadgeIcons} />
}, { }, {
name: "Android", name: "Android",
icon: <Android size={sizeBadgeIcons || "1em"} /> icon: <Android size={sizeBadgeIcons} />
}] }]
}, { }, {
title: "Languages", title: "Languages",
skillBars: [{ skillBars: [{
name: "German (native)", name: "German (native)",
icon: <span style={{ fontSize: sizeCardIcons || "2em" }}>🇩🇪</span>, icon: <Icon path={mdiTranslateVariant} size={sizeCardIcons} />,
pct: 100 pct: 100
}, { }, {
name: "English (C1)", name: "English (C1)",
icon: <span style={{ fontSize: sizeCardIcons || "2em" }}>🇬🇧</span>, icon: <Icon path={mdiTranslateVariant} size={sizeCardIcons} />,
pct: 90 pct: 90
}, { }, {
name: "Russian (basics)", name: "Russian (basics)",
icon: <span style={{ fontSize: sizeCardIcons || "2em", fontFamily: "Arial" }}>🇷🇺</span>, icon: <Icon path={mdiTranslateVariant} size={sizeCardIcons} />,
pct: 30 pct: 30
}], }],
additional: [] additional: []

View File

@ -1,5 +1,6 @@
import type { NextPage } from "next"; import type { NextPage } from "next";
import { useEffect } from "react"; import { useEffect } from "react";
import Color from "color";
import Layout from "../components/Blog/Layout"; import Layout from "../components/Blog/Layout";
import styles from "../styles/Blog/AboutMe.module.scss"; import styles from "../styles/Blog/AboutMe.module.scss";
@ -9,30 +10,42 @@ import achievements from "../data/achievements";
const Badge: NextPage<{ additional: AdditionalSkill }> = ({ additional }) => { const Badge: NextPage<{ additional: AdditionalSkill }> = ({ additional }) => {
return <div className={styles.badge}> return <div className={styles.badge}>
{additional.icon || null} {additional.name} <span>{additional.icon || null}</span><span>{additional.name}</span>
</div>; </div>;
}; };
const SkillBar: NextPage<{ skill: Skill }> = ({ skill }) => { const SkillBar: NextPage<{ skill: Skill }> = ({ skill }) => {
return <div className={styles.skillBar}> return <div className={styles.skillBar}>
<div className={styles.barName}>{skill.name}{skill.icon || null}</div> <div className={styles.barName}>{skill.icon || null}</div>
<div className={styles.percentBar} style={{"--barPct": skill.pct + "%"} as React.CSSProperties}> <div className={styles.percentBar} style={{"--barPct": skill.pct + "%"} as React.CSSProperties}>
<div className={`${styles.front} vpAnimated`}></div> <div className={`${styles.front} vpAnimated`}></div>
</div> </div>
<div>{skill.name}</div>
</div>; </div>;
}; };
const SkillCard: NextPage<{ card: SkillCard }> = ({ card }) => { const SkillCard: NextPage<{ card: SkillCard }> = ({ card }) => {
return <div className={styles.card}> const cardStyle = {
background: card.colors?.background,
"--ch-color": card.colors?.heading,
"--bar-color": card.colors?.bars,
color: undefined,
} as React.CSSProperties;
try {
cardStyle.color = Color(cardStyle.background).isDark() ? "#ddd" : "#222";
} catch {}
return <div className={styles.skillCard} style={cardStyle}>
<h3>{card.title}</h3> <h3>{card.title}</h3>
<div className={styles.skillBarsSet}> <div className={styles.skillBarsSet}>
{card.skillBars.sort((bar1, bar2) => bar2.pct - bar1.pct).map((skill, i) => {card.skillBars.sort((bar1, bar2) => bar2.pct - bar1.pct).map((skill, i) =>
<SkillBar key={i} skill={skill} /> <SkillBar key={i} skill={skill} />
)} )}
</div><br />
<div className={styles.badgeSet}>
{card.additional?.map((skill, i) => <Badge additional={skill} key={i} />)}
</div> </div>
{card.additional && card.additional.length > 0 ? <div className={styles.badgeSet}>
{card.additional?.map((skill, i) => <Badge additional={skill} key={i} />)}
</div> : null}
</div>; </div>;
}; };

View File

@ -14,7 +14,7 @@
border-radius: 0.5em; border-radius: 0.5em;
height: 100%; height: 100%;
position: absolute; position: absolute;
background: var(--blog_color-accent); background: var(--bar-color, var(--blog_color-accent));
animation: barFill 2s ease-in-out; animation: barFill 2s ease-in-out;
animation-fill-mode: forwards; animation-fill-mode: forwards;
} }
@ -23,6 +23,18 @@
.badgeSet { .badgeSet {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
margin-top: 10px;
}
.achievement {
display: grid;
grid-template-columns: 2em auto;
column-gap: 10px;
padding: 5px;
& > span:first-of-type {
height: 2em;
}
} }
.badge { .badge {
@ -32,6 +44,14 @@
border: 1px solid var(--blog_content-border); border: 1px solid var(--blog_content-border);
border-radius: 0.5em; border-radius: 0.5em;
padding: 5px; padding: 5px;
& > span {
align-self: center;
}
& > span:first-of-type {
height: 1em;
}
} }
@keyframes barFill { @keyframes barFill {
@ -41,4 +61,55 @@
100% { 100% {
width: var(--barPct); width: var(--barPct);
} }
}
.skillCard {
padding: 10px;
border: 1px solid var(--blog_content-border);
border-radius: 0.5em;
margin-bottom: 20px;
h3 {
margin: 0;
color: var(--ch-color) !important;
}
&:last-of-type {
margin-bottom: 0;
}
&.useDarkColor {
color: #222;
}
&.useLightColor {
color: #ddd;
}
}
.skillBar {
display: grid;
grid-template-columns: 2em auto;
column-gap: 10px;
padding: 10px;
margin: 10px 0;
& > div {
align-self: center;
}
& > div:first-of-type {
height: 2em;
grid-row: 1/3;
}
& > div:nth-of-type(3) {
text-align: center;
margin-top: -5px;
font-size: small;
}
&:last-of-type {
margin-bottom: 0;
}
} }