Struggling to implement copy-to-clipboard functionality in React JS

I have a section on my website with a contact information. I want to ensure that when users click on the email address, it gets copied to their clipboards automatically.

Here is the code snippet:

 return (
        <InfoContainer lightBg={lightBg} id={id}>
            <InfoWrapper>
                <InfoRow imgStart={imgStart}>
                    <Column1>
                    <TextWrapper>
                        <TopLine>{topLine}</TopLine>
                        <Subtitle darkText={darkText}>{headLine}</Subtitle>
                        <Heading lightText={lightText}>{description}</Heading>
                        <Subtitle darkText={darkText}>{headLine2}</Subtitle>
                    </TextWrapper>
                    </Column1>
                    <Column2>
                        <ImgWrap>
                            <Img src={img} alt={alt} />
                        </ImgWrap>
                    </Column2>
                </InfoRow>
            </InfoWrapper>
        </InfoContainer>
    )
}

This component is designed for reusability, hence I have implemented features like lightText and darkText in a separate file for easy reuse.

The data is passed from a data.js file which contains the following:

export const homeObjThree = {
    id: 'experience',
    lightBg: false,
    lightText: true,
    lightTextDesc: true,
    topLine: 'Contact Me',
    headLine: 'you can reach out to me at:' ,
    description:'<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="462223302728212b332d2e23342c232306212b272f2a6825292b">[email protected]</a>',
    headLine2: 'Or simply just drop by a hello :)',
    imgStart: false,
    img: experience,
    alt: 'alt line does not always have to boring',
    dark: true,
    primary: true,
    darkText: true,
  };

The email address is passed as the description, which is the only part I want to be copied.

The styled component Heading is defined as follows:

export const Heading = styled.h1`
  color: #fff;
  margin-bottom: 24px;
  font-size: 30px;
  line-height: 1.1 ;
  font-weight: 600;
  color: ${({ lightText }) => (lightText ? '#f7f8fa' : '#010606')};

  @media screen and (max-width: 480px) {
    font-size: 18px;
  }
`;

To make the email address look like a link, you can underline it when users hover over the text. Additionally, clicking on the text should copy it to the clipboard with a confirmation message. You may refer to resources like this link for guidance.

However, if you encounter issues such as the one mentioned for the onCopy() function, where the error 'state is not defined no-undef' occurs, you need to properly define state within the component. Here is an example:

const InfoSection = ({
    lightBg,
    imgStart,
    topLine,
    lightText,
    headLine,
    description,
    headLine2,
    img,
    alt,
    id,
    darkText,
  }) => {
    this.state = {
        value: '',
        copied: false,
      };
    return (
        <InfoContainer lightBg={lightBg} id={id}>
            <InfoWrapper>
                <InfoRow imgStart={imgStart}>
                    <Column1>
                    <TextWrapper>
                        <TopLine>{topLine}</TopLine>
                        <Subtitle darkText={darkText}>{headLine}</Subtitle>
                        <CopyToClipboard text={description} onCopy={() => this.setState({copied: true})}>
                            <Heading lightText={lightText}>{description}</Heading>
                        </CopyToClipboard>
                        {this.state.copied ? <span style={{color: '#01BF71'}}>Copied.</span> : null}
                        <Subtitle darkText={darkText}>{headLine2}</Subtitle>
                    </TextWrapper>
                    </Column1>
                    <Column2>
                        <ImgWrap>
                            <Img src={img} alt={alt} />
                        </ImgWrap>
                    </Column2>
                </InfoRow>
            </InfoWrapper>
        </InfoContainer>
    )
}

Answer №1

If you are looking to utilize the react-copy-to-clipboard library,

you will need to enclose the Heading component as shown below:

import {CopyToClipboard} from 'react-copy-to-clipboard';

...

<CopyToClipboard text={description}>
   <Heading lightText={lightText}>{description}</Heading>
<CopyToClipboard>

To style the text like a hyperlink, apply this CSS to the Heading:

cursor: pointer;

&:hover {
  text-decoration: underline;
}

Edit:

If you want to display Copied underneath upon copying the text, you must manage a state that updates when the text is copied using the onCopy prop of the CopyToClipboard component like so:

const InfoSection = ({
    lightBg,
    imgStart,
    topLine,
    ...
  }) => {

  const [copied, setCopyStatus] = React.useState(false)

  ...

  <CopyToClipboard text={description} onCopy={() => setCopyStatus(true)}>
   <Heading lightText={lightText}>{description}</Heading>
  <CopyToClipboard>
  {copied ? <span style={{color: 'red'}}>Copied.</span> : null)}
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The forkJoin method fails to execute the log lines

I've come up with a solution. private retrieveData() { console.log('Start'); const sub1 = this.http['url1'].get(); const sub2 = this.http['url2'].get(); const sub3 = this.http['url3'].get(); ...

Recreate the MUI paper background image

I'm currently integrating Material-UI into my NextJS project and I am wondering if there is a way to apply the paper background-image effect to other components as well. This would help me ensure consistency in color across different elements, especia ...

Using force-directed layout to access and retrieve specific data from external or internal data sources

Just starting out with d3js and currently working on modifying the Force directed layout found at http://bl.ocks.org/mbostock/1153292 I have managed to make it so that when I hover over the node circles, the corresponding source value filenames should app ...

JavaScript in a copied style

When using JavaScript to copy a table cell, I encountered an issue where the style was not being copied along with the content. Attempting to directly assign the style from one cell to another did not work as expected. To ensure that the text-align proper ...

Python tutorial: Scrape a website with a dropdown menu of ul-li items

Recently, I came across a query on how to scrape a particular website using Python that has a search box and javascripts. Intrigued by this question, I decided to try scraping company ratings from the website . The main goal was to input a company name in ...

Tracking locations in real time with the AR.js framework

Is it possible to utilize the AR.js web framework for creating an Augmented Reality web app that helps users navigate from their current location to a specific destination with coordinates (lat, long)? I am looking to have it compatible with Chrome/Safari ...

Storing a collection of items in an array using jQuery

Looking to organize list items from multiple lists of the same class into an array. For example: <ul class="myList"> <li>item 1</li> <li>item 2</li> </ul> <ul class="myList"> <li>i ...

Is it possible to iterate over an array and invoke a function at the same time?

const students = ['John', 'Mark']; const weight = [92, 85] const height = [1.88, 1.76] function yourBodyMass(name, funct, mass, height) { console.log(`${name}, your body mass index is ${funct(mass, height)}.`) } function calculateBM ...

Wrapping header text in Vuetify's v-data-table

Struggling with wrapping the header text on a v-data-table component. I've tried applying styles, but only tbody elements are affected. The header (thead element) remains unchanged. Any suggestions on how to get custom styling for the header? For ins ...

Upon encountering an issue with starting the create-react-app script

Encountered an error at the beginning of the script while running the command below: npm start The Issue The project dependency tree may be causing a problem. This is not likely a bug in Create React App, but rather something that needs fixing on your ...

Centered CSS Box with Pointing Arrow

I'm looking for a way to create a unique div design that includes an arrow pointing downwards attached to the bottom. After some exploration, I was able to achieve this look through this process: http://jsfiddle.net/hyH48/. However, my challenge lies ...

Sending a parameter to an (internationally?) externalized class

Forgive me if this question seems convoluted - my grasp on the intricacies of module.export functionality and class scoping may be lacking, but I'll do my best to elaborate. At present, I possess a discord bot with a music player that incorporates a M ...

AngularJS controller exceeding allowed complexity (SonarLint alert)

While utilizing SonarLint in Eclipse, I encountered an issue while working on an AngularJS application. Specifically, I was cleaning up a controller to improve readability when SonarLint flagged the following problem: The function has a complexity of 11 ...

Prevent caching in Internet Explorer 11 when using AJAX requests

In my current project, I am encountering a problem with AJAX specifically in Internet Explorer 11. The issue arises when the page requests certain values from the server through an AJAX call using the following code snippet: var xmlhttp; if (window.XMLHtt ...

Maintain the current application state within a modal until the subsequent click using Jquery

Due to the challenges faced with drag and drop functionality on slow mobile devices, I am considering implementing a modal approach for moving elements from one place to another. Here is how it would work: When a user clicks on an item, it is visually ma ...

Troubleshooting: Images not displaying on webpage due to Ajax, JQuery, and JavaScript integration

I'm currently working on building a dynamic photo gallery using Ajax and JQuery in Javascript. I have set up a directory named "images" in Visual Studio Code and it contains my selection of 5 images. However, when I click the "next" and "previous" but ...

Determining the optimal times to utilize traditional loops instead of array helpers

After writing in Javascript for some time, I've become quite comfortable with using array helpers. However, there have been moments where traditional for loops seem more practical and easier to work with compared to array helpers. Can you provide me w ...

Welcome to Digital Ocean! It appears you are attempting to utilize TypeScript

Over the past 48 hours, I've been struggling to build my project on a DO App. Strangely enough, there were no changes made to the project, yet out of nowhere it started breaking with an unexpected error message: [2023-04-06 09:03:02] │ It seems like ...

What is the proper way to detach an event listener from a class?

I am facing a challenge when trying to remove an event listener. After running the script, I receive an error message stating that changeGirl.off("click") is not a function. Despite this issue, everything else within the code is working perfectly fine. Any ...

The event was triggered, however, some sections of the code did not run

I am currently working on a project called lan-info on GitHub. Here is the code snippet that I am using: let arpSweepCommand = './arpSweep.sh'; app.get('/arp', (req, res) => { console.log('we have a working signal!'); ...