## Summary Not perfect, but IMO helpful: <img width="1792" alt="Screen Shot 2023-08-02 at 9 29 24 PM" src="https://github.com/astral-sh/ruff/assets/1309177/e613e918-75cb-475e-9ea4-f833d1a0b5f6"> <img width="1792" alt="Screen Shot 2023-08-02 at 9 29 20 PM" src="https://github.com/astral-sh/ruff/assets/1309177/bb3efdfe-40e1-45b5-b774-082521b2d214">
53 lines
1.3 KiB
TypeScript
53 lines
1.3 KiB
TypeScript
import { useEffect, useState } from "react";
|
|
import AstralButton from "./AstralButton";
|
|
|
|
export default function ShareButton({ onShare }: { onShare?: () => void }) {
|
|
const [copied, setCopied] = useState(false);
|
|
|
|
useEffect(() => {
|
|
if (copied) {
|
|
const timeout = setTimeout(() => setCopied(false), 2000);
|
|
return () => clearTimeout(timeout);
|
|
}
|
|
}, [copied]);
|
|
|
|
return copied ? (
|
|
<AstralButton
|
|
type="button"
|
|
className="relative flex-none leading-6 py-1.5 px-3 cursor-auto dark:shadow-copied"
|
|
>
|
|
<span
|
|
className="absolute inset-0 flex items-center justify-center invisible"
|
|
aria-hidden="true"
|
|
>
|
|
Share
|
|
</span>
|
|
<span aria-hidden="false">Copied!</span>
|
|
</AstralButton>
|
|
) : (
|
|
<AstralButton
|
|
type="button"
|
|
className="relative flex-none leading-6 py-1.5 px-3 shadow-sm disabled:opacity-50"
|
|
disabled={!onShare || copied}
|
|
onClick={
|
|
onShare
|
|
? () => {
|
|
setCopied(true);
|
|
onShare();
|
|
}
|
|
: undefined
|
|
}
|
|
>
|
|
<span
|
|
className="absolute inset-0 flex items-center justify-center"
|
|
aria-hidden="false"
|
|
>
|
|
Share
|
|
</span>
|
|
<span className="invisible" aria-hidden="true">
|
|
Copied!
|
|
</span>
|
|
</AstralButton>
|
|
);
|
|
}
|