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(plugin-git): add built-in component <Contributors/> <Changelog/>, close #375 #384

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 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
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion docs/.vuepress/theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const IS_PROD = process.env.NODE_ENV === 'production'

export default defaultTheme({
logo: '/images/hero.png',
repo: 'vuepress/ecosystem',
repo: 'https://github.com/vuepress/ecosystem',
docsDir: 'docs',
hostname: 'https://ecosystem.vuejs.press',

Expand Down
85 changes: 85 additions & 0 deletions docs/plugins/development/git.md
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,39 @@ This plugin will significantly slow down the speed of data preparation, especial

Page filter, if it returns `true`, the page will collect git information.

### locales

- Type: `Record<string, GitLocaleData>`

```ts
export interface GitLocaleData extends LocaleData {
/**
* Contributors title
*/
contributors: string
/**
* Changelog title
*/
changelog: string
/**
* Changelog on time
*/
changelogOn: string
/**
* Changelog button
*/
changelogButton: string
Comment on lines +209 to +216
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think these names are proper. I do not know what should I fill in another language at a glance at all.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also don't know what would be a more appropriate name, please help me change the field name.

/**
* Latest updated
*/
latestUpdated: string
}
```

- Details:

Locales configuration, used in the [Git Component](#component).

## Frontmatter

### gitInclude
Expand Down Expand Up @@ -343,3 +376,55 @@ interface GitChangelog {
The changelog of the page.

This attribute would also include contributors to the files listed in [gitInclude](#gitinclude).

## Git Component{#component}

The plugin provides components related to Git information, which can be used in themes.

The components are imported as follows:

```ts
import { Changelog, Contributors } from '@vuepress/plugin-git/client'
```

### Contributors

List the contributor information for the current page.

```vue{8}
<script setup>
import { Contributors } from '@vuepress/plugin-git/client'
</script>
<template>
<div vp-content>
<Content />
<Contributors />
</div>
</template>
```

**Effect Preview:**

![contributors](/images/git/contributor-en.png)

### Changelog

List the changelog of the current page.

```vue{8}
<script setup>
import { Changelog } from '@vuepress/plugin-git/client'
</script>
<template>
<div vp-content>
<Content />
<Changelog />
</div>
</template>
```

**Effect Preview:**

![changelog](/images/git/changelog-en.png)
85 changes: 85 additions & 0 deletions docs/zh/plugins/development/git.md
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,39 @@ export default {

页面过滤器,如果返回 `true` ,该页面将收集 git 信息

### locales

- 类型: `Record<string, GitLocaleData>`

```ts
export interface GitLocaleData extends LocaleData {
/**
* 贡献者 标题
*/
contributors: string
/**
* 更新日志 标题
*/
changelog: string
/**
* 更新 `于` 文本
*/
changelogOn: string
/**
* 查看更新日志 文本
*/
changelogButton: string
/**
* 最近更新 文本
*/
latestUpdated: string
}
```

- 详情:

多语言配置,在 [Git 组件](#component) 中使用。

## Frontmatter

### gitInclude
Expand Down Expand Up @@ -335,3 +368,55 @@ interface GitChangelog {
页面的变更历史记录。

该属性将会包含 [gitInclude](#gitinclude) 所列文件的变更历史记录。

## Git 组件{#component}

插件提供了与 Git 信息相关的组件,可以在主题中使用。

组件通过以下方式导入:

```ts
import { Changelog, Contributors } from '@vuepress/plugin-git/client'
```

### Contributors

列出当前页面的贡献者信息。

```vue{8}
<script setup>
import { Contributors } from '@vuepress/plugin-git/client'
</script>

<template>
<div vp-content>
<Content />
<Contributors />
</div>
</template>
```

**效果预览:**

![contributors](/images/git/contributor-zh.png)

### Changelog

列出当前页面的变更历史记录。

```vue{8}
<script setup>
import { Changelog } from '@vuepress/plugin-git/client'
</script>

<template>
<div vp-content>
<Content />
<Changelog />
</div>
</template>
```

**效果预览:**

![changelog](/images/git/changelog-zh.png)
8 changes: 6 additions & 2 deletions plugins/development/plugin-git/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"type": "module",
"exports": {
".": "./lib/node/index.js",
"./client": "./lib/client/index.js",
"./package.json": "./package.json"
},
"main": "./lib/node/index.js",
Expand All @@ -32,10 +33,13 @@
"scripts": {
"build": "tsc -b tsconfig.build.json",
"bundle": "rollup -c rollup.config.ts --configPlugin esbuild",
"clean": "rimraf --glob ./lib ./*.tsbuildinfo"
"clean": "rimraf --glob ./lib ./*.tsbuildinfo",
"style": "sass src:lib --embed-sources --style=compressed --pkg-importer=node"
},
"dependencies": {
"execa": "^9.5.2"
"@vuepress/helper": "workspace:*",
"execa": "^9.5.2",
"vue": "^3.5.13"
},
"peerDependencies": {
"vuepress": "catalog:"
Expand Down
9 changes: 6 additions & 3 deletions plugins/development/plugin-git/rollup.config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { rollupBundle } from '../../../scripts/rollup.js'

export default rollupBundle('node/index', {
external: ['execa'],
})
export default [
...rollupBundle('node/index', {
external: ['execa'],
}),
...rollupBundle('client/index'),
]
139 changes: 139 additions & 0 deletions plugins/development/plugin-git/src/client/components/Changelog.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
import type { VNode } from 'vue'
import { computed, defineComponent, h, ref } from 'vue'
import { usePageData, usePageFrontmatter, usePageLang } from 'vuepress/client'
import type {
GitChangelog,
GitPluginFrontmatter,
GitPluginPageData,
} from '../../shared/index.js'
import { useGitLocales } from '../composables/index.js'
import { VPHeader } from './VPHeader.js'

import '../styles/vars.css'
import '../styles/changelog.css'

type ResolvedChangelog = Omit<GitChangelog, 'date'> & { datetime: string }

export const Changelog = defineComponent({
name: 'Changelog',
props: {
headerLevel: {
type: Number,
default: 2,
},
title: {
type: String,
default: '',
},
},
setup(props) {
const page = usePageData<GitPluginPageData>()
const lang = usePageLang()
const frontmatter = usePageFrontmatter<GitPluginFrontmatter>()
const locale = useGitLocales()

const list = computed<ResolvedChangelog[]>(() => {
if (frontmatter.value.changelog === false) return []

const formatter = new Intl.DateTimeFormat(lang.value, {
dateStyle: 'short',
})
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
return (page.value.git?.changelog ?? []).map(({ date, ...item }) => {
const datetime = formatter.format(date)
return { datetime, ...item }
})
})

const latestUpdated = computed(() => {
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
const latest = (page.value.git?.changelog ?? [])[0]

// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (!latest) return ''

const formatter = new Intl.DateTimeFormat(lang.value, {
dateStyle: 'short',
timeStyle: 'short',
})
return formatter.format(latest.date)
})

const active = ref(false)

const toggle = (): void => {
active.value = !active.value
}

const ChangelogHeader = (): VNode =>
h('div', { class: 'changelog-header', onClick: toggle }, [
h('div', { class: 'latest-updated' }, [
h('span', { class: 'vpi-changelog' }),
h('span', [locale.value.latestUpdated || 'Latest updated:', ' ']),
h('span', { 'data-allow-mismatch': true }, latestUpdated.value),
]),
h('div', [
h('span', { class: 'vpi-changelog-menu' }),
h('span', locale.value.changelogButton || 'View All Changelog'),
]),
])

const ReleaseTag = ({ item }: { item: ResolvedChangelog }): VNode =>
h(
'li',
{ class: 'changelog release-tag' },
h('div', [
h('a', { class: 'link release-tag' }, h('code', item.tag)),
h('span', { 'class': 'datetime', 'data-allow-mismatch': true }, [
locale.value.changelogOn || 'on',
' ',
item.datetime,
]),
]),
)

const Commit = ({ item }: { item: ResolvedChangelog }): VNode =>
h('li', { class: 'changelog commit' }, [
h(
item.commitUrl ? 'a' : 'span',
{
class: 'link hash',
href: item.commitUrl,
target: '_blank',
rel: 'noreferrer',
},
[h('code', item.hash.slice(0, 5))],
),
h('span', { class: 'divider' }, '-'),
h('span', { class: 'message', innerHTML: item.message }),
h('span', { 'class': 'datetime', 'data-allow-mismatch': true }, [
locale.value.changelogOn || 'on',
' ',
item.datetime,
]),
])

return () =>
list.value.length
? [
h(VPHeader, {
level: props.headerLevel,
anchor: 'doc-changelog',
title: props.title || locale.value.changelog || 'Changelog',
}),

h('div', { class: ['vp-changelog', { active: active.value }] }, [
h(ChangelogHeader),

h('ul', { class: 'changelog-list' }, [
list.value.map((item) =>
item.tag
? h(ReleaseTag, { item, key: item.tag })
: h(Commit, { item, key: item.hash }),
),
]),
]),
]
: null
},
})
Loading
Loading