chadtmiller.com/pds.js
An atproto PDS in JavaScript, for Cloudflare Workers and Node
0
0
import { CheckIcon, CopyIcon } from 'lucide-react';
import { useState } from 'react';
import { Button } from '#/components/atoms/button.jsx';
import { cn } from '#/lib/utils.js';
/**
* A shell command with a copy button beside it. The command is what a reader
* came for, so it reads in full where there is room and truncates where there
* is not. `lines` draws several commands as one block, each on its own
* line, and copies them joined by newlines the way a shell takes them.
* @param {{command?: string, lines?: string[], label?: string, className?: string}} props
*/
export function CopyCommand({ command, lines, label, className }) {
const [copied, setCopied] = useState(false);
const text = lines ? lines.join('\n') : (command ?? '');
const copy = async () => {
await navigator.clipboard.writeText(text);
setCopied(true);
setTimeout(() => setCopied(false), 1600);
};
if (lines) {
return (
<div
className={cn(
'relative rounded-lg border border-border bg-muted',
className,
)}
>
<pre className="overflow-x-auto px-4 py-3 pr-14 font-mono text-[12.5px] text-foreground leading-relaxed">
{text}
</pre>
<Button
variant="outline"
size="icon-sm"
aria-label={label ?? 'Copy these commands'}
onClick={copy}
className="absolute top-2 right-2"
>
{copied ? <CheckIcon /> : <CopyIcon />}
</Button>
</div>
);
}
return (
<div className={cn('flex min-w-0 items-center gap-1.5', className)}>
<code className="min-w-0 flex-1 truncate rounded-lg border border-border bg-muted px-2.5 py-1.5 font-mono text-[11.5px] text-muted-foreground">
{text}
</code>
<Button
variant="outline"
size="icon-sm"
aria-label={label ?? `Copy ${text}`}
onClick={copy}
>
{copied ? <CheckIcon /> : <CopyIcon />}
</Button>
</div>
);
}