feat: add support optional icon for file-tree and code-tabs (#216)

* feat(theme)!: migrate `plugin-markdown-hint`

* chore: tweak

* chore: tweak

* chore: tweak

* chore: tweak

* chore: tweak

* chore: tweak

* chore: tweak

* chore: tweak

* chore: tweak

* chore: tweak

* fix(theme): improve `home-blog` styles in mobile, close #210

* chore: tweak

* chore: tweak

* chore: tweak

* feat: add support optional icon for `file-tree` and `code-tabs`

* chore: tweak

* chore: tweak

* chore: tweak

* chore: tweak
This commit is contained in:
pengzhanbo 2024-09-26 00:14:06 +08:00 committed by GitHub
parent 49672724eb
commit ca21d1b8cb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
28 changed files with 509 additions and 94 deletions

View File

@ -38,6 +38,8 @@ export const themeConfig = defineNoteConfig({
'阅读统计',
'markdown增强',
'markdownPower',
'markdownImage',
'markdownMath',
'水印',
],
},

View File

@ -20,10 +20,8 @@ export const theme: Theme = plumeTheme({
imageSize: 'all',
pdf: true,
caniuse: true,
plot: true,
bilibili: true,
youtube: true,
icons: true,
codepen: true,
replit: true,
codeSandbox: true,

View File

@ -6,7 +6,6 @@ permalink: /article/enx7c9s/
tags:
- 预览
- 标签
sticky: true
---
这是一篇 示例文章。

View File

@ -0,0 +1,72 @@
---
title: 1.0.0-rc.102 至 rc.103 更新说明
createTime: 2024/09/24 23:45:49
permalink: /article/6pa64b1n/
sticky: 3
---
这两个版本做了一些 破坏性的更新,主要围绕以下两个方面:
- 适配 [Vuepress Guidelines](https://ecosystem.vuejs.press/zh/themes/guidelines.html)
- 更新 vuepress-plugin-md-enhance 插件,并迁移其中的部分功能,改用 VuePress 官方插件
## 适配 VuePress Guidelines
VuePress 推出了 [主题开发指南](https://ecosystem.vuejs.press/zh/themes/guidelines.html)。
这一举措旨在规范化主题开发流程,并提出了主题开发过程中需要遵守的几个约定,这包括:
- 约定 CSS 变量命名规范,并约束 主要 CSS 变量的命名,如 `--vp-c-accent``--vp-c-text` 等。
- 约定 主要的 HTML 元素容器应添加指定的 属性名,如 `vp-content`, `vp-navbar` 等。
- 约定 双主题模式应使用 `[data-theme="light"]``[data-theme="dark"]` 来区分。
围绕这几个约定,可以使得 VuePress 的 开发者们,可以很方便的 开发出 更具通用性的 主题和插件。
`plume` 主题也同样适配了这些约定:
- **CSS 变量命名的变更****HTML 元素添加属性**,对于用户是无感知的,您无需关注这方面是否会有影响。
- **双主题模式**,对于有自定义主题需求的用户而言,如果您有重新定义深色模式下的样式,则需要做出一些调整:
在 CSS 中的 `.dark` 类应替换为 `[data-theme="dark"]`,请不用担心替换会带来额外的副作用,它们在 CSS 中的
优先级是相同的,您可以安全的执行替换操作。
## vuepress-plugin-md-enhance 插件迁移
[vuepress-plugin-md-enhance](https://plugin-md-enhance.vuejs.press/zh/) 提供了非常多的功能支持,但与之带来的困难是,
它变得越来越臃肿,变得难以维护了。
我在 [#4130](https://github.com/vuepress-theme-hope/vuepress-theme-hope/issues/4130) 中提出了拆分迁移的计划。
因此从 `@2.0.0-rc.53` 版本开始,逐步开始拆分迁移的计划。
截止到 `@2.0.0-rc.54` 版本,已经拆分出了以下插件:
- [@vuepress/plugin-markdown-hint](https://ecosystem.vuejs.press/zh/plugins/markdown/markdown-hint.html)
- [@vuepress/plugin-markdown-image](https://ecosystem.vuejs.press/zh/plugins/markdown/markdown-image.html)
- [@vuepress/plugin-markdown-math](https://ecosystem.vuejs.press/zh/plugins/markdown/markdown-math.html)
- [@vuepress/plugin-markdown-tab](https://ecosystem.vuejs.press/zh/plugins/markdown/markdown-tab.html)
当前主题也将 vuepress-plugin-md-enhance 更新到 `@2.0.0-rc.54` 版本,因此,也重新接入了上述的插件。
- `@vuepress/plugin-markdown-hint` 提供了 提示容器 和 `github alerts` 支持,主题已内置了该插件,对于该插件的迁移,
用户是无需做任何修改的,您可以继续使用这些功能。
- `@vuepress/plugin-markdown-image` 提供了图片支持,主题已内置了该插件,但不启用该插件的默认功能,
因此,如果您使用了如 `plugins.mdEnhance.imgSize` 配置项,您需要通过`plugins.markdownImage` 重新进行配置。
- `@vuepress/plugin-markdown-math` 提供了数学公式支持,主题已内置了该插件,并默认启用了 `katex` 支持。
- `@vuepress/plugin-markdown-tab` 提供了 Tab 容器 和 代码分组支持,主题重写了插件部分内容,对 `code-tabs` 容器
做了一些调整,支持在 代码分组标题中显示 相关联的图标。
## 其它更新
- **文件树** 现在支持 不同的图标方案,可在 `:::file-tree` 后跟随 `:simple-icon` / `:colored-icon` 切换。
默认为 colored-icon如果切换为 simple-icon则不再根据 文件夹名和文件扩展名匹配不同的图标,仅显示默认的
文件夹图标和文件图标。
- **代码块分组** 的标题现在支持显示 图标。当作为 文件名时,与 **文件树** 采用相同的图标解析规则,还额外支持
不同的技术、框架、语言的名称图标。
- 优化了 容器、任务列表、脚注、等的样式。

View File

@ -1,9 +1,7 @@
---
title: 1.0.0-rc.73 至 rc.77 更新说明
author: pengzhanbo
createTime: 2024/07/11 09:18:48
permalink: /article/5vjshyi9/
sticky: 3
---
近期的这几个版本主要围绕 **实现单独的主题配置文件** ,监听并支持热更新。

View File

@ -0,0 +1,40 @@
---
title: Markdown Image
createTime: 2024/09/24 12:06:28
permalink: /config/plugins/markdown-image/
---
## 概述
为 Markdown 图像添加附加功能。
关联插件:[@vuepress/plugin-markdown-image](https://ecosystem.vuejs.press/zh/plugins/markdown/markdown-image.html)
## 配置
插件默认不启用任何功能,你需要手动开启它们。
```ts
import { defineUserConfig } from 'vuepress'
import { plumeTheme } from 'vuepress-theme-plume'
export default defineUserConfig({
theme: plumeTheme({
plugins: {
markdownImage: {
// 启用 figure
// figure: true,
// 启用图片懒加载
// lazyload: true,
// 启用图片标记
// mark: true,
// 启用图片大小
// size: true,
}
}
}),
})
```

View File

@ -0,0 +1,32 @@
---
title: Markdown Math
createTime: 2024/09/24 13:20:41
permalink: /config/plugins/markdown-math/
---
## 概述
为 Markdown 添加数学支持。
关联插件:[@vuepress/plugin-markdown-math](https://ecosystem.vuejs.press/zh/plugins/markdown/markdown-math.html)
此插件允许你使用 mathjax 或 katex 在 Markdown 中渲染 $\TeX$ 内容。
## 配置
插件默认启用 `katex`
```ts
import { defineUserConfig } from 'vuepress'
import { plumeTheme } from 'vuepress-theme-plume'
export default defineUserConfig({
theme: plumeTheme({
plugins: {
markdownMath: {
type: 'katex',
}
}
}),
})
```

View File

@ -1,13 +1,12 @@
---
title: Markdown Power
author: pengzhanbo
createTime: 2024/04/04 06:56:33
permalink: /config/plugin/markdown-power/
permalink: /config/plugins/markdown-power/
---
## 概述
提供 Markdown 增强功能。
为 主题 提供 Markdown 增强功能。
关联插件: [@vuepress-plume/plugin-md-power](https://github.com/pengzhanbo/vuepress-theme-plume/tree/main/plugins/plugin-md-power)
@ -23,9 +22,12 @@ export default defineUserConfig({
theme: plumeTheme({
plugins: {
markdownPower: {
// 默认不启用任何功能,你需要手动开启它们
fileTree: true, // :::file-tree 文件树容器
plot: true, // !!plot!! 隐秘文本
icons: true, // :[collect:name]: 内联 iconify 图标
// 默认不启用以下功能,你需要手动开启它们
// pdf: true, // @[pdf](url) 嵌入 PDF 文件
// icons: true, // :[collect:name]: 内联 iconify 图标
// bilibili: true, // @[bilibili](bvid) 嵌入 bilibili 视频
// youtube: true, // @[youtube](id) 嵌入 youtube 视频
// codepen: true, // @[codepen](user/slash) 嵌入 codepen
@ -34,8 +36,6 @@ export default defineUserConfig({
// jsfiddle: true, // @[jsfiddle](id) 嵌入 jsfiddle
// caniuse: true, // @[caniuse](feature) 嵌入 caniuse
// repl: true, // :::go-repl :::kotlin-repl :::rust-repl
// plot: true, // !!plot!! 隐秘文本
// fileTree: true, // :::file-tree 文件树容器
// imageSize: true, // 在构建阶段为 图片添加 width/height 属性
}

View File

@ -21,28 +21,17 @@ export default defineUserConfig({
theme: plumeTheme({
plugins: {
markdownEnhance: {
hint: true, // 提示容器
codetabs: true, // 代码组
tabs: true, // 选项卡
align: true, // 对齐容器
mark: true, // 标记语法
tasklist: true, // 任务列表语法
attrs: true, // 属性语法
sup: true, // 上标语法
sub: true, // 下标语法
alert: true, // GFM 通知语法
footnote: true, // 注脚语法
katex: true, // 数学公式
// 以下可选项在 主题中默认不启用,
// 请在主题中自行配置
// include: true, // Markdown 导入支持
// figure: true, // 启用图片 Figure 支持
// imgLazyload: true, // 使用原生方式懒加载页面图片
// imgMark: true, // 浅色/深色 图片标记
// imgSize: true, // 图片尺寸支持
// obsidianImgSize: true, // obsidian 图片尺寸支持
// mathjax: true, // Math Jax 数学公式 语法支持
// chart: true, // 图表支持
// echarts: true, // ECharts 图表支持
// flowchart: true, // 流程图支持
@ -53,7 +42,6 @@ export default defineUserConfig({
// vuePlayground: true, // Vue 交互演示
// sandpack: true, // sandpack 交互演示
// demo: true, // 代码案例
// revealJs: true, // 幻灯片支持
}
}
}),
@ -68,3 +56,12 @@ export default defineUserConfig({
主题还未完全对 该插件提供的 所有 增强功能 进行 样式上的适配。
如果你在使用过程中遇到样式上的问题,可以在 [issue](https://github.com/pengzhanbo/vuepress-theme-plume/issues) 里提出。
:::
::: warning
该插件从 `2.0.0-rc.53` 开始,移除了部分功能。主题从 `1.0.0-rc.103` 版本开始,适配至最新版。
由此带来的影响是,`plugins.mdEnhance``imgSize`/`imgLazyload`/`imgMark`/`figure`/`obsidianImgSize`/`katex`/`mathjax`/`tabs`/`code-tabs`/`hint`/`alerts`弃用。
- `imgSize`/`imgLazyload`/`imgMark`/`figure`/`obsidianImgSize` 所实现的功能,您可以使用 `plugins.markdownImage` 重新进行配置。
- `katex` / `mathjax` 所实现的功能,您可以使用 `plugins.markdownMath` 进行配置。
- `tabs` / `code-tabs` / `hint` / `alerts` 已变更为 主题的内置功能,您无需额外的配置。
:::

View File

@ -1,6 +1,5 @@
---
title: 阅读统计
author: pengzhanbo
createTime: 2024/03/06 15:23:39
permalink: /config/plugins/reading-time/
---

View File

@ -88,11 +88,13 @@ export default defineUserConfig({
你可以直接在 [VuePress 配置文件](#vuepress-配置文件) 相同的路径下创建一个 `plume.config.js` 文件,这样就可以在该文件中进行主题配置。
你也可以使用 TypeScript 来创建一个 `plume.config.ts` 文件,以获得更好的类型提示。
```txt :no-line-numbers
{sourceDir}/.vuepress/
├── config.ts
└── plume.config.ts // [!code ++]
```
::: file-tree
- docs
- .vuepress
- config.ts
- **plume.config.ts**
:::
::: code-tabs
@tab plume.config.ts

View File

@ -178,6 +178,7 @@ tags:
- 通过加粗文件名或目录名来突出显示,例如 `**README.md**`
- 通过在名称后添加更多文本来为文件或目录添加注释
- 使用 `...``…` 作为名称来添加占位符文件和目录。
- 在 `:::file-tree` 后添加 `:simple-icon` 或 添加 `:colored-icon` 可以切换为简单图标或彩色图标,默认为彩色图标。
**输入:**
@ -233,6 +234,60 @@ tags:
- …
:::
### 使用简单图标
**输入:**
```md
::: file-tree:simple-icon
- docs
- .vuepress
- config.ts
- page1.md
- README.md
- package.json
:::
```
**输出:**
::: file-tree:simple-icon
- docs
- .vuepress
- config.ts
- page1.md
- README.md
- package.json
:::
### 配置
你可以在 `plugins.mdPower.fileTree` 选项中配置 文件树的图标默认类型:
```ts
export default defineUserConfig({
theme: plumeTheme({
plugins: {
markdownPower: {
fileTree: {
icon: 'simple', // 'simple' | 'colored'
}
},
}
})
})
```
::: tip 担心彩色图标会影响构建包体积?
您无需担心,文件树的彩色图标 也是从 `iconify` 解析获取,推荐您在本地安装 `@iconify/json` 项目,
主题会自动将 `@iconify/json` 中的图标数据解析为本地图标资源,即使您在不同的页面
多次使用,这包括了 导航栏、侧边栏、图标组件等,相同图标仅会存在一份资源!
每个彩色图标的大小约在 `1kb ~ 2kb` 之间,即使您的文件树非常夸张的使用了 100+ 不同的图标,对最终的构建包体积影响
也不会很大。
:::
## 选项组
在 Markdown 中支持选项卡。
@ -513,34 +568,13 @@ interface PlotOptions {
## iconify 图标
在 Markdown 文件中使用 [iconify](https://iconify.design/) 的图标。 主题一方面提供了
[`<Icon />`](../功能/组件.md#图标) 组件来支持在 markdown 中使用图标,
在 Markdown 文件中使用 [iconify](https://iconify.design/) 的图标。
一方面,主题还提供了另一种可选的方式,以更简单的方式,在 Markdown 中使用图标,并且将 图标资源编译到
本地静态资源中
主题一方面提供了[`<Icon />`](../功能/组件.md#图标) 组件来支持在 markdown 中使用图标;
另一方面,主题还提供了图标的 markdown 语法,以更简单的方式,在 Markdown 中使用图标
### 配置
该功能默认不启用,你需要在 `theme` 配置中启用。
::: code-tabs
@tab .vuepress/config.ts
```ts
export default defineUserConfig({
theme: plumeTheme({
plugins: {
markdownPower: {
icons: true,
},
}
})
})
```
:::
同时,该功能还需要你额外安装 `@iconify/json` 依赖。
为了更好的使用该功能,主题推荐你安装 `@iconify/json` 依赖。主题会自动解析 `@iconify/json` 中的图标数据,
将有使用的图标打包为本地资源,以获得更好的访问体验。
::: code-tabs
@tab pnpm

View File

@ -70,3 +70,193 @@ export default config
:::
你还可以通过 `@tab:active` 选择其中一个代码块作为默认显示的代码块。
**输入:**
````md
::: code-tabs
@tab config.js
```js
/**
* @type {import('vuepress').UserConfig}
*/
const config = {
// ..
}
export default config
```
@tab:active config.ts <!-- [!code hl] -->
```ts
import type { UserConfig } from 'vuepress'
const config: UserConfig = {
// ..
}
export default config
```
:::
````
**输出:**
::: code-tabs
@tab config.js
```js
/**
* @type {import('vuepress').UserConfig}
*/
const config = {
// ..
}
export default config
```
@tab:active config.ts
```ts
import type { UserConfig } from 'vuepress'
const config: UserConfig = {
// ..
}
export default config
```
:::
## 分组标题图标 <Badge type="tip" text="v1.0.0-rc.103 +" />
主题支持在 代码块分组的组标题上显示图标。 图标根据 标题,即 `@tab 标题` 进行解析适配不同的图标
默认解析规则与 [文件树](../markdown/进阶.md#文件树) 一致。
如, `pnpm / yarn / npm` 分组图标:
**输入:**
````md
::: code-tabs
@tab pnpm
```sh
pnpm i
```
@tab yarn
```sh
yarn
```
@tab npm
```sh
npm install
```
:::
````
**输出:**
::: code-tabs
@tab pnpm
```sh
pnpm i
```
@tab yarn
```sh
yarn
```
@tab npm
```sh
npm install
```
:::
主题默认适配了 前端主流的一些技术:
- 运行环境,如: `NodeJs / Deno / Bun`
- 包管理器,如: `pnpm / yarn / npm`
- 库、框架,如: `vue / react / angular / svelte / solid / Next / Nuxt`
还包括一些主流的语言,如: `TypeScript / JavaScript / C / C++ / Java / Python / Rust / Kotlin / Swift / Go`
::: info
如果您发现您所使用的 库、框架、语言等未能正确显示图标,可以提出 [issue](https://github.com/pengzhanbo/vuepress-theme-plume/issues/new) 告诉我,我会尽量添加相关图标。
:::
### 配置
您可以通过 `plugins.mdPower.codeTabs` 控制分组图标的行为:
```ts
export default defineUserConfig({
theme: plumeTheme({
plugins: {
markdownPower: {
codeTabs: {
icon: true, // CodeTabsOptions
}
},
}
})
})
```
```ts
export interface CodeTabsOptions {
icon?: boolean | { named?: false | string[], extensions?: false | string[] }
}
```
- `true`: 使用默认解析规则显示图标
- `false`: 不显示图标
- `{ named?: false | string[], extensions?: false | string[] }`:
- `named`: 表示 库/框架/语言 名称,严格匹配 `@tab 标题` 中的 `标题` 字段,如 `pnpm``yarn``npm` 等,如果设置为 `false` 则不显示图标,如果为 空数组,则使用默认匹配规则
- `extensions`: 表示 文件扩展名,匹配 `@tab 标题` 中的 `标题` 字段是否包含扩展名,如 `.ts``.js` 等,如果设置为 `false` 则不显示图标,如果为 空数组,则使用默认匹配规则
请注意, `named``extensions` 数组中的元素必须是 `string` 类型,且严格区分大小写。
举一个例子,如果您是一个前端开发,且仅想在 `pnpm/yarn/npm` 分组时显示图标,其它分组时不显示图标,
那么可以进行如下配置:
```ts
export default defineUserConfig({
theme: plumeTheme({
plugins: {
markdownPower: {
codeTabs: {
icon: {
named: ['pnpm', 'yarn', 'npm'], // [!code ++:2]
extensions: false,
}
}
},
}
})
})
```
你可以灵活地配置图标显示规则。
::: tip 担心图标会影响构建包体积?
您无需担心,代码块分组的图标 也是从 `iconify` 解析获取,推荐您在本地安装 `@iconify/json` 项目,
主题会自动将 `@iconify/json` 中的图标数据解析为本地图标资源,即使您在不同的页面
多次使用,这包括了 导航栏、侧边栏、图标组件等,相同图标仅会存在一份资源!
每个彩色图标的大小约在 `1kb ~ 2kb` 之间,即使您的文件树非常夸张的使用了 100+ 不同的图标,对最终的构建包体积影响
也不会很大。
:::

View File

@ -8,9 +8,24 @@ permalink: /guide/features/icon/
## 概述
主题支持 [iconify](https://icon-sets.iconify.design/) 的所有图标,并提供了不同的方式来使用它们
主题支持 [iconify](https://icon-sets.iconify.design/) 的所有图标,并提供了不同的方式来使用它们
## 组件
- [导航栏图标](../../config/导航栏配置.md#配置)
- [侧边栏图标](../../guide/知识笔记.md#侧边栏图标)
- [图标组件](#图标组件)
- [图标语法糖](../../guide/markdown/进阶.md#iconify-图标)
- [文件树图标](../../guide/markdown/进阶.md#文件树)
- [代码分组标题图标](../代码/代码组.md#分组标题图标)
::: tip 主题对图标的优化
上述的不同的使用图标的方式,主题在内部都采取了相同的解析策略,即使您在不同的位置使用了相同的图标,
也不会重复加载相同的图标资源。
图标默认是通过远程请求加载,主题也非常建议您在本地项目中安装 `@iconify/json` 包,以便主题能够将图标全部解析为本地资源,
这可以有效的提高页面的访问体验。
:::
## 图标组件
通过 `<Icon />` 组件来使用图标。

View File

@ -281,3 +281,28 @@ cd open-source # 进入 D: 分区下的 open-source 目录
- ### 完成
::::
## 更新主题
您可以直接在项目中运行以下命令检查是否有可用的更新:
::: code-tabs
@tab pnpm
```sh
pnpm dlx vp-update
```
@tab yarn
``` sh
yarn dlx vp-update
```
@tab npm
``` sh
npx vp-update
```
:::

View File

@ -12,7 +12,7 @@ const el = ref<HTMLElement>()
function toggle(e: HTMLElementEventMap['click']) {
const target = e.target as HTMLElement
if (target.matches('.comment'))
if (target.matches('.comment') || e.currentTarget === target)
return
active.value = !active.value
}

View File

@ -24,6 +24,6 @@ export async function containerPlugin(
if (options.fileTree) {
// ::: file-tree
fileTreePlugin(md)
fileTreePlugin(md, isPlainObject(options.fileTree) ? options.fileTree : {})
}
}

View File

@ -6,13 +6,14 @@
*/
import type { PluginWithOptions } from 'markdown-it'
import type { RuleInline } from 'markdown-it/lib/parser_inline.mjs'
import type { IconsOptions } from '../../shared/index.js'
const [openTag, endTag] = [':[', ']:']
export const iconsPlugin: PluginWithOptions<never> = md =>
md.inline.ruler.before('emphasis', 'iconify', createTokenizer())
export const iconsPlugin: PluginWithOptions<IconsOptions> = (md, options = {}) =>
md.inline.ruler.before('emphasis', 'iconify', createTokenizer(options))
function createTokenizer(): RuleInline {
function createTokenizer(options: IconsOptions): RuleInline {
return (state, silent) => {
let found = false
const max = state.posMax
@ -56,8 +57,8 @@ function createTokenizer(): RuleInline {
state.posMax = state.pos
state.pos = start + 2
const [name, options = ''] = content.split(/\s+/)
const [size, color] = options.split('/')
const [name, opt = ''] = content.split(/\s+/)
const [size = options.size, color = options.color] = opt.split('/')
const icon = state.push('vp_iconify_open', 'VPIcon', 1)
icon.markup = openTag
@ -65,7 +66,7 @@ function createTokenizer(): RuleInline {
if (name)
icon.attrSet('name', name)
if (size)
icon.attrSet('size', size)
icon.attrSet('size', String(size))
if (color)
icon.attrSet('color', color)

View File

@ -22,12 +22,12 @@ export function inlineSyntaxPlugin(
if (options.icons) {
// :[collect:name]:
md.use(iconsPlugin)
md.use(iconsPlugin, isPlainObject(options.icons) ? options.icons : {})
}
if (
options.plot === true
|| (typeof options.plot === 'object' && options.plot.tag !== false)
|| (isPlainObject(options.plot) && options.plot.tag !== false)
) {
// !!plot!!
md.use(plotPlugin)

View File

@ -7,7 +7,9 @@ import { imageSizePlugin } from './enhance/imageSize.js'
import { inlineSyntaxPlugin } from './inline/index.js'
import { prepareConfigFile } from './prepareConfigFile.js'
export function markdownPowerPlugin(options: MarkdownPowerPluginOptions = {}): Plugin {
export function markdownPowerPlugin(
options: MarkdownPowerPluginOptions = {},
): Plugin {
return {
name: 'vuepress-plugin-md-power',
@ -19,11 +21,7 @@ export function markdownPowerPlugin(options: MarkdownPowerPluginOptions = {}): P
extendsBundlerOptions(bundlerOptions, app) {
if (options.repl) {
addViteOptimizeDepsInclude(
bundlerOptions,
app,
['shiki/core', 'shiki/wasm'],
)
addViteOptimizeDepsInclude(bundlerOptions, app, ['shiki/core', 'shiki/wasm'])
}
},

View File

@ -0,0 +1,3 @@
export interface CodeTabsOptions {
icon?: boolean | { named?: false | string[], extensions?: false | string[] }
}

View File

@ -0,0 +1,5 @@
export type FileTreeIconMode = 'simple' | 'colored'
export interface FileTreeOptions {
icon?: FileTreeIconMode
}

View File

@ -1,10 +1,4 @@
export interface IconsOptions {
/**
* The prefix of the icon className
* @default 'vp-mdi'
*/
prefix?: string
/**
* The size of the icon
* @default '1em'

View File

@ -1,6 +1,8 @@
export * from './caniuse.js'
export * from './codepen.js'
export * from './codeSandbox.js'
export * from './codeTabs.js'
export * from './fileTree.js'
export * from './icons.js'
export * from './jsfiddle.js'
export * from './pdf.js'
@ -8,7 +10,5 @@ export * from './plot.js'
export * from './plugin.js'
export * from './repl.js'
export * from './replit.js'
export * from './size.js'
export * from './video.js'

View File

@ -1,10 +1,16 @@
import type { CanIUseOptions } from './caniuse.js'
import type { CodeTabsOptions } from './codeTabs.js'
import type { FileTreeOptions } from './fileTree.js'
import type { IconsOptions } from './icons.js'
import type { PDFOptions } from './pdf.js'
import type { PlotOptions } from './plot.js'
import type { ReplOptions } from './repl.js'
export interface MarkdownPowerPluginOptions {
/**
*
*/
codeTabs?: CodeTabsOptions
/**
* PDF
*
@ -92,7 +98,7 @@ export interface MarkdownPowerPluginOptions {
*
* @default false
*/
fileTree?: boolean
fileTree?: boolean | FileTreeOptions
/**
* caniuse

View File

@ -5,7 +5,7 @@ import VPDocFooter from '@theme/VPDocFooter.vue'
import VPDocMeta from '@theme/VPDocMeta.vue'
import VPEncryptPage from '@theme/VPEncryptPage.vue'
import VPTransitionFadeSlideY from '@theme/VPTransitionFadeSlideY.vue'
import { computed, nextTick, ref, watch } from 'vue'
import { computed, nextTick, ref, resolveComponent, watch } from 'vue'
import { useRoute } from 'vuepress/client'
import {
useBlogPageData,
@ -24,7 +24,7 @@ const headers = useHeaders()
const { isPageDecrypted } = useEncrypt()
const hasComments = computed(() => {
return page.value.frontmatter.comments !== false && isPageDecrypted.value
return !!resolveComponent('CommentService') && page.value.frontmatter.comments !== false && isPageDecrypted.value
})
const enableAside = computed(() => {
@ -136,6 +136,7 @@ watch(
</div>
</div>
</div>
<slot name="doc-bottom" />
</div>
</VPTransitionFadeSlideY>
</template>

View File

@ -4,7 +4,7 @@ import VPLink from '@theme/VPLink.vue'
defineProps<{
href: string
title: string
title?: string
icon?: string | { svg: string }
description?: string
}>()
@ -13,7 +13,7 @@ defineProps<{
<template>
<div class="vp-link-card">
<span class="body">
<VPLink :href="href" no-icon class="link">
<VPLink :href="href" no-icon class="link no-icon">
<slot name="title">
<VPIcon v-if="icon" :name="icon" />
<span v-if="title" v-html="title" />

View File

@ -159,7 +159,7 @@ export function resolveHeaders(headers: MenuItem[], range?: ThemeOutline): MenuI
return ret
}
export function useActiveAnchor(container: Ref<HTMLElement>, marker: Ref<HTMLElement>): void {
export function useActiveAnchor(container: Ref<HTMLElement | null>, marker: Ref<HTMLElement | null>): void {
const { isAsideEnabled } = useAside()
let prevActiveLink: HTMLAnchorElement | null = null
@ -219,21 +219,25 @@ export function useActiveAnchor(container: Ref<HTMLElement>, marker: Ref<HTMLEle
prevActiveLink = null
}
else {
prevActiveLink = container.value.querySelector(
prevActiveLink = container.value?.querySelector(
`a[href="${decodeURIComponent(hash)}"]`,
)
) ?? null
}
const activeLink = prevActiveLink
if (activeLink) {
activeLink.classList.add('active')
marker.value.style.top = `${activeLink.offsetTop + 39}px`
marker.value.style.opacity = '1'
if (marker.value) {
marker.value.style.top = `${activeLink.offsetTop + 39}px`
marker.value.style.opacity = '1'
}
}
else {
marker.value.style.top = '33px'
marker.value.style.opacity = '0'
if (marker.value) {
marker.value.style.top = '33px'
marker.value.style.opacity = '0'
}
}
}