diff --git a/README.md b/README.md index 80c1632..1131325 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# sharethis-reactjs +# sharethis-reactjs ![alt text][logo] @@ -121,7 +121,7 @@ class App extends React.Component { action_enable: true, // show/hide call to action (true, false) action_pos: 'bottom', // position of call to action (left, top, right) alignment: 'center', // alignment of buttons (left, center, right) - color: 'white', // set the color of buttons (social, white) + color: 'white', // set the color of buttons (social, white) enabled: true, // show/hide buttons (true, false) networks: [ // which networks to include (see FOLLOW NETWORKS) 'twitter', @@ -136,7 +136,7 @@ class App extends React.Component { instagram: 'sharethis', youtube: '/channel/UCbM93niCmdc2RD9RZbLMP6A?view_as=subscriber' }, - radius: 9, // the corner radius on each button (INTEGER) + radius: 16, // the corner radius on each button (INTEGER) size: 32, // the size of each button (INTEGER) spacing: 8 // the spacing between buttons (INTEGER) }} @@ -154,7 +154,7 @@ class App extends React.Component { language: 'en', // which language to use (see LANGUAGES) min_count: 0, // hide react counts less than min_count (INTEGER) networks: [ // which networks to include (see SHARING NETWORKS) - 'linkedin', + 'linkedin', // network without options 'facebook', 'twitter', 'pinterest', @@ -180,6 +180,61 @@ class App extends React.Component { }} /> + + ); } @@ -232,4 +287,4 @@ slight_smile, heart_eyes, laughing, astonished, sob, rage ``` Open `localhost:5000` - + diff --git a/demo/App.jsx b/demo/App.jsx index 608cee1..dfdf899 100644 --- a/demo/App.jsx +++ b/demo/App.jsx @@ -124,7 +124,7 @@ class App extends React.Component { language: 'en', // which language to use (see LANGUAGES) min_count: 0, // hide react counts less than min_count (INTEGER) networks: [ // which networks to include (see SHARING NETWORKS) - 'linkedin', + 'linkedin', // network without options 'facebook', 'twitter', 'pinterest', @@ -150,6 +150,61 @@ class App extends React.Component { }} /> + + ); } diff --git a/src/index.d.ts b/src/index.d.ts index 56b93e9..0556f11 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -1,5 +1,5 @@ declare module "sharethis-reactjs" { - type SharingNetwork = + type Network = | "blogger" | "delicious" | "digg" @@ -27,7 +27,10 @@ declare module "sharethis-reactjs" { | "whatsapp" | "xing"; - type FollowNetwork = + type SharingNetwork = + | Network | [Network, object] + + type FollowNetwork = | "blogger" | "digg" | "facebook" @@ -55,7 +58,7 @@ declare module "sharethis-reactjs" { | "yelp" | "youtube"; - type Reaction = + type Reaction = | "slight_smile" | "heart_eyes" | "laughing" diff --git a/src/index.js b/src/index.js index f921657..a36bd6b 100644 --- a/src/index.js +++ b/src/index.js @@ -1,13 +1,102 @@ - // dependencies -import React from "react"; +import React from 'react'; + +const normalizeNetworks = networks => { + const options = []; + const normalizedNetworks = []; + + networks.forEach(network => { + if (typeof network === 'string') { + normalizedNetworks.push(network); + options.push(undefined); + return; + } + + const [name, option] = network; + normalizedNetworks.push(name); + options.push(option); + return; + }); + + return [normalizedNetworks, options]; +}; + +const getStyleString = style => + Object.entries(style) + .map( + ([k, v]) => + `${k.replace(/[A-Z]/g, match => `-${match.toLowerCase()}`)}:${v}` + ) + .join(';'); + +const applyAttributes = (element, attributes) => { + Object.keys(attributes).forEach(key => { + if (key === 'style') { + element[key] = getStyleString(attributes[key]); + return; + } + + if (key === 'className') { + element['class'] = attributes[key]; + } + + element[key] = attributes[key]; + }); +}; + +const applyOptions = (elements, options) => { + elements.forEach((element, index) => { + if (options[index]) { + const option = options[index]; + + if (option.icon) { + const image = document.querySelector( + `[data-network="${element.dataset.network}"] > img` + ); + const text = document.querySelector( + `[data-network="${element.dataset.network}"] > span` + ); + + if (option.icon) { + applyAttributes(image, option.icon); + } + + if (option.text) { + applyAttributes(text, option.text); + } + + if (option.container) { + applyAttributes(element, option.container); + } + } + } + }); +}; + +const applyIconOptions = (elements, options) => { + elements + .filter(element => options[element.dataset.network]) + .forEach((element, index) => { + const image = document.querySelector( + `[data-network="${element.dataset.network}"] > img` + ); + + applyAttributes(image, options[element.dataset.network]); + }); +}; // load project wrapper const load = function(component, product) { - // load config - let config = component.props.config || {enabled: true}; + let config = component.props.config || { enabled: true }; config = JSON.parse(JSON.stringify(config)); + const [networks, networkOptions] = normalizeNetworks( + config.networks ? config.networks : [] + ); + + if (config.networks) { + config.networks = networks; + } // load buttons const _onShareThisLoaded = window.onShareThisLoaded; @@ -18,8 +107,18 @@ const load = function(component, product) { config.id = id; } if (component.buttons.current) { - component.buttons.current.id = config.id; + const buttons = component.buttons.current; + buttons.id = config.id; window.__sharethis__.load(product, config); + + const networks = [ + ...document.querySelectorAll(`#${config.id} > [data-network]`), + ].filter(el => el.dataset.network); + applyOptions(networks, networkOptions); + + if (component.props.icons) { + applyIconOptions(networks, component.props.icons); + } } if (_onShareThisLoaded) { _onShareThisLoaded(); @@ -35,19 +134,21 @@ const load = function(component, product) { window.onShareThisLoaded(); } } else { - const script = document.createElement("script"); + const script = document.createElement('script'); script.setAttribute('id', 'sharethis-js'); const params = { property: config.property || '', product: product, - source: 'reactjs' - } - const query = Object.keys(params).map(key => key + '=' + params[key]).join('&'); - script.src = "https://platform-api.sharethis.com/js/sharethis.js?" + query; + source: 'reactjs', + }; + const query = Object.keys(params) + .map(key => key + '=' + params[key]) + .join('&'); + script.src = 'https://platform-api.sharethis.com/js/sharethis.js?' + query; script.async = true; document.body.appendChild(script); } -} +}; // inline follow buttons class InlineFollowButtons extends React.Component { @@ -60,12 +161,10 @@ class InlineFollowButtons extends React.Component { load(this, 'inline-follow-buttons'); } - render () { - return ( -
- ); + render() { + return
; } -}; +} class InlineShareButtons extends React.Component { constructor(props) { @@ -77,12 +176,10 @@ class InlineShareButtons extends React.Component { load(this, 'inline-share-buttons'); } - render () { - return ( -
- ); + render() { + return
; } -}; +} class InlineReactionButtons extends React.Component { constructor(props) { @@ -94,12 +191,10 @@ class InlineReactionButtons extends React.Component { load(this, 'inline-reaction-buttons'); } - render () { - return ( -
- ); + render() { + return
; } -}; +} class StickyShareButtons extends React.Component { constructor(props) { @@ -111,18 +206,15 @@ class StickyShareButtons extends React.Component { load(this, 'sticky-share-buttons'); } - render () { - return ( -
- ); + render() { + return
; } -}; +} // export export { InlineFollowButtons, InlineReactionButtons, InlineShareButtons, - StickyShareButtons -} - + StickyShareButtons, +};