├── .npmignore ├── .babelrc ├── .gitignore ├── assets └── ZeroClipboard.swf ├── package.json ├── loadScript.js ├── README.md ├── docs.js ├── index.html └── index.js /.npmignore: -------------------------------------------------------------------------------- 1 | index.html 2 | docs.js 3 | -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["react"] 3 | } 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | docs-bundle.js 3 | .idea/ 4 | -------------------------------------------------------------------------------- /assets/ZeroClipboard.swf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brigand/react-zeroclipboard/HEAD/assets/ZeroClipboard.swf -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-zeroclipboard", 3 | "version": "4.0.1", 4 | "description": "react component for zeroclipboard", 5 | "main": "index.js", 6 | "keywords": [ 7 | "react", 8 | "clipboard", 9 | "react-component" 10 | ], 11 | "scripts": { 12 | "test": "echo \"Error: no test specified\" && exit 1", 13 | "docs": "npm run browserify", 14 | "browserify": "browserify -d -t babelify docs.js -o docs-bundle.js" 15 | }, 16 | "repository": "https://github.com/brigand/react-zeroclipboard.git", 17 | "homepage": "http://brigand.github.io/react-zeroclipboard/", 18 | "author": "Frankie Bagnardi ", 19 | "license": "MIT", 20 | "devDependencies": { 21 | "babel-core": "^6.0.12", 22 | "babel-preset-react": "^6.0.12", 23 | "babelify": "^7.0.2", 24 | "browserify": "^9.0.8", 25 | "envify": "^3.4.0", 26 | "react": "^0.14.0", 27 | "react-dom": "^0.14.0" 28 | }, 29 | "browserify": { 30 | "transform": [ 31 | "envify" 32 | ] 33 | }, 34 | "dependencies": { 35 | "create-react-class": "^15.5.3", 36 | "envify": "^3" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /loadScript.js: -------------------------------------------------------------------------------- 1 | var loading = {}; 2 | 3 | module.exports = function loadScript(src, callback){ 4 | if (typeof(window) === 'undefined') return; 5 | 6 | // we don't want duplicate script elements 7 | // so we use an array of callbacks instead of 8 | // multiple onload handlers 9 | if (loading[src]) { 10 | loading[src].push(callback); 11 | return; 12 | } 13 | 14 | // create the array of callbacks 15 | loading[src] = [callback]; 16 | 17 | // create a script, and handle success/failure in node callback style 18 | var script = document.createElement('script'); 19 | script.onload = function(){ 20 | loading[src].forEach(function(cb){ 21 | cb(); 22 | }); 23 | delete loading[src]; 24 | }; 25 | 26 | script.onerror = function(error){ 27 | loading[src].forEach(function(cb){ 28 | cb(error) 29 | }); 30 | delete loading[src]; 31 | }; 32 | 33 | // set the src and append it to the head 34 | // I believe async is true by default, but there's no harm in setting it 35 | script.async = true; 36 | script.src = src; 37 | document.getElementsByTagName("head")[0].appendChild(script); 38 | }; 39 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | ## react-zeroclipboard 3 | 4 | This is a wrapper around ZeroClipboard for use with React. ZeroClipboard has a difficult to work with api 5 | which is being abstracted from you. This library... 6 | 7 | * asynchronusly loads zeroclipboard from cdnjs 8 | * handles mounting/unmounting of components 9 | * figures out which element was clicked 10 | * allows you to declare text/html/rtf, or pass a function which returns it dynamically 11 | 12 | ## Warning! 13 | 14 | zero-clipboard uses flash which is being phased out across many browsers, and is sometimes buggy in the browsers that do support it. There have been reports of the plugin randomly not working, despite no significant changes to the plugin, and keeping the same zero-clipboard version. 15 | 16 | If you're interested in solving this, your help is very much appreciated, and this section will be replaced with a big "thank you" for your work. Until then, using this plugin isn't recommended. 17 | 18 | ### Install 19 | 20 | This is only available through npm, it should work with browserify or webpack. It's compatible with react 0.13 and up. 21 | 22 | ```sh 23 | npm install --save react-zeroclipboard 24 | ``` 25 | 26 | Or for react 0.11 and 0.12 27 | 28 | ```sh 29 | npm install --save react-zeroclipboard@0.4 30 | ``` 31 | 32 | Also install react if you haven't already (of course). 33 | 34 | ### Usage 35 | 36 | Here's a simple example: 37 | 38 | ```js 39 | render: function(){ 40 | return ( 41 |
42 |

Click the button to copy some text

43 | 44 | 45 | 46 |
47 | ) 48 | } 49 | ``` 50 | 51 | The full api offers more flexibility. If you provide e.g. html and text, they'll both be set and 52 | the application you're pasting into decides which one to use. Methods have higher priority than 53 | the literal strings, if for some reason you pass both. 54 | 55 | ```js 56 | String)} 61 | getHtml={(Void -> String)} 62 | getRichText={(Void -> String)} 63 | 64 | onCopy={(Event -> Void)} 65 | onAfterCopy={(Event -> Void)} 66 | onErrorCopy={(Error -> Void)} 67 | 68 | onReady={(Event -> Void)} 69 | 70 | // optional 71 | swfPath="http://user_defined_cdn_path/ZeroClipboard.swf" 72 | /> 73 | ``` 74 | 75 | Here's an example where we copy the current url to the clipboard, both in plain text and a html anchor 76 | 77 | If the user pastes this in their address bar they get the url, and if they paste it in gmail they get a nice link. 78 | 79 | ```js 80 | render: function(){ 81 | return ( 82 |
83 |

Copy a link to this page

84 | My Page'; }}> 87 | 88 | 89 |
90 | ) 91 | } 92 | ``` 93 | 94 | ## I'm getting weird ZeroClipboard errors 95 | 96 | Usually this is caused by flash weirdness and/or cdnjs where we pull ZeroClipboard from. You can work around this 97 | by hosting ZeroClipboard and the swf yourself. Make sure the page and the two assets are either both http, or both 98 | https. There's a copy of the swf in the assets directory of this repo. 99 | 100 | To access it with webpack, configure a loader for swf files: 101 | 102 | ```js 103 | { 104 | test: /\.swf$/g, 105 | loader: 'file-loader' 106 | } 107 | ``` 108 | 109 | And then import the swf from this package. 110 | 111 | ```jsx 112 | 113 | ``` 114 | -------------------------------------------------------------------------------- /docs.js: -------------------------------------------------------------------------------- 1 | var React = require('react'); 2 | var createReactClass = require('create-react-class'); 3 | var ReactDOM = require('react-dom'); 4 | var ReactZeroClipboard = require('./'); 5 | window.d = ReactDOM; 6 | var npmInstallCommand = "npm install react-zeroclipboard"; 7 | var zclipProps = { 8 | swfPath: './assets/ZeroClipboard.swf' 9 | }; 10 | 11 | NpmInstallLink = createReactClass({ 12 | render: function(){ 13 | return ( 14 |
15 | 16 | 17 | Copy 18 | 19 |
20 | ); 21 | } 22 | }); 23 | ReactDOM.render(, document.getElementById("npm-install-link-target")); 24 | 25 | 26 | 27 | var list = [ 28 | "apples", "oranges", "bananas" 29 | ]; 30 | 31 | var MultiTypeDemo = createReactClass({ 32 | getText: function(){ 33 | return list.map(function(x){ return "- " + x }).join("\n"); 34 | }, 35 | getHtml: function(){ 36 | var items = list.map(function(x, i){ 37 | if (i % 2) { 38 | return "
  • " + x + "
  • " ; 39 | } 40 | else { 41 | return "
  • " + x + "
  • " ; 42 | } 43 | 44 | }); 45 | return "
      " + items.join('\n') + "
        "; 46 | }, 47 | render: function(){ 48 | return ( 49 |
        50 | 51 |
        Copy List
        52 |
        53 |
        54 |
        55 |