@react-hook/copy
Advanced tools
| function e(e){return e}import{useState as r,useRef as t,useEffect as n,useCallback as o}from"react";export default function(c){function a(){return u(1)}function i(){return u(e)}var[d,u]=r(0),m=t(()=>u(0));return n(()=>m.current,[c]),{copied:d,copy:o(()=>function(e){if(navigator.clipboard)return navigator.clipboard.writeText(e);var r=document.createElement("span");r.textContent=e,r.style.whiteSpace="pre",document.body.appendChild(r);var t=window.getSelection();if(!t)return Promise.reject();var n=window.document.createRange();t.removeAllRanges(),n.selectNode(r),t.addRange(n);try{window.document.execCommand("copy")}catch(e){return Promise.reject()}return t.removeAllRanges(),window.document.body.removeChild(r),Promise.resolve()}(c).then(a).catch(i),[c]),reset:m.current}} | ||
| //# sourceMappingURL=index.mjs.map |
| {"version":3,"file":"index.mjs","sources":["../../src/index.tsx"],"sourcesContent":["import * as React from 'react'\n\nfunction useCopy(text: string) {\n const [copied, setCopied] = React.useState(false)\n const reset = React.useRef(() => setCopied(false))\n // Resets 'copied' if text changes\n React.useEffect(() => reset.current, [text])\n return {\n copied,\n copy: React.useCallback(\n () =>\n copyToClipboard(text)\n .then(() => setCopied(true))\n .catch(() => setCopied((copied) => copied)),\n [text]\n ),\n reset: reset.current,\n } as const\n}\n/* istanbul ignore next */\nfunction copyToClipboard(text: string) {\n // uses the Async Clipboard API when available. Requires a secure browing\n // context (i.e. HTTPS)\n if (navigator.clipboard) return navigator.clipboard.writeText(text)\n // puts the text to copy into a <span>\n const span = document.createElement('span')\n span.textContent = text\n // preserves consecutive spaces and newlines\n span.style.whiteSpace = 'pre'\n // adds the <span> to the page\n document.body.appendChild(span)\n // makes a selection object representing the range of text selected by the user\n const selection = window.getSelection()\n if (!selection) return Promise.reject()\n const range = window.document.createRange()\n selection.removeAllRanges()\n range.selectNode(span)\n selection.addRange(range)\n // copies text to the clipboard\n try {\n window.document.execCommand('copy')\n } catch (err) {\n return Promise.reject()\n }\n // cleans up the dom element and selection\n selection.removeAllRanges()\n window.document.body.removeChild(span)\n // the Async Clipboard API returns a promise that may reject with `undefined`\n // so we match that here for consistency\n return Promise.resolve()\n}\n\nexport default useCopy\n"],"names":["copied","text","setCopied","React","reset","current","copy","navigator","clipboard","writeText","span","document","createElement","textContent","style","whiteSpace","body","appendChild","selection","window","getSelection","Promise","reject","range","createRange","removeAllRanges","selectNode","addRange","execCommand","err","removeChild","resolve","copyToClipboard","then","catch"],"mappings":"AAaiC,WAACA,UAAWA,8FAX7C,SAAiBC,uBAUKC,EAAU,uBACTA,SAVdF,EAAQE,GAAaC,EAAe,GACrCC,EAAQD,EAAa,IAAMD,EAAU,WAE3CC,EAAgB,IAAMC,EAAMC,QAAS,CAACJ,IAC/B,CACLD,OAAAA,EACAM,KAAMH,EACJ,IAUN,SAAyBF,MAGnBM,UAAUC,UAAW,OAAOD,UAAUC,UAAUC,UAAUR,OAExDS,EAAOC,SAASC,cAAc,QACpCF,EAAKG,YAAcZ,EAEnBS,EAAKI,MAAMC,WAAa,MAExBJ,SAASK,KAAKC,YAAYP,OAEpBQ,EAAYC,OAAOC,mBACpBF,EAAW,OAAOG,QAAQC,aACzBC,EAAQJ,OAAOR,SAASa,cAC9BN,EAAUO,kBACVF,EAAMG,WAAWhB,GACjBQ,EAAUS,SAASJ,OAGjBJ,OAAOR,SAASiB,YAAY,QAC5B,MAAOC,UACAR,QAAQC,gBAGjBJ,EAAUO,kBACVN,OAAOR,SAASK,KAAKc,YAAYpB,GAG1BW,QAAQU,UAtCTC,CAAgB/B,GACbgC,QACAC,SACL,CAACjC,IAEHG,MAAOA,EAAMC"} |
| "use strict"; | ||
| exports.__esModule = true; | ||
| exports.default = void 0; | ||
| var React = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("react")); | ||
| function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } | ||
| function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } | ||
| function _ref2(copied) { | ||
| return copied; | ||
| } | ||
| function useCopy(text) { | ||
| const [copied, setCopied] = React.useState(false); | ||
| const reset = React.useRef(() => setCopied(false)); // Resets 'copied' if text changes | ||
| React.useEffect(() => reset.current, [text]); | ||
| function _ref() { | ||
| return setCopied(true); | ||
| } | ||
| function _ref3() { | ||
| return setCopied(_ref2); | ||
| } | ||
| return { | ||
| copied, | ||
| copy: React.useCallback(() => copyToClipboard(text).then(_ref).catch(_ref3), [text]), | ||
| reset: reset.current | ||
| }; | ||
| } | ||
| /* istanbul ignore next */ | ||
| function copyToClipboard(text) { | ||
| // uses the Async Clipboard API when available. Requires a secure browing | ||
| // context (i.e. HTTPS) | ||
| if (navigator.clipboard) return navigator.clipboard.writeText(text); // puts the text to copy into a <span> | ||
| const span = document.createElement('span'); | ||
| span.textContent = text; // preserves consecutive spaces and newlines | ||
| span.style.whiteSpace = 'pre'; // adds the <span> to the page | ||
| document.body.appendChild(span); // makes a selection object representing the range of text selected by the user | ||
| const selection = window.getSelection(); | ||
| if (!selection) return Promise.reject(); | ||
| const range = window.document.createRange(); | ||
| selection.removeAllRanges(); | ||
| range.selectNode(span); | ||
| selection.addRange(range); // copies text to the clipboard | ||
| try { | ||
| window.document.execCommand('copy'); | ||
| } catch (err) { | ||
| return Promise.reject(); | ||
| } // cleans up the dom element and selection | ||
| selection.removeAllRanges(); | ||
| window.document.body.removeChild(span); // the Async Clipboard API returns a promise that may reject with `undefined` | ||
| // so we match that here for consistency | ||
| return Promise.resolve(); | ||
| } | ||
| var _default = useCopy; | ||
| exports.default = _default; |
| import * as React from 'react'; | ||
| function _ref2(copied) { | ||
| return copied; | ||
| } | ||
| function useCopy(text) { | ||
| const [copied, setCopied] = React.useState(false); | ||
| const reset = React.useRef(() => setCopied(false)); // Resets 'copied' if text changes | ||
| React.useEffect(() => reset.current, [text]); | ||
| function _ref() { | ||
| return setCopied(true); | ||
| } | ||
| function _ref3() { | ||
| return setCopied(_ref2); | ||
| } | ||
| return { | ||
| copied, | ||
| copy: React.useCallback(() => copyToClipboard(text).then(_ref).catch(_ref3), [text]), | ||
| reset: reset.current | ||
| }; | ||
| } | ||
| /* istanbul ignore next */ | ||
| function copyToClipboard(text) { | ||
| // uses the Async Clipboard API when available. Requires a secure browing | ||
| // context (i.e. HTTPS) | ||
| if (navigator.clipboard) return navigator.clipboard.writeText(text); // puts the text to copy into a <span> | ||
| const span = document.createElement('span'); | ||
| span.textContent = text; // preserves consecutive spaces and newlines | ||
| span.style.whiteSpace = 'pre'; // adds the <span> to the page | ||
| document.body.appendChild(span); // makes a selection object representing the range of text selected by the user | ||
| const selection = window.getSelection(); | ||
| if (!selection) return Promise.reject(); | ||
| const range = window.document.createRange(); | ||
| selection.removeAllRanges(); | ||
| range.selectNode(span); | ||
| selection.addRange(range); // copies text to the clipboard | ||
| try { | ||
| window.document.execCommand('copy'); | ||
| } catch (err) { | ||
| return Promise.reject(); | ||
| } // cleans up the dom element and selection | ||
| selection.removeAllRanges(); | ||
| window.document.body.removeChild(span); // the Async Clipboard API returns a promise that may reject with `undefined` | ||
| // so we match that here for consistency | ||
| return Promise.resolve(); | ||
| } | ||
| export default useCopy; |
| !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("react")):"function"==typeof define&&define.amd?define(["react"],t):(e=e||self).useCopy=t(e.React)}(this,(function(e){"use strict";function t(e){return e}return function(n){function r(){return i(1)}function o(){return i(t)}var c=e.useState(0),u=c[0],i=c[1],a=e.useRef((function(){return i(0)}));return e.useEffect((function(){return a.current}),[n]),{copied:u,copy:e.useCallback((function(){return function(e){if(navigator.clipboard)return navigator.clipboard.writeText(e);var t=document.createElement("span");t.textContent=e,t.style.whiteSpace="pre",document.body.appendChild(t);var n=window.getSelection();if(!n)return Promise.reject();var r=window.document.createRange();n.removeAllRanges(),r.selectNode(t),n.addRange(r);try{window.document.execCommand("copy")}catch(e){return Promise.reject()}return n.removeAllRanges(),window.document.body.removeChild(t),Promise.resolve()}(n).then(r).catch(o)}),[n]),reset:a.current}}})); | ||
| //# sourceMappingURL=use-copy.js.map |
| {"version":3,"file":"use-copy.js","sources":["../../src/index.tsx"],"sourcesContent":["import * as React from 'react'\n\nfunction useCopy(text: string) {\n const [copied, setCopied] = React.useState(false)\n const reset = React.useRef(() => setCopied(false))\n // Resets 'copied' if text changes\n React.useEffect(() => reset.current, [text])\n return {\n copied,\n copy: React.useCallback(\n () =>\n copyToClipboard(text)\n .then(() => setCopied(true))\n .catch(() => setCopied((copied) => copied)),\n [text]\n ),\n reset: reset.current,\n } as const\n}\n/* istanbul ignore next */\nfunction copyToClipboard(text: string) {\n // uses the Async Clipboard API when available. Requires a secure browing\n // context (i.e. HTTPS)\n if (navigator.clipboard) return navigator.clipboard.writeText(text)\n // puts the text to copy into a <span>\n const span = document.createElement('span')\n span.textContent = text\n // preserves consecutive spaces and newlines\n span.style.whiteSpace = 'pre'\n // adds the <span> to the page\n document.body.appendChild(span)\n // makes a selection object representing the range of text selected by the user\n const selection = window.getSelection()\n if (!selection) return Promise.reject()\n const range = window.document.createRange()\n selection.removeAllRanges()\n range.selectNode(span)\n selection.addRange(range)\n // copies text to the clipboard\n try {\n window.document.execCommand('copy')\n } catch (err) {\n return Promise.reject()\n }\n // cleans up the dom element and selection\n selection.removeAllRanges()\n window.document.body.removeChild(span)\n // the Async Clipboard API returns a promise that may reject with `undefined`\n // so we match that here for consistency\n return Promise.resolve()\n}\n\nexport default useCopy\n"],"names":["copied","text","setCopied","React","reset","current","copy","navigator","clipboard","writeText","span","document","createElement","textContent","style","whiteSpace","body","appendChild","selection","window","getSelection","Promise","reject","range","createRange","removeAllRanges","selectNode","addRange","execCommand","err","removeChild","resolve","copyToClipboard","then","catch"],"mappings":"gOAaiC,WAACA,UAAWA,SAX7C,SAAiBC,uBAUKC,EAAU,uBACTA,WAVOC,WAAe,GAApCH,OAAQE,OACTE,EAAQD,UAAa,kBAAMD,EAAU,aAE3CC,aAAgB,kBAAMC,EAAMC,UAAS,CAACJ,IAC/B,CACLD,OAAAA,EACAM,KAAMH,eACJ,kBAUN,SAAyBF,MAGnBM,UAAUC,UAAW,OAAOD,UAAUC,UAAUC,UAAUR,OAExDS,EAAOC,SAASC,cAAc,QACpCF,EAAKG,YAAcZ,EAEnBS,EAAKI,MAAMC,WAAa,MAExBJ,SAASK,KAAKC,YAAYP,OAEpBQ,EAAYC,OAAOC,mBACpBF,EAAW,OAAOG,QAAQC,aACzBC,EAAQJ,OAAOR,SAASa,cAC9BN,EAAUO,kBACVF,EAAMG,WAAWhB,GACjBQ,EAAUS,SAASJ,OAGjBJ,OAAOR,SAASiB,YAAY,QAC5B,MAAOC,UACAR,QAAQC,gBAGjBJ,EAAUO,kBACVN,OAAOR,SAASK,KAAKc,YAAYpB,GAG1BW,QAAQU,UAtCTC,CAAgB/B,GACbgC,QACAC,WACL,CAACjC,IAEHG,MAAOA,EAAMC"} |
| import {renderHook, act} from '@testing-library/react-hooks' | ||
| import useCopy from './index' | ||
| describe('useCopy()', () => { | ||
| const writeText = jest.fn(async (text) => text) | ||
| // @ts-ignore | ||
| window.navigator.clipboard = { | ||
| writeText, | ||
| } | ||
| it('should work', async () => { | ||
| const {result} = renderHook(() => useCopy('copy me')) | ||
| expect(result.current.copied).toBe(false) | ||
| await act(() => result.current.copy()) | ||
| expect(writeText).toBeCalled() | ||
| expect(result.current.copied).toBe(true) | ||
| act(() => result.current.reset()) | ||
| expect(result.current.copied).toBe(false) | ||
| }) | ||
| }) |
| import * as React from 'react' | ||
| function useCopy(text: string) { | ||
| const [copied, setCopied] = React.useState(false) | ||
| const reset = React.useRef(() => setCopied(false)) | ||
| // Resets 'copied' if text changes | ||
| React.useEffect(() => reset.current, [text]) | ||
| return { | ||
| copied, | ||
| copy: React.useCallback( | ||
| () => | ||
| copyToClipboard(text) | ||
| .then(() => setCopied(true)) | ||
| .catch(() => setCopied((copied) => copied)), | ||
| [text] | ||
| ), | ||
| reset: reset.current, | ||
| } as const | ||
| } | ||
| /* istanbul ignore next */ | ||
| function copyToClipboard(text: string) { | ||
| // uses the Async Clipboard API when available. Requires a secure browing | ||
| // context (i.e. HTTPS) | ||
| if (navigator.clipboard) return navigator.clipboard.writeText(text) | ||
| // puts the text to copy into a <span> | ||
| const span = document.createElement('span') | ||
| span.textContent = text | ||
| // preserves consecutive spaces and newlines | ||
| span.style.whiteSpace = 'pre' | ||
| // adds the <span> to the page | ||
| document.body.appendChild(span) | ||
| // makes a selection object representing the range of text selected by the user | ||
| const selection = window.getSelection() | ||
| if (!selection) return Promise.reject() | ||
| const range = window.document.createRange() | ||
| selection.removeAllRanges() | ||
| range.selectNode(span) | ||
| selection.addRange(range) | ||
| // copies text to the clipboard | ||
| try { | ||
| window.document.execCommand('copy') | ||
| } catch (err) { | ||
| return Promise.reject() | ||
| } | ||
| // cleans up the dom element and selection | ||
| selection.removeAllRanges() | ||
| window.document.body.removeChild(span) | ||
| // the Async Clipboard API returns a promise that may reject with `undefined` | ||
| // so we match that here for consistency | ||
| return Promise.resolve() | ||
| } | ||
| export default useCopy |
| declare function useCopy( | ||
| text: string | ||
| ): { | ||
| readonly copied: boolean | ||
| readonly copy: () => Promise<void> | ||
| readonly reset: () => void | ||
| } | ||
| export default useCopy |
+2
-2
@@ -1,4 +0,4 @@ | ||
| The MIT License (MIT) | ||
| MIT License | ||
| Copyright (c) 2019 Jared Lunde | ||
| Copyright (c) 2020 Jared Lunde | ||
@@ -5,0 +5,0 @@ Permission is hereby granted, free of charge, to any person obtaining a copy |
+114
-21
| { | ||
| "name": "@react-hook/copy", | ||
| "version": "1.0.1", | ||
| "main": "dist/cjs/index.js", | ||
| "module": "dist/es/index.js", | ||
| "author": "Jared Lunde <jared@BeStellar.co> (https://BeStellar.co)", | ||
| "version": "2.0.0", | ||
| "homepage": "https://github.com/jaredLunde/react-hook#readme", | ||
| "repository": "github:jaredLunde/react-hook", | ||
| "bugs": "https://github.com/jaredLunde/react-hook/issues", | ||
| "author": "Jared Lunde <jared.lunde@gmail.com> (https://jaredLunde.com)", | ||
| "license": "MIT", | ||
| "sideEffects": false, | ||
| "repository": "https://github.com/jaredLunde/react-hook/tree/master/packages/copy", | ||
| "scripts": { | ||
| "build": "yarn run build:es && yarn run build:cjs", | ||
| "build:es": "rimraf dist/es && cross-env NODE_ENV=production BABEL_ENV=es babel src --out-dir dist/es && npm run prettier:es", | ||
| "build:cjs": "rimraf dist/cjs && cross-env NODE_ENV=production BABEL_ENV=cjs babel src --out-dir dist/cjs && npm run prettier:cjs", | ||
| "watch:es": "rimraf dist/es && cross-env NODE_ENV=production BABEL_ENV=es babel src -w --out-dir dist/es", | ||
| "prettier": "prettier --single-quote --no-semi --no-bracket-spacing --trailing-comma es5 --write", | ||
| "prettier:es": "yarn prettier \"dist/es/**/*.js\"", | ||
| "prettier:cjs": "yarn prettier \"dist/cjs/**/*.js\"", | ||
| "prepublishOnly": "yarn build" | ||
| }, | ||
| "description": "A React hook for copying text to the clipboard", | ||
| "keywords": [ | ||
@@ -29,11 +19,114 @@ "react", | ||
| ], | ||
| "main": "dist/main/index.js", | ||
| "module": "dist/module/index.js", | ||
| "unpkg": "dist/umd/use-copy.js", | ||
| "source": "src/index.tsx", | ||
| "types": "types/index.d.ts", | ||
| "files": [ | ||
| "/dist", | ||
| "/src", | ||
| "/types" | ||
| ], | ||
| "exports": { | ||
| ".": { | ||
| "browser": "./dist/module/index.js", | ||
| "import": "./dist/esm/index.mjs", | ||
| "require": "./dist/main/index.js", | ||
| "umd": "./dist/umd/use-copy.js", | ||
| "source": "./src/index.tsx", | ||
| "types": "./types/index.d.ts", | ||
| "default": "./dist/main/index.js" | ||
| }, | ||
| "./package.json": "./package.json", | ||
| "./": "./" | ||
| }, | ||
| "sideEffects": false, | ||
| "scripts": { | ||
| "build": "lundle build --umd-case camel", | ||
| "check-types": "lundle check-types", | ||
| "dev": "lundle build -f module,cjs -w", | ||
| "format": "prettier --write \"{,!(node_modules|dist|coverage)/**/}*.{ts,tsx,js,jsx,md,yml,json}\"", | ||
| "lint": "eslint . --ext .ts,.tsx", | ||
| "prepublishOnly": "npm run lint && npm run test && npm run build && npm run format", | ||
| "test": "jest", | ||
| "validate": "lundle check-types && npm run lint && jest --coverage" | ||
| }, | ||
| "husky": { | ||
| "hooks": { | ||
| "pre-commit": "lint-staged" | ||
| } | ||
| }, | ||
| "lint-staged": { | ||
| "**/*.{ts,tsx,js,jsx}": [ | ||
| "lundle build -f types", | ||
| "eslint", | ||
| "prettier --write" | ||
| ], | ||
| "**/*.{md,yml,json}": [ | ||
| "prettier --write" | ||
| ] | ||
| }, | ||
| "eslintConfig": { | ||
| "extends": [ | ||
| "lunde" | ||
| ] | ||
| }, | ||
| "eslintIgnore": [ | ||
| "node_modules", | ||
| "coverage", | ||
| "dist", | ||
| "test", | ||
| "*.config.js" | ||
| ], | ||
| "jest": { | ||
| "moduleDirectories": [ | ||
| "node_modules", | ||
| "src", | ||
| "test" | ||
| ], | ||
| "testMatch": [ | ||
| "<rootDir>/src/**/?(*.)test.{ts,tsx}" | ||
| ], | ||
| "collectCoverageFrom": [ | ||
| "**/src/**/*.{ts,tsx}" | ||
| ], | ||
| "setupFilesAfterEnv": [ | ||
| "./test/setup.js" | ||
| ], | ||
| "snapshotResolver": "./test/resolve-snapshot.js", | ||
| "globals": { | ||
| "__DEV__": true | ||
| } | ||
| }, | ||
| "prettier": { | ||
| "semi": false, | ||
| "singleQuote": true, | ||
| "jsxSingleQuote": true, | ||
| "bracketSpacing": false | ||
| }, | ||
| "devDependencies": { | ||
| "@stellar-apps/babel-preset-es": "^1.0.4", | ||
| "@stellar-apps/babel-preset-react": "^1.0.1", | ||
| "prettier": "^1.16.4", | ||
| "rimraf": "^2.6.3" | ||
| "@testing-library/jest-dom": "latest", | ||
| "@testing-library/react": "latest", | ||
| "@testing-library/react-hooks": "latest", | ||
| "@testing-library/user-event": "latest", | ||
| "@types/jest": "latest", | ||
| "@types/react": "latest", | ||
| "@types/react-dom": "latest", | ||
| "babel-jest": "latest", | ||
| "eslint": "latest", | ||
| "eslint-config-lunde": "latest", | ||
| "husky": "latest", | ||
| "jest": "latest", | ||
| "lint-staged": "latest", | ||
| "lundle": "latest", | ||
| "prettier": "latest", | ||
| "react": "latest", | ||
| "react-dom": "latest", | ||
| "react-test-renderer": "latest", | ||
| "typescript": "latest" | ||
| }, | ||
| "dependencies": {}, | ||
| "peerDependencies": { | ||
| "react": "^16.8.0" | ||
| "react": ">=16.8" | ||
| } | ||
| } |
+54
-11
@@ -1,19 +0,62 @@ | ||
| # @react-hook/copy | ||
| <hr> | ||
| <div align="center"> | ||
| <h1 align="center"> | ||
| useCopy() | ||
| </h1> | ||
| </div> | ||
| <p align="center"> | ||
| <a href="https://bundlephobia.com/result?p=@react-hook/copy"> | ||
| <img alt="Bundlephobia" src="https://img.shields.io/bundlephobia/minzip/@react-hook/copy?style=for-the-badge&labelColor=24292e"> | ||
| </a> | ||
| <a aria-label="Types" href="https://www.npmjs.com/package/@react-hook/copy"> | ||
| <img alt="Types" src="https://img.shields.io/npm/types/@react-hook/copy?style=for-the-badge&labelColor=24292e"> | ||
| </a> | ||
| <!-- | ||
| <a aria-label="Code coverage report" href="https://codecov.io/gh/jaredLunde/react-hook"> | ||
| <img alt="Code coverage" src="https://img.shields.io/codecov/c/gh/jaredLunde/react-hook?style=for-the-badge&labelColor=24292e"> | ||
| </a> | ||
| <a aria-label="Build status" href="https://travis-ci.com/jaredLunde/react-hook"> | ||
| <img alt="Build status" src="https://img.shields.io/travis/com/jaredLunde/react-hook?style=for-the-badge&labelColor=24292e"> | ||
| </a> | ||
| --> | ||
| <a aria-label="NPM version" href="https://www.npmjs.com/package/@react-hook/copy"> | ||
| <img alt="NPM Version" src="https://img.shields.io/npm/v/@react-hook/copy?style=for-the-badge&labelColor=24292e"> | ||
| </a> | ||
| <a aria-label="License" href="https://jaredlunde.mit-license.org/"> | ||
| <img alt="MIT License" src="https://img.shields.io/npm/l/@react-hook/copy?style=for-the-badge&labelColor=24292e"> | ||
| </a> | ||
| </p> | ||
| <pre align="center">npm i @react-hook/copy</pre> | ||
| <hr> | ||
| A React hook for copying text to the clipboard | ||
| ## Installation | ||
| `yarn add @react-hook/copy` | ||
| ## Quick Start | ||
| ## Usage | ||
| ```jsx harmony | ||
| import useCopy from '@react-hook/copy' | ||
| const F = props => { | ||
| const [copied, copy] = useCopy('This text will be copied to the clipboard') | ||
| return ( | ||
| <a onClick={copy}> | ||
| {copied === false ? 'Copy' : 'Copied'} | ||
| </a> | ||
| const Component = (props) => { | ||
| const {copied, copy, reset} = useCopy( | ||
| 'This text will be copied to the clipboard' | ||
| ) | ||
| return <a onClick={copy}>{copied === false ? 'Copy' : 'Copied'}</a> | ||
| } | ||
| ``` | ||
| ``` | ||
| ## API | ||
| ### useCopy(text: string) | ||
| | Argument | Type | Required? | Description | | ||
| | -------- | -------- | --------- | ----------------------------------------------------------------- | | ||
| | text | `string` | Yes | The text you want to copy to the clipboard when `copy` is clicked | | ||
| ### Returns `{copied: boolean, copy: () => void, reset: () => void}` | ||
| ## LICENSE | ||
| MIT |
| 'use strict' | ||
| exports.__esModule = true | ||
| exports.default = exports.copyToClipboard = void 0 | ||
| var _react = require('react') | ||
| const copyToClipboard = text => { | ||
| // uses the Async Clipboard API when available. Requires a secure browing | ||
| // context (i.e. HTTPS) | ||
| if (navigator.clipboard) { | ||
| return navigator.clipboard.writeText(text) | ||
| } // puts the text to copy into a <span> | ||
| const span = document.createElement('span') | ||
| span.textContent = text // preserves consecutive spaces and newlines | ||
| span.style.whiteSpace = 'pre' // adds the <span> to the page | ||
| document.body.appendChild(span) // makes a selection object representing the range of text selected by the user | ||
| const selection = window.getSelection() | ||
| const range = window.document.createRange() | ||
| selection.removeAllRanges() | ||
| range.selectNode(span) | ||
| selection.addRange(range) // copies text to the clipboard | ||
| let success = false | ||
| try { | ||
| success = window.document.execCommand('copy') | ||
| } catch (err) { | ||
| console.log('error', err) | ||
| } // cleans up the dom element and selection | ||
| selection.removeAllRanges() | ||
| window.document.body.removeChild(span) // the Async Clipboard API returns a promise that may reject with `undefined` | ||
| // so we match that here for consistency | ||
| return success ? Promise.resolve() : Promise.reject() | ||
| } | ||
| exports.copyToClipboard = copyToClipboard | ||
| var _default = text => { | ||
| const [copied, setCopied] = (0, _react.useState)(false) | ||
| function _ref() { | ||
| return setCopied(true) | ||
| } | ||
| const copy = (0, _react.useCallback)(() => { | ||
| const promise = copyToClipboard(text) | ||
| if (copied === false) { | ||
| promise.then(_ref) | ||
| } | ||
| }, [text]) // reset 'copied' if text changes | ||
| function _ref2() { | ||
| return setCopied(false) | ||
| } | ||
| ;(0, _react.useEffect)(() => _ref2, [text]) | ||
| return [copied, copy] | ||
| } | ||
| exports.default = _default |
| import {useState, useCallback, useEffect} from 'react' | ||
| export const copyToClipboard = text => { | ||
| // uses the Async Clipboard API when available. Requires a secure browing | ||
| // context (i.e. HTTPS) | ||
| if (navigator.clipboard) { | ||
| return navigator.clipboard.writeText(text) | ||
| } // puts the text to copy into a <span> | ||
| const span = document.createElement('span') | ||
| span.textContent = text // preserves consecutive spaces and newlines | ||
| span.style.whiteSpace = 'pre' // adds the <span> to the page | ||
| document.body.appendChild(span) // makes a selection object representing the range of text selected by the user | ||
| const selection = window.getSelection() | ||
| const range = window.document.createRange() | ||
| selection.removeAllRanges() | ||
| range.selectNode(span) | ||
| selection.addRange(range) // copies text to the clipboard | ||
| let success = false | ||
| try { | ||
| success = window.document.execCommand('copy') | ||
| } catch (err) { | ||
| console.log('error', err) | ||
| } // cleans up the dom element and selection | ||
| selection.removeAllRanges() | ||
| window.document.body.removeChild(span) // the Async Clipboard API returns a promise that may reject with `undefined` | ||
| // so we match that here for consistency | ||
| return success ? Promise.resolve() : Promise.reject() | ||
| } | ||
| export default text => { | ||
| const [copied, setCopied] = useState(false) | ||
| function _ref() { | ||
| return setCopied(true) | ||
| } | ||
| const copy = useCallback(() => { | ||
| const promise = copyToClipboard(text) | ||
| if (copied === false) { | ||
| promise.then(_ref) | ||
| } | ||
| }, [text]) // reset 'copied' if text changes | ||
| function _ref2() { | ||
| return setCopied(false) | ||
| } | ||
| useEffect(() => _ref2, [text]) | ||
| return [copied, copy] | ||
| } |
-54
| import {useState, useCallback, useEffect} from 'react' | ||
| export const copyToClipboard = text => { | ||
| // uses the Async Clipboard API when available. Requires a secure browing | ||
| // context (i.e. HTTPS) | ||
| if (navigator.clipboard) { | ||
| return navigator.clipboard.writeText(text) | ||
| } | ||
| // puts the text to copy into a <span> | ||
| const span = document.createElement('span') | ||
| span.textContent = text | ||
| // preserves consecutive spaces and newlines | ||
| span.style.whiteSpace = 'pre' | ||
| // adds the <span> to the page | ||
| document.body.appendChild(span) | ||
| // makes a selection object representing the range of text selected by the user | ||
| const selection = window.getSelection() | ||
| const range = window.document.createRange() | ||
| selection.removeAllRanges() | ||
| range.selectNode(span) | ||
| selection.addRange(range) | ||
| // copies text to the clipboard | ||
| let success = false | ||
| try { | ||
| success = window.document.execCommand('copy') | ||
| } catch (err) { | ||
| console.log('error', err) | ||
| } | ||
| // cleans up the dom element and selection | ||
| selection.removeAllRanges() | ||
| window.document.body.removeChild(span) | ||
| // the Async Clipboard API returns a promise that may reject with `undefined` | ||
| // so we match that here for consistency | ||
| return success ? Promise.resolve() : Promise.reject() | ||
| } | ||
| export default text => { | ||
| const [copied, setCopied] = useState(false) | ||
| const copy = useCallback( | ||
| () => { | ||
| const promise = copyToClipboard(text) | ||
| if (copied === false) { | ||
| promise.then(() => setCopied(true)) | ||
| } | ||
| }, | ||
| [text] | ||
| ) | ||
| // reset 'copied' if text changes | ||
| useEffect(() => () => setCopied(false), [text]) | ||
| return [copied, copy] | ||
| } |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
No bug tracker
MaintenancePackage does not have a linked bug tracker in package.json.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
No website
QualityPackage does not have a website.
Found 1 instance in 1 package
21225
166.31%12
100%184
29.58%63
231.58%19
375%2
100%1
Infinity%