├── .babelrc ├── .editorconfig ├── .eslintrc.js ├── .gitignore ├── .npmignore ├── .prettierrc ├── LICENSE ├── README.md ├── package.json ├── rollup.config.js ├── src ├── components │ ├── SocialShareButton.tsx │ ├── buttons │ │ ├── EmailShareButton.ts │ │ ├── FacebookMessengerShareButton.ts │ │ ├── FacebookShareButton.ts │ │ ├── GabShareButton.ts │ │ ├── HatenaShareButton.ts │ │ ├── InstapaperShareButton.ts │ │ ├── LineShareButton.ts │ │ ├── LinkedinShareButton.ts │ │ ├── LivejournalShareButton.ts │ │ ├── MailruShareButton.ts │ │ ├── PinterestShareButton.ts │ │ ├── PocketShareButton.ts │ │ ├── RedditShareButton.ts │ │ ├── TelegramShareButton.ts │ │ ├── TumblrShareButton.ts │ │ ├── TwitterShareButton.ts │ │ ├── VKShareButton.ts │ │ ├── ViberShareButton.ts │ │ ├── WeiboShareButton.ts │ │ ├── WhatsappShareButton.ts │ │ └── WorkplaceShareButton.ts │ ├── counts │ │ ├── FacebookShareCount.ts │ │ ├── HatenaShareCount.ts │ │ ├── OKShareCount.ts │ │ ├── PinterestShareCount.ts │ │ ├── RedditShareCount.ts │ │ ├── TumblrShareCount.ts │ │ └── VKShareCount.ts │ └── icons │ │ └── icon.tsx ├── constant │ └── icons.ts ├── hocs │ ├── createShareButton.tsx │ └── createShareCount.tsx ├── index.ts ├── types.d.ts └── utils │ ├── button.ts │ ├── count.ts │ └── index.ts ├── tsconfig.json └── yarn.lock /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "@babel/preset-env", 4 | "@babel/preset-react" 5 | ] // , 6 | // "plugins": ["@babel/plugin-proposal-class-properties"] 7 | } -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig: http://EditorConfig.org 2 | root = true 3 | 4 | [*] 5 | end_of_line = lf 6 | charset = utf-8 7 | trim_trailing_whitespace = true 8 | insert_final_newline = true 9 | indent_style = space 10 | tab_width = 2 11 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | parser: '@typescript-eslint/parser', 3 | extends: [ 4 | 'plugin:@typescript-eslint/recommended', 5 | 'plugin:react/recommended', 6 | ], 7 | parserOptions: { 8 | ecmaVersion: 2018, 9 | sourceType: 'module', 10 | }, 11 | plugins: ['react-hooks'], 12 | rules: { 13 | curly: 'error', 14 | '@typescript-eslint/indent': 'off', 15 | '@typescript-eslint/no-non-null-assertion': 'off', 16 | '@typescript-eslint/no-empty-function': 'off', 17 | '@typescript-eslint/ban-ts-comment': 'warn', 18 | '@typescript-eslint/no-explicit-any': 'off', 19 | '@typescript-eslint/explicit-function-return-type': 'off', 20 | '@typescript-eslint/no-empty-function': 'off', 21 | '@typescript-eslint/no-object-literal-type-assertion': 'off', 22 | 'react-hooks/rules-of-hooks': 'error', 23 | 'react-hooks/exhaustive-deps': 'error', 24 | 'react/display-name': 'warn', 25 | 'no-console': 'error', 26 | '@typescript-eslint/no-this-alias': [ 27 | 'error', 28 | { 29 | 'allowDestructuring': true, // Allow `const { props, state } = this`; false by default 30 | 'allowedNames': ['self'] // Allow `const self = this`; `[]` by default 31 | } 32 | ], 33 | '@typescript-eslint/explicit-module-boundary-types': 'off', 34 | }, 35 | overrides: [ 36 | { 37 | files: ['*.spec.ts', '*.spec.tsx'], 38 | rules: { 39 | // Allow testing runtime errors to suppress TS errors 40 | '@typescript-eslint/ban-ts-comment': 'off', 41 | '@typescript-eslint/explicit-module-boundary-types': 'off', 42 | }, 43 | }, 44 | ], 45 | settings: { 46 | react: { 47 | pragma: 'React', 48 | version: 'detect', 49 | }, 50 | }, 51 | }; -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | node_modules 5 | 6 | # builds 7 | build 8 | dist 9 | 10 | # misc 11 | .DS_Store 12 | .env 13 | .env.local 14 | .env.development.local 15 | .env.test.local 16 | .env.production.local 17 | 18 | npm-debug.log* 19 | yarn-debug.log* 20 | yarn-error.log* 21 | 22 | package-lock.json 23 | 24 | /supports/create-react-app/node_modules 25 | /supports/create-react-app/package-lock.json 26 | 27 | /supports/create-next-app/node_modules 28 | /supports/create-next-app/.next 29 | /supports/create-next-app/package-lock.json -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | demo 3 | docs 4 | .tsconfig 5 | .eslintrc 6 | .gitignore 7 | .git 8 | *.png 9 | *.config.js 10 | tsconfig.json 11 | rollup.config.mjs 12 | .eslintrc.js 13 | .prettierrc 14 | .editorconfig 15 | .babelrc 16 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "trailingComma": "all", 3 | "singleQuote": true, 4 | "semi": false 5 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 ayda-tech 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # React-Share-Kit 3 | React-Share-Kit is a simple and easy-to-use library for adding social media share buttons to your React & Next applications. With React-Share-Kit, you can quickly integrate share buttons for popular social media platforms such as Facebook, Twitter, LinkedIn, and more. 4 | 5 | If package size is mater and you don't need use share count functionality instead of your React.js, Next.js and PReact project build with Javascript and Typescript. [React-share-lite](https://www.npmjs.com/package/react-share-lite) is the solution to enhance your application performance. 6 | **** 7 | [![downloads](https://img.shields.io/npm/dm/react-share-kit.svg?label=monthly%20downloads)](https://www.npmjs.com/package/react-share-kit) [![downloads](https://img.shields.io/npm/dt/react-share-kit.svg?label=total%20downloads)](https://www.npmjs.com/package/react-share-kit) 8 | 9 | [![NPM](https://img.shields.io/npm/v/react-share-kit.svg)](https://www.npmjs.com/package/react-share-kit) ![npm bundle size](https://img.shields.io/bundlephobia/min/react-share-kit) [![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com) 10 | 11 | ![Share buttons screenshot](https://github.com/ayda-tech/react-share-lite/blob/main/react-share-lite.png?raw=true) 12 | 13 | 14 | --- 15 | 16 | ### Table of Contents 17 | - [React-Share-Kit](#react-share-kit) 18 | - [Table of Contents](#table-of-contents) 19 | - [Installation](#installation) 20 | - [📕 Share Button Global Props](#-share-button-global-props) 21 | - [💡 Usage of ShareButtons](#-usage-of-sharebuttons) 22 | - [Facebook Share](#facebook-share) 23 | - [Twitter Share](#twitter-share) 24 | - [Linkedin Share](#linkedin-share) 25 | - [Whatsapp Share](#whatsapp-share) 26 | - [Telegram Share](#telegram-share) 27 | - [FacebookMessenger Share](#facebookmessenger-share) 28 | - [Email Share](#email-share) 29 | - [VK Share](#vk-share) 30 | - [Pinterest Share](#pinterest-share) 31 | - [Reddit Share](#reddit-share) 32 | - [Line Share](#line-share) 33 | - [Tumblr Share](#tumblr-share) 34 | - [Viber Share](#viber-share) 35 | - [Weibo Share](#weibo-share) 36 | - [Mailru Share](#mailru-share) 37 | - [LiveJournal Share](#livejournal-share) 38 | - [Workplace Share](#workplace-share) 39 | - [Pocket Share](#pocket-share) 40 | - [Instapaper Share](#instapaper-share) 41 | - [Hatena Share](#hatena-share) 42 | - [Gab Share](#gab-share) 43 | - [📕 Share Count global props](#-share-count-global-props) 44 | - [💡 Usage of ShareCount](#-usage-of-sharecount) 45 | - [Facebook Count](#facebook-count) 46 | - [Hatena Count](#hatena-count) 47 | - [OK Count](#ok-count) 48 | - [Pinterest Count](#pinterest-count) 49 | - [Tumblr Count](#tumblr-count) 50 | - [VK Count](#vk-count) 51 | - [License](#license) 52 | 53 | ## Installation 54 | 55 | To install React-Share-Kit, simply run: 56 | 57 | ```bash 58 | npm install react-share-kit 59 | ``` 60 | 61 | or 62 | 63 | ```bash 64 | yarn add react-share-kit 65 | ``` 66 | 67 | ## 📕 Share Button Global Props 68 | 69 | Each button supports a set of global props that are consistent across all buttons. However, in addition to these global props, each button also possesses its own unique set of specific properties. These specific properties are tailored to the individual functionality and customization options of each button. 70 | 71 | | Props | Type | Default | Description | Required | 72 | | :--- | :--- | :--- | :--- | :--- | 73 | | url | string | | The URL of the shared page. | TRUE | 74 | | title | string | | The title of the shared page. | FALSE | 75 | | windowWidth | number | 550 | Opened window width. | FALSE | 76 | | windowHeight | number | 400 | Opened window height. | FALSE | 77 | | blankTarget | boolean | false | Open share window in a new tab if set to `true`. | FALSE | 78 | | bgColor | string | related color | Icon background color. | FALSE | 79 | | round | boolean | false | The "round" attribute creates a fully circular button shape, giving it a 100% rounded appearance. | FALSE | 80 | | borderRadius | number | 0px | Custom round share. | FALSE | 81 | | size | number | 64px | The button size. | FALSE | 82 | | buttonTitle | string | | The title of button used instead of icon. | FALSE | 83 | 84 | 👨‍💻 Example 85 | 86 | ```jsx 87 | import React from 'react'; 88 | import { FacebookShare, FacebookCount } from 'react-share-kit'; 89 | 90 | const ShareButtons = () => { 91 | const shareUrl = 'https://github.com/ayda-tech/react-share-kit'; 92 | const title = 'Check out this awesome website!'; 93 | 94 | return ( 95 | <> 96 | 97 | 98 | 103 | 104 | 109 | {shareCount => {shareCount}} 110 | 111 | 112 | ); 113 | }; 114 | ``` 115 | 116 | ## 💡 Usage of ShareButtons 117 | 118 | ### Facebook Share 119 | 120 | 👨‍💻 Example 121 | 122 | ```js 123 | import { FacebookShare } from 'react-share-kit' 124 | 125 | 130 | 131 | ``` 132 | 133 | 📕 Props: Supports only on Facebook 134 | 135 | | Props | Type | Default | Description | Required | 136 | | :--- | :--- | :--- | :--- | :--- | 137 | | quote | string | | A quote to be shared. | FALSE | 138 | | hashtag | string | | Hashtag to be shared. | FALSE | 139 | 140 | ### Twitter Share 141 | 142 | 👨‍💻 Example 143 | 144 | ```js 145 | import { TwitterShare } from 'react-share-kit' 146 | 147 | 152 | ``` 153 | 📕 Props: Supports only on Twitter 154 | 155 | | Props | Type | Default | Description | Required | 156 | | :--- | :--- | :--- | :--- | :--- | 157 | | via | string | | | FALSE | 158 | | hashtags | array | | | FALSE | 159 | | related | array | | | FALSE | 160 | 161 | ### Linkedin Share 162 | 163 | 👨‍💻 Example 164 | 165 | ```js 166 | import { LinkedinShare } from 'react-share-kit' 167 | 168 | 169 | ``` 170 | 171 | ### Whatsapp Share 172 | 173 | 👨‍💻 Example 174 | 175 | ```js 176 | import { WhatsappShare } from 'react-share-kit' 177 | 178 | 183 | ``` 184 | 185 | 📕 Props: Supports only on WhatsApp 186 | 187 | | Props | Type | Default | Description | Required | 188 | | :--- | :--- | :--- | :--- | :--- | 189 | | separator | string | | | FALSE | 190 | 191 | 192 | ### Telegram Share 193 | 194 | 👨‍💻 Example 195 | 196 | ```js 197 | import { TelegramShare } from 'react-share-kit' 198 | 199 | 200 | ``` 201 | 202 | ### FacebookMessenger Share 203 | 204 | 👨‍💻 Example 205 | 206 | ```js 207 | import { FacebookMessengerShare } from 'react-share-kit' 208 | 209 | 214 | ``` 215 | 216 | 📕 Props: Supports only on Facebook Messenger 217 | 218 | | Props | Type | Default | Description | Required | 219 | | :--- | :--- | :--- | :--- | :--- | 220 | | appId | string | | Facebook application id. | TRUE | 221 | | redirectUri | string | | The URL to redirect to after sharing (default: the shared url). | FALSE | 222 | | to | string | | A user ID of a recipient. Once the dialog comes up, the sender can specify additional people as recipients. | FALSE | 223 | 224 | ### Email Share 225 | 226 | 👨‍💻 Example 227 | 228 | ```js 229 | import { EmailShare } from 'react-share-kit' 230 | 231 | 236 | ``` 237 | 238 | 📕 Props: Supports only on Email 239 | 240 | | Props | Type | Default | Description | Required | 241 | | :--- | :--- | :--- | :--- | :--- | 242 | | children | node | | React component, HTML element or string. | TRUE | 243 | | url | string | | The URL of the shared page. | TRUE | 244 | | subject | string | | | FALSE | 245 | | body | string | | | FALSE | 246 | | separator | string | | | FALSE | 247 | | blankTarget | boolean | false | Open share window in a new tab if set to `true`. | FALSE | 248 | 249 | ### VK Share 250 | 251 | 👨‍💻 Example 252 | 253 | ```js 254 | import { VKShare } from 'react-share-kit' 255 | 256 | 260 | ``` 261 | 262 | 📕 Props: Supports only on VK 263 | 264 | | Props | Type | Default | Description | Required | 265 | | :--- | :--- | :--- | :--- | :--- | 266 | | image | string | | An absolute link to the image that will be shared. | FALSE | 267 | | noParse | boolean | | If true is passed, VK will not retrieve URL information. | FALSE | 268 | | noVkLinks | boolean | | If true is passed, there will be no links to the user's profile in the open window. Only for mobile devices. | FALSE | 269 | 270 | ### Pinterest Share 271 | 272 | 👨‍💻 Example 273 | 274 | ```js 275 | import { PinterestShare } from 'react-share-kit' 276 | 277 | 281 | ``` 282 | 📕 Props: Supports only on Pinterest 283 | 284 | | Props | Type | Default | Description | Required | 285 | | :--- | :--- | :--- | :--- | :--- | 286 | | media | string | | The image URL that will be pinned. | TRUE | 287 | | description | string | | The description of the shared media. | FALSE | 288 | 289 | ### Reddit Share 290 | 291 | 👨‍💻 Example 292 | 293 | ```js 294 | import { RedditShare } from 'react-share-kit' 295 | 296 | 297 | ``` 298 | 299 | ### Line Share 300 | 301 | 👨‍💻 Example 302 | 303 | ```js 304 | import { LineShare } from 'react-share-kit' 305 | 306 | 307 | ``` 308 | 309 | ### Tumblr Share 310 | 311 | 👨‍💻 Example 312 | 313 | ```js 314 | import { TumblrShare } from 'react-share-kit' 315 | 316 | 320 | ``` 321 | 322 | 📕 Props: Supports only on Tumblr 323 | 324 | | Props | Type | Default | Description | Required | 325 | | :--- | :--- | :--- | :--- | :--- | 326 | | tags | Array<string> | | | FALSE | 327 | | caption | string | | The description of the shared page. | FALSE | 328 | | posttype | string | link | | FALSE | 329 | 330 | ### Viber Share 331 | 332 | 👨‍💻 Example 333 | 334 | ```js 335 | import { ViberShare } from 'react-share-kit' 336 | 337 | 341 | ``` 342 | 343 | 📕 Props: Supports only on Viber 344 | 345 | | Props | Type | Default | Description | Required | 346 | | :--- | :--- | :--- | :--- | :--- | 347 | | separator | string | | | FALSE | 348 | 349 | ### Weibo Share 350 | 351 | 👨‍💻 Example 352 | 353 | ```js 354 | import { WeiboShare } from 'react-share-kit' 355 | 356 | 361 | ``` 362 | 363 | 📕 Props: Supports only on Weibo 364 | 365 | | Props | Type | Default | Description | Required | 366 | | :--- | :--- | :--- | :--- | :--- | 367 | | image | string | | The image URL that will be shared. | FALSE | 368 | 369 | ### Mailru Share 370 | 371 | 👨‍💻 Example 372 | 373 | ```js 374 | import { MailruShare } from 'react-share-kit' 375 | 376 | 377 | ``` 378 | 379 | 📕 Props: Supports only on Mail-Ru 380 | 381 | | Props | Type | Default | Description | Required | 382 | | :--- | :--- | :--- | :--- | :--- | 383 | | description | string | | Description of the shared page. | FALSE | 384 | | imageUrl | string | | Image url of the shared page. | FALSE | 385 | 386 | ### LiveJournal Share 387 | 388 | 👨‍💻 Example 389 | 390 | ```js 391 | import { LiveJournalShare } from 'react-share-kit' 392 | 393 | 394 | ``` 395 | 396 | 📕 Props: Supports only on Live Journal 397 | 398 | | Props | Type | Default | Description | Required | 399 | | :--- | :--- | :--- | :--- | :--- | 400 | | description | string | | Description of the shared page. | FALSE | 401 | 402 | ### Workplace Share 403 | 404 | 👨‍💻 Example 405 | 406 | ```js 407 | import { WorkplaceShare } from 'react-share-kit' 408 | 409 | 413 | ``` 414 | 415 | 📕 Props: Supports only on Workspace 416 | 417 | | Props | Type | Default | Description | Required | 418 | | :--- | :--- | :--- | :--- | :--- | 419 | | quote | string | | | FALSE | 420 | | hashtag | string | | | FALSE | 421 | 422 | ### Pocket Share 423 | 424 | 👨‍💻 Example 425 | 426 | ```js 427 | import { 428 | PocketShare 429 | } from 'react-share-kit' 430 | 431 | 432 | ``` 433 | 434 | ### Instapaper Share 435 | 436 | 👨‍💻 Example 437 | 438 | ```js 439 | import { InstapaperShare } from 'react-share-kit' 440 | 441 | 442 | ``` 443 | 444 | 📕 Props: Supports only on Instapaper 445 | 446 | | Props | Type | Default | Description | Required | 447 | | :--- | :--- | :--- | :--- | :--- | 448 | | description | string | | Description of the shared page. | FALSE | 449 | 450 | ### Hatena Share 451 | 452 | 👨‍💻 Example 453 | 454 | ```js 455 | import { HatenaShare } from 'react-share-kit' 456 | 457 | 458 | ``` 459 | 460 | ### Gab Share 461 | 462 | 👨‍💻 Example 463 | 464 | ```js 465 | import { GabShare } from 'react-share-kit' 466 | 467 | 468 | ``` 469 | 470 | ## 📕 Share Count global props 471 | 472 | | Props | Type | Default | Description | Required | 473 | | :--- | :--- | :--- | :--- | :--- | 474 | | url | string | | The URL of the shared page. | TRUE | 475 | | children | node | | React component, HTML element or string. | FALSE | 476 | | appId | string | | Facebook application id. | TRUE | 477 | | appSecret | string | | Facebook application secret. | TRUE | 478 | 479 | ## 💡 Usage of ShareCount 480 | 481 | ### Facebook Count 482 | 483 | 👨‍💻 Example 484 | 485 | ```js 486 | import { FacebookCount } from 'react-share-kit' 487 | 488 | 493 | 494 | 499 | {shareCount => {shareCount}} 500 | 501 | ``` 502 | 503 | 📕 Props: Supports only on Facebook count 504 | 505 | | Props | Type | Default | Description | Required | 506 | | :--- | :--- | :--- | :--- | :--- | 507 | | appId | string | | Facebook application id. | TRUE | 508 | | appSecret | string | | Facebook application secret. | TRUE | 509 | 510 | ### Hatena Count 511 | 512 | 👨‍💻 Example 513 | 514 | ```js 515 | import { HatenaCount } from 'react-share-kit' 516 | 517 | 518 | 519 | 520 | {shareCount => {shareCount}} 521 | 522 | ``` 523 | 524 | ### OK Count 525 | 526 | 👨‍💻 Example 527 | 528 | ```js 529 | import { OKCount } from 'react-share-kit' 530 | 531 | 532 | 533 | 534 | {shareCount => {shareCount}} 535 | 536 | ``` 537 | 538 | ### Pinterest Count 539 | 540 | 👨‍💻 Example 541 | 542 | ```js 543 | import { PinterestShareCount } from 'react-share-kit' 544 | 545 | 546 | 547 | 548 | {shareCount => {shareCount}} 549 | 550 | ``` 551 | 552 | ### Tumblr Count 553 | 554 | 👨‍💻 Example 555 | 556 | ```js 557 | import { TumblrCount } from 'react-share-kit' 558 | 559 | 560 | 561 | 562 | {shareCount => {shareCount}} 563 | 564 | ``` 565 | 566 | ### VK Count 567 | 568 | 👨‍💻 Example 569 | 570 | ```js 571 | import { VKCount } from 'react-share-kit' 572 | 573 | 574 | 575 | 576 | {shareCount => {shareCount}} 577 | 578 | ``` 579 | 580 | ## License 581 | 582 | React-Share-Kit is licensed under the MIT License. See the [LICENSE](https://github.com/ayda-tech/react-share-kit/blob/main/LICENSE) file for more details. 583 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-share-kit", 3 | "version": "1.1.0", 4 | "description": "Social media share buttons and share counts for React and Nextjs.", 5 | "scripts": { 6 | "build": "rollup -c", 7 | "prettier": "prettier --write './src/*.ts' './src/**/*.ts' './src/**/*.tsx' --config ./.prettierrc", 8 | "lint:check": "eslint ./src --ext .tsx,.ts --report-unused-disable-directives", 9 | "dev": "rollup -c -w" 10 | }, 11 | "author": "Ayda Tech", 12 | "license": "MIT", 13 | "keywords": [ 14 | "react-share-kit", 15 | "react-share", 16 | "next-share", 17 | "social-share", 18 | "share-button", 19 | "social-count", 20 | "social-share-buttons", 21 | "social-media-share-buttons", 22 | "social-button-count", 23 | "social-count-buttons", 24 | "sharing", 25 | "share", 26 | "social", 27 | "button", 28 | "react", 29 | "nextjs", 30 | "next.js support" 31 | ], 32 | "devDependencies": { 33 | "@babel/core": "^7.23.3", 34 | "@babel/plugin-proposal-class-properties": "^7.18.6", 35 | "@babel/preset-env": "^7.23.3", 36 | "@rollup/plugin-babel": "^6.0.4", 37 | "@rollup/plugin-commonjs": "^25.0.7", 38 | "@rollup/plugin-node-resolve": "^15.2.3", 39 | "@rollup/plugin-terser": "^0.4.4", 40 | "@rollup/plugin-typescript": "^11.1.5", 41 | "@types/jsonp": "^0.2.3", 42 | "@types/react": "^18.2.37", 43 | "@typescript-eslint/eslint-plugin": "^6.11.0", 44 | "@typescript-eslint/parser": "^6.11.0", 45 | "eslint": "^8.54.0", 46 | "eslint-plugin-react-hooks": "^4.6.0", 47 | "prettier": "^3.1.0", 48 | "react": "^18.2.0", 49 | "react-dom": "^18.2.0", 50 | "react-scripts": "^5.0.1", 51 | "rollup": "^4.5.0", 52 | "rollup-plugin-bundle-size": "^1.0.3", 53 | "rollup-plugin-dts": "^6.1.0", 54 | "rollup-plugin-typescript2": "^0.36.0", 55 | "typescript": "^5.2.2" 56 | }, 57 | "peerDependencies": { 58 | "react": "^18.2.0" 59 | }, 60 | "dependencies": { 61 | "jsonp": "^0.2.1" 62 | }, 63 | "type": "module", 64 | "main": "dist/index.js", 65 | "module": "dist/index.es.js", 66 | "jsnext:main": "dist/index.es.js", 67 | "types": "dist/index.d.ts", 68 | "files": [ 69 | "dist" 70 | ], 71 | "repository": { 72 | "type": "git", 73 | "url": "git+https://github.com/ayda-tech/react-share-kit.git" 74 | }, 75 | "homepage": "https://react-share-kit.vercel.app/" 76 | } 77 | -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import typescript from 'rollup-plugin-typescript2' 2 | import babel from '@rollup/plugin-babel' 3 | import commonjs from '@rollup/plugin-commonjs' 4 | import terser from '@rollup/plugin-terser' 5 | import dts from 'rollup-plugin-dts' 6 | import bundleSize from 'rollup-plugin-bundle-size' 7 | 8 | import packageJSON from './package.json' assert { type: 'json' } 9 | 10 | // ======= FOR BUILDING NODE.JS PACKAGE ======= 11 | // import builtins from 'builtin-modules' 12 | // import resolve, { nodeResolve } from '@rollup/plugin-node-resolve' 13 | // ============================================ 14 | 15 | export default [ 16 | { 17 | input: 'src/index.ts', 18 | output: [ 19 | { 20 | file: packageJSON.main, 21 | format: 'cjs', 22 | exports: 'named', 23 | }, 24 | { 25 | file: packageJSON.module, 26 | format: 'esm', 27 | exports: 'named', 28 | }, 29 | ], 30 | // external: builtins, 31 | external: ['react', 'react-dom'], 32 | plugins: [ 33 | typescript({ 34 | check: true, 35 | tsconfig: './tsconfig.json', 36 | }), 37 | babel({ 38 | exclude: 'node_modules/**', 39 | babelHelpers: 'bundled', 40 | }), 41 | // resolve({ 42 | // preferBuiltins: true, 43 | // }), 44 | // nodeResolve(), 45 | commonjs({ 46 | extensions: ['.js', '.ts', '.tsx'], 47 | }), 48 | terser(), 49 | bundleSize(), 50 | ], 51 | }, 52 | { 53 | input: 'src/types.d.ts', 54 | output: { 55 | file: 'dist/types.d.ts', 56 | format: 'es', 57 | }, 58 | plugins: [dts()], 59 | }, 60 | ] 61 | -------------------------------------------------------------------------------- /src/components/SocialShareButton.tsx: -------------------------------------------------------------------------------- 1 | import React, { useRef } from 'react' 2 | import { 3 | CustomWindow, 4 | getPositionOnWindowCenter, 5 | getPositionOnScreenCenter, 6 | isPromise, 7 | } from '../utils' 8 | 9 | import Icon from './icons/icon' 10 | import { CustomProps } from '../types' 11 | 12 | export type Props = Omit< 13 | React.ButtonHTMLAttributes, 14 | keyof CustomProps 15 | > & 16 | CustomProps 17 | 18 | const SocialShareButton = ({ 19 | onShareWindowClose, 20 | windowHeight = 400, 21 | windowPosition = 'windowCenter', 22 | windowWidth = 550, 23 | blankTarget = false, 24 | beforeOnClick, 25 | disabled, 26 | networkLink, 27 | onClick, 28 | url, 29 | openShareDialogOnClick, 30 | opts, 31 | children, 32 | forwardedRef, 33 | networkName, 34 | style, 35 | round, 36 | bgColor, 37 | size = 64, 38 | borderRadius = 0, 39 | iconFillColor, 40 | buttonTitle, 41 | color, 42 | ...rest 43 | }: Props) => { 44 | const buttonRef = useRef(null) 45 | 46 | const openShareDialog = (link: string) => { 47 | const windowConfig = { 48 | height: windowHeight, 49 | width: windowWidth, 50 | ...(windowPosition === 'windowCenter' 51 | ? getPositionOnWindowCenter(windowWidth, windowHeight) 52 | : getPositionOnScreenCenter(windowWidth, windowHeight)), 53 | } 54 | 55 | CustomWindow(link, windowConfig, blankTarget, onShareWindowClose) 56 | } 57 | 58 | const handleClick = async (event: React.MouseEvent) => { 59 | const link = networkLink(url, opts) 60 | 61 | if (disabled) { 62 | return 63 | } 64 | 65 | event.preventDefault() 66 | 67 | if (beforeOnClick) { 68 | const returnVal = beforeOnClick() 69 | 70 | if (isPromise(returnVal)) { 71 | await returnVal 72 | } 73 | } 74 | 75 | if (openShareDialogOnClick) { 76 | openShareDialog(link) 77 | } 78 | 79 | if (onClick) { 80 | onClick(event, link) 81 | } 82 | } 83 | 84 | const newStyle = { 85 | backgroundColor: 'transparent', 86 | border: 'none', 87 | padding: 0, 88 | font: 'inherit', 89 | color: 'inherit', 90 | cursor: 'pointer', 91 | outline: 'none', 92 | ...style, 93 | } 94 | 95 | return ( 96 | 115 | ) 116 | } 117 | 118 | SocialShareButton.defaultProps = { 119 | disabledStyle: { opacity: 0.6 }, 120 | openShareDialogOnClick: true, 121 | resetButtonStyle: true, 122 | } 123 | 124 | export default SocialShareButton 125 | -------------------------------------------------------------------------------- /src/components/buttons/EmailShareButton.ts: -------------------------------------------------------------------------------- 1 | import createShareButton from '../../hocs/createShareButton' 2 | import { EmailLinkParams } from '../../types' 3 | import { emailLink } from '../../utils/button' 4 | 5 | const EmailShareButton = createShareButton( 6 | 'email', 7 | emailLink, 8 | (props) => ({ 9 | subject: props.subject, 10 | body: props.body, 11 | separator: props.separator || ' ', 12 | }), 13 | { 14 | openShareDialogOnClick: false, 15 | onClick: (_, link: string) => { 16 | window.location.href = link 17 | }, 18 | }, 19 | ) 20 | 21 | export default EmailShareButton 22 | -------------------------------------------------------------------------------- /src/components/buttons/FacebookMessengerShareButton.ts: -------------------------------------------------------------------------------- 1 | import createShareButton from '../../hocs/createShareButton' 2 | import { FacebookMessengerLinkParams } from '../../types' 3 | import { facebookMessengerLink } from '../../utils/button' 4 | 5 | const FacebookMessengerShareButton = 6 | createShareButton( 7 | 'facebookmessenger', 8 | facebookMessengerLink, 9 | ({ appId, redirectUri, to }) => ({ 10 | appId, 11 | redirectUri, 12 | to, 13 | }), 14 | { 15 | windowWidth: 1000, 16 | windowHeight: 820, 17 | }, 18 | ) 19 | 20 | export default FacebookMessengerShareButton 21 | -------------------------------------------------------------------------------- /src/components/buttons/FacebookShareButton.ts: -------------------------------------------------------------------------------- 1 | import createShareButton from '../../hocs/createShareButton' 2 | import { FacebookLinkParams } from '../../types' 3 | import { facebookLink } from '../../utils/button' 4 | 5 | const FacebookShareButton = createShareButton( 6 | 'facebook', 7 | facebookLink, 8 | (props) => ({ 9 | quote: props.quote, 10 | hashtag: props.hashtag, 11 | }), 12 | { 13 | windowWidth: 550, 14 | windowHeight: 400, 15 | }, 16 | ) 17 | 18 | export default FacebookShareButton 19 | -------------------------------------------------------------------------------- /src/components/buttons/GabShareButton.ts: -------------------------------------------------------------------------------- 1 | import createShareButton from '../../hocs/createShareButton' 2 | import { GapLinkParams } from '../../types' 3 | import { gabLink } from '../../utils/button' 4 | 5 | const GabShareButton = createShareButton( 6 | 'gab', 7 | gabLink, 8 | ({ title }) => ({ 9 | title, 10 | }), 11 | { 12 | windowWidth: 660, 13 | windowHeight: 640, 14 | windowPosition: 'windowCenter', 15 | }, 16 | ) 17 | 18 | export default GabShareButton 19 | -------------------------------------------------------------------------------- /src/components/buttons/HatenaShareButton.ts: -------------------------------------------------------------------------------- 1 | import createShareButton from '../../hocs/createShareButton' 2 | import { HatenaLinkParams } from '../../types' 3 | import { hatenaLink } from '../../utils/button' 4 | 5 | const HatenaShareButton = createShareButton( 6 | 'hatena', 7 | hatenaLink, 8 | ({ title }) => ({ 9 | title, 10 | }), 11 | { 12 | windowWidth: 660, 13 | windowHeight: 460, 14 | windowPosition: 'windowCenter', 15 | }, 16 | ) 17 | 18 | export default HatenaShareButton 19 | -------------------------------------------------------------------------------- /src/components/buttons/InstapaperShareButton.ts: -------------------------------------------------------------------------------- 1 | import createShareButton from '../../hocs/createShareButton' 2 | import { InstaPaperLinkParams } from '../../types' 3 | import { instapaperLink } from '../../utils/button' 4 | 5 | const InstapaperShareButton = createShareButton( 6 | 'instapaper', 7 | instapaperLink, 8 | ({ title, description }) => ({ 9 | title, 10 | description, 11 | }), 12 | { 13 | windowWidth: 500, 14 | windowHeight: 500, 15 | windowPosition: 'windowCenter', 16 | }, 17 | ) 18 | 19 | export default InstapaperShareButton 20 | -------------------------------------------------------------------------------- /src/components/buttons/LineShareButton.ts: -------------------------------------------------------------------------------- 1 | import createShareButton from '../../hocs/createShareButton' 2 | import { LineLinkParams } from '../../types' 3 | import { lineLink } from '../../utils/button' 4 | 5 | const LineShareButton = createShareButton( 6 | 'line', 7 | lineLink, 8 | ({ title }) => ({ 9 | title, 10 | }), 11 | { 12 | windowWidth: 500, 13 | windowHeight: 500, 14 | }, 15 | ) 16 | 17 | export default LineShareButton 18 | -------------------------------------------------------------------------------- /src/components/buttons/LinkedinShareButton.ts: -------------------------------------------------------------------------------- 1 | import createShareButton from '../../hocs/createShareButton' 2 | import { LinkedInLinkParams } from '../../types' 3 | import { linkedinLink } from '../../utils/button' 4 | 5 | const LinkedinShareButton = createShareButton( 6 | 'linkedin', 7 | linkedinLink, 8 | ({ title, summary, source }) => ({ title, summary, source }), 9 | { 10 | windowWidth: 750, 11 | windowHeight: 600, 12 | }, 13 | ) 14 | 15 | export default LinkedinShareButton 16 | -------------------------------------------------------------------------------- /src/components/buttons/LivejournalShareButton.ts: -------------------------------------------------------------------------------- 1 | import createShareButton from '../../hocs/createShareButton' 2 | import { LiveJournalLinkParams } from '../../types' 3 | import { liveJournalLink } from '../../utils/button' 4 | 5 | const LiveJournalShareButton = createShareButton( 6 | 'livejournal', 7 | liveJournalLink, 8 | ({ description, title }) => ({ 9 | title, 10 | description, 11 | }), 12 | { 13 | windowWidth: 660, 14 | windowHeight: 460, 15 | }, 16 | ) 17 | 18 | export default LiveJournalShareButton 19 | -------------------------------------------------------------------------------- /src/components/buttons/MailruShareButton.ts: -------------------------------------------------------------------------------- 1 | import createShareButton from '../../hocs/createShareButton' 2 | import { MailruLinkParams } from '../../types' 3 | import { mailruLink } from '../../utils/button' 4 | 5 | const MailruShareButton = createShareButton( 6 | 'mailru', 7 | mailruLink, 8 | ({ title, description, imageUrl }) => ({ 9 | title, 10 | description, 11 | imageUrl, 12 | }), 13 | { 14 | windowWidth: 660, 15 | windowHeight: 460, 16 | }, 17 | ) 18 | 19 | export default MailruShareButton 20 | -------------------------------------------------------------------------------- /src/components/buttons/PinterestShareButton.ts: -------------------------------------------------------------------------------- 1 | import createShareButton from '../../hocs/createShareButton' 2 | import { PinterestLinkParams } from '../../types' 3 | import { pinterestLink } from '../../utils/button' 4 | 5 | const PinterestShareButton = createShareButton( 6 | 'pinterest', 7 | pinterestLink, 8 | ({ media, description }) => ({ 9 | media, 10 | description, 11 | }), 12 | { 13 | windowWidth: 1000, 14 | windowHeight: 730, 15 | }, 16 | ) 17 | 18 | export default PinterestShareButton 19 | -------------------------------------------------------------------------------- /src/components/buttons/PocketShareButton.ts: -------------------------------------------------------------------------------- 1 | import createShareButton from '../../hocs/createShareButton' 2 | import { PocketLinkParams } from '../../types' 3 | import { pocketLink } from '../../utils/button' 4 | 5 | const PocketShareButton = createShareButton( 6 | 'pocket', 7 | pocketLink, 8 | ({ title }) => ({ 9 | title, 10 | }), 11 | { 12 | windowWidth: 500, 13 | windowHeight: 500, 14 | }, 15 | ) 16 | 17 | export default PocketShareButton 18 | -------------------------------------------------------------------------------- /src/components/buttons/RedditShareButton.ts: -------------------------------------------------------------------------------- 1 | import createShareButton from '../../hocs/createShareButton' 2 | import { RedditLinkParams } from '../../types' 3 | import { redditLink } from '../../utils/button' 4 | 5 | const RedditShareButton = createShareButton( 6 | 'reddit', 7 | redditLink, 8 | ({ title }) => ({ 9 | title, 10 | }), 11 | { 12 | windowWidth: 660, 13 | windowHeight: 460, 14 | windowPosition: 'windowCenter', 15 | }, 16 | ) 17 | 18 | export default RedditShareButton 19 | -------------------------------------------------------------------------------- /src/components/buttons/TelegramShareButton.ts: -------------------------------------------------------------------------------- 1 | import createShareButton from '../../hocs/createShareButton' 2 | import { TelegramLinkParams } from '../../types' 3 | import { telegramLink } from '../../utils/button' 4 | 5 | const TelegramShareButton = createShareButton( 6 | 'telegram', 7 | telegramLink, 8 | ({ title }) => ({ 9 | title, 10 | }), 11 | { 12 | windowWidth: 550, 13 | windowHeight: 400, 14 | }, 15 | ) 16 | 17 | export default TelegramShareButton 18 | -------------------------------------------------------------------------------- /src/components/buttons/TumblrShareButton.ts: -------------------------------------------------------------------------------- 1 | import createShareButton from '../../hocs/createShareButton' 2 | import { TumblrLinkParams } from '../../types' 3 | import { tumblrLink } from '../../utils/button' 4 | 5 | const TumblrShareButton = createShareButton< 6 | TumblrLinkParams & { tags?: string[] }, 7 | TumblrLinkParams & { tags: string } 8 | >( 9 | 'tumblr', 10 | tumblrLink, 11 | ({ title, tags, caption, posttype }) => ({ 12 | title, 13 | caption, 14 | tags: (tags || []).join(','), 15 | posttype: posttype || 'link', 16 | }), 17 | { 18 | windowWidth: 660, 19 | windowHeight: 460, 20 | }, 21 | ) 22 | 23 | export default TumblrShareButton 24 | -------------------------------------------------------------------------------- /src/components/buttons/TwitterShareButton.ts: -------------------------------------------------------------------------------- 1 | import createShareButton from '../../hocs/createShareButton' 2 | import { TwitterLinkParams } from '../../types' 3 | import { twitterLink } from '../../utils/button' 4 | 5 | const TwitterShareButton = createShareButton( 6 | 'twitter', 7 | twitterLink, 8 | ({ title, via, related, hashtags }) => ({ 9 | hashtags, 10 | title, 11 | via, 12 | related, 13 | }), 14 | { 15 | windowWidth: 550, 16 | windowHeight: 400, 17 | }, 18 | ) 19 | 20 | export default TwitterShareButton 21 | -------------------------------------------------------------------------------- /src/components/buttons/VKShareButton.ts: -------------------------------------------------------------------------------- 1 | import createShareButton from '../../hocs/createShareButton' 2 | import { VKShareLinkParams } from '../../types' 3 | import { vkLink } from '../../utils/button' 4 | 5 | const VKShareButton = createShareButton( 6 | 'vk', 7 | vkLink, 8 | ({ title, image, noParse, noVkLinks }) => ({ 9 | title, 10 | image, 11 | noParse, 12 | noVkLinks, 13 | }), 14 | { 15 | windowWidth: 660, 16 | windowHeight: 460, 17 | }, 18 | ) 19 | 20 | export default VKShareButton 21 | -------------------------------------------------------------------------------- /src/components/buttons/ViberShareButton.ts: -------------------------------------------------------------------------------- 1 | import createShareButton from '../../hocs/createShareButton' 2 | import { ViberLinkParams } from '../../types' 3 | import { viberLink } from '../../utils/button' 4 | 5 | const ViberShareButton = createShareButton( 6 | 'viber', 7 | viberLink, 8 | ({ separator, title }) => ({ 9 | title, 10 | separator: separator || ' ', 11 | }), 12 | { 13 | windowWidth: 660, 14 | windowHeight: 460, 15 | }, 16 | ) 17 | 18 | export default ViberShareButton 19 | -------------------------------------------------------------------------------- /src/components/buttons/WeiboShareButton.ts: -------------------------------------------------------------------------------- 1 | import createShareButton from '../../hocs/createShareButton' 2 | import { WeiboShareLinkParams } from '../../types' 3 | import { weiboLink } from '../../utils/button' 4 | 5 | const WeiboShareButton = createShareButton( 6 | 'weibo', 7 | weiboLink, 8 | (props) => ({ 9 | title: props.title, 10 | image: props.image, 11 | }), 12 | { 13 | windowWidth: 660, 14 | windowHeight: 550, 15 | windowPosition: 'screenCenter', 16 | }, 17 | ) 18 | 19 | export default WeiboShareButton 20 | -------------------------------------------------------------------------------- /src/components/buttons/WhatsappShareButton.ts: -------------------------------------------------------------------------------- 1 | import createShareButton from '../../hocs/createShareButton' 2 | import { WhatsAppLinkParams } from '../../types' 3 | import { whatsappLink } from '../../utils/button' 4 | 5 | const WhatsappShareButton = createShareButton( 6 | 'whatsapp', 7 | whatsappLink, 8 | ({ title, separator }) => ({ 9 | title, 10 | separator: separator || ' ', 11 | }), 12 | { 13 | windowWidth: 550, 14 | windowHeight: 400, 15 | }, 16 | ) 17 | 18 | export default WhatsappShareButton 19 | -------------------------------------------------------------------------------- /src/components/buttons/WorkplaceShareButton.ts: -------------------------------------------------------------------------------- 1 | import createShareButton from '../../hocs/createShareButton' 2 | import { WorkplaceLinkParams } from '../../types' 3 | import { workplaceLink } from '../../utils/button' 4 | 5 | const WorkplaceShareButton = createShareButton( 6 | 'workplace', 7 | workplaceLink, 8 | ({ quote, hashtag }) => ({ 9 | quote, 10 | hashtag, 11 | }), 12 | { 13 | windowWidth: 550, 14 | windowHeight: 400, 15 | }, 16 | ) 17 | 18 | export default WorkplaceShareButton 19 | -------------------------------------------------------------------------------- /src/components/counts/FacebookShareCount.ts: -------------------------------------------------------------------------------- 1 | import createShareCount from '../../hocs/createShareCount' 2 | import { getFacebookShareCount } from '../../utils/count' 3 | 4 | export default createShareCount(getFacebookShareCount) 5 | -------------------------------------------------------------------------------- /src/components/counts/HatenaShareCount.ts: -------------------------------------------------------------------------------- 1 | import createShareCount from '../../hocs/createShareCount' 2 | import { getHatenaShareCount } from '../../utils/count' 3 | 4 | export default createShareCount(getHatenaShareCount) 5 | -------------------------------------------------------------------------------- /src/components/counts/OKShareCount.ts: -------------------------------------------------------------------------------- 1 | import createShareCount from '../../hocs/createShareCount' 2 | import { getOKShareCount } from '../../utils/count' 3 | 4 | export default createShareCount(getOKShareCount) 5 | -------------------------------------------------------------------------------- /src/components/counts/PinterestShareCount.ts: -------------------------------------------------------------------------------- 1 | import createShareCount from '../../hocs/createShareCount' 2 | import { getPinterestShareCount } from '../../utils/count' 3 | 4 | export default createShareCount(getPinterestShareCount) 5 | -------------------------------------------------------------------------------- /src/components/counts/RedditShareCount.ts: -------------------------------------------------------------------------------- 1 | import createShareCount from '../../hocs/createShareCount' 2 | import { getRedditShareCount } from '../../utils/count' 3 | 4 | export default createShareCount(getRedditShareCount) 5 | -------------------------------------------------------------------------------- /src/components/counts/TumblrShareCount.ts: -------------------------------------------------------------------------------- 1 | import createShareCount from '../../hocs/createShareCount' 2 | import { getTumblrShareCount } from '../../utils/count' 3 | 4 | export default createShareCount(getTumblrShareCount) 5 | -------------------------------------------------------------------------------- /src/components/counts/VKShareCount.ts: -------------------------------------------------------------------------------- 1 | import createShareCount from '../../hocs/createShareCount' 2 | import { getVKShareCount } from '../../utils/count' 3 | 4 | export default createShareCount(getVKShareCount) 5 | -------------------------------------------------------------------------------- /src/components/icons/icon.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { IconProps } from '../../types' 3 | 4 | import icons from '../../constant/icons' 5 | 6 | const Icon: React.FC = ({ 7 | color, 8 | background, 9 | round, 10 | size, 11 | borderRadius, 12 | network, 13 | }) => { 14 | const icon = icons[network.toString()] 15 | 16 | return ( 17 | 18 | {round ? ( 19 | 20 | ) : ( 21 | 28 | )} 29 | 30 | 31 | ) 32 | } 33 | 34 | export default React.memo(Icon) 35 | -------------------------------------------------------------------------------- /src/constant/icons.ts: -------------------------------------------------------------------------------- 1 | import { SocialIcons } from '../types' 2 | 3 | const icons: SocialIcons = { 4 | gab: { 5 | color: '#00d178', 6 | name: 'gab', 7 | path: 'm17.0506,23.97457l5.18518,0l0,14.23933c0,6.82699 -3.72695,10.09328 -9.33471,10.09328c-2.55969,0 -4.82842,-0.87286 -6.22084,-2.0713l2.07477,-3.88283c1.19844,0.81051 2.33108,1.29543 3.85511,1.29543c2.75366,0 4.44049,-1.97432 4.44049,-4.82149l0,-0.87286c-1.16728,1.39242 -2.81947,2.0713 -4.63446,2.0713c-4.44048,0 -7.81068,-3.68885 -7.81068,-8.28521c0,-4.59289 3.37019,-8.28174 7.81068,-8.28174c1.81499,0 3.46718,0.67888 4.63446,2.0713l0,-1.55521zm-3.62997,11.39217c1.97777,0 3.62997,-1.6522 3.62997,-3.62652c0,-1.97432 -1.6522,-3.62305 -3.62997,-3.62305c-1.97778,0 -3.62997,1.64873 -3.62997,3.62305c0,1.97432 1.65219,3.62652 3.62997,3.62652zm25.7077,4.13913l-5.18518,0l0,-1.29197c-1.00448,1.13264 -2.3969,1.81152 -4.21188,1.81152c-3.62997,0 -5.63893,-2.52504 -5.63893,-5.4034c0,-4.27076 5.251,-5.85715 9.78846,-4.49937c-0.09698,-1.39241 -0.9733,-2.39343 -2.78829,-2.39343c-1.26426,0 -2.72248,0.48492 -3.62997,1.00102l-1.5552,-3.72003c1.19844,-0.77587 3.40136,-1.55174 5.96452,-1.55174c3.78931,0 7.25648,2.13365 7.25648,7.95962l0,8.08777zm-5.18518,-6.14809c-2.42806,-0.77587 -4.66563,-0.3533 -4.66563,1.36124c0,1.00101 0.84168,1.6799 1.84616,1.6799c1.20191,0 2.56315,-0.96984 2.81947,-3.04115zm13.00626,-17.66495l0,9.83695c1.16727,-1.39242 2.81946,-2.0713 4.63445,-2.0713c4.44048,0 7.81068,3.68885 7.81068,8.28174c0,4.59636 -3.37019,8.28521 -7.81068,8.28521c-1.81499,0 -3.46718,-0.67888 -4.63445,-2.0713l0,1.55174l-5.18519,0l0,-23.81304l5.18519,0zm3.62997,19.67391c1.97777,0 3.62997,-1.6522 3.62997,-3.62652c0,-1.97432 -1.6522,-3.62305 -3.62997,-3.62305c-1.97778,0 -3.62997,1.64873 -3.62997,3.62305c0,1.97432 1.65219,3.62652 3.62997,3.62652zm0,0', 8 | }, 9 | email: { 10 | color: '#7f7f7f', 11 | name: 'email', 12 | path: 'M17,22v20h30V22H17z M41.1,25L32,32.1L22.9,25H41.1z M20,39V26.6l12,9.3l12-9.3V39H20z', 13 | }, 14 | facebook: { 15 | color: '#3b5998', 16 | name: 'facebook', 17 | path: 'M34.1,47V33.3h4.6l0.7-5.3h-5.3v-3.4c0-1.5,0.4-2.6,2.6-2.6l2.8,0v-4.8c-0.5-0.1-2.2-0.2-4.1-0.2 c-4.1,0-6.9,2.5-6.9,7V28H24v5.3h4.6V47H34.1z', 18 | }, 19 | facebookmessenger: { 20 | color: '#2196F3', 21 | name: 'facebookmessenger', 22 | path: 'M 53.066406 21.871094 C 52.667969 21.339844 51.941406 21.179688 51.359375 21.496094 L 37.492188 29.058594 L 28.867188 21.660156 C 28.339844 21.207031 27.550781 21.238281 27.054688 21.730469 L 11.058594 37.726562 C 10.539062 38.25 10.542969 39.09375 11.0625 39.613281 C 11.480469 40.027344 12.121094 40.121094 12.640625 39.839844 L 26.503906 32.28125 L 35.136719 39.679688 C 35.667969 40.132812 36.457031 40.101562 36.949219 39.609375 L 52.949219 23.613281 C 53.414062 23.140625 53.464844 22.398438 53.066406 21.871094 Z M 53.066406 21.871094', 23 | }, 24 | github: { 25 | color: '#24292e', 26 | name: 'github', 27 | path: 'M32,16c-8.8,0-16,7.2-16,16c0,7.1,4.6,13.1,10.9,15.2 c0.8,0.1,1.1-0.3,1.1-0.8c0-0.4,0-1.4,0-2.7c-4.5,1-5.4-2.1-5.4-2.1c-0.7-1.8-1.8-2.3-1.8-2.3c-1.5-1,0.1-1,0.1-1 c1.6,0.1,2.5,1.6,2.5,1.6c1.4,2.4,3.7,1.7,4.7,1.3c0.1-1,0.6-1.7,1-2.1c-3.6-0.4-7.3-1.8-7.3-7.9c0-1.7,0.6-3.2,1.6-4.3 c-0.2-0.4-0.7-2,0.2-4.2c0,0,1.3-0.4,4.4,1.6c1.3-0.4,2.6-0.5,4-0.5c1.4,0,2.7,0.2,4,0.5c3.1-2.1,4.4-1.6,4.4-1.6 c0.9,2.2,0.3,3.8,0.2,4.2c1,1.1,1.6,2.5,1.6,4.3c0,6.1-3.7,7.5-7.3,7.9c0.6,0.5,1.1,1.5,1.1,3c0,2.1,0,3.9,0,4.4 c0,0.4,0.3,0.9,1.1,0.8C43.4,45.1,48,39.1,48,32C48,23.2,40.8,16,32,16z', 28 | }, 29 | hatena: { 30 | color: '#009ad9', 31 | name: 'hatena', 32 | path: 'M 36.164062 33.554688 C 34.988281 32.234375 33.347656 31.5 31.253906 31.34375 C 33.125 30.835938 34.476562 30.09375 35.335938 29.09375 C 36.191406 28.09375 36.609375 26.78125 36.609375 25.101562 C 36.628906 23.875 36.332031 22.660156 35.75 21.578125 C 35.160156 20.558594 34.292969 19.71875 33.253906 19.160156 C 32.304688 18.640625 31.175781 18.265625 29.847656 18.042969 C 28.523438 17.824219 26.195312 17.730469 22.867188 17.730469 L 14.769531 17.730469 L 14.769531 47.269531 L 23.113281 47.269531 C 26.46875 47.269531 28.886719 47.15625 30.367188 46.929688 C 31.851562 46.695312 33.085938 46.304688 34.085938 45.773438 C 35.289062 45.148438 36.28125 44.179688 36.933594 42.992188 C 37.597656 41.796875 37.933594 40.402344 37.933594 38.816406 C 37.933594 36.621094 37.347656 34.867188 36.164062 33.554688 Z M 22.257812 24.269531 L 23.984375 24.269531 C 25.988281 24.269531 27.332031 24.496094 28.015625 24.945312 C 28.703125 25.402344 29.042969 26.183594 29.042969 27.285156 C 29.042969 28.390625 28.664062 29.105469 27.9375 29.550781 C 27.210938 29.992188 25.84375 30.199219 23.855469 30.199219 L 22.257812 30.199219 Z M 29.121094 41.210938 C 28.328125 41.691406 26.976562 41.925781 25.078125 41.925781 L 22.257812 41.925781 L 22.257812 35.488281 L 25.195312 35.488281 C 27.144531 35.488281 28.496094 35.738281 29.210938 36.230469 C 29.925781 36.726562 30.304688 37.582031 30.304688 38.832031 C 30.304688 40.078125 29.914062 40.742188 29.105469 41.222656 Z M 29.121094 41.210938 M 46.488281 39.792969 C 44.421875 39.792969 42.742188 41.46875 42.742188 43.535156 C 42.742188 45.605469 44.421875 47.28125 46.488281 47.28125 C 48.554688 47.28125 50.230469 45.605469 50.230469 43.535156 C 50.230469 41.46875 48.554688 39.792969 46.488281 39.792969 Z M 46.488281 39.792969 M 43.238281 17.730469 L 49.738281 17.730469 L 49.738281 37.429688 L 43.238281 37.429688 Z M 43.238281 17.730469 ', 33 | }, 34 | instagram: { 35 | color: '#e94475', 36 | name: 'instagram', 37 | path: 'M 39.88,25.89 C 40.86,25.89 41.65,25.10 41.65,24.12 41.65,23.14 40.86,22.35 39.88,22.35 38.90,22.35 38.11,23.14 38.11,24.12 38.11,25.10 38.90,25.89 39.88,25.89 Z M 32.00,24.42 C 27.82,24.42 24.42,27.81 24.42,32.00 24.42,36.19 27.82,39.58 32.00,39.58 36.18,39.58 39.58,36.18 39.58,32.00 39.58,27.82 36.18,24.42 32.00,24.42 Z M 32.00,36.92 C 29.28,36.92 27.08,34.72 27.08,32.00 27.08,29.28 29.28,27.08 32.00,27.08 34.72,27.08 36.92,29.28 36.92,32.00 36.92,34.72 34.72,36.92 32.00,36.92 Z M 32.00,19.90 C 35.94,19.90 36.41,19.92 37.96,19.99 39.41,20.05 40.19,20.29 40.71,20.50 41.40,20.77 41.89,21.08 42.41,21.60 42.92,22.12 43.24,22.61 43.51,23.30 43.71,23.82 43.95,24.60 44.02,26.04 44.09,27.60 44.11,28.06 44.11,32.01 44.11,35.95 44.09,36.41 44.02,37.97 43.95,39.41 43.71,40.19 43.51,40.71 43.24,41.40 42.92,41.90 42.41,42.41 41.89,42.93 41.40,43.25 40.71,43.51 40.19,43.71 39.41,43.96 37.96,44.02 36.41,44.09 35.94,44.11 32.00,44.11 28.06,44.11 27.59,44.09 26.04,44.02 24.59,43.96 23.81,43.72 23.29,43.51 22.60,43.24 22.11,42.93 21.59,42.41 21.08,41.90 20.76,41.40 20.49,40.71 20.29,40.19 20.05,39.41 19.98,37.97 19.91,36.41 19.89,35.95 19.89,32.01 19.89,28.06 19.91,27.60 19.98,26.04 20.05,24.60 20.29,23.82 20.49,23.30 20.76,22.61 21.08,22.12 21.59,21.60 22.11,21.08 22.60,20.76 23.29,20.50 23.81,20.30 24.59,20.05 26.04,19.99 27.59,19.91 28.06,19.90 32.00,19.90 Z M 32.00,17.24 C 27.99,17.24 27.49,17.26 25.91,17.33 24.34,17.40 23.27,17.65 22.33,18.01 21.36,18.39 20.54,18.90 19.72,19.72 18.90,20.54 18.39,21.37 18.01,22.33 17.65,23.27 17.40,24.34 17.33,25.92 17.26,27.49 17.24,27.99 17.24,32.00 17.24,36.01 17.26,36.51 17.33,38.09 17.40,39.66 17.65,40.73 18.01,41.67 18.39,42.65 18.90,43.47 19.72,44.29 20.54,45.11 21.37,45.61 22.33,45.99 23.27,46.36 24.34,46.61 25.92,46.68 27.49,46.75 27.99,46.77 32.01,46.77 36.02,46.77 36.52,46.75 38.09,46.68 39.66,46.61 40.74,46.36 41.68,45.99 42.65,45.62 43.47,45.11 44.29,44.29 45.11,43.47 45.62,42.64 46.00,41.67 46.36,40.74 46.61,39.66 46.68,38.09 46.75,36.51 46.77,36.01 46.77,32.00 46.77,27.99 46.75,27.49 46.68,25.91 46.61,24.34 46.36,23.27 46.00,22.33 45.62,21.35 45.11,20.53 44.29,19.71 43.47,18.89 42.65,18.39 41.68,18.01 40.74,17.64 39.67,17.39 38.09,17.32 36.51,17.26 36.01,17.24 32.00,17.24 Z', 38 | }, 39 | instapaper: { 40 | color: '#1F1F1F', 41 | name: 'instapaper', 42 | path: 'M35.688 43.012c0 2.425.361 2.785 3.912 3.056V48H24.401v-1.932c3.555-.27 3.912-.63 3.912-3.056V20.944c0-2.379-.36-2.785-3.912-3.056V16H39.6v1.888c-3.55.27-3.912.675-3.912 3.056v22.068h.001z', 43 | }, 44 | line: { 45 | color: '#00b800', 46 | name: 'line', 47 | path: 'M52.62 30.138c0 3.693-1.432 7.019-4.42 10.296h.001c-4.326 4.979-14 11.044-16.201 11.972-2.2.927-1.876-.591-1.786-1.112l.294-1.765c.069-.527.142-1.343-.066-1.865-.232-.574-1.146-.872-1.817-1.016-9.909-1.31-17.245-8.238-17.245-16.51 0-9.226 9.251-16.733 20.62-16.733 11.37 0 20.62 7.507 20.62 16.733zM27.81 25.68h-1.446a.402.402 0 0 0-.402.401v8.985c0 .221.18.4.402.4h1.446a.401.401 0 0 0 .402-.4v-8.985a.402.402 0 0 0-.402-.401zm9.956 0H36.32a.402.402 0 0 0-.402.401v5.338L31.8 25.858a.39.39 0 0 0-.031-.04l-.002-.003-.024-.025-.008-.007a.313.313 0 0 0-.032-.026.255.255 0 0 1-.021-.014l-.012-.007-.021-.012-.013-.006-.023-.01-.013-.005-.024-.008-.014-.003-.023-.005-.017-.002-.021-.003-.021-.002h-1.46a.402.402 0 0 0-.402.401v8.985c0 .221.18.4.402.4h1.446a.401.401 0 0 0 .402-.4v-5.337l4.123 5.568c.028.04.063.072.101.099l.004.003a.236.236 0 0 0 .025.015l.012.006.019.01a.154.154 0 0 1 .019.008l.012.004.028.01.005.001a.442.442 0 0 0 .104.013h1.446a.4.4 0 0 0 .401-.4v-8.985a.402.402 0 0 0-.401-.401zm-13.442 7.537h-3.93v-7.136a.401.401 0 0 0-.401-.401h-1.447a.4.4 0 0 0-.401.401v8.984a.392.392 0 0 0 .123.29c.072.068.17.111.278.111h5.778a.4.4 0 0 0 .401-.401v-1.447a.401.401 0 0 0-.401-.401zm21.429-5.287c.222 0 .401-.18.401-.402v-1.446a.401.401 0 0 0-.401-.402h-5.778a.398.398 0 0 0-.279.113l-.005.004-.006.008a.397.397 0 0 0-.111.276v8.984c0 .108.043.206.112.278l.005.006a.401.401 0 0 0 .284.117h5.778a.4.4 0 0 0 .401-.401v-1.447a.401.401 0 0 0-.401-.401h-3.93v-1.519h3.93c.222 0 .401-.18.401-.402V29.85a.401.401 0 0 0-.401-.402h-3.93V27.93h3.93z', 48 | }, 49 | linkedin: { 50 | color: '#007fb1', 51 | name: 'linkedin', 52 | path: 'M20.4,44h5.4V26.6h-5.4V44z M23.1,18c-1.7,0-3.1,1.4-3.1,3.1c0,1.7,1.4,3.1,3.1,3.1 c1.7,0,3.1-1.4,3.1-3.1C26.2,19.4,24.8,18,23.1,18z M39.5,26.2c-2.6,0-4.4,1.4-5.1,2.8h-0.1v-2.4h-5.2V44h5.4v-8.6 c0-2.3,0.4-4.5,3.2-4.5c2.8,0,2.8,2.6,2.8,4.6V44H46v-9.5C46,29.8,45,26.2,39.5,26.2z', 53 | }, 54 | livejournal: { 55 | color: '#21A5D8', 56 | name: 'livejournal', 57 | path: 'M18.3407821,28.1764706 L21.9441341,31.789916 L33.0055865,42.882353 C33.0055865,42.882353 33.0893855,42.9663866 33.0893855,42.9663866 L46.6648046,47 C46.6648046,47 46.6648046,47 46.7486034,47 C46.8324022,47 46.8324022,47 46.9162012,46.9159664 C47,46.8319327 47,46.8319327 47,46.7478991 L42.9776536,33.1344537 C42.9776536,33.1344537 42.9776536,33.1344537 42.8938548,33.0504202 L31.1620111,21.3697479 L31.1620111,21.3697479 L28.1452514,18.2605042 C27.3072626,17.4201681 26.5530726,17 25.7150838,17 C24.2905028,17 23.0335195,18.3445378 21.5251397,19.8571429 C21.273743,20.1092437 20.9385475,20.4453781 20.6871508,20.697479 C20.3519553,21.0336134 20.1005586,21.2857143 19.849162,21.5378151 C18.3407821,22.9663866 17.0837989,24.2268908 17,25.7394958 C17.0837989,26.4957983 17.5027933,27.3361345 18.3407821,28.1764706 Z M39.9012319,39.6134454 C39.7336341,39.4453781 39.4822374,37.6806724 40.2364275,36.8403362 C40.9906174,36.0840337 41.6610084,36 42.1638017,36 C42.3313995,36 42.4989973,36 42.5827961,36 L44.8453659,43.5630253 L43.5883828,44.8235295 L36.0464833,42.5546218 C35.9626843,42.2184874 35.8788855,41.2100841 36.8844722,40.2016807 C37.2196676,39.8655463 37.8900587,39.6134454 38.5604498,39.6134454 C39.147042,39.6134454 39.5660364,39.7815126 39.5660364,39.7815126 C39.6498353,39.8655463 39.8174331,39.8655463 39.8174331,39.7815126 C39.9850307,39.7815126 39.9850307,39.697479 39.9012319,39.6134454 Z', 58 | }, 59 | mailru: { 60 | color: '#168DE2', 61 | name: 'mailru', 62 | path: 'M39.7107745,17 C41.6619755,17 43.3204965,18.732852 43.3204965,21.0072202 C43.3204965,23.2815885 41.7595357,25.0144404 39.7107745,25.0144404 C37.7595732,25.0144404 36.1010522,23.2815885 36.1010522,21.0072202 C36.1010522,18.732852 37.7595732,17 39.7107745,17 Z M24.3938451,17 C26.3450463,17 28.0035672,18.732852 28.0035672,21.0072202 C28.0035672,23.2815885 26.4426063,25.0144404 24.3938451,25.0144404 C22.4426439,25.0144404 20.7841229,23.2815885 20.7841229,21.0072202 C20.7841229,18.732852 22.4426439,17 24.3938451,17 Z M51.9057817,43.4259928 C51.7106617,44.0758123 51.4179815,44.6173285 50.9301812,44.9422383 C50.637501,45.1588448 50.2472607,45.267148 49.8570205,45.267148 C49.07654,45.267148 48.3936197,44.833935 48.0033795,44.0758123 L46.2472985,40.7184115 L45.759498,41.2599278 C42.5400162,44.9422383 37.466893,47 32.0035297,47 C26.5401664,47 21.5646034,44.9422383 18.2475614,41.2599278 L17.7597611,40.7184115 L16.00368,44.0758123 C15.6134398,44.833935 14.9305194,45.267148 14.1500389,45.267148 C13.7597986,45.267148 13.3695584,45.1588448 13.0768782,44.9422383 C12.0037176,44.2924187 11.7110374,42.7761733 12.2963978,41.5848375 L16.7841605,33.0288807 C17.1744007,32.270758 17.8573211,31.8375453 18.6378016,31.8375453 C19.0280418,31.8375453 19.4182821,31.9458485 19.7109623,32.1624548 C20.7841229,32.8122743 21.0768031,34.3285197 20.4914427,35.5198555 L20.1012025,36.2779783 L20.2963226,36.602888 C22.4426439,39.9602888 27.0279667,42.234657 31.9059697,42.234657 C36.7839727,42.234657 41.3692955,40.068592 43.5156167,36.602888 L43.7107367,36.2779783 L43.3204965,35.6281587 C43.0278165,35.0866425 42.9302562,34.436823 43.1253765,33.7870035 C43.3204965,33.137184 43.6131767,32.5956678 44.100977,32.270758 C44.3936572,32.0541515 44.7838975,31.9458485 45.1741377,31.9458485 C45.9546182,31.9458485 46.6375385,32.3790613 47.0277787,33.137184 L51.5155415,41.6931408 C52.003342,42.234657 52.100902,42.8844765 51.9057817,43.4259928 Z', 63 | }, 64 | pinterest: { 65 | color: '#cb2128', 66 | name: 'pinterest', 67 | path: 'M32,16c-8.8,0-16,7.2-16,16c0,6.6,3.9,12.2,9.6,14.7c0-1.1,0-2.5,0.3-3.7 c0.3-1.3,2.1-8.7,2.1-8.7s-0.5-1-0.5-2.5c0-2.4,1.4-4.1,3.1-4.1c1.5,0,2.2,1.1,2.2,2.4c0,1.5-0.9,3.7-1.4,5.7 c-0.4,1.7,0.9,3.1,2.5,3.1c3,0,5.1-3.9,5.1-8.5c0-3.5-2.4-6.1-6.7-6.1c-4.9,0-7.9,3.6-7.9,7.7c0,1.4,0.4,2.4,1.1,3.1 c0.3,0.3,0.3,0.5,0.2,0.9c-0.1,0.3-0.3,1-0.3,1.3c-0.1,0.4-0.4,0.6-0.8,0.4c-2.2-0.9-3.3-3.4-3.3-6.1c0-4.5,3.8-10,11.4-10 c6.1,0,10.1,4.4,10.1,9.2c0,6.3-3.5,11-8.6,11c-1.7,0-3.4-0.9-3.9-2c0,0-0.9,3.7-1.1,4.4c-0.3,1.2-1,2.5-1.6,3.4 c1.4,0.4,3,0.7,4.5,0.7c8.8,0,16-7.2,16-16C48,23.2,40.8,16,32,16z', 68 | }, 69 | pocket: { 70 | color: '#EF3F56', 71 | name: 'pocket', 72 | path: 'M41.084 29.065l-7.528 7.882a2.104 2.104 0 0 1-1.521.666 2.106 2.106 0 0 1-1.522-.666l-7.528-7.882c-.876-.914-.902-2.43-.065-3.384.84-.955 2.228-.987 3.1-.072l6.015 6.286 6.022-6.286c.88-.918 2.263-.883 3.102.071.841.938.82 2.465-.06 3.383l-.015.002zm6.777-10.976C47.463 16.84 46.361 16 45.14 16H18.905c-1.2 0-2.289.82-2.716 2.044-.125.363-.189.743-.189 1.125v10.539l.112 2.096c.464 4.766 2.73 8.933 6.243 11.838.06.053.125.102.19.153l.04.033c1.882 1.499 3.986 2.514 6.259 3.014a14.662 14.662 0 0 0 6.13.052c.118-.042.235-.065.353-.087.03 0 .065-.022.098-.042a15.395 15.395 0 0 0 6.011-2.945l.039-.045.18-.153c3.502-2.902 5.765-7.072 6.248-11.852L48 29.674v-10.52c0-.366-.041-.728-.161-1.08l.022.015z', 73 | }, 74 | reddit: { 75 | color: '#ff4500', 76 | name: 'reddit', 77 | path: 'm 52.8165,31.942362 c 0,-2.4803 -2.0264,-4.4965 -4.5169,-4.4965 -1.2155,0 -2.3171,0.4862 -3.128,1.2682 -3.077,-2.0247 -7.2403,-3.3133 -11.8507,-3.4782 l 2.5211,-7.9373 6.8272,1.5997 -0.0102,0.0986 c 0,2.0281 1.6575,3.6771 3.6958,3.6771 2.0366,0 3.6924,-1.649 3.6924,-3.6771 0,-2.0281 -1.6575,-3.6788 -3.6924,-3.6788 -1.564,0 -2.8968,0.9758 -3.4357,2.3443 l -7.3593,-1.7255 c -0.3213,-0.0782 -0.6477,0.1071 -0.748,0.4233 L 32,25.212062 c -4.8246,0.0578 -9.1953,1.3566 -12.41,3.4425 -0.8058,-0.7446 -1.8751,-1.2104 -3.0583,-1.2104 -2.4905,0 -4.5152,2.0179 -4.5152,4.4982 0,1.649 0.9061,3.0787 2.2389,3.8607 -0.0884,0.4794 -0.1462,0.9639 -0.1462,1.4569 0,6.6487 8.1736,12.0581 18.2223,12.0581 10.0487,0 18.224,-5.4094 18.224,-12.0581 0,-0.4658 -0.0493,-0.9248 -0.1275,-1.377 1.4144,-0.7599 2.3885,-2.2304 2.3885,-3.9406 z m -29.2808,3.0872 c 0,-1.4756 1.207,-2.6775 2.6894,-2.6775 1.4824,0 2.6877,1.2019 2.6877,2.6775 0,1.4756 -1.2053,2.6758 -2.6877,2.6758 -1.4824,0 -2.6894,-1.2002 -2.6894,-2.6758 z m 15.4037,7.9373 c -1.3549,1.3481 -3.4816,2.0043 -6.5008,2.0043 l -0.0221,-0.0051 -0.0221,0.0051 c -3.0209,0 -5.1476,-0.6562 -6.5008,-2.0043 -0.2465,-0.2448 -0.2465,-0.6443 0,-0.8891 0.2465,-0.2465 0.6477,-0.2465 0.8942,0 1.105,1.0999 2.9393,1.6337 5.6066,1.6337 l 0.0221,0.0051 0.0221,-0.0051 c 2.6673,0 4.5016,-0.5355 5.6066,-1.6354 0.2465,-0.2465 0.6477,-0.2448 0.8942,0 0.2465,0.2465 0.2465,0.6443 0,0.8908 z m -0.3213,-5.2615 c -1.4824,0 -2.6877,-1.2002 -2.6877,-2.6758 0,-1.4756 1.2053,-2.6775 2.6877,-2.6775 1.4824,0 2.6877,1.2019 2.6877,2.6775 0,1.4756 -1.2053,2.6758 -2.6877,2.6758 z', 78 | }, 79 | spotify: { 80 | color: '#2EBD59', 81 | name: 'spotify', 82 | path: 'M32,16c-8.8,0-16,7.2-16,16c0,8.8,7.2,16,16,16c8.8,0,16-7.2,16-16C48,23.2,40.8,16,32,16 M39.3,39.1c-0.3,0.5-0.9,0.6-1.4,0.3c-3.8-2.3-8.5-2.8-14.1-1.5c-0.5,0.1-1.1-0.2-1.2-0.7c-0.1-0.5,0.2-1.1,0.8-1.2 c6.1-1.4,11.3-0.8,15.5,1.8C39.5,38,39.6,38.6,39.3,39.1 M41.3,34.7c-0.4,0.6-1.1,0.8-1.7,0.4c-4.3-2.6-10.9-3.4-15.9-1.9 c-0.7,0.2-1.4-0.2-1.6-0.8c-0.2-0.7,0.2-1.4,0.8-1.6c5.8-1.8,13-0.9,18,2.1C41.5,33.4,41.7,34.1,41.3,34.7 M41.5,30.2 c-5.2-3.1-13.7-3.3-18.6-1.9c-0.8,0.2-1.6-0.2-1.9-1c-0.2-0.8,0.2-1.6,1-1.9c5.7-1.7,15-1.4,21,2.1c0.7,0.4,0.9,1.3,0.5,2.1 C43.1,30.4,42.2,30.6,41.5,30.2', 83 | }, 84 | telegram: { 85 | color: '#37aee2', 86 | name: 'telegram', 87 | path: 'm45.90873,15.44335c-0.6901,-0.0281 -1.37668,0.14048 -1.96142,0.41265c-0.84989,0.32661 -8.63939,3.33986 -16.5237,6.39174c-3.9685,1.53296 -7.93349,3.06593 -10.98537,4.24067c-3.05012,1.1765 -5.34694,2.05098 -5.4681,2.09312c-0.80775,0.28096 -1.89996,0.63566 -2.82712,1.72788c-0.23354,0.27218 -0.46884,0.62161 -0.58825,1.10275c-0.11941,0.48114 -0.06673,1.09222 0.16682,1.5716c0.46533,0.96052 1.25376,1.35737 2.18443,1.71383c3.09051,0.99037 6.28638,1.93508 8.93263,2.8236c0.97632,3.44171 1.91401,6.89571 2.84116,10.34268c0.30554,0.69185 0.97105,0.94823 1.65764,0.95525l-0.00351,0.03512c0,0 0.53908,0.05268 1.06412,-0.07375c0.52679,-0.12292 1.18879,-0.42846 1.79109,-0.99212c0.662,-0.62161 2.45836,-2.38812 3.47683,-3.38552l7.6736,5.66477l0.06146,0.03512c0,0 0.84989,0.59703 2.09312,0.68132c0.62161,0.04214 1.4399,-0.07726 2.14229,-0.59176c0.70766,-0.51626 1.1765,-1.34683 1.396,-2.29506c0.65673,-2.86224 5.00979,-23.57745 5.75257,-27.00686l-0.02107,0.08077c0.51977,-1.93157 0.32837,-3.70159 -0.87096,-4.74991c-0.60054,-0.52152 -1.2924,-0.7498 -1.98425,-0.77965l0,0.00176zm-0.2072,3.29069c0.04741,0.0439 0.0439,0.0439 0.00351,0.04741c-0.01229,-0.00351 0.14048,0.2072 -0.15804,1.32576l-0.01229,0.04214l-0.00878,0.03863c-0.75858,3.50668 -5.15554,24.40802 -5.74203,26.96472c-0.08077,0.34417 -0.11414,0.31959 -0.09482,0.29852c-0.1756,-0.02634 -0.50045,-0.16506 -0.52679,-0.1756l-13.13468,-9.70175c4.4988,-4.33199 9.09945,-8.25307 13.744,-12.43229c0.8218,-0.41265 0.68483,-1.68573 -0.29852,-1.70681c-1.04305,0.24584 -1.92279,0.99564 -2.8798,1.47502c-5.49971,3.2626 -11.11882,6.13186 -16.55882,9.49279c-2.792,-0.97105 -5.57873,-1.77704 -8.15298,-2.57601c2.2336,-0.89555 4.00889,-1.55579 5.75608,-2.23009c3.05188,-1.1765 7.01687,-2.7042 10.98537,-4.24067c7.94051,-3.06944 15.92667,-6.16346 16.62028,-6.43037l0.05619,-0.02283l0.05268,-0.02283c0.19316,-0.0878 0.30378,-0.09658 0.35471,-0.10009c0,0 -0.01756,-0.05795 -0.00351,-0.04566l-0.00176,0zm-20.91715,22.0638l2.16687,1.60145c-0.93418,0.91311 -1.81743,1.77353 -2.45485,2.38812l0.28798,-3.98957', 88 | }, 89 | tumblr: { 90 | color: '#2c4762', 91 | name: 'tumblr', 92 | path: 'M39.2,41c-0.6,0.3-1.6,0.5-2.4,0.5c-2.4,0.1-2.9-1.7-2.9-3v-9.3h6v-4.5h-6V17c0,0-4.3,0-4.4,0 c-0.1,0-0.2,0.1-0.2,0.2c-0.3,2.3-1.4,6.4-5.9,8.1v3.9h3V39c0,3.4,2.5,8.1,9,8c2.2,0,4.7-1,5.2-1.8L39.2,41z', 93 | }, 94 | twitter: { 95 | color: '#000000', 96 | name: 'twitter', 97 | path: 'M 41.116 18.375 h 4.962 l -10.8405 12.39 l 12.753 16.86 H 38.005 l -7.821 -10.2255 L 21.235 47.625 H 16.27 l 11.595 -13.2525 L 15.631 18.375 H 25.87 l 7.0695 9.3465 z m -1.7415 26.28 h 2.7495 L 24.376 21.189 H 21.4255 z', 98 | }, 99 | viber: { 100 | color: '#7C529E', 101 | name: 'viber', 102 | path: 'm31.0,12.3c9.0,0.2 16.4,6.2 18.0,15.2c0.2,1.5 0.3,3.0 0.4,4.6a1.0,1.0 0 0 1 -0.8,1.2l-0.1,0a1.1,1.1 0 0 1 -1.0,-1.2l0,0c-0.0,-1.2 -0.1,-2.5 -0.3,-3.8a16.1,16.1 0 0 0 -13.0,-13.5c-1.0,-0.1 -2.0,-0.2 -3.0,-0.3c-0.6,-0.0 -1.4,-0.1 -1.6,-0.8a1.1,1.1 0 0 1 0.9,-1.2l0.6,0l0.0,-0.0zm10.6,39.2a19.9,19.9 0 0 1 -2.1,-0.6c-6.9,-2.9 -13.2,-6.6 -18.3,-12.2a47.5,47.5 0 0 1 -7.0,-10.7c-0.8,-1.8 -1.6,-3.7 -2.4,-5.6c-0.6,-1.7 0.3,-3.4 1.4,-4.7a11.3,11.3 0 0 1 3.7,-2.8a2.4,2.4 0 0 1 3.0,0.7a39.0,39.0 0 0 1 4.7,6.5a3.1,3.1 0 0 1 -0.8,4.2c-0.3,0.2 -0.6,0.5 -1.0,0.8a3.3,3.3 0 0 0 -0.7,0.7a2.1,2.1 0 0 0 -0.1,1.9c1.7,4.9 4.7,8.7 9.7,10.8a5.0,5.0 0 0 0 2.5,0.6c1.5,-0.1 2.0,-1.8 3.1,-2.7a2.9,2.9 0 0 1 3.5,-0.1c1.1,0.7 2.2,1.4 3.3,2.2a37.8,37.8 0 0 1 3.1,2.4a2.4,2.4 0 0 1 0.7,3.0a10.4,10.4 0 0 1 -4.4,4.8a10.8,10.8 0 0 1 -1.9,0.6c-0.7,-0.2 0.6,-0.2 0,0l0.0,0l0,-0.0zm3.1,-21.4a4.2,4.2 0 0 1 -0.0,0.6a1.0,1.0 0 0 1 -1.9,0.1a2.7,2.7 0 0 1 -0.1,-0.8a10.9,10.9 0 0 0 -1.4,-5.5a10.2,10.2 0 0 0 -4.2,-4.0a12.3,12.3 0 0 0 -3.4,-1.0c-0.5,-0.0 -1.0,-0.1 -1.5,-0.2a0.9,0.9 0 0 1 -0.9,-1.0l0,-0.1a0.9,0.9 0 0 1 0.9,-0.9l0.1,0a14.1,14.1 0 0 1 5.9,1.5a11.9,11.9 0 0 1 6.5,9.3c0,0.1 0.0,0.3 0.0,0.5c0,0.4 0.0,0.9 0.0,1.5l0,0l0.0,0.0zm-5.6,-0.2a1.1,1.1 0 0 1 -1.2,-0.9l0,-0.1a11.3,11.3 0 0 0 -0.2,-1.4a4.0,4.0 0 0 0 -1.5,-2.3a3.9,3.9 0 0 0 -1.2,-0.5c-0.5,-0.1 -1.1,-0.1 -1.6,-0.2a1.0,1.0 0 0 1 -0.8,-1.1l0,0l0,0a1.0,1.0 0 0 1 1.1,-0.8c3.4,0.2 6.0,2.0 6.3,6.2a2.8,2.8 0 0 1 0,0.8a0.8,0.8 0 0 1 -0.8,0.7l0,0l0.0,-0.0z', 103 | }, 104 | vk: { 105 | color: '#45668e', 106 | name: 'vk', 107 | path: 'M44.94,44.84h-0.2c-2.17-.36-3.66-1.92-4.92-3.37C39.1,40.66,38,38.81,36.7,39c-1.85.3-.93,3.52-1.71,4.9-0.62,1.11-3.29.91-5.12,0.71-5.79-.62-8.75-3.77-11.35-7.14A64.13,64.13,0,0,1,11.6,26a10.59,10.59,0,0,1-1.51-4.49C11,20.7,12.56,21,14.11,21c1.31,0,3.36-.29,4.32.2C19,21.46,19.57,23,20,24a37.18,37.18,0,0,0,3.31,5.82c0.56,0.81,1.41,2.35,2.41,2.14s1.06-2.63,1.1-4.18c0-1.77,0-4-.5-4.9S25,22,24.15,21.47c0.73-1.49,2.72-1.63,5.12-1.63,2,0,4.84-.23,5.62,1.12s0.25,3.85.2,5.71c-0.06,2.09-.41,4.25,1,5.21,1.09-.12,1.68-1.2,2.31-2A28,28,0,0,0,41.72,24c0.44-1,.91-2.65,1.71-3,1.21-.47,3.15-0.1,4.92-0.1,1.46,0,4.05-.41,4.52.61,0.39,0.85-.75,3-1.1,3.57a61.88,61.88,0,0,1-4.12,5.61c-0.58.78-1.78,2-1.71,3.27,0.05,0.94,1,1.67,1.71,2.35a33.12,33.12,0,0,1,3.92,4.18c0.47,0.62,1.5,2,1.4,2.76C52.66,45.81,46.88,44.24,44.94,44.84Z', 108 | }, 109 | weibo: { 110 | color: '#CD201F', 111 | name: 'weibo', 112 | path: 'M40.9756152,15.0217119 C40.5000732,15.0546301 39.9999314,15.1204666 39.5325878,15.2192213 C38.6634928,15.4085016 38.0977589,16.2643757 38.2863368,17.1284787 C38.4667163,18.0008129 39.3194143,18.5686519 40.1885094,18.3793715 C42.8613908,17.8115326 45.7720411,18.6427174 47.7316073,20.8153207 C49.6911735,22.996153 50.2077122,25.975254 49.3714112,28.5840234 C49.1008441,29.4316684 49.5763861,30.3533789 50.4208857,30.6249537 C51.2653852,30.8965286 52.1754769,30.4192153 52.4542425,29.5715703 C53.6349013,25.9011885 52.9133876,21.7699494 50.1585171,18.7085538 C48.0923641,16.4042776 45.2063093,15.1533848 42.3530505,15.0217119 C41.8775084,14.9970227 41.4511594,14.9887937 40.9756152,15.0217119 Z M27.9227762,19.8277737 C24.9957268,20.140498 20.863421,22.4365431 17.2312548,26.0822378 C13.2711279,30.0571148 11,34.2871065 11,37.9328012 C11,44.9032373 19.8713401,49.125 28.5786978,49.125 C39.9917329,49.125 47.600423,42.4261409 47.600423,37.1427636 C47.600423,33.9496952 44.9603397,32.1638816 42.549827,31.4149913 C41.9594976,31.2339421 41.5167516,31.1434164 41.8283133,30.3616079 C42.5006339,28.66632 42.6236176,27.1932286 41.8939054,26.1480742 C40.5328692,24.1894405 36.7203236,24.2881952 32.448635,26.0822378 C32.448635,26.0822378 31.1203949,26.6912261 31.4647526,25.6213825 C32.1206742,23.4981576 32.0304845,21.712342 31.0056075,20.6836478 C30.2840938,19.9512176 29.2510184,19.6878718 27.9227762,19.8277737 Z M42.0906819,20.6836478 C41.6233383,20.6589586 41.1723917,20.716566 40.7132466,20.8153207 C39.9671353,20.9716828 39.4997917,21.7781784 39.6637721,22.5270687 C39.8277525,23.275959 40.5574647,23.7450433 41.303576,23.5804521 C42.1972686,23.3911718 43.2057485,23.6380596 43.8616701,24.3704897 C44.5175916,25.1029198 44.6733735,26.0657797 44.3864073,26.9381118 C44.1486363,27.6705419 44.5093932,28.4770397 45.2391054,28.7156963 C45.9688176,28.9461239 46.780521,28.5922524 47.0100936,27.8598223 C47.584026,26.0740087 47.2396661,24.0248493 45.8950269,22.5270687 C44.886547,21.4078489 43.4845162,20.7494842 42.0906819,20.6836478 Z M29.496988,29.9665891 C35.3100922,30.1723275 39.9917329,33.0691319 40.3852858,37.0769272 C40.8362324,41.6607904 35.5970585,45.9319315 28.6442899,46.6232144 C21.6915214,47.3144973 15.6488446,44.154347 15.197898,39.5787128 C14.7469514,34.9948495 20.059916,30.7237084 27.004486,30.0324256 C27.8735831,29.950131 28.6688875,29.9336709 29.496988,29.9665891 Z M25.5614586,34.3776322 C23.183744,34.5916017 20.9372116,35.9577073 19.9205332,37.9328012 C18.5348994,40.6238672 19.9041362,43.6029661 23.0689567,44.582284 C26.340366,45.5945202 30.1857056,44.0638213 31.5303448,41.1587879 C32.8503864,38.3195909 31.1613894,35.3734082 27.9227762,34.5751416 C27.1438688,34.3776322 26.356763,34.3035667 25.5614586,34.3776322 Z M24.052839,38.7228388 C24.3316067,38.7310678 24.5857748,38.8215935 24.8399449,38.9203482 C25.8648218,39.3400561 26.1845841,40.4428158 25.5614586,41.4221338 C24.9219361,42.3932227 23.5690963,42.8623069 22.5442194,42.4096807 C21.5357395,41.9652856 21.2487754,40.8542948 21.8882979,39.9078951 C22.3638421,39.2001542 23.2247386,38.7146097 24.052839,38.7228388 Z', 113 | }, 114 | whatsapp: { 115 | color: '#25D366', 116 | name: 'whatsapp', 117 | path: 'm42.32286,33.93287c-0.5178,-0.2589 -3.04726,-1.49644 -3.52105,-1.66732c-0.4712,-0.17346 -0.81554,-0.2589 -1.15987,0.2589c-0.34175,0.51004 -1.33075,1.66474 -1.63108,2.00648c-0.30032,0.33658 -0.60064,0.36247 -1.11327,0.12945c-0.5178,-0.2589 -2.17994,-0.80259 -4.14759,-2.56312c-1.53269,-1.37217 -2.56312,-3.05503 -2.86603,-3.57283c-0.30033,-0.5178 -0.03366,-0.80259 0.22524,-1.06149c0.23301,-0.23301 0.5178,-0.59547 0.7767,-0.90616c0.25372,-0.31068 0.33657,-0.5178 0.51262,-0.85437c0.17088,-0.36246 0.08544,-0.64725 -0.04402,-0.90615c-0.12945,-0.2589 -1.15987,-2.79613 -1.58964,-3.80584c-0.41424,-1.00971 -0.84142,-0.88027 -1.15987,-0.88027c-0.29773,-0.02588 -0.64208,-0.02588 -0.98382,-0.02588c-0.34693,0 -0.90616,0.12945 -1.37736,0.62136c-0.4712,0.5178 -1.80194,1.76053 -1.80194,4.27186c0,2.51134 1.84596,4.945 2.10227,5.30747c0.2589,0.33657 3.63497,5.51458 8.80262,7.74113c1.23237,0.5178 2.1903,0.82848 2.94111,1.08738c1.23237,0.38836 2.35599,0.33657 3.24402,0.20712c0.99159,-0.15534 3.04985,-1.24272 3.47963,-2.45956c0.44013,-1.21683 0.44013,-2.22654 0.31068,-2.45955c-0.12945,-0.23301 -0.46601,-0.36247 -0.98382,-0.59548m-9.40068,12.84407l-0.02589,0c-3.05503,0 -6.08417,-0.82849 -8.72495,-2.38189l-0.62136,-0.37023l-6.47252,1.68286l1.73463,-6.29129l-0.41424,-0.64725c-1.70875,-2.71846 -2.6149,-5.85116 -2.6149,-9.07706c0,-9.39809 7.68934,-17.06155 17.15993,-17.06155c4.58253,0 8.88029,1.78642 12.11655,5.02268c3.23625,3.21036 5.02267,7.50812 5.02267,12.06476c-0.0078,9.3981 -7.69712,17.06155 -17.14699,17.06155m14.58906,-31.58846c-3.93529,-3.80584 -9.1133,-5.95471 -14.62789,-5.95471c-11.36055,0 -20.60848,9.2065 -20.61625,20.52564c0,3.61684 0.94757,7.14565 2.75211,10.26282l-2.92557,10.63564l10.93337,-2.85309c3.0136,1.63108 6.4052,2.4958 9.85634,2.49839l0.01037,0c11.36574,0 20.61884,-9.2091 20.62403,-20.53082c0,-5.48093 -2.14111,-10.64081 -6.03239,-14.51915', 118 | }, 119 | workplace: { 120 | color: '#3b3d4a', 121 | name: 'workplace', 122 | path: 'M34.019,10.292c0.21,0.017,0.423,0.034,0.636,0.049 c3.657,0.262,6.976,1.464,9.929,3.635c3.331,2.448,5.635,5.65,6.914,9.584c0.699,2.152,0.983,4.365,0.885,6.623 c-0.136,3.171-1.008,6.13-2.619,8.867c-0.442,0.75-0.908,1.492-1.495,2.141c-0.588,0.651-1.29,1.141-2.146,1.383 c-1.496,0.426-3.247-0.283-3.961-1.642c-0.26-0.494-0.442-1.028-0.654-1.548c-1.156-2.838-2.311-5.679-3.465-8.519 c-0.017-0.042-0.037-0.082-0.065-0.145c-0.101,0.245-0.192,0.472-0.284,0.698c-1.237,3.051-2.475,6.103-3.711,9.155 c-0.466,1.153-1.351,1.815-2.538,2.045c-1.391,0.267-2.577-0.154-3.496-1.247c-0.174-0.209-0.31-0.464-0.415-0.717 c-2.128-5.22-4.248-10.442-6.37-15.665c-0.012-0.029-0.021-0.059-0.036-0.104c0.054-0.003,0.103-0.006,0.15-0.006 c1.498-0.001,2.997,0,4.495-0.004c0.12-0.001,0.176,0.03,0.222,0.146c1.557,3.846,3.117,7.691,4.679,11.536 c0.018,0.046,0.039,0.091,0.067,0.159c0.273-0.673,0.536-1.32,0.797-1.968c1.064-2.627,2.137-5.25,3.19-7.883 c0.482-1.208,1.376-1.917,2.621-2.135c1.454-0.255,2.644,0.257,3.522,1.449c0.133,0.18,0.229,0.393,0.313,0.603 c1.425,3.495,2.848,6.991,4.269,10.488c0.02,0.047,0.04,0.093,0.073,0.172c0.196-0.327,0.385-0.625,0.559-0.935 c0.783-1.397,1.323-2.886,1.614-4.461c0.242-1.312,0.304-2.634,0.187-3.962c-0.242-2.721-1.16-5.192-2.792-7.38 c-2.193-2.939-5.086-4.824-8.673-5.625c-1.553-0.346-3.124-0.405-4.705-0.257c-3.162,0.298-6.036,1.366-8.585,3.258 c-3.414,2.534-5.638,5.871-6.623,10.016c-0.417,1.76-0.546,3.547-0.384,5.348c0.417,4.601,2.359,8.444,5.804,11.517 c2.325,2.073,5.037,3.393,8.094,3.989c1.617,0.317,3.247,0.395,4.889,0.242c1-0.094,1.982-0.268,2.952-0.529 c0.04-0.01,0.081-0.018,0.128-0.028c0,1.526,0,3.047,0,4.586c-0.402,0.074-0.805,0.154-1.21,0.221 c-0.861,0.14-1.728,0.231-2.601,0.258c-0.035,0.002-0.071,0.013-0.108,0.021c-0.493,0-0.983,0-1.476,0 c-0.049-0.007-0.1-0.018-0.149-0.022c-0.315-0.019-0.629-0.033-0.945-0.058c-1.362-0.105-2.702-0.346-4.017-0.716 c-3.254-0.914-6.145-2.495-8.66-4.752c-2.195-1.971-3.926-4.29-5.176-6.963c-1.152-2.466-1.822-5.057-1.993-7.774 c-0.014-0.226-0.033-0.451-0.05-0.676c0-0.502,0-1.003,0-1.504c0.008-0.049,0.02-0.099,0.022-0.148 c0.036-1.025,0.152-2.043,0.338-3.052c0.481-2.616,1.409-5.066,2.8-7.331c2.226-3.625,5.25-6.386,9.074-8.254 c2.536-1.24,5.217-1.947,8.037-2.126c0.23-0.015,0.461-0.034,0.691-0.051C33.052,10.292,33.535,10.292,34.019,10.292z', 123 | }, 124 | } 125 | 126 | export default icons 127 | -------------------------------------------------------------------------------- /src/hocs/createShareButton.tsx: -------------------------------------------------------------------------------- 1 | import React, { Ref, forwardRef } from 'react' 2 | 3 | import SocialShareButton, { 4 | Props as ShareButtonProps, 5 | } from '../components/SocialShareButton' 6 | 7 | function createShareButton< 8 | OptionProps extends Record, 9 | LinkOptions = OptionProps, 10 | >( 11 | networkName: string, 12 | link: (url: string, options: LinkOptions) => string, 13 | optsMap: (props: OptionProps) => LinkOptions, 14 | defaultProps: Partial & OptionProps>, 15 | ) { 16 | type Props = Omit< 17 | ShareButtonProps, 18 | 'forwardedRef' | 'networkName' | 'networkLink' | 'opts' 19 | > & 20 | OptionProps 21 | 22 | function CreatedButton(props: Props, ref: Ref) { 23 | const opts: any = optsMap(props) 24 | const passedProps: any = { ...props } 25 | 26 | const optsKeys = Object.keys(opts) 27 | optsKeys.forEach((key) => { 28 | delete passedProps[key] 29 | }) 30 | 31 | return ( 32 | 33 | {...defaultProps} 34 | {...passedProps} 35 | forwardedRef={ref} 36 | networkName={networkName} 37 | networkLink={link} 38 | opts={optsMap(props)} 39 | /> 40 | ) 41 | } 42 | 43 | CreatedButton.displayName = `ShareButton-${networkName}` 44 | 45 | return forwardRef(CreatedButton) 46 | } 47 | 48 | export default createShareButton 49 | -------------------------------------------------------------------------------- /src/hocs/createShareCount.tsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import { SocialMediaShareCountProps, StateTypes } from '../types' 3 | 4 | const defaultChildren = (shareCount: number) => shareCount 5 | 6 | class SocialMediaShareCount extends Component< 7 | SocialMediaShareCountProps, 8 | StateTypes 9 | > { 10 | _isMounted = false 11 | 12 | constructor(props: SocialMediaShareCountProps) { 13 | super(props) 14 | this.state = { count: 0, isLoading: false } 15 | } 16 | 17 | componentDidMount() { 18 | this._isMounted = true 19 | this.updateCount(this.props.url, this.props.appId, this.props.appSecret) 20 | } 21 | 22 | componentDidUpdate(prevProps: SocialMediaShareCountProps) { 23 | if (this.props.url !== prevProps.url) { 24 | this.updateCount(this.props.url, this.props.appId, this.props.appSecret) 25 | } 26 | } 27 | 28 | componentWillUnmount() { 29 | this._isMounted = false 30 | } 31 | 32 | updateCount(url: string, appId?: string, appSecret?: string) { 33 | this.setState({ 34 | isLoading: true, 35 | }) 36 | 37 | this.props.getCount( 38 | url, 39 | (count) => { 40 | if (this._isMounted) { 41 | this.setState({ 42 | count, 43 | isLoading: false, 44 | }) 45 | } 46 | }, 47 | appId, 48 | appSecret, 49 | ) 50 | } 51 | 52 | render() { 53 | const { count, isLoading } = this.state 54 | 55 | const { 56 | children = defaultChildren, 57 | // eslint-disable-next-line react/prop-types 58 | className, 59 | // eslint-disable-next-line @typescript-eslint/no-unused-vars 60 | getCount: _, 61 | // ...rest 62 | } = this.props 63 | 64 | return ( 65 | 66 | {!isLoading && count !== undefined && children(count)} 67 | 68 | ) 69 | } 70 | } 71 | 72 | export default function createShareCount( 73 | getCount: SocialMediaShareCountProps['getCount'], 74 | ) { 75 | const ShareCount = (props: Omit) => ( 76 | 77 | ) 78 | 79 | ShareCount.displayName = `ShareCount(${getCount.name})` 80 | 81 | return ShareCount 82 | } 83 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | // Buttons 2 | export { default as FacebookShare } from './components/buttons/FacebookShareButton' 3 | export { default as LineShare } from './components/buttons/LineShareButton' 4 | export { default as PinterestShare } from './components/buttons/PinterestShareButton' 5 | export { default as RedditShare } from './components/buttons/RedditShareButton' 6 | export { default as TelegramShare } from './components/buttons/TelegramShareButton' 7 | export { default as TumblrShare } from './components/buttons/TumblrShareButton' 8 | export { default as TwitterShare } from './components/buttons/TwitterShareButton' 9 | export { default as ViberShare } from './components/buttons/ViberShareButton' 10 | export { default as WeiboShare } from './components/buttons/WeiboShareButton' 11 | export { default as WhatsappShare } from './components/buttons/WhatsappShareButton' 12 | export { default as LinkedinShare } from './components/buttons/LinkedinShareButton' 13 | export { default as VKShareShare } from './components/buttons/VKShareButton' 14 | export { default as MailruShare } from './components/buttons/MailruShareButton' 15 | export { default as LiveJournalShare } from './components/buttons/LivejournalShareButton' 16 | export { default as WorkplaceShare } from './components/buttons/WorkplaceShareButton' 17 | export { default as PocketShare } from './components/buttons/PocketShareButton' 18 | export { default as InstapaperShare } from './components/buttons/InstapaperShareButton' 19 | export { default as HatenaShare } from './components/buttons/HatenaShareButton' 20 | export { default as FacebookMessengerShare } from './components/buttons/FacebookMessengerShareButton' 21 | export { default as EmailShare } from './components/buttons/EmailShareButton' 22 | export { default as GabShare } from './components/buttons/GabShareButton' 23 | 24 | // Counts 25 | export { default as OKCount } from './components/counts/OKShareCount' 26 | export { default as PinterestCount } from './components/counts/PinterestShareCount' 27 | export { default as TumblrCount } from './components/counts/TumblrShareCount' 28 | export { default as VKCount } from './components/counts/VKShareCount' 29 | export { default as HatenaCount } from './components/counts/HatenaShareCount' 30 | export { default as FacebookCount } from './components/counts/FacebookShareCount' 31 | export { default as RedditCount } from './components/counts/RedditShareCount' 32 | -------------------------------------------------------------------------------- /src/types.d.ts: -------------------------------------------------------------------------------- 1 | //=============LINK TYPES 2 | 3 | import { CSSProperties, Ref } from 'react' 4 | 5 | // Email Link: TYPE 6 | export type EmailLinkParams = { 7 | body?: string 8 | separator?: string 9 | subject?: string 10 | } 11 | // Facebook Link: TYPE 12 | export type FacebookLinkParams = { quote?: string; hashtag?: string } 13 | // Facebook Messenger Link: TYPE 14 | export type FacebookMessengerLinkParams = { 15 | appId: string 16 | redirectUri?: string 17 | to?: string 18 | } 19 | // Gab Link: TYPE 20 | export type GapLinkParams = { title?: string } 21 | // Hatena Link: TYPE 22 | export type HatenaLinkParams = { title?: string } 23 | // InstaPaper Link: TYPE 24 | export type InstaPaperLinkParams = { title?: string; description?: string } 25 | // Line Link: TYPE 26 | export type LineLinkParams = { title?: string } 27 | // Linkedin Link: TYPE 28 | export type LinkedInLinkParams = { 29 | title?: string 30 | summary?: string 31 | source?: string 32 | } 33 | // LiveJournal Link: TYPE 34 | export type LiveJournalLinkParams = { title?: string; description?: string } 35 | // Mailru Link: TYPE 36 | export type MailruLinkParams = { 37 | title?: string 38 | description?: string 39 | imageUrl?: string 40 | } 41 | // Pinterest Link: TYPE 42 | export type PinterestLinkParams = { media: string; description?: string } 43 | // Pocket Link: TYPE 44 | export type PocketLinkParams = { title?: string } 45 | // Reddit Link: TYPE 46 | export type RedditLinkParams = { title?: string } 47 | // Telegram Link: TYPE 48 | export type TelegramLinkParams = { title?: string } 49 | // Tumblr Link: TYPE 50 | export type TumblrLinkParams = { 51 | title?: string 52 | caption?: string 53 | tags?: string 54 | posttype?: 'link' | string 55 | } 56 | // Twitter Link: TYPE 57 | export type TwitterLinkParams = { 58 | title?: string 59 | via?: string 60 | hashtags?: string[] 61 | related?: string[] 62 | } 63 | // Viber Link: TYPE 64 | export type ViberLinkParams = { title?: string; separator?: string } 65 | // VK Link: TYPE 66 | export type VKShareLinkParams = { 67 | title?: string 68 | image?: string 69 | noParse?: boolean 70 | noVkLinks?: boolean 71 | } 72 | // Weibo Link: TYPE 73 | export type WeiboShareLinkParams = { title?: string; image?: string } 74 | // WhatsApp Link: TYPE 75 | export type WhatsAppLinkParams = { title?: string; separator?: string } 76 | // Workplace Link: TYPE 77 | export type WorkplaceLinkParams = { 78 | quote?: string 79 | hashtag?: string 80 | } 81 | 82 | //======= HOC TYPES 83 | export type SocialMediaShareCountProps = 84 | React.HTMLAttributes & { 85 | children?: (shareCount: number) => React.ReactNode 86 | getCount: ( 87 | url: string, 88 | callback: (shareCount?: number) => void, 89 | appId?: string, 90 | appSecret?: string, 91 | ) => void 92 | url: string 93 | appId?: string 94 | appSecret?: string 95 | } 96 | 97 | export type StateTypes = { 98 | count?: number 99 | isLoading: boolean 100 | } 101 | 102 | //======= ICON TYPES 103 | export type SocialIcon = { 104 | color: string 105 | name: string 106 | path: string 107 | } 108 | 109 | export type SocialIcons = { 110 | [key: string]: SocialIcon 111 | } 112 | 113 | //======= SOCIAL SHARE TYPES 114 | 115 | export type NetworkLink = ( 116 | url: string, 117 | options: LinkOptions, 118 | ) => string 119 | 120 | export type WindowPosition = 'windowCenter' | 'screenCenter' 121 | 122 | export type CustomProps = { 123 | buttonTitle?: string 124 | /** 125 | * Disables click action and adds `disabled` class 126 | */ 127 | disabled?: boolean 128 | /** 129 | * Style when button is disabled 130 | * @default { opacity: 0.6 } 131 | */ 132 | disabledStyle?: React.CSSProperties 133 | forwardedRef?: Ref 134 | networkName: string 135 | networkLink: NetworkLink 136 | onClick?: (event: React.MouseEvent, link: string) => void 137 | openShareDialogOnClick?: boolean 138 | opts: LinkOptions 139 | /** 140 | * URL of the shared page 141 | */ 142 | url: string 143 | style?: React.CSSProperties 144 | windowWidth?: number 145 | windowHeight?: number 146 | windowPosition?: WindowPosition 147 | /** 148 | * Takes a function that returns a Promise to be fulfilled before calling 149 | * `onClick`. If you do not return promise, `onClick` is called immediately. 150 | */ 151 | beforeOnClick?: () => Promise | void 152 | /** 153 | * Takes a function to be called after closing share dialog. 154 | */ 155 | onShareWindowClose?: () => void 156 | resetButtonStyle?: boolean 157 | blankTarget?: boolean 158 | size?: number 159 | round?: boolean 160 | borderRadius?: number 161 | iconStyle?: CSSProperties 162 | iconFillColor?: string 163 | bgColor?: string 164 | } 165 | 166 | export type IconProps = { 167 | network: string 168 | color?: React.CSSProperties['color'] 169 | background?: React.CSSProperties['backgroundColor'] 170 | round?: boolean 171 | size?: number 172 | borderRadius?: React.CSSProperties['borderRadius'] 173 | } 174 | -------------------------------------------------------------------------------- /src/utils/button.ts: -------------------------------------------------------------------------------- 1 | import transformObjectToParams, { isMobileOrTablet } from '.' 2 | import { 3 | EmailLinkParams, 4 | FacebookLinkParams, 5 | FacebookMessengerLinkParams, 6 | GapLinkParams, 7 | HatenaLinkParams, 8 | InstaPaperLinkParams, 9 | LineLinkParams, 10 | LinkedInLinkParams, 11 | LiveJournalLinkParams, 12 | MailruLinkParams, 13 | PinterestLinkParams, 14 | PocketLinkParams, 15 | RedditLinkParams, 16 | TelegramLinkParams, 17 | TumblrLinkParams, 18 | TwitterLinkParams, 19 | VKShareLinkParams, 20 | ViberLinkParams, 21 | WeiboShareLinkParams, 22 | WhatsAppLinkParams, 23 | WorkplaceLinkParams, 24 | } from '../types' 25 | 26 | /** 27 | * Generates a Facebook sharing link. 28 | * 29 | * @param url - The URL to be shared. 30 | * @param quote - Optional. A quote or description to be included in the shared post. 31 | * @param hashtag - Optional. A hashtag to be included in the shared post. 32 | * @returns The Facebook sharing link. 33 | */ 34 | export function facebookLink( 35 | url: string, 36 | { quote, hashtag }: FacebookLinkParams, 37 | ) { 38 | return ( 39 | 'https://www.facebook.com/sharer/sharer.php' + 40 | transformObjectToParams({ 41 | u: url, 42 | quote, 43 | hashtag, 44 | }) 45 | ) 46 | } 47 | 48 | /** 49 | * Generates a Email link for composing an email. 50 | * 51 | * @param url - The email address or addresses to send the email to. 52 | * @param subject - Optional. The subject line of the email. 53 | * @param body - Optional. The body content of the email. 54 | * @param separator - Optional. The separator to use between the body and the URL. 55 | * @returns The email link. 56 | */ 57 | export function emailLink( 58 | url: string, 59 | { subject, body, separator }: EmailLinkParams, 60 | ) { 61 | return ( 62 | 'mailto:' + 63 | transformObjectToParams({ 64 | subject, 65 | body: body ? body + separator + url : url, 66 | }) 67 | ) 68 | } 69 | 70 | /** 71 | * Generates a Facebook Messenger link for sending a message. 72 | * 73 | * @param url - The URL to be shared within the message. 74 | * @param appId - Optional. The Facebook App ID or Your app's unique identifier.. 75 | * @param redirectUri - Optional. The URL to redirect to after a person clicks a button on the dialog. 76 | * Required when using URL redirection. 77 | * @param to - Optional. A user ID of a recipient. Once the dialog comes up, the sender can 78 | * specify additional people as recipients. 79 | * @returns The Facebook Messenger link. 80 | */ 81 | export function facebookMessengerLink( 82 | url: string, 83 | { appId, redirectUri, to }: FacebookMessengerLinkParams, 84 | ) { 85 | return ( 86 | 'https://www.facebook.com/dialog/send' + 87 | transformObjectToParams({ 88 | link: url, 89 | redirect_uri: redirectUri || url, 90 | app_id: appId, 91 | to, 92 | }) 93 | ) 94 | } 95 | 96 | /** 97 | * Generates a Gab Social link for composing a post. 98 | * 99 | * @param url - The URL to be shared within the post. 100 | * @param title - The title or text of the post. 101 | * @returns The Gab Social link for composing the post. 102 | */ 103 | export function gabLink(url: string, { title }: GapLinkParams) { 104 | return ( 105 | 'https://gab.com/compose' + 106 | transformObjectToParams({ 107 | url, 108 | text: title, 109 | }) 110 | ) 111 | } 112 | 113 | /** 114 | * Generates a Hatena bookmark link for adding a bookmark. 115 | * 116 | * @param url - The URL to be bookmarked. 117 | * @param title - The title of the bookmark. 118 | * @returns The Hatena bookmark link. 119 | */ 120 | export function hatenaLink(url: string, { title }: HatenaLinkParams) { 121 | return `http://b.hatena.ne.jp/add?mode=confirm&url=${url}&title=${title}` 122 | } 123 | 124 | /** 125 | * Generates an Instapaper link for saving a page. 126 | * 127 | * @param url - The URL of the page to be saved. 128 | * @param title - The title of the page. 129 | * @param description - Optional. The description of the page. 130 | * @returns The Instapaper link for saving the page. 131 | */ 132 | export function instapaperLink( 133 | url: string, 134 | { title, description }: InstaPaperLinkParams, 135 | ) { 136 | return ( 137 | 'http://www.instapaper.com/hello2' + 138 | transformObjectToParams({ 139 | url, 140 | title, 141 | description, 142 | }) 143 | ) 144 | } 145 | 146 | /** 147 | * Generates a LINE Login link for sharing a URL. 148 | * 149 | * @param url - The URL to be shared. 150 | * @param title - The title or text of the shared content. 151 | * @returns The LINE Login link for sharing the URL. 152 | */ 153 | export function lineLink(url: string, { title }: LineLinkParams) { 154 | return ( 155 | 'https://social-plugins.line.me/lineit/share' + 156 | transformObjectToParams({ 157 | url, 158 | text: title, 159 | }) 160 | ) 161 | } 162 | 163 | /** 164 | * Generates a LinkedIn sharing link for sharing an article. 165 | * 166 | * @param url - The URL of the article to be shared. 167 | * @param title - The title of the article. 168 | * @param summary - Optional. The summary or description of the article. 169 | * @param source - Optional. The source or publication of the article. 170 | * @returns The LinkedIn sharing link for sharing the article. 171 | */ 172 | export function linkedinLink( 173 | url: string, 174 | { title, summary, source }: LinkedInLinkParams, 175 | ) { 176 | return ( 177 | // 'https://linkedin.com/shareArticle' + 178 | 'https://linkedin.com/sharing/share-offsite' + 179 | transformObjectToParams({ url, mini: 'true', title, summary, source }) 180 | ) 181 | } 182 | 183 | /** 184 | * Generates a LiveJournal update link for creating a new post. 185 | * 186 | * @param _url - This parameter is not used. 187 | * @param title - The title of the post. 188 | * @param description - The description or content of the post. 189 | * @returns The LiveJournal update link for creating a new post. 190 | */ 191 | export function liveJournalLink( 192 | _url: string, 193 | { title, description }: LiveJournalLinkParams, 194 | ) { 195 | return ( 196 | 'https://www.livejournal.com/update.bml' + 197 | transformObjectToParams({ 198 | subject: title, 199 | event: description, 200 | }) 201 | ) 202 | } 203 | 204 | /** 205 | * Generates a Mail.Ru sharing link for sharing content. 206 | * 207 | * @param url - The URL of the content to be shared. 208 | * @param title - The title of the content. 209 | * @param description - The description or summary of the content. 210 | * @param imageUrl - Optional. The URL of an image associated with the content. 211 | * @returns The Mail.Ru sharing link for sharing the content. 212 | */ 213 | export function mailruLink( 214 | url: string, 215 | { title, description, imageUrl }: MailruLinkParams, 216 | ) { 217 | return ( 218 | 'https://connect.mail.ru/share' + 219 | transformObjectToParams({ 220 | url, 221 | title, 222 | description, 223 | image_url: imageUrl, 224 | }) 225 | ) 226 | } 227 | 228 | /** 229 | * Generates a Pinterest sharing link. 230 | * 231 | * @param url - The URL to be pinned. 232 | * @param media - The media URL to be associated with the pin (optional). 233 | * @param description - The description of the pin (optional). 234 | * @returns The Pinterest sharing link. 235 | */ 236 | export function pinterestLink( 237 | url: string, 238 | { media, description }: PinterestLinkParams, 239 | ) { 240 | return ( 241 | 'https://pinterest.com/pin/create/button/' + 242 | transformObjectToParams({ 243 | url, 244 | media, 245 | description, 246 | }) 247 | ) 248 | } 249 | 250 | /** 251 | * Generates a Pocket saving link. 252 | * 253 | * @param url - The URL to be saved. 254 | * @param title - The title of the saved item (optional). 255 | * @returns The Pocket saving link. 256 | */ 257 | export function pocketLink(url: string, { title }: PocketLinkParams) { 258 | return ( 259 | 'https://getpocket.com/save' + 260 | transformObjectToParams({ 261 | url, 262 | title, 263 | }) 264 | ) 265 | } 266 | 267 | /** 268 | * Generates a Reddit submission link. 269 | * 270 | * @param url - The URL to be submitted. 271 | * @param title - The title of the submission (optional). 272 | * @returns The Reddit submission link. 273 | */ 274 | export function redditLink(url: string, { title }: RedditLinkParams) { 275 | return ( 276 | 'https://www.reddit.com/submit' + 277 | transformObjectToParams({ 278 | url, 279 | title, 280 | }) 281 | ) 282 | } 283 | 284 | /** 285 | * Generates a Telegram sharing link. 286 | * 287 | * @param url - The URL to be shared. 288 | * @param title - The title of the shared content (optional). 289 | * @returns The Telegram sharing link. 290 | */ 291 | export function telegramLink(url: string, { title }: TelegramLinkParams) { 292 | return ( 293 | 'https://telegram.me/share/' + 294 | transformObjectToParams({ 295 | url, 296 | text: title, 297 | }) 298 | ) 299 | } 300 | 301 | /** 302 | * Generates a Tumblr sharing link. 303 | * 304 | * @param url - The URL to be shared. 305 | * @param title - The title of the shared content (optional). 306 | * @param caption - The caption of the shared content (optional). 307 | * @param tags - An array of tags associated with the shared content (optional). 308 | * @param posttype - The type of post (optional). 309 | * @returns The Tumblr sharing link. 310 | */ 311 | export function tumblrLink( 312 | url: string, 313 | { title, caption, tags, posttype }: TumblrLinkParams, 314 | ) { 315 | return ( 316 | 'https://www.tumblr.com/widgets/share/tool' + 317 | transformObjectToParams({ 318 | canonicalUrl: url, 319 | title, 320 | caption, 321 | tags, 322 | posttype, 323 | }) 324 | ) 325 | } 326 | 327 | /** 328 | * Generates a Twitter sharing link. 329 | * 330 | * @param url - The URL to be shared. 331 | * @param title - The title of the shared content (optional). 332 | * @param via - The Twitter username to attribute the tweet to (optional). 333 | * @param hashtags - An array of hashtags to include in the tweet (optional). 334 | * @param related - An array of related accounts to suggest following after the tweet is sent (optional). 335 | * @returns The Twitter sharing link. 336 | */ 337 | export function twitterLink( 338 | url: string, 339 | { title, via, hashtags = [], related = [] }: TwitterLinkParams, 340 | ) { 341 | return ( 342 | 'https://twitter.com/intent/tweet' + 343 | transformObjectToParams({ 344 | url, 345 | text: title, 346 | via, 347 | hashtags: hashtags.length > 0 ? hashtags.join(',') : undefined, 348 | related: related.length > 0 ? related.join(',') : undefined, 349 | }) 350 | ) 351 | } 352 | 353 | /** 354 | * Generates a Viber sharing link. 355 | * 356 | * @param url - The URL to be shared. 357 | * @param title - The title of the shared content (optional). 358 | * @param separator - The separator between the title and URL (optional). 359 | * @returns The Viber sharing link. 360 | */ 361 | export function viberLink(url: string, { title, separator }: ViberLinkParams) { 362 | return ( 363 | 'viber://forward' + 364 | transformObjectToParams({ 365 | text: title ? title + separator + url : url, 366 | }) 367 | ) 368 | } 369 | 370 | /** 371 | * Generates a VKontakte (VK) sharing link. 372 | * 373 | * @param url - The URL to be shared. 374 | * @param title - The title of the shared content (optional). 375 | * @param image - The URL of the image to be shared (optional). 376 | * @param noParse - Specifies whether to disable VK parsing of the shared content (optional). 377 | * @param noVkLinks - Specifies whether to disable VK-specific links in the shared content (optional). 378 | * @returns The VKontakte sharing link. 379 | */ 380 | export function vkLink( 381 | url: string, 382 | { title, image, noParse, noVkLinks }: VKShareLinkParams, 383 | ) { 384 | return ( 385 | 'https://vk.com/share.php' + 386 | transformObjectToParams({ 387 | url, 388 | title, 389 | image, 390 | noparse: noParse ? 1 : 0, 391 | no_vk_links: noVkLinks ? 1 : 0, 392 | }) 393 | ) 394 | } 395 | 396 | /** 397 | * Generates a Weibo sharing link. 398 | * 399 | * @param url - The URL to be shared. 400 | * @param title - The title of the shared content (optional). 401 | * @param image - The URL of the image to be shared (optional). 402 | * @returns The Weibo sharing link. 403 | */ 404 | export function weiboLink(url: string, { title, image }: WeiboShareLinkParams) { 405 | return ( 406 | 'http://service.weibo.com/share/share.php' + 407 | transformObjectToParams({ 408 | url, 409 | title, 410 | pic: image, 411 | }) 412 | ) 413 | } 414 | 415 | /** 416 | * Generates a WhatsApp sharing link. 417 | * 418 | * @param url - The URL to be shared. 419 | * @param title - The title of the shared content (optional). 420 | * @param separator - The separator between the title and URL (optional). 421 | * @returns The WhatsApp sharing link. 422 | */ 423 | export function whatsappLink( 424 | url: string, 425 | { title, separator }: WhatsAppLinkParams, 426 | ) { 427 | return ( 428 | 'https://' + 429 | (isMobileOrTablet() ? 'api' : 'web') + 430 | '.whatsapp.com/send' + 431 | transformObjectToParams({ 432 | text: title ? title + separator + url : url, 433 | }) 434 | ) 435 | } 436 | 437 | /** 438 | * Generates a Workplace sharing link. 439 | * 440 | * @param url - The URL to be shared. 441 | * @param quote - The quote or message to include in the shared content (optional). 442 | * @param hashtag - The hashtag to include in the shared content (optional). 443 | * @returns The Workplace sharing link. 444 | */ 445 | export function workplaceLink( 446 | url: string, 447 | { quote, hashtag }: WorkplaceLinkParams, 448 | ) { 449 | return ( 450 | 'https://work.facebook.com/sharer.php' + 451 | transformObjectToParams({ 452 | u: url, 453 | quote, 454 | hashtag, 455 | }) 456 | ) 457 | } 458 | -------------------------------------------------------------------------------- /src/utils/count.ts: -------------------------------------------------------------------------------- 1 | import jsonp from 'jsonp' 2 | import objectToGetParams from '.' 3 | 4 | declare global { 5 | interface Window { 6 | OK: { 7 | Share: { 8 | count: (index: number, _count: number) => void 9 | } 10 | callbacks: ((count?: number) => void)[] 11 | } 12 | ODKL: { 13 | updateCount: (index: string, count: string) => void 14 | } 15 | } 16 | interface Window { 17 | VK: { 18 | Share?: { 19 | count: (index: number, count: number) => void 20 | } 21 | callbacks?: ((count?: number) => void)[] 22 | } 23 | } 24 | } 25 | 26 | /** 27 | * Retrieves the share count of a Facebook post or URL. 28 | * 29 | * @param shareUrl - The URL or post to retrieve the share count for. 30 | * @param callback - The callback function to be called with the share count. 31 | * @param appId - The Facebook app ID (optional). 32 | * @param appSecret - The Facebook app secret (optional). 33 | */ 34 | export function getFacebookShareCount( 35 | shareUrl: string, 36 | callback: (shareCount?: number) => void, 37 | appId?: string, 38 | appSecret?: string, 39 | ) { 40 | const endpoint = `https://graph.facebook.com/?id=${shareUrl}&fields=engagement&access_token=${appId}|${appSecret}` 41 | 42 | jsonp(endpoint, (err: any, data: any) => { 43 | callback( 44 | !err && data && data.engagement ? data.engagement.share_count : undefined, 45 | ) 46 | }) 47 | } 48 | 49 | /** 50 | * Retrieves the share count of a URL on Hatena Bookmark. 51 | * 52 | * @param shareUrl - The URL to retrieve the share count for. 53 | * @param callback - The callback function to be called with the share count. 54 | */ 55 | export function getHatenaShareCount( 56 | shareUrl: string, 57 | callback: (shareCount?: number) => void, 58 | ) { 59 | const url = 'https://bookmark.hatenaapis.com/count/entry' 60 | 61 | jsonp( 62 | url + 63 | objectToGetParams({ 64 | url: shareUrl, 65 | }), 66 | (err, data) => { 67 | callback(!err ? data : undefined) 68 | }, 69 | ) 70 | } 71 | 72 | /** 73 | * Retrieves the share count of a URL on OK.ru (Odnoklassniki). 74 | * 75 | * @param shareUrl - The URL to retrieve the share count for. 76 | * @param callback - The callback function to be called with the share count. 77 | */ 78 | export function getOKShareCount( 79 | shareUrl: string, 80 | callback: (shareCount?: number) => void, 81 | ) { 82 | if (!window.OK) { 83 | window.OK = { 84 | Share: { 85 | count: function count(index, _count) { 86 | window.OK.callbacks[index](_count) 87 | }, 88 | }, 89 | callbacks: [], 90 | } 91 | } 92 | 93 | const url = 'https://connect.ok.ru/dk' 94 | const index = window.OK.callbacks.length 95 | 96 | window.ODKL = { 97 | updateCount(index, count) { 98 | const callbackIndex = 99 | index === '' ? 0 : parseInt(index.replace('react-share-', ''), 10) 100 | window.OK.callbacks[callbackIndex]( 101 | count === '' ? undefined : parseInt(count, 10), 102 | ) 103 | }, 104 | } 105 | window.OK.callbacks.push(callback) 106 | 107 | return jsonp( 108 | url + 109 | objectToGetParams({ 110 | 'st.cmd': 'extLike', 111 | uid: `react-share-${index}`, 112 | ref: shareUrl, 113 | }), 114 | ) 115 | } 116 | 117 | /** 118 | * Retrieves the share count of a URL on Pinterest. 119 | * 120 | * @param shareUrl - The URL to retrieve the share count for. 121 | * @param callback - The callback function to be called with the share count. 122 | */ 123 | export function getPinterestShareCount( 124 | shareUrl: string, 125 | callback: (shareCount?: number) => void, 126 | ) { 127 | const url = 'https://api.pinterest.com/v1/urls/count.json' 128 | 129 | jsonp( 130 | url + 131 | objectToGetParams({ 132 | url: shareUrl, 133 | }), 134 | (err, data) => { 135 | callback(!err && data ? data.count : undefined) 136 | }, 137 | ) 138 | } 139 | 140 | /** 141 | * Retrieves the share count of a URL on Reddit. 142 | * 143 | * @param shareUrl - The URL to retrieve the share count for. 144 | * @param callback - The callback function to be called with the share count. 145 | */ 146 | export function getRedditShareCount( 147 | shareUrl: string, 148 | callback: (shareCount?: number) => void, 149 | ) { 150 | const endpoint = `https://www.reddit.com/api/info.json?limit=1&url=${shareUrl}` 151 | 152 | jsonp(endpoint, { param: 'jsonp' }, (err, response) => { 153 | callback( 154 | !err && 155 | response && 156 | response.data && 157 | response.data.children.length > 0 && 158 | response.data.children[0].data.score 159 | ? response.data.children[0].data.score 160 | : undefined, 161 | ) 162 | }) 163 | } 164 | 165 | /** 166 | * Retrieves the share count of a URL on Tumblr. 167 | * 168 | * @param shareUrl - The URL to retrieve the share count for. 169 | * @param callback - The callback function to be called with the share count. 170 | */ 171 | export function getTumblrShareCount( 172 | shareUrl: string, 173 | callback: (shareCount?: number) => void, 174 | ) { 175 | const endpoint = 'https://api.tumblr.com/v2/share/stats' 176 | 177 | return jsonp( 178 | endpoint + 179 | objectToGetParams({ 180 | url: shareUrl, 181 | }), 182 | (err, data) => { 183 | callback( 184 | !err && data && data.response ? data.response.note_count : undefined, 185 | ) 186 | }, 187 | ) 188 | } 189 | 190 | /** 191 | * Retrieves the share count of a URL on VK.com (VKontakte). 192 | * 193 | * @param shareUrl - The URL to retrieve the share count for. 194 | * @param callback - The callback function to be called with the share count. 195 | */ 196 | export function getVKShareCount( 197 | shareUrl: string, 198 | callback: (shareCount?: number) => void, 199 | ) { 200 | if (!window.VK) { 201 | window.VK = {} 202 | } 203 | window.VK.Share = { 204 | count: (index, count) => window.VK.callbacks![index](count), 205 | } 206 | window.VK.callbacks = [] 207 | 208 | const url = 'https://vk.com/share.php' 209 | const index = window.VK.callbacks.length 210 | 211 | window.VK.callbacks.push(callback) 212 | 213 | return jsonp( 214 | url + 215 | objectToGetParams({ 216 | act: 'count', 217 | index, 218 | url: shareUrl, 219 | }), 220 | ) 221 | } 222 | -------------------------------------------------------------------------------- /src/utils/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Checks if the user's device is a mobile or tablet device. 3 | * 4 | * @returns A boolean indicating whether the device is a mobile or tablet device. 5 | */ 6 | export function isMobileOrTablet() { 7 | return /(android|iphone|ipad|mobile)/i.test(navigator.userAgent) 8 | } 9 | 10 | /** 11 | * Opens a custom window or dialog with specified dimensions and configuration options. 12 | * 13 | * @param url - The URL to open in the window or dialog. 14 | * @param options - The options for configuring the window or dialog. 15 | * @param blankTarget - Specifies whether to open the URL in a new blank tab or window. 16 | * @param onClose - The callback function to be called when the window or dialog is closed. 17 | * @returns The opened window or dialog. 18 | */ 19 | export function CustomWindow( 20 | url: string, 21 | { 22 | height, 23 | width, 24 | ...configRest 25 | }: { height: number; width: number; [key: string]: any }, 26 | blankTarget?: boolean, 27 | onClose?: (dialog: Window | null) => void, 28 | ) { 29 | const config: { [key: string]: string | number } = { 30 | height, 31 | width, 32 | location: 'no', 33 | toolbar: 'no', 34 | status: 'no', 35 | directories: 'no', 36 | menubar: 'no', 37 | scrollbars: 'yes', 38 | resizable: 'no', 39 | centerscreen: 'yes', 40 | chrome: 'yes', 41 | ...configRest, 42 | } 43 | 44 | let dialog: Window 45 | 46 | if (blankTarget) { 47 | dialog = window.open(url, '_blank') 48 | } else { 49 | dialog = window.open( 50 | url, 51 | '', 52 | Object.keys(config) 53 | .map((key) => `${key}=${config[key]}`) 54 | .join(', '), 55 | ) 56 | } 57 | 58 | if (onClose) { 59 | const interval = window.setInterval(() => { 60 | try { 61 | if (dialog === null || dialog.closed) { 62 | window.clearInterval(interval) 63 | onClose(dialog) 64 | } 65 | } catch (e) { 66 | /* eslint-disable no-console */ 67 | console.error(e) 68 | /* eslint-enable no-console */ 69 | } 70 | }, 1000) 71 | } 72 | 73 | return dialog 74 | } 75 | 76 | /** 77 | * Calculates the position (left and top) of a window or dialog to center it on the user's screen. 78 | * 79 | * @param width - The width of the window or dialog. 80 | * @param height - The height of the window or dialog. 81 | * @returns An object containing the left and top positions to center the window or dialog. 82 | */ 83 | export const getPositionOnWindowCenter = (width: number, height: number) => ({ 84 | left: 85 | window.outerWidth / 2 + 86 | (window.screenX || window.screenLeft || 0) - 87 | width / 2, 88 | top: 89 | window.outerHeight / 2 + 90 | (window.screenY || window.screenTop || 0) - 91 | height / 2, 92 | }) 93 | 94 | /** 95 | * Calculates the position (left and top) of an element on the screen to center it horizontally and vertically. 96 | * 97 | * @param width - The width of the element. 98 | * @param height - The height of the element. 99 | * @returns An object containing the left and top positions to center the element on the screen. 100 | */ 101 | export const getPositionOnScreenCenter = (width: number, height: number) => ({ 102 | top: (window.screen.height - height) / 2, 103 | left: (window.screen.width - width) / 2, 104 | }) 105 | 106 | /** 107 | * Checks if an object is a Promise. 108 | * 109 | * @param obj - The object to check. 110 | * @returns A boolean indicating whether the object is a Promise. 111 | */ 112 | export const isPromise = (obj: any | Promise) => 113 | !!obj && 114 | (typeof obj === 'object' || typeof obj === 'function') && 115 | typeof obj.then === 'function' 116 | 117 | /** 118 | * Transforms an object into a query string format with URL parameters. 119 | * 120 | * @param object - The object to transform into parameters. 121 | * @returns The query string with URL parameters. 122 | */ 123 | export default function transformObjectToParams(object: { 124 | [key: string]: string | number | undefined | null 125 | }) { 126 | const params = Object.entries(object) 127 | .filter(([, value]) => value !== undefined && value !== null) 128 | .map( 129 | ([key, value]) => 130 | `${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`, 131 | ) 132 | 133 | return params.length > 0 ? `?${params.join('&')}` : '' 134 | } 135 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "es2015", 5 | "lib": ["es2017", "es7", "es6", "es5", "dom"], 6 | "allowJs": false, 7 | "jsx": "react", 8 | "declaration": true, 9 | "sourceMap": true, 10 | "outDir": "./dist", 11 | "rootDir": "src", 12 | "noEmit": true, 13 | "strict": true, 14 | "strictNullChecks": true, 15 | "noUnusedLocals": true, 16 | "noUnusedParameters": true, 17 | "noImplicitReturns": true, 18 | "noFallthroughCasesInSwitch": true, 19 | "moduleResolution": "node", 20 | "allowSyntheticDefaultImports": true, 21 | "esModuleInterop": true, 22 | }, 23 | "exclude": [ 24 | "node_modules", 25 | "dist", 26 | ] 27 | } --------------------------------------------------------------------------------