In this article, we are going to learn and develop a feature - click to copy. This comes handy if you want your users to share a post or important data for example - a cars details.

To illustrate this feature, let's consider the example of sharing car details. When a user visits your website, you'll want to provide them with a button that allows them to effortlessly copy essential information about the car, like its make, model, vehicle type, and price.

Let get going.

First let's build a card that shows car information.

Car details card

Now when a user clicks on the Share button, all the car details will be copied to the clipboard.

Here is the basic component that render the car details: 

import "./App.css";

const SingleCar = () => {
	return (
		<div className="single-car">
			<img src="hector.webp" />
			<div className="car-details">
				<h2>MG Hector</h2>
				<div className="flex">
					<p>Price</p>
					<p>$1,059,763</p>
				</div>
				<div className="flex">
					<p>Engine</p>
					<p>1451 to 1956 cc</p>
				</div>
				<div className="flex">
					<p>Fuel Type</p>
					<p>Petrol & Diesel</p>
				</div>
				<div className="flex">
					<p>Transmission</p>
					<p>Manual & Automatic</p>
				</div>
				<div className="flex">
					<p>Seating Capacity</p>
					<p>5 Seater</p>
				</div>
			</div>
			<div className="btn-group">
				<button>Book Now</button>
				<button>Copy Details</button>
			</div>
		</div>
	);
};

function App() {
	return (
		<div className="App">
			<SingleCar />
		</div>
	);
}

export default App;


Let's create a new component in src/partials/ and name it ClickToCopy. Here is the our current structre and barebone ClickToCopy component.

Dir structre

Next, let's creat a function that copies the car details. We are creating this as an independent component so that we can reuse it.

import React from "react";

export default function ClickToCopy({ data }) {
	const [copyActionMsg, copyActionMsgSet] = React.useState("");
	const [copySuccess, copySuccessSet] = React.useState(false);

	const copyData = async (data) => {
		try {
			await navigator.clipboard.writeText(data);
			copySuccessSet(true);
			copyActionMsgSet("Car details copied to clipboard!");
		} catch (error) {
			copyActionMsgSet("Something went wrong! Please try again!");
			copySuccessSet(false);
		}
	};


	React.useEffect(() => {
		const timeoutId = setTimeout(() => {
			copyActionMsgSet("");
			copySuccessSet(false);
		}, 3000);
		return () => clearTimeout(timeoutId);
	}, [data]);

	return (
		<>
			<button onClick={() => {copyData(data)}}>
				{copySuccess ? 'Copied' : 'Copy Details'}
			</button>
		</>
	);
}

This will copy the data that is passed from parent component. In our case, App.js is parent component.

  1. We are using navigator.clipboard.writeText function to copy the data.
  2. copyActionMsg using const [copyActionMsg, copyActionMsgSet] = React.useState(""); to store the message displayed when data is successfully copie
  3. copySuccess using const [copySuccess, copySuccessSet] = React.useState(false); to store the success status.

After 3 seconds, we switch back to our initial state in useEffect Hook.

Note the button. When the copySuccess is true, we show the button label Copied and default Copy Details.

Let's import ClickToCopy component in app.js and test it.

import "./App.css";

// import the component
import ClickToCopy from "./partials/ClickToCopy";

const SingleCar = () => {
	return (
		<div className="single-car">
			<img src="hector.webp" />
			<div className="car-details">
				<h2>MG Hector</h2>
				<div className="flex">
					<p>Price</p>
					<p>1451 to 1956 cc</p>
				</div>
				<div className="flex">
					<p>Engine</p>
					<p>1451 to 1956 cc</p>
				</div>
				<div className="flex">
					<p>Fuel Type</p>
					<p>Petrol & Diesel</p>
				</div>
				<div className="flex">
					<p>Transmission</p>
					<p>Manual & Automatic</p>
				</div>
				<div className="flex">
					<p>Seating Capacity</p>
					<p>5 Seater</p>
				</div>
			</div>
			<div className="btn-group">
				<button>Book Now</button>

				{/* Use the component and pass the data */}
				<ClickToCopy
					data={`
                        Car - MG Hector\n
                        Price: $1,059,763,\n
                        Engine: 1451 to 1956 cc,\n
                        Fuel Type: Petrol & Diesel,\n
                        Transmission: Manual & Automatic,\n
                        Seating Capacity: 5 Seater`}
				/>
			</div>
		</div>
	);
};

function App() {
	return (
		<div className="App">
			<SingleCar />
		</div>
	);
}

export default App;

That is all. Now in our case, we have used static data.

The data can be dynamic and may be coming from the API. There could be multiple cards and each card can have the same button. All we need is to set the data once and it will work.

 

We can implement the same feature in jQuery - Select and copy data to clipboard using jQuery