From 6056e07db12b10ba51b4b9131a592cf1655d1710 Mon Sep 17 00:00:00 2001 From: lucasflomuller Date: Wed, 16 Sep 2020 10:54:18 -0300 Subject: [PATCH 1/5] feat: Add option object to individual network --- demo/App.jsx | 55 ++++++++++++++++++- src/index.d.ts | 9 ++-- src/index.js | 144 +++++++++++++++++++++++++++++++++++++------------ 3 files changed, 170 insertions(+), 38 deletions(-) diff --git a/demo/App.jsx b/demo/App.jsx index 608cee1..9158f96 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,59 @@ 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..74bd4da 100644 --- a/src/index.js +++ b/src/index.js @@ -1,13 +1,90 @@ - // 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) + } + } + } + }); +}; // 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 +95,14 @@ 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 (_onShareThisLoaded) { _onShareThisLoaded(); @@ -35,19 +118,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 +145,10 @@ class InlineFollowButtons extends React.Component { load(this, 'inline-follow-buttons'); } - render () { - return ( -
- ); + render() { + return
; } -}; +} class InlineShareButtons extends React.Component { constructor(props) { @@ -77,12 +160,10 @@ class InlineShareButtons extends React.Component { load(this, 'inline-share-buttons'); } - render () { - return ( -
- ); + render() { + return
; } -}; +} class InlineReactionButtons extends React.Component { constructor(props) { @@ -94,12 +175,10 @@ class InlineReactionButtons extends React.Component { load(this, 'inline-reaction-buttons'); } - render () { - return ( -
- ); + render() { + return
; } -}; +} class StickyShareButtons extends React.Component { constructor(props) { @@ -111,18 +190,15 @@ class StickyShareButtons extends React.Component { load(this, 'sticky-share-buttons'); } - render () { - return ( -
- ); + render() { + return
; } -}; +} // export export { InlineFollowButtons, InlineReactionButtons, InlineShareButtons, - StickyShareButtons -} - + StickyShareButtons, +}; From 5bceadf1e657d44840f5d0d37e852a0d5b20d6cc Mon Sep 17 00:00:00 2001 From: lucasflomuller Date: Wed, 16 Sep 2020 14:31:13 -0300 Subject: [PATCH 2/5] feat: Change custom logo --- demo/App.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demo/App.jsx b/demo/App.jsx index 9158f96..7c4ae82 100644 --- a/demo/App.jsx +++ b/demo/App.jsx @@ -166,7 +166,7 @@ class App extends React.Component { 'facebook', ['twitter', { // network with options icon: { // options applied to the icon - src: 'https://logodownload.org/wp-content/uploads/2014/09/twitter-logo-4.png', + src: 'https://pbs.twimg.com/profile_images/531381005165158401/bUJYaSO9_400x400.png', style: { objectFit: 'contain' } From ed71f7b10c5f1a089ec8e9c932cc5515ac79d4bf Mon Sep 17 00:00:00 2001 From: lucasflomuller Date: Wed, 16 Sep 2020 15:04:28 -0300 Subject: [PATCH 3/5] docs: Update readme --- README.md | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 58 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 80c1632..bf36e3c 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,59 @@ class App extends React.Component { }} /> + +
); } @@ -232,4 +285,4 @@ slight_smile, heart_eyes, laughing, astonished, sob, rage ``` Open `localhost:5000` - + From b5d96b3963bc8ca8543ef62deebb839d0d595d71 Mon Sep 17 00:00:00 2001 From: lucasflomuller Date: Mon, 19 Oct 2020 00:39:34 -0300 Subject: [PATCH 4/5] feat: Add icons as separate property in config --- README.md | 14 ++++++++------ demo/App.jsx | 14 ++++++++------ src/index.js | 42 +++++++++++++++++++++++++++++------------- 3 files changed, 45 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index bf36e3c..23019c8 100644 --- a/README.md +++ b/README.md @@ -191,16 +191,18 @@ class App extends React.Component { labels: 'counts', // button labels (cta, counts, null) 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', // network without options - 'facebook', - ['twitter', { // network with options - icon: { // options applied to the icon + icons: { + twitter: { // options applied to the icon src: 'https://pbs.twimg.com/profile_images/531381005165158401/bUJYaSO9_400x400.png', style: { objectFit: 'contain' } - }, + } + }, + networks: [ // which networks to include (see SHARING NETWORKS) + 'linkedin', // network without options + 'facebook', + ['twitter', { // network with options text: { // options applied to the span of the text style: { color: 'black' diff --git a/demo/App.jsx b/demo/App.jsx index 7c4ae82..75e9b02 100644 --- a/demo/App.jsx +++ b/demo/App.jsx @@ -161,16 +161,18 @@ class App extends React.Component { labels: 'counts', // button labels (cta, counts, null) 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', // network without options - 'facebook', - ['twitter', { // network with options - icon: { // options applied to the icon + icons: { + twitter: { // options applied to the icon src: 'https://pbs.twimg.com/profile_images/531381005165158401/bUJYaSO9_400x400.png', style: { objectFit: 'contain' } - }, + } + }, + networks: [ // which networks to include (see SHARING NETWORKS) + 'linkedin', // network without options + 'facebook', + ['twitter', { // network with options text: { // options applied to the span of the text style: { color: 'black' diff --git a/src/index.js b/src/index.js index 74bd4da..acecba7 100644 --- a/src/index.js +++ b/src/index.js @@ -1,11 +1,11 @@ // dependencies import React from 'react'; -const normalizeNetworks = (networks) => { +const normalizeNetworks = networks => { const options = []; const normalizedNetworks = []; - networks.forEach((network) => { + networks.forEach(network => { if (typeof network === 'string') { normalizedNetworks.push(network); options.push(undefined); @@ -21,28 +21,28 @@ const normalizeNetworks = (networks) => { return [normalizedNetworks, options]; }; -const getStyleString = (style) => +const getStyleString = style => Object.entries(style) .map( ([k, v]) => - `${k.replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`)}:${v}` + `${k.replace(/[A-Z]/g, match => `-${match.toLowerCase()}`)}:${v}` ) .join(';'); const applyAttributes = (element, attributes) => { - Object.keys(attributes).forEach((key) => { + Object.keys(attributes).forEach(key => { if (key === 'style') { element[key] = getStyleString(attributes[key]); - return + return; } if (key === 'className') { - element['class'] = attributes[key] + element['class'] = attributes[key]; } element[key] = attributes[key]; }); -} +}; const applyOptions = (elements, options) => { elements.forEach((element, index) => { @@ -58,21 +58,33 @@ const applyOptions = (elements, options) => { ); if (option.icon) { - applyAttributes(image, option.icon) + applyAttributes(image, option.icon); } if (option.text) { - applyAttributes(text, option.text) + applyAttributes(text, option.text); } if (option.container) { - applyAttributes(element, 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 @@ -101,8 +113,12 @@ const load = function(component, product) { const networks = [ ...document.querySelectorAll(`#${config.id} > [data-network]`), - ].filter((el) => el.dataset.network); + ].filter(el => el.dataset.network); applyOptions(networks, networkOptions); + + if (config.icons) { + applyIconOptions(networks, config.icons); + } } if (_onShareThisLoaded) { _onShareThisLoaded(); @@ -126,7 +142,7 @@ const load = function(component, product) { source: 'reactjs', }; const query = Object.keys(params) - .map((key) => key + '=' + params[key]) + .map(key => key + '=' + params[key]) .join('&'); script.src = 'https://platform-api.sharethis.com/js/sharethis.js?' + query; script.async = true; From 7feadee3da79f9072b2ca1ef581ac227624ce5c1 Mon Sep 17 00:00:00 2001 From: lucasflomuller Date: Mon, 19 Oct 2020 00:41:55 -0300 Subject: [PATCH 5/5] feat: Add icons as props --- README.md | 16 ++++++++-------- demo/App.jsx | 16 ++++++++-------- src/index.js | 4 ++-- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 23019c8..1131325 100644 --- a/README.md +++ b/README.md @@ -182,6 +182,14 @@ class App extends React.Component { el.dataset.network); applyOptions(networks, networkOptions); - if (config.icons) { - applyIconOptions(networks, config.icons); + if (component.props.icons) { + applyIconOptions(networks, component.props.icons); } } if (_onShareThisLoaded) {