e30e75b5d4
Code Quality / Oxlint + Oxfmt (push) Waiting to run
Code Quality / Template Sync (push) Waiting to run
Code Quality / Build Changed Packages (push) Waiting to run
Code Quality / Test Changed Packages (push) Waiting to run
Deploy Expo Example / Deploy Production (push) Waiting to run
Deploy Ink Example / Deploy Production (push) Waiting to run
Python Tests / pytest (assistant-stream, 3.10) (push) Waiting to run
Python Tests / pytest (assistant-stream, 3.12) (push) Waiting to run
Python Tests / pytest (assistant-ui-sync-server-api, 3.10) (push) Waiting to run
Python Tests / pytest (assistant-ui-sync-server-api, 3.12) (push) Waiting to run
Deploy Shadcn Registry / Deploy Production (push) Waiting to run
Template Metrics / LOC + Bundle Size (push) Waiting to run
Changesets / Create Version PR (push) Has been cancelled
80 lines
2.2 KiB
TypeScript
80 lines
2.2 KiB
TypeScript
"use client";
|
|
|
|
import { useState, useCallback } from "react";
|
|
import { Check, Link2 } from "lucide-react";
|
|
import { cn } from "@/lib/utils";
|
|
import { analytics } from "@/lib/analytics";
|
|
|
|
interface ShareButtonProps {
|
|
className?: string;
|
|
}
|
|
|
|
export function ShareButton({ className }: ShareButtonProps) {
|
|
const [copied, setCopied] = useState(false);
|
|
|
|
const handleShare = useCallback(async () => {
|
|
analytics.builder.shareClicked();
|
|
const url = window.location.href;
|
|
|
|
// Try Web Share API on mobile
|
|
if (navigator.share && /mobile|android/i.test(navigator.userAgent)) {
|
|
try {
|
|
await navigator.share({
|
|
title: "assistant-ui Playground",
|
|
text: "Check out my chat UI configuration",
|
|
url,
|
|
});
|
|
return;
|
|
} catch {
|
|
// User cancelled or not supported, fall through to copy
|
|
}
|
|
}
|
|
|
|
// Copy to clipboard
|
|
try {
|
|
await navigator.clipboard.writeText(url);
|
|
setCopied(true);
|
|
setTimeout(() => setCopied(false), 2000);
|
|
} catch {
|
|
// Fallback for older browsers
|
|
const textArea = document.createElement("textarea");
|
|
textArea.value = url;
|
|
textArea.style.position = "fixed";
|
|
textArea.style.left = "-9999px";
|
|
document.body.appendChild(textArea);
|
|
textArea.select();
|
|
document.execCommand("copy");
|
|
document.body.removeChild(textArea);
|
|
setCopied(true);
|
|
setTimeout(() => setCopied(false), 2000);
|
|
}
|
|
}, []);
|
|
|
|
return (
|
|
<button
|
|
type="button"
|
|
onClick={handleShare}
|
|
className={cn(
|
|
"flex items-center gap-1.5 rounded-md px-2.5 py-1 text-xs font-medium transition-colors",
|
|
copied
|
|
? "bg-green-500/10 text-green-600 dark:text-green-400"
|
|
: "text-muted-foreground hover:text-foreground",
|
|
className,
|
|
)}
|
|
title={copied ? "Link copied to clipboard" : "Copy shareable link"}
|
|
>
|
|
{copied ? (
|
|
<>
|
|
<Check className="size-3.5" />
|
|
<span className="hidden sm:inline">Copied!</span>
|
|
</>
|
|
) : (
|
|
<>
|
|
<Link2 className="size-3.5" />
|
|
<span className="hidden sm:inline">Share</span>
|
|
</>
|
|
)}
|
|
</button>
|
|
);
|
|
}
|