🛠️ Create codeBlock UI component + setup shadcn/ui registry

This commit is contained in:
pheralb
2025-08-31 13:43:17 +01:00
parent 26b8f0a2ae
commit 73bd5a4f78
3 changed files with 119 additions and 20 deletions
+71
View File
@@ -0,0 +1,71 @@
<script lang="ts">
import type { Component, Snippet, SvelteComponent } from "svelte";
import { cn } from "@/utils/cn";
import CopyIcon from "@lucide/svelte/icons/copy";
import CheckIcon from "@lucide/svelte/icons/check";
import { clipboard } from "@/utils/clipboard";
interface Props {
code: string;
className?: string;
Icon?: Component;
copyDuration?: number;
}
let { Icon, className, code, copyDuration = 2000 }: Props = $props();
let copied = $state(false);
let timeoutId: ReturnType<typeof setTimeout> | null = null;
const handleCopy = async () => {
try {
await clipboard(code);
if (timeoutId) {
clearTimeout(timeoutId);
}
copied = true;
timeoutId = setTimeout(() => {
copied = false;
timeoutId = null;
}, copyDuration);
} catch (error) {
copied = false;
}
};
$effect(() => {
return () => {
if (timeoutId) {
clearTimeout(timeoutId);
}
};
});
</script>
<div
class={cn(
"relative flex items-center space-x-2 rounded-md border border-neutral-200 p-2.5 dark:border-neutral-800",
className,
)}
>
<button
class="absolute right-2 transition-colors hover:text-neutral-600 dark:hover:text-neutral-400"
onclick={handleCopy}
disabled={copied}
title={copied ? "Copied" : "Copy code"}
>
{#if copied}
<CheckIcon size={14} />
{:else}
<CopyIcon size={14} />
{/if}
</button>
{#if Icon}
<Icon size={14} class="text-neutral-500" />
{/if}
<code class="pr-8 font-mono text-sm select-all">
{code}
</code>
</div>
+10 -20
View File
@@ -1,11 +1,11 @@
<script lang="ts">
import { clipboard } from "@/utils/clipboard";
import CopyIcon from "@lucide/svelte/icons/copy";
import { Button } from "@/components/ui/button";
import Shadcn from "@/components/logos/shadcn.svelte";
import SelectPkgManager from "@/components/selectPkgManager.svelte";
import { pkgManager, type PackageManager } from "@/stores/pkgManager.store";
import Shadcn from "../logos/shadcn.svelte";
import CodeBlock from "@/components/codeBlock.svelte";
import SetupShadcnRegistry from "@/components/svgs/setupShadcnRegistry.svelte";
interface Props {
svgTitle: string;
@@ -26,24 +26,14 @@
.toLowerCase()
.replace(/\s+/g, "-")
.replace(/[^a-z0-9-]/g, "");
const handleCopy = () => {
clipboard(`${shadcnCommand} @svgl/${svgFormatTitle}`);
};
</script>
<div class="flex items-center justify-between space-x-2">
<SetupShadcnRegistry>
<Button variant="outline" size="sm">
<span>Setup Registry</span>
</Button>
</SetupShadcnRegistry>
<SelectPkgManager />
<Button variant="outline" onclick={handleCopy} size="sm">
<CopyIcon size={14} />
<span>Copy</span>
</Button>
</div>
<div
class="flex items-center space-x-2 rounded-md border border-neutral-200 p-2.5 dark:border-neutral-800"
>
<Shadcn size={14} />
<code class="font-mono text-sm select-all">
{shadcnCommand} @svgl/{svgFormatTitle}
</code>
</div>
<CodeBlock code={`${shadcnCommand} @svgl/${svgFormatTitle}`} Icon={Shadcn} />
@@ -0,0 +1,38 @@
<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>