Update domain page UI
This commit is contained in:
97
packages/ui/src/code.tsx
Normal file
97
packages/ui/src/code.tsx
Normal file
@@ -0,0 +1,97 @@
|
||||
import { Light as SyntaxHighlighter } from "react-syntax-highlighter";
|
||||
import js from "react-syntax-highlighter/dist/esm/languages/hljs/javascript";
|
||||
import ruby from "react-syntax-highlighter/dist/esm/languages/hljs/ruby";
|
||||
import php from "react-syntax-highlighter/dist/esm/languages/hljs/php";
|
||||
import python from "react-syntax-highlighter/dist/esm/languages/hljs/python";
|
||||
// import { nightOwl } from "react-syntax-highlighter/dist/esm/styles/hljs";
|
||||
import codeTheme from "../code-theme";
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "./tabs";
|
||||
import { Button } from "./button";
|
||||
import { ClipboardCopy, Check } from "lucide-react";
|
||||
import { useState } from "react";
|
||||
|
||||
type Language = "js" | "ruby" | "php" | "python";
|
||||
|
||||
type CodeProps = {
|
||||
codeBlocks: {
|
||||
language: Language;
|
||||
code: string;
|
||||
display?: string;
|
||||
}[];
|
||||
};
|
||||
|
||||
SyntaxHighlighter.registerLanguage("js", js);
|
||||
SyntaxHighlighter.registerLanguage("ruby", ruby);
|
||||
SyntaxHighlighter.registerLanguage("php", php);
|
||||
SyntaxHighlighter.registerLanguage("python", python);
|
||||
|
||||
export const Code: React.FC<CodeProps> = ({ codeBlocks }) => {
|
||||
const [selectedTab, setSelectedTab] = useState(
|
||||
codeBlocks[0]?.language ?? "js"
|
||||
);
|
||||
const [isCopied, setIsCopied] = useState(false);
|
||||
|
||||
const copyToClipboard = async (code: string) => {
|
||||
try {
|
||||
await navigator.clipboard.writeText(code);
|
||||
setIsCopied(true);
|
||||
setTimeout(() => setIsCopied(false), 2000); // Reset the icon back to clipboard after 2 seconds
|
||||
} catch (err) {
|
||||
alert("Failed to copy code");
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="rounded-md bg-background border">
|
||||
<Tabs
|
||||
defaultValue={codeBlocks[0]?.language}
|
||||
onValueChange={(val) => setSelectedTab(val as Language)}
|
||||
>
|
||||
<div className="flex justify-between items-center border-b py-1 px-2">
|
||||
<TabsList className="w-full rounded-none justify-start bg-transparent h-12">
|
||||
<div className="">
|
||||
{codeBlocks.map((block) => (
|
||||
<TabsTrigger
|
||||
key={block.language}
|
||||
value={block.language}
|
||||
className="data-[state=active]:bg-accent py-0.5 px-4"
|
||||
>
|
||||
{block.language}
|
||||
</TabsTrigger>
|
||||
))}
|
||||
</div>
|
||||
</TabsList>
|
||||
<Button
|
||||
size="icon"
|
||||
variant="icon"
|
||||
onClick={() =>
|
||||
copyToClipboard(
|
||||
codeBlocks.find((block) => block.language === selectedTab)
|
||||
?.code || ""
|
||||
)
|
||||
}
|
||||
>
|
||||
{isCopied ? (
|
||||
<Check className="h-4 w-4" />
|
||||
) : (
|
||||
<ClipboardCopy className="h-4 w-4" />
|
||||
)}
|
||||
</Button>
|
||||
</div>
|
||||
{codeBlocks.map((block) => (
|
||||
<TabsContent
|
||||
key={block.language}
|
||||
value={block.language}
|
||||
className="py-2"
|
||||
>
|
||||
<div className="overflow-auto max-w-[38rem] h-[20rem]">
|
||||
<SyntaxHighlighter language={block.language} style={codeTheme}>
|
||||
{block.code}
|
||||
</SyntaxHighlighter>
|
||||
</div>
|
||||
</TabsContent>
|
||||
))}
|
||||
</Tabs>
|
||||
</div>
|
||||
);
|
||||
};
|
55
packages/ui/src/tabs.tsx
Normal file
55
packages/ui/src/tabs.tsx
Normal file
@@ -0,0 +1,55 @@
|
||||
"use client";
|
||||
|
||||
import * as React from "react";
|
||||
import * as TabsPrimitive from "@radix-ui/react-tabs";
|
||||
|
||||
import { cn } from "../lib/utils";
|
||||
|
||||
const Tabs = TabsPrimitive.Root;
|
||||
|
||||
const TabsList = React.forwardRef<
|
||||
React.ElementRef<typeof TabsPrimitive.List>,
|
||||
React.ComponentPropsWithoutRef<typeof TabsPrimitive.List>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<TabsPrimitive.List
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"inline-flex h-10 items-center justify-center rounded-md bg-muted p-1 text-muted-foreground",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
TabsList.displayName = TabsPrimitive.List.displayName;
|
||||
|
||||
const TabsTrigger = React.forwardRef<
|
||||
React.ElementRef<typeof TabsPrimitive.Trigger>,
|
||||
React.ComponentPropsWithoutRef<typeof TabsPrimitive.Trigger>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<TabsPrimitive.Trigger
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
TabsTrigger.displayName = TabsPrimitive.Trigger.displayName;
|
||||
|
||||
const TabsContent = React.forwardRef<
|
||||
React.ElementRef<typeof TabsPrimitive.Content>,
|
||||
React.ComponentPropsWithoutRef<typeof TabsPrimitive.Content>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<TabsPrimitive.Content
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
TabsContent.displayName = TabsPrimitive.Content.displayName;
|
||||
|
||||
export { Tabs, TabsList, TabsTrigger, TabsContent };
|
Reference in New Issue
Block a user