mirror of
https://github.com/xHyroM/website.git
synced 2024-12-22 04:21:06 +01:00
feat: better docs navigation
This commit is contained in:
parent
901dd16f6d
commit
90098f9c20
16 changed files with 332 additions and 87 deletions
|
@ -1,8 +1,5 @@
|
|||
module.exports = {
|
||||
plugins: [
|
||||
require.resolve("prettier-plugin-astro"),
|
||||
require.resolve("prettier-plugin-tailwindcss"),
|
||||
],
|
||||
plugins: [require.resolve("prettier-plugin-astro")],
|
||||
overrides: [
|
||||
{
|
||||
files: "*.astro",
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { defineConfig } from "astro/config";
|
||||
|
||||
// https://astro.build/config
|
||||
import tailwind from "@astrojs/tailwind";
|
||||
|
||||
// https://astro.build/config
|
||||
|
@ -12,6 +11,9 @@ import sitemap from "@astrojs/sitemap";
|
|||
// https://astro.build/config
|
||||
import compress from "astro-compress";
|
||||
|
||||
// https://astro.build/config
|
||||
import preact from "@astrojs/preact";
|
||||
|
||||
// https://astro.build/config
|
||||
import prefetch from "@astrojs/prefetch";
|
||||
import robotsTxt from "astro-robots-txt";
|
||||
|
@ -21,6 +23,8 @@ import { dirname, resolve } from "node:path";
|
|||
import { fileURLToPath } from "node:url";
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
// https://astro.build/config
|
||||
|
||||
// https://astro.build/config
|
||||
export default defineConfig({
|
||||
site: "https://xhyrom.dev/",
|
||||
|
@ -43,6 +47,7 @@ export default defineConfig({
|
|||
sitemap: true,
|
||||
}),
|
||||
minify(),
|
||||
preact(),
|
||||
],
|
||||
vite: {
|
||||
resolve: {
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@astrojs/image": "^0.16.9",
|
||||
"@astrojs/preact": "^2.2.1",
|
||||
"@astrojs/prefetch": "^0.2.3",
|
||||
"@astrojs/sitemap": "^1.3.3",
|
||||
"@astrojs/tailwind": "^3.1.3",
|
||||
|
@ -23,6 +24,7 @@
|
|||
"astro-tooltips": "^0.6.2",
|
||||
"fireworks-js": "^2.10.5",
|
||||
"html-minifier": "^4.0.0",
|
||||
"preact": "^10.15.1",
|
||||
"tailwindcss": "^3.3.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
133
pnpm-lock.yaml
133
pnpm-lock.yaml
|
@ -9,6 +9,9 @@ dependencies:
|
|||
'@astrojs/image':
|
||||
specifier: ^0.16.9
|
||||
version: 0.16.9(astro@2.5.7)
|
||||
'@astrojs/preact':
|
||||
specifier: ^2.2.1
|
||||
version: 2.2.1(preact@10.15.1)
|
||||
'@astrojs/prefetch':
|
||||
specifier: ^0.2.3
|
||||
version: 0.2.3
|
||||
|
@ -42,6 +45,9 @@ dependencies:
|
|||
html-minifier:
|
||||
specifier: ^4.0.0
|
||||
version: 4.0.0
|
||||
preact:
|
||||
specifier: ^10.15.1
|
||||
version: 10.15.1
|
||||
tailwindcss:
|
||||
specifier: ^3.3.2
|
||||
version: 3.3.2
|
||||
|
@ -142,6 +148,22 @@ packages:
|
|||
- supports-color
|
||||
dev: false
|
||||
|
||||
/@astrojs/preact@2.2.1(preact@10.15.1):
|
||||
resolution: {integrity: sha512-lObgrX/qfK2sEnGDWoyQ8KojFJ54FIKB4TeywWmgj4ZTg0yLnvvOz6ReyPQ8VfR/1MU+vWs22jE4cuZJ/vPnOA==}
|
||||
engines: {node: '>=16.12.0'}
|
||||
peerDependencies:
|
||||
preact: ^10.6.5
|
||||
dependencies:
|
||||
'@babel/core': 7.22.1
|
||||
'@babel/plugin-transform-react-jsx': 7.22.3(@babel/core@7.22.1)
|
||||
'@preact/signals': 1.1.3(preact@10.15.1)
|
||||
babel-plugin-module-resolver: 5.0.0
|
||||
preact: 10.15.1
|
||||
preact-render-to-string: 5.2.6(preact@10.15.1)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/@astrojs/prefetch@0.2.3:
|
||||
resolution: {integrity: sha512-r51t4fkGcePA6FHFVDD5vC/whhoKWFSaKNug/4Z2FSKZZga9yjb2qDcrul7u32nVDN+30ywZ/RQAmBMrHOmLiw==}
|
||||
dependencies:
|
||||
|
@ -723,6 +745,19 @@ packages:
|
|||
resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==}
|
||||
dev: false
|
||||
|
||||
/@preact/signals-core@1.3.0:
|
||||
resolution: {integrity: sha512-M+M3ZOtd1dtV/uasyk4SZu1vbfEJ4NeENv0F7F12nijZYedB5wSgbtZcuACyssnTznhF4ctUyrR0dZHuHfyWKA==}
|
||||
dev: false
|
||||
|
||||
/@preact/signals@1.1.3(preact@10.15.1):
|
||||
resolution: {integrity: sha512-N09DuAVvc90bBZVRwD+aFhtGyHAmJLhS3IFoawO/bYJRcil4k83nBOchpCEoS0s5+BXBpahgp0Mjf+IOqP57Og==}
|
||||
peerDependencies:
|
||||
preact: 10.x
|
||||
dependencies:
|
||||
'@preact/signals-core': 1.3.0
|
||||
preact: 10.15.1
|
||||
dev: false
|
||||
|
||||
/@proload/core@0.3.3:
|
||||
resolution: {integrity: sha512-7dAFWsIK84C90AMl24+N/ProHKm4iw0akcnoKjRvbfHifJZBLhaDsDus1QJmhG12lXj4e/uB/8mB/0aduCW+NQ==}
|
||||
dependencies:
|
||||
|
@ -1093,6 +1128,17 @@ packages:
|
|||
postcss-value-parser: 4.2.0
|
||||
dev: false
|
||||
|
||||
/babel-plugin-module-resolver@5.0.0:
|
||||
resolution: {integrity: sha512-g0u+/ChLSJ5+PzYwLwP8Rp8Rcfowz58TJNCe+L/ui4rpzE/mg//JVX0EWBUYoxaextqnwuGHzfGp2hh0PPV25Q==}
|
||||
engines: {node: '>= 16'}
|
||||
dependencies:
|
||||
find-babel-config: 2.0.0
|
||||
glob: 8.1.0
|
||||
pkg-up: 3.1.0
|
||||
reselect: 4.1.8
|
||||
resolve: 1.22.2
|
||||
dev: false
|
||||
|
||||
/bail@2.0.2:
|
||||
resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==}
|
||||
dev: false
|
||||
|
@ -1161,6 +1207,12 @@ packages:
|
|||
concat-map: 0.0.1
|
||||
dev: false
|
||||
|
||||
/brace-expansion@2.0.1:
|
||||
resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==}
|
||||
dependencies:
|
||||
balanced-match: 1.0.2
|
||||
dev: false
|
||||
|
||||
/braces@3.0.2:
|
||||
resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==}
|
||||
engines: {node: '>=8'}
|
||||
|
@ -1855,6 +1907,21 @@ packages:
|
|||
dependencies:
|
||||
to-regex-range: 5.0.1
|
||||
|
||||
/find-babel-config@2.0.0:
|
||||
resolution: {integrity: sha512-dOKT7jvF3hGzlW60Gc3ONox/0rRZ/tz7WCil0bqA1In/3I8f1BctpXahRnEKDySZqci7u+dqq93sZST9fOJpFw==}
|
||||
engines: {node: '>=16.0.0'}
|
||||
dependencies:
|
||||
json5: 2.2.3
|
||||
path-exists: 4.0.0
|
||||
dev: false
|
||||
|
||||
/find-up@3.0.0:
|
||||
resolution: {integrity: sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==}
|
||||
engines: {node: '>=6'}
|
||||
dependencies:
|
||||
locate-path: 3.0.0
|
||||
dev: false
|
||||
|
||||
/find-up@4.1.0:
|
||||
resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==}
|
||||
engines: {node: '>=8'}
|
||||
|
@ -1958,6 +2025,17 @@ packages:
|
|||
path-is-absolute: 1.0.1
|
||||
dev: false
|
||||
|
||||
/glob@8.1.0:
|
||||
resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==}
|
||||
engines: {node: '>=12'}
|
||||
dependencies:
|
||||
fs.realpath: 1.0.0
|
||||
inflight: 1.0.6
|
||||
inherits: 2.0.4
|
||||
minimatch: 5.1.6
|
||||
once: 1.4.0
|
||||
dev: false
|
||||
|
||||
/globals@11.12.0:
|
||||
resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==}
|
||||
engines: {node: '>=4'}
|
||||
|
@ -2337,6 +2415,14 @@ packages:
|
|||
strip-bom: 3.0.0
|
||||
dev: false
|
||||
|
||||
/locate-path@3.0.0:
|
||||
resolution: {integrity: sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==}
|
||||
engines: {node: '>=6'}
|
||||
dependencies:
|
||||
p-locate: 3.0.0
|
||||
path-exists: 3.0.0
|
||||
dev: false
|
||||
|
||||
/locate-path@5.0.0:
|
||||
resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==}
|
||||
engines: {node: '>=8'}
|
||||
|
@ -2838,6 +2924,13 @@ packages:
|
|||
brace-expansion: 1.1.11
|
||||
dev: false
|
||||
|
||||
/minimatch@5.1.6:
|
||||
resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==}
|
||||
engines: {node: '>=10'}
|
||||
dependencies:
|
||||
brace-expansion: 2.0.1
|
||||
dev: false
|
||||
|
||||
/minimist@1.2.8:
|
||||
resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
|
||||
dev: false
|
||||
|
@ -3022,6 +3115,13 @@ packages:
|
|||
yocto-queue: 1.0.0
|
||||
dev: false
|
||||
|
||||
/p-locate@3.0.0:
|
||||
resolution: {integrity: sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==}
|
||||
engines: {node: '>=6'}
|
||||
dependencies:
|
||||
p-limit: 2.3.0
|
||||
dev: false
|
||||
|
||||
/p-locate@4.1.0:
|
||||
resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==}
|
||||
engines: {node: '>=8'}
|
||||
|
@ -3073,6 +3173,11 @@ packages:
|
|||
tslib: 2.5.2
|
||||
dev: false
|
||||
|
||||
/path-exists@3.0.0:
|
||||
resolution: {integrity: sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==}
|
||||
engines: {node: '>=4'}
|
||||
dev: false
|
||||
|
||||
/path-exists@4.0.0:
|
||||
resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
|
||||
engines: {node: '>=8'}
|
||||
|
@ -3128,6 +3233,13 @@ packages:
|
|||
find-up: 4.1.0
|
||||
dev: false
|
||||
|
||||
/pkg-up@3.1.0:
|
||||
resolution: {integrity: sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==}
|
||||
engines: {node: '>=8'}
|
||||
dependencies:
|
||||
find-up: 3.0.0
|
||||
dev: false
|
||||
|
||||
/postcss-import@15.1.0(postcss@8.4.24):
|
||||
resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
|
@ -3206,6 +3318,19 @@ packages:
|
|||
source-map-js: 1.0.2
|
||||
dev: false
|
||||
|
||||
/preact-render-to-string@5.2.6(preact@10.15.1):
|
||||
resolution: {integrity: sha512-JyhErpYOvBV1hEPwIxc/fHWXPfnEGdRKxc8gFdAZ7XV4tlzyzG847XAyEZqoDnynP88akM4eaHcSOzNcLWFguw==}
|
||||
peerDependencies:
|
||||
preact: '>=10'
|
||||
dependencies:
|
||||
preact: 10.15.1
|
||||
pretty-format: 3.8.0
|
||||
dev: false
|
||||
|
||||
/preact@10.15.1:
|
||||
resolution: {integrity: sha512-qs2ansoQEwzNiV5eAcRT1p1EC/dmEzaATVDJNiB3g2sRDWdA7b7MurXdJjB2+/WQktGWZwxvDrnuRFbWuIr64g==}
|
||||
dev: false
|
||||
|
||||
/prebuild-install@7.1.1:
|
||||
resolution: {integrity: sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==}
|
||||
engines: {node: '>=10'}
|
||||
|
@ -3313,6 +3438,10 @@ packages:
|
|||
engines: {node: '>=10.13.0'}
|
||||
hasBin: true
|
||||
|
||||
/pretty-format@3.8.0:
|
||||
resolution: {integrity: sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew==}
|
||||
dev: false
|
||||
|
||||
/prismjs@1.29.0:
|
||||
resolution: {integrity: sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==}
|
||||
engines: {node: '>=6'}
|
||||
|
@ -3456,6 +3585,10 @@ packages:
|
|||
unist-util-visit: 4.1.2
|
||||
dev: false
|
||||
|
||||
/reselect@4.1.8:
|
||||
resolution: {integrity: sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ==}
|
||||
dev: false
|
||||
|
||||
/resolve-from@5.0.0:
|
||||
resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==}
|
||||
engines: {node: '>=8'}
|
||||
|
|
|
@ -30,12 +30,12 @@ const navItems = [
|
|||
<a class="text-2xl font-extrabold" href="/">xHyroM</a>
|
||||
<nav>
|
||||
<ul
|
||||
class="nav-links absolute left-0 top-0 z-20 hidden w-full gap-10 border-b-[1px] border-neutral-800 bg-gray transition-all md:relative md:flex md:flex-row md:border-b-0 md:bg-transparent [&_li]:my-2 [&_li]:ml-4"
|
||||
class="nav-links absolute left-0 top-0 z-20 hidden w-full gap-10 border-b-[1px] border-neutral-800 bg-dark-200 transition-all md:relative md:flex md:flex-row md:border-b-0 md:bg-transparent [&_li]:my-2 [&_li]:ml-4"
|
||||
>
|
||||
{
|
||||
navItems.map((item) => (
|
||||
<li class=" transition-all hover:-translate-y-[2px]">
|
||||
<a href={item.link} class="text-neutral-300 hover:text-hyroGold">
|
||||
<a href={item.link} class="text-neutral-300 hover:text-gold">
|
||||
{item.name}
|
||||
</a>
|
||||
</li>
|
||||
|
|
|
@ -11,13 +11,14 @@ const isCurrentPage = (item: Sidebar) => {
|
|||
};
|
||||
|
||||
const getLinkClasses = (link: Sidebar) => {
|
||||
const baseClasses =
|
||||
"block py-2 px-6 my-1 transition-colors border-l hover:border-slate-300 hover:text-slate-300";
|
||||
const baseClasses = "py-1 px-6 my-1 transition-colors border-l -ml-px pl-4";
|
||||
|
||||
if (isCurrentPage(link)) {
|
||||
return baseClasses + " border-slate-300 text-slate-100";
|
||||
return baseClasses + " border-gold text-gold";
|
||||
} else {
|
||||
return baseClasses + " text-slate-400";
|
||||
return (
|
||||
baseClasses + " border-transparent text-gray-100 hover:text-gray-200"
|
||||
);
|
||||
}
|
||||
};
|
||||
---
|
||||
|
@ -39,11 +40,11 @@ const getLinkClasses = (link: Sidebar) => {
|
|||
aria-labelledby="grid-left"
|
||||
class="bg-dark-r w-64 -translate-x-full p-4 transition-transform duration-200 md:visible md:translate-x-0 md:bg-transparent"
|
||||
>
|
||||
<ul>
|
||||
<ul class="border-l border-dark-300">
|
||||
{
|
||||
docs.sidebar.map((item) =>
|
||||
item.header ? (
|
||||
<li class="mt-4 font-semibold text-white">{item.text}</li>
|
||||
<li class="mt-4 pl-4 font-semibold text-white">{item.text}</li>
|
||||
) : (
|
||||
<li class={getLinkClasses(item)}>
|
||||
<a href={item.link}>{item.text}</a>
|
||||
|
|
|
@ -1,15 +1,28 @@
|
|||
---
|
||||
import TableOfContents from "./TableOfContents.astro";
|
||||
import TableOfContents from "./TableOfContents";
|
||||
|
||||
const { item } = Astro.props;
|
||||
|
||||
const headings = item.getHeadings();
|
||||
interface Props {
|
||||
item: {
|
||||
getHeadings: () => {
|
||||
depth: number;
|
||||
slug: string;
|
||||
text: string;
|
||||
}[];
|
||||
};
|
||||
}
|
||||
|
||||
const headings = item
|
||||
.getHeadings()
|
||||
.filter(({ depth }) => depth > 1 && depth < 4);
|
||||
---
|
||||
|
||||
{
|
||||
headings.length > 1 && (
|
||||
<nav aria-labelledby="grid-right" class="invisible md:visible">
|
||||
<div class="px-8">
|
||||
<TableOfContents headings={headings} />
|
||||
<nav aria-labelledby="grid-right" class="p-4 invisible md:visible">
|
||||
<div class="pl-8">
|
||||
<TableOfContents headings={headings} client:idle />
|
||||
</div>
|
||||
</nav>
|
||||
)
|
||||
|
|
|
@ -1,46 +0,0 @@
|
|||
---
|
||||
const { headings } = Astro.props;
|
||||
|
||||
const parseDepth = (depth: number) => {
|
||||
switch (depth) {
|
||||
case 1:
|
||||
return "ml-0";
|
||||
case 2:
|
||||
return "ml-4";
|
||||
case 3:
|
||||
return "ml-8";
|
||||
case 4:
|
||||
return "ml-12";
|
||||
case 5:
|
||||
return "ml-16";
|
||||
case 6:
|
||||
return "ml-20";
|
||||
default:
|
||||
return "ml-0";
|
||||
}
|
||||
};
|
||||
---
|
||||
|
||||
<ul class="mt-24 flex flex-col gap-4">
|
||||
{
|
||||
headings.map(
|
||||
({
|
||||
slug,
|
||||
text,
|
||||
depth,
|
||||
}: {
|
||||
slug: string;
|
||||
text: string;
|
||||
depth: number;
|
||||
}) => {
|
||||
return (
|
||||
<li
|
||||
class={`text-slate-100 hover:text-slate-700 ${parseDepth(depth)}`}
|
||||
>
|
||||
<a href={`#${slug}`}>{text}</a>
|
||||
</li>
|
||||
);
|
||||
}
|
||||
)
|
||||
}
|
||||
</ul>
|
120
src/components/widgets/docs/TableOfContents.tsx
Normal file
120
src/components/widgets/docs/TableOfContents.tsx
Normal file
|
@ -0,0 +1,120 @@
|
|||
import type { MarkdownHeading } from "astro";
|
||||
import type { FunctionalComponent } from "preact";
|
||||
import { useState, useEffect, useRef } from "preact/hooks";
|
||||
|
||||
type ItemOffsets = {
|
||||
id: string;
|
||||
topOffset: number;
|
||||
};
|
||||
|
||||
const parseDepth = (depth: number) => {
|
||||
switch (depth) {
|
||||
case 1:
|
||||
return "ml-0";
|
||||
case 2:
|
||||
return "ml-4";
|
||||
case 3:
|
||||
return "ml-8";
|
||||
case 4:
|
||||
return "ml-12";
|
||||
case 5:
|
||||
return "ml-16";
|
||||
case 6:
|
||||
return "ml-20";
|
||||
default:
|
||||
return "ml-0";
|
||||
}
|
||||
};
|
||||
|
||||
const TableOfContents: FunctionalComponent<{ headings: MarkdownHeading[] }> = ({
|
||||
headings = [],
|
||||
}) => {
|
||||
const toc = useRef<HTMLUListElement>(null);
|
||||
const onThisPageId = "on-this-page-heading";
|
||||
const itemOffsets = useRef<ItemOffsets[]>([]);
|
||||
const [currentId, setCurrentId] = useState("overview");
|
||||
useEffect(() => {
|
||||
const getItemOffsets = () => {
|
||||
const titles = document.querySelectorAll("article :is(h1, h2, h3, h4)");
|
||||
itemOffsets.current = Array.from(titles).map((title) => ({
|
||||
id: title.id,
|
||||
topOffset: title.getBoundingClientRect().top + window.scrollY,
|
||||
}));
|
||||
};
|
||||
|
||||
getItemOffsets();
|
||||
window.addEventListener("resize", getItemOffsets);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener("resize", getItemOffsets);
|
||||
};
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (!toc.current) return;
|
||||
|
||||
const setCurrent: IntersectionObserverCallback = (entries) => {
|
||||
for (const entry of entries) {
|
||||
if (entry.isIntersecting) {
|
||||
const { id } = entry.target;
|
||||
if (id === onThisPageId) continue;
|
||||
setCurrentId(entry.target.id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const observerOptions: IntersectionObserverInit = {
|
||||
rootMargin: "-100px 0% -66%",
|
||||
threshold: 1,
|
||||
};
|
||||
|
||||
const headingsObserver = new IntersectionObserver(
|
||||
setCurrent,
|
||||
observerOptions
|
||||
);
|
||||
|
||||
// Observe all the headings in the main page content.
|
||||
document
|
||||
.querySelectorAll("article :is(h1,h2,h3)")
|
||||
.forEach((h) => headingsObserver.observe(h));
|
||||
|
||||
// Stop observing when the component is unmounted.
|
||||
return () => headingsObserver.disconnect();
|
||||
}, [toc.current]);
|
||||
|
||||
const onLinkClick = (e: MouseEvent) => {
|
||||
setCurrentId(
|
||||
(e.target as HTMLButtonElement)!.getAttribute("href")!.replace("#", "")
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<ul ref={toc} className={"border-l border-dark-300"}>
|
||||
<li id={onThisPageId} className="mt-4 pl-4 font-semibold text-white">
|
||||
On this page
|
||||
</li>
|
||||
{headings.map(({ slug, text, depth }) => {
|
||||
return (
|
||||
<li
|
||||
className={`border-l py-1 ${
|
||||
currentId === slug
|
||||
? "text-gold border-gold"
|
||||
: "text-gray-100 hover:text-gray-200 border-transparent"
|
||||
}`}
|
||||
>
|
||||
<a
|
||||
className={parseDepth(depth)}
|
||||
href={`#${slug}`}
|
||||
onClick={onLinkClick}
|
||||
>
|
||||
{text}
|
||||
</a>
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
);
|
||||
};
|
||||
|
||||
export default TableOfContents;
|
|
@ -17,13 +17,13 @@ const currentPage = new URL(Astro.request.url).pathname;
|
|||
|
||||
<div class="grid grid-cols-12">
|
||||
<div
|
||||
class="col-span-3 flex flex-row md:sticky md:top-0 md:h-screen md:pt-12"
|
||||
class="col-span-3 flex flex-row md:sticky md:top-0 md:h-screen md:pt-4"
|
||||
>
|
||||
<div class="ml-auto">
|
||||
<LeftSidebar currentPage={currentPage} />
|
||||
</div>
|
||||
</div>
|
||||
<main class="col-span-6 overflow-auto py-4 pb-32 md:px-8">
|
||||
<main class="col-span-6 overflow-auto py-12">
|
||||
<div>
|
||||
<article id="article" class="content">
|
||||
<section class="main-section prose prose-invert max-w-none">
|
||||
|
@ -34,7 +34,7 @@ const currentPage = new URL(Astro.request.url).pathname;
|
|||
</div>
|
||||
</main>
|
||||
<div
|
||||
class="col-span-3 flex flex-row md:sticky md:top-0 md:block md:h-screen"
|
||||
class="col-span-3 flex flex-row md:sticky md:top-0 md:h-screen md:pt-4"
|
||||
>
|
||||
<RightSidebar item={item} />
|
||||
</div>
|
||||
|
|
|
@ -31,7 +31,7 @@ import Layout from "@layouts/Layout.astro";
|
|||
|
||||
<p class="mb-4">
|
||||
In the meantime, why not take a look around our <a
|
||||
class="text-hyroGold"
|
||||
class="text-gold"
|
||||
href="/">homepage</a
|
||||
> and see if you can find something else that piques your interest? Who knows,
|
||||
you might just stumble upon something even better than what you were originally
|
||||
|
|
|
@ -30,32 +30,31 @@ import { skills } from "~/config";
|
|||
<main class="text-2xl text-white">
|
||||
<section>
|
||||
<p class="mb-4">
|
||||
My name is <span class="text-hyroGold">Jozef Steinhübl</span> ("bl" - not
|
||||
"bel", I'm not a bell), but you may know me by my pseudonyms, <span
|
||||
class="text-hyroGold"
|
||||
My name is <span class="text-gold">Jozef Steinhübl</span> ("bl" - not "bel",
|
||||
I'm not a bell), but you may know me by my pseudonyms, <span
|
||||
class="text-gold"
|
||||
>Hyro, xHyroM, or general_kubo
|
||||
</span>. I am a developer with a passion for creating innovative
|
||||
solutions, and I am currently engaged in various projects. Most of my
|
||||
work is open-source and accessible on <a
|
||||
class="text-hyroGold"
|
||||
class="text-gold"
|
||||
href="https://github.com/xHyroM">GitHub</a
|
||||
>, where I contribute to the development of cutting-edge software
|
||||
solutions. You can also check <a
|
||||
class="text-hyroGold"
|
||||
href="/projects">Projects</a
|
||||
solutions. You can also check <a class="text-gold" href="/projects"
|
||||
>Projects</a
|
||||
> page on this website.
|
||||
</p>
|
||||
|
||||
<p class="mb-4">
|
||||
Apart from my open-source projects, I'm working/have also worked on
|
||||
other notable projects such as <a
|
||||
class="text-hyroGold"
|
||||
class="text-gold"
|
||||
href="https://rajce.pro">rajce.pro</a
|
||||
>, <a class="text-hyroGold" href="https://lendmark.sk">LendMark</a>, <a
|
||||
class="text-hyroGold"
|
||||
>, <a class="text-gold" href="https://lendmark.sk">LendMark</a>, <a
|
||||
class="text-gold"
|
||||
href="https://discord.com/api/oauth2/authorize?client_id=720321585625694239&permissions=8&scope=applications.commands%20bot"
|
||||
>Mr. Infinity</a
|
||||
>, <a class="text-hyroGold" href="http://github.com/xHyroM/roles-bot"
|
||||
>, <a class="text-gold" href="http://github.com/xHyroM/roles-bot"
|
||||
>Roles Bot</a
|
||||
> and for different content creators and influencers. My keen interest
|
||||
in the latest technologies motivates me to contribute to diverse projects
|
||||
|
@ -96,13 +95,13 @@ import { skills } from "~/config";
|
|||
and while I do not claim to be a master of any programming language,
|
||||
my expertise in various languages is continually evolving. As a
|
||||
contributor and moderator for the <a
|
||||
class="text-hyroGold"
|
||||
class="text-gold"
|
||||
href="https://bun.sh">Bun</a
|
||||
> project, I collaborated with my friend <a
|
||||
class="text-hyroGold"
|
||||
class="text-gold"
|
||||
href="https://github.com/Fire-The-Fox">@FireTheFox</a
|
||||
> to develop a native implementation of the <a
|
||||
class="text-hyroGold"
|
||||
class="text-gold"
|
||||
href="https://github.com/oven-sh/bun/pull/1115">node:os module</a
|
||||
>.
|
||||
</p>
|
||||
|
|
|
@ -40,7 +40,7 @@ const posts = page.data as {
|
|||
<main>
|
||||
{posts.map(post => {
|
||||
return (
|
||||
<a class="text-2xl font-semibold text-hyroGold text-opacity-80 mb-4 break-all" href={post.url}>{post.frontmatter.title}</a>
|
||||
<a class="text-2xl font-semibold text-gold text-opacity-80 mb-4 break-all" href={post.url}>{post.frontmatter.title}</a>
|
||||
<p class="text-1xl text-opacity-40 text-white italic break-all">
|
||||
{new Date(post.frontmatter.date).toLocaleDateString('en-us', {
|
||||
year: 'numeric',
|
||||
|
@ -49,7 +49,7 @@ const posts = page.data as {
|
|||
})}
|
||||
</p>
|
||||
<p class="text-1xl text-white break-all">{post.frontmatter.description}</p>
|
||||
<hr class="mt-4 mb-4 text-gray" />
|
||||
<hr class="mt-4 mb-4 text-dark-200" />
|
||||
)
|
||||
})}
|
||||
|
||||
|
|
|
@ -60,7 +60,7 @@ projects.sort((a, b) => a.name.localeCompare(b.name));
|
|||
<main class="flex flex-wrap justify-center gap-12">
|
||||
{
|
||||
projects.map((project) => (
|
||||
<section class="flex min-h-max w-80 flex-col justify-between rounded-md border-[1px] border-neutral-800 bg-gray p-6 md:w-96">
|
||||
<section class="flex min-h-max w-80 flex-col justify-between rounded-md border-[1px] border-neutral-800 bg-dark-200 p-6 md:w-96">
|
||||
<div class="flex">
|
||||
<h2 class="mb-4 break-words text-3xl font-bold text-white">
|
||||
{project.name}
|
||||
|
|
|
@ -14,8 +14,27 @@ module.exports = {
|
|||
extend: {
|
||||
colors: {
|
||||
dark: "#0D0D0D",
|
||||
gray: "#131313",
|
||||
hyroGold: "#fbc119",
|
||||
"dark-100": "#1A1A1A",
|
||||
"dark-200": "#242424",
|
||||
"dark-300": "#2E2E2E",
|
||||
"dark-400": "#383838",
|
||||
"dark-500": "#424242",
|
||||
"dark-600": "#4C4C4C",
|
||||
"dark-700": "#565656",
|
||||
"dark-800": "#606060",
|
||||
"dark-900": "#6A6A6A",
|
||||
gray: "#808080",
|
||||
"gray-100": "#999999",
|
||||
"gray-200": "#B3B3B3",
|
||||
"gray-300": "#CCCCCC",
|
||||
"gray-400": "#E6E6E6",
|
||||
"gray-500": "#F2F2F2",
|
||||
gold: "#fbc119",
|
||||
"gold-100": "#f9b84c",
|
||||
"gold-200": "#f8ad3e",
|
||||
"gold-300": "#f7a22f",
|
||||
"gold-400": "#f69721",
|
||||
"gold-500": "#f58c12",
|
||||
},
|
||||
dropShadow: {
|
||||
yellow: ["0 35px 35px rgba(250, 193, 25, 0.5)"],
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
"extends": "astro/tsconfigs/strict",
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"jsx": "preserve",
|
||||
"jsxImportSource": "preact",
|
||||
"paths": {
|
||||
"~/*": ["src/*"],
|
||||
"@docs/*": ["docs/*"],
|
||||
|
|
Loading…
Reference in a new issue