GithubHelp home page GithubHelp logo

charlesstover / use-clippy Goto Github PK

View Code? Open in Web Editor NEW
181.0 3.0 11.0 1022 KB

React Hook for reading from and writing to the user's clipboard.

Home Page: https://www.npmjs.com/package/use-clippy

License: MIT License

TypeScript 100.00%
npm npmjs react reactjs react-hooks clipboard clipboard-manager clipboard-managers clipboard-management clipboard-js

use-clippy's Introduction

useClippy Tweet version minified size minzipped size downloads build

useClippy is a TypeScript-friendly React hook for reading from and writing to the user's clipboard.

Not to be confused with Microsoft Office's assistant, Clippy. ๐Ÿ“Ž

Demo

You can see use-clippy in action via GitHub Pages, which hosts the demo directory.

Install

  • npm install use-clippy or
  • yarn add use-clippy

Use

useClippy() returns a tuple analogous to useState, where the first item is the clipboard contents and the second item is a function for setting the clipboard contents.

import React from 'react';
import useClippy from 'use-clippy';

export default function MyComponent() {

  // clipboard is the contents of the user's clipboard.
  // setClipboard('new value') wil set the contents of the user's clipboard.
  const [clipboard, setClipboard] = useClippy();

  return (
    <div>

      {/* Button that demonstrates reading the clipboard. */}
      <button
        onClick={() => {
          alert(`Your clipboard contains: ${clipboard}`);
        }}
      >
        Read my clipboard
      </button>

      {/* Button that demonstrates writing to the clipboard. */}
      <button
        onClick={() => {
          setClipboard(`Random number: ${Math.random()}`);
        }}
      >
        Copy something new
      </button>
    </div>
  );
}

Sponsor ๐Ÿ’—

If you are a fan of this project, you may become a sponsor via GitHub's Sponsors Program.

use-clippy's People

Contributors

0xflotus avatar dependabot-preview[bot] avatar dependabot[bot] avatar quisido avatar vanchoy 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

use-clippy's Issues

Only write permissions version

I only need to be able to put a string in the user's clipboard in my project, if there was a hypothetical clippy version with only write functionality would it avoid the need for the user to give permission to the site to read the clipboard's contents? It would be nice to reduce friction for the user.

React version dependency

Could you please update the dependency for the React version, because on npm i it looks for React 16.8 and we are already on 18+ and it throws an error. On React 17+ works with manual --force install.

Using clippy across multiple components does not propagate changes to the clipboard of each component

Thanks for this great utility.

I am using clippy across multiple components as you can see here and when copying text to the clipboard from component 1, changes are not detected in the main component. Is this how it is intended to work or the way it is coded in the link is wrong? If I do a ctrl V or paste from the context menu, I can pick up the changes made to the clipboard from any of the components.

Thanks.

Get clipboard contents on load?

I'm able to get the clipboard contents when I copy something on the page but not when I already have something in the clipboard.

Is it possible to get the clipboard contents on page load?

Failed to copy with DOMException document not focused in latest firefox / chrome.

It failed to copy to clipboard with DOMException document not focused in latest firefox / chrome.

It seems to me the root clause is at the

const write = (text: string): void => {
defocused the document and after it failed, it try the clipboard API which throws the DOMException.

It seems it works if I restore the original focus:

const write = (text: string): void => {
  const textArea: HTMLTextAreaElement = createTextArea();
  const curActiveElement = document.activeElement as HTMLElement
  textArea.value = text;
  textArea.select();
  const success: boolean = document.execCommand('copy');
  removeElement(textArea);
  if(curActiveElement) curActiveElement.focus()
  if (!success) {
    throw NOT_ALLOWED_ERROR;
  }
};

I guess similar problem exists for reading the clipboard but I did not use / test it.

Safari support

Thought it would work for multiple browsers, does it currently only work for Chrome ?

Chrome is reading the clipboard correctly, Safari returns an empty string.

paste not updating `clipboard`

I can read the current content of the clipboard just fine, but if I paste new content, clipboard is not updated. I tried it on https://charlesstover.github.io/use-clippy/ as well, but nothing.

Am I missing something or does this hook not support live paste events?

Edit: I tried this on macOS with both Chrome and Brave.

And yes, I allowed clipboard access.
image

image support?

Does use-clippy work with images?

I've tried using it in my project, but I'm having no luck.

Wanted to check if this would be a feature request / something you are looking at - or is this out of scope?

Great little utility otherwise ๐Ÿ‘

modal with useClippy in it scrolls the page

I encountered kinda strange behaviour, I made a fullscreen modal for my project, which has sharing buttons. facebook, twitter, reddit, mail and...copy of URL with use of your library. However when I click on a button that opens that modal and useClippy is not commented then it scrolls 640 pixels in Y axis somehow. When I comment and not use useClippy then it works perfectly fine.
without useClippy:
image

with (at the top you can see my bookmarks bar for reference):
image

faulty code:

const ShareModal = ({handleClose}) => {
  const url = 'http://www.google.com'
  const [clipboard, setClipboard] = useClippy()
  return (
    <Modal>
      <div className={styles.wrapper}>
          <div className={styles.close} onClick={handleClose}/>
          <h2 className={styles.title}>Share it!</h2>
          <FacebookShareButton url={`${url}`} className={styles.mediaLink} onClick={handleClose}>
            <FacebookIcon size={32} borderRadius={32}/> <span className={styles.mediaText}>Facebook</span>
          </FacebookShareButton>
          <TwitterShareButton url={`${url}`} className={styles.mediaLink} onClick={handleClose}>
            <TwitterIcon size={32} borderRadius={32}/> <span className={styles.mediaText}>Twitter</span>
          </TwitterShareButton>
          <RedditShareButton url={`${url}`} className={styles.mediaLink} onClick={handleClose}>
            <RedditIcon size={32} borderRadius={32}/> <span className={styles.mediaText}>Reddit</span>
          </RedditShareButton>
          <EmailShareButton url={`${url}`} className={styles.mediaLink} onClick={handleClose}>
            <EmailIcon size={32} borderRadius={32}/> <span className={styles.mediaText}>Mail</span>
          </EmailShareButton>
          <div url={`${url}`} className={styles.mediaLink} onClick={()=> {setClipboard(url); handleClose()}}>
            <img src={urlCopy} className={styles.mediaImage}/> <span className={styles.mediaText}>Copy link</span>
          </div>
      </div>
    </Modal>
    
  );
}

working code:

const ShareModal = ({handleClose}) => {
  const url = 'http://www.google.com'
  return (
    <Modal>
      <div className={styles.wrapper}>
          <div className={styles.close} onClick={handleClose}/>
          <h2 className={styles.title}>Share it!</h2>
          <FacebookShareButton url={`${url}`} className={styles.mediaLink} onClick={handleClose}>
            <FacebookIcon size={32} borderRadius={32}/> <span className={styles.mediaText}>Facebook</span>
          </FacebookShareButton>
          <TwitterShareButton url={`${url}`} className={styles.mediaLink} onClick={handleClose}>
            <TwitterIcon size={32} borderRadius={32}/> <span className={styles.mediaText}>Twitter</span>
          </TwitterShareButton>
          <RedditShareButton url={`${url}`} className={styles.mediaLink} onClick={handleClose}>
            <RedditIcon size={32} borderRadius={32}/> <span className={styles.mediaText}>Reddit</span>
          </RedditShareButton>
          <EmailShareButton url={`${url}`} className={styles.mediaLink} onClick={handleClose}>
            <EmailIcon size={32} borderRadius={32}/> <span className={styles.mediaText}>Mail</span>
          </EmailShareButton>
          <div url={`${url}`} className={styles.mediaLink} onClick={()=> {handleClose()}}>
            <img src={urlCopy} className={styles.mediaImage}/> <span className={styles.mediaText}>Copy link</span>
          </div>
      </div>
    </Modal>
    
  );
}

CSS (just in case):

.wrapper {
  display: flex;
  flex-direction: column;
  min-width: 280px;
  position: relative;
}

.mediaLink {
  display: flex;
  align-items: center;
  width: 100%;
  padding: 8px !important;
  border-radius: 10px;
  cursor: pointer;
  &:not(:last-of-type) {
    margin: 0 0 8px;
  }
  &:hover {
    background: rgba(0,0,0,0.2) !important;
  }
  &:active, &:focus {
    background: rgba(0,0,0,0.4) !important;
    outline: none;
  }
}

.mediaText {
  margin: 0 0 0 16px;
}

.mediaImage {
  width: 32px;
  height: 32px;
  background: #006186;
  border-radius: 16px;

}

.title {
  font-size: 24px;
  font-weight: bold;
  text-align: center;
}

.close {
  position: absolute;
  top: 8px;
  right: 8px;
  width: 20px;
  height: 20px;
  background: red;
  border-radius: 10px;
  cursor: pointer;
  &::after {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%) rotate(45deg);
    content: '';
    display: block;
    height: 12px;
    width: 2px;
    background: white;
  }
  &::before {
    position: absolute;
    content: '';
    display: block;
    height: 12px;
    width: 2px;
    background: white;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%) rotate(-45deg);
  }
}

Have problem on Firefox

08:57:56.210 TypeError: nav.clipboard.readText is not a function use-clippy.js:130

I'm using React 16.8 and Node 10.16, Firefox 69

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.