Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for Web Share API. #148

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
10 changes: 10 additions & 0 deletions jsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"compilerOptions": {
"checkJs": true,
"module": "esnext",
"target": "es2019",
"moduleResolution": "node",
"jsx": "react"
},
"exclude": ["node_modules", "**/node_modules/*"]
}
131 changes: 88 additions & 43 deletions src/components/ShareSocialCta/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,70 @@ import TwitterButton from "../SocialButtons/TwitterButton";
import FacebookButton from "../SocialButtons/FacebookButton";
import WhatsappButton from "../SocialButtons/WhatsappButton";
import LinkedinButton from "../SocialButtons/LinkedInButton";
import NativeShareButton from "../SocialButtons/NativeShareButton";
import EarthIcon from "../Images/Icons/EarthIcon.svg";

function FallbackShareButtons({
ctaTitle,
emailBody,
emailSubject,
facebookQuote,
facebookHashtag,
linkedinTitle,
linkedinDescription,
twitterTitle,
twitterAccount,
twitterHashtags,
url,
whatsappTitle,
currentUrl
}) {
return (
<div className={styles.socialContainer}>
<div className={styles.socialButton}>
<TwitterButton
url={url}
currentUrl={currentUrl}
twitterTitle={twitterTitle}
twitterAccount={twitterAccount}
hashtags={twitterHashtags}
/>
</div>
<div className={styles.socialButton}>
<FacebookButton
url={url}
currentUrl={currentUrl}
facebookQuote={facebookQuote}
facebookHashtag={facebookHashtag}
>
{null}
</FacebookButton>
</div>
<div className={styles.socialButton}>
<WhatsappButton url={url} whatsappTitle={whatsappTitle} />
</div>
<div className={styles.socialButton}>
<LinkedinButton
url={url}
currentUrl={currentUrl}
title={linkedinTitle}
description={linkedinDescription}
/>
</div>
<div className={styles.socialButton}>
<EmailButton
emailBody={emailBody}
currentUrl={currentUrl}
emailSubject={emailSubject}
/>
</div>
<div className={styles.socialButton}>
<CopyLinkButton currentUrl={currentUrl} />
</div>
</div>
);
}

function ShareSocialCta({
children,
ctaCopy,
Expand All @@ -28,6 +90,30 @@ function ShareSocialCta({
whatsappTitle,
currentUrl
}) {
const webShareApi =
typeof window !== "undefined" && "share" in window.navigator;
const propsForFallbackShareButtons = {
ctaTitle,
emailBody,
emailSubject,
facebookQuote,
facebookHashtag,
linkedinTitle,
linkedinDescription,
twitterTitle,
twitterAccount,
twitterHashtags,
url,
whatsappTitle,
currentUrl
};

const shareButtons = webShareApi ? (
<NativeShareButton title="Climate Choice" text={twitterTitle} url={url} />
) : (
<FallbackShareButtons {...propsForFallbackShareButtons} />
);

return (
<section id="share" aria-label="share" className={styles.container}>
<div className={`${GlobalStyles.inner} ${styles.inner}`}>
Expand All @@ -51,50 +137,9 @@ function ShareSocialCta({
Send this page to your friends, family and followers via our handy
pre written message.
</p>

<div className={styles.socialContainer}>
<div className={styles.socialButton}>
<TwitterButton
url={url}
currentUrl={currentUrl}
twitterTitle={twitterTitle}
twitterAccount={twitterAccount}
hashtags={twitterHashtags}
/>
</div>
<div className={styles.socialButton}>
<FacebookButton
url={url}
currentUrl={currentUrl}
facebookQuote={facebookQuote}
facebookHashtag={facebookHashtag}
>
{null}
</FacebookButton>
</div>
<div className={styles.socialButton}>
<WhatsappButton url={url} whatsappTitle={whatsappTitle} />
</div>
<div className={styles.socialButton}>
<LinkedinButton
url={url}
currentUrl={currentUrl}
title={linkedinTitle}
description={linkedinDescription}
/>
</div>
<div className={styles.socialButton}>
<EmailButton
emailBody={emailBody}
currentUrl={currentUrl}
emailSubject={emailSubject}
/>
</div>
<div className={styles.socialButton}>
<CopyLinkButton currentUrl={currentUrl} />
</div>
</div>
{shareButtons}
</div>

<span className={styles.thanks}>
Thank you{" "}
<span role="img" aria-label="raising_hands">
Expand Down
44 changes: 44 additions & 0 deletions src/components/SocialButtons/NativeShareButton.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import React from "react";
import styles from "./styles.module.scss";
import buttonStyles from "../../styles/Buttons.module.scss";

/**
Copy link
Contributor Author

@enjikaka enjikaka Nov 5, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With JSDoc like this and JS type checking enabled in VS Code this will give you errors when specifing props wrongly or adding props that doesn't exists. Kinda handy and no need to go in fully for TypeScript or Flow in the project. Could be progressively and selectively added. :)

Type checking could also be run with the TypeScript CLI in CI like so; tsc -p jsconfig.json --noEmit

Skärmavbild 2019-11-05 kl  17 54 51

Skärmavbild 2019-11-05 kl  18 05 14

* @typedef Props
* @prop {string} title
* @prop {string} text
* @prop {string} url
*/

/**
* Renders a button that opens the Web Share API dialog
* with the, in Props, provided text, title and url.
*
* @param {Props} props
*/
export default function NativeShareButton(props) {
const { title, text, url } = props;

async function openShareDialog() {
try {
await navigator.share({
title,
text,
url
});
} catch (shareError) {
// Handle share error maybe?
// This would be trying to share on unsecure origins...
}
}

return (
<>
<button
className={`${styles.button} ${buttonStyles.btnSimple}`}
onClick={openShareDialog}
>
Share
</button>
</>
);
}