headplane/app/components/Attribute.tsx

68 lines
1.6 KiB
TypeScript
Raw Normal View History

2025-02-01 18:11:33 -05:00
import { Check, Copy } from 'lucide-react';
import cn from '~/utils/cn';
2025-01-28 16:06:41 -05:00
import toast from '~/utils/toast';
2024-03-26 09:28:52 -04:00
2025-02-01 18:11:33 -05:00
export interface AttributeProps {
2024-12-31 10:30:14 +05:30
name: string;
value: string;
isCopyable?: boolean;
link?: string;
2024-03-26 09:28:52 -04:00
}
2025-02-01 18:11:33 -05:00
export default function Attribute({
name,
value,
link,
isCopyable,
}: AttributeProps) {
2024-03-26 09:28:52 -04:00
return (
2025-02-01 18:11:33 -05:00
<dl className="flex items-center w-full gap-x-1">
<dt className="font-semibold w-1/4 shrink-0 text-sm">
{link ? (
<a className="hover:underline" href={link}>
{name}
</a>
2024-12-31 10:30:14 +05:30
) : (
name
)}
2024-03-26 09:28:52 -04:00
</dt>
2025-02-01 18:11:33 -05:00
<dd
className={cn(
'rounded-lg truncate w-full px-2.5 py-1 text-sm',
'flex items-center gap-x-1',
'focus-within:outline-none focus-within:ring-2',
isCopyable && 'hover:bg-headplane-100 dark:hover:bg-headplane-800',
)}
>
{isCopyable ? (
<button
type="button"
className="w-full flex items-center gap-x-1 outline-none"
onClick={async (event) => {
const svgs = event.currentTarget.querySelectorAll('svg');
for (const svg of svgs) {
svg.toggleAttribute('data-copied', true);
}
await navigator.clipboard.writeText(value);
toast('Copied to clipboard');
2024-03-26 09:28:52 -04:00
2025-02-01 18:11:33 -05:00
setTimeout(() => {
for (const svg of svgs) {
svg.toggleAttribute('data-copied', false);
}
}, 1000);
}}
>
2025-02-04 17:21:03 -05:00
<p className="truncate">{value}</p>
2025-02-01 18:11:33 -05:00
<Check className="h-4.5 w-4.5 p-1 hidden data-[copied]:block" />
<Copy className="h-4.5 w-4.5 p-1 block data-[copied]:hidden" />
</button>
) : (
value
)}
</dd>
2024-03-26 09:28:52 -04:00
</dl>
2024-12-31 10:30:14 +05:30
);
2024-03-26 09:28:52 -04:00
}