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:'[email protected]',
    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?

1 Answer 1

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)}
}
Sign up to request clarification or add additional context in comments.

3 Comments

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'
@DevangMukherjee you can use the onCopy prop of CopyToClipboard component which change the current state. in npm (npmjs.com/package/react-copy-to-clipboard) there is a demo of exactly that solution for you.
I updated the answer with onCopy() issue can you please have a look?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.