🎨 Initial sidebar UI component

This commit is contained in:
pheralb
2025-08-25 19:05:47 +01:00
parent 60fca6b2ff
commit 9038d92465
5 changed files with 133 additions and 0 deletions
@@ -0,0 +1,41 @@
<script lang="ts">
import type { tCategory } from "@/types/categories";
import { cn } from "@/utils/cn";
import { svgs } from "@/data/svgs";
import { page } from "$app/state";
import { getCategories } from "@/data";
import { sidebarItemClasses } from "./sidebarItemClasses";
// Get category counts:
const categories: tCategory[] = getCategories();
let categoryCounts: Record<string, number> = {};
categories.forEach((category) => {
categoryCounts[category] = svgs.filter((svg) =>
svg.category.includes(category),
).length;
});
</script>
{#each categories.sort() as category}
<a
href={`/directory/${category.toLowerCase()}`}
data-sveltekit-preload-data
class={cn(
sidebarItemClasses.base,
page.url.pathname === `/directory/${category.toLowerCase()}` &&
sidebarItemClasses.active,
"pr-3",
)}
>
<p class="truncate">{category}</p>
<span
class={cn(
"dark:bg-dark rounded-lg border border-neutral-200 bg-white px-2 py-0.5 font-mono text-xs font-medium text-neutral-600 shadow-sm dark:border-neutral-800 dark:bg-neutral-900 dark:text-neutral-400",
page.url.pathname && "border-transparent",
)}
>
{categoryCounts[category]}
</span>
</a>
{/each}
@@ -0,0 +1,22 @@
<script lang="ts">
import { cn } from "@/utils/cn";
import { page } from "$app/state";
import { sidebarLinks } from "./sidebarLinks";
import { sidebarItemClasses } from "./sidebarItemClasses";
</script>
{#each sidebarLinks as sidebarLink}
<a
href={sidebarLink.href}
data-sveltekit-preload-data
class={cn(
sidebarItemClasses.base,
"justify-start space-x-3",
page.url.pathname === sidebarLink.href && sidebarItemClasses.active,
)}
>
<sidebarLink.icon size={16} />
<p class="truncate">{sidebarLink.title}</p>
</a>
{/each}
+30
View File
@@ -0,0 +1,30 @@
<script lang="ts">
import { cn } from "@/utils/cn";
import { Separator } from "@/components/ui/separator";
import ShowCategories from "@/components/layout/showCategories.svelte";
import ShowSidebarLinks from "@/components/layout/showSidebarLinks.svelte";
</script>
<section>
<aside
class={cn(
"fixed left-0 h-[calc(100vh-5.4rem)]",
"overflow-x-hidden",
"w-54 pr-2 pl-3",
"flex flex-col space-y-3",
"bg-neutral-100 dark:bg-neutral-950",
)}
>
<nav class="flex flex-col space-y-0.5">
<ShowSidebarLinks />
</nav>
<Separator orientation="horizontal" />
<nav class="flex flex-col space-y-0.5 overflow-y-auto">
<ShowCategories />
</nav>
</aside>
<main class={cn("mr-4 mb-4 ml-56", "overflow-hidden")}>
<slot />
</main>
</section>
@@ -0,0 +1,13 @@
import { cn } from "@/utils/cn";
export const sidebarItemClasses = {
base: cn(
"rounded-md px-2 py-1.5",
"flex w-full items-center justify-between space-x-3 text-sm",
"text-neutral-600 dark:text-neutral-400",
"hover:text-black dark:hover:text-white",
),
active: cn(
"rounded-lg shadow-sm text-black dark:text-white border border-neutral-200 bg-white font-medium dark:border-neutral-800 dark:bg-neutral-800",
),
};
+27
View File
@@ -0,0 +1,27 @@
import BoxIcon from "@lucide/svelte/icons/box";
import HouseIcon from "@lucide/svelte/icons/house";
import CloudIcon from "@lucide/svelte/icons/cloud";
import HeartIcon from "@lucide/svelte/icons/heart";
export const sidebarLinks = [
{
title: "Home",
href: "/",
icon: HouseIcon,
},
{
title: "Favorites",
href: "/favorites",
icon: HeartIcon,
},
{
title: "API",
href: "/api",
icon: CloudIcon,
},
{
title: "Extensions",
href: "/extensions",
icon: BoxIcon,
},
];