on master help sign in
fix: refactor CopyButton into useCopiable hook and button
8aab3dfMatt Condon (shrugs)
src/components/CopyButton.js+5−18
@@ -1,9 +1,9 @@
1−import React, { useCallback, useEffect, useRef, useState } from 'react';
1+import React from 'react';
2−import { LinkButton } from 'indigo-react';
3import cn from 'classnames';
2import cn from 'classnames';
4−import copy from 'copy-to-clipboard';
3+import { LinkButton } from 'indigo-react';
4+
5+import useCopiable from 'lib/useCopiable';
5
6
6−const COPY_DELAY = 2 * 1000; // ms
7const renderDefaultCopyText = didCopy => (didCopy ? 'Copied!' : 'Copy');
7const renderDefaultCopyText = didCopy => (didCopy ? 'Copied!' : 'Copy');
8
8
9export default function CopyButton({
9export default function CopyButton({
@@ -13,20 +13,7 @@ export default function CopyButton({
13 className,
13 className,
14 ...rest
14 ...rest
15}) {
15}) {
16− const [didCopy, setDidCopy] = useState(false);
16+ const [doCopy, didCopy] = useCopiable(text);
17−
18− // what we really want here is a useDebouncedCallback from use-debounced
19− // but that's a relatively large dep for a single simple usage so ¯\_(ツ)_/¯
20− const listener = useRef(); // <NodeJS.Listener>
21− useEffect(() => () => clearTimeout(listener.current), []);
22−
23− const doCopy = useCallback(() => {
24− copy(text);
25− setDidCopy(true);
26−
27− clearTimeout(listener.current);
28− listener.current = setTimeout(() => setDidCopy(false), COPY_DELAY);
29− }, [text]);
30
17
31 return (
18 return (
32 <As
19 <As
src/lib/useCopiable.jsnew file+23
@@ -0,0 +1,23 @@
1+import { useState, useEffect, useRef, useCallback } from 'react';
2+import copy from 'copy-to-clipboard';
3+
4+const COPY_DELAY = 2 * 1000; // ms
5+
6+export default function useCopiable(text) {
7+ const [didCopy, setDidCopy] = useState(false);
8+
9+ // what we really want here is a useDebouncedCallback from use-debounced
10+ // but that's a relatively large dep for a single simple usage so ¯\_(ツ)_/¯
11+ const listener = useRef(); // <NodeJS.Listener>
12+ useEffect(() => () => clearTimeout(listener.current), []);
13+
14+ const doCopy = useCallback(() => {
15+ copy(text);
16+ setDidCopy(true);
17+
18+ clearTimeout(listener.current);
19+ listener.current = setTimeout(() => setDidCopy(false), COPY_DELAY);
20+ }, [text]);
21+
22+ return [doCopy, didCopy];
23+}