Code Snippet
optics/code-snippetFreeComponent
A code snippet component with tabs and copy functionality.
See it running
Open the demo on optics
optics.agusmayol.com.ar/components/code-snippetInstall it
npx shadcn@latest add https://optics.agusmayol.com.ar/r/code-snippet.jsonSource
1"use client";23import { CheckIcon, CopyIcon } from "lucide-react";4import { useState } from "react";5import { Button } from "@/registry/optics/button";6import { useRender } from "@base-ui/react/use-render";7import { mergeProps } from "@base-ui/react/merge-props";8import {9 Tabs,10 TabsContent,11 TabsContents,12 TabsList,13 TabsTrigger,14} from "@/registry/optics/tabs";15import { ScrollArea } from "@/registry/optics/scroll-area";16import { cn } from "@/registry/optics/lib/utils";1718export const Snippet = ({ className = "", ...props }) => (19 <Tabs20 className={cn(21 "group w-full gap-0 overflow-hidden rounded-md border border-input",22 className,23 )}24 {...props}25 />26);2728export const SnippetHeader = ({ className = "", ...props }) => (29 <div30 className={cn(31 "flex flex-row items-center justify-between border-b bg-secondary p-1",32 className,33 )}34 {...props}35 />36);3738export const SnippetCopyButton = ({39 render = undefined,40 value = "",41 onCopy = undefined,42 onError = undefined,43 timeout = 2000,44 ...props45}) => {46 const [isCopied, setIsCopied] = useState(false);4748 const copyToClipboard = async () => {49 if (typeof window === "undefined" || !value) return;5051 try {52 // Try modern clipboard API first53 if (navigator.clipboard?.writeText) {54 await navigator.clipboard.writeText(value);55 } else {56 // Fallback for iOS and older browsers57 const textArea = document.createElement("textarea");58 textArea.value = value;59 textArea.style.position = "fixed";60 textArea.style.opacity = "0";61 document.body.appendChild(textArea);62 textArea.select();63 document.execCommand("copy");64 document.body.removeChild(textArea);65 }66 setIsCopied(true);67 onCopy?.();68 setTimeout(() => setIsCopied(false), timeout);69 } catch (error) {70 onError?.(error);71 }72 };7374 const buttonContent = (75 <>76 <div className="relative">77 <div78 className={cn(79 "absolute inset-0 flex items-center justify-center transition-all duration-300 ease-in-out will-change-[transform,opacity,filter]",80 isCopied81 ? "scale-100 opacity-100 blur-0"82 : "blur-xs scale-[0.25] opacity-0",83 )}84 >85 <CheckIcon className="text-muted-foreground" size={14} />86 </div>87 <div88 className={cn(89 "transition-[transform, opacity, filter] duration-300 ease-in-out will-change-[transform,opacity,filter]",90 isCopied91 ? "blur-xs scale-[0.25] opacity-0"92 : "scale-100 opacity-100 blur-0",93 )}94 >95// … truncated
What it pulls in
npm packages
Other registry items
Files it writes
More from optics
All 79 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Accordionaccordion | optics | Components | Free | 5 deps | |
| Alertalert | optics | Components | Free | 4 deps | |
| Alert Dialogalert-dialog | optics | Components | Free | 4 deps | |
| Aspect Ratioaspect-ratio | optics | Components | Free | 2 deps | |
| Auto Heightauto-height | optics | Components | Free | 3 deps | |
| Avataravatar | optics | Components | Free | 3 deps | |
| Badgebadge | optics | Components | Free | 4 deps | |
| Breadcrumbbreadcrumb | optics | Components | Free | 4 deps |
