-
+
-
+
{{ $t('modal.footer.navigateText') }}
-
+
{{ $t('modal.footer.selectText') }}
diff --git a/src/client/theme-default/components/VPNavBarSearchButton.vue b/src/client/theme-default/components/VPNavBarSearchButton.vue
index 2c943363..d72c9932 100644
--- a/src/client/theme-default/components/VPNavBarSearchButton.vue
+++ b/src/client/theme-default/components/VPNavBarSearchButton.vue
@@ -1,6 +1,7 @@
@@ -57,7 +35,7 @@ const svg = computed(() => {
+import VPIcon from '../VPSVGSpriteIcon.vue';
+
+
+
+
+
diff --git a/src/client/theme-default/components/search-icons/VPLocalSearchBackIcon.vue b/src/client/theme-default/components/search-icons/VPLocalSearchBackIcon.vue
new file mode 100644
index 00000000..a91a8ad3
--- /dev/null
+++ b/src/client/theme-default/components/search-icons/VPLocalSearchBackIcon.vue
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/src/client/theme-default/components/search-icons/VPLocalSearchClearIcon.vue b/src/client/theme-default/components/search-icons/VPLocalSearchClearIcon.vue
new file mode 100644
index 00000000..f14f148a
--- /dev/null
+++ b/src/client/theme-default/components/search-icons/VPLocalSearchClearIcon.vue
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/src/client/theme-default/components/search-icons/VPLocalSearchIcon.vue b/src/client/theme-default/components/search-icons/VPLocalSearchIcon.vue
new file mode 100644
index 00000000..679b80f5
--- /dev/null
+++ b/src/client/theme-default/components/search-icons/VPLocalSearchIcon.vue
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/src/client/theme-default/components/search-icons/VPLocalSearchNavDownIcon.vue b/src/client/theme-default/components/search-icons/VPLocalSearchNavDownIcon.vue
new file mode 100644
index 00000000..3c3db85f
--- /dev/null
+++ b/src/client/theme-default/components/search-icons/VPLocalSearchNavDownIcon.vue
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/src/client/theme-default/components/search-icons/VPLocalSearchNavUpIcon.vue b/src/client/theme-default/components/search-icons/VPLocalSearchNavUpIcon.vue
new file mode 100644
index 00000000..67edf4b9
--- /dev/null
+++ b/src/client/theme-default/components/search-icons/VPLocalSearchNavUpIcon.vue
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/src/client/theme-default/components/search-icons/VPLocalSearchSelectIcon.vue b/src/client/theme-default/components/search-icons/VPLocalSearchSelectIcon.vue
new file mode 100644
index 00000000..c6d8d372
--- /dev/null
+++ b/src/client/theme-default/components/search-icons/VPLocalSearchSelectIcon.vue
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/src/client/theme-default/components/search-icons/VPLocalSearchTilesIcon.vue b/src/client/theme-default/components/search-icons/VPLocalSearchTilesIcon.vue
new file mode 100644
index 00000000..c30acd1f
--- /dev/null
+++ b/src/client/theme-default/components/search-icons/VPLocalSearchTilesIcon.vue
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/src/client/theme-default/components/search-icons/VPLocalSearchToggleIcon.vue b/src/client/theme-default/components/search-icons/VPLocalSearchToggleIcon.vue
new file mode 100644
index 00000000..d5cd164d
--- /dev/null
+++ b/src/client/theme-default/components/search-icons/VPLocalSearchToggleIcon.vue
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/src/client/theme-default/support/socialIcons.ts b/src/client/theme-default/support/socialIcons.ts
new file mode 100644
index 00000000..189ccc84
--- /dev/null
+++ b/src/client/theme-default/support/socialIcons.ts
@@ -0,0 +1,2 @@
+// keep this module empty: transformed by vitepress:svg-sprite plugin
+export const socialIcons: Record = {}
diff --git a/src/node/plugin.ts b/src/node/plugin.ts
index d7f582b4..53d7812b 100644
--- a/src/node/plugin.ts
+++ b/src/node/plugin.ts
@@ -153,9 +153,7 @@ export async function createVitePressPlugin(
!!site.themeConfig?.algolia, // legacy
__CARBON__: !!site.themeConfig?.carbonAds,
__ASSETS_DIR__: JSON.stringify(siteConfig.assetsDir),
- __VUE_PROD_HYDRATION_MISMATCH_DETAILS__: !!process.env.DEBUG,
- __SOCIAL_SVG_SPRITE_ICONS__:
- site.themeConfig?.enableSocialLinksSVGSprite === true
+ __VUE_PROD_HYDRATION_MISMATCH_DETAILS__: !!process.env.DEBUG
},
optimizeDeps: {
// force include vue to avoid duplicated copies when linked + optimized
diff --git a/src/node/plugins/svgSpritePlugin.ts b/src/node/plugins/svgSpritePlugin.ts
index 919cecc5..0d333dd6 100644
--- a/src/node/plugins/svgSpritePlugin.ts
+++ b/src/node/plugins/svgSpritePlugin.ts
@@ -4,11 +4,31 @@ import type { DefaultTheme } from '../index'
export function svgSpritePlugin(siteConfig: SiteConfig) {
let useSvgSprites: Record = {}
+ let virtual: [name: string, path: string][] = []
+ const virtualName = 'virtual:vp-social-icons'
+ const resolvedVirtualName = `\0${virtualName}`
return {
name: 'vitepress:svg-sprite',
enforce: 'pre',
configResolved() {
useSvgSprites = prepareSvgSprites(useSvgSprites, siteConfig)
+ virtual = prepareSVGIcons(siteConfig)
+ },
+ resolveId(id: string) {
+ if (id === virtualName) {
+ return resolvedVirtualName
+ }
+ },
+ load(id) {
+ if (id === resolvedVirtualName) {
+ if (virtual.length === 0) {
+ return 'export const socialIcons = {}'
+ }
+ return `${virtual.map(([name, path]) => `import ${name} from ${JSON.stringify(path)}`).join('\n')}
+
+export const socialIcons = {${virtual.map(([name]) => name).join(',')}}
+`
+ }
},
generateBundle(_options, bundle) {
Object.entries(useSvgSprites).forEach(([fileName, source]) => {
@@ -46,6 +66,45 @@ export function svgSpritePlugin(siteConfig: SiteConfig) {
} satisfies Plugin
}
+function prepareSVGIcons({ site }: SiteConfig) {
+ const socialIconPrefix =
+ site.themeConfig?.enableSocialLinksSVGSprite === true
+ ? 'vitepress/dist/client/theme-default/components/sprite-social-icons/'
+ : 'vitepress/dist/client/theme-default/components/social-icons/'
+ const socialIcons: DefaultTheme.SocialLink[] =
+ site.themeConfig?.socialLinks ?? []
+
+ return socialIcons
+ .filter((s) => typeof s.icon === 'string')
+ .map((s) => {
+ let icon: string = ''
+ switch (s.icon) {
+ case 'x':
+ icon = 'X'
+ break
+ case 'github':
+ icon = 'GitHub'
+ break
+ case 'youtube':
+ icon = 'YouTube'
+ break
+ case 'discord':
+ case 'facebook':
+ case 'instagram':
+ case 'mastodon':
+ case 'npm':
+ case 'slack':
+ case 'twitter':
+ icon = s.icon.charAt(0).toUpperCase() + s.icon.slice(1)
+ break
+ }
+ return [s.icon, `${socialIconPrefix}VP${icon}Icon.vue`] as [
+ name: string,
+ path: string
+ ]
+ })
+}
+
const svgSprite = `
`
-const localSearchSvgSprite = `
-
-`
-
const socialSvgSpriteSymbols = {
discord: `
@@ -172,44 +226,99 @@ const socialSvgSpriteSymbols = {
`
}
+const localSearchSvgSprite = `
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`
+
+const DocSearchIcon = `
+
+
+ `
+
function prepareSvgSprites(
sprites: Record,
siteConfig: SiteConfig
) {
sprites['vp-icons-sprite.svg'] = svgSprite
- if (siteConfig.site.themeConfig?.enableSocialLinksSVGSprite) {
- const socialLinks: DefaultTheme.SocialLink[] | undefined =
- siteConfig.site.themeConfig.socialLinks
- if (socialLinks?.length) {
- const entries = Object.values(
- socialLinks.reduce(
- (sprite, l) => {
- if (l.icon) {
- if (typeof l.icon !== 'object') {
- if (l.icon in socialSvgSpriteSymbols) {
- sprite[l.icon] = socialSvgSpriteSymbols[l.icon]
- }
- } else if ('id' in l.icon && 'symbol' in l.icon) {
- sprite[l.icon.id] = l.icon.symbol
- // we don't need the symbol in the site configuration
- l.icon.symbol = ''
+ const socialLinks: DefaultTheme.SocialLink[] | undefined =
+ siteConfig.site.themeConfig.socialLinks
+ if (socialLinks?.length) {
+ const entries = Object.values(
+ socialLinks.reduce(
+ (sprite, l) => {
+ if (l.icon) {
+ if (typeof l.icon !== 'object') {
+ if (l.icon in socialSvgSpriteSymbols) {
+ sprite[l.icon] = socialSvgSpriteSymbols[l.icon]
}
+ } else if ('id' in l.icon && 'symbol' in l.icon) {
+ sprite[l.icon.id] = l.icon.symbol
+ // we don't need the symbol in the site configuration
+ l.icon.symbol = ''
}
+ }
- return sprite
- },
- {} as Record
- )
+ return sprite
+ },
+ {} as Record
)
- entries.unshift(`
+ )
+ entries.unshift(`
')
- sprites['vp-social-icons-sprite.svg'] = entries.join('')
- }
+ entries.push('')
+ sprites['vp-social-icons-sprite.svg'] = entries.join('')
}
if (siteConfig.site.themeConfig?.search?.provider === 'local') {
- sprites['vp-local-search-icons-sprite.svg'] = localSearchSvgSprite
+ sprites['vp-local-search-icons-sprite.svg'] =
+ `
+
+`
+ } else {
+ sprites['vp-local-search-icons-sprite.svg'] =
+ `
+
+`
}
return sprites
diff --git a/types/default-theme.d.ts b/types/default-theme.d.ts
index 2c3aeef4..c852955a 100644
--- a/types/default-theme.d.ts
+++ b/types/default-theme.d.ts
@@ -89,19 +89,6 @@ export namespace DefaultTheme {
*/
socialLinks?: SocialLink[]
- /**
- * Should VitePress generate and use SVG Sprite to render SVG social links?.
- *
- * To enable this feature, you need to provide `{ sprite: string; symbol: string }` in `socialLinks` entries if you're using custom `svg`:
- * - the symbol is the svg content: replace svg with symbol tag: `` => ``
- * - remove any xmlns and role attributes
- * - include id attribute, must match the sprite value
- * - remove title and desc tags if present
- *
- * @default false
- */
- enableSocialLinksSVGSprite?: boolean
-
/**
* The footer configuration.
*/