feat: better docs navigation

This commit is contained in:
xHyroM 2023-06-04 18:46:31 +02:00
parent 901dd16f6d
commit 90098f9c20
No known key found for this signature in database
GPG key ID: BE0423F386C436AA
16 changed files with 332 additions and 87 deletions

View file

@ -1,8 +1,5 @@
module.exports = { module.exports = {
plugins: [ plugins: [require.resolve("prettier-plugin-astro")],
require.resolve("prettier-plugin-astro"),
require.resolve("prettier-plugin-tailwindcss"),
],
overrides: [ overrides: [
{ {
files: "*.astro", files: "*.astro",

View file

@ -1,6 +1,5 @@
import { defineConfig } from "astro/config"; import { defineConfig } from "astro/config";
// https://astro.build/config
import tailwind from "@astrojs/tailwind"; import tailwind from "@astrojs/tailwind";
// https://astro.build/config // https://astro.build/config
@ -12,6 +11,9 @@ import sitemap from "@astrojs/sitemap";
// https://astro.build/config // https://astro.build/config
import compress from "astro-compress"; import compress from "astro-compress";
// https://astro.build/config
import preact from "@astrojs/preact";
// https://astro.build/config // https://astro.build/config
import prefetch from "@astrojs/prefetch"; import prefetch from "@astrojs/prefetch";
import robotsTxt from "astro-robots-txt"; import robotsTxt from "astro-robots-txt";
@ -21,6 +23,8 @@ import { dirname, resolve } from "node:path";
import { fileURLToPath } from "node:url"; import { fileURLToPath } from "node:url";
const __dirname = dirname(fileURLToPath(import.meta.url)); const __dirname = dirname(fileURLToPath(import.meta.url));
// https://astro.build/config
// https://astro.build/config // https://astro.build/config
export default defineConfig({ export default defineConfig({
site: "https://xhyrom.dev/", site: "https://xhyrom.dev/",
@ -43,6 +47,7 @@ export default defineConfig({
sitemap: true, sitemap: true,
}), }),
minify(), minify(),
preact(),
], ],
vite: { vite: {
resolve: { resolve: {

View file

@ -12,6 +12,7 @@
}, },
"dependencies": { "dependencies": {
"@astrojs/image": "^0.16.9", "@astrojs/image": "^0.16.9",
"@astrojs/preact": "^2.2.1",
"@astrojs/prefetch": "^0.2.3", "@astrojs/prefetch": "^0.2.3",
"@astrojs/sitemap": "^1.3.3", "@astrojs/sitemap": "^1.3.3",
"@astrojs/tailwind": "^3.1.3", "@astrojs/tailwind": "^3.1.3",
@ -23,6 +24,7 @@
"astro-tooltips": "^0.6.2", "astro-tooltips": "^0.6.2",
"fireworks-js": "^2.10.5", "fireworks-js": "^2.10.5",
"html-minifier": "^4.0.0", "html-minifier": "^4.0.0",
"preact": "^10.15.1",
"tailwindcss": "^3.3.2" "tailwindcss": "^3.3.2"
}, },
"devDependencies": { "devDependencies": {

View file

@ -9,6 +9,9 @@ dependencies:
'@astrojs/image': '@astrojs/image':
specifier: ^0.16.9 specifier: ^0.16.9
version: 0.16.9(astro@2.5.7) version: 0.16.9(astro@2.5.7)
'@astrojs/preact':
specifier: ^2.2.1
version: 2.2.1(preact@10.15.1)
'@astrojs/prefetch': '@astrojs/prefetch':
specifier: ^0.2.3 specifier: ^0.2.3
version: 0.2.3 version: 0.2.3
@ -42,6 +45,9 @@ dependencies:
html-minifier: html-minifier:
specifier: ^4.0.0 specifier: ^4.0.0
version: 4.0.0 version: 4.0.0
preact:
specifier: ^10.15.1
version: 10.15.1
tailwindcss: tailwindcss:
specifier: ^3.3.2 specifier: ^3.3.2
version: 3.3.2 version: 3.3.2
@ -142,6 +148,22 @@ packages:
- supports-color - supports-color
dev: false 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: /@astrojs/prefetch@0.2.3:
resolution: {integrity: sha512-r51t4fkGcePA6FHFVDD5vC/whhoKWFSaKNug/4Z2FSKZZga9yjb2qDcrul7u32nVDN+30ywZ/RQAmBMrHOmLiw==} resolution: {integrity: sha512-r51t4fkGcePA6FHFVDD5vC/whhoKWFSaKNug/4Z2FSKZZga9yjb2qDcrul7u32nVDN+30ywZ/RQAmBMrHOmLiw==}
dependencies: dependencies:
@ -723,6 +745,19 @@ packages:
resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==} resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==}
dev: false 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: /@proload/core@0.3.3:
resolution: {integrity: sha512-7dAFWsIK84C90AMl24+N/ProHKm4iw0akcnoKjRvbfHifJZBLhaDsDus1QJmhG12lXj4e/uB/8mB/0aduCW+NQ==} resolution: {integrity: sha512-7dAFWsIK84C90AMl24+N/ProHKm4iw0akcnoKjRvbfHifJZBLhaDsDus1QJmhG12lXj4e/uB/8mB/0aduCW+NQ==}
dependencies: dependencies:
@ -1093,6 +1128,17 @@ packages:
postcss-value-parser: 4.2.0 postcss-value-parser: 4.2.0
dev: false 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: /bail@2.0.2:
resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==}
dev: false dev: false
@ -1161,6 +1207,12 @@ packages:
concat-map: 0.0.1 concat-map: 0.0.1
dev: false 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: /braces@3.0.2:
resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==}
engines: {node: '>=8'} engines: {node: '>=8'}
@ -1855,6 +1907,21 @@ packages:
dependencies: dependencies:
to-regex-range: 5.0.1 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: /find-up@4.1.0:
resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==}
engines: {node: '>=8'} engines: {node: '>=8'}
@ -1958,6 +2025,17 @@ packages:
path-is-absolute: 1.0.1 path-is-absolute: 1.0.1
dev: false 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: /globals@11.12.0:
resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==}
engines: {node: '>=4'} engines: {node: '>=4'}
@ -2337,6 +2415,14 @@ packages:
strip-bom: 3.0.0 strip-bom: 3.0.0
dev: false 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: /locate-path@5.0.0:
resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==}
engines: {node: '>=8'} engines: {node: '>=8'}
@ -2838,6 +2924,13 @@ packages:
brace-expansion: 1.1.11 brace-expansion: 1.1.11
dev: false 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: /minimist@1.2.8:
resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
dev: false dev: false
@ -3022,6 +3115,13 @@ packages:
yocto-queue: 1.0.0 yocto-queue: 1.0.0
dev: false 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: /p-locate@4.1.0:
resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==}
engines: {node: '>=8'} engines: {node: '>=8'}
@ -3073,6 +3173,11 @@ packages:
tslib: 2.5.2 tslib: 2.5.2
dev: false dev: false
/path-exists@3.0.0:
resolution: {integrity: sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==}
engines: {node: '>=4'}
dev: false
/path-exists@4.0.0: /path-exists@4.0.0:
resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
engines: {node: '>=8'} engines: {node: '>=8'}
@ -3128,6 +3233,13 @@ packages:
find-up: 4.1.0 find-up: 4.1.0
dev: false 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): /postcss-import@15.1.0(postcss@8.4.24):
resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==} resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==}
engines: {node: '>=14.0.0'} engines: {node: '>=14.0.0'}
@ -3206,6 +3318,19 @@ packages:
source-map-js: 1.0.2 source-map-js: 1.0.2
dev: false 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: /prebuild-install@7.1.1:
resolution: {integrity: sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==} resolution: {integrity: sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==}
engines: {node: '>=10'} engines: {node: '>=10'}
@ -3313,6 +3438,10 @@ packages:
engines: {node: '>=10.13.0'} engines: {node: '>=10.13.0'}
hasBin: true hasBin: true
/pretty-format@3.8.0:
resolution: {integrity: sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew==}
dev: false
/prismjs@1.29.0: /prismjs@1.29.0:
resolution: {integrity: sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==} resolution: {integrity: sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==}
engines: {node: '>=6'} engines: {node: '>=6'}
@ -3456,6 +3585,10 @@ packages:
unist-util-visit: 4.1.2 unist-util-visit: 4.1.2
dev: false dev: false
/reselect@4.1.8:
resolution: {integrity: sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ==}
dev: false
/resolve-from@5.0.0: /resolve-from@5.0.0:
resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==}
engines: {node: '>=8'} engines: {node: '>=8'}

View file

@ -30,12 +30,12 @@ const navItems = [
<a class="text-2xl font-extrabold" href="/">xHyroM</a> <a class="text-2xl font-extrabold" href="/">xHyroM</a>
<nav> <nav>
<ul <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) => ( navItems.map((item) => (
<li class=" transition-all hover:-translate-y-[2px]"> <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} {item.name}
</a> </a>
</li> </li>

View file

@ -11,13 +11,14 @@ const isCurrentPage = (item: Sidebar) => {
}; };
const getLinkClasses = (link: Sidebar) => { const getLinkClasses = (link: Sidebar) => {
const baseClasses = const baseClasses = "py-1 px-6 my-1 transition-colors border-l -ml-px pl-4";
"block py-2 px-6 my-1 transition-colors border-l hover:border-slate-300 hover:text-slate-300";
if (isCurrentPage(link)) { if (isCurrentPage(link)) {
return baseClasses + " border-slate-300 text-slate-100"; return baseClasses + " border-gold text-gold";
} else { } 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" 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" 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) => docs.sidebar.map((item) =>
item.header ? ( 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)}> <li class={getLinkClasses(item)}>
<a href={item.link}>{item.text}</a> <a href={item.link}>{item.text}</a>

View file

@ -1,15 +1,28 @@
--- ---
import TableOfContents from "./TableOfContents.astro"; import TableOfContents from "./TableOfContents";
const { item } = Astro.props; 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 && ( headings.length > 1 && (
<nav aria-labelledby="grid-right" class="invisible md:visible"> <nav aria-labelledby="grid-right" class="p-4 invisible md:visible">
<div class="px-8"> <div class="pl-8">
<TableOfContents headings={headings} /> <TableOfContents headings={headings} client:idle />
</div> </div>
</nav> </nav>
) )

View file

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

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

View file

@ -17,13 +17,13 @@ const currentPage = new URL(Astro.request.url).pathname;
<div class="grid grid-cols-12"> <div class="grid grid-cols-12">
<div <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"> <div class="ml-auto">
<LeftSidebar currentPage={currentPage} /> <LeftSidebar currentPage={currentPage} />
</div> </div>
</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> <div>
<article id="article" class="content"> <article id="article" class="content">
<section class="main-section prose prose-invert max-w-none"> <section class="main-section prose prose-invert max-w-none">
@ -34,7 +34,7 @@ const currentPage = new URL(Astro.request.url).pathname;
</div> </div>
</main> </main>
<div <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} /> <RightSidebar item={item} />
</div> </div>

View file

@ -31,7 +31,7 @@ import Layout from "@layouts/Layout.astro";
<p class="mb-4"> <p class="mb-4">
In the meantime, why not take a look around our <a In the meantime, why not take a look around our <a
class="text-hyroGold" class="text-gold"
href="/">homepage</a href="/">homepage</a
> and see if you can find something else that piques your interest? Who knows, > 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 you might just stumble upon something even better than what you were originally

View file

@ -30,32 +30,31 @@ import { skills } from "~/config";
<main class="text-2xl text-white"> <main class="text-2xl text-white">
<section> <section>
<p class="mb-4"> <p class="mb-4">
My name is <span class="text-hyroGold">Jozef Steinhübl</span> ("bl" - not My name is <span class="text-gold">Jozef Steinhübl</span> ("bl" - not "bel",
"bel", I'm not a bell), but you may know me by my pseudonyms, <span I'm not a bell), but you may know me by my pseudonyms, <span
class="text-hyroGold" class="text-gold"
>Hyro, xHyroM, or general_kubo >Hyro, xHyroM, or general_kubo
</span>. I am a developer with a passion for creating innovative </span>. I am a developer with a passion for creating innovative
solutions, and I am currently engaged in various projects. Most of my solutions, and I am currently engaged in various projects. Most of my
work is open-source and accessible on <a work is open-source and accessible on <a
class="text-hyroGold" class="text-gold"
href="https://github.com/xHyroM">GitHub</a href="https://github.com/xHyroM">GitHub</a
>, where I contribute to the development of cutting-edge software >, where I contribute to the development of cutting-edge software
solutions. You can also check <a solutions. You can also check <a class="text-gold" href="/projects"
class="text-hyroGold" >Projects</a
href="/projects">Projects</a
> page on this website. > page on this website.
</p> </p>
<p class="mb-4"> <p class="mb-4">
Apart from my open-source projects, I'm working/have also worked on Apart from my open-source projects, I'm working/have also worked on
other notable projects such as <a other notable projects such as <a
class="text-hyroGold" class="text-gold"
href="https://rajce.pro">rajce.pro</a href="https://rajce.pro">rajce.pro</a
>, <a class="text-hyroGold" href="https://lendmark.sk">LendMark</a>, <a >, <a class="text-gold" href="https://lendmark.sk">LendMark</a>, <a
class="text-hyroGold" class="text-gold"
href="https://discord.com/api/oauth2/authorize?client_id=720321585625694239&permissions=8&scope=applications.commands%20bot" href="https://discord.com/api/oauth2/authorize?client_id=720321585625694239&permissions=8&scope=applications.commands%20bot"
>Mr. Infinity</a >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 >Roles Bot</a
> and for different content creators and influencers. My keen interest > and for different content creators and influencers. My keen interest
in the latest technologies motivates me to contribute to diverse projects 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, and while I do not claim to be a master of any programming language,
my expertise in various languages is continually evolving. As a my expertise in various languages is continually evolving. As a
contributor and moderator for the <a contributor and moderator for the <a
class="text-hyroGold" class="text-gold"
href="https://bun.sh">Bun</a href="https://bun.sh">Bun</a
> project, I collaborated with my friend <a > project, I collaborated with my friend <a
class="text-hyroGold" class="text-gold"
href="https://github.com/Fire-The-Fox">@FireTheFox</a href="https://github.com/Fire-The-Fox">@FireTheFox</a
> to develop a native implementation of the <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 href="https://github.com/oven-sh/bun/pull/1115">node:os module</a
>. >.
</p> </p>

View file

@ -40,7 +40,7 @@ const posts = page.data as {
<main> <main>
{posts.map(post => { {posts.map(post => {
return ( 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"> <p class="text-1xl text-opacity-40 text-white italic break-all">
{new Date(post.frontmatter.date).toLocaleDateString('en-us', { {new Date(post.frontmatter.date).toLocaleDateString('en-us', {
year: 'numeric', year: 'numeric',
@ -49,7 +49,7 @@ const posts = page.data as {
})} })}
</p> </p>
<p class="text-1xl text-white break-all">{post.frontmatter.description}</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" />
) )
})} })}

View file

@ -60,7 +60,7 @@ projects.sort((a, b) => a.name.localeCompare(b.name));
<main class="flex flex-wrap justify-center gap-12"> <main class="flex flex-wrap justify-center gap-12">
{ {
projects.map((project) => ( 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"> <div class="flex">
<h2 class="mb-4 break-words text-3xl font-bold text-white"> <h2 class="mb-4 break-words text-3xl font-bold text-white">
{project.name} {project.name}

View file

@ -14,8 +14,27 @@ module.exports = {
extend: { extend: {
colors: { colors: {
dark: "#0D0D0D", dark: "#0D0D0D",
gray: "#131313", "dark-100": "#1A1A1A",
hyroGold: "#fbc119", "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: { dropShadow: {
yellow: ["0 35px 35px rgba(250, 193, 25, 0.5)"], yellow: ["0 35px 35px rgba(250, 193, 25, 0.5)"],

View file

@ -2,6 +2,8 @@
"extends": "astro/tsconfigs/strict", "extends": "astro/tsconfigs/strict",
"compilerOptions": { "compilerOptions": {
"baseUrl": ".", "baseUrl": ".",
"jsx": "preserve",
"jsxImportSource": "preact",
"paths": { "paths": {
"~/*": ["src/*"], "~/*": ["src/*"],
"@docs/*": ["docs/*"], "@docs/*": ["docs/*"],