Skip to content

Commit

Permalink
feat(theme-default): improve theme extending
Browse files Browse the repository at this point in the history
  • Loading branch information
Mister-Hope committed Jan 8, 2025
1 parent 42a3474 commit 9617217
Show file tree
Hide file tree
Showing 21 changed files with 99 additions and 47 deletions.
2 changes: 1 addition & 1 deletion docs/themes/default/extending.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ export default defineUserConfig({

## Modifying Behavior

Most of the core behaviors of the default theme have been extracted into a composable API, and also provide [aliases](https://v2.vuepress.vuejs.org/zh/reference/plugin-api.html#alias) with the `@theme` prefix.
Most of the core behaviors of the default theme have been extracted into a composable API or util function, and also provide [aliases](https://v2.vuepress.vuejs.org/zh/reference/plugin-api.html#alias) with the `@theme` prefix.

For example, if you want to add some default values ​​to the theme data of the default theme, you can override the `useThemeData` function of `@theme/useThemeData`.

Expand Down
2 changes: 1 addition & 1 deletion docs/zh/themes/default/extending.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ export default defineUserConfig({

## 修改行为

默认主题的核心行为大多都被抽离成可组合式 API,并同样提供了 `@theme` 前缀的 [alias](https://v2.vuepress.vuejs.org/zh/reference/plugin-api.html#alias)
默认主题的核心行为大多都被抽离成可组合式 API 或工具函数,并同样提供了 `@theme` 前缀的 [alias](https://v2.vuepress.vuejs.org/zh/reference/plugin-api.html#alias)

比如,如果你想为默认主题的主题数据添加一些默认值,你可以通过覆盖 `@theme/useThemeData``useThemeData` 函数来实现。

Expand Down
32 changes: 32 additions & 0 deletions themes/theme-default/src/client/components/VPAutoLink.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<script setup lang="ts">
import type { VNode } from 'vue'
import type { AutoLinkConfig } from 'vuepress/client'
import { AutoLink } from 'vuepress/client'
defineProps<{
/**
* The auto link config
*/
config: AutoLinkConfig
}>()
defineSlots<{
default?: (config: AutoLinkConfig) => VNode | VNode[]
before?: (config: AutoLinkConfig) => VNode | VNode[] | null
after?: (config: AutoLinkConfig) => VNode | VNode[] | null
}>()
</script>

<template>
<AutoLink :config="config">
<template v-if="$slots.default" #default>
<slot v-bind="config" />
</template>
<template #before>
<slot name="before" v-bind="config" />
</template>
<template #after>
<slot name="after" v-bind="config" />
</template>
</AutoLink>
</template>
9 changes: 4 additions & 5 deletions themes/theme-default/src/client/components/VPHomeHero.vue
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<script setup lang="ts">
import VPAutoLink from '@theme/VPAutoLink.vue'
import { useDarkMode } from '@theme/useDarkMode'
import type { FunctionalComponent } from 'vue'
import { computed, h } from 'vue'
import {
AutoLink,
ClientOnly,
usePageFrontmatter,
useSiteLocaleData,
Expand Down Expand Up @@ -48,10 +48,9 @@ const actions = computed(() => {
return []
}
return frontmatter.value.actions.map(({ text, link, type = 'primary' }) => ({
text,
link,
return frontmatter.value.actions.map(({ type = 'primary', ...rest }) => ({
type,
...rest,
}))
})
Expand Down Expand Up @@ -88,7 +87,7 @@ const HomeHeroImage: FunctionalComponent = () => {
</p>

<p v-if="actions.length" class="vp-hero-actions">
<AutoLink
<VPAutoLink
v-for="action in actions"
:key="action.text"
class="vp-hero-action-button"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
<script setup lang="ts">
import VPAutoLink from '@theme/VPAutoLink.vue'
import VPDropdownTransition from '@theme/VPDropdownTransition.vue'
import { useToggle } from '@vueuse/core'
import { computed, toRefs, watch } from 'vue'
import { AutoLink, useRoute } from 'vuepress/client'
import { useRoute } from 'vuepress/client'
import type { AutoLinkOptions, NavGroup } from '../../shared/index.js'
const props = defineProps<{
Expand Down Expand Up @@ -74,7 +75,7 @@ watch(
>
<template v-if="'children' in child">
<h4 class="vp-navbar-dropdown-subtitle">
<AutoLink
<VPAutoLink
v-if="child.link"
:config="child"
@focusout="
Expand All @@ -98,7 +99,7 @@ watch(
:key="grandchild.link"
class="vp-navbar-dropdown-subitem"
>
<AutoLink
<VPAutoLink
:config="grandchild"
@focusout="
() => {
Expand All @@ -116,7 +117,7 @@ watch(
</template>

<template v-else>
<AutoLink
<VPAutoLink
:config="child"
@focusout="
() => {
Expand Down
4 changes: 2 additions & 2 deletions themes/theme-default/src/client/components/VPNavbarItems.vue
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
<script setup lang="ts">
import VPAutoLink from '@theme/VPAutoLink.vue'
import VPNavbarDropdown from '@theme/VPNavbarDropdown.vue'
import { useNavbarConfig } from '@theme/useNavbarConfig'
import { useNavbarRepo } from '@theme/useNavbarRepo'
import { useNavbarSelectLanguage } from '@theme/useNavbarSelectLanguage'
import { useThemeLocaleData } from '@theme/useThemeData'
import { DeviceType, useUpdateDeviceStatus } from '@theme/useUpdateDeviceStatus'
import { computed, ref } from 'vue'
import { AutoLink } from 'vuepress/client'
const navbarConfig = useNavbarConfig()
const navbarSelectLanguage = useNavbarSelectLanguage()
Expand Down Expand Up @@ -47,7 +47,7 @@ useUpdateDeviceStatus(
:class="{ mobile: isMobile }"
:config="item"
/>
<AutoLink v-else :config="item" />
<VPAutoLink v-else :config="item" />
</div>
</nav>
</template>
Expand Down
6 changes: 3 additions & 3 deletions themes/theme-default/src/client/components/VPPageMeta.vue
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<script setup lang="ts">
import VPAutoLink from '@theme/VPAutoLink.vue'
import VPEditIcon from '@theme/VPEditIcon.vue'
import { useContributors } from '@theme/useContributors'
import { useEditLink } from '@theme/useEditLink'
import { useLastUpdated } from '@theme/useLastUpdated'
import { useThemeLocaleData } from '@theme/useThemeData'
import { AutoLink } from 'vuepress/client'
const themeLocale = useThemeLocaleData()
const editLink = useEditLink()
Expand All @@ -15,11 +15,11 @@ const contributors = useContributors()
<template>
<footer class="vp-page-meta">
<div v-if="editLink" class="vp-meta-item edit-link">
<AutoLink class="label" :config="editLink">
<VPAutoLink class="label" :config="editLink">
<template #before>
<VPEditIcon />
</template>
</AutoLink>
</VPAutoLink>
</div>

<div class="vp-meta-item git-info">
Expand Down
10 changes: 5 additions & 5 deletions themes/theme-default/src/client/components/VPPageNav.vue
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<script setup lang="ts">
import VPAutoLink from '@theme/VPAutoLink.vue'
import { useNavigate } from '@theme/useNavigate'
import { useRelatedLinks } from '@theme/useRelatedLinks'
import { useThemeLocaleData } from '@theme/useThemeData'
import { useEventListener } from '@vueuse/core'
import { computed } from 'vue'
import { AutoLink } from 'vuepress/client'
const themeLocale = useThemeLocaleData()
const navigate = useNavigate()
Expand Down Expand Up @@ -39,25 +39,25 @@ useEventListener('keydown', (event): void => {
class="vp-page-nav"
:aria-label="navbarLabel"
>
<AutoLink v-if="prevLink" class="prev" :config="prevLink">
<VPAutoLink v-if="prevLink" class="prev" :config="prevLink">
<div class="hint">
<span class="arrow left" />
{{ themeLocale.prev ?? 'Prev' }}
</div>
<div class="link">
<span>{{ prevLink.text }}</span>
</div>
</AutoLink>
</VPAutoLink>

<AutoLink v-if="nextLink" class="next" :config="nextLink">
<VPAutoLink v-if="nextLink" class="next" :config="nextLink">
<div class="hint">
{{ themeLocale.next ?? 'Next' }}
<span class="arrow right" />
</div>
<div class="link">
<span>{{ nextLink.text }}</span>
</div>
</AutoLink>
</VPAutoLink>
</nav>
</template>

Expand Down
9 changes: 5 additions & 4 deletions themes/theme-default/src/client/components/VPSidebarItem.vue
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
<script setup lang="ts">
import VPAutoLink from '@theme/VPAutoLink.vue'
import VPDropdownTransition from '@theme/VPDropdownTransition.vue'
import { isActiveSidebarItem } from '@theme/isActiveSidebarItem'
import { useToggle } from '@vueuse/core'
import { computed, nextTick, onBeforeUnmount, toRefs } from 'vue'
import { AutoLink, useRoute, useRouter } from 'vuepress/client'
import { useRoute, useRouter } from 'vuepress/client'
import type { SidebarItem } from '../typings.js'
import { isActiveLinkItem } from '../utils/index.js'
const props = withDefaults(
defineProps<{
Expand All @@ -27,7 +28,7 @@ const router = useRouter()
const collapsible = computed(
() => 'collapsible' in item.value && item.value.collapsible,
)
const isActive = computed(() => isActiveLinkItem(item.value, route))
const isActive = computed(() => isActiveSidebarItem(item.value, route))
const itemClass = computed(() => ({
'vp-sidebar-item': true,
'vp-sidebar-heading': depth.value === 0,
Expand Down Expand Up @@ -61,7 +62,7 @@ onBeforeUnmount(() => {

<template>
<li>
<AutoLink v-if="item.link" :class="itemClass" :config="item" />
<VPAutoLink v-if="item.link" :class="itemClass" :config="item" />
<p
v-else
tabindex="0"
Expand Down
2 changes: 1 addition & 1 deletion themes/theme-default/src/client/composables/useEditLink.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { resolveEditLink } from '@theme/resolveEditLink'
import { useThemeLocaleData } from '@theme/useThemeData'
import type { ComputedRef } from 'vue'
import { computed } from 'vue'
Expand All @@ -7,7 +8,6 @@ import type {
DefaultThemeNormalPageFrontmatter,
DefaultThemePageData,
} from '../../shared/index.js'
import { resolveEditLink } from '../utils/index.js'

export const useEditLink = (): ComputedRef<AutoLinkConfig | null> => {
const themeLocale = useThemeLocaleData()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import { isLinkInternal } from '@theme/isLinkInternal'
import { resolveAutoLink } from '@theme/resolveAutoLink'
import { resolvePrefix } from '@theme/resolvePrefix'
import { useThemeLocaleData } from '@theme/useThemeData'
import type { ComputedRef } from 'vue'
import { computed } from 'vue'
Expand All @@ -7,14 +10,13 @@ import type {
NavbarLinkOptions,
} from '../../shared/navbar.js'
import type { NavbarItem } from '../typings.js'
import { getAutoLink, isLinkInternal, resolvePrefix } from '../utils/index.js'

const resolveNavbarItem = (
item: NavbarGroupOptions | NavbarLinkOptions,
prefix = '',
): NavbarItem => {
if (isString(item)) {
return getAutoLink(resolvePrefix(prefix, item))
return resolveAutoLink(resolvePrefix(prefix, item))
}

if ('children' in item) {
Expand All @@ -29,7 +31,7 @@ const resolveNavbarItem = (
return {
...item,
link: isLinkInternal(item.link)
? getAutoLink(resolvePrefix(prefix, item.link)).link
? resolveAutoLink(resolvePrefix(prefix, item.link)).link
: item.link,
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { resolveRepoType } from '@theme/resolveRepoType'
import { useThemeLocaleData } from '@theme/useThemeData'
import type { ComputedRef } from 'vue'
import { computed } from 'vue'
import { isLinkHttp } from 'vuepress/shared'
import type { NavbarItem } from '../typings.js'
import { resolveRepoType } from '../utils/index.js'

/**
* Get navbar config of repository link
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { resolveAutoLink } from '@theme/resolveAutoLink'
import { useSidebarItems } from '@theme/useSidebarItems'
import { useThemeLocaleData } from '@theme/useThemeData'
import type { ComputedRef } from 'vue'
Expand All @@ -9,7 +10,6 @@ import type {
DefaultThemeNormalPageFrontmatter,
} from '../../shared/index.js'
import type { SidebarItem } from '../typings.js'
import { getAutoLink } from '../utils/index.js'

const resolveFromFrontmatterConfig = (
config: AutoLinkOptions | string | false | undefined,
Expand All @@ -20,13 +20,13 @@ const resolveFromFrontmatterConfig = (
}

if (isString(config)) {
return getAutoLink(config, currentPath)
return resolveAutoLink(config, currentPath)
}

if (isPlainObject(config)) {
return {
...config,
link: getAutoLink(config.link, currentPath).link,
link: resolveAutoLink(config.link, currentPath).link,
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import { isLinkInternal } from '@theme/isLinkInternal'
import { resolveAutoLink } from '@theme/resolveAutoLink'
import { resolvePrefix } from '@theme/resolvePrefix'
import { useThemeLocaleData } from '@theme/useThemeData'
import type { MenuItem } from '@vuepress/helper/client'
import { getHeaders, keys, startsWith } from '@vuepress/helper/client'
Expand All @@ -21,7 +24,6 @@ import type {
SidebarOptions,
} from '../../shared/index.js'
import type { SidebarHeaderItem, SidebarItem } from '../typings.js'
import { getAutoLink, isLinkInternal, resolvePrefix } from '../utils/index.js'

export type HeadersRef = Ref<MenuItem[]>

Expand Down Expand Up @@ -104,12 +106,12 @@ export const resolveArraySidebarItems = (
pathPrefix: string,
): SidebarItem => {
const childItem: SidebarItemOptions = isString(item)
? getAutoLink(resolvePrefix(pathPrefix, item))
? resolveAutoLink(resolvePrefix(pathPrefix, item))
: isString(item.link)
? {
...item,
link: isLinkInternal(item.link)
? getAutoLink(resolvePrefix(pathPrefix, item.link)).link
? resolveAutoLink(resolvePrefix(pathPrefix, item.link)).link
: item.link,
}
: item
Expand Down
2 changes: 1 addition & 1 deletion themes/theme-default/src/client/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export * from './getAutoLink.js'
export * from './isActiveSidebarItem.js'
export * from './isLinkInternal.js'
export * from './resolveAutoLink.js'
export * from './resolveEditLink.js'
export * from './resolvePrefix.js'
export * from './resolveRepoType.js'
4 changes: 2 additions & 2 deletions themes/theme-default/src/client/utils/isActiveSidebarItem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const isActiveLink = (
return currentPath === targetPath
}

export const isActiveLinkItem = (
export const isActiveSidebarItem = (
item: SidebarItem,
route: RouteLocationNormalizedLoaded,
): boolean => {
Expand All @@ -27,7 +27,7 @@ export const isActiveLinkItem = (
}

if ('children' in item) {
return item.children.some((child) => isActiveLinkItem(child, route))
return item.children.some((child) => isActiveSidebarItem(child, route))
}

return false
Expand Down
Loading

0 comments on commit 9617217

Please sign in to comment.