🛠️ Refactor sidebar link activation, enhance PageCard and PageHeader components, and improve badge styles

This commit is contained in:
pheralb
2025-08-29 00:14:31 +01:00
parent 62a6dddc34
commit 09291b90fe
9 changed files with 59 additions and 26 deletions
@@ -54,7 +54,7 @@
class={cn( class={cn(
sidebarItemClasses.base, sidebarItemClasses.base,
"justify-start space-x-3", "justify-start space-x-3",
String(page.url.pathname) === "/api" && sidebarItemClasses.active, String(page.url.pathname) === "/docs/api" && sidebarItemClasses.active,
)} )}
> >
<Cloud size={16} /> <Cloud size={16} />
+5 -1
View File
@@ -4,9 +4,11 @@
interface PageCardProps { interface PageCardProps {
children: Snippet; children: Snippet;
containerClass?: string;
contentCardClass?: string;
} }
let { children }: PageCardProps = $props(); let { children, contentCardClass, containerClass }: PageCardProps = $props();
</script> </script>
<div <div
@@ -14,11 +16,13 @@
"mt-2.5 overflow-hidden", "mt-2.5 overflow-hidden",
"rounded-md border border-neutral-200 dark:border-neutral-800", "rounded-md border border-neutral-200 dark:border-neutral-800",
"bg-white dark:bg-neutral-900/40", "bg-white dark:bg-neutral-900/40",
containerClass,
)} )}
> >
<div <div
class={cn( class={cn(
"max-h-[calc(100vh-8.6rem)] min-h-[calc(100vh-8.6rem)] overflow-y-auto", "max-h-[calc(100vh-8.6rem)] min-h-[calc(100vh-8.6rem)] overflow-y-auto",
contentCardClass,
)} )}
> >
{@render children?.()} {@render children?.()}
+22
View File
@@ -0,0 +1,22 @@
<script lang="ts">
import type { Snippet } from "svelte";
import { cn } from "@/utils/cn";
interface PageHeaderProps {
children: Snippet;
className?: string;
}
let { children, className }: PageHeaderProps = $props();
</script>
<div
class={cn(
"sticky top-0 z-50 flex h-12.5 items-center justify-between py-1.5 pr-2 pl-3",
"border-b border-neutral-200 dark:border-neutral-800",
"bg-white/80 backdrop-blur-sm dark:bg-neutral-900/40",
className,
)}
>
{@render children?.()}
</div>
+1 -1
View File
@@ -17,7 +17,7 @@ const badgeVariants = tv({
danger: danger:
"bg-red-100 text-red-800 border-red-200 dark:bg-red-900 dark:text-red-100 dark:border-red-800", "bg-red-100 text-red-800 border-red-200 dark:bg-red-900 dark:text-red-100 dark:border-red-800",
outline: outline:
"bg-transparent border border-neutral-300 text-neutral-700 dark:border-neutral-700 dark:text-neutral-400", "bg-transparent border border-neutral-300 text-neutral-700 dark:border-neutral-800 dark:text-neutral-400",
}, },
size: { size: {
sm: "text-xs px-2 py-0.5", sm: "text-xs px-2 py-0.5",
+1 -1
View File
@@ -13,7 +13,7 @@
bind:ref bind:ref
data-slot="tabs-list" data-slot="tabs-list"
class={cn( class={cn(
"inline-flex h-9 items-center justify-center rounded-md border border-neutral-200 bg-neutral-100 p-1 text-neutral-500 dark:border-neutral-800 dark:bg-neutral-900 dark:text-neutral-400", "inline-flex h-9 items-center justify-center rounded-md border border-neutral-200 bg-white p-1 text-neutral-500 dark:border-neutral-800 dark:bg-neutral-900 dark:text-neutral-400",
className, className,
)} )}
{...restProps} {...restProps}
+1 -1
View File
@@ -13,7 +13,7 @@
bind:ref bind:ref
data-slot="tabs-trigger" data-slot="tabs-trigger"
class={cn( class={cn(
"inline-flex items-center justify-center rounded-md px-3 py-1 text-sm font-medium whitespace-nowrap ring-offset-white transition-all focus-visible:ring-2 focus-visible:ring-neutral-950 focus-visible:ring-offset-2 focus-visible:outline-none disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-white data-[state=active]:text-neutral-950 data-[state=active]:shadow dark:ring-offset-neutral-950 dark:focus-visible:ring-neutral-300 dark:data-[state=active]:bg-neutral-950 dark:data-[state=active]:text-neutral-50", "inline-flex items-center justify-center rounded-md px-3 py-1 text-sm font-medium whitespace-nowrap ring-offset-white transition-all focus-visible:ring-2 focus-visible:ring-neutral-950 focus-visible:ring-offset-2 focus-visible:outline-none disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-neutral-200 data-[state=active]:text-neutral-950 data-[state=active]:shadow dark:ring-offset-neutral-950 dark:focus-visible:ring-neutral-300 dark:data-[state=active]:bg-neutral-800 dark:data-[state=active]:text-neutral-50",
className, className,
)} )}
{...restProps} {...restProps}
+7 -8
View File
@@ -14,6 +14,7 @@
import Container from "@/components/container.svelte"; import Container from "@/components/container.svelte";
import PageCard from "@/components/pageCard.svelte"; import PageCard from "@/components/pageCard.svelte";
import PageHeader from "@/components/pageHeader.svelte";
import FolderIcon from "@lucide/svelte/icons/folder"; import FolderIcon from "@lucide/svelte/icons/folder";
import FolderSearchIcon from "@lucide/svelte/icons/folder-search"; import FolderSearchIcon from "@lucide/svelte/icons/folder-search";
@@ -64,6 +65,10 @@
}); });
</script> </script>
<svelte:head>
<title>A beautiful library with SVG logos - Svgl</title>
</svelte:head>
<Search <Search
searchValue={searchTerm} searchValue={searchTerm}
onSearch={handleSearch} onSearch={handleSearch}
@@ -71,13 +76,7 @@
/> />
<PageCard> <PageCard>
<div <PageHeader>
class={cn(
"sticky top-0 z-50 flex h-12.5 items-center justify-between py-1.5 pr-2 pl-3",
"border-b border-neutral-200 dark:border-neutral-800",
"bg-white/80 backdrop-blur-sm dark:bg-neutral-900/40",
)}
>
<div <div
class="flex items-center space-x-2 text-neutral-500 dark:text-neutral-400" class="flex items-center space-x-2 text-neutral-500 dark:text-neutral-400"
> >
@@ -103,7 +102,7 @@
searchSvgs(); searchSvgs();
}} }}
/> />
</div> </PageHeader>
<Container className="my-6"> <Container className="my-6">
<Grid> <Grid>
{#each displaySvgs as svg} {#each displaySvgs as svg}
+5
View File
@@ -0,0 +1,5 @@
import { redirect } from "@sveltejs/kit";
export const load = async () => {
return redirect(307, "/docs/api");
};
+16 -13
View File
@@ -2,6 +2,10 @@
import type { iSVG } from "@/types/svg"; import type { iSVG } from "@/types/svg";
import type { PageProps } from "./$types"; import type { PageProps } from "./$types";
import { page } from "$app/state";
import { goto } from "$app/navigation";
import { SvelteURLSearchParams } from "svelte/reactivity";
import { cn } from "@/utils/cn"; import { cn } from "@/utils/cn";
import { searchWithFuse } from "@/utils/searchWithFuse"; import { searchWithFuse } from "@/utils/searchWithFuse";
@@ -12,16 +16,14 @@
import Container from "@/components/container.svelte"; import Container from "@/components/container.svelte";
import PageCard from "@/components/pageCard.svelte"; import PageCard from "@/components/pageCard.svelte";
import PageHeader from "@/components/pageHeader.svelte";
import FolderIcon from "@lucide/svelte/icons/folder-open"; import FolderIcon from "@lucide/svelte/icons/folder-open";
import ArrowLeftIcon from "@lucide/svelte/icons/arrow-left"; import ArrowLeftIcon from "@lucide/svelte/icons/arrow-left";
import { page } from "$app/state";
import { goto } from "$app/navigation";
import { SvelteURLSearchParams } from "svelte/reactivity";
import { buttonVariants } from "@/components/ui/button"; import { buttonVariants } from "@/components/ui/button";
// SSR Data: // SSR Data:
let { data }: PageProps = $props(); let { data }: PageProps = $props();
const directoryData = $derived(data);
// States: // States:
let searchTerm = $state<string>(data.searchTerm || ""); let searchTerm = $state<string>(data.searchTerm || "");
@@ -62,6 +64,9 @@
searchSvgs(); searchSvgs();
}; };
const formatCategory = (category: string) =>
category.charAt(0).toUpperCase() + category.slice(1);
$effect(() => { $effect(() => {
filteredSvgs = data.svgs.filter((svg: iSVG) => filteredSvgs = data.svgs.filter((svg: iSVG) =>
svg.title.toLowerCase().includes(searchTerm.toLowerCase()), svg.title.toLowerCase().includes(searchTerm.toLowerCase()),
@@ -69,6 +74,10 @@
}); });
</script> </script>
<svelte:head>
<title>{formatCategory(directoryData.category)} SVG logos - Svgl</title>
</svelte:head>
<Search <Search
searchValue={searchTerm} searchValue={searchTerm}
onSearch={handleSearch} onSearch={handleSearch}
@@ -76,13 +85,7 @@
/> />
<PageCard> <PageCard>
<div <PageHeader>
class={cn(
"sticky top-0 z-50 flex h-12.5 items-center justify-between py-1.5 pr-2 pl-2",
"border-b border-neutral-200 dark:border-neutral-800",
"bg-white/80 backdrop-blur-sm dark:bg-neutral-900/40",
)}
>
<div <div
class="flex items-center space-x-2 font-medium text-neutral-950 dark:text-neutral-50" class="flex items-center space-x-2 font-medium text-neutral-950 dark:text-neutral-50"
> >
@@ -100,7 +103,7 @@
</a> </a>
<FolderIcon size={18} strokeWidth={1.5} /> <FolderIcon size={18} strokeWidth={1.5} />
<p> <p>
{data.category.slice(0, 1).toUpperCase() + data.category.slice(1)} {formatCategory(directoryData.category)}
</p> </p>
<span>-</span> <span>-</span>
{#if !searchTerm} {#if !searchTerm}
@@ -114,7 +117,7 @@
</p> </p>
{/if} {/if}
</div> </div>
</div> </PageHeader>
<Container className="my-6"> <Container className="my-6">
<Grid> <Grid>
{#each filteredSvgs as svg} {#each filteredSvgs as svg}