Merge pull request #202 from ZhenyaGoroh/clipboard-copy
Clipboard copy button
This commit is contained in:
@@ -2,9 +2,9 @@
|
||||
import { useState, useEffect } from "react";
|
||||
import styled, { keyframes } from "styled-components";
|
||||
import { ny } from "@/lib/utils";
|
||||
import { Checkbox } from "./ui/checkbox";
|
||||
import { ChevronLeft, InfoIcon } from "lucide-react";
|
||||
import { Button } from "./ui/button";
|
||||
import { CopyButton } from "./ui/copy-button";
|
||||
import Particles from "./ui/particles";
|
||||
import confetti from "canvas-confetti";
|
||||
import { releases, releaseTree } from "@/lib/releases";
|
||||
@@ -189,6 +189,9 @@ export default function DownloadPage() {
|
||||
setSelectedLinuxDownloadType("flatpak");
|
||||
};
|
||||
|
||||
const linuxAppimageBashScript =
|
||||
'bash <(curl https://updates.zen-browser.app/appimage.sh)';
|
||||
|
||||
return (
|
||||
<>
|
||||
<link
|
||||
@@ -238,8 +241,12 @@ export default function DownloadPage() {
|
||||
If you're using an AppImage, you can use the automatic
|
||||
installer, check it out{" "}
|
||||
</p>
|
||||
<pre className="mt-2 rounded-md bg-background p-2 text-muted-foreground">
|
||||
bash {"<"}(curl https://updates.zen-browser.app/appimage.sh)
|
||||
<pre className="mt-2 flex items-center rounded-md bg-background p-2 text-muted-foreground">
|
||||
{linuxAppimageBashScript}
|
||||
<CopyButton
|
||||
className="ml-3"
|
||||
valueToCopy={linuxAppimageBashScript}
|
||||
/>
|
||||
</pre>
|
||||
</div>
|
||||
)}
|
||||
|
||||
61
src/components/ui/copy-button.tsx
Normal file
61
src/components/ui/copy-button.tsx
Normal file
@@ -0,0 +1,61 @@
|
||||
"use client";
|
||||
|
||||
import * as React from "react";
|
||||
|
||||
import { Button } from "./button";
|
||||
import { CheckIcon, CopyIcon } from "@radix-ui/react-icons";
|
||||
|
||||
import { useClipboard } from "@/lib/hooks";
|
||||
|
||||
const CopyButton = React.forwardRef<
|
||||
React.ElementRef<typeof Button>,
|
||||
React.ComponentPropsWithoutRef<typeof Button> & {
|
||||
valueToCopy: string;
|
||||
}
|
||||
>(({ className, valueToCopy, ...props }, ref) => {
|
||||
const copyToClipboard = useClipboard(valueToCopy);
|
||||
|
||||
const [showSuccessIcon, setShowSuccessIcon] = React.useState(false);
|
||||
|
||||
const handleCopy = () => {
|
||||
copyToClipboard();
|
||||
setShowSuccessIcon(true);
|
||||
};
|
||||
|
||||
React.useEffect(() => {
|
||||
let timeout: ReturnType<typeof setTimeout> | null = null;
|
||||
|
||||
if (showSuccessIcon) {
|
||||
timeout = setTimeout(() => {
|
||||
setShowSuccessIcon(false);
|
||||
}, 5000);
|
||||
}
|
||||
|
||||
return () => {
|
||||
if (timeout) {
|
||||
clearTimeout(timeout);
|
||||
}
|
||||
};
|
||||
}, [showSuccessIcon]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Button
|
||||
ref={ref}
|
||||
variant={"ghost"}
|
||||
size={"icon"}
|
||||
className={className}
|
||||
onClick={handleCopy}
|
||||
{...props}
|
||||
>
|
||||
{showSuccessIcon ? (
|
||||
<CheckIcon className="size-5 text-green-500" />
|
||||
) : (
|
||||
<CopyIcon className="size-4" />
|
||||
)}
|
||||
</Button>
|
||||
</>
|
||||
);
|
||||
});
|
||||
|
||||
export { CopyButton };
|
||||
7
src/lib/hooks.ts
Normal file
7
src/lib/hooks.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
export function useClipboard(valueToCopy: string) {
|
||||
const copyToClipboard = () => {
|
||||
navigator.clipboard.writeText(valueToCopy);
|
||||
};
|
||||
|
||||
return copyToClipboard;
|
||||
}
|
||||
Reference in New Issue
Block a user