diff --git a/docs/.vuepress/config.ts b/docs/.vuepress/config.ts index 9c6c515..76825c8 100644 --- a/docs/.vuepress/config.ts +++ b/docs/.vuepress/config.ts @@ -5,25 +5,9 @@ import { defineUserConfig } from 'vuepress' import { socialSharePlugin } from 'vuepress-plugin-social-share' import { version } from '../../package.json' import type { NavbarLinkOptions } from '@vuepress/theme-default' -import type { SocialShareNetwork } from 'vuepress-plugin-social-share' const packageName = 'vuepress-plugin-social-share' -const extendsNetworks: Record = { - pinterest: { - sharer: 'https://pinterest.com/pin/create/button/?url=@url&media=@media&description=@title', - type: 'popup', - icon: '/pinterest.png', - }, - linkedin: { - sharer: - 'https://www.linkedin.com/shareArticle?mini=true&url=@url&title=@title&summary=@description', - type: 'popup', - color: '#1786b1', - icon: '', - }, -} - const VERSIONS: NavbarLinkOptions[] = [ { text: `v${version} (current)`, link: '/' }, { text: `Release Notes`, link: `https://github.com/ntnyq/${packageName}/releases` }, @@ -80,12 +64,34 @@ export default defineUserConfig({ theme: 'one-dark-pro', }), socialSharePlugin({ - networks: ['qq', 'twitter', 'weibo', 'email', 'linkedin', 'pinterest', 'wechat'], + networks: [ + 'qq', + 'twitter', + 'weibo', + 'email', + 'wechat', + { + name: 'pinterest', + type: 'popup', + icon: '/pinterest.png', + default: true, + sharer: + 'https://pinterest.com/pin/create/button/?url=@url&media=@media&description=@title', + }, + { + name: 'linkedin', + type: 'popup', + color: '#1786b1', + default: true, + sharer: + 'https://www.linkedin.com/shareArticle?mini=true&url=@url&title=@title&summary=@description', + icon: '', + }, + ], twitterUser: 'ntnyq', fallbackImage: '/hero.png', useCustomStyle: false, hideWhenPrint: true, - extendsNetworks, }), ], }) diff --git a/docs/guide/README.md b/docs/guide/README.md index fa18b97..abec886 100644 --- a/docs/guide/README.md +++ b/docs/guide/README.md @@ -99,26 +99,24 @@ export default defineUserConfig({ ### networks -- **type:** `(string | SocialShareNetworkWithName)[]` +- **type:** `(string | SocialShareNetworkWithName | OverrideSocialShareNetworkWithName)[]` - **default** `['twitter', 'facebook', 'reddit']` ```ts +type ThemeableValue = T | { light: T; dark: T } +type OverrideSocialShareNetworkWithName = Partial & { + name: BuiltInNetworkNames +} type SocialShareNetworkWithName = { + /** + * Sharer name + */ + name: string + /** * Sharer icon */ - icon: - | string - | { - /** - * icon for dark mode - */ - dark: string - /** - * icon for light mode - */ - light: string - } + icon: ThemeableValue /** * Sharer type @@ -128,18 +126,7 @@ type SocialShareNetworkWithName = { /** * Sharer icon color */ - color?: - | string - | { - /** - * color for dark mode - */ - dark: string - /** - * color for light mode - */ - light: string - } + color?: ThemeableValue /** * Sharer URL diff --git a/src/client/components/SocialShare.ts b/src/client/components/SocialShare.ts index e105f3a..0b06147 100644 --- a/src/client/components/SocialShare.ts +++ b/src/client/components/SocialShare.ts @@ -187,17 +187,22 @@ export const SocialShare = defineComponent({ const body = document.body const socialShareEl = document.querySelector('#__VUEPRESS_SOCIAL_SHARE__') const socialShareOverlay = document.createElement('div') + socialShareOverlay.id = '__VUEPRESS_SOCIAL_SHARE__' socialShareOverlay.classList.add('social-share-overlay') + if (socialShareEl && socialShareEl.parentNode) { socialShareEl.remove() } + try { const QRCode = await import('qrcode') const dataURL = await QRCode.toDataURL(url.value, qrcodeRenderOptions.value) + socialShareOverlay.innerHTML = `` body.append(socialShareOverlay) socialShareOverlay.classList.add('show') + socialShareOverlay.addEventListener('click', evt => { socialShareOverlay.classList.remove('show') socialShareOverlay.remove() @@ -233,18 +238,16 @@ export const SocialShare = defineComponent({ const onShare = (name: string) => { const network = options.networksData.find(item => item.name === name)! const shareURL = createShareURL(name, network) + switch (network.type) { case 'popup': - openSharer(shareURL) - break + return openSharer(shareURL) case 'qrcode': - showQRCode() - break + return showQRCode() case 'direct': - openWindow(shareURL) - break + return openWindow(shareURL) default: - break + return openSharer(shareURL) } } const renderNetworkList = (networks: SocialShareNetworkWithName[]) => diff --git a/src/client/components/SocialShareNetwork.ts b/src/client/components/SocialShareNetwork.ts index 18fe9e7..d8b1dc1 100644 --- a/src/client/components/SocialShareNetwork.ts +++ b/src/client/components/SocialShareNetwork.ts @@ -20,7 +20,9 @@ export const SocialShareNetwork = defineComponent({ required: true, validator: (network: SocialShareNetworkWithName) => { if (!network.icon) return false - if (['popup'].includes(network.type)) return Boolean(network.sharer) + if (network.type !== 'qrcode') { + return Boolean(network.sharer) + } return true }, }, diff --git a/src/node/helpers.ts b/src/node/helpers.ts index 8c08b5a..863fabb 100644 --- a/src/node/helpers.ts +++ b/src/node/helpers.ts @@ -1,7 +1,6 @@ import { Logger } from '@vuepress/helper' import deepmerge from 'deepmerge' -import { isString } from '../shared/index.js' -import { BUILT_IN_NETWORKS, PLUGIN_NAME } from './constants.js' +import { BUILT_IN_NETWORKS, isString, PLUGIN_NAME } from '../shared/index.js' import type { SocialShareNetworkWithName, SocialSharePluginOptions } from '../shared/index.js' export const logger = new Logger(PLUGIN_NAME) @@ -31,7 +30,7 @@ export function resolveNetworksData( if (mergedNetworkNames.has(network.name)) { mergedNetworks[network.name] = deepmerge(mergedNetworks[network.name], network) } else { - mergedNetworks[network.name] = network + mergedNetworks[network.name] = network as SocialShareNetworkWithName } } } diff --git a/src/node/socialSharePlugin.ts b/src/node/socialSharePlugin.ts index 2c9e327..3541760 100644 --- a/src/node/socialSharePlugin.ts +++ b/src/node/socialSharePlugin.ts @@ -1,6 +1,6 @@ import { addViteSsrNoExternal } from '@vuepress/helper' import { getDirname, path } from 'vuepress/utils' -import { PLUGIN_NAME } from './constants.js' +import { PLUGIN_NAME } from '../shared/index.js' import { logger, resolveNetworksData } from './helpers.js' import type { PluginFunction } from 'vuepress/core' import type { diff --git a/src/node/constants.ts b/src/shared/constants.ts similarity index 99% rename from src/node/constants.ts rename to src/shared/constants.ts index 2f54acc..550df50 100644 --- a/src/node/constants.ts +++ b/src/shared/constants.ts @@ -1,4 +1,4 @@ -import type { SocialShareNetwork } from '../shared/index.js' +import type { SocialShareNetwork } from './network.js' export const PLUGIN_NAME = 'vuepress-plugin-social-share' diff --git a/src/shared/index.ts b/src/shared/index.ts index 4a9b161..fa2f39f 100644 --- a/src/shared/index.ts +++ b/src/shared/index.ts @@ -1,3 +1,4 @@ export * from './utils.js' export * from './plugin.js' export * from './network.js' +export * from './constants.js' diff --git a/src/shared/network.ts b/src/shared/network.ts index a333348..8bac7e3 100644 --- a/src/shared/network.ts +++ b/src/shared/network.ts @@ -1,39 +1,9 @@ -/** - * network color - */ -export type SocialShareColor = - | string - | { - /** - * color for dark mode - */ - dark: string - /** - * color for light mode - */ - light: string - } - -/** - * network type - */ -export type SocialShareType = 'direct' | 'popup' | 'qrcode' +import type { BuiltInNetworkNames } from './constants.js' /** - * network icon + * Themeable value */ -export type SocilaShareIcon = - | string - | { - /** - * icon for dark mode - */ - dark: string - /** - * icon for light mode - */ - light: string - } +export type ThemeableValue = T | { light: T; dark: T } /** * Social share network @@ -42,17 +12,17 @@ export interface SocialShareNetwork { /** * Sharer icon */ - icon: SocilaShareIcon + icon: ThemeableValue /** * Sharer type */ - type: SocialShareType + type: 'direct' | 'popup' | 'qrcode' /** * Sharer icon color */ - color?: SocialShareColor + color?: ThemeableValue /** * Sharer URL @@ -79,3 +49,13 @@ export type SocialShareNetworkWithName = SocialShareNetwork & { */ name: string } + +/** + * Override social share network with name + */ +export type OverrideSocialShareNetworkWithName = Partial & { + /** + * Built-in share name + */ + name: BuiltInNetworkNames +} diff --git a/src/shared/plugin.ts b/src/shared/plugin.ts index 006ae10..b738915 100644 --- a/src/shared/plugin.ts +++ b/src/shared/plugin.ts @@ -1,5 +1,9 @@ import type { QRCodeToDataURLOptions } from 'qrcode' -import type { SocialShareNetwork, SocialShareNetworkWithName } from './network' +import type { + OverrideSocialShareNetworkWithName, + SocialShareNetwork, + SocialShareNetworkWithName, +} from './network.js' /** * @deprecated use `Record` instead @@ -71,7 +75,7 @@ export interface SocialSharePluginOptions { * * @default ['twitter', 'facebook', 'reddit'] */ - networks?: (string | SocialShareNetworkWithName)[] + networks?: (string | SocialShareNetworkWithName | OverrideSocialShareNetworkWithName)[] /** * Twitter profile username