Skip to content

Commit

Permalink
feat(theme-default)!: rename auto to heading in sidebar and impro…
Browse files Browse the repository at this point in the history
…ve layout types (#186)
  • Loading branch information
Mister-Hope committed May 31, 2024
1 parent 45a5afb commit ae1f93c
Show file tree
Hide file tree
Showing 26 changed files with 284 additions and 144 deletions.
16 changes: 8 additions & 8 deletions docs/themes/default/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ Config of this section can be used as normal config, and can also be used in the

### navbar

- Type: `false | (NavbarItem | NavbarGroup | string)[]`
- Type: `false | NavbarOptions`

- Default: `[]`

Expand All @@ -99,19 +99,19 @@ Config of this section can be used as normal config, and can also be used in the

Set to `false` to disable navbar.

To configure the navbar items, you can set it to a _navbar array_, each item of which could be a `NavbarItem` object, a `NavbarGroup` object, or a string:
To configure the navbar items, you can set it to a _navbar array_, each item of which could be a `NavbarLink` object, a `NavbarGroup` object, or a string:

- A `NavbarItem` object should have a `text` field and a `link` field, could have an optional `activeMatch` field.
- A `NavbarLink` object should have a `text` field and a `link` field, could have an optional `activeMatch` field.
- A `NavbarGroup` object should have a `text` field and a `children` field, could have an optional `prefix` field. The `children` field should be a _navbar array_ too, and `prefix` will be prepended before every link inside it.
- A string should be the path to the target page file. It will be converted to a `NavbarItem` object, using the page title as `text`, and the page route path as `link`.
- A string should be the path to the target page file. It will be converted to a `NavbarLink` object, using the page title as `text`, and the page route path as `link`.

- Example 1:

```ts
export default {
theme: defaultTheme({
navbar: [
// NavbarItem
// NavbarLink
{
text: 'Foo',
link: '/foo/',
Expand Down Expand Up @@ -269,9 +269,9 @@ export default {

### sidebar

- Type: `false | 'auto' | SidebarConfigArray | SidebarConfigObject`
- Type: `false | SidebarOptions`

- Default: `'auto'`
- Default: `'heading'`

- Details:

Expand All @@ -281,7 +281,7 @@ export default {

Set to `false` to disable sidebar.

If you set it to `'auto'`, the sidebar will be automatically generated from the page headers.
If you set it to `'heading'`, the sidebar will be automatically generated from the page headers.

To configure the sidebar items manually, you can set this option to a _sidebar array_, each item of which could be a `SidebarItem` object or a string:

Expand Down
2 changes: 1 addition & 1 deletion docs/themes/default/frontmatter.md
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ Frontmatter in this section will only take effect in normal pages.

### sidebar

- Type: `false | 'auto' | SidebarConfigArray | SidebarConfigObject`
- Type: `false | SidebarOptions`

- Details:

Expand Down
16 changes: 8 additions & 8 deletions docs/zh/themes/default/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@

### navbar

- 类型: `false | (NavbarItem | NavbarGroup | string)[]`
- 类型: `false | NavbarOptions`

- 默认值: `[]`

Expand All @@ -99,19 +99,19 @@

设置为 `false` 可以禁用导航栏。

为了配置导航栏元素,你可以将其设置为 _导航栏数组_ ,其中的每个元素是 `NavbarItem` 对象、 `NavbarGroup` 对象、或者字符串:
为了配置导航栏元素,你可以将其设置为 _导航栏数组_ ,其中的每个元素是 `NavbarLink` 对象、 `NavbarGroup` 对象、或者字符串:

- `NavbarItem` 对象应该有一个 `text` 字段和一个 `link` 字段,还有一个可选的 `activeMatch` 字段。
- `NavbarLink` 对象应该有一个 `text` 字段和一个 `link` 字段,还有一个可选的 `activeMatch` 字段。
- `NavbarGroup` 对象应该有一个 `text` 字段和一个 `children` 字段,还有一个可选的 `prefix` 字段。 `children` 字段同样是一个 _导航栏数组_,而 `prefix` 会作为 _导航栏数组_ 的路径前缀。
- 字符串应为目标页面文件的路径。它将会被转换为 `NavbarItem` 对象,将页面标题作为 `text` ,将页面路由路径作为 `link`
- 字符串应为目标页面文件的路径。它将会被转换为 `NavbarLink` 对象,将页面标题作为 `text` ,将页面路由路径作为 `link`

- 示例 1:

```ts
export default {
theme: defaultTheme({
navbar: [
// NavbarItem
// NavbarLink
{
text: 'Foo',
link: '/foo/',
Expand Down Expand Up @@ -270,9 +270,9 @@ export default {

### sidebar

- 类型: `false | 'auto' | SidebarConfigArray | SidebarConfigObject`
- 类型: `false | SidebarOptions`

- 默认值: `'auto'`
- 默认值: `'heading'`

- 详情:

Expand All @@ -282,7 +282,7 @@ export default {

设置为 `false` 可以禁用侧边栏。

如果你设置为 `'auto'`,侧边栏会根据页面标题自动生成。
如果你设置为 `'heading'`,侧边栏会根据页面标题自动生成。

为了手动配置侧边栏元素,你可以将其设置为 _侧边栏数组_ ,其中的每个元素是一个 `SidebarItem` 对象或者一个字符串:

Expand Down
2 changes: 1 addition & 1 deletion docs/zh/themes/default/frontmatter.md
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ features:

### sidebar

- 类型: `false | 'auto' | SidebarConfigArray | SidebarConfigObject`
- 类型: `false | SidebarOptions`

- 详情:

Expand Down
11 changes: 11 additions & 0 deletions e2e/docs/sidebar/frontmatter/config.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
sidebar:
- /
- /zh/
---

# Sidebar

## Sidebar Heading 1

## Sidebar Heading 2
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
sidebar: auto
sidebar: false
---

# Sidebar
Expand Down
9 changes: 9 additions & 0 deletions e2e/docs/sidebar/frontmatter/heading.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
sidebar: heading
---

# Sidebar

## Sidebar Heading 1

## Sidebar Heading 2
29 changes: 24 additions & 5 deletions e2e/tests/theme-default/sidebar.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { expect, test } from '@playwright/test'

test.describe('has heading sidebar', () => {
test('frontmatter', async ({ page }) => {
await page.goto('sidebar/auto.html')
await page.goto('sidebar/frontmatter/heading.html')

const sidebarItems = page.locator('a.sidebar-item')

Expand Down Expand Up @@ -30,11 +30,30 @@ test.describe('has heading sidebar', () => {
})
})

test('has configured sidebar', async ({ page }) => {
await page.goto('sidebar/config/1.html')
test.describe('has configured sidebar', () => {
test('theme config', async ({ page }) => {
await page.goto('sidebar/config/1.html')

const sidebarItems = page.locator('a.sidebar-item')

await expect(sidebarItems.nth(1)).toContainText('sidebar 1')
await expect(sidebarItems.nth(4)).toContainText('sidebar 2')
})

test('frontmatter', async ({ page }) => {
await page.goto('sidebar/frontmatter/config.html')

const sidebarItems = page.locator('a.sidebar-item')

await expect(sidebarItems.nth(0)).toContainText('Home')
await expect(sidebarItems.nth(1)).toContainText('主页')
})
})

test('frontmatter disable', async ({ page }) => {
await page.goto('sidebar/frontmatter/disable.html')

const sidebarItems = page.locator('a.sidebar-item')

await expect(sidebarItems.nth(1)).toContainText('sidebar 1')
await expect(sidebarItems.nth(4)).toContainText('sidebar 2')
expect(await sidebarItems.count()).toBe(0)
})
8 changes: 5 additions & 3 deletions themes/theme-default/src/client/components/NavbarDropdown.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ import DropdownTransition from '@theme/DropdownTransition.vue'
import { computed, ref, toRefs, watch } from 'vue'
import type { PropType } from 'vue'
import { AutoLink, useRoute } from 'vuepress/client'
import type { NavbarItem, ResolvedNavbarItem } from '../../shared/index.js'
import type { AutoLinkOptions, NavGroup } from '../../shared/index.js'
const props = defineProps({
item: {
type: Object as PropType<Exclude<ResolvedNavbarItem, NavbarItem>>,
type: Object as PropType<
NavGroup<AutoLinkOptions | NavGroup<AutoLinkOptions>>
>,
required: true,
},
})
Expand Down Expand Up @@ -77,7 +79,7 @@ const isLastItemOfArray = (item: unknown, arr: unknown[]): boolean =>
:key="child.text"
class="navbar-dropdown-item"
>
<template v-if="child.children">
<template v-if="'children' in child">
<h4 class="navbar-dropdown-subtitle">
<AutoLink
v-if="child.link"
Expand Down
10 changes: 4 additions & 6 deletions themes/theme-default/src/client/components/PageNav.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,13 @@ import {
} from 'vuepress/client'
import type { AutoLinkConfig } from 'vuepress/client'
import { isPlainObject, isString } from 'vuepress/shared'
import type {
DefaultThemeNormalPageFrontmatter,
ResolvedSidebarItem,
} from '../../shared/index.js'
import type { DefaultThemeNormalPageFrontmatter } from '../../shared/index.js'
import {
useNavigate,
useSidebarItems,
useThemeLocaleData,
} from '../composables/index.js'
import type { SidebarItem } from '../typings.js'
/**
* Resolve `prev` or `next` config from frontmatter
Expand Down Expand Up @@ -57,7 +55,7 @@ const resolveFromFrontmatterConfig = (
* Resolve `prev` or `next` config from sidebar items
*/
const resolveFromSidebarItems = (
sidebarItems: ResolvedSidebarItem[],
sidebarItems: SidebarItem[],
currentPath: string,
offset: number,
): null | AutoLinkConfig => {
Expand All @@ -71,7 +69,7 @@ const resolveFromSidebarItems = (
}
for (const item of sidebarItems) {
if (item.children) {
if ('children' in item) {
const childResult = resolveFromSidebarItems(
item.children,
currentPath,
Expand Down
21 changes: 12 additions & 9 deletions themes/theme-default/src/client/components/SidebarItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ import { useToggle } from '@vueuse/core'
import { computed, nextTick, onBeforeUnmount, toRefs } from 'vue'
import type { PropType } from 'vue'
import { AutoLink, useRoute, useRouter } from 'vuepress/client'
import type { ResolvedSidebarItem } from '../../shared/index.js'
import { isActiveSidebarItem } from '../utils/index.js'
import type { SidebarItem } from '../typings.js'
import { isActiveLinkItem } from '../utils/index.js'
const props = defineProps({
item: {
type: Object as PropType<ResolvedSidebarItem>,
type: Object as PropType<SidebarItem>,
required: true,
},
depth: {
Expand All @@ -23,20 +23,23 @@ const { item, depth } = toRefs(props)
const route = useRoute()
const router = useRouter()
const isActive = computed(() => isActiveSidebarItem(item.value, route))
const collapsible = computed(
() => 'collapsible' in item.value && item.value.collapsible,
)
const isActive = computed(() => isActiveLinkItem(item.value, route))
const itemClass = computed(() => ({
'sidebar-item': true,
'sidebar-heading': depth.value === 0,
'active': isActive.value,
'collapsible': item.value.collapsible,
'collapsible': collapsible.value,
}))
const isOpenDefault = computed(() =>
item.value.collapsible ? isActive.value : true,
collapsible.value ? isActive.value : true,
)
const [isOpen, toggleIsOpen] = useToggle(isOpenDefault.value)
const onClick = (e: Event): void => {
if (item.value.collapsible) {
if (collapsible.value) {
e.preventDefault()
// toggle open status on click
toggleIsOpen()
Expand Down Expand Up @@ -66,13 +69,13 @@ onBeforeUnmount(() => {
>
{{ item.text }}
<span
v-if="item.collapsible"
v-if="collapsible"
class="arrow"
:class="isOpen ? 'down' : 'right'"
/>
</p>

<DropdownTransition v-if="item.children?.length">
<DropdownTransition v-if="'children' in item && item.children.length">
<ul v-show="isOpen" class="sidebar-item-children">
<SidebarItem
v-for="child in item.children"
Expand Down
23 changes: 14 additions & 9 deletions themes/theme-default/src/client/composables/useNavbarConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,31 @@ import { computed } from 'vue'
import type { ComputedRef } from 'vue'
import { isString } from 'vuepress/shared'
import type {
NavbarGroup,
NavbarItem,
ResolvedNavbarItem,
} from '../../shared/index.js'
NavbarGroupOptions,
NavbarLinkOptions,
NavGroup,
} from '../../shared/navbar.js'
import type { NavbarItem } from '../typings.js'
import { getAutoLink, isLinkInternal, resolvePrefix } from '../utils/index.js'
import { useThemeLocaleData } from './useThemeData.js'

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

if ('children' in item) {
return {
...item,
children: item.children.map((child) =>
resolveNavbarItem(child, resolvePrefix(prefix, item.prefix)),
children: item.children.map(
(child) =>
resolveNavbarItem(
child,
resolvePrefix(prefix, item.prefix),
) as NavGroup<NavbarLinkOptions>,
),
}
}
Expand All @@ -34,7 +39,7 @@ const resolveNavbarItem = (
}
}

export const useNavbarConfig = (): ComputedRef<ResolvedNavbarItem[]> => {
export const useNavbarConfig = (): ComputedRef<NavbarItem[]> => {
const themeLocale = useThemeLocaleData()

return computed(() =>
Expand Down
4 changes: 2 additions & 2 deletions themes/theme-default/src/client/composables/useNavbarRepo.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { computed } from 'vue'
import type { ComputedRef } from 'vue'
import { isLinkHttp } from 'vuepress/shared'
import type { ResolvedNavbarItem } from '../../shared/index.js'
import type { NavbarItem } from '../typings.js'
import { resolveRepoType } from '../utils/index.js'
import { useThemeLocaleData } from './useThemeData.js'

/**
* Get navbar config of repository link
*/
export const useNavbarRepo = (): ComputedRef<ResolvedNavbarItem[]> => {
export const useNavbarRepo = (): ComputedRef<NavbarItem[]> => {
const themeLocale = useThemeLocaleData()

const repo = computed(() => themeLocale.value.repo)
Expand Down
Loading

0 comments on commit ae1f93c

Please sign in to comment.