Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions docs/reference/plugin/external-link-icon.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,43 @@ This plugin has been integrated into the default theme.
npm i -D @vuepress/plugin-external-link-icon@next
```

## Options

### locales

- Type: `Record<string, { openInNewWindow: string }>`

- Details:

The a11y text of the external link icon in different locales.

If this option is not specified, it will fallback to default text.

- Example:

```js
module.exports = {
plugins: [
[
'@vuepress/plugin-external-link-icon',
{
locales: {
'/': {
openInNewWindow: 'open in new window',
},
'/zh/': {
openInNewWindow: '在新窗口打开',
},
},
},
],
],
}
```

- Also see:
- [Guide > I18n](../../guide/i18n.md)

## Frontmatter

### externalLinkIcon
Expand Down
37 changes: 37 additions & 0 deletions docs/zh/reference/plugin/external-link-icon.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,43 @@
npm i -D @vuepress/plugin-external-link-icon@next
```

## 配置项

### locales

- 类型: `Record<string, { openInNewWindow: string }>`

- 详情:

外部链接图标在不同 locales 下的 A11y 文字。

如果没有指定该配置项,它会降级使用默认文字。

- 示例:

```js
module.exports = {
plugins: [
[
'@vuepress/plugin-external-link-icon',
{
locales: {
'/': {
openInNewWindow: 'open in new window',
},
'/zh/': {
openInNewWindow: '在新窗口打开',
},
},
},
],
],
}
```

- 参考:
- [指南 > 多语言支持](../../guide/i18n.md)

## Frontmatter

### externalLinkIcon
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
import { defineClientAppEnhance } from '@vuepress/client'
import { h } from 'vue'
import type { ExternalLinkIconLocales } from '../shared'
import { ExternalLinkIcon } from './components/ExternalLinkIcon'

declare const __EXTERNAL_LINK_ICON_LOCALES__: ExternalLinkIconLocales

const locales = __EXTERNAL_LINK_ICON_LOCALES__

export default defineClientAppEnhance(({ app }) => {
app.component('ExternalLinkIcon', ExternalLinkIcon)
// wrap the `<ExternalLinkIcon />` component with plugin options
app.component('ExternalLinkIcon', h(ExternalLinkIcon, { locales }))
})
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { h } from 'vue'
import type { FunctionalComponent } from 'vue'
import { useRouteLocale } from '@vuepress/client'
import { computed, defineComponent, h } from 'vue'
import type { PropType } from 'vue'
import type { ExternalLinkIconLocales } from '../../shared'

import '../styles/vars.css'
import '../styles/external-link-icon.css'
Expand Down Expand Up @@ -30,7 +32,35 @@ const svg = h(
]
)

export const ExternalLinkIcon: FunctionalComponent = (_, { slots }) =>
h('span', [svg, slots.default?.()])
export const ExternalLinkIcon = defineComponent({
name: 'ExternalLinkIcon',

ExternalLinkIcon.displayName = 'ExternalLinkIcon'
props: {
locales: {
type: Object as PropType<ExternalLinkIconLocales>,
required: false,
default: () => ({}),
},
},

setup(props) {
const routeLocale = useRouteLocale()
const locale = computed(
() =>
props.locales[routeLocale.value] ?? {
openInNewWindow: 'open in new window',
}
)
return () =>
h('span', [
svg,
h(
'span',
{
class: 'external-link-icon-sr-only',
},
locale.value.openInNewWindow
),
])
},
})
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,16 @@
vertical-align: middle;
top: -1px;
}

.external-link-icon-sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border-width: 0;
user-select: none;
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,24 @@
import type { Plugin } from '@vuepress/core'
import type { MarkdownEnv } from '@vuepress/markdown'
import { path } from '@vuepress/utils'
import type { ExternalLinkIconLocales } from '../shared'

export type ExternalLinkIconPluginOptions = Record<never, never>
/**
* Options for @vuepress/plugin-external-link-icon
*/
export type ExternalLinkIconPluginOptions = {
locales?: ExternalLinkIconLocales
}

export const externalLinkIconPlugin: Plugin<ExternalLinkIconPluginOptions> = {
export const externalLinkIconPlugin: Plugin<ExternalLinkIconPluginOptions> = ({
locales = {},
}) => ({
name: '@vuepress/plugin-external-link-icon',

define: {
__EXTERNAL_LINK_ICON_LOCALES__: locales,
},

clientAppEnhanceFiles: path.resolve(
__dirname,
'../client/clientAppEnhance.js'
Expand Down Expand Up @@ -44,4 +56,4 @@ export const externalLinkIconPlugin: Plugin<ExternalLinkIconPluginOptions> = {
return result
}
},
}
})
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './types'
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import type { LocaleConfig } from '@vuepress/shared'

export type ExternalLinkIconLocales = LocaleConfig<{
openInNewWindow: string
}>
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@
"rootDir": "./src",
"outDir": "./lib"
},
"include": ["./src/node"]
"include": ["./src/node", "./src/shared"]
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@
"rootDir": "./src",
"outDir": "./lib"
},
"include": ["./src/client"]
"include": ["./src/client", "./src/shared"]
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { h } from 'vue'
import Badge from './components/global/Badge.vue'
import CodeGroup from './components/global/CodeGroup'
import CodeGroupItem from './components/global/CodeGroupItem.vue'
import ExternalLinkIcon from './components/global/ExternalLinkIcon.vue'
import { useScrollPromise } from './composables'

import './styles/index.scss'
Expand All @@ -13,10 +12,6 @@ export default defineClientAppEnhance(({ app, router }) => {
app.component('CodeGroup', CodeGroup)
app.component('CodeGroupItem', CodeGroupItem)

// override the `<ExternalLinkIcon>` provided by @vuepress/plugin-external-link-icon
delete app._context.components.ExternalLinkIcon
app.component('ExternalLinkIcon', ExternalLinkIcon)

// compat with @vuepress/plugin-docsearch and @vuepress/plugin-search
app.component('NavbarSearch', () => {
const SearchComponent =
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
@use 'navbar-dropdown';
@use 'page';
@use 'sidebar';
@use 'sr-only';
@use 'toc';
@use 'transitions';

Expand Down
12 changes: 0 additions & 12 deletions packages/@vuepress/theme-default/src/client/styles/sr-only.scss

This file was deleted.

6 changes: 5 additions & 1 deletion packages/@vuepress/theme-default/src/node/defaultTheme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
resolveContainerPluginOptionsForCodeGroup,
resolveContainerPluginOptionsForCodeGroupItem,
resolveContainerPluginOptionsForDetails,
resolveExternalLinkIconPluginOptions,
resolveGitPluginOptions,
resolveMediumZoomPluginOptions,
} from './utils'
Expand Down Expand Up @@ -108,7 +109,10 @@ export const defaultTheme: Theme<DefaultThemeOptions> = (
'@vuepress/container',
resolveContainerPluginOptionsForCodeGroupItem(themePlugins),
],
['@vuepress/external-link-icon', themePlugins.externalLinkIcon !== false],
[
'@vuepress/external-link-icon',
resolveExternalLinkIconPluginOptions(themePlugins, localeOptions),
],
['@vuepress/git', resolveGitPluginOptions(themePlugins, localeOptions)],
['@vuepress/medium-zoom', resolveMediumZoomPluginOptions(themePlugins)],
['@vuepress/nprogress', themePlugins.nprogress !== false],
Expand Down
1 change: 1 addition & 0 deletions packages/@vuepress/theme-default/src/node/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export * from './assignDefaultLocaleOptions'
export * from './resolveActiveHeaderLinksPluginOptions'
export * from './resolveContainerPluginOptions'
export * from './resolveExternalLinkIconPluginOptions'
export * from './resolveGitPluginOptions'
export * from './resolveMediumZoomPluginOptions'
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import type { ExternalLinkIconPluginOptions } from '@vuepress/plugin-external-link-icon'
import type { DefaultThemeData, DefaultThemePluginsOptions } from '../../shared'

/**
* Resolve options for @vuepress/plugin-external-link-icon
*/
export const resolveExternalLinkIconPluginOptions = (
themePlugins: DefaultThemePluginsOptions,
localeOptions: DefaultThemeData
): ExternalLinkIconPluginOptions | boolean => {
if (themePlugins?.externalLinkIcon === false) {
return false
}

return {
locales: Object.entries(localeOptions.locales || {}).reduce(
(result, [key, value]) => {
result[key] = {
openInNewWindow:
value.openInNewWindow ?? localeOptions.openInNewWindow,
}
return result
},
{}
),
}
}