diff --git a/.vscode/settings.json b/.vscode/settings.json
index c406b560..91ebc9bc 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -33,9 +33,10 @@
"editor.codeActionsOnSave": {
"source.fixAll.stylelint": "explicit",
"source.fixAll.eslint": "explicit",
+ "source.fixAll.markdownlint": "explicit",
"source.organizeImports": "never"
},
- "editor.formatOnPaste": true,
+ "editor.formatOnPaste": false,
"eslint.validate": [
"javascript",
"javascriptreact",
diff --git a/docs/notes/theme/guide/markdown/基础.md b/docs/notes/theme/guide/markdown/基础.md
index 21b1a2f3..e6ccc712 100644
--- a/docs/notes/theme/guide/markdown/基础.md
+++ b/docs/notes/theme/guide/markdown/基础.md
@@ -4,6 +4,9 @@ author: pengzhanbo
icon: fluent:markdown-20-filled
createTime: 2024/03/05 11:10:39
permalink: /guide/markdown/basic/
+tags:
+ - 指南
+ - markdown
---
::: note
diff --git a/docs/notes/theme/guide/markdown/扩展.md b/docs/notes/theme/guide/markdown/扩展.md
index 447035f1..ff92f4a2 100644
--- a/docs/notes/theme/guide/markdown/扩展.md
+++ b/docs/notes/theme/guide/markdown/扩展.md
@@ -4,6 +4,9 @@ author: pengzhanbo
icon: fluent-mdl2:auto-enhance-on
createTime: 2024/03/05 23:29:07
permalink: /guide/markdown/extensions/
+tags:
+ - 指南
+ - markdown
---
## 标题锚点
diff --git a/docs/notes/theme/guide/markdown/进阶.md b/docs/notes/theme/guide/markdown/进阶.md
index b175cd96..0f2a7366 100644
--- a/docs/notes/theme/guide/markdown/进阶.md
+++ b/docs/notes/theme/guide/markdown/进阶.md
@@ -5,203 +5,97 @@ icon: ic:outline-auto-fix-high
outline: 2
createTime: 2024/03/05 16:27:59
permalink: /guide/markdown/advance/
+tags:
+ - 指南
+ - markdown
---
-## iconify 图标
+## 卡片
-在 Markdown 文件中使用 [iconify](https://iconify.design/) 的图标。 主题虽然提供了
-[``](/guide/features/component/#iconify) 组件来支持在 markdown 中使用图标,
-但是它需要从远程加载图标,可能速度比较慢。
+对于想要突出显示的内容,可以将其放在 卡片容器 `::: card` 中。
-为此,主题提供了另一种可选的方式,以更简单的方式,在 Markdown 中使用图标,并且将 图标资源编译到
-本地静态资源中。
-
-### 配置
-
-该功能默认不启用,你需要在 `theme` 配置中启用。
-
-::: code-tabs
-@tab .vuepress/config.ts
-
-```ts
-export default defineUserConfig({
- theme: plumeTheme({
- plugins: {
- markdownPower: {
- icons: true,
- },
- }
- })
-})
-```
-
-:::
-
-同时,该功能还需要你额外安装 `@iconify/json` 依赖。
-
-::: code-tabs
-@tab pnpm
-
-```sh
-pnpm add @iconify/json
-```
-
-@tab yarn
-
-```sh
-yarn add @iconify/json
-```
-
-@tab npm
-
-```sh
-npm install @iconify/json
-```
-
-:::
+如果需要在空间足够时并排显示多个卡片,可以使用 `card-grid` 容器,包裹 多个卡片。
### 语法
```md
-:[collect:name]:
+
+::: card title="标题" icon="twemoji:astonished-face"
+
+这里是卡片内容。
+:::
+
+
+:::: card-grid
+
+::: card title="卡片标题 1" icon="twemoji:astonished-face"
+
+这里是卡片内容。
+:::
+
+::: card title="卡片标题 2" icon="twemoji:astonished-face"
+
+这里是卡片内容。
+:::
+
+::::
```
-设置图标大小和颜色
-
-```md
-:[collect:name size]:
-:[collect:name /color]:
-:[collect:name size/color]:
-```
-
-`iconify` 拥有非常多的图标,这些图标被分组为不同的 `collect`,每个 `collect` 都有自己的
-图标。
-
-你可以从 中获取 collect 和 name。
+卡片 支持 可选的 `title` 和 `icon`。 其中, icon 支持传入 图片链接,也可以传入 iconify 图标名。
### 示例
-输入:
+**输入:**
```md
-:[ion:logo-markdown]:
+::: card title="卡片标题" icon="twemoji:astonished-face"
+
+这里是卡片内容。
+:::
```
-输出:
+**输出:**
-:[ion:logo-markdown]:
+::: card title="卡片标题" icon="twemoji:astonished-face"
-该语法为行内语法,因此,你可以在同一行中跟其他 markdown 语法 一起使用。
-
-输入:
-
-```md
-github: :[tdesign:logo-github-filled]:
-修改颜色::[tdesign:logo-github-filled /#f00]:
-修改大小::[tdesign:logo-github-filled 36px]:
-修改大小颜色::[tdesign:logo-github-filled 36px/#f00]:
-```
-
-输出:
-
-github: :[tdesign:logo-github-filled]:
-修改颜色::[tdesign:logo-github-filled /#f00]:
-修改大小::[tdesign:logo-github-filled 36px]:
-修改大小颜色::[tdesign:logo-github-filled 36px/#f00]:
-
-## “隐秘”文本
-
-有时候,你不想直接把文本内容毫无保留的展示出来,想要保留一些 隐秘性,
-可能是为了引起读者的好奇心,也可能纯粹是故意增加点阅读障碍,让文章变得更加有趣。
-
-为了满足这种小小的心思,主题提供了一个 **“隐秘”文本** 的有趣小功能。它看起来像这样:
-
-:::demo-wrapper
-你知道吗, !!鲁迅!! 曾说过:“ !!我没说过这句话!!! ” 令我醍醐灌顶,深受启发,浑身迸发出无可匹敌的
-力量!于是,!!我在床上翻了个身!! !
+这里是卡片内容。
:::
-读者不能直接阅读到完整的内容,部分的内容被 “遮住”,需要鼠标悬停到内容上,才能看到被遮住的内容。
-
-### 配置
-
-该功能默认不启用,你需要在 `theme` 配置中启用。
-
-::: code-tabs
-@tab .vuepress/config.ts
-
-```ts
-export default defineUserConfig({
- theme: plumeTheme({
- plugins: {
- markdownPower: {
- plot: true,
- },
- }
- })
-})
-```
-
-:::
-
-`markdownPower.plot` 支持传入 `boolean | PlotOptions` 类型
-
-```ts
-interface PlotOptions {
- /**
- * 是否启用 `!! !!` markdown (该标记为非标准标记,脱离插件将不生效)
- * 如果设置为 false, 则表示不启用该标记,只能使用 组件
- * @default true
- */
- tag?: boolean
-
- /**
- * 遮罩层颜色
- */
- mask?: string | { light: string, dark: string }
-
- /**
- * 文本颜色
- */
- color?: string | { light: string, dark: string }
-
- /**
- * 触发方式
- *
- * @default 'hover'
- */
- trigger?: 'hover' | 'click'
-}
-```
-
-### 语法
+**输入:**
```md
-!!需要隐秘的内容!!
-```
+:::: card-grid
+::: card title="卡片标题 1" icon="twemoji:astonished-face"
-如果不想使用 非标准的 `!! !!` 标记语法,你可以将 `plot.tag` 设置为 `false` ,
-然后使用 [``](/guide/features/component/#plot) 组件替代。
-
-### 示例
-
-输入:
-
-```md
-你知道吗, !!鲁迅!! 曾说过:“ !!我没说过这句话!!! ” 令我醍醐灌顶,深受启发,浑身迸发出无可匹敌的
-力量!于是,!!我在床上翻了个身!! !
-```
-
-输出:
-
-:::demo-wrapper
-你知道吗, !!鲁迅!! 曾说过:“ !!我没说过这句话!!! ” 令我醍醐灌顶,深受启发,浑身迸发出无可匹敌的
-力量!于是,!!我在床上翻了个身!! !
+这里是卡片内容。
:::
-## 步骤容器
+::: card title="卡片标题 2" icon="twemoji:astonished-face"
-在 Markdown 中支持 步骤容器。
+这里是卡片内容。
+:::
+::::
+```
+
+**输出:**
+
+:::: card-grid
+::: card title="卡片标题 1" icon="twemoji:astonished-face"
+
+这里是卡片内容。
+:::
+
+::: card title="卡片标题 2" icon="twemoji:astonished-face"
+
+这里是卡片内容。
+:::
+::::
+
+::: info
+如果你更喜欢通过组件的方式使用 卡片,你可以查看 [卡片组件](/guide/features/component/#card) 。
+:::
+
+## 步骤
有时候,你需要将内容 划分为递进的步骤展示,你可以使用 `steps` 容器 实现。
@@ -372,6 +266,96 @@ corepack use pnpm@8
:::
+## “隐秘”文本
+
+有时候,你不想直接把文本内容毫无保留的展示出来,想要保留一些 隐秘性,
+可能是为了引起读者的好奇心,也可能纯粹是故意增加点阅读障碍,让文章变得更加有趣。
+
+为了满足这种小小的心思,主题提供了一个 **“隐秘”文本** 的有趣小功能。它看起来像这样:
+
+:::demo-wrapper
+你知道吗, !!鲁迅!! 曾说过:“ !!我没说过这句话!!! ” 令我醍醐灌顶,深受启发,浑身迸发出无可匹敌的
+力量!于是,!!我在床上翻了个身!! !
+:::
+
+读者不能直接阅读到完整的内容,部分的内容被 “遮住”,需要鼠标悬停到内容上,才能看到被遮住的内容。
+
+### 配置
+
+该功能默认不启用,你需要在 `theme` 配置中启用。
+
+::: code-tabs
+@tab .vuepress/config.ts
+
+```ts
+export default defineUserConfig({
+ theme: plumeTheme({
+ plugins: {
+ markdownPower: {
+ plot: true,
+ },
+ }
+ })
+})
+```
+
+:::
+
+`markdownPower.plot` 支持传入 `boolean | PlotOptions` 类型
+
+```ts
+interface PlotOptions {
+ /**
+ * 是否启用 `!! !!` markdown (该标记为非标准标记,脱离插件将不生效)
+ * 如果设置为 false, 则表示不启用该标记,只能使用 组件
+ * @default true
+ */
+ tag?: boolean
+
+ /**
+ * 遮罩层颜色
+ */
+ mask?: string | { light: string, dark: string }
+
+ /**
+ * 文本颜色
+ */
+ color?: string | { light: string, dark: string }
+
+ /**
+ * 触发方式
+ *
+ * @default 'hover'
+ */
+ trigger?: 'hover' | 'click'
+}
+```
+
+### 语法
+
+```md
+!!需要隐秘的内容!!
+```
+
+如果不想使用 非标准的 `!! !!` 标记语法,你可以将 `plot.tag` 设置为 `false` ,
+然后使用 [``](/guide/features/component/#plot) 组件替代。
+
+### 示例
+
+输入:
+
+```md
+你知道吗, !!鲁迅!! 曾说过:“ !!我没说过这句话!!! ” 令我醍醐灌顶,深受启发,浑身迸发出无可匹敌的
+力量!于是,!!我在床上翻了个身!! !
+```
+
+输出:
+
+:::demo-wrapper
+你知道吗, !!鲁迅!! 曾说过:“ !!我没说过这句话!!! ” 令我醍醐灌顶,深受启发,浑身迸发出无可匹敌的
+力量!于是,!!我在床上翻了个身!! !
+:::
+
## 示例容器
有时候,你可能需要在 内容中补充一些 示例,但期望能与 其它内容 分隔开来呈现。
@@ -460,6 +444,108 @@ corepack use pnpm@8
:::
+## iconify 图标
+
+在 Markdown 文件中使用 [iconify](https://iconify.design/) 的图标。 主题虽然提供了
+[``](/guide/features/component/#iconify) 组件来支持在 markdown 中使用图标,
+但是它需要从远程加载图标,可能速度比较慢。
+
+为此,主题提供了另一种可选的方式,以更简单的方式,在 Markdown 中使用图标,并且将 图标资源编译到
+本地静态资源中。
+
+### 配置
+
+该功能默认不启用,你需要在 `theme` 配置中启用。
+
+::: code-tabs
+@tab .vuepress/config.ts
+
+```ts
+export default defineUserConfig({
+ theme: plumeTheme({
+ plugins: {
+ markdownPower: {
+ icons: true,
+ },
+ }
+ })
+})
+```
+
+:::
+
+同时,该功能还需要你额外安装 `@iconify/json` 依赖。
+
+::: code-tabs
+@tab pnpm
+
+```sh
+pnpm add @iconify/json
+```
+
+@tab yarn
+
+```sh
+yarn add @iconify/json
+```
+
+@tab npm
+
+```sh
+npm install @iconify/json
+```
+
+:::
+
+### 语法
+
+```md
+:[collect:name]:
+```
+
+设置图标大小和颜色
+
+```md
+:[collect:name size]:
+:[collect:name /color]:
+:[collect:name size/color]:
+```
+
+`iconify` 拥有非常多的图标,这些图标被分组为不同的 `collect`,每个 `collect` 都有自己的
+图标。
+
+你可以从 中获取 collect 和 name。
+
+### 示例
+
+输入:
+
+```md
+:[ion:logo-markdown]:
+```
+
+输出:
+
+:[ion:logo-markdown]:
+
+该语法为行内语法,因此,你可以在同一行中跟其他 markdown 语法 一起使用。
+
+输入:
+
+```md
+github: :[tdesign:logo-github-filled]:
+修改颜色::[tdesign:logo-github-filled /#f00]:
+修改大小::[tdesign:logo-github-filled 36px]:
+修改大小颜色::[tdesign:logo-github-filled 36px/#f00]:
+```
+
+输出:
+
+github: :[tdesign:logo-github-filled]:
+修改颜色::[tdesign:logo-github-filled /#f00]:
+修改大小::[tdesign:logo-github-filled 36px]:
+修改大小颜色::[tdesign:logo-github-filled 36px/#f00]:
+
## can I use
此功能默认不启用,你可以在配置文件中启用它。
diff --git a/docs/notes/theme/guide/功能/组件.md b/docs/notes/theme/guide/功能/组件.md
index 14136b1a..767fb11b 100644
--- a/docs/notes/theme/guide/功能/组件.md
+++ b/docs/notes/theme/guide/功能/组件.md
@@ -9,11 +9,15 @@ permalink: /guide/features/component/
## 概述
+VuePress 支持在 Markdown 文件中使用 组件。
+
主题提供了一些具有通用性的组件,可以在任何地方使用。
-## ``
+## 徽章
-标签,用于在页面中增加一些提示信息。
+使用 `` 组件来显示 行内信息,如状态或标签。
+
+将你想显示的内容传递给 `` 组件的 `text` 属性。
### Props
@@ -38,37 +42,37 @@ permalink: /guide/features/component/
- VuePress -
- VuePress -
-## ``
+## 图标
-支持 iconify 所有图标,支持通过 icon name 加载图标。
+支持 iconify 所有图标,通过 icon name 加载图标。
可在 [iconify search](https://icon-sets.iconify.design/) 搜索图标使用。
### Props
-| 名称 | 类型 | 默认值 | 说明 |
-| ----- | ------ | ---------------- | ---------- |
-| name | string | `''` | icon name |
-| color | string | `'currentcolor'` | icon color |
-| size | string | `'1em'` | icon size |
+| 名称 | 类型 | 默认值 | 说明 |
+| ----- | ------ | ---------------- | -------- |
+| name | string | `''` | 图标名 |
+| color | string | `'currentcolor'` | 图标颜色 |
+| size | string | `'1em'` | 图标大小 |
**输入:**
```md
-- home -
-- vscode -
-- twitter -
+- home -
+- vscode -
+- twitter -
```
**输出:**
-- home -
-- vscode -
-- twitter -
+- home -
+- vscode -
+- twitter -
-## ``
+## “隐秘”文本
-[“隐秘”文本](/guide/markdown/advance/#隐秘-文本) 组件。
+使用 `` 组件显示 [“隐秘”文本](/guide/markdown/advance/#隐秘-文本) ,能够更灵活的控制行为。
该组件默认不启用,你需要在 theme 配置中启用。
@@ -109,11 +113,85 @@ export default defineUserConfig({
- 鼠标悬停 - 悬停时可见
- 点击 - 点击时可见
-## ``
+## 卡片
-- 类型:`Component`
+使用 `` 组件在页面中显示卡片。
-自定义首页时,提供给 区域 的 包装容器。
+也可以使用 markdown [卡片容器](/guide/markdown/advance/#卡片) 语法,替代 `` 组件。
+
+### Props
+
+| 名称 | 类型 | 默认值 | 说明 |
+| ----- | --------------------------- | ------ | ---------------------------------------------------------------- |
+| title | `string` | `''` | 标题 |
+| icon | `string \| { svg: string }` | `''` | 显示在标题左侧的图标,支持 iconify 所有图标,也可以使用 图片链接 |
+
+### 插槽
+
+| 名称 | 说明 |
+| ------- | ---------- |
+| default | 卡片内容 |
+| title | 自定义标题 |
+
+**输入:**
+
+```md
+
+ 这里是卡片内容。
+
+
+
+
+ 卡片标题
+
+ 这里是卡片内容。
+
+```
+
+**输出:**
+
+
+ 这里是卡片内容。
+
+
+
+
+ 卡片标题
+
+ 这里是卡片内容。
+
+
+## 卡片排列容器
+
+当你需要将多个卡片排列,可以使用 `` 组件。在空间足够时,多个卡片会自动排列。
+
+**输入:**
+
+```md
+
+
+ 这里是卡片内容。
+
+
+ 这里是卡片内容。
+
+
+```
+
+**输出:**
+
+
+
+ 这里是卡片内容。
+
+
+ 这里是卡片内容。
+
+
+
+## 首页布局容器
+
+自定义首页时,使用 ``提供给 区域 的 包装容器。
### Props
diff --git a/theme/src/client/components/global/VPCard.vue b/theme/src/client/components/global/VPCard.vue
new file mode 100644
index 00000000..d1effcec
--- /dev/null
+++ b/theme/src/client/components/global/VPCard.vue
@@ -0,0 +1,72 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/theme/src/client/components/global/VPCardGrid.vue b/theme/src/client/components/global/VPCardGrid.vue
new file mode 100644
index 00000000..5724bb24
--- /dev/null
+++ b/theme/src/client/components/global/VPCardGrid.vue
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
diff --git a/theme/src/client/config.ts b/theme/src/client/config.ts
index c21cafbe..d697285a 100644
--- a/theme/src/client/config.ts
+++ b/theme/src/client/config.ts
@@ -3,11 +3,13 @@ import './styles/index.css'
import { defineClientConfig } from 'vuepress/client'
import type { ClientConfig } from 'vuepress/client'
import { h } from 'vue'
-import VPBadge from './components/global/VPBadge.vue'
+import VPHomeBox from '@theme/Home/VPHomeBox.vue'
+import VPCard from '@theme/global/VPCard.vue'
+import VPBadge from '@theme/global/VPBadge.vue'
+import VPCardGrid from '@theme/global/VPCardGrid.vue'
import { enhanceScrollBehavior, setupDarkMode, setupWatermark } from './composables/index.js'
import Layout from './layouts/Layout.vue'
import NotFound from './layouts/NotFound.vue'
-import VPHomeBox from './components/Home/VPHomeBox.vue'
export default defineClientConfig({
enhance({ app, router }) {
@@ -18,6 +20,12 @@ export default defineClientConfig({
app.component('Badge', VPBadge)
app.component('VPBadge', VPBadge) // alias
+ app.component('VPCard', VPCard)
+ app.component('Card', VPCard)
+
+ app.component('VPCardGrid', VPCardGrid)
+ app.component('CardGrid', VPCardGrid)
+
app.component('DocSearch', () => {
const SearchComponent
= app.component('Docsearch') || app.component('SearchBox')
diff --git a/theme/src/client/index.ts b/theme/src/client/index.ts
index f4051017..2a17102e 100644
--- a/theme/src/client/index.ts
+++ b/theme/src/client/index.ts
@@ -11,6 +11,9 @@ export { default as Layout } from './layouts/Layout.vue'
export { default as NotFound } from './layouts/NotFound.vue'
export { default as VPBadge } from './components/global/VPBadge.vue'
+export { default as VPCard } from './components/global/VPCard.vue'
+export { default as VPCardGrid } from './components/global/VPCardGrid.vue'
+
export { default as VPImage } from './components/VPImage.vue'
export { default as VPButton } from './components/VPButton.vue'
export { default as VPLink } from './components/VPLink.vue'
diff --git a/theme/src/node/config/extendsBundlerOptions.ts b/theme/src/node/config/extendsBundlerOptions.ts
index a19d59dd..b753f17a 100644
--- a/theme/src/node/config/extendsBundlerOptions.ts
+++ b/theme/src/node/config/extendsBundlerOptions.ts
@@ -1,4 +1,4 @@
-import { addViteConfig, addViteOptimizeDepsInclude, addViteSsrNoExternal } from '@vuepress/helper'
+import { addViteConfig, addViteOptimizeDepsExclude, addViteOptimizeDepsInclude, addViteSsrNoExternal } from '@vuepress/helper'
import type { App } from 'vuepress'
export function extendsBundlerOptions(bundlerOptions: any, app: App): void {
@@ -9,6 +9,7 @@ export function extendsBundlerOptions(bundlerOptions: any, app: App): void {
})
addViteOptimizeDepsInclude(bundlerOptions, app, '@vueuse/core', true)
+ addViteOptimizeDepsExclude(bundlerOptions, app, '@theme')
addViteSsrNoExternal(bundlerOptions, app, [
'@vuepress/helper',
diff --git a/theme/src/node/plugins/containerPlugins.ts b/theme/src/node/plugins/containerPlugins.ts
index 502ce428..723f2dde 100644
--- a/theme/src/node/plugins/containerPlugins.ts
+++ b/theme/src/node/plugins/containerPlugins.ts
@@ -39,6 +39,15 @@ export const customContainerPlugins: Plugin[] = [
return '\n'
},
}),
+ /**
+ * :::steps
+ * 1. 步骤 1
+ * xxx
+ * 2. 步骤 2
+ * xxx
+ * 3. ...
+ * :::
+ */
containerPlugin({
type: 'steps',
before() {
@@ -48,6 +57,42 @@ export const customContainerPlugins: Plugin[] = [
return ''
},
}),
+ /**
+ * ::: card title="xxx" icon="xxx"
+ * xxx
+ * :::
+ */
+ containerPlugin({
+ type: 'card',
+ before(info) {
+ const title = resolveAttr(info, 'title')
+ const icon = resolveAttr(info, 'icon')
+ return ``
+ },
+ after() {
+ return ''
+ },
+ }),
+
+ /**
+ * :::: card-grid
+ * ::: card
+ * xxx
+ * :::
+ * ::: card
+ * xxx
+ * :::
+ * ::::
+ */
+ containerPlugin({
+ type: 'card-grid',
+ before() {
+ return ''
+ },
+ after() {
+ return ''
+ },
+ }),
]
/**