10 Commits
Author SHA1 Message Date
pheralb ea4b598f2f Update Shiki configuration to include JSON and HTML languages
📦 Build / 🛠️ Build app (push) Has been cancelled
🧑‍🚀 Check / ⚙️ Linting (push) Has been cancelled
🧑‍🚀 Check / 📦 SVGs Size (push) Has been cancelled
2025-09-05 11:27:00 +01:00
pheralb fff76243ec ⚙️ Improve mode toggle functionality with keyboard shortcut support (CMD + L) 2025-09-05 11:26:44 +01:00
pheralb 9825fc2544 📦 Add SVGL for Framer extension with description and creator details 2025-09-05 11:14:39 +01:00
pheralb 04ffbe9bbb Refactor setup registry component and update documentation for shadcn/ui integration 2025-09-05 11:14:15 +01:00
pheralb bc831bed17 🎨 Initial responsive design + add sidebar menu to header component 2025-09-05 11:14:05 +01:00
pheralb d3e92602c1 📦 Add Sheet UI component 2025-09-05 11:07:09 +01:00
pheralb 3a11cd3d31 ⚙️ Update dialog title to reflect multiple SVG download options 2025-09-05 09:15:00 +01:00
pheralb e465cd7a51 🛠️ Merge branch 'main' of github.com:pheralb/svgl into dev 2025-09-05 09:11:45 +01:00
Pablo HdezandGitHub f45b2d9d27 Merge pull request #756 from jonahsnider/sanity-rebrand
📦 Build / 🛠️ Build app (push) Has been cancelled
🧑‍🚀 Check / ⚡ Testing with Vitest (push) Has been cancelled
🧑‍🚀 Check / 📦 SVGs Size (push) Has been cancelled
🚀 Deploy / ☁️ API (push) Has been cancelled
Update Sanity wordmark and add logo
2025-09-05 09:00:38 +01:00
Jonah Snider 9db8deed28 Update Sanity wordmark and add logo 2025-09-04 17:31:53 -07:00
29 changed files with 443 additions and 104 deletions
+43 -39
View File
@@ -12,6 +12,7 @@
import { buttonVariants } from "@/components/ui/button"; import { buttonVariants } from "@/components/ui/button";
import SvglVersion from "@/components/svglVersion.svelte"; import SvglVersion from "@/components/svglVersion.svelte";
import SendIcon from "@/components/ui/moving-icons/send-icon.svelte"; import SendIcon from "@/components/ui/moving-icons/send-icon.svelte";
import SidebarMobileMenu from "@/components/layout/sidebarMobileMenu.svelte";
interface HeaderProps { interface HeaderProps {
githubStars?: number; githubStars?: number;
@@ -25,6 +26,7 @@
> >
<nav class="flex w-full items-center justify-between"> <nav class="flex w-full items-center justify-between">
<div class="flex items-center space-x-3"> <div class="flex items-center space-x-3">
<SidebarMobileMenu className="md:hidden" />
<a <a
href="/" href="/"
class="flex items-center space-x-2.5 transition-colors hover:text-neutral-700 dark:hover:text-neutral-300" class="flex items-center space-x-2.5 transition-colors hover:text-neutral-700 dark:hover:text-neutral-300"
@@ -32,7 +34,7 @@
<Svgl size={28} /> <Svgl size={28} />
<h2 class="font-onest text-xl font-medium tracking-tight">svgl</h2> <h2 class="font-onest text-xl font-medium tracking-tight">svgl</h2>
</a> </a>
<SvglVersion /> <SvglVersion className="hidden md:block" />
</div> </div>
<div class="flex h-5 items-center space-x-2.5"> <div class="flex h-5 items-center space-x-2.5">
<div class="flex items-center space-x-1.5"> <div class="flex items-center space-x-1.5">
@@ -54,50 +56,52 @@
)} )}
/> />
</div> </div>
<Separator orientation="vertical" /> <div class="hidden h-5 items-center space-x-2 md:flex">
{#if githubStars !== undefined} <Separator orientation="vertical" />
{#if githubStars !== undefined}
<a
target="_blank"
title="GitHub Repository"
href={globals.githubUrl}
class={cn(
buttonVariants({ variant: "ghost" }),
"w-fit hover:bg-neutral-200 dark:hover:bg-neutral-800",
)}
>
<Github size={20} />
<span class="text-neutral-600 dark:text-neutral-400">
{githubStars >= 1000
? `${(githubStars / 1000).toFixed(1)}k`
: githubStars.toLocaleString()}
</span>
</a>
{:else}
<a
target="_blank"
title="GitHub Repository"
href={globals.githubUrl}
class={cn(
buttonVariants({ variant: "ghost", size: "icon" }),
"hover:bg-neutral-200 dark:hover:bg-neutral-800",
)}
>
<Github size={20} />
</a>
{/if}
<Separator orientation="vertical" />
<a <a
target="_blank" target="_blank"
title="GitHub Repository" href={globals.submitUrl}
href={globals.githubUrl}
class={cn( class={cn(
buttonVariants({ variant: "ghost" }), buttonVariants({
"w-fit hover:bg-neutral-200 dark:hover:bg-neutral-800", variant: mode.current === "dark" ? "default" : "radial",
}),
)} )}
> >
<Github size={20} /> <SendIcon size={14} />
<span class="text-neutral-600 dark:text-neutral-400"> <span>Submit</span>
{githubStars >= 1000
? `${(githubStars / 1000).toFixed(1)}k`
: githubStars.toLocaleString()}
</span>
</a> </a>
{:else} </div>
<a
target="_blank"
title="GitHub Repository"
href={globals.githubUrl}
class={cn(
buttonVariants({ variant: "ghost", size: "icon" }),
"hover:bg-neutral-200 dark:hover:bg-neutral-800",
)}
>
<Github size={20} />
</a>
{/if}
<Separator orientation="vertical" />
<a
target="_blank"
href={globals.submitUrl}
class={cn(
buttonVariants({
variant: mode.current === "dark" ? "default" : "radial",
}),
)}
>
<SendIcon size={14} />
<span>Submit</span>
</a>
</div> </div>
</nav> </nav>
</header> </header>
@@ -1,5 +1,7 @@
<script lang="ts"> <script lang="ts">
import { cn } from "@/utils/cn"; import { cn } from "@/utils/cn";
import { globals } from "@/globals";
import { page } from "$app/state"; import { page } from "$app/state";
import favoritesStore from "@/stores/favorites.store"; import favoritesStore from "@/stores/favorites.store";
@@ -10,6 +12,8 @@
import House from "@lucide/svelte/icons/house"; import House from "@lucide/svelte/icons/house";
import Heart from "@lucide/svelte/icons/heart"; import Heart from "@lucide/svelte/icons/heart";
import Cloud from "@lucide/svelte/icons/cloud"; import Cloud from "@lucide/svelte/icons/cloud";
import Submit from "@lucide/svelte/icons/send";
import Github from "@/components/logos/github.svelte";
let favorites = $derived($favoritesStore); let favorites = $derived($favoritesStore);
let favoritesCount = $derived(favoritesStore.getCount(favorites)); let favoritesCount = $derived(favoritesStore.getCount(favorites));
@@ -72,3 +76,19 @@
<Box size={16} /> <Box size={16} />
<p class="truncate">Extensions</p> <p class="truncate">Extensions</p>
</a> </a>
<a
href={globals.submitUrl}
target="_blank"
class={cn(sidebarItemClasses.base, "flex justify-start space-x-3 md:hidden")}
>
<Submit size={16} />
<p class="truncate">Submit SVG</p>
</a>
<a
href={globals.githubUrl}
target="_blank"
class={cn(sidebarItemClasses.base, "flex justify-start space-x-3 md:hidden")}
>
<Github size={16} />
<p class="truncate">GitHub Repository</p>
</a>
+3 -3
View File
@@ -9,10 +9,10 @@
<section> <section>
<aside <aside
class={cn( class={cn(
"fixed left-0 h-[calc(100vh-5rem)]", "md:fixed md:left-0 md:h-[calc(100vh-5rem)]",
"overflow-x-hidden", "overflow-x-hidden",
"w-54 pr-2 pl-3", "w-54 pr-2 pl-3",
"flex flex-col space-y-3", "hidden flex-col space-y-3 md:flex",
"bg-neutral-100 dark:bg-neutral-950", "bg-neutral-100 dark:bg-neutral-950",
)} )}
> >
@@ -24,7 +24,7 @@
<ShowCategories /> <ShowCategories />
</nav> </nav>
</aside> </aside>
<main class={cn("mr-4 mb-4 ml-56", "overflow-hidden")}> <main class={cn("mb-4 px-4 md:mr-4 md:ml-56 md:px-0", "overflow-hidden")}>
<slot /> <slot />
</main> </main>
</section> </section>
@@ -0,0 +1,42 @@
<script lang="ts">
import { cn } from "@/utils/cn";
import * as Sheet from "@/components/ui/sheet";
import { buttonVariants } from "@/components/ui/button";
import Separator from "@/components/ui/separator/separator.svelte";
import MenuIcon from "@lucide/svelte/icons/menu";
import Svgl from "@/components/logos/svgl.svelte";
import ShowCategories from "@/components/layout/showCategories.svelte";
import ShowSidebarLinks from "@/components/layout/showSidebarLinks.svelte";
interface Props {
className?: string;
}
let { className }: Props = $props();
</script>
<Sheet.Root>
<Sheet.Trigger
title="Open SVGL Menu"
class={cn(buttonVariants({ variant: "ghost", size: "icon" }), className)}
>
<MenuIcon class="size-5" />
<span class="sr-only">Open Menu</span>
</Sheet.Trigger>
<Sheet.Content class="gap-0.5" side="left">
<Sheet.Header>
<Sheet.Title class="flex items-center space-x-2">
<Svgl size={28} />
<h2 class="font-onest text-xl font-medium tracking-tight">svgl</h2>
</Sheet.Title>
</Sheet.Header>
<nav class="flex flex-col space-y-0.5 overflow-y-auto px-3 pb-3">
<ShowSidebarLinks />
<Separator orientation="horizontal" class="my-3" />
<ShowCategories />
</nav>
</Sheet.Content>
</Sheet.Root>
+18 -3
View File
@@ -1,17 +1,32 @@
<script lang="ts"> <script lang="ts">
import { onMount } from "svelte";
import { toggleMode } from "mode-watcher";
import SunIcon from "@lucide/svelte/icons/sun"; import SunIcon from "@lucide/svelte/icons/sun";
import MoonIcon from "@lucide/svelte/icons/moon"; import MoonIcon from "@lucide/svelte/icons/moon";
import { toggleMode } from "mode-watcher";
interface Props { interface Props {
className?: string; className?: string;
} }
let { className }: Props = $props(); let { className }: Props = $props();
const handleKeydown = (event: KeyboardEvent) => {
if (event.ctrlKey && event.key === "l") {
event.preventDefault();
toggleMode();
}
};
onMount(() => {
window.addEventListener("keydown", handleKeydown);
return () => {
window.removeEventListener("keydown", handleKeydown);
};
});
</script> </script>
<button class={className} onclick={toggleMode} title="Mode Toggle"> <button class={className} onclick={toggleMode} title="Mode Toggle (Cmd + l)">
<SunIcon <SunIcon
size={20} size={20}
strokeWidth={1.5} strokeWidth={1.5}
+8 -2
View File
@@ -1,8 +1,14 @@
<script> <script lang="ts">
import { PUBLIC_SVGL_VERSION } from "$env/static/public"; import { PUBLIC_SVGL_VERSION } from "$env/static/public";
import Badge from "@/components/ui/badge/badge.svelte"; import Badge from "@/components/ui/badge/badge.svelte";
interface Props {
className?: string;
}
let { className }: Props = $props();
</script> </script>
{#if PUBLIC_SVGL_VERSION} {#if PUBLIC_SVGL_VERSION}
<Badge variant="outline">{PUBLIC_SVGL_VERSION}</Badge> <Badge variant="outline" class={className}>{PUBLIC_SVGL_VERSION}</Badge>
{/if} {/if}
+13 -7
View File
@@ -1,11 +1,11 @@
<script lang="ts"> <script lang="ts">
import { Button } from "@/components/ui/button"; import { buttonVariants } from "@/components/ui/button";
import Shadcn from "@/components/logos/shadcn.svelte"; import Shadcn from "@/components/logos/shadcn.svelte";
import SelectPkgManager from "@/components/selectPkgManager.svelte"; import SelectPkgManager from "@/components/selectPkgManager.svelte";
import { pkgManager, type PackageManager } from "@/stores/pkgManager.store"; import { pkgManager, type PackageManager } from "@/stores/pkgManager.store";
import CodeBlock from "@/components/codeBlock.svelte"; import CodeBlock from "@/components/codeBlock.svelte";
import SetupShadcnRegistry from "@/components/svgs/setupShadcnRegistry.svelte"; import ArrowUpRightIcon from "@lucide/svelte/icons/arrow-up-right";
interface Props { interface Props {
svgTitle: string; svgTitle: string;
@@ -29,11 +29,17 @@
</script> </script>
<div class="flex items-center justify-between space-x-2"> <div class="flex items-center justify-between space-x-2">
<SetupShadcnRegistry> <a
<Button variant="outline" size="sm"> href="/docs/shadcn-ui"
<span>Setup Registry</span> target="_blank"
</Button> class={buttonVariants({ variant: "outline", size: "sm" })}
</SetupShadcnRegistry> >
<span>Setup Registry</span>
<ArrowUpRightIcon
size={14}
class="text-neutral-500 dark:text-neutral-400"
/>
</a>
<SelectPkgManager /> <SelectPkgManager />
</div> </div>
<CodeBlock code={`${shadcnCommand} @svgl/${svgFormatTitle}`} Icon={Shadcn} /> <CodeBlock code={`${shadcnCommand} @svgl/${svgFormatTitle}`} Icon={Shadcn} />
+1 -1
View File
@@ -114,7 +114,7 @@
</Dialog.Trigger> </Dialog.Trigger>
<Dialog.Content> <Dialog.Content>
<Dialog.Header> <Dialog.Header>
<Dialog.Title>Download {svgInfo.title} SVG</Dialog.Title> <Dialog.Title>Download {svgInfo.title} SVGs</Dialog.Title>
<Dialog.Description> <Dialog.Description>
This logo has multiple options to download: This logo has multiple options to download:
</Dialog.Description> </Dialog.Description>
@@ -1,38 +0,0 @@
<script lang="ts">
import type { Snippet } from "svelte";
import * as Dialog from "@/components/ui/dialog";
import CodeBlock from "@/components/codeBlock.svelte";
interface Props {
children: Snippet;
}
let { children }: Props = $props();
let registryCode = `
"registries": {
"@svgl": "https://svgl.app/r/{name}.json"
}
`;
</script>
<Dialog.Root>
<Dialog.Trigger>
{@render children()}
</Dialog.Trigger>
<Dialog.Content class="text-sm">
<Dialog.Header>
<Dialog.Title>Setup shadcn/ui registry</Dialog.Title>
<Dialog.Description>
Use the code below to configure the @svgl registry for your project.
</Dialog.Description>
</Dialog.Header>
<p>
1. Copy and paste the code into
<span class="font-mono">components.json</span>:
</p>
<CodeBlock code={registryCode} />
<p class="mt-2">2. Then use the following command to add SVGs:</p>
<CodeBlock code="npx shadcn@latest add @svgl/[svg-name]" />
</Dialog.Content>
</Dialog.Root>
+36
View File
@@ -0,0 +1,36 @@
import { Dialog as SheetPrimitive } from "bits-ui";
import Trigger from "./sheet-trigger.svelte";
import Close from "./sheet-close.svelte";
import Overlay from "./sheet-overlay.svelte";
import Content from "./sheet-content.svelte";
import Header from "./sheet-header.svelte";
import Footer from "./sheet-footer.svelte";
import Title from "./sheet-title.svelte";
import Description from "./sheet-description.svelte";
const Root = SheetPrimitive.Root;
const Portal = SheetPrimitive.Portal;
export {
Root,
Close,
Trigger,
Portal,
Overlay,
Content,
Header,
Footer,
Title,
Description,
//
Root as Sheet,
Close as SheetClose,
Trigger as SheetTrigger,
Portal as SheetPortal,
Overlay as SheetOverlay,
Content as SheetContent,
Header as SheetHeader,
Footer as SheetFooter,
Title as SheetTitle,
Description as SheetDescription,
};
@@ -0,0 +1,8 @@
<script lang="ts">
import { Dialog as SheetPrimitive } from "bits-ui";
let { ref = $bindable(null), ...restProps }: SheetPrimitive.CloseProps =
$props();
</script>
<SheetPrimitive.Close bind:ref data-slot="sheet-close" {...restProps} />
@@ -0,0 +1,45 @@
<script lang="ts">
import type { Snippet } from "svelte";
import type { WithoutChildrenOrChild } from "@/types/components";
import SheetOverlay from "./sheet-overlay.svelte";
import { sheetVariants, type Side } from "./sheet.variants";
import { cn } from "@/utils/cn";
import { Dialog as SheetPrimitive } from "bits-ui";
import XIcon from "@lucide/svelte/icons/x";
let {
ref = $bindable(null),
class: className,
side = "right",
portalProps,
children,
...restProps
}: WithoutChildrenOrChild<SheetPrimitive.ContentProps> & {
portalProps?: SheetPrimitive.PortalProps;
side?: Side;
children: Snippet;
} = $props();
</script>
<SheetPrimitive.Portal {...portalProps}>
<SheetOverlay />
<SheetPrimitive.Content
bind:ref
data-slot="sheet-content"
class={cn(sheetVariants({ side }), className)}
{...restProps}
>
{@render children?.()}
<SheetPrimitive.Close
class={cn(
"ring-offset-neutral-300 focus-visible:ring-neutral-300 dark:ring-offset-neutral-700 dark:focus-visible:ring-neutral-700",
"absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-hidden disabled:pointer-events-none",
)}
>
<XIcon class="size-4" />
<span class="sr-only">Close</span>
</SheetPrimitive.Close>
</SheetPrimitive.Content>
</SheetPrimitive.Portal>
@@ -0,0 +1,17 @@
<script lang="ts">
import { Dialog as SheetPrimitive } from "bits-ui";
import { cn } from "@/utils/cn";
let {
ref = $bindable(null),
class: className,
...restProps
}: SheetPrimitive.DescriptionProps = $props();
</script>
<SheetPrimitive.Description
bind:ref
data-slot="sheet-description"
class={cn("text-sm text-neutral-700 dark:text-neutral-300", className)}
{...restProps}
/>
@@ -0,0 +1,21 @@
<script lang="ts">
import type { HTMLAttributes } from "svelte/elements";
import type { WithElementRef } from "@/types/components";
import { cn } from "@/utils/cn";
let {
ref = $bindable(null),
class: className,
children,
...restProps
}: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
</script>
<div
bind:this={ref}
data-slot="sheet-footer"
class={cn("mt-auto flex flex-col gap-2 p-4", className)}
{...restProps}
>
{@render children?.()}
</div>
@@ -0,0 +1,21 @@
<script lang="ts">
import type { HTMLAttributes } from "svelte/elements";
import type { WithElementRef } from "@/types/components";
import { cn } from "@/utils/cn";
let {
ref = $bindable(null),
class: className,
children,
...restProps
}: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
</script>
<div
bind:this={ref}
data-slot="sheet-header"
class={cn("flex flex-col gap-1.5 p-4", className)}
{...restProps}
>
{@render children?.()}
</div>
@@ -0,0 +1,20 @@
<script lang="ts">
import { Dialog as SheetPrimitive } from "bits-ui";
import { cn } from "@/utils/cn";
let {
ref = $bindable(null),
class: className,
...restProps
}: SheetPrimitive.OverlayProps = $props();
</script>
<SheetPrimitive.Overlay
bind:ref
data-slot="sheet-overlay"
class={cn(
"fixed inset-0 z-50 bg-neutral-200/50 backdrop-blur-[4px] data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0 dark:bg-neutral-900/50",
className,
)}
{...restProps}
/>
@@ -0,0 +1,17 @@
<script lang="ts">
import { Dialog as SheetPrimitive } from "bits-ui";
import { cn } from "@/utils/cn";
let {
ref = $bindable(null),
class: className,
...restProps
}: SheetPrimitive.TitleProps = $props();
</script>
<SheetPrimitive.Title
bind:ref
data-slot="sheet-title"
class={cn("font-semibold text-neutral-950 dark:text-neutral-50", className)}
{...restProps}
/>
@@ -0,0 +1,8 @@
<script lang="ts">
import { Dialog as SheetPrimitive } from "bits-ui";
let { ref = $bindable(null), ...restProps }: SheetPrimitive.TriggerProps =
$props();
</script>
<SheetPrimitive.Trigger bind:ref data-slot="sheet-trigger" {...restProps} />
+22
View File
@@ -0,0 +1,22 @@
import { tv, type VariantProps } from "tailwind-variants";
const sheetVariants = tv({
base: "bg-white dark:bg-neutral-900 border-neutral-200 dark:border-neutral-800 data-[state=open]:animate-in data-[state=closed]:animate-out fixed z-50 flex flex-col gap-4 shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500",
variants: {
side: {
top: "data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top inset-x-0 top-0 h-auto border-b",
bottom:
"data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom inset-x-0 bottom-0 h-auto border-t",
left: "data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left inset-y-0 left-0 h-full w-3/4 border-r sm:max-w-sm",
right:
"data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right inset-y-0 right-0 h-full w-3/4 border-l sm:max-w-sm",
},
},
defaultVariants: {
side: "left",
},
});
type Side = VariantProps<typeof sheetVariants>["side"];
export { sheetVariants, type Side };
+12
View File
@@ -24,6 +24,18 @@ export const extensions: Extension[] = [
socialUrl: "https://x.com/ridemountainpig", socialUrl: "https://x.com/ridemountainpig",
}, },
}, },
{
name: "SVGL for Framer",
description:
"Import colorful SVG logos, fast and easy using our plugin for Framer.",
url: "https://www.framer.com/marketplace/plugins/svgl/",
image:
"https://raw.githubusercontent.com/pheralb/svgl/refs/heads/main/static/library/framer.svg",
created_by: {
name: "Krishna Singh",
socialUrl: "https://x.com/krishnasinghdev",
},
},
{ {
name: "SVGL for Vue", name: "SVGL for Vue",
description: "An open-source NPM package that offers a SVGL Logos for Vue.", description: "An open-source NPM package that offers a SVGL Logos for Vue.",
+13 -6
View File
@@ -2323,12 +2323,6 @@ export const svgs: iSVG[] = [
url: "https://www.webflow.com", url: "https://www.webflow.com",
brandUrl: "https://brand-at.webflow.io/resources", brandUrl: "https://brand-at.webflow.io/resources",
}, },
{
title: "Sanity",
category: "CMS",
route: "/library/sanity.svg",
url: "https://www.sanity.io",
},
{ {
title: "sky", title: "sky",
category: "Entertainment", category: "Entertainment",
@@ -3865,4 +3859,17 @@ export const svgs: iSVG[] = [
url: "https://ahrefs.com/", url: "https://ahrefs.com/",
brandUrl: "https://ahrefs.com/logo", brandUrl: "https://ahrefs.com/logo",
}, },
{
title: "Sanity",
category: "CMS",
route: {
dark: "/library/sanity-dark.svg",
light: "/library/sanity-light.svg",
},
wordmark: {
dark: "/library/sanity-wordmark-dark.svg",
light: "/library/sanity-wordmark-light.svg",
},
url: "https://www.sanity.io",
},
]; ];
+42
View File
@@ -0,0 +1,42 @@
---
title: shadcn/ui Registry
description: How to use shadcn/ui to add SVGs to your project.
---
## shadcn/ui Registry
SVGL v5 support [shadcn/ui](https://ui.shadcn.com/) registry, so you can easily add SVGs to your project using their CLI. Add the registry config once and you will be able to install any SVG in `.tsx` using `npm`, `yarn`, `bun` or `pnpm`.
## Add registry
Add the SVGL registry to your `components.json` file:
```json
{
"registries": {
"@svgl": "https://svgl.app/r/{name}.json"
}
}
```
[shadcn/ui Namespaces](https://ui.shadcn.com/docs/registry/namespace) documentation.
## Usage
Add SVGs using the [shadcn/ui CLI](https://ui.shadcn.com/docs/cli/installation):
```bash
npx shadcn@latest add @svgl/sanity
# or
pnpm dlx shadcn@latest add @svgl/sanity
# or
yarn dlx shadcn@latest add @svgl/sanity
# or
bunx shadcn@latest add @svgl/sanity
```
Add multiple SVGs at once:
```bash
pnpm dlx shadcn@latest add @svgl/sanity @svgl/github @svgl/supabase @svgl/vercel
```
+5 -2
View File
@@ -7,6 +7,9 @@
import Container from "@/components/container.svelte"; import Container from "@/components/container.svelte";
import FileText from "@lucide/svelte/icons/file-text"; import FileText from "@lucide/svelte/icons/file-text";
// Markdown:
import "@/styles/markdown.css";
let { data }: PageProps = $props(); let { data }: PageProps = $props();
const document = $derived(data.document); const document = $derived(data.document);
</script> </script>
@@ -18,7 +21,7 @@
<PageCard <PageCard
containerClass="mt-0" containerClass="mt-0"
contentCardClass="max-h-[calc(100vh-5.2rem)] min-h-[calc(100vh-5.2rem)]" contentCardClass="max-h-[calc(100vh-5rem)] min-h-[calc(100vh-5rem)]"
> >
<PageHeader> <PageHeader>
<div <div
@@ -31,6 +34,6 @@
</div> </div>
</PageHeader> </PageHeader>
<Container className="my-6"> <Container className="my-6">
<article>{@html document.html}</article> <article class="markdown">{@html document.html}</article>
</Container> </Container>
</PageCard> </PageCard>
+4 -2
View File
@@ -11,8 +11,10 @@ import githubLight from "@shikijs/themes/github-light";
import githubDark from "@shikijs/themes/github-dark"; import githubDark from "@shikijs/themes/github-dark";
// Languages: // Languages:
import html from "@shikijs/langs/html";
import ts from "@shikijs/langs/ts"; import ts from "@shikijs/langs/ts";
import bash from "@shikijs/langs/bash"; import bash from "@shikijs/langs/bash";
import json from "@shikijs/langs/json";
let jsEngine: RegexEngine | null = null; let jsEngine: RegexEngine | null = null;
let highlighter: Promise<HighlighterCore> | null = null; let highlighter: Promise<HighlighterCore> | null = null;
@@ -29,13 +31,13 @@ const rehypeShikiOptions: RehypeShikiOptions = {
light: "github-light", light: "github-light",
dark: "github-dark", dark: "github-dark",
}, },
langs: [bash, ts], langs: [bash, ts, json, html],
}; };
const shikiHighlighter = async (): Promise<HighlighterCore> => { const shikiHighlighter = async (): Promise<HighlighterCore> => {
highlighter ??= createHighlighterCore({ highlighter ??= createHighlighterCore({
themes: [githubLight, githubDark], themes: [githubLight, githubDark],
langs: [bash, ts], langs: [bash, ts, json, html],
engine: getShikiEngine(), engine: getShikiEngine(),
}); });
return highlighter; return highlighter;
+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="1em" fill="none" viewBox="0 0 192 192"><path fill="#fff" d="m160.077 112.697-5.212-9.068-25.206 15.352 27.996-35.644 4.233-2.484-1.047-1.573 1.923-2.457-8.835-7.353-4.043 5.153-81.62 47.752 30.177-36.29 56.208-30.81-5.34-10.322-30.615 16.775 15.075-18.118-8.637-7.61-33.928 40.797-33.698 18.48 25.799-34.106 16.166-8.414-5.134-10.438L47.24 66.836l12.844-16.995-8.972-7.186L24 78.538l.42.336 5.066 10.314 30.057-15.653-27.396 36.21 4.49 3.597 2.67 5.162 31.646-17.35-34.848 41.911 8.637 7.609 1.734-2.086 84.067-49.343-27.911 35.547.456.38-.043.027 5.786 10.066 37.123-22.616-14.295 23.067L141.24 152 164 115.278l-3.923-2.581Z"/></svg>

After

Width:  |  Height:  |  Size: 682 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="1em" fill="none" viewBox="0 0 192 192"><path fill="#0D0E12" d="m160.077 112.697-5.212-9.068-25.206 15.352 27.996-35.644 4.233-2.484-1.047-1.573 1.923-2.457-8.835-7.353-4.043 5.153-81.62 47.752 30.177-36.29 56.208-30.81-5.34-10.322-30.615 16.775 15.075-18.118-8.637-7.61-33.928 40.797-33.698 18.48 25.799-34.106 16.166-8.414-5.134-10.438L47.24 66.836l12.844-16.995-8.972-7.186L24 78.538l.42.336 5.066 10.314 30.057-15.653-27.396 36.21 4.49 3.597 2.67 5.162 31.646-17.35-34.848 41.911 8.637 7.609 1.734-2.086 84.067-49.343-27.911 35.547.456.38-.043.027 5.786 10.066 37.123-22.616-14.295 23.067L141.24 152 164 115.278l-3.923-2.581Z"/></svg>

After

Width:  |  Height:  |  Size: 685 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="1em" fill="none" viewBox="0 0 435 154"><path fill="white" d="M44.883 52.446c-11.465-8.649-23.07-15.344-23.07-25.108 0-5.856 5.17-11.853 12.305-11.853 12.865 0 20.412 13.39 27.824 30.125h4.612V7.112h-32.16C7.83 7.112 0 23.154 0 35.705c0 16.46 13.565 26.224 28.942 37.66 10.764 7.95 19.853 15.344 19.853 23.853 0 9.206-6.294 14.505-14.265 14.505-8.53 0-21.112-11.161-29.924-34.31H0v42.683h36.777c22.653 0 33.977-17.856 34.395-32.22.558-16.735-13.842-26.082-26.289-35.43ZM145.002 106.841V61.788c0-19.528-12.165-24.686-29.783-24.686H83.895l.141 31.803h5.171c5.453-13.53 13.283-23.43 21.671-23.43 7.271 0 10.488 6.279 10.488 12.833v6.138c-11.747 6.977-43.065 12.833-43.065 34.033 0 12.275 8.53 22.456 20.977 22.456 10.765 0 18.176-6.977 21.953-15.203.7 6.836 5.171 14.364 15.383 14.364h16.082v-6.138c-5.171 0-7.688-3.485-7.688-7.111l-.006-.006Zm-24.053-6.977c-2.236 3.21-5.736 6.836-9.93 6.836-5.871 0-9.647-4.466-9.647-13.39 0-10.181 13.7-16.735 19.577-21.617V99.87v-.006ZM270.145 28.453c8.947 0 14.541-6.279 14.541-14.364C284.686 6.002 279.092 0 270.145 0s-14.683 5.997-14.683 14.088c0 8.092 6.012 14.365 14.683 14.365ZM409.135 37.102v6.138c8.812 0 11.324 4.6 6.994 17.016l-10.488 28.312-13.424-34.45c-3.076-6.695-1.4-10.878 5.035-10.878v-6.138h-66.695V9.207h-6.294c-1.817 9.482-11.747 27.895-28.665 27.895v6.138h10.906v57.328c0 9.623 3.218 20.502 21.953 20.502h29.083V89.548h-5.17c-2.101 7.394-6.43 22.175-15.801 22.175-5.17 0-6.012-5.721-6.012-10.322V45.886h26.707c3.217 0 6.57.417 8.247 4.325l28.383 70.02c-5.453 12.416-14.824 14.364-31.601 9.206v24.551c4.336 0 15.518.141 17.477-.416 11.047-3.21 18.594-24.827 21.671-33.194l24.047-64.857c2.659-7.112 4.894-12.275 9.506-12.275v-6.138h-25.865l.006-.006ZM237.703 106.841V59.276c0-14.921-7.129-23.852-21.253-23.852-12.441 0-19.647 8.608-25.171 16.617V37.096h-31.883v6.138c5.453 0 7.83 3.344 7.83 7.252v56.349c0 3.767-2.794 7.112-7.83 7.112v6.137h39.713v-6.137c-5.036 0-7.83-3.345-7.83-7.112V59.646c3.224-4.272 6.935-8.878 13.141-8.878 5.871 0 9.23 4.741 9.23 10.462v45.611c0 3.767-2.794 7.111-7.83 7.111v6.138h39.713v-6.138c-5.036 0-7.83-3.344-7.83-7.111ZM284.127 106.841V37.102h-31.882v6.138c5.453 0 7.829 3.344 7.829 7.252v56.349c0 3.767-2.794 7.111-7.829 7.111v6.138h39.712v-6.138c-5.035 0-7.83-3.344-7.83-7.111Z"/></svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="1em" fill="none" viewBox="0 0 435 154"><path fill="#0D0E12" d="M44.883 52.446c-11.465-8.649-23.07-15.344-23.07-25.108 0-5.856 5.17-11.853 12.305-11.853 12.865 0 20.412 13.39 27.824 30.125h4.612V7.112h-32.16C7.83 7.112 0 23.154 0 35.705c0 16.46 13.565 26.224 28.942 37.66 10.764 7.95 19.853 15.344 19.853 23.853 0 9.206-6.294 14.505-14.265 14.505-8.53 0-21.112-11.161-29.924-34.31H0v42.683h36.777c22.653 0 33.977-17.856 34.395-32.22.558-16.735-13.842-26.082-26.289-35.43ZM145.002 106.841V61.788c0-19.528-12.165-24.686-29.783-24.686H83.895l.141 31.803h5.171c5.453-13.53 13.283-23.43 21.671-23.43 7.271 0 10.488 6.279 10.488 12.833v6.138c-11.747 6.977-43.065 12.833-43.065 34.033 0 12.275 8.53 22.456 20.977 22.456 10.765 0 18.176-6.977 21.953-15.203.7 6.836 5.171 14.364 15.383 14.364h16.082v-6.138c-5.171 0-7.688-3.485-7.688-7.111l-.006-.006Zm-24.053-6.977c-2.236 3.21-5.736 6.836-9.93 6.836-5.871 0-9.647-4.466-9.647-13.39 0-10.181 13.7-16.735 19.577-21.617V99.87v-.006ZM270.145 28.453c8.947 0 14.541-6.279 14.541-14.364C284.686 6.002 279.092 0 270.145 0s-14.683 5.997-14.683 14.088c0 8.092 6.012 14.365 14.683 14.365ZM409.135 37.102v6.138c8.812 0 11.324 4.6 6.994 17.016l-10.488 28.312-13.424-34.45c-3.076-6.695-1.4-10.878 5.035-10.878v-6.138h-66.695V9.207h-6.294c-1.817 9.482-11.747 27.895-28.665 27.895v6.138h10.906v57.328c0 9.623 3.218 20.502 21.953 20.502h29.083V89.548h-5.17c-2.101 7.394-6.43 22.175-15.801 22.175-5.17 0-6.012-5.721-6.012-10.322V45.886h26.707c3.217 0 6.57.417 8.247 4.325l28.383 70.02c-5.453 12.416-14.824 14.364-31.601 9.206v24.551c4.336 0 15.518.141 17.477-.416 11.047-3.21 18.594-24.827 21.671-33.194l24.047-64.857c2.659-7.112 4.894-12.275 9.506-12.275v-6.138h-25.865l.006-.006ZM237.703 106.841V59.276c0-14.921-7.129-23.852-21.253-23.852-12.441 0-19.647 8.608-25.171 16.617V37.096h-31.883v6.138c5.453 0 7.83 3.344 7.83 7.252v56.349c0 3.767-2.794 7.112-7.83 7.112v6.137h39.713v-6.137c-5.036 0-7.83-3.345-7.83-7.112V59.646c3.224-4.272 6.935-8.878 13.141-8.878 5.871 0 9.23 4.741 9.23 10.462v45.611c0 3.767-2.794 7.111-7.83 7.111v6.138h39.713v-6.138c-5.036 0-7.83-3.344-7.83-7.111ZM284.127 106.841V37.102h-31.882v6.138c5.453 0 7.829 3.344 7.829 7.252v56.349c0 3.767-2.794 7.111-7.829 7.111v6.138h39.712v-6.138c-5.035 0-7.83-3.344-7.83-7.111Z"/></svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

-1
View File
@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="104" preserveAspectRatio="xMidYMid" viewBox="0 0 512 104"><path fill="#F37368" d="M381.462 36.986v64.834h-20.886V26.833z"/><path fill="#F7A199" d="m85.865 89.781 15.665 13.634 65.994-34.375-6.817-16.39-74.842 37.131Zm274.71-41.772 53.086-27.558-8.992-15.52-44.093 21.902v21.176Z"/><path fill="#F37368" d="M211.182 31.91v69.91h-20.016V2.176l20.016 29.733ZM85.865 89.78l15.665 13.634 30.169-75.422-9.718-25.817L85.865 89.78Z"/><path fill="#F04939" d="M121.98 2.176h20.597l38.146 99.644h-21.176L121.98 2.176Zm92.248 0L258.176 70.2v31.619l-67.01-99.644h23.062Zm81.659 0h20.74v99.644h-20.74V2.176Zm64.689 18.275h-31.91V2.176h74.407l10.588 18.275H360.576Z"/><path fill="#F7A199" d="M475.014 63.964v37.856h-20.596V63.964"/><path fill="#F04939" d="m489.228 2.176-34.81 61.788h20.596L511.13 2.176z"/><path fill="#F37368" d="m454.418 63.964-35.97-61.788h22.626l24.222 42.352z"/><path fill="#F04939" d="M8.558 13.779c0 13.78 8.557 22.046 25.672 26.398l18.13 4.206c16.245 3.771 26.108 13.054 26.108 28.138.145 6.527-2.03 12.909-5.947 18.13 0-15.084-7.832-23.206-26.543-28.138l-17.84-4.06C13.78 55.26 2.756 47.572 2.756 31.183c0-6.237 2.03-12.474 5.802-17.405"/><path fill="#F37368" d="M258.176 65.124V2.176h20.016v99.644h-20.016zM61.353 68.75c7.687 4.932 11.168 11.894 11.168 21.902-6.527 8.267-17.695 12.763-30.894 12.763-22.191 0-38-11.023-41.337-30.023h21.321c2.756 8.702 10.008 12.763 19.871 12.763 11.749.145 19.726-6.237 19.871-17.405M8.558 13.634C14.794 5.512 25.528.58 38.58.58c22.772 0 35.826 12.039 39.162 28.864H57.147c-2.32-6.672-7.978-11.894-18.276-11.894-11.168.145-18.71 6.527-19.145 16.68-7.474-4.122-11.459-12.184-11.168-20.596Z"/></svg>

Before

Width:  |  Height:  |  Size: 1.7 KiB