on master help sign in
fix: refactor CopyButton into useCopiable hook and button
commit8aab3dfdb317482213ed97b13d340523035fe7fa authorMatt Condon (shrugs) <mattgcondon@gmail.com> dateMon 19 Aug 2019, 13:35 (7 years ago) parentf201d8c
2 files changed+28−18
src/components/CopyButton.js+5−18 src/lib/useCopiable.js+23
src/components/CopyButton.js+5−18
@@ -1,9 +1,9 @@
1−import React, { useCallback, useEffect, useRef, useState } from 'react';
2−import { LinkButton } from 'indigo-react';
1+import React from 'react';
32import cn from 'classnames';
4−import copy from 'copy-to-clipboard';
3+import { LinkButton } from 'indigo-react';
4+
5+import useCopiable from 'lib/useCopiable';
56
6−const COPY_DELAY = 2 * 1000; // ms
77const renderDefaultCopyText = didCopy => (didCopy ? 'Copied!' : 'Copy');
88
99export default function CopyButton({
@@ -13,20 +13,7 @@ export default function CopyButton({
1313 className,
1414 ...rest
1515}) {
16− const [didCopy, setDidCopy] = useState(false);
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]);
16+ const [doCopy, didCopy] = useCopiable(text);
3017
3118 return (
3219 <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+}