Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(theme-default): improve theme extending #331

Merged
merged 1 commit into from
Jan 8, 2025
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
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
Loading