Giter Site home page Giter Site logo

react-clipboard.js's Introduction

React-Clipboard

React wrapper for clipboard.js

Build Status Dependency Status

Installation

$ npm i --save react-clipboard.js

Usage

You can use clipboard.js original data-* attributes:

import ReactDOM from 'react-dom';
import React, { Component } from 'react';
import Clipboard from 'react-clipboard.js';

class MyView extends Component {
  render() {
    return (
      <Clipboard data-clipboard-text="I'll be copied">
        copy to clipboard
      </Clipboard>
    );
  }
}

ReactDOM.render(<MyView/>, document.getElementById('app'));
  • If you want to provide any constructor option as in new Clipboard('#id', options), you may use option-* attributes

  • callbacks will be connected via on* attributes (such as onSuccess)

import ReactDOM from 'react-dom';
import React, { Component } from 'react';
import Clipboard from 'react-clipboard.js';

class MyView extends Component {
  constructor() {
    super();

    this.onSuccess = this.onSuccess.bind(this);
    this.getText = this.getText.bind(this);
  }

  onSuccess() {
    console.info('successfully copied');
  }

  getText() {
    return 'I\'ll be copied';
  }

  render() {
    // Providing option-text as this.getText works the same way as providing:
    //
    // var clipboard = new Clipboard('#anything', {
    //   text: this.getText,
    // });
    //
    // onSuccess works as a 'success' callback:
    //
    // clipboard.on('success', this.onSuccess);
    return (
      <Clipboard option-text={this.getText} onSuccess={this.onSuccess}>
        copy to clipboard
      </Clipboard>
    );
  }
}

ReactDOM.render(<MyView/>, document.getElementById('app'));

Custom HTML tags may be used as well (you can use custom components as well): Beware: Stateless/Functional components are yet to be added

import ReactDOM from 'react-dom';
import React, { Component } from 'react';
import Clipboard from 'react-clipboard.js';

class MyView extends Component {
  render() {
    // Clipboard is now rendered as an '<a>'
    return (
      <Clipboard component="a" button-href="#" data-clipboard-text="I'll be copied">
        copy to clipboard
      </Clipboard>
    );
  }
}

ReactDOM.render(<MyView/>, document.getElementById('app'));

Default html properties may be passed with the button-* pattern:

import ReactDOM from 'react-dom';
import React, { Component } from 'react';
import Clipboard from 'react-clipboard.js';

class MyView extends Component {
  render() {
    return (
      <Clipboard data-clipboard-text="I'll be copied" button-title="I'm a tooltip">
        copy to clipboard
      </Clipboard>
    );
  }
}

ReactDOM.render(<MyView/>, document.getElementById('react-body'));

License

This code is released under CC0 (Public Domain)

react-clipboard.js's People

Contributors

ahmetcetin avatar annuhdo avatar bondz avatar domoritz avatar hashwin avatar kmalakoff avatar marcinlichwala-tomtom avatar mazuh avatar nene avatar nihey avatar ppvg avatar seanmheff avatar thebosz avatar veeramarni avatar worldmaker avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

react-clipboard.js's Issues

Do not add type prop when component is not button or input

I'd like to render the ClipboardButton as simple div, so I write:

<CliboardButton component="div"/>

which will result in:

<div type="button"/>

In my case this conflicts with normalize.css which has rules like:

button,
html [type="button"],
[type="reset"],
[type="submit"] {
  -webkit-appearance: button;
}

resulting in div rendered with a look of a button. My current workaround is to use some silly value for the type prop:

<CliboardButton component="div" type="blah"/>

call destroy to cleanup

found out that destroy is never called, so the event listener will never be cleaned up when unmounting the react component. This should be handled in componentWillUnmount

from clipboard.js docs:

var clipboard = new Clipboard('.btn');
clipboard.destroy();

Cannot run mocha tests

Hi,

Thanks a lot for your work on react-clipboard!

We have an issue when running mocha tests using:
mocha --compilers js:babel-core/register ...

We have the following error:

(function (exports, require, module, __filename, __dirname) { import React fro
                                                              ^^^^^^
SyntaxError: Unexpected reserved word
    at Module._compile (module.js:439:25)

This is because the main index file of the package is using ES6 syntax. Babel, by default does not try to do any transformations for node_modules packages:

http://babeljs.io/docs/usage/require/#usage

We tried to do what was suggested here, although it is really advised that node modules, for accessibility purposes, use a transpiled version:

http://stackoverflow.com/questions/31822593/import-a-module-from-node-modules-with-babel-but-failed#answer-31822668

To make it work with Babel, we also had to do require a custom file as described here:

http://stackoverflow.com/questions/20049790/how-to-pass-compiler-options-to-mocha#answer-28700064

We got passed this issue but got another one here:

/Users/olivier/Documents/sources/outfit_repos/outfit/node_modules/clipboard/node_modules/good-listener/node_modules/delegate/node_modules/closest/node_modules/matches-selector/index.js:6
var proto = Element.prototype;
            ^
ReferenceError: Element is not defined
    at Object.<anonymous> (/Users/olivier/Documents/sources/outfit_repos/outfit/node_modules/clipboard/node_modules/good-listener/node_modules/delegate/node_modules/closest/node_modules/matches-selector/index.js:6:13)
    at Module._compile (module.js:456:26)
    at Module._extensions..js (module.js:474:10)

Are we missing anything?

Thanks a lot for your feedback!

Usage in modal

I'm having the usual problem of this not working in a modal.
I tried the recommended solution of option-container as noted in the advanced usage, but can't get that to work.

https://clipboardjs.com/#advanced-usage

I'm specially using material ui rather the the bootstrap modal but it should be the same fix.

Add typescript definition

Hi,

I was hoping to use this with my Typescript project, but I noticed that @types/react-clipboard.js doesn't exist. Having a type definition would be super useful!

How to render my content?

I want to render my content And don't want it wrapped on a button or input.
I just want the ability of copy.
Can we do this by a props attribute?

Install broken

npm ERR! [email protected] install: `webpack -p`
npm ERR! spawn ENOENT
npm ERR! 
npm ERR! Failed at the [email protected] install script 'webpack -p'.
npm ERR! This is most likely a problem with the react-clipboard.js package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     webpack -p
npm ERR! You can get their info via:
npm ERR!     npm owner ls react-clipboard.js
npm ERR! There is likely additional logging output above.

I don't think it is a good idea to be compiling assets on release. Users of the library should get a known-to-be tested version of the library instead of something that is dynamically generated.

unsafe-eval in react-clipboard.js

the compiled output uses eval, which throws against a CSP that forbids eval.

probably related to webpack/webpack#6461

ExtensionConfig.a7e6ddbd.js:411 Uncaught EvalError: Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src 'self' https://www.google-analytics.com".

    at Object../index.js (ExtensionConfig.a7e6ddbd.js:411)
    at o (ExtensionConfig.a7e6ddbd.js:411)
    at ./index.js (ExtensionConfig.a7e6ddbd.js:411)
    at ExtensionConfig.a7e6ddbd.js:411
    at ExtensionConfig.a7e6ddbd.js:411
    at Object.parcelRequire.BRDb.clipboard (ExtensionConfig.a7e6ddbd.js:411)
    at f (ExtensionConfig.a7e6ddbd.js:1)
    at p (ExtensionConfig.a7e6ddbd.js:1)
    at Object.parcelRequire.qckN.react (ExtensionConfig.a7e6ddbd.js:427)
    at f (ExtensionConfig.a7e6ddbd.js:1)

"Copied" tooltip

Hi, thanks for the application!
How can I show tooltip after copy value?
copied

I don't get the functionality

Forgive me if I'm missing something here, but based on the examples, you're not actually copying the element -- you're copying some text defined in a JavaScript object, correct? I think it's misleading to name this after clipboard.js, as one of the features of that was the ability to copy the content of actual DOM elements (including HTML that didn't need to be escaped). It supported rich-text copying as well (equivalent to ctrl+a, ctrl+c on a webpage)

Is there an example of this usage, or is this supported?

Thanks for hearing me out as I continue to look for a solution.

React Element as Component

The components currently renders a button by default or lets the user specify a HTML tag as string to render.

This can be expanded to allow the component accept a React Element as the component to render. For example.

<ClipboardButton component={MyReactElement} data-clipboard-text="Hello World" />

This would require that the component only renders a button and passes all props along to the component. I'm might cause breaking changes.

This is an example I'm hoping to achieve

<ClipboardButton component={MyCustomElement} customElementProp="string" disabled />

As of now, only specific props are passed to the component, and the button's attributes must be prefixed with button-

This would require some changes and better tests.
My initial take on this is here


  • Allow React Element to be passed as prop
  • Remove the need for button-* props
  • option-* props should be passed as objects object
  • Better tests
  • Document API

option-text propType validation?

Hello,

Thanks for making react-clipboard.js!

I ran into a problem the other day in a project that uses react-clipboard. We are using the option-text onSuccess pattern for copying and alerting to the user that a copy occurred.

We inadvertently passed a string as our option-text prop instead of a function that returns a string. This caused the copy functionality to break.

Would it be possible to add additional prop validation for common option props like option-text?

After looking at the code, I realize this might be a bit more challenging than I had originally expected, since it seems that all of the option-* params are dynamic.

provide type property for the button

If I use the element which is created by the library within a form and press the copy button it triggeres a submit of my form, which is not the expected behavior.

Fix would be if the type can be set from the caller, like

<ClipboardButton type={'button'} option-text={this.getText} onSuccess={this.onSuccess}>
   copy to clipboard
</ClipboardButton>

API Changes

I was thinking about changing the API a little bit so that a clipboard option insertion would be made easier:

Today we have:

var MyView = React.createClass({
  clipboardOptions: {
    text: function() {
      return "Dynamic content copying"
    },
  },

  render: function() {
    return <div>
      <ClipboardButton options={this.clipboardOptions}>
        copy to clipboard
      </ClipboardButton>
    </div>;
  },
});

I would change it to:

var MyView = React.createClass({
  getText: function() {
    return "Dynamic content copying";
  },

  render: function() {
    return <div>
      <ClipboardButton options-text={this.getText}>
        copy to clipboard
      </ClipboardButton>
    </div>;
  },
});

So that everything that was inside this.props.options would now come from this.props['options-*']

Anyone who's currently using this project has any issue with this?

Why only button tag?

Could it render other tag like span or div?

      <Clipboard component="div" data-clipboard-text="I'll be copied">
        copy to clipboard
      </Clipboard>

Add class on success

Hi,

I would like to add a specific className on success. How can I do this?

Thanks,
Maxime

When using Custom HTML tag it should not care about children supplied to ClipboardButton

When using Custom HTML tag it should not care about children supplied to ClipboardButton.

I am trying to create a Clipboard component like this:

<Clipboard component="a" button-href="#" data-clipboard-text={window.location.href}><i className="fa fas fa-link"></i> Copy Link </Clipboard>

I am getting this error:

Warning: Failed prop type: Invalid prop `children` supplied to `ClipboardButton`.

Allow option to instantiate clipboard.js by passing in HTMLElement rather than the selector String.

Clipboard.js supports an option now where we can pass in an HTMLElement in the constructor, see:

https://github.com/zenorocha/clipboard.js/blob/master/demo/constructor-node.html#L16-L19

This is useful, because in some situations we want to stopPropagation on the copy link, but in the current way of doing this it results that the event is not propagated to the clipboard.js package.

There are several issues on clipboard.js github page regarding stopPropagation, where the author suggest to use this approach:

I have tested with this component, and instantiating Clipboard by passing the DOMNode fixes my problem:

        this.clipboard = new Clipboard(ReactDOM.findDOMNode(this), options);

Edit-2: A better way seems to be to use this.refs instead. This also works fine. See my fork as an experiment.

However, would be nice if the component was updated with a property to use string instantiation or HTMLElement instantiation.

Edit-1: Perhaps this should even be the official implementation? The old clipboard.js API that takes a selector was pretty weird and this plugin is also doing all sorts of magic to work around that, by using a counter and creating a custom id ...

Something related to custom components is messed up

When supplying custom component as a component prop, there are some errors:

Warning: Failed prop type: Invalid prop `component` supplied to `ClipboardButton`, expected a ReactNode.
Warning: Failed prop type: Invalid prop `children` supplied to `ClipboardButton`.

My code:

import Clipboard from 'react-clipboard.js'
import Button from 'ui/button'

...

<Clipboard component={ Button }>
   { this.props.children }
</Clipboard>

onError doesn't working

I'm trying to use onError function, but doesn't work.

The onSuccess works like a charm :)

Can you help with this?

[email protected] issues

First of all:
react-clipboard.js
and
react-clipboard.min.js
are minified both.
3266 bytes.
And I get an error with minified version (using webpack)

ERROR in ./~/react-clipboard.js/dist/react-clipboard.js
  Module parse failed: /opt/python/bundle/153/app/node_modules/react-clipboard.js/dist/react-clipboard.js Unexpected token (1:2333)

Add ID attribute

I've been trying to get a Bootstrap tooltip working with the clipboard component but there's no way for me to do ids at the moment

Version 0.2.0 doesn't work on React 0.13

Looks like the library was recently changed to use refs.element. In React 0.13, you'd need to call refs.element.getDOMNode(). I think it's fine to not support old React versions, but you should probably update the peerDependencies in package.json accordingly.

If component is 'a' there is no way to prevent page reload

<ClipboardButton
 component='a'
 button-href={someUrl}
 data-clipboard-text={someUrl}
 onSuccess={() => console.log('copied')}
</ClipboardButton>

I need to be able to click on the button/link via "Open in new tab" (or Ctrl/Cmd + click) so it opens such a someUrl into a new browser tab. So I need that component='a'.

At the same time, if I just do a normal click on the button/link I just want the onSuccess to happen, but not the page reload or page navigation action. For this to happen, the internally generated <a> component should react on onClick (so it calls event.preventDefault(), but that's not possible with the current API.

What about exposing a onComponentClick(event) prop into ClipboardButton so the app can control it?

SSR: ReferenceError: window is not defined

I get an error on server side rendering after updating from v2.0.3 to v2.0.5:

/.../node_modules/react-clipboard.js/dist/react-clipboard.js:10
})(window, function(__WEBPACK_EXTERNAL_MODULE_clipboard__, __WEBPACK_EXTERNAL_MODULE_prop_types__, __WEBPACK_EXTERNAL_MODULE_react__) {
   ^
ReferenceError: window is not defined
    at Object.<anonymous> (/.../node_modules/react-clipboard.js/dist/react-clipboard.js:10:4)

Using NodeJS v10.14.2

2.0.0: Error: Cannot find module './clipboard-action'

I upgraded react-clipboard.js from 1.1.3 to 2.0.0. When running browserify on my project now I get this error:

Error: Cannot find module './clipboard-action' from '/XXXXX/node_modules/clipboard/dist'

Indeed, node_modules/clipboard/dist just contains this:

clipboard.js
clipboard.min.js

Make the component isomorphic

Please make the component isomorphic. Now it can't be used for serverside rendering because it uses things like Element.

Fails in Safari

I have the Clipboard component working perfectly on the Chrome and Firefox browsers, but on Safari it fails quietly.
I've added onError={this._handleClipboardError} to see what was going wrong but there are no details there.

screen shot 2016-03-14 at 1 57 09 pm

Failed propType: Required prop `value` was not specified

I followed the documentation down to the "t" but for some reason, I'm getting this error upon basic rendering: "Warning: Failed propType: Required prop value was not specified in <<anonymous>>."

Here's my code:

var React = require('react');
var ClipboardButton = require('react-clipboard');

var TestComponent = React.createClass({
  render: function() {
   return (
      <div>
       <ClipboardButton data-clipboard-text="test copy text">
              Child Text
        </ClipboardButton>
    </div>
    );
  }
});

module.exports = TestComponent;

`

I was really hoping to integrate this module into my project. Any help would be much appreciated!

propagate attributes to <button>

Please propagate all non-ClipboardButton specific attributes to contained button. Currently I can't set eg. title. or id (which is now autogenerated). Thanks.

'style' prop should be object

Hi,

I've set this up in my project and it works well.
But I am getting some warnings that don't seem right.

Warning: Failed prop type: Invalid prop `style` of type `object` supplied to `ClipboardButton`, expected `string`.

Aren't inline styles usually objects?

Warning: Failed prop type: Invalid prop `children` supplied to `ClipboardButton`.

Not sure why we would have to explicitly allow children, maybe something is disallowing it?

How to make option-text derive from async/await

Hello, I need help

getClipboardText = async () => {
    const { uid, templateId, content } = this.props
    const { data } = await getTinyUrl(templateId, { uid })
    return `${content} ${data}`
}
render () {
    return <Clipboard option-text={this.getClipboardText} >Copy</Clipboard>
}

Code above doesnt work, why and how to make it works

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.