Homepage UI Update
This commit is contained in:
5
.gitignore
vendored
5
.gitignore
vendored
@@ -25,4 +25,7 @@ pnpm-debug.log*
|
|||||||
|
|
||||||
# pagefind
|
# pagefind
|
||||||
|
|
||||||
public/pagefind
|
public/pagefind
|
||||||
|
|
||||||
|
pnpm-lock.yaml
|
||||||
|
bun.lock
|
||||||
18
package.json
18
package.json
@@ -14,33 +14,33 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@astrojs/rss": "^4.0.14",
|
"@astrojs/rss": "^4.0.14",
|
||||||
"@astrojs/sitemap": "^3.6.0",
|
"@astrojs/sitemap": "^3.6.1",
|
||||||
"@resvg/resvg-js": "^2.6.2",
|
"@resvg/resvg-js": "^2.6.2",
|
||||||
"@tailwindcss/vite": "^4.1.17",
|
"@tailwindcss/vite": "^4.1.18",
|
||||||
"astro": "^5.16.3",
|
"astro": "^5.16.8",
|
||||||
"dayjs": "^1.11.19",
|
"dayjs": "^1.11.19",
|
||||||
"lodash.kebabcase": "^4.1.1",
|
"lodash.kebabcase": "^4.1.1",
|
||||||
"remark-collapse": "^0.1.2",
|
"remark-collapse": "^0.1.2",
|
||||||
"remark-toc": "^9.0.0",
|
"remark-toc": "^9.0.0",
|
||||||
"satori": "^0.15.2",
|
"satori": "^0.15.2",
|
||||||
"sharp": "^0.34.5",
|
"sharp": "^0.34.5",
|
||||||
"tailwindcss": "^4.1.17"
|
"tailwindcss": "^4.1.18"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@astrojs/check": "^0.9.6",
|
"@astrojs/check": "^0.9.6",
|
||||||
"@pagefind/default-ui": "^1.4.0",
|
"@pagefind/default-ui": "^1.4.0",
|
||||||
"@shikijs/transformers": "^3.17.0",
|
"@shikijs/transformers": "^3.21.0",
|
||||||
"@tailwindcss/typography": "^0.5.19",
|
"@tailwindcss/typography": "^0.5.19",
|
||||||
"@types/lodash.kebabcase": "^4.1.9",
|
"@types/lodash.kebabcase": "^4.1.9",
|
||||||
"@typescript-eslint/parser": "^8.48.0",
|
"@typescript-eslint/parser": "^8.52.0",
|
||||||
"eslint": "^9.39.1",
|
"eslint": "^9.39.2",
|
||||||
"eslint-plugin-astro": "^1.5.0",
|
"eslint-plugin-astro": "^1.5.0",
|
||||||
"globals": "^16.5.0",
|
"globals": "^16.5.0",
|
||||||
"pagefind": "^1.4.0",
|
"pagefind": "^1.4.0",
|
||||||
"prettier": "^3.7.3",
|
"prettier": "^3.7.4",
|
||||||
"prettier-plugin-astro": "^0.14.1",
|
"prettier-plugin-astro": "^0.14.1",
|
||||||
"prettier-plugin-tailwindcss": "^0.6.14",
|
"prettier-plugin-tailwindcss": "^0.6.14",
|
||||||
"typescript": "^5.9.3",
|
"typescript": "^5.9.3",
|
||||||
"typescript-eslint": "^8.48.0"
|
"typescript-eslint": "^8.52.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
6065
pnpm-lock.yaml
generated
6065
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -17,9 +17,7 @@ const { noMarginTop = false } = Astro.props;
|
|||||||
>
|
>
|
||||||
<Socials centered />
|
<Socials centered />
|
||||||
<div class="my-2 flex flex-col items-center whitespace-nowrap sm:flex-row">
|
<div class="my-2 flex flex-col items-center whitespace-nowrap sm:flex-row">
|
||||||
<span><a href={SITE.website} rel="noopener noreferrer" target="_blank"
|
<span>{SITE.author}</span>
|
||||||
>{SITE.author}</a
|
|
||||||
></span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|||||||
@@ -13,156 +13,155 @@ const { pathname } = Astro.url;
|
|||||||
|
|
||||||
// Remove trailing slash from current pathname if exists
|
// Remove trailing slash from current pathname if exists
|
||||||
const currentPath =
|
const currentPath =
|
||||||
pathname.endsWith("/") && pathname !== "/" ? pathname.slice(0, -1) : pathname;
|
pathname.endsWith("/") && pathname !== "/" ? pathname.slice(0, -1) : pathname;
|
||||||
|
|
||||||
const isActive = (path: string) => {
|
const isActive = (path: string) => {
|
||||||
const currentPathArray = currentPath.split("/").filter(p => p.trim());
|
const currentPathArray = currentPath.split("/").filter(p => p.trim());
|
||||||
const pathArray = path.split("/").filter(p => p.trim());
|
const pathArray = path.split("/").filter(p => p.trim());
|
||||||
|
|
||||||
return currentPath === path || currentPathArray[0] === pathArray[0];
|
return currentPath === path || currentPathArray[0] === pathArray[0];
|
||||||
};
|
};
|
||||||
---
|
---
|
||||||
|
|
||||||
<header>
|
<header>
|
||||||
<a
|
<a
|
||||||
id="skip-to-content"
|
id="skip-to-content"
|
||||||
href="#main-content"
|
href="#main-content"
|
||||||
class="absolute start-16 -top-full z-50 bg-background px-3 py-2 text-accent backdrop-blur-lg transition-all focus:top-4"
|
class="absolute start-16 -top-full z-50 bg-background px-3 py-2 text-accent backdrop-blur-lg transition-all focus:top-4"
|
||||||
>
|
>
|
||||||
Skip to content
|
Skip to content
|
||||||
</a>
|
</a>
|
||||||
<div
|
<div
|
||||||
id="nav-container"
|
id="nav-container"
|
||||||
class="mx-auto flex max-w-app flex-col items-center justify-between sm:flex-row"
|
class="mx-auto flex max-w-app flex-col items-center justify-between sm:flex-row"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
id="top-nav-wrap"
|
id="top-nav-wrap"
|
||||||
class="relative flex w-full items-baseline justify-between bg-background p-4 sm:items-center sm:py-6"
|
class="relative flex w-full items-baseline justify-center bg-background p-4 sm:items-center sm:py-6"
|
||||||
>
|
>
|
||||||
<a
|
<nav
|
||||||
href="/"
|
id="nav-menu"
|
||||||
class="absolute py-1 text-xl leading-8 font-semibold whitespace-nowrap sm:static sm:my-auto sm:text-2xl sm:leading-none"
|
class="flex w-full flex-col items-center sm:flex-row sm:justify-center sm:space-x-4 sm:py-0"
|
||||||
>
|
>
|
||||||
{SITE.title}
|
<button
|
||||||
</a>
|
id="menu-btn"
|
||||||
<nav
|
class="focus-outline self-end p-2 sm:hidden"
|
||||||
id="nav-menu"
|
aria-label="Open Menu"
|
||||||
class="flex w-full flex-col items-center sm:ms-2 sm:flex-row sm:justify-end sm:space-x-4 sm:py-0"
|
aria-expanded="false"
|
||||||
>
|
aria-controls="menu-items"
|
||||||
<button
|
>
|
||||||
id="menu-btn"
|
<IconX id="close-icon" class="hidden" />
|
||||||
class="focus-outline self-end p-2 sm:hidden"
|
<IconMenuDeep id="menu-icon" />
|
||||||
aria-label="Open Menu"
|
</button>
|
||||||
aria-expanded="false"
|
<ul
|
||||||
aria-controls="menu-items"
|
id="menu-items"
|
||||||
>
|
class:list={[
|
||||||
<IconX id="close-icon" class="hidden" />
|
"mt-4 grid w-44 grid-cols-2 place-content-center gap-2",
|
||||||
<IconMenuDeep id="menu-icon" />
|
"[&>li>a]:block [&>li>a]:px-4 [&>li>a]:py-3 [&>li>a]:text-center [&>li>a]:font-medium [&>li>a]:hover:text-accent sm:[&>li>a]:px-2 sm:[&>li>a]:py-1",
|
||||||
</button>
|
"hidden",
|
||||||
<ul
|
"sm:mt-0 sm:flex sm:w-auto sm:gap-x-5 sm:gap-y-0",
|
||||||
id="menu-items"
|
]}
|
||||||
class:list={[
|
>
|
||||||
"mt-4 grid w-44 grid-cols-2 place-content-center gap-2",
|
<li class="col-span-2">
|
||||||
"[&>li>a]:block [&>li>a]:px-4 [&>li>a]:py-3 [&>li>a]:text-center [&>li>a]:font-medium [&>li>a]:hover:text-accent sm:[&>li>a]:px-2 sm:[&>li>a]:py-1",
|
<a href="/" class:list={{ "active-nav": isActive("/") }}>
|
||||||
"hidden",
|
Home
|
||||||
"sm:mt-0 sm:flex sm:w-auto sm:gap-x-5 sm:gap-y-0",
|
</a>
|
||||||
]}
|
</li>
|
||||||
>
|
<li class="col-span-2">
|
||||||
<li class="col-span-2">
|
<a href="/posts" class:list={{ "active-nav": isActive("/posts") }}>
|
||||||
<a href="/posts" class:list={{ "active-nav": isActive("/posts") }}>
|
Posts
|
||||||
Posts
|
</a>
|
||||||
</a>
|
</li>
|
||||||
</li>
|
<li class="col-span-2">
|
||||||
<li class="col-span-2">
|
<a href="/tags" class:list={{ "active-nav": isActive("/tags") }}>
|
||||||
<a href="/tags" class:list={{ "active-nav": isActive("/tags") }}>
|
Tags
|
||||||
Tags
|
</a>
|
||||||
</a>
|
</li>
|
||||||
</li>
|
<li class="col-span-2">
|
||||||
<li class="col-span-2">
|
<a href="/about" class:list={{ "active-nav": isActive("/about") }}>
|
||||||
<a href="/about" class:list={{ "active-nav": isActive("/about") }}>
|
About
|
||||||
About
|
</a>
|
||||||
</a>
|
</li>
|
||||||
</li>
|
{
|
||||||
{
|
SITE.showArchives && (
|
||||||
SITE.showArchives && (
|
<li class="col-span-2">
|
||||||
<li class="col-span-2">
|
<LinkButton
|
||||||
<LinkButton
|
href="/archives"
|
||||||
href="/archives"
|
class:list={[
|
||||||
class:list={[
|
"focus-outline flex justify-center p-3 sm:p-1",
|
||||||
"focus-outline flex justify-center p-3 sm:p-1",
|
{
|
||||||
{
|
"active-nav [&>svg]:stroke-accent": isActive("/archives"),
|
||||||
"active-nav [&>svg]:stroke-accent": isActive("/archives"),
|
},
|
||||||
},
|
]}
|
||||||
]}
|
ariaLabel="archives"
|
||||||
ariaLabel="archives"
|
title="Archives"
|
||||||
title="Archives"
|
>
|
||||||
>
|
<IconArchive class="hidden sm:inline-block" />
|
||||||
<IconArchive class="hidden sm:inline-block" />
|
<span class="sm:sr-only">Archives</span>
|
||||||
<span class="sm:sr-only">Archives</span>
|
</LinkButton>
|
||||||
</LinkButton>
|
</li>
|
||||||
</li>
|
)
|
||||||
)
|
}
|
||||||
}
|
<li class="col-span-1 flex items-center justify-center">
|
||||||
<li class="col-span-1 flex items-center justify-center">
|
<LinkButton
|
||||||
<LinkButton
|
href="/search"
|
||||||
href="/search"
|
class:list={[
|
||||||
class:list={[
|
"focus-outline flex p-3 sm:p-1",
|
||||||
"focus-outline flex p-3 sm:p-1",
|
{ "[&>svg]:stroke-accent": isActive("/search") },
|
||||||
{ "[&>svg]:stroke-accent": isActive("/search") },
|
]}
|
||||||
]}
|
ariaLabel="search"
|
||||||
ariaLabel="search"
|
title="Search"
|
||||||
title="Search"
|
>
|
||||||
>
|
<IconSearch />
|
||||||
<IconSearch />
|
<span class="sr-only">Search</span>
|
||||||
<span class="sr-only">Search</span>
|
</LinkButton>
|
||||||
</LinkButton>
|
</li>
|
||||||
</li>
|
{
|
||||||
{
|
SITE.lightAndDarkMode && (
|
||||||
SITE.lightAndDarkMode && (
|
<li class="col-span-1 flex items-center justify-center">
|
||||||
<li class="col-span-1 flex items-center justify-center">
|
<button
|
||||||
<button
|
id="theme-btn"
|
||||||
id="theme-btn"
|
class="focus-outline relative size-12 p-4 sm:size-8 hover:[&>svg]:stroke-accent"
|
||||||
class="focus-outline relative size-12 p-4 sm:size-8 hover:[&>svg]:stroke-accent"
|
title="Toggles light & dark"
|
||||||
title="Toggles light & dark"
|
aria-label="auto"
|
||||||
aria-label="auto"
|
aria-live="polite"
|
||||||
aria-live="polite"
|
>
|
||||||
>
|
<IconMoon class="absolute top-[50%] left-[50%] -translate-[50%] scale-100 rotate-0 transition-all dark:scale-0 dark:-rotate-90" />
|
||||||
<IconMoon class="absolute top-[50%] left-[50%] -translate-[50%] scale-100 rotate-0 transition-all dark:scale-0 dark:-rotate-90" />
|
<IconSunHigh class="absolute top-[50%] left-[50%] -translate-[50%] scale-0 rotate-90 transition-all dark:scale-100 dark:rotate-0" />
|
||||||
<IconSunHigh class="absolute top-[50%] left-[50%] -translate-[50%] scale-0 rotate-90 transition-all dark:scale-100 dark:rotate-0" />
|
</button>
|
||||||
</button>
|
</li>
|
||||||
</li>
|
)
|
||||||
)
|
}
|
||||||
}
|
</ul>
|
||||||
</ul>
|
</nav>
|
||||||
</nav>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<Hr />
|
||||||
<Hr />
|
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
function toggleNav() {
|
function toggleNav() {
|
||||||
const menuBtn = document.querySelector("#menu-btn");
|
const menuBtn = document.querySelector("#menu-btn");
|
||||||
const menuItems = document.querySelector("#menu-items");
|
const menuItems = document.querySelector("#menu-items");
|
||||||
const menuIcon = document.querySelector("#menu-icon");
|
const menuIcon = document.querySelector("#menu-icon");
|
||||||
const closeIcon = document.querySelector("#close-icon");
|
const closeIcon = document.querySelector("#close-icon");
|
||||||
|
|
||||||
if (!menuBtn || !menuItems || !menuIcon || !closeIcon) return;
|
if (!menuBtn || !menuItems || !menuIcon || !closeIcon) return;
|
||||||
|
|
||||||
menuBtn.addEventListener("click", () => {
|
menuBtn.addEventListener("click", () => {
|
||||||
const openMenu = menuBtn.getAttribute("aria-expanded") === "true";
|
const openMenu = menuBtn.getAttribute("aria-expanded") === "true";
|
||||||
|
|
||||||
menuBtn.setAttribute("aria-expanded", openMenu ? "false" : "true");
|
menuBtn.setAttribute("aria-expanded", openMenu ? "false" : "true");
|
||||||
menuBtn.setAttribute("aria-label", openMenu ? "Open Menu" : "Close Menu");
|
menuBtn.setAttribute("aria-label", openMenu ? "Open Menu" : "Close Menu");
|
||||||
|
|
||||||
menuItems.classList.toggle("hidden");
|
menuItems.classList.toggle("hidden");
|
||||||
menuIcon.classList.toggle("hidden");
|
menuIcon.classList.toggle("hidden");
|
||||||
closeIcon.classList.toggle("hidden");
|
closeIcon.classList.toggle("hidden");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleNav();
|
toggleNav();
|
||||||
|
|
||||||
// Runs on view transitions navigation
|
// Runs on view transitions navigation
|
||||||
document.addEventListener("astro:after-swap", toggleNav);
|
document.addEventListener("astro:after-swap", toggleNav);
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -23,8 +23,8 @@ const recentPosts = sortedPosts.filter(({ data }) => !data.featured);
|
|||||||
<Layout>
|
<Layout>
|
||||||
<Header />
|
<Header />
|
||||||
<main id="main-content" data-layout="index">
|
<main id="main-content" data-layout="index">
|
||||||
<section id="hero" class="pt-8 pb-6">
|
<section id="hero" class="pt-2 pb-4">
|
||||||
<h1 class="my-4 inline-block text-4xl font-bold sm:my-8 sm:text-5xl">
|
<h1 class="my-2 inline-block text-4xl font-bold sm:my-4 sm:text-5xl">
|
||||||
{SITE.title}
|
{SITE.title}
|
||||||
</h1>
|
</h1>
|
||||||
<a
|
<a
|
||||||
|
|||||||
Reference in New Issue
Block a user