SPB Git forge
38commits 1branches 0releases
338.7 MBsize
maindefault branch
5 h agolast push
HTML 53.9% TypeScript 44.5% JavaScript 0.6% SQL 0.5%
2.0 KB · 49 lines tsx
Raw Blame History
1"use client";23import { Check, Copy } from "lucide-react";4import { useState } from "react";5import { Tab, TabList, TabPanel, Tabs } from "@/components/ui/tabs";67const LANGS = [8  { key: "curl", label: "curl" },9  { key: "js", label: "JavaScript" },10  { key: "python", label: "Python" },11] as const;1213/** curl / JS / Python example tabs with a copy button; the pre scrolls inside its box, never the page. */14export function CodeTabs({ example, id }: { example: { curl: string; js: string; python: string }; id: string }) {15  const [tab, setTab] = useState<string>("curl");16  const [copied, setCopied] = useState(false);17  const text = example[tab as keyof typeof example] ?? example.curl;18  const copy = async () => {19    try {20      await navigator.clipboard.writeText(text);21      setCopied(true);22      setTimeout(() => setCopied(false), 1800);23    } catch {24      window.prompt("Copy", text);25    }26  };27  return (28    <Tabs value={tab} onValueChange={setTab} className="min-w-0">29      <div className="flex items-end justify-between gap-2">30        <TabList label={`Code examples for ${id}`} className="min-w-0 flex-1">31          {LANGS.map((l) => (32            <Tab key={l.key} value={l.key} className="h-10 min-w-[44px] text-[12px] sm:h-9">33              {l.label}34            </Tab>35          ))}36        </TabList>37        <button type="button" onClick={() => void copy()} className="inline-flex h-10 shrink-0 items-center gap-1 rounded-sm border border-hair px-2.5 text-[11.5px] text-ink-2 hover:bg-surface-2 hover:text-ink sm:h-9" aria-label={`Copy ${tab} example`}>38          {copied ? <Check className="size-3.5 text-ok" aria-hidden /> : <Copy className="size-3.5" aria-hidden />} {copied ? "Copied" : "Copy"}39        </button>40      </div>41      {LANGS.map((l) => (42        <TabPanel key={l.key} value={l.key} className="pt-2">43          <pre className="figure max-w-full overflow-x-auto whitespace-pre rounded-sm border border-hair bg-surface-2 px-3 py-2.5 text-[12px] leading-relaxed text-ink-2">{example[l.key]}</pre>44        </TabPanel>45      ))}46    </Tabs>47  );48}49