0

I have a contact me section on my where I have email ID, so I want when people click on the email ID the email ID is copied to their clipboards.

This is the code

 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>
    )
}

Since this is a part of reusable component I have used things like lightText and darkText defined in a seperate file, so that it is easy to reuse.

I am passing the data from a data.js file which looks like this,

export const homeObjThree = {
    id: 'experience',
    lightBg: false,
    lightText: true,
    lightTextDesc: true,
    topLine: 'Contact Me',
    headLine: 'you can reach out to me at:' ,
    description:'devangmukherjee@gmail.com',
    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 description I am passing is the email ID and that is the only thing I want to be copied.

Heading is styled component looks like this

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;
  }
`;

How can I make it to look like a link? possibly when people hover over the text it underlines it and when they click on it, the text gets copied with a text that it is copied.

I tried to make this work from - In reactJS, how to copy text to clipboard?

But it didn't work. Please Help.

Update : for onCopy() I tried this but i got an error

const InfoSection = ({
    lightBg,
    imgStart,
    topLine,
    lightText,
    headLine,
    description,
    headLine2,
    img,
    alt,
    id,
    darkText,
  }) => {
    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>
    )
}

error 'state' is not defined no-undef

How do I define state here?

Devang Mukherjee
  • 185
  • 1
  • 1
  • 11

1 Answers1

1

If you want to use react-copy-to-clipboard library,

you should wrap Heading like so:

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

...

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

About making the make the text to be looking like a link, you can add this css to Heading:

cursor: pointer;

&:hover {
  text-decoration: underline;
}

Edit:

In order to show copied below, you need to have a state which changes its value upon copying the text using onCopy prop of CopyToClipboard component like this:

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)}
}
zb22
  • 3,126
  • 3
  • 19
  • 34
  • Thank you this worked flawlessly. Can you tell me how do I this? When the email id is clicked I wanted small text to appear saying 'copied' – Devang Mukherjee Nov 23 '20 at 10:03
  • @DevangMukherjee you can use the `onCopy` prop of `CopyToClipboard` component which change the current state. in npm (https://www.npmjs.com/package/react-copy-to-clipboard) there is a demo of exactly that solution for you. – zb22 Nov 23 '20 at 10:08
  • I updated the answer with ```onCopy()``` issue can you please have a look? – Devang Mukherjee Nov 23 '20 at 10:30