UNPKG

@worldresources/gfw-components

Version:

React component library for the Global Forest Watch project.

180 lines (161 loc) 5.2 kB
import React, { PureComponent } from 'react'; import PropTypes from 'prop-types'; import TwitterIcon from 'assets/icons/social/twitter.svg'; import FacebookIcon from 'assets/icons/social/facebook.svg'; import Switch from 'components/switch'; import Button from 'components/button'; import Loader from 'components/loader'; import getShortenUrl from 'services/bitly'; import Input from 'components/html/input'; import { ShareWrapper } from './styles'; const isServer = typeof window === 'undefined'; class Share extends PureComponent { static propTypes = { /** title string */ title: PropTypes.string, /** url in input when link is selected */ shareUrl: PropTypes.string, /** url in input when embed is selected */ embedUrl: PropTypes.string, /** enables embed tab menu */ embed: PropTypes.bool, /** overide the iframe width and height */ embedSettings: PropTypes.shape({ width: PropTypes.number, height: PropTypes.number, }), /** API token for bitly account */ token: PropTypes.string, }; static defaultProps = { title: 'Share this view', shareUrl: '', embedUrl: '', embedSettings: { width: 670, height: 490 }, token: process.env.BITLY_TOKEN, }; state = { loading: false, copied: false, selected: 'link', shareUrl: this.props.shareUrl || (!isServer ? window.location.href : ''), embedUrl: this.props.embedUrl || (this.props.embed && !isServer ? window.location.href : ''), }; inputRef = React.createRef(); componentDidMount() { this.handleShortenUrl(); } handleShortenUrl = () => { if (this.props.token) { this.setState({ loading: true }); getShortenUrl(this.state.shareUrl, this.props.token) .then((response) => { if (response.status >= 200 && response.status < 400) { this.setState({ shareUrl: response?.data?.link, loading: false, }); } else { this.setState({ loading: false }); } }) .catch(() => this.setState({ loading: false })); } }; handleCopyToClipboard = () => { this.inputRef.current.select(); if (typeof document !== 'undefined') { try { document.execCommand('copy'); this.setState({ copied: true }); setTimeout(() => this.setState({ copied: false }), 2500); } catch (err) { alert('This browser does not support clipboard access'); // eslint-disable-line } } }; handleFocus = (event) => { event.target.select(); }; render() { const { title, embedSettings } = this.props; const { selected, loading, copied, shareUrl, embedUrl } = this.state; const { width, height } = embedSettings || {}; const inputValue = selected === 'embed' ? `<iframe width="${width || 670}" height="${ height || 490 }" frameborder="0" src="${embedUrl}"></iframe>` : shareUrl; return ( <ShareWrapper> <div className="actions"> {embedUrl && ( <Switch className="share-switch-tab" value={selected} options={[ { label: 'LINK', value: 'link' }, { label: 'EMBED', value: 'embed' }, ]} onChange={() => this.setState({ selected: selected === 'embed' ? 'link' : 'embed', })} /> )} <p className="info"> {selected === 'embed' ? 'Click and paste HTML to embed in website' : 'Click and paste link in email or IM'} </p> <div className="input-wrapper"> <div className="input-container"> {loading && selected !== 'embed' && ( <Loader className="input-loader" /> )} <Input ref={this.inputRef} type="text" value={!loading ? inputValue : ''} readOnly onClick={this.handleFocus} /> </div> <Button medium className="copy-button" onClick={() => this.handleCopyToClipboard()} disabled={loading} > {copied ? 'COPIED!' : 'COPY'} </Button> </div> </div> <div className="social-container"> <a href={`https://twitter.com/intent/tweet?text=${title}&via=globalforests&url=${shareUrl}`} target="_blank" rel="noopener noreferrer" > <Button light round big className="social-btn"> <TwitterIcon className="social-icon" /> </Button> </a> <a href={`https://www.facebook.com/sharer.php?u=${shareUrl}`} target="_blank" rel="noopener noreferrer" > <Button light round big className="social-btn"> <FacebookIcon className="social-icon" /> </Button> </a> </div> </ShareWrapper> ); } } export default Share;