feat(theme): option to show icon for external links (#2501)

Co-authored-by: Divyansh Singh <40380293+brc-dd@users.noreply.github.com>
pull/2562/head
烽宁 1 year ago committed by GitHub
parent 00d94e9ee5
commit 52cfbc3236
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -398,3 +398,10 @@ Can be used to customize the label of the return to top button. This label is on
- Default: `Change language`
Can be used to customize the aria-label of the language toggle button in navbar. This is only used if you're using [i18n](../guide/i18n).
## externalLinkIcon
- Type: `boolean`
- Default: `false`
Whether to show an external link icon next to external links in markdown.

@ -2,10 +2,13 @@
import { useRoute } from 'vitepress'
import { useSidebar } from 'vitepress/theme'
import { computed } from 'vue'
import { useData } from '../composables/data'
import VPDocAside from './VPDocAside.vue'
import VPDocFooter from './VPDocFooter.vue'
import VPDocOutlineDropdown from './VPDocOutlineDropdown.vue'
const { theme } = useData()
const route = useRoute()
const { hasSidebar, hasAside, leftAside } = useSidebar()
@ -42,7 +45,13 @@ const pageName = computed(() =>
<slot name="doc-before" />
<VPDocOutlineDropdown />
<main class="main">
<Content class="vp-doc" :class="pageName" />
<Content
class="vp-doc"
:class="[
pageName,
theme.externalLinkIcon && 'external-link-icon-enabled'
]"
/>
</main>
<VPDocFooter>
<template #doc-footer-before><slot name="doc-footer-before" /></template>
@ -193,4 +202,8 @@ const pageName = computed(() =>
.VPDoc.has-aside .content-container {
max-width: 688px;
}
.external-link-icon-enabled :is(.vp-doc a[href*='://'], .vp-doc a[target='_blank'])::after {
content: '';
}
</style>

@ -1,7 +1,6 @@
<script lang="ts" setup>
import { computed } from 'vue'
import { normalizeLink } from '../support/utils'
import VPIconExternalLink from './icons/VPIconExternalLink.vue'
import { EXTERNAL_URL_RE } from '../../shared'
const props = defineProps<{
@ -20,25 +19,11 @@ const isExternal = computed(() => props.href && EXTERNAL_URL_RE.test(props.href)
<component
:is="tag"
class="VPLink"
:class="{ link: href }"
:class="{ link: href, 'vp-external-link-icon': isExternal && !noIcon }"
:href="href ? normalizeLink(href) : undefined"
:target="target || (isExternal ? '_blank' : undefined)"
:rel="rel || (isExternal ? 'noreferrer' : undefined)"
>
<slot />
<VPIconExternalLink v-if="isExternal && !noIcon" class="icon" />
</component>
</template>
<style scoped>
.icon {
display: inline-block;
margin-top: -1px;
margin-left: 4px;
width: 11px;
height: 11px;
fill: var(--vp-c-text-3);
transition: fill 0.25s;
flex-shrink: 0;
}
</style>

@ -1,13 +0,0 @@
<template>
<svg
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
focusable="false"
height="24px"
viewBox="0 0 24 24"
width="24px"
>
<path d="M0 0h24v24H0V0z" fill="none" />
<path d="M9 5v2h6.59L4 18.59 5.41 20 17 8.41V15h2V5H9z" />
</svg>
</template>

@ -522,3 +522,24 @@
margin: 0 !important;
max-width: calc((100% - 24px) / 2) !important;
}
:is(
.vp-external-link-icon,
.vp-doc a[href*='://'],
.vp-doc a[target='_blank']
)::after {
display: inline-block;
margin-top: -1px;
margin-left: 4px;
width: 11px;
height: 11px;
background: currentColor;
flex-shrink: 0;
--icon: url("data:image/svg+xml, %3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' %3E%3Cpath d='M0 0h24v24H0V0z' fill='none' /%3E%3Cpath d='M9 5v2h6.59L4 18.59 5.41 20 17 8.41V15h2V5H9z' /%3E%3C/svg%3E");
-webkit-mask-image: var(--icon);
mask-image: var(--icon);
}
.vp-external-link-icon::after {
content: '';
}

@ -122,6 +122,13 @@ export namespace DefaultTheme {
* @default true
*/
i18nRouting?: boolean
/**
* Show external link icon in Markdown links.
*
* @default false
*/
externalLinkIcon?: boolean
}
// nav -----------------------------------------------------------------------

Loading…
Cancel
Save