mirror of
https://github.com/pheralb/svgl.git
synced 2025-12-29 08:01:36 +08:00
🎨 Initial sidebar UI component
This commit is contained in:
@@ -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}
|
||||||
@@ -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",
|
||||||
|
),
|
||||||
|
};
|
||||||
@@ -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,
|
||||||
|
},
|
||||||
|
];
|
||||||
Reference in New Issue
Block a user