Skip to content
Closed
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
19 changes: 14 additions & 5 deletions docs/.vuepress/components/VPSidebarItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
import VPAutoLink from '@theme/VPAutoLink.vue'
import VPDropdownTransition from '@theme/VPDropdownTransition.vue'
import { isActiveSidebarItem } from '@theme/isActiveSidebarItem'
import type { SidebarItem } from '@vuepress/theme-default/client'
import type {
SidebarGroupItem,
SidebarItem,
} from '@vuepress/theme-default/client'
import { useToggle } from '@vueuse/core'
import { computed, nextTick, onBeforeUnmount, toRefs } from 'vue'
import { useRoute, useRouter } from 'vuepress/client'
Expand All @@ -25,9 +28,7 @@ const { item, depth } = toRefs(props)
const route = useRoute()
const router = useRouter()

const collapsible = computed(
() => 'collapsible' in item.value && item.value.collapsible,
)
const collapsible = computed(() => (item.value as SidebarGroupItem).collapsible)
const isActive = computed(() => isActiveSidebarItem(item.value, route))
const itemClass = computed(() => ({
'vp-sidebar-item': true,
Expand Down Expand Up @@ -62,7 +63,15 @@ onBeforeUnmount(() => {

<template>
<li>
<VPAutoLink v-if="item.link" :class="itemClass" :config="item" />
<VPAutoLink v-if="item.link" :class="itemClass" :config="item">
<template #after>
<span
v-if="collapsible"
class="arrow"
:class="isOpen ? 'down' : 'right'"
/>
</template>
</VPAutoLink>
<p
v-else
tabindex="0"
Expand Down
34 changes: 29 additions & 5 deletions docs/plugins/development/toc.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,15 +61,25 @@ Therefore, this plugin is more useful for theme developers.

Specify the name of the TOC component.

### defaultPropsOptions
### headersOptions

- Type: `Partial<GetHeadersOptions>`

- Default: `{}`

- Details:

Override the default values of the component [headersOptions](#headersoptions-1) prop.

### propsOptions

- Type: `Partial<TocPropsOptions>`

- Default: `{}`

- Details:

Override the default values of the component [options](#options-1) prop.
Override the default values of the component [propsOptions](#propsoptions-1) prop.

## Component Props

Expand Down Expand Up @@ -100,7 +110,21 @@ interface PageHeader {

If this prop is not specified, the headers of current page will be used.

### options
### headersOptions

- Type: `Partial<GetHeadersOptions>`

See [GetHeadersOptions](../../tools/helper/client.md#getheaders)

- Default:

See [GetHeadersOptions](../../tools/helper/client.md#getheaders), it can be overridden by [headersOptions](#headaersoptions) in plugin options.

- Details:

Customize header extracting behavior.

### propsOptions

- Type: `Partial<TocPropsOptions>`

Expand All @@ -119,7 +143,7 @@ interface TocPropsOptions {

- Default:

Following default values can be overridden by [defaultPropsOptions](#defaultpropsoptions).
Following default values can be overridden by [propsOptions](#propsoptions) in plugin options.

```ts
const defaultOptions = {
Expand All @@ -136,7 +160,7 @@ const defaultOptions = {

- Details:

Customize the TOC component.
Customize TOC component render behavior.

If the `containerTag` is set to an empty string `''`, the `<nav>` container will be removed totally.

Expand Down
34 changes: 29 additions & 5 deletions docs/zh/plugins/development/toc.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,15 +61,25 @@ Markdown 语法 `[[toc]]` 仅能在 Markdown 文件中使用。它是由 markdow

指定目录组件的名称。

### defaultPropsOptions
### headerOptions

- 类型: `Partial<GetHeadersOptions>`

- 默认值: `{}`

- 详情:

覆盖组件 [headerOptions](#headeroptions-1) Prop 的默认值。

### propsOptions

- 类型: `Partial<TocPropsOptions>`

- 默认值: `{}`

- 详情:

覆盖组件 [options](#options) Prop 的默认值。
覆盖组件 [propsOptions](#propsoptions-1) Prop 的默认值。

## 组件 Props

Expand Down Expand Up @@ -100,7 +110,21 @@ interface PageHeader {

如果该 Prop 没有被设置,默认会使用当前页面的标题。

### options
### headerOptions

- 类型: `Partial<GetHeadersOptions>`

详见 [GetHeadersOptions](../../tools/helper/client.md#getheaders)

- 默认值:

详见 [GetHeadersOptions](../../tools/helper/client.md#getheaders),可以通过插件选项中的 [headerOptions](#headeroptions) 来覆盖。

- 详情:

覆盖 [getHeaders](../../tools/helper/client.md#getheaders) 函数的默认值。

### propsOptions

- 类型: `Partial<TocPropsOptions>`

Expand All @@ -119,7 +143,7 @@ interface TocPropsOptions {

- 默认值:

下列默认值可以用过 [defaultPropsOptions](#defaultpropsoptions) 来覆盖:
下列默认值可以用过插件选项中的 [propsOptions](#propsoptions) 来覆盖:

```ts
const defaultOptions = {
Expand All @@ -136,7 +160,7 @@ const defaultOptions = {

- 详情:

自定义目录组件
自定义目录组件渲染行为

如果 `containerTag` 设置为空字符串 `''` ,那么最外层的 `<nav>` Container 会被完全移除。

Expand Down
1 change: 1 addition & 0 deletions plugins/development/plugin-toc/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"clean": "rimraf --glob ./lib ./*.tsbuildinfo"
},
"dependencies": {
"@vuepress/helper": "workspace:*",
"vue": "^3.5.13",
"vue-router": "^4.5.0"
},
Expand Down
43 changes: 27 additions & 16 deletions plugins/development/plugin-toc/src/client/components/Toc.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
import type { GetHeadersOptions } from '@vuepress/helper/client'
import { useHeaders } from '@vuepress/helper/client'
import type { PropType, VNode } from 'vue'
import { computed, defineComponent, h, toRefs } from 'vue'
import type { RouteLocationNormalizedLoaded } from 'vue-router'
import { RouterLink } from 'vue-router'
import type { PageHeader } from 'vuepress/client'
import { RouteLink, usePageData, useRoute } from 'vuepress/client'
import { RouteLink, useRoute } from 'vuepress/client'
import type { TocPropsOptions } from '../../shared/index.js'

export type TocPropsHeaders = PageHeader[]

export interface TocProps {
headers: TocPropsHeaders
options: TocPropsOptions
headersOptions: GetHeadersOptions
propsOptions: TocPropsOptions
}

const renderLink = (
Expand Down Expand Up @@ -104,24 +107,28 @@ export const Toc = defineComponent({
name: 'Toc',

props: {
headers: Array as PropType<TocPropsHeaders | undefined>,

options: Object as PropType<Partial<TocPropsOptions>>,
/**
* Headers to render the table of contents
*/
headers: Array as PropType<TocPropsHeaders>,

/**
* Get headers options
*/
headersOptions: Object as PropType<GetHeadersOptions>,

/**
* TOC prop options
*/
propsOptions: Object as PropType<Partial<TocPropsOptions>>,
},

setup(props) {
const { headers: propsHeaders, options: propsOptions } = toRefs(props)
const { headers, headersOptions, propsOptions } = toRefs(props)

const pageHeaders = useHeaders(headersOptions)
const route = useRoute()
const page = usePageData()
const headers = computed<TocPropsHeaders>(() => {
const headersToUse = propsHeaders.value ?? page.value.headers

// skip h1 header
return headersToUse[0]?.level === 1
? headersToUse[0].children
: headersToUse
})

const options = computed<TocPropsOptions>(() => ({
containerTag: 'nav',
containerClass: 'vuepress-toc',
Expand All @@ -135,7 +142,11 @@ export const Toc = defineComponent({
}))

return () => {
const renderedHeaders = renderHeaders(headers.value, options.value, route)
const renderedHeaders = renderHeaders(
headers.value ?? pageHeaders.value,
options.value,
route,
)

if (options.value.containerTag) {
return h(
Expand Down
16 changes: 10 additions & 6 deletions plugins/development/plugin-toc/src/client/config.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,27 @@
import type { GetHeadersOptions } from '@vuepress/helper/client'
import { h } from 'vue'
import { defineClientConfig } from 'vuepress/client'
import type { TocPropsOptions } from '../shared/index.js'
import type { TocProps } from './components/Toc.js'
import { Toc } from './components/Toc.js'

declare const __TOC_COMPONENT_NAME__: string
declare const __TOC_DEFAULT_PROPS_OPTIONS__: TocPropsOptions

const defaultPropsOptions = __TOC_DEFAULT_PROPS_OPTIONS__
declare const __TOC_HEADERS_OPTIONS__: GetHeadersOptions
declare const __TOC_PROPS_OPTIONS__: TocPropsOptions

export default defineClientConfig({
enhance({ app }) {
// wrap the toc component with default options
app.component(__TOC_COMPONENT_NAME__, (props: TocProps) =>
h(Toc, {
headers: props.headers,
options: {
...defaultPropsOptions,
...props.options,
headersOptions: {
...__TOC_HEADERS_OPTIONS__,
...props.headersOptions,
},
propsOptions: {
...__TOC_PROPS_OPTIONS__,
...props.propsOptions,
},
}),
)
Expand Down
1 change: 1 addition & 0 deletions plugins/development/plugin-toc/src/node/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export type * from './options.js'
export * from './tocPlugin.js'
export type * from '../shared/index.js'
30 changes: 30 additions & 0 deletions plugins/development/plugin-toc/src/node/options.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import type { GetHeadersOptions } from '@vuepress/helper'
import type { TocPropsOptions } from '../shared/index.js'

/**
* Options for @vuepress/plugin-toc
*/
export interface TocPluginOptions {
/**
* Specify the name of the TOC component
*
* @default 'Toc'
*/
componentName?: string

/**
* Default header options
*/
headerOptions?: GetHeadersOptions

/**
* Default props options
*/
propsOptions?: Partial<TocPropsOptions>

// FIXME: Remove in stable
/**
* @deprecated use `propsOptions` instead
*/
defaultPropsOptions?: Partial<TocPropsOptions>
}
25 changes: 6 additions & 19 deletions plugins/development/plugin-toc/src/node/tocPlugin.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,23 @@
import type { Plugin } from 'vuepress/core'
import { getDirname, path } from 'vuepress/utils'
import type { TocPropsOptions } from '../shared/index.js'
import type { TocPluginOptions } from './options.js'

const __dirname = import.meta.dirname || getDirname(import.meta.url)

/**
* Options for @vuepress/plugin-toc
*/
export interface TocPluginOptions {
/**
* Specify the name of the TOC component
*
* @default 'Toc'
*/
componentName?: string

/**
* Override the default values of the `options` prop of the TOC component
*/
defaultPropsOptions?: Partial<TocPropsOptions>
}

export const tocPlugin = ({
componentName = 'Toc',
headerOptions = {},
// eslint-disable-next-line @typescript-eslint/no-deprecated
defaultPropsOptions = {},
propsOptions = defaultPropsOptions,
}: TocPluginOptions = {}): Plugin => ({
name: '@vuepress/plugin-toc',

clientConfigFile: path.resolve(__dirname, '../client/config.js'),

define: {
__TOC_COMPONENT_NAME__: componentName,
__TOC_DEFAULT_PROPS_OPTIONS__: defaultPropsOptions,
__TOC_HEADERS_OPTIONS__: headerOptions,
__TOC_PROPS_OPTIONS__: propsOptions,
},
})
3 changes: 3 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@ const unsetHeight = (item: Element): void => {
&-enter-from,
&-leave-to {
height: 0 !important;
opacity: 0;
}

&-enter-active {
transition:
height 0.3s ease-in-out,
opacity 0.6s ease-out;
}
}
</style>
Loading
Loading