feat(theme): allow passing functions for nav links (#4963)

main
Miroma 23 hours ago committed by GitHub
parent 31d87e2738
commit 34cfa91b6f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -89,7 +89,7 @@ type NavItem = NavItemWithLink | NavItemWithChildren
interface NavItemWithLink { interface NavItemWithLink {
text: string text: string
link: string link: string | ((payload: PageData) => string)
activeMatch?: string activeMatch?: string
target?: string target?: string
rel?: string rel?: string

@ -55,6 +55,8 @@ export default {
The `text` is the actual text displayed in nav, and the `link` is the link that will be navigated to when the text is clicked. For the link, set path to the actual file without `.md` prefix, and always start with `/`. The `text` is the actual text displayed in nav, and the `link` is the link that will be navigated to when the text is clicked. For the link, set path to the actual file without `.md` prefix, and always start with `/`.
The `link` can also be a function that accepts [`PageData`](./runtime-api#usedata) as the argument and returns the path.
Nav links can also be dropdown menus. To do this, set `items` key on link option. Nav links can also be dropdown menus. To do this, set `items` key on link option.
```js ```js

@ -89,7 +89,7 @@ type NavItem = NavItemWithLink | NavItemWithChildren
interface NavItemWithLink { interface NavItemWithLink {
text: string text: string
link: string link: string | ((payload: PageData) => string)
activeMatch?: string activeMatch?: string
target?: string target?: string
rel?: string rel?: string

@ -55,6 +55,8 @@ export default {
`text` es el texto que se muestra en la navegación, y el `link` es el link al que será navegando cuando se hace click en el texto. Para el enlace, establezca la ruta al archivo sin el prefijo `.md` y siempre comenzar por `/`. `text` es el texto que se muestra en la navegación, y el `link` es el link al que será navegando cuando se hace click en el texto. Para el enlace, establezca la ruta al archivo sin el prefijo `.md` y siempre comenzar por `/`.
El `link` también puede ser una función que acepte [`PageData`](./runtime-api#usedata) como argumento y devuelva la ruta.
Links de navegación también pueden ser menus _dropdown_. Para hacer eso, establezca la clave de `items` en la opción del link. Links de navegación también pueden ser menus _dropdown_. Para hacer eso, establezca la clave de `items` en la opción del link.
```js ```js

@ -89,7 +89,7 @@ type NavItem = NavItemWithLink | NavItemWithChildren
interface NavItemWithLink { interface NavItemWithLink {
text: string text: string
link: string link: string | ((payload: PageData) => string)
activeMatch?: string activeMatch?: string
target?: string target?: string
rel?: string rel?: string

@ -55,6 +55,8 @@ export default {
`text` متن واقعی است که در ناوبری نمایش داده می‌شود و `link` لینکی است که هنگام کلیک بر روی متن به آن ناوبری می‌شود. برای لینک، مسیر را به صورت واقعی بدون پیشوند `.md` تنظیم کنید و همیشه با `/` شروع کنید. `text` متن واقعی است که در ناوبری نمایش داده می‌شود و `link` لینکی است که هنگام کلیک بر روی متن به آن ناوبری می‌شود. برای لینک، مسیر را به صورت واقعی بدون پیشوند `.md` تنظیم کنید و همیشه با `/` شروع کنید.
`link` همچنین می‌تواند تابعی باشد که [`PageData`](./runtime-api#usedata) را به عنوان آرگومان بپذیرد و مسیر را برگرداند.
لینک‌های ناوبری همچنین می‌توانند منوهای کشویی باشند. برای این کار، کلید `items` را در گزینه لینک تنظیم کنید. لینک‌های ناوبری همچنین می‌توانند منوهای کشویی باشند. برای این کار، کلید `items` را در گزینه لینک تنظیم کنید.
```js ```js

@ -89,7 +89,7 @@ type NavItem = NavItemWithLink | NavItemWithChildren
interface NavItemWithLink { interface NavItemWithLink {
text: string text: string
link: string link: string | ((payload: PageData) => string)
activeMatch?: string activeMatch?: string
target?: string target?: string
rel?: string rel?: string

@ -55,6 +55,8 @@ export default {
`text`는 네비게이션 바에 표시되는 실제 텍스트이며, `link`는 텍스트를 클릭했을 때 이동할 링크입니다. 링크의 경로는 `.md` 접미사 없이 실제 파일 경로로 설정하며, 항상 `/`로 시작해야 합니다. `text`는 네비게이션 바에 표시되는 실제 텍스트이며, `link`는 텍스트를 클릭했을 때 이동할 링크입니다. 링크의 경로는 `.md` 접미사 없이 실제 파일 경로로 설정하며, 항상 `/`로 시작해야 합니다.
`link`는 또한 [`PageData`](./runtime-api#usedata)를 인자로 받아 경로를 반환하는 함수가 될 수도 있습니다.
네비게이션 바 링크는 드롭다운 메뉴가 될 수 있습니다. 이를 위해 `link` 옵션에 `items` 키를 설정합니다. 네비게이션 바 링크는 드롭다운 메뉴가 될 수 있습니다. 이를 위해 `link` 옵션에 `items` 키를 설정합니다.
```js ```js

@ -89,7 +89,7 @@ type NavItem = NavItemWithLink | NavItemWithChildren
interface NavItemWithLink { interface NavItemWithLink {
text: string text: string
link: string link: string | ((payload: PageData) => string)
activeMatch?: string activeMatch?: string
target?: string target?: string
rel?: string rel?: string

@ -55,6 +55,8 @@ export default {
`text` é o próprio texto mostrado na navegação, e o `link` é o link para o qual será navegado quando o texto for clicado. Para o link, defina o caminho para o próprio arquivo sem o prefixo `.md` e sempre comece com `/`. `text` é o próprio texto mostrado na navegação, e o `link` é o link para o qual será navegado quando o texto for clicado. Para o link, defina o caminho para o próprio arquivo sem o prefixo `.md` e sempre comece com `/`.
O `link` também pode ser uma função que aceita [`PageData`](./runtime-api#usedata) como argumento e retorna o caminho.
Links de navegação também podem ser menus _dropdown_. Para fazer isso, defina a chave `items` na opção do link. Links de navegação também podem ser menus _dropdown_. Para fazer isso, defina a chave `items` na opção do link.
```js ```js

@ -89,7 +89,7 @@ type NavItem = NavItemWithLink | NavItemWithChildren
interface NavItemWithLink { interface NavItemWithLink {
text: string text: string
link: string link: string | ((payload: PageData) => string)
activeMatch?: string activeMatch?: string
target?: string target?: string
rel?: string rel?: string

@ -55,6 +55,8 @@ export default {
`text` — это текст, отображаемый в навигации, а `link` — это ссылка, на которую будет осуществлён переход при нажатии на текст. Для ссылки задайте путь к фактическому файлу без префикса `.md` и всегда начинайте с `/`. `text` — это текст, отображаемый в навигации, а `link` — это ссылка, на которую будет осуществлён переход при нажатии на текст. Для ссылки задайте путь к фактическому файлу без префикса `.md` и всегда начинайте с `/`.
`link` также может быть функцией, которая принимает [`PageData`](./runtime-api#usedata) в качестве аргумента и возвращает путь.
Навигационные ссылки также могут быть выпадающими меню. Для этого установите ключ `items` вместо ключа `link`: Навигационные ссылки также могут быть выпадающими меню. Для этого установите ключ `items` вместо ключа `link`:
```js ```js

@ -89,7 +89,7 @@ type NavItem = NavItemWithLink | NavItemWithChildren
interface NavItemWithLink { interface NavItemWithLink {
text: string text: string
link: string link: string | ((payload: PageData) => string)
activeMatch?: string activeMatch?: string
target?: string target?: string
rel?: string rel?: string

@ -55,6 +55,8 @@ export default {
`text` 是 nav 中显示的实际文本,而 `link` 是单击文本时将导航到的链接。对于链接,将路径设置为不带 `.md` 后缀的实际文件,并且始终以 `/` 开头。 `text` 是 nav 中显示的实际文本,而 `link` 是单击文本时将导航到的链接。对于链接,将路径设置为不带 `.md` 后缀的实际文件,并且始终以 `/` 开头。
`link` 也可以是一个函数,它接受 [`PageData`](./runtime-api#usedata) 作为参数并返回路径。
导航链接也可以是下拉菜单。为此,请替换 `link` 选项,设置 `items` 数组。 导航链接也可以是下拉菜单。为此,请替换 `link` 选项,设置 `items` 数组。
```js ```js

@ -1,15 +1,22 @@
<script lang="ts" setup generic="T extends DefaultTheme.NavItemWithLink"> <script lang="ts" setup generic="T extends DefaultTheme.NavItemWithLink">
import type { DefaultTheme } from 'vitepress/theme' import type { DefaultTheme } from 'vitepress/theme'
import { computed } from 'vue'
import { useData } from '../composables/data' import { useData } from '../composables/data'
import { isActive } from '../../shared' import { isActive } from '../../shared'
import VPLink from './VPLink.vue' import VPLink from './VPLink.vue'
defineProps<{ const props = defineProps<{
item: T item: T
}>() }>()
const { page } = useData() const { page } = useData()
const href = computed(() =>
typeof props.item.link === 'function'
? props.item.link(page.value)
: props.item.link
)
defineOptions({ inheritAttrs: false }) defineOptions({ inheritAttrs: false })
</script> </script>
@ -20,11 +27,11 @@ defineOptions({ inheritAttrs: false })
:class="{ :class="{
active: isActive( active: isActive(
page.relativePath, page.relativePath,
item.activeMatch || item.link, item.activeMatch || href,
!!item.activeMatch !!item.activeMatch
) )
}" }"
:href="item.link" :href
:target="item.target" :target="item.target"
:rel="item.rel" :rel="item.rel"
:no-icon="item.noIcon" :no-icon="item.noIcon"

@ -17,7 +17,7 @@ const isChildActive = (navItem: DefaultTheme.NavItem) => {
if ('link' in navItem) { if ('link' in navItem) {
return isActive( return isActive(
page.value.relativePath, page.value.relativePath,
navItem.link, typeof navItem.link === "function" ? navItem.link(page.value) : navItem.link,
!!props.item.activeMatch !!props.item.activeMatch
) )
} }

@ -1,14 +1,21 @@
<script lang="ts" setup> <script lang="ts" setup>
import type { DefaultTheme } from 'vitepress/theme' import type { DefaultTheme } from 'vitepress/theme'
import { computed } from 'vue'
import { useData } from '../composables/data' import { useData } from '../composables/data'
import { isActive } from '../../shared' import { isActive } from '../../shared'
import VPLink from './VPLink.vue' import VPLink from './VPLink.vue'
defineProps<{ const props = defineProps<{
item: DefaultTheme.NavItemWithLink item: DefaultTheme.NavItemWithLink
}>() }>()
const { page } = useData() const { page } = useData()
const href = computed(() =>
typeof props.item.link === 'function'
? props.item.link(page.value)
: props.item.link
)
</script> </script>
<template> <template>
@ -17,11 +24,11 @@ const { page } = useData()
VPNavBarMenuLink: true, VPNavBarMenuLink: true,
active: isActive( active: isActive(
page.relativePath, page.relativePath,
item.activeMatch || item.link, item.activeMatch || href,
!!item.activeMatch !!item.activeMatch
) )
}" }"
:href="item.link" :href
:target="item.target" :target="item.target"
:rel="item.rel" :rel="item.rel"
:no-icon="item.noIcon" :no-icon="item.noIcon"

@ -1,20 +1,29 @@
<script lang="ts" setup> <script lang="ts" setup>
import type { DefaultTheme } from 'vitepress/theme' import type { DefaultTheme } from 'vitepress/theme'
import { inject } from 'vue' import { computed, inject } from 'vue'
import { useData } from '../composables/data'
import { navInjectionKey } from '../composables/nav' import { navInjectionKey } from '../composables/nav'
import VPLink from './VPLink.vue' import VPLink from './VPLink.vue'
defineProps<{ const props = defineProps<{
item: DefaultTheme.NavItemWithLink item: DefaultTheme.NavItemWithLink
}>() }>()
const { page } = useData()
const href = computed(() =>
typeof props.item.link === 'function'
? props.item.link(page.value)
: props.item.link
)
const { closeScreen } = inject(navInjectionKey)! const { closeScreen } = inject(navInjectionKey)!
</script> </script>
<template> <template>
<VPLink <VPLink
class="VPNavScreenMenuGroupLink" class="VPNavScreenMenuGroupLink"
:href="item.link" :href
:target="item.target" :target="item.target"
:rel="item.rel" :rel="item.rel"
:no-icon="item.noIcon" :no-icon="item.noIcon"

@ -1,20 +1,29 @@
<script lang="ts" setup> <script lang="ts" setup>
import type { DefaultTheme } from 'vitepress/theme' import type { DefaultTheme } from 'vitepress/theme'
import { inject } from 'vue' import { computed, inject } from 'vue'
import { useData } from '../composables/data'
import { navInjectionKey } from '../composables/nav' import { navInjectionKey } from '../composables/nav'
import VPLink from './VPLink.vue' import VPLink from './VPLink.vue'
defineProps<{ const props = defineProps<{
item: DefaultTheme.NavItemWithLink item: DefaultTheme.NavItemWithLink
}>() }>()
const { page } = useData()
const href = computed(() =>
typeof props.item.link === 'function'
? props.item.link(page.value)
: props.item.link
)
const { closeScreen } = inject(navInjectionKey)! const { closeScreen } = inject(navInjectionKey)!
</script> </script>
<template> <template>
<VPLink <VPLink
class="VPNavScreenMenuLink" class="VPNavScreenMenuLink"
:href="item.link" :href
:target="item.target" :target="item.target"
:rel="item.rel" :rel="item.rel"
:no-icon="item.noIcon" :no-icon="item.noIcon"

@ -171,7 +171,7 @@ export namespace DefaultTheme {
export interface NavItemWithLink { export interface NavItemWithLink {
text: string text: string
link: string link: string | ((payload: PageData) => string)
items?: never items?: never
/** /**

Loading…
Cancel
Save