Skip to content

Commit 20bb435

Browse files
authored
Merge pull request #3172 from pyth-network/chore/copy-hook
chore: export reusable useCopy hook
2 parents a5d6805 + 8853f2c commit 20bb435

File tree

3 files changed

+46
-36
lines changed

3 files changed

+46
-36
lines changed

packages/component-library/package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@
1515
"types": "./dist/esm/useData/index.d.ts",
1616
"default": "./dist/esm/useData/index.js"
1717
},
18+
"./useCopy": {
19+
"types": "./dist/esm/useCopy/index.d.ts",
20+
"default": "./dist/esm/useCopy/index.js"
21+
},
1822
"./useQueryParamsPagination": {
1923
"types": "./dist/esm/useQueryParamsPagination/index.d.ts",
2024
"default": "./dist/esm/useQueryParamsPagination/index.js"

packages/component-library/src/CopyButton/index.tsx

Lines changed: 3 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,10 @@ import { Check } from "@phosphor-icons/react/dist/ssr/Check";
44
import { Copy } from "@phosphor-icons/react/dist/ssr/Copy";
55
import clsx from "clsx";
66
import type { ComponentProps } from "react";
7-
import { useCallback, useEffect, useState } from "react";
87

9-
import styles from "./index.module.scss";
108
import { Button } from "../unstyled/Button/index.jsx";
11-
import { useLogger } from "../useLogger/index.jsx";
12-
13-
const COPY_INDICATOR_TIME = 1000;
9+
import { useCopy } from "../useCopy";
10+
import styles from "./index.module.scss";
1411

1512
type OwnProps = {
1613
text: string;
@@ -30,37 +27,7 @@ export const CopyButton = ({
3027
className,
3128
...props
3229
}: Props) => {
33-
const [isCopied, setIsCopied] = useState(false);
34-
const logger = useLogger();
35-
const copy = useCallback(() => {
36-
navigator.clipboard
37-
.writeText(text)
38-
.then(() => {
39-
setIsCopied(true);
40-
})
41-
.catch((error: unknown) => {
42-
/* TODO do something here? */
43-
logger.error(error);
44-
});
45-
}, [text, logger]);
46-
47-
useEffect(() => {
48-
setIsCopied(false);
49-
}, [text]);
50-
51-
useEffect(() => {
52-
if (isCopied) {
53-
const timeout = setTimeout(() => {
54-
setIsCopied(false);
55-
}, COPY_INDICATOR_TIME);
56-
return () => {
57-
clearTimeout(timeout);
58-
};
59-
} else {
60-
return;
61-
}
62-
}, [isCopied]);
63-
30+
const { isCopied, copy } = useCopy(text);
6431
return (
6532
<Button
6633
onPress={copy}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
"use client";
2+
3+
import { useCallback, useEffect, useState } from "react";
4+
5+
import { useLogger } from "../useLogger";
6+
7+
export const useCopy = (text: string, copyIndicatorTime = 1000) => {
8+
const [isCopied, setIsCopied] = useState(false);
9+
const logger = useLogger();
10+
const copy = useCallback(() => {
11+
navigator.clipboard
12+
.writeText(text)
13+
.then(() => {
14+
setIsCopied(true);
15+
})
16+
.catch((error: unknown) => {
17+
logger.error(error);
18+
});
19+
}, [text, logger]);
20+
21+
useEffect(() => {
22+
setIsCopied(false);
23+
}, [text]);
24+
25+
useEffect(() => {
26+
if (isCopied) {
27+
const timeout = setTimeout(() => {
28+
setIsCopied(false);
29+
}, copyIndicatorTime);
30+
return () => {
31+
clearTimeout(timeout);
32+
};
33+
} else {
34+
return;
35+
}
36+
}, [isCopied, copyIndicatorTime]);
37+
38+
return { isCopied, copy };
39+
};

0 commit comments

Comments
 (0)