27
loading...
This website collects cookies to deliver better user experience
First published on Telerik Blog
create-react-app
. Run the command below in your command-line application:npx create-react-app sharer
App.js
. Replace the content in it with the code you see below:import React from "react";
import "./App.css";
function App() {
return <div className="App"></div>;
}
export default App;
App.css
and replace it with the content below.html {
box-sizing: border-box;
}
*,
*::before,
*::after {
box-sizing: inherit;
padding: 0;
margin: 0;
}
.App {
font-family: "Jost", sans-serif;
position: relative;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
background: #eee;
color: #888;
}
button {
border: 0;
padding: 0 20px;
border-radius: 4px;
cursor: pointer;
}
.close-button {
align-self: center;
padding: 0;
background: transparent;
font-size: 1.6rem;
color: #666;
}
.share-button-wrapper {
padding: 10px 20px;
background: #ddd;
border-radius: 4px;
text-transform: uppercase;
letter-spacing: 2px;
font-size: 0.9rem;
cursor: pointer;
}
.share-modal {
position: absolute;
z-index: 9999;
width: 80%;
max-width: 400px;
box-shadow: 0 0 5px #eee;
transform: translateY(-200%);
transition: 0.2s cubic-bezier(0.165, 0.84, 0.44, 1);
}
.share-modal.opened {
background: #fff;
transform: translateY(0%);
}
.modal-header,
.modal-body,
.modal-footer {
display: flex;
padding: 20px;
}
.modal-header {
justify-content: space-between;
padding: 15px 20px;
}
.modal-title {
align-self: center;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.7px;
font-size: 0.9rem;
color: #666;
}
.modal-body {
flex: 1;
display: grid;
grid-gap: 20px;
}
.modal-body > .row {
display: grid;
grid-template-rows: 1fr;
grid-template-columns: 1fr 1fr;
grid-gap: 20px;
}
.modal-body > .row > div {
align-self: center;
justify-self: center;
width: 100%;
}
.modal-body > .row > div > button {
height: 35px;
width: 100%;
padding: 0 25px;
background: transparent;
color: #888;
border: 1px solid #eee;
text-transform: uppercase;
letter-spacing: 2px;
font-size: 0.8rem;
cursor: pointer;
}
.modal-footer-link {
align-self: center;
background: #eee;
padding: 10px 15px;
margin-right: 10px;
border-radius: 4px;
text-transform: lowercase;
letter-spacing: 2px;
font-size: 0.8rem;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.modal-footer-button {
flex: 1 0 auto;
text-transform: uppercase;
color: #fff;
background: #ff008d;
font-weight: 600;
}
Share.js
in the src folder. This component will be responsible to trigger the share pop-up. Add the content below in Share.js
.import React from "react";
function Share({ label }) {
return (
<button className="sharer-button">
<span className="sharer-button-text">{label}</span>
</button>
);
}
export default Share;
App.js
. Add an import statement to Share.js
after line 1, in App.js
import Share from "./Share";
return (
<div>
<Share
label="Share"
title="My Web Share Adventures"
text="Hello World! I shared this content via Web Share"
/>
</div>
);
Share.js
with the following:function Share({ label, text, title }) {
const canonical = document.querySelector("link[rel=canonical]");
let url = canonical ? canonical.href : document.location.href;
const shareDetails = { url, title, text };
const handleSharing = async () => {
if (navigator.share) {
try {
await navigator
.share(shareDetails)
.then(() =>
console.log("Hooray! Your content was shared to tha world")
);
} catch (error) {
console.log(`Oops! I couldn't share to the world because: ${error}`);
}
} else {
// fallback code
console.log(
"Web share is currently not supported on this browser. Please provide a callback"
);
}
};
return (
<button className="sharer-button" onClick={handleSharing}>
<span className="sharer-button-text">{label}</span>
</button>
);
}
handleSharing
that would use the Web Share API to trigger the share picker and allow the user to select the destination. It checks if the browser supports the API by calling if (navigator.share)
. If it doesn't, a message is printed in the console. Otherwise, it calls navigator.share()
to trigger the native sharing mechanism of the device the browser is running on. It accepts an object which contains properties for the url, text, and title to be shared. It returns a promise that, when the promise fulfills, it prints a success message in the console. The promise returned from navigator.share()
will reject immediately if the parameter is not correctly specified, and will also reject if the user cancels sharing. Otherwise, it'll succeed when the user has chosen a destination.ShareModal.js
in the src directory and update it with the following:import React, { Fragment } from "react";
function ShareModal({ modalVisible, shareData, handleClose }) {
return (
<>
<div className={`${"share-modal"} ${modalVisible ? "opened" : "closed"}`}>
<section className="modal-header">
<h3 className="modal-title">Share Via</h3>
<button className="close-button" onClick={() => handleClose(false)}>
×
</button>
</section>
<section className="modal-body">
<div className="row">
<div>
<button>Facebook</button>
</div>
<div>
<button>Twitter</button>
</div>
</div>
<div className="row">
<div>
<button>Instagram</button>
</div>
<div>
<button>Tiktok</button>
</div>
</div>
</section>
<section className="modal-footer">
<div className="modal-footer-link">{shareData.url}</div>
<button className="modal-footer-button">Copy Link</button>
</section>
</div>
</>
);
}
export default ShareModal;
Share.js
by adding data to the state to determine when to show or hide the modal.const [showModal, setShowModal] = useState(false);
handleSharing
function by calling setShowModal(true)
in the else block, when the Web Share API is not supported by the browser.else {
// fallback code
setShowModal(true); //this is the line added in this snippet
// .... other code statement below
}
ShareModal
. Update the return statement for Share.js
to the code below.return (
<>
<button className="sharer-button" onClick={handleSharing}>
<span className="sharer-button-text">{label}</span>
</button>
<ShareModal
handleClose={setShowModal}
shareData={shareDetails}
modalVisible={showModal}
/>
</>
);