diff --git a/README.md b/README.md
index 74449a3cc6..7b4f10b2bb 100644
--- a/README.md
+++ b/README.md
@@ -73,6 +73,7 @@
- [**Side-effects**](./docs/Side-effects.md)
- [`useAsync`](./docs/useAsync.md) — resolves an `async` function.
- [`useAsyncRetry`](./docs/useAsyncRetry.md) — `useAsync` with `retry()` method.
+ - [`useCopyToClipboard`](./docs/useCopyToClipboard.md) — copies text to clipboard.
- [`useDebounce`](./docs/useDebounce.md) — debounces a function. [![][img-demo]](https://streamich.github.io/react-use/?path=/story/side-effects-usedebounce--demo)
- [`useFavicon`](./docs/useFavicon.md) — sets favicon of the page.
- [`useLocalStorage`](./docs/useLocalStorage.md) — manages a value in `localStorage`.
diff --git a/docs/useCopyToClipboard.md b/docs/useCopyToClipboard.md
index ce59f7dc4e..79b83f7b4a 100644
--- a/docs/useCopyToClipboard.md
+++ b/docs/useCopyToClipboard.md
@@ -1,54 +1,35 @@
# `useCopyToClipboard`
-copy text to a users clipboard.
+Copy text to a user's clipboard.
-## Usage
-
-### basic usage:
-
-```jsx
-import {useCopyToClipboard} from 'react-use';
-const myComp = (props) => {
- const [success, copyToClipboard] = useCopyToClipboard();
- const myText = 'text to be copied';
- return (
- copyToClipboard(myText) }>{myText}
- )
-}
-```
+## Usage
-### with timeout:
+Basic usage
```jsx
-import {useCopyToClipboard} from 'react-use';
+const Demo = () => {
+ const [text, setText] = React.useState('');
+ const [copied, copyToClipboard] = useCopyToClipboard(text);
-const myComp = (props) => {
- const [success, copyToClipboard] = useCopyToClipboard(2000);
- const myText = 'text to be copied';
return (
-
copyToClipboard(myText) }>{myText}
- { success &&
copied to clipboard}
+
setText(e.target.value)} />
+
+
Copied: {copied ? 'Yes' : 'No'}
- )
+ )
}
```
-### with custom polyfill:
+## Reference
-```jsx
-import {useCopyToClipboard} from 'react-use';
-import * as clipboard from "clipboard-polyfill"
-
-const myComp = (props) => {
- const [success, copyToClipboard] = useCopyToClipboard(undefined, clipboard.writeText);
- const myText = 'text to be copied';
- return (
-
- copyToClipboard(myText) }>{myText}
- { success && copied to clipboard}
-
- )
-}
+```js
+const [copied, copyToClipboard] = useCopyToClipboard(text);
+const [copied, copyToClipboard] = useCopyToClipboard(text, copyFunction);
```
+
+, where
+
+- `copyFunction` — function that receives a single string argument, which
+ it copies to user's clipboard.
diff --git a/src/__stories__/useCopyToClipboard.story.tsx b/src/__stories__/useCopyToClipboard.story.tsx
index d97437e53e..fa346a017f 100644
--- a/src/__stories__/useCopyToClipboard.story.tsx
+++ b/src/__stories__/useCopyToClipboard.story.tsx
@@ -4,13 +4,14 @@ import ShowDocs from './util/ShowDocs';
import {useCopyToClipboard} from '..';
const Demo = () => {
- const [success, copyToClipboard] = useCopyToClipboard(2000);
- const textToCopy = "text to be copied"
+ const [text, setText] = React.useState('');
+ const [copied, copyToClipboard] = useCopyToClipboard(text);
+
return (
-
{textToCopy}
-
- { success &&
text copied!}
+
setText(e.target.value)} />
+
+
Copied: {copied ? 'Yes' : 'No'}
@@ -18,6 +19,6 @@ const Demo = () => {
)
}
-storiesOf('UI|useCopyToClipboard', module)
+storiesOf('Side-effects|useCopyToClipboard', module)
.add('Docs', () =>
)
.add('Demo', () =>
)
diff --git a/src/useCopyToClipboard.ts b/src/useCopyToClipboard.ts
index 01d7457b37..0515f9270f 100644
--- a/src/useCopyToClipboard.ts
+++ b/src/useCopyToClipboard.ts
@@ -1,41 +1,27 @@
-import {useState, useEffect} from 'react';
-import * as clipboard from "clipboard-polyfill"
+import useUpdateEffect from './useUpdateEffect';
+import {useState, useCallback} from 'react';
const copyDefault = (text) => {
- console.log('run');
- const element = document.createElement('textarea'); // create textarea HTML element
- element.value = text; // add the text to be copied to the element
- document.body.appendChild(element); // add element to DOM
- element.select(); // select the text
- document.execCommand('copy'); // execute copy command
- document.body.removeChild(element); // remove element from DOM
+ const element = document.createElement('textarea');
+ element.value = text;
+ document.body.appendChild(element);
+ element.select();
+ document.execCommand('copy');
+ document.body.removeChild(element);
};
+const useCopyToClipboard = (text: string = '', copy = copyDefault): [boolean, () => void] => {
+ const [copied, setCopied] = useState(false);
+ const copyToClipboard = useCallback(() => {
+ copy(text);
+ setCopied(true);
+ }, [text]);
-const useCopyToClipboard = (timeout = undefined, copy = copyDefault) => {
+ useUpdateEffect(() => {
+ setCopied(false);
+ }, [text]);
- const [success, setSuccess] = useState(false);
-
- const copyToClipboard = (text) => {
-
- if (typeof text == "string" || typeof text == "number" ) {
- copy(text);
- setSuccess(true);
- }
- else {
- setSuccess(false);
- console.error(`Cannot copy typeof ${typeof text} to clipboard, must be a valid string or number.`);
- }
- }
-
- useEffect( () => {
- // if timeout given, set success to false
- if (timeout) {
- if (success) setTimeout( () => setSuccess(false), timeout);
- }
- }, [success])
-
- return [success, copyToClipboard];
+ return [copied, copyToClipboard];
}
export default useCopyToClipboard;