mirror of
https://github.com/pengzhanbo/vuepress-theme-plume.git
synced 2026-04-23 10:58:13 +08:00
* feat: add multiple provider support for icon * chore: tweak * chore: tweak
This commit is contained in:
parent
0425046e9e
commit
149732520a
2
.vscode/settings.json
vendored
2
.vscode/settings.json
vendored
@ -64,9 +64,11 @@
|
||||
"composables",
|
||||
"Docsearch",
|
||||
"esbuild",
|
||||
"fontawesome",
|
||||
"frontmatter",
|
||||
"gsap",
|
||||
"iarna",
|
||||
"iconfont",
|
||||
"iconify",
|
||||
"katex",
|
||||
"leancloud",
|
||||
|
||||
BIN
docs/.vuepress/public/images/icon/fontawesome-1.png
Normal file
BIN
docs/.vuepress/public/images/icon/fontawesome-1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 148 KiB |
BIN
docs/.vuepress/public/images/icon/iconfont-1.png
Normal file
BIN
docs/.vuepress/public/images/icon/iconfont-1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 79 KiB |
BIN
docs/.vuepress/public/images/icon/iconfont-2.png
Normal file
BIN
docs/.vuepress/public/images/icon/iconfont-2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 116 KiB |
BIN
docs/.vuepress/public/images/icon/iconfont-3.png
Normal file
BIN
docs/.vuepress/public/images/icon/iconfont-3.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 178 KiB |
BIN
docs/.vuepress/public/images/icon/iconify-1.png
Normal file
BIN
docs/.vuepress/public/images/icon/iconify-1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 43 KiB |
@ -137,11 +137,13 @@ export default defineUserConfig({
|
||||
- **默认值**: `false`
|
||||
- **详情**: 是否启用 `npm-to` 容器
|
||||
|
||||
### icons
|
||||
### icon
|
||||
|
||||
- **类型**: `boolean | IconsOptions`
|
||||
- **默认值**: `true`
|
||||
- **详情**: 是否启用图标语法
|
||||
- **类型**: `IconOptions`
|
||||
- **默认值**: `{ provider: 'iconify' }`
|
||||
- **详情**: 图标配置
|
||||
|
||||
[查看 **icon** 使用说明](../../theme/guide/features/icon.md){.read-more}
|
||||
|
||||
### plot
|
||||
|
||||
|
||||
@ -123,11 +123,7 @@ type NavItem = string | {
|
||||
*/
|
||||
link: string
|
||||
/**
|
||||
* 支持 iconify 图标,直接使用 iconify name 即可自动加载
|
||||
* @see https://icon-sets.iconify.design/
|
||||
*
|
||||
* - 如果 iconify 图标不满足您的需求,也可以支持传入 svg 字符串。
|
||||
* - 还支持使用 本地图片 或 远程图片,本地图片的路径需要以 `/` 开头。
|
||||
* 图标名称,或者 svg 图标
|
||||
*/
|
||||
icon?: string | { svg: string }
|
||||
|
||||
@ -225,6 +221,20 @@ export default defineUserConfig({
|
||||
|
||||
这表示,以 `/blog/` 或 `/article/` 开头的页面链接地址,该链接元素将被激活。
|
||||
|
||||
### 图标
|
||||
|
||||
支持通过 [markdown -> icon](../guide/features/icon.md) 配置的来源的图标。
|
||||
|
||||
- 当 `markdown.icon.provide` 为 `iconify` 时,支持 [iconify](https://iconify.design/) 图标
|
||||
- 当 `markdown.icon.provide` 为 `iconfont` 时,支持 [iconfont](https://www.iconfont.cn/) 图标
|
||||
- 当 `markdown.icon.provide` 为 `fontawesome` 时,支持 [fontawesome](https://fontawesome.com/) 图标
|
||||
|
||||
`markdown.icon.provide` 为非 `iconify` 值时,可以在 图标名称前加上 `iconify` 前缀,强制使用 [iconify](https://iconify.design/) 图标。
|
||||
|
||||
```ts
|
||||
const item = { text: '首页', link: '/', icon: 'iconify carbon:home' }
|
||||
```
|
||||
|
||||
## 配置帮助函数
|
||||
|
||||
主题提供了 `defineNavbarConfig(config)` 函数,为主题使用者提供导航栏配置的类型帮助。
|
||||
|
||||
@ -7,16 +7,53 @@ permalink: /guide/components/icon/
|
||||
|
||||
## 概述
|
||||
|
||||
支持 iconify 所有图标,通过 icon name 加载图标。
|
||||
图标组件 `<Icon />`,根据 `markdown.icon` 配置,从不同的图标库加载图标。
|
||||
|
||||
可在 [iconify search](https://icon-sets.iconify.design/) 搜索图标使用。
|
||||
[主题还提供了 markdown 语法支持,点击了解更多](../markdown/icons.md){.read-more}
|
||||
|
||||
## 配置
|
||||
|
||||
```ts title=".vuepress/config.ts" twoslash
|
||||
import { defineUserConfig } from 'vuepress'
|
||||
import { plumeTheme } from 'vuepress-theme-plume'
|
||||
|
||||
export default defineUserConfig({
|
||||
theme: plumeTheme({
|
||||
markdown: { // [!code ++:3]
|
||||
icon: { provider: 'iconify' } // 默认支持
|
||||
}
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
```ts
|
||||
interface IconOptions {
|
||||
/**
|
||||
* 图标提供商
|
||||
*/
|
||||
provider: 'iconify' | 'iconfont' | 'fontawesome'
|
||||
/**
|
||||
* 图标默认前缀,不同的提供商默认前缀不同
|
||||
* - iconify - 默认为 `''`
|
||||
* - iconfont - 默认为 `iconfont icon-`
|
||||
* - fontawesome - 默认为 `fas`
|
||||
*/
|
||||
prefix?: string
|
||||
/**
|
||||
* 图标资源地址
|
||||
*/
|
||||
assets?: IconAssetLink | IconAssetLink[]
|
||||
size?: string | number
|
||||
color?: string
|
||||
}
|
||||
```
|
||||
|
||||
## Props
|
||||
|
||||
:::: field-group
|
||||
|
||||
::: field name="name" type="string" default="''" optional
|
||||
图标名称
|
||||
图标名称,当 `markdown.icon.prefix` 有值时,`name` 中的前缀可以省略
|
||||
:::
|
||||
|
||||
::: field name="color" type="string" default="'currentcolor'" optional
|
||||
|
||||
@ -18,7 +18,7 @@ permalink: /guide/components/link-card/
|
||||
:::
|
||||
|
||||
::: field name="icon" type="string | { svg: string }" default="''" optional
|
||||
显示在标题左侧的图标,支持 iconify 所有图标,也可以使用 图片链接
|
||||
显示在标题左侧的图标,支持 [markdown.icon](../features/icon.md) 配置的提供商的图标,也可以使用 图片链接
|
||||
:::
|
||||
|
||||
::: field name="href" type="string" default="''" optional
|
||||
|
||||
@ -7,80 +7,110 @@ permalink: /guide/features/icon/
|
||||
|
||||
## 概述
|
||||
|
||||
主题支持 [iconify](https://icon-sets.iconify.design/) 的所有图标,并提供了不同的方式来使用它们:
|
||||
主题支持以下来源的图标:
|
||||
|
||||
- [iconify](https://iconify.design/) - 默认支持
|
||||
- [iconfont](https://www.iconfont.cn/) - 可选
|
||||
- [fontawesome](https://fontawesome.com/) - 可选
|
||||
|
||||
在主题的以下功能中以相同的方式使用图标:
|
||||
|
||||
- [导航栏图标](../../config/navbar.md#配置)
|
||||
- [侧边栏图标](../../guide/document.md#侧边栏图标)
|
||||
- [图标组件](#图标组件)
|
||||
- [图标语法糖](../../guide/markdown/icons.md)
|
||||
- [文件树图标](../../guide/markdown/file-tree.md)
|
||||
- [代码分组标题图标](../code/code-tabs.md#分组标题图标)
|
||||
|
||||
提供语法糖和组件支持:
|
||||
|
||||
[Markdown 图标语法糖支持](../markdown/icons.md){.read-more}
|
||||
|
||||
[图标组件支持](../components/icon.md){.read-more}
|
||||
|
||||
::: tip 主题对图标的优化
|
||||
上述的不同的使用图标的方式,主题在内部都采取了相同的解析策略,即使您在不同的位置使用了相同的图标,
|
||||
也不会重复加载相同的图标资源。
|
||||
|
||||
图标默认是通过远程请求加载,主题也非常建议您在本地项目中安装 `@iconify/json` 包,以便主题能够将图标全部解析为本地资源,
|
||||
这可以有效的提高页面的访问体验。
|
||||
:::
|
||||
|
||||
## 图标组件
|
||||
## 配置
|
||||
|
||||
通过 `<Icon />` 组件来使用图标。
|
||||
```ts title=".vuepress/config.ts" twoslash
|
||||
import { defineUserConfig } from 'vuepress'
|
||||
import { plumeTheme } from 'vuepress-theme-plume'
|
||||
|
||||
你可以在 markdown 文件中使用该 组件。
|
||||
|
||||
### 属性
|
||||
|
||||
`<Icon />` 组件接受一个 `name` 属性,用于指定图标的名称。还支持传入 `color` 和 `size` 属性来设置图标的颜色和大小。
|
||||
但对于 彩色图标,`color` 属性设置无效。
|
||||
|
||||
| 属性 | 类型 | 描述 |
|
||||
| ----- | ------------------ | -------------------------------------------------------------------------- |
|
||||
| name | `string` | 图标名称,在 [iconify](https://icon-sets.iconify.design/) 可获取对应的名称 |
|
||||
| color | `string` | 图标颜色,仅纯色图标支持设置颜色 |
|
||||
| size | `number \| string` | 设置图标大小,默认单位为 `px` ,可自定义单位 |
|
||||
|
||||
**示例:**
|
||||
|
||||
````md
|
||||
- 纯色图标:<Icon name="octicon:smiley-16" />
|
||||
- 定义纯色图标的颜色和大小:<Icon name="octicon:smiley-16" color="red" size="2em" />
|
||||
- 彩色图标:<Icon name="noto:smiling-face-with-open-hands" />
|
||||
- 定义彩色图标的大小:<Icon name="noto:smiling-face-with-open-hands" size="2em" />
|
||||
````
|
||||
|
||||
- 纯色图标:<Icon name="octicon:smiley-16" />
|
||||
- 定义纯色图标的颜色和大小:<Icon name="octicon:smiley-16" color="red" size="2em" />
|
||||
- 彩色图标:<Icon name="noto:smiling-face-with-open-hands" />
|
||||
- 定义彩色图标的大小:<Icon name="noto:smiling-face-with-open-hands" size="2em" />
|
||||
|
||||
### 加载图标
|
||||
|
||||
`<Icon />` 组件默认通过 远程请求 `CDN` 获取图标资源,但这可能受到网络环境的影响,出现加载失败
|
||||
或者延迟显示的情况。
|
||||
|
||||
为了解决这一问题,主题建议 在你的站点项目中安装 `@iconify/json` 包。
|
||||
主题会检查当前项目是否安装了 `@iconify/json`,如果安装了该包,则主题自动解析所使用到的图标,
|
||||
并处理为本地图标资源,在构建时打包到 `dist` 目录中。
|
||||
|
||||
由于 `@iconify/json` 包比较大,需要手动进行安装:
|
||||
|
||||
::: npm-to
|
||||
|
||||
```sh
|
||||
npm install @iconify/json
|
||||
export default defineUserConfig({
|
||||
theme: plumeTheme({
|
||||
markdown: { // [!code ++:3]
|
||||
icon: { provider: 'iconify' } // 默认支持
|
||||
}
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
:::
|
||||
## 配置项
|
||||
|
||||
## markdown 语法糖
|
||||
### provider
|
||||
|
||||
相关内容请查看 [iconify-图标 语法糖](../markdown/icons.md)
|
||||
- **类型**: `'iconify' | 'iconfont' | 'fontawesome'`
|
||||
- **默认值**: `'iconify'`
|
||||
|
||||
---
|
||||
图标提供商
|
||||
|
||||
::: tip 说明
|
||||
[navbar](../../config/theme.md#navbar) 配置和 [notes](../../config/theme.md#notes) 配置
|
||||
中的 `icon` 选项,也支持传入 iconify 图标名,并且当安装了 `@iconify/json`,也会自动解析为本地图标资源。
|
||||
:::
|
||||
### prefix
|
||||
|
||||
- **类型**: `string`
|
||||
- **默认值**: `''` (不同的图标提供商有不同的默认值)
|
||||
- **详情**:
|
||||
|
||||
图标前缀
|
||||
|
||||
- 提供商为 `iconify` 时,默认为 `''`,设置 `iconify` 的图标集作为前缀,比如 `mdi` 。
|
||||
- 提供商为 `iconfont` 时,默认为 `'iconfont icon-'`
|
||||
- 提供商为 `fontawesome` 时默认为 `'fas'`,可选值如下:
|
||||
|
||||
```ts
|
||||
type FontAwesomePrefix =
|
||||
| 'fas' | 's' // fa-solid fa-name
|
||||
| 'far' | 'r' // fa-regular fa-name
|
||||
| 'fal' | 'l' // fa-light fa-name
|
||||
| 'fat' | 't' // fa-thin fa-name
|
||||
| 'fads' | 'ds' // fa-duotone fa-solid fa-name
|
||||
| 'fass' | 'ss' // fa-sharp fa-solid fa-name
|
||||
| 'fasr' | 'sr' // fa-sharp fa-regular fa-name
|
||||
| 'fasl' | 'sl' // fa-sharp fa-light fa-name
|
||||
| 'fast' | 'st' // fa-sharp fa-thin fa-name
|
||||
| 'fasds' | 'sds' // fa-sharp-duotone fa-solid fa-name
|
||||
| 'fab' | 'b' // fa-brands fa-name
|
||||
```
|
||||
|
||||
### assets
|
||||
|
||||
- **类型**: `(string | FontAwesomeAssetBuiltin)[] | string | FontAwesomeAssetBuiltin`
|
||||
|
||||
```ts
|
||||
type FontAwesomeAssetBuiltin = 'fontawesome' | 'fontawesome-with-brands'
|
||||
```
|
||||
|
||||
- **默认值**: `undefined`
|
||||
|
||||
- **详情**:
|
||||
|
||||
- `iconify` 时,不需要设置;
|
||||
- `iconfont` 时,设置为 iconfont 的资源地址;
|
||||
- `fontawesome` 时,设置为 `fontawesome` 的资源地址,可选值为 `fontawesome` 或 `fontawesome-with-brands`,
|
||||
或者自定义资源地址。
|
||||
|
||||
### size
|
||||
|
||||
- **类型**: `string | number`
|
||||
- **默认值**: `1em`
|
||||
- **详情**:
|
||||
|
||||
图标的默认尺寸
|
||||
|
||||
### color
|
||||
|
||||
- **类型**: `string`
|
||||
- **默认值**: `'currentColor'`
|
||||
- **详情**:
|
||||
|
||||
图标的默认颜色
|
||||
|
||||
@ -2,12 +2,33 @@
|
||||
title: 图标
|
||||
createTime: 2024/09/30 14:49:39
|
||||
icon: grommet-icons:emoji
|
||||
permalink: /guide/markdown/iconify/
|
||||
permalink: /guide/markdown/icon/
|
||||
badge:
|
||||
text: 变更
|
||||
type: warning
|
||||
---
|
||||
|
||||
<script setup>
|
||||
import { useStyleTag, useScriptTag } from '@vueuse/core'
|
||||
|
||||
useStyleTag(`@import url("//at.alicdn.com/t/c/font_4920010_cm826bt13ke.css");`)
|
||||
useScriptTag(
|
||||
'https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6/js/solid.min.js',
|
||||
() => {},
|
||||
{ attrs: { "data-auto-replace-svg": "nest" } }
|
||||
)
|
||||
useScriptTag(
|
||||
'https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6/js/regular.min.js',
|
||||
() => {},
|
||||
{ attrs: { "data-auto-replace-svg": "nest" } }
|
||||
)
|
||||
useScriptTag(
|
||||
'https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6/js/fontawesome.min.js',
|
||||
() => {},
|
||||
{ attrs: { "data-auto-replace-svg": "nest" } }
|
||||
)
|
||||
</script>
|
||||
|
||||
::: warning 图标语法糖在 `1.0.0-rc.144` 版本中进行了破坏性变更。
|
||||
|
||||
`:[collect:name size/color]:` 语法糖已弃用,请使用 `::collect:name =size /color::` 代替。
|
||||
@ -23,13 +44,127 @@ badge:
|
||||
|
||||
## 概述
|
||||
|
||||
在 Markdown 文件中使用 [iconify](https://iconify.design/) 的图标。
|
||||
主题支持在 Markdown 文件中以下来源的图标:
|
||||
|
||||
主题一方面提供了[`<Icon />`](../components/icon.md) 组件来支持在 markdown 中使用图标;
|
||||
另一方面,主题还提供了图标的 markdown 语法,以更简单的方式,在 Markdown 中使用图标。
|
||||
- [iconify](https://iconify.design/) - 默认支持
|
||||
- [iconfont](https://www.iconfont.cn/) - 可选
|
||||
- [fontawesome](https://fontawesome.com/) - 可选
|
||||
|
||||
为了更好的使用该功能,主题推荐你安装 `@iconify/json` 依赖。主题会自动解析 `@iconify/json` 中的图标数据,
|
||||
将有使用的图标打包为本地资源,以获得更好的访问体验。
|
||||
主题提供图标 markdown 语法支持,使用简单灵活的方式在 Markdown 中插入图标。
|
||||
|
||||
[主题还提供了 `<Icon />` 组件支持,点击了解更多](../components/icon.md){.read-more}
|
||||
|
||||
## 语法
|
||||
|
||||
图标语法为行内语法,可以在段落中与其他 markdown 语法混合使用。
|
||||
|
||||
**基础语法**,使用 `::` 包裹图标名称:
|
||||
|
||||
```md
|
||||
::name::
|
||||
```
|
||||
|
||||
**设置图标大小和颜色**:(注意空格不可缺少)
|
||||
|
||||
```md
|
||||
::name =size::
|
||||
::name /color::
|
||||
::name =size /color::
|
||||
```
|
||||
|
||||
- `=size`: 设置图标大小
|
||||
|
||||
- `=16`: 图标的宽高为 `16px`
|
||||
- `=24x16`: 图标的宽为 `24px`,高为 `16px`
|
||||
- `=x16`: 图标的高为 `16px`,宽为自适应
|
||||
- `=1.2em`: 图标的宽高为 `1.2em`
|
||||
- `=1.2emx1.5em`: 图标的宽为 `1.2em`,高为 `1.5em`
|
||||
|
||||
- `/color`: 设置图标颜色,支持 `hex`/ `rgb` / `rgba` / `hsl` / `hsla` 等合法颜色色值
|
||||
|
||||
- `/#fff` : 图标的颜色为 `#fff`
|
||||
- `/rgb(255,0,0)`: 图标的颜色为 `rgb(255,0,0)`
|
||||
|
||||
## Iconify
|
||||
|
||||
[iconify](https://iconify.design/) 提供了 **200K +** 的开源图标支持,足以满足大多数项目的需求。
|
||||
主题将 **iconify** 作为默认的图标来源支持。
|
||||
|
||||
在 Markdown 中使用 `::collect:name` 语法来插入图标。
|
||||
|
||||
### 配置
|
||||
|
||||
```ts title=".vuepress/config.ts" twoslash
|
||||
import { defineUserConfig } from 'vuepress'
|
||||
import { plumeTheme } from 'vuepress-theme-plume'
|
||||
|
||||
export default defineUserConfig({
|
||||
theme: plumeTheme({
|
||||
markdown: { // [!code ++:3]
|
||||
icon: { provider: 'iconify' } // 默认支持
|
||||
}
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
```ts
|
||||
interface IconOptions {
|
||||
provider: 'iconify'
|
||||
prefix?: string
|
||||
}
|
||||
```
|
||||
|
||||
### 使用
|
||||
|
||||
::: steps
|
||||
|
||||
- 从 [iconify search](https://icon-sets.iconify.design/) 搜索想要使用的图标,复制图标名称:
|
||||
|
||||

|
||||
|
||||
- 在 Markdown 中使用 `::collect:name` 语法来插入图标
|
||||
|
||||
```md
|
||||
::carbon:home::
|
||||
```
|
||||
|
||||
**输出:** ::carbon:home::
|
||||
|
||||
:::
|
||||
|
||||
在 Iconify 中,图标被分为不同的 `collect`,每个 `collect` 下有若干个图标。
|
||||
在 `::collect:name` 语法中,使用 `:` 来分隔 `collect` 和 `name`。
|
||||
|
||||
如果你主要使用某个 `collect` 下的图标,可以在配置中指定 `prefix`, 以便在 `::collect:name` 语法中省略 `collect` 前缀:
|
||||
|
||||
```ts title=".vuepress/config.ts" twoslash
|
||||
import { defineUserConfig } from 'vuepress'
|
||||
import { plumeTheme } from 'vuepress-theme-plume'
|
||||
|
||||
export default defineUserConfig({
|
||||
theme: plumeTheme({
|
||||
markdown: {
|
||||
icon: {
|
||||
provider: 'iconify',
|
||||
prefix: 'carbon', // 默认使用 `collect` 图标集合 // [!code ++]
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
```md
|
||||
::home:: <!-- 默认使用 `carbon` 图标集,自动补全为 `carbon:home` -->
|
||||
::solar:user-bold:: <!-- 显式的使用其他图标集 -->
|
||||
```
|
||||
|
||||
**输出:** ::carbon:home:: ::solar:user-bold::
|
||||
|
||||
### 安装
|
||||
|
||||
对于企业内部项目,或无法访问外部网络资源的情况下,主题推荐安装 `@iconify/json` 依赖。
|
||||
|
||||
主题自动解析 `@iconify/json` 中的图标数据,将已使用的图标打包为本地资源。
|
||||
|
||||
::: npm-to
|
||||
|
||||
@ -39,38 +174,7 @@ npm install @iconify/json
|
||||
|
||||
:::
|
||||
|
||||
## 语法
|
||||
|
||||
```md
|
||||
::collect:name::
|
||||
```
|
||||
|
||||
设置图标大小和颜色
|
||||
|
||||
```md
|
||||
::collect:name =size::
|
||||
::collect:name /color::
|
||||
::collect:name =size /color::
|
||||
```
|
||||
|
||||
`iconify` 拥有非常多的图标,这些图标被分组为不同的 `collect`,每个 `collect` 都有自己的
|
||||
图标。
|
||||
|
||||
你可以从 <https://icon-sets.iconify.design/> 中获取 collect 和 name。
|
||||
|
||||
## 示例
|
||||
|
||||
输入:
|
||||
|
||||
```md
|
||||
::ion:logo-markdown::
|
||||
```
|
||||
|
||||
输出:
|
||||
|
||||
::ion:logo-markdown::
|
||||
|
||||
该语法为行内语法,因此,你可以在同一行中跟其他 markdown 语法 一起使用。
|
||||
### 示例
|
||||
|
||||
输入:
|
||||
|
||||
@ -91,3 +195,243 @@ github: ::tdesign:logo-github-filled::
|
||||
修改大小颜色:::tdesign:logo-github-filled =36px /#f00::
|
||||
|
||||
彩色图标 ::skill-icons:vscode-dark =36px::
|
||||
|
||||
## Iconfont
|
||||
|
||||
[iconfont](https://www.iconfont.cn/) 是提供了海量的图标支持。
|
||||
|
||||
### 配置
|
||||
|
||||
```ts title=".vuepress/config.ts" twoslash
|
||||
import { defineUserConfig } from 'vuepress'
|
||||
import { plumeTheme } from 'vuepress-theme-plume'
|
||||
|
||||
export default defineUserConfig({
|
||||
theme: plumeTheme({
|
||||
markdown: { // [!code ++:3]
|
||||
icon: {
|
||||
provider: 'iconfont',
|
||||
assets: 'https://at.alicdn.com/t/c/xxxx.css' // 示例地址
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
```ts
|
||||
interface IconOptions {
|
||||
provider: 'iconfont'
|
||||
/**
|
||||
* 图标前缀
|
||||
* @default 'iconfont icon-'
|
||||
*/
|
||||
prefix?: string
|
||||
|
||||
/**
|
||||
* iconfont 资源地址
|
||||
*/
|
||||
assets: string | string[]
|
||||
}
|
||||
```
|
||||
|
||||
### 使用
|
||||
|
||||
[前往 **iconfont 帮助中心** 了解 **创建项目**和 **添加图标**](https://www.iconfont.cn/help/detail){.read-more}
|
||||
|
||||
:::steps
|
||||
|
||||
- 从 iconfont 获取项目的资源地址,复制并粘贴到 `assets` 配置中:
|
||||
|
||||

|
||||
|
||||
```ts title=".vuepress/config.ts"
|
||||
export default defineUserConfig({
|
||||
theme: plumeTheme({
|
||||
markdown: {
|
||||
icon: {
|
||||
provider: 'iconfont',
|
||||
assets: 'https://at.alicdn.com/t/c/xxxx.css' // 示例地址 // [!code ++]
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
也可以选择下载至本地,将资源存放到 `.vuepress/public` 目录中,然后在 `assets` 配置中填写本地文件路径。
|
||||
|
||||
- 检查 iconfont 的项目配置,获取 `prefix` 配置:
|
||||
|
||||

|
||||
|
||||
其中 `prefix` 配置由 `font family` 和 `font class` 前缀组成,如果 iconfont 的项目配置为默认配置,
|
||||
则 `prefix` 为 `iconfont icon-`,此时你可以忽略此步骤。
|
||||
|
||||
```ts title=".vuepress/config.ts"
|
||||
export default defineUserConfig({
|
||||
theme: plumeTheme({
|
||||
markdown: {
|
||||
icon: {
|
||||
provider: 'iconfont',
|
||||
prefix: 'iconfont icon-', // 默认值 // [!code ++]
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
- 在 Markdown 中使用 `::name::` 语法来插入图标:
|
||||
|
||||

|
||||
|
||||
将图片中的 `font class` 填入 `::name::` 语法中:
|
||||
|
||||
```md
|
||||
::hot::
|
||||
::hot =24px::
|
||||
::hot =24px /#f00::
|
||||
```
|
||||
|
||||
输出:
|
||||
<VPIcon provider="iconfont" name="hot" />
|
||||
<VPIcon provider="iconfont" name="hot" size="24px" />
|
||||
<VPIcon provider="iconfont" name="hot" size="24px" color="#f00" />
|
||||
|
||||
:::
|
||||
|
||||
## Fontawesome
|
||||
|
||||
[Fontawesome](https://fontawesome.com/) 提供了 免费 和 付费 的图标支持,付费图标需要进行订阅。
|
||||
|
||||
[查看 **Fontawesome** 官方文档](https://docs.fontawesome.com/web/setup/get-started){.read-more}
|
||||
|
||||
### 配置
|
||||
|
||||
```ts title=".vuepress/config.ts" twoslash
|
||||
import { defineUserConfig } from 'vuepress'
|
||||
import { plumeTheme } from 'vuepress-theme-plume'
|
||||
|
||||
export default defineUserConfig({
|
||||
theme: plumeTheme({
|
||||
markdown: { // [!code ++:3]
|
||||
icon: {
|
||||
provider: 'fontawesome',
|
||||
assets: 'fontawesome' // 预设资源地址,从 CDN 加载
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
```ts
|
||||
interface IconOptions {
|
||||
provider: 'fontawesome'
|
||||
/**
|
||||
* 图标前缀
|
||||
* @default 'fas'
|
||||
*/
|
||||
prefix?: FontAwesomePrefix
|
||||
/**
|
||||
* iconfont 资源地址
|
||||
*/
|
||||
assets: (FontAwesomeAssetBuiltin | string)[]
|
||||
}
|
||||
|
||||
type FontAwesomeAssetBuiltin = 'fontawesome' | 'fontawesome-with-brands'
|
||||
|
||||
type FontAwesomePrefix =
|
||||
| 'fas' | 's' // fa-solid fa-name
|
||||
| 'far' | 'r' // fa-regular fa-name
|
||||
| 'fal' | 'l' // fa-light fa-name
|
||||
| 'fat' | 't' // fa-thin fa-name
|
||||
| 'fads' | 'ds' // fa-duotone fa-solid fa-name
|
||||
| 'fass' | 'ss' // fa-sharp fa-solid fa-name
|
||||
| 'fasr' | 'sr' // fa-sharp fa-regular fa-name
|
||||
| 'fasl' | 'sl' // fa-sharp fa-light fa-name
|
||||
| 'fast' | 'st' // fa-sharp fa-thin fa-name
|
||||
| 'fasds' | 'sds' // fa-sharp-duotone fa-solid fa-name
|
||||
| 'fab' | 'b' // fa-brands fa-name
|
||||
```
|
||||
|
||||
[在 **Fontawesome** 中,图标通过 families + styles 控制样式,**查看详情**](https://docs.fontawesome.com/web/add-icons/how-to#setting-different-families--styles){.read-more}
|
||||
|
||||
为便于管理,可以通过 `::prefix:name` 语法,通过前缀设置 families + styles,默认前缀为 `fas`,可以省略它:
|
||||
|
||||
```md
|
||||
::name:: <!-- prefix = fas -->
|
||||
::fas:name:: <!-- prefix = fas -->
|
||||
::s:name:: <!-- prefix = fas , s 为 fas 的缩写 -->
|
||||
```
|
||||
|
||||
可以通过配置 `markdown.icon.prefix` 修改默认前缀。
|
||||
|
||||
::: tip
|
||||
Fontawesome 的免费图标仅支持 `solid` 、部分 `regular` 以及 `brands`,
|
||||
对于免费版本,前缀仅支持 `fas` / `far` / `fab` 和它们的缩写前缀。
|
||||
:::
|
||||
|
||||
### 使用
|
||||
|
||||
[前往 **https://fontawesome.com/search?ic=free** 搜索免费图标](https://fontawesome.com/search?ic=free){.read-more}
|
||||
|
||||
:::steps
|
||||
|
||||
- 复制图标名称:
|
||||
|
||||

|
||||
|
||||
- 在 Markdown 中使用 `::prefix:name` 语法插入图标:
|
||||
|
||||
```md
|
||||
::circle-user:: <!-- prefix = fas -->
|
||||
::fas:circle-user:: <!-- prefix = fas -->
|
||||
::s:circle-user:: <!-- prefix = fas, s 为 fas 的缩写 -->
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
### 示例
|
||||
|
||||
```md
|
||||
::circle-user::
|
||||
::circle-user =24px::
|
||||
::circle-user =24px /#f00::
|
||||
```
|
||||
|
||||
输出:
|
||||
|
||||
<VPIcon provider="fontawesome" name="circle-user" />
|
||||
<VPIcon provider="fontawesome" name="circle-user" size="24px" />
|
||||
<VPIcon provider="fontawesome" name="circle-user" size="24px" color="#f00" />
|
||||
|
||||
[为 Fontawesome 添加更多样式支持](https://docs.fontawesome.com/web/style/styling){.read-more}
|
||||
|
||||
```
|
||||
::circle-user 2xl:: <!-- 2xl 为 fa-2xl 的缩写, 图标大小为 2em -->
|
||||
::circle-user rotate-90:: <!-- 图标旋转 90 度 -->
|
||||
::circle-user beat:: <!-- 图标动画 -->
|
||||
::circle-user border:: <!-- 图标边框 -->
|
||||
::circle-user 2xl beat:: <!-- 混合多种样式 -->
|
||||
```
|
||||
|
||||
输出:
|
||||
|
||||
<VPIcon provider="fontawesome" name="circle-user" extra="2xl" />
|
||||
<VPIcon provider="fontawesome" name="circle-user" extra="rotate-90" />
|
||||
<VPIcon provider="fontawesome" name="circle-user" extra="beat" />
|
||||
<VPIcon provider="fontawesome" name="circle-user" extra="border" />
|
||||
<VPIcon provider="fontawesome" name="circle-user" extra="2xl beat" />
|
||||
|
||||
## 其它说明
|
||||
|
||||
当 `markdown.icon.provider` 设置为非 `iconify` 时,`iconify` 作为默认支持,依然可以在
|
||||
markdown 中插入 iconify 图标:
|
||||
|
||||
在 `::collect:name::` 语法中,在开始位置添加 `iconify`:
|
||||
|
||||
```md /iconify /
|
||||
::iconify carbon:home::
|
||||
```
|
||||
|
||||
输出:
|
||||
|
||||
::iconify carbon:home::
|
||||
|
||||
@ -481,8 +481,19 @@ const typescript = defineNoteConfig({
|
||||
|
||||
### 侧边栏图标
|
||||
|
||||
为侧边栏添加 ==图标== 有助于 侧边栏更好的呈现。得益于 [iconify](https://iconify.design/) 这个强大的开源图标库,
|
||||
你可以使用超过 `200k` 的图标,仅需要添加 `icon` 配置即可。
|
||||
为侧边栏添加 ==图标== 有助于 侧边栏更好的呈现。
|
||||
|
||||
支持通过 [markdown -> icon](../guide/features/icon.md) 配置的来源的图标。
|
||||
|
||||
- 当 `markdown.icon.provide` 为 `iconify` 时,支持 [iconify](https://iconify.design/) 图标
|
||||
- 当 `markdown.icon.provide` 为 `iconfont` 时,支持 [iconfont](https://www.iconfont.cn/) 图标
|
||||
- 当 `markdown.icon.provide` 为 `fontawesome` 时,支持 [fontawesome](https://fontawesome.com/) 图标
|
||||
|
||||
`markdown.icon.provide` 为非 `iconify` 值时,可以在 图标名称前加上 `iconify` 前缀,强制使用 [iconify](https://iconify.design/) 图标。
|
||||
|
||||
```ts
|
||||
const item = { text: '首页', link: '/', icon: 'iconify carbon:home' }
|
||||
```
|
||||
|
||||
```ts title=".vuepress/notes.ts" twoslash
|
||||
import { defineNoteConfig } from 'vuepress-theme-plume'
|
||||
|
||||
@ -7,13 +7,13 @@ exports[`codeTabsPlugin > should work with default 1`] = `
|
||||
</code></pre>
|
||||
</div></template><template #tab2="{ value, isActive }"><div class="language-lang"><pre><code>const c = 3
|
||||
</code></pre>
|
||||
</div></template></CodeTabs><CodeTabs id="11" :data='[{"id":"npm"},{"id":"pnpm"},{"id":"yarn"}]' :active="1"><template #title0="{ value, isActive }"><VPIcon name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #title2="{ value, isActive }"><VPIcon name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>npm i
|
||||
</div></template></CodeTabs><CodeTabs id="11" :data='[{"id":"npm"},{"id":"pnpm"},{"id":"yarn"}]' :active="1"><template #title0="{ value, isActive }"><VPIcon provider="iconify" name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #title2="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>npm i
|
||||
</code></pre>
|
||||
</div></template><template #tab1="{ value, isActive }"><div class="language-lang"><pre><code>pnpm i
|
||||
</code></pre>
|
||||
</div></template><template #tab2="{ value, isActive }"><div class="language-lang"><pre><code>yarn
|
||||
</code></pre>
|
||||
</div></template></CodeTabs><CodeTabs id="22" :data='[{"id":"a.ts"},{"id":"a.js"}]' tab-id="pm"><template #title0="{ value, isActive }"><VPIcon name="vscode-icons:file-type-typescript"/><span>a.ts</span></template><template #title1="{ value, isActive }"><VPIcon name="vscode-icons:file-type-js"/><span>a.js</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>const a = 1
|
||||
</div></template></CodeTabs><CodeTabs id="22" :data='[{"id":"a.ts"},{"id":"a.js"}]' tab-id="pm"><template #title0="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-typescript"/><span>a.ts</span></template><template #title1="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-js"/><span>a.js</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>const a = 1
|
||||
</code></pre>
|
||||
</div></template><template #tab1="{ value, isActive }"><div class="language-lang"><pre><code>const a = 1
|
||||
</code></pre>
|
||||
@ -67,13 +67,13 @@ exports[`codeTabsPlugin > should work with options: { named: [npm,pnpm,yarn], ex
|
||||
</code></pre>
|
||||
</div></template><template #tab2="{ value, isActive }"><div class="language-lang"><pre><code>const c = 3
|
||||
</code></pre>
|
||||
</div></template></CodeTabs><CodeTabs id="11" :data='[{"id":"npm"},{"id":"pnpm"},{"id":"yarn"}]' :active="1"><template #title0="{ value, isActive }"><VPIcon name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #title2="{ value, isActive }"><VPIcon name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>npm i
|
||||
</div></template></CodeTabs><CodeTabs id="11" :data='[{"id":"npm"},{"id":"pnpm"},{"id":"yarn"}]' :active="1"><template #title0="{ value, isActive }"><VPIcon provider="iconify" name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #title2="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>npm i
|
||||
</code></pre>
|
||||
</div></template><template #tab1="{ value, isActive }"><div class="language-lang"><pre><code>pnpm i
|
||||
</code></pre>
|
||||
</div></template><template #tab2="{ value, isActive }"><div class="language-lang"><pre><code>yarn
|
||||
</code></pre>
|
||||
</div></template></CodeTabs><CodeTabs id="22" :data='[{"id":"a.ts"},{"id":"a.js"}]' tab-id="pm"><template #title0="{ value, isActive }"><VPIcon name="vscode-icons:file-type-typescript"/><span>a.ts</span></template><template #title1="{ value, isActive }"><VPIcon name="vscode-icons:file-type-js"/><span>a.js</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>const a = 1
|
||||
</div></template></CodeTabs><CodeTabs id="22" :data='[{"id":"a.ts"},{"id":"a.js"}]' tab-id="pm"><template #title0="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-typescript"/><span>a.ts</span></template><template #title1="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-js"/><span>a.js</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>const a = 1
|
||||
</code></pre>
|
||||
</div></template><template #tab1="{ value, isActive }"><div class="language-lang"><pre><code>const a = 1
|
||||
</code></pre>
|
||||
|
||||
@ -72,91 +72,91 @@ exports[`fileTree > parseFileTreeRawContent > should work 1`] = `
|
||||
|
||||
exports[`fileTreePlugin > should work with default options 1`] = `
|
||||
"<div class="vp-file-tree"><FileTreeNode expanded type="folder" filename="docs" :level="0">
|
||||
<template #icon><VPIcon name="vscode-icons:folder-type-docs" /></template><FileTreeNode type="file" filename="README.md" :level="1">
|
||||
<template #icon><VPIcon name="flat-color-icons:info" /></template>
|
||||
<template #icon><VPIcon provider="iconify" name="vscode-icons:folder-type-docs" /></template><FileTreeNode type="file" filename="README.md" :level="1">
|
||||
<template #icon><VPIcon provider="iconify" name="flat-color-icons:info" /></template>
|
||||
</FileTreeNode>
|
||||
<FileTreeNode type="file" filename="foo.md" :level="1">
|
||||
<template #icon><VPIcon name="vscode-icons:file-type-markdown" /></template>
|
||||
<template #icon><VPIcon provider="iconify" name="vscode-icons:file-type-markdown" /></template>
|
||||
</FileTreeNode>
|
||||
</FileTreeNode>
|
||||
<FileTreeNode expanded type="folder" filename="src" :level="0">
|
||||
<template #icon><VPIcon name="vscode-icons:folder-type-src" /></template><FileTreeNode expanded type="folder" filename="client" :level="1">
|
||||
<template #icon><VPIcon name="vscode-icons:folder-type-client" /></template><FileTreeNode expanded type="folder" filename="components" :level="2">
|
||||
<template #icon><VPIcon name="vscode-icons:folder-type-component" /></template><FileTreeNode focus type="file" filename="Navbar.vue" :level="3">
|
||||
<template #icon><VPIcon name="vscode-icons:file-type-vue" /></template>
|
||||
<template #icon><VPIcon provider="iconify" name="vscode-icons:folder-type-src" /></template><FileTreeNode expanded type="folder" filename="client" :level="1">
|
||||
<template #icon><VPIcon provider="iconify" name="vscode-icons:folder-type-client" /></template><FileTreeNode expanded type="folder" filename="components" :level="2">
|
||||
<template #icon><VPIcon provider="iconify" name="vscode-icons:folder-type-component" /></template><FileTreeNode focus type="file" filename="Navbar.vue" :level="3">
|
||||
<template #icon><VPIcon provider="iconify" name="vscode-icons:file-type-vue" /></template>
|
||||
</FileTreeNode>
|
||||
</FileTreeNode>
|
||||
<FileTreeNode type="file" filename="index.ts" :level="2">
|
||||
<template #icon><VPIcon name="vscode-icons:file-type-typescript" /></template><template #comment># comment</template>
|
||||
<template #icon><VPIcon provider="iconify" name="vscode-icons:file-type-typescript" /></template><template #comment># comment</template>
|
||||
</FileTreeNode>
|
||||
</FileTreeNode>
|
||||
<FileTreeNode expanded type="folder" filename="node" :level="1">
|
||||
<template #icon><VPIcon name="vscode-icons:default-folder" /></template><FileTreeNode type="file" filename="index.ts" :level="2">
|
||||
<template #icon><VPIcon name="vscode-icons:file-type-typescript" /></template>
|
||||
<template #icon><VPIcon provider="iconify" name="vscode-icons:default-folder" /></template><FileTreeNode type="file" filename="index.ts" :level="2">
|
||||
<template #icon><VPIcon provider="iconify" name="vscode-icons:file-type-typescript" /></template>
|
||||
</FileTreeNode>
|
||||
</FileTreeNode>
|
||||
</FileTreeNode>
|
||||
<FileTreeNode type="file" filename=".gitignore" :level="0">
|
||||
<template #icon><VPIcon name="vscode-icons:file-type-git" /></template>
|
||||
<template #icon><VPIcon provider="iconify" name="vscode-icons:file-type-git" /></template>
|
||||
</FileTreeNode>
|
||||
<FileTreeNode type="file" filename="package.json" :level="0">
|
||||
<template #icon><VPIcon name="vscode-icons:file-type-node" /></template>
|
||||
<template #icon><VPIcon provider="iconify" name="vscode-icons:file-type-node" /></template>
|
||||
</FileTreeNode></div>
|
||||
<div class="vp-file-tree"><p class="vp-file-tree-title">files</p><FileTreeNode expanded type="folder" filename="src" :level="0">
|
||||
<template #icon><VPIcon name="vscode-icons:folder-type-src" /></template><FileTreeNode expanded type="folder" filename="js" :level="1">
|
||||
<template #icon><VPIcon name="vscode-icons:default-folder" /></template><FileTreeNode type="file" filename="…" :level="2">
|
||||
<template #icon><VPIcon provider="iconify" name="vscode-icons:folder-type-src" /></template><FileTreeNode expanded type="folder" filename="js" :level="1">
|
||||
<template #icon><VPIcon provider="iconify" name="vscode-icons:default-folder" /></template><FileTreeNode type="file" filename="…" :level="2">
|
||||
|
||||
</FileTreeNode>
|
||||
</FileTreeNode>
|
||||
<FileTreeNode type="folder" filename="vue" :level="1">
|
||||
<template #icon><VPIcon name="vscode-icons:default-folder" /></template><FileTreeNode type="file" filename="…" :level="2">
|
||||
<template #icon><VPIcon provider="iconify" name="vscode-icons:default-folder" /></template><FileTreeNode type="file" filename="…" :level="2">
|
||||
|
||||
</FileTreeNode>
|
||||
</FileTreeNode>
|
||||
<FileTreeNode type="folder" filename="css" :level="1">
|
||||
<template #icon><VPIcon name="vscode-icons:folder-type-css" /></template><FileTreeNode type="file" filename="…" :level="2">
|
||||
<template #icon><VPIcon provider="iconify" name="vscode-icons:folder-type-css" /></template><FileTreeNode type="file" filename="…" :level="2">
|
||||
|
||||
</FileTreeNode>
|
||||
</FileTreeNode>
|
||||
</FileTreeNode>
|
||||
<FileTreeNode type="file" filename="README.md" :level="0">
|
||||
<template #icon><VPIcon name="flat-color-icons:info" /></template>
|
||||
<template #icon><VPIcon provider="iconify" name="flat-color-icons:info" /></template>
|
||||
</FileTreeNode></div>
|
||||
<div class="vp-file-tree"><FileTreeNode type="file" filename="docs" :level="0">
|
||||
<template #icon><VPIcon name="vscode-icons:default-file" /></template>
|
||||
<template #icon><VPIcon provider="iconify" name="vscode-icons:default-file" /></template>
|
||||
</FileTreeNode>
|
||||
<FileTreeNode expanded type="folder" filename="src" :level="0">
|
||||
<template #icon><VPIcon name="vscode-icons:default-folder" /></template><FileTreeNode type="file" filename="a.js" :level="1">
|
||||
<template #icon><VPIcon name="vscode-icons:default-file" /></template>
|
||||
<template #icon><VPIcon provider="iconify" name="vscode-icons:default-folder" /></template><FileTreeNode type="file" filename="a.js" :level="1">
|
||||
<template #icon><VPIcon provider="iconify" name="vscode-icons:default-file" /></template>
|
||||
</FileTreeNode>
|
||||
<FileTreeNode type="file" filename="b.ts" :level="1">
|
||||
<template #icon><VPIcon name="vscode-icons:default-file" /></template>
|
||||
<template #icon><VPIcon provider="iconify" name="vscode-icons:default-file" /></template>
|
||||
</FileTreeNode>
|
||||
</FileTreeNode>
|
||||
<FileTreeNode type="file" filename="README.md" :level="0">
|
||||
<template #icon><VPIcon name="vscode-icons:default-file" /></template>
|
||||
<template #icon><VPIcon provider="iconify" name="vscode-icons:default-file" /></template>
|
||||
</FileTreeNode></div>
|
||||
<div class="vp-file-tree"><FileTreeNode type="file" filename="" :level="0">
|
||||
<template #icon><VPIcon name="vscode-icons:default-file" /></template>
|
||||
<template #icon><VPIcon provider="iconify" name="vscode-icons:default-file" /></template>
|
||||
</FileTreeNode>
|
||||
<FileTreeNode expanded type="folder" filename="" :level="0">
|
||||
<template #icon><VPIcon name="vscode-icons:default-folder" /></template><FileTreeNode type="file" filename="" :level="1">
|
||||
<template #icon><VPIcon name="vscode-icons:default-file" /></template>
|
||||
<template #icon><VPIcon provider="iconify" name="vscode-icons:default-folder" /></template><FileTreeNode type="file" filename="" :level="1">
|
||||
<template #icon><VPIcon provider="iconify" name="vscode-icons:default-file" /></template>
|
||||
</FileTreeNode>
|
||||
</FileTreeNode></div>
|
||||
<div class="vp-file-tree"><FileTreeNode expanded type="folder" filename="docs" :level="0">
|
||||
<template #icon><VPIcon name="vscode-icons:folder-type-docs" /></template><FileTreeNode type="file" diff="add" filename="added.md" :level="1">
|
||||
<template #icon><VPIcon name="vscode-icons:file-type-markdown" /></template>
|
||||
<template #icon><VPIcon provider="iconify" name="vscode-icons:folder-type-docs" /></template><FileTreeNode type="file" diff="add" filename="added.md" :level="1">
|
||||
<template #icon><VPIcon provider="iconify" name="vscode-icons:file-type-markdown" /></template>
|
||||
</FileTreeNode>
|
||||
<FileTreeNode type="file" diff="remove" filename="remove.md" :level="1">
|
||||
<template #icon><VPIcon name="vscode-icons:file-type-markdown" /></template>
|
||||
<template #icon><VPIcon provider="iconify" name="vscode-icons:file-type-markdown" /></template>
|
||||
</FileTreeNode>
|
||||
</FileTreeNode>
|
||||
<FileTreeNode type="file" diff="add" filename="src" :level="0">
|
||||
<template #icon><VPIcon name="vscode-icons:default-file" /></template>
|
||||
<template #icon><VPIcon provider="iconify" name="vscode-icons:default-file" /></template>
|
||||
</FileTreeNode>
|
||||
<FileTreeNode type="file" diff="remove" filename="source" :level="0">
|
||||
<template #icon><VPIcon name="vscode-icons:default-file" /></template>
|
||||
<template #icon><VPIcon provider="iconify" name="vscode-icons:default-file" /></template>
|
||||
</FileTreeNode></div>
|
||||
<div class="vp-file-tree"></div>
|
||||
"
|
||||
|
||||
@ -1,108 +1,91 @@
|
||||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||
|
||||
exports[`iconsPlugin > should not work with invalid icon 1`] = `
|
||||
exports[`iconPlugin > should not work with invalid icon 1`] = `
|
||||
"<p>:: mdi:11 ::</p>
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`iconsPlugin > should not work with invalid icon 2`] = `
|
||||
exports[`iconPlugin > should not work with invalid icon 2`] = `
|
||||
"<p>::::</p>
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`iconsPlugin > should not work with invalid icon 3`] = `
|
||||
exports[`iconPlugin > should not work with invalid icon 3`] = `
|
||||
"<p>::]&</p>
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`iconsPlugin > should not work with invalid icon 4`] = `
|
||||
"<p>::::</p>
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`iconsPlugin > should not work with invalid icon 5`] = `
|
||||
exports[`iconPlugin > should not work with invalid icon 4`] = `
|
||||
"<p>::mdi:11</p>
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`iconsPlugin > should work 1`] = `
|
||||
"<p><VPIcon name="mdi:11" /></p>
|
||||
exports[`iconPlugin > should work with options -> { provider: "fontawesome", prefix } 1`] = `
|
||||
"<p><VPIcon provider="fontawesome" name="home" /></p>
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`iconsPlugin > should work 2`] = `
|
||||
"<p><strong>strong</strong> <VPIcon name="mdi:11" /> <VPIcon name="mdi:11" /></p>
|
||||
exports[`iconPlugin > should work with options -> { provider: "fontawesome", prefix } 2`] = `
|
||||
"<p><VPIcon provider="fontawesome" size="32px" name="home" /></p>
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`iconsPlugin > should work 3`] = `
|
||||
"<p><strong>strong</strong>
|
||||
<VPIcon name="mdi:11" />
|
||||
<VPIcon name="mdi:11" /></p>
|
||||
exports[`iconPlugin > should work with options -> { provider: "fontawesome", prefix } 3`] = `
|
||||
"<p><VPIcon provider="fontawesome" color="#eee" name="home" /></p>
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`iconsPlugin > should work with options 1`] = `
|
||||
"<p><VPIcon name="mdi:11" size="1.25em" color="#ccc" /></p>
|
||||
exports[`iconPlugin > should work with options -> { provider: "fontawesome", prefix } 4`] = `
|
||||
"<p><VPIcon provider="fontawesome" size="32px" color="#eee" name="home" /></p>
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`iconsPlugin > should work with options 2`] = `
|
||||
"<p><strong>strong</strong> <VPIcon name="mdi:11" size="1.25em" color="#ccc" /> <VPIcon name="mdi:11" size="1.25em" color="#ccc" /></p>
|
||||
exports[`iconPlugin > should work with options -> { provider: "fontawesome", prefix } 5`] = `
|
||||
"<p><VPIcon provider="fontawesome" name="fas:home" /></p>
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`iconsPlugin > should work with single icon options 1`] = `
|
||||
"<p><VPIcon name="mdi:11" size="36px" /></p>
|
||||
exports[`iconPlugin > should work with options -> { provider: "fontawesome", prefix } 6`] = `
|
||||
"<p><VPIcon provider="fontawesome" name="fas:home" extra="2xl" data-fa-transform="shrink-8" /></p>
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`iconsPlugin > should work with single icon options 2`] = `
|
||||
"<p><VPIcon name="mdi:11" size="32px" color="#eee" /></p>
|
||||
exports[`iconPlugin > should work with options -> { provider: "iconfont", prefix } 1`] = `
|
||||
"<p><VPIcon provider="iconfont" name="home" /></p>
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`iconsPlugin > should work with single icon options 3`] = `
|
||||
"<p><VPIcon name="mdi:11" color="#eee" /></p>
|
||||
exports[`iconPlugin > should work with options -> { provider: "iconfont", prefix } 2`] = `
|
||||
"<p><VPIcon provider="iconfont" size="32px" name="home" /></p>
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`iconsPlugin > should work with single icon options 4`] = `
|
||||
"<p><VPIcon name="mdi:11" size="32px/" /></p>
|
||||
exports[`iconPlugin > should work with options -> { provider: "iconfont", prefix } 3`] = `
|
||||
"<p><VPIcon provider="iconfont" color="#eee" name="home" /></p>
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`iconsPlugin > should work with single icon options 5`] = `
|
||||
"<p><VPIcon name="mdi:11" class="/" /></p>
|
||||
exports[`iconPlugin > should work with options -> { provider: "iconfont", prefix } 4`] = `
|
||||
"<p><VPIcon provider="iconfont" size="32px" color="#eee" name="home" /></p>
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`iconsPlugin > should work with single icon options 6`] = `
|
||||
"<p><VPIcon name="mdi:11" size="1.25em" color="#ccc" /></p>
|
||||
exports[`iconPlugin > should work with options -> { provider: "iconify", prefix } 1`] = `
|
||||
"<p><VPIcon provider="iconify" name="11" /></p>
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`iconsPlugin > should work with single icon options 7`] = `
|
||||
"<p><VPIcon name="mdi:11" size="36px" color="#ccc" /></p>
|
||||
exports[`iconPlugin > should work with options -> { provider: "iconify", prefix } 2`] = `
|
||||
"<p><VPIcon provider="iconify" size="32px" color="#eee" name="11" /></p>
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`iconsPlugin > should work with single icon options 8`] = `
|
||||
"<p><VPIcon name="mdi:11" size="32px/#eee" color="#ccc" /></p>
|
||||
exports[`iconPlugin > should work with options -> { provider: "iconify", prefix } 3`] = `
|
||||
"<p><VPIcon provider="iconify" color="#eee" name="mdi:11" /></p>
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`iconsPlugin > should work with single icon options 9`] = `
|
||||
"<p><VPIcon name="mdi:11" size="1.25em" color="#eee" /></p>
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`iconsPlugin > should work with single icon options 10`] = `
|
||||
"<p><VPIcon name="mdi:11" size="32px/" color="#ccc" /></p>
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`iconsPlugin > should work with single icon options 11`] = `
|
||||
"<p><VPIcon name="mdi:11" size="1.25em" color="#ccc" class="/" /></p>
|
||||
exports[`iconPlugin > should work with options -> { provider: "iconify", prefix } 4`] = `
|
||||
"<p><VPIcon provider="iconify" size="32px/" name="fas:11" /></p>
|
||||
"
|
||||
`;
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||
|
||||
exports[`npmToPlugin > should work width options: [npm, yarn, pnpm] 1`] = `
|
||||
"<CodeTabs id="0" :data='[{"id":"npm"},{"id":"yarn"},{"id":"pnpm"}]' tab-id="npm-to-npm-yarn-pnpm"><template #title0="{ value, isActive }"><VPIcon name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #title2="{ value, isActive }"><VPIcon name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>
|
||||
"<CodeTabs id="0" :data='[{"id":"npm"},{"id":"yarn"},{"id":"pnpm"}]' tab-id="npm-to-npm-yarn-pnpm"><template #title0="{ value, isActive }"><VPIcon provider="iconify" name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #title2="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>
|
||||
</code></pre>
|
||||
</div></template><template #tab1="{ value, isActive }"><div class="language-lang"><pre><code>
|
||||
</code></pre>
|
||||
</div></template><template #tab2="{ value, isActive }"><div class="language-lang"><pre><code>
|
||||
</code></pre>
|
||||
</div></template></CodeTabs><CodeTabs id="0" :data='[{"id":"npm"},{"id":"yarn"},{"id":"pnpm"}]' tab-id="npm-to-npm-yarn-pnpm"><template #title0="{ value, isActive }"><VPIcon name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #title2="{ value, isActive }"><VPIcon name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>npm install
|
||||
</div></template></CodeTabs><CodeTabs id="0" :data='[{"id":"npm"},{"id":"yarn"},{"id":"pnpm"}]' tab-id="npm-to-npm-yarn-pnpm"><template #title0="{ value, isActive }"><VPIcon provider="iconify" name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #title2="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>npm install
|
||||
|
||||
</code></pre>
|
||||
</div></template><template #tab1="{ value, isActive }"><div class="language-lang"><pre><code>yarn
|
||||
@ -16,7 +16,7 @@ exports[`npmToPlugin > should work width options: [npm, yarn, pnpm] 1`] = `
|
||||
</div></template><template #tab2="{ value, isActive }"><div class="language-lang"><pre><code>pnpm install
|
||||
|
||||
</code></pre>
|
||||
</div></template></CodeTabs><CodeTabs id="0" :data='[{"id":"npm"},{"id":"yarn"},{"id":"pnpm"}]' tab-id="npm-to-npm-yarn-pnpm"><template #title0="{ value, isActive }"><VPIcon name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #title2="{ value, isActive }"><VPIcon name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>npm install
|
||||
</div></template></CodeTabs><CodeTabs id="0" :data='[{"id":"npm"},{"id":"yarn"},{"id":"pnpm"}]' tab-id="npm-to-npm-yarn-pnpm"><template #title0="{ value, isActive }"><VPIcon provider="iconify" name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #title2="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>npm install
|
||||
|
||||
</code></pre>
|
||||
</div></template><template #tab1="{ value, isActive }"><div class="language-lang"><pre><code>yarn
|
||||
@ -25,7 +25,7 @@ exports[`npmToPlugin > should work width options: [npm, yarn, pnpm] 1`] = `
|
||||
</div></template><template #tab2="{ value, isActive }"><div class="language-lang"><pre><code>pnpm install
|
||||
|
||||
</code></pre>
|
||||
</div></template></CodeTabs><CodeTabs id="0" :data='[{"id":"npm"},{"id":"yarn"},{"id":"pnpm"}]' tab-id="npm-to-npm-yarn-pnpm"><template #title0="{ value, isActive }"><VPIcon name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #title2="{ value, isActive }"><VPIcon name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>npm install
|
||||
</div></template></CodeTabs><CodeTabs id="0" :data='[{"id":"npm"},{"id":"yarn"},{"id":"pnpm"}]' tab-id="npm-to-npm-yarn-pnpm"><template #title0="{ value, isActive }"><VPIcon provider="iconify" name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #title2="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>npm install
|
||||
|
||||
</code></pre>
|
||||
</div></template><template #tab1="{ value, isActive }"><div class="language-lang"><pre><code>yarn
|
||||
@ -34,7 +34,7 @@ exports[`npmToPlugin > should work width options: [npm, yarn, pnpm] 1`] = `
|
||||
</div></template><template #tab2="{ value, isActive }"><div class="language-lang"><pre><code>pnpm install
|
||||
|
||||
</code></pre>
|
||||
</div></template></CodeTabs><CodeTabs id="0" :data='[{"id":"npm"},{"id":"yarn"},{"id":"pnpm"}]' tab-id="npm-to-npm-yarn-pnpm"><template #title0="{ value, isActive }"><VPIcon name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #title2="{ value, isActive }"><VPIcon name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>cross-env NODE_ENV=production npm run docs
|
||||
</div></template></CodeTabs><CodeTabs id="0" :data='[{"id":"npm"},{"id":"yarn"},{"id":"pnpm"}]' tab-id="npm-to-npm-yarn-pnpm"><template #title0="{ value, isActive }"><VPIcon provider="iconify" name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #title2="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>cross-env NODE_ENV=production npm run docs
|
||||
|
||||
</code></pre>
|
||||
</div></template><template #tab1="{ value, isActive }"><div class="language-lang"><pre><code>cross-env NODE_ENV=production yarn docs
|
||||
@ -43,7 +43,7 @@ exports[`npmToPlugin > should work width options: [npm, yarn, pnpm] 1`] = `
|
||||
</div></template><template #tab2="{ value, isActive }"><div class="language-lang"><pre><code>cross-env NODE_ENV=production pnpm docs
|
||||
|
||||
</code></pre>
|
||||
</div></template></CodeTabs><CodeTabs id="0" :data='[{"id":"npm"},{"id":"yarn"},{"id":"pnpm"}]' tab-id="npm-to-npm-yarn-pnpm"><template #title0="{ value, isActive }"><VPIcon name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #title2="{ value, isActive }"><VPIcon name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>npm i -D package1 package2
|
||||
</div></template></CodeTabs><CodeTabs id="0" :data='[{"id":"npm"},{"id":"yarn"},{"id":"pnpm"}]' tab-id="npm-to-npm-yarn-pnpm"><template #title0="{ value, isActive }"><VPIcon provider="iconify" name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #title2="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>npm i -D package1 package2
|
||||
npm i --save-peer package3
|
||||
npm run docs
|
||||
|
||||
@ -58,7 +58,7 @@ pnpm add --save-peer package3
|
||||
pnpm docs
|
||||
|
||||
</code></pre>
|
||||
</div></template></CodeTabs><CodeTabs id="0" :data='[{"id":"npm"},{"id":"yarn"},{"id":"pnpm"}]' tab-id="npm-to-npm-yarn-pnpm"><template #title0="{ value, isActive }"><VPIcon name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #title2="{ value, isActive }"><VPIcon name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>npm install && npm run docs
|
||||
</div></template></CodeTabs><CodeTabs id="0" :data='[{"id":"npm"},{"id":"yarn"},{"id":"pnpm"}]' tab-id="npm-to-npm-yarn-pnpm"><template #title0="{ value, isActive }"><VPIcon provider="iconify" name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #title2="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>npm install && npm run docs
|
||||
mkdir foo
|
||||
|
||||
</code></pre>
|
||||
@ -70,7 +70,7 @@ mkdir foo
|
||||
mkdir foo
|
||||
|
||||
</code></pre>
|
||||
</div></template></CodeTabs><CodeTabs id="0" :data='[{"id":"npm"},{"id":"yarn"},{"id":"pnpm"}]' tab-id="npm-to-npm-yarn-pnpm"><template #title0="{ value, isActive }"><VPIcon name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #title2="{ value, isActive }"><VPIcon name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>npm run docs -- --clean-cache --clean-temp
|
||||
</div></template></CodeTabs><CodeTabs id="0" :data='[{"id":"npm"},{"id":"yarn"},{"id":"pnpm"}]' tab-id="npm-to-npm-yarn-pnpm"><template #title0="{ value, isActive }"><VPIcon provider="iconify" name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #title2="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>npm run docs -- --clean-cache --clean-temp
|
||||
|
||||
|
||||
</code></pre>
|
||||
@ -82,7 +82,7 @@ mkdir foo
|
||||
|
||||
|
||||
</code></pre>
|
||||
</div></template></CodeTabs><CodeTabs id="0" :data='[{"id":"npm"},{"id":"pnpm"},{"id":"yarn"}]' tab-id="npm-to-npm-pnpm-yarn"><template #title0="{ value, isActive }"><VPIcon name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #title2="{ value, isActive }"><VPIcon name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>npm create vuepress-theme-plume@latest
|
||||
</div></template></CodeTabs><CodeTabs id="0" :data='[{"id":"npm"},{"id":"pnpm"},{"id":"yarn"}]' tab-id="npm-to-npm-pnpm-yarn"><template #title0="{ value, isActive }"><VPIcon provider="iconify" name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #title2="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>npm create vuepress-theme-plume@latest
|
||||
|
||||
</code></pre>
|
||||
</div></template><template #tab1="{ value, isActive }"><div class="language-lang"><pre><code>pnpm create vuepress-theme-plume@latest
|
||||
@ -91,7 +91,7 @@ mkdir foo
|
||||
</div></template><template #tab2="{ value, isActive }"><div class="language-lang"><pre><code>yarn create vuepress-theme-plume@latest
|
||||
|
||||
</code></pre>
|
||||
</div></template></CodeTabs><CodeTabs id="0" :data='[{"id":"npm"},{"id":"pnpm"},{"id":"yarn"},{"id":"bun"},{"id":"deno"}]' tab-id="npm-to-npm-pnpm-yarn-bun-deno"><template #title0="{ value, isActive }"><VPIcon name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #title2="{ value, isActive }"><VPIcon name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #title3="{ value, isActive }"><VPIcon name="vscode-icons:file-type-bun"/><span>bun</span></template><template #title4="{ value, isActive }"><VPIcon name="vscode-icons:file-type-light-deno"/><span>deno</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>npx vp-update
|
||||
</div></template></CodeTabs><CodeTabs id="0" :data='[{"id":"npm"},{"id":"pnpm"},{"id":"yarn"},{"id":"bun"},{"id":"deno"}]' tab-id="npm-to-npm-pnpm-yarn-bun-deno"><template #title0="{ value, isActive }"><VPIcon provider="iconify" name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #title2="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #title3="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-bun"/><span>bun</span></template><template #title4="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-light-deno"/><span>deno</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>npx vp-update
|
||||
|
||||
</code></pre>
|
||||
</div></template><template #tab1="{ value, isActive }"><div class="language-lang"><pre><code>pnpm dlx vp-update
|
||||
@ -106,7 +106,7 @@ mkdir foo
|
||||
</div></template><template #tab4="{ value, isActive }"><div class="language-lang"><pre><code>deno run -A vp-update
|
||||
|
||||
</code></pre>
|
||||
</div></template></CodeTabs><CodeTabs id="0" :data='[{"id":"npm"},{"id":"yarn"},{"id":"pnpm"}]' tab-id="npm-to-npm-yarn-pnpm"><template #title0="{ value, isActive }"><VPIcon name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #title2="{ value, isActive }"><VPIcon name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>mkdir foo
|
||||
</div></template></CodeTabs><CodeTabs id="0" :data='[{"id":"npm"},{"id":"yarn"},{"id":"pnpm"}]' tab-id="npm-to-npm-yarn-pnpm"><template #title0="{ value, isActive }"><VPIcon provider="iconify" name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #title2="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>mkdir foo
|
||||
|
||||
</code></pre>
|
||||
</div></template><template #tab1="{ value, isActive }"><div class="language-lang"><pre><code>mkdir foo
|
||||
@ -121,13 +121,13 @@ mkdir foo
|
||||
`;
|
||||
|
||||
exports[`npmToPlugin > should work width options: { tabs: [npm, yarn, pnpm] } 1`] = `
|
||||
"<CodeTabs id="0" :data='[{"id":"npm"},{"id":"yarn"},{"id":"pnpm"}]' tab-id="npm-to-npm-yarn-pnpm"><template #title0="{ value, isActive }"><VPIcon name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #title2="{ value, isActive }"><VPIcon name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>
|
||||
"<CodeTabs id="0" :data='[{"id":"npm"},{"id":"yarn"},{"id":"pnpm"}]' tab-id="npm-to-npm-yarn-pnpm"><template #title0="{ value, isActive }"><VPIcon provider="iconify" name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #title2="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>
|
||||
</code></pre>
|
||||
</div></template><template #tab1="{ value, isActive }"><div class="language-lang"><pre><code>
|
||||
</code></pre>
|
||||
</div></template><template #tab2="{ value, isActive }"><div class="language-lang"><pre><code>
|
||||
</code></pre>
|
||||
</div></template></CodeTabs><CodeTabs id="0" :data='[{"id":"npm"},{"id":"yarn"},{"id":"pnpm"}]' tab-id="npm-to-npm-yarn-pnpm"><template #title0="{ value, isActive }"><VPIcon name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #title2="{ value, isActive }"><VPIcon name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>npm install
|
||||
</div></template></CodeTabs><CodeTabs id="0" :data='[{"id":"npm"},{"id":"yarn"},{"id":"pnpm"}]' tab-id="npm-to-npm-yarn-pnpm"><template #title0="{ value, isActive }"><VPIcon provider="iconify" name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #title2="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>npm install
|
||||
|
||||
</code></pre>
|
||||
</div></template><template #tab1="{ value, isActive }"><div class="language-lang"><pre><code>yarn
|
||||
@ -136,7 +136,7 @@ exports[`npmToPlugin > should work width options: { tabs: [npm, yarn, pnpm] } 1`
|
||||
</div></template><template #tab2="{ value, isActive }"><div class="language-lang"><pre><code>pnpm install
|
||||
|
||||
</code></pre>
|
||||
</div></template></CodeTabs><CodeTabs id="0" :data='[{"id":"npm"},{"id":"yarn"},{"id":"pnpm"}]' tab-id="npm-to-npm-yarn-pnpm"><template #title0="{ value, isActive }"><VPIcon name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #title2="{ value, isActive }"><VPIcon name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>npm install
|
||||
</div></template></CodeTabs><CodeTabs id="0" :data='[{"id":"npm"},{"id":"yarn"},{"id":"pnpm"}]' tab-id="npm-to-npm-yarn-pnpm"><template #title0="{ value, isActive }"><VPIcon provider="iconify" name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #title2="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>npm install
|
||||
|
||||
</code></pre>
|
||||
</div></template><template #tab1="{ value, isActive }"><div class="language-lang"><pre><code>yarn
|
||||
@ -145,7 +145,7 @@ exports[`npmToPlugin > should work width options: { tabs: [npm, yarn, pnpm] } 1`
|
||||
</div></template><template #tab2="{ value, isActive }"><div class="language-lang"><pre><code>pnpm install
|
||||
|
||||
</code></pre>
|
||||
</div></template></CodeTabs><CodeTabs id="0" :data='[{"id":"npm"},{"id":"yarn"},{"id":"pnpm"}]' tab-id="npm-to-npm-yarn-pnpm"><template #title0="{ value, isActive }"><VPIcon name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #title2="{ value, isActive }"><VPIcon name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>npm install
|
||||
</div></template></CodeTabs><CodeTabs id="0" :data='[{"id":"npm"},{"id":"yarn"},{"id":"pnpm"}]' tab-id="npm-to-npm-yarn-pnpm"><template #title0="{ value, isActive }"><VPIcon provider="iconify" name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #title2="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>npm install
|
||||
|
||||
</code></pre>
|
||||
</div></template><template #tab1="{ value, isActive }"><div class="language-lang"><pre><code>yarn
|
||||
@ -154,7 +154,7 @@ exports[`npmToPlugin > should work width options: { tabs: [npm, yarn, pnpm] } 1`
|
||||
</div></template><template #tab2="{ value, isActive }"><div class="language-lang"><pre><code>pnpm install
|
||||
|
||||
</code></pre>
|
||||
</div></template></CodeTabs><CodeTabs id="0" :data='[{"id":"npm"},{"id":"yarn"},{"id":"pnpm"}]' tab-id="npm-to-npm-yarn-pnpm"><template #title0="{ value, isActive }"><VPIcon name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #title2="{ value, isActive }"><VPIcon name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>cross-env NODE_ENV=production npm run docs
|
||||
</div></template></CodeTabs><CodeTabs id="0" :data='[{"id":"npm"},{"id":"yarn"},{"id":"pnpm"}]' tab-id="npm-to-npm-yarn-pnpm"><template #title0="{ value, isActive }"><VPIcon provider="iconify" name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #title2="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>cross-env NODE_ENV=production npm run docs
|
||||
|
||||
</code></pre>
|
||||
</div></template><template #tab1="{ value, isActive }"><div class="language-lang"><pre><code>cross-env NODE_ENV=production yarn docs
|
||||
@ -163,7 +163,7 @@ exports[`npmToPlugin > should work width options: { tabs: [npm, yarn, pnpm] } 1`
|
||||
</div></template><template #tab2="{ value, isActive }"><div class="language-lang"><pre><code>cross-env NODE_ENV=production pnpm docs
|
||||
|
||||
</code></pre>
|
||||
</div></template></CodeTabs><CodeTabs id="0" :data='[{"id":"npm"},{"id":"yarn"},{"id":"pnpm"}]' tab-id="npm-to-npm-yarn-pnpm"><template #title0="{ value, isActive }"><VPIcon name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #title2="{ value, isActive }"><VPIcon name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>npm i -D package1 package2
|
||||
</div></template></CodeTabs><CodeTabs id="0" :data='[{"id":"npm"},{"id":"yarn"},{"id":"pnpm"}]' tab-id="npm-to-npm-yarn-pnpm"><template #title0="{ value, isActive }"><VPIcon provider="iconify" name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #title2="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>npm i -D package1 package2
|
||||
npm i --save-peer package3
|
||||
npm run docs
|
||||
|
||||
@ -178,7 +178,7 @@ pnpm add --save-peer package3
|
||||
pnpm docs
|
||||
|
||||
</code></pre>
|
||||
</div></template></CodeTabs><CodeTabs id="0" :data='[{"id":"npm"},{"id":"yarn"},{"id":"pnpm"}]' tab-id="npm-to-npm-yarn-pnpm"><template #title0="{ value, isActive }"><VPIcon name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #title2="{ value, isActive }"><VPIcon name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>npm install && npm run docs
|
||||
</div></template></CodeTabs><CodeTabs id="0" :data='[{"id":"npm"},{"id":"yarn"},{"id":"pnpm"}]' tab-id="npm-to-npm-yarn-pnpm"><template #title0="{ value, isActive }"><VPIcon provider="iconify" name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #title2="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>npm install && npm run docs
|
||||
mkdir foo
|
||||
|
||||
</code></pre>
|
||||
@ -190,7 +190,7 @@ mkdir foo
|
||||
mkdir foo
|
||||
|
||||
</code></pre>
|
||||
</div></template></CodeTabs><CodeTabs id="0" :data='[{"id":"npm"},{"id":"yarn"},{"id":"pnpm"}]' tab-id="npm-to-npm-yarn-pnpm"><template #title0="{ value, isActive }"><VPIcon name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #title2="{ value, isActive }"><VPIcon name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>npm run docs -- --clean-cache --clean-temp
|
||||
</div></template></CodeTabs><CodeTabs id="0" :data='[{"id":"npm"},{"id":"yarn"},{"id":"pnpm"}]' tab-id="npm-to-npm-yarn-pnpm"><template #title0="{ value, isActive }"><VPIcon provider="iconify" name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #title2="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>npm run docs -- --clean-cache --clean-temp
|
||||
|
||||
|
||||
</code></pre>
|
||||
@ -202,7 +202,7 @@ mkdir foo
|
||||
|
||||
|
||||
</code></pre>
|
||||
</div></template></CodeTabs><CodeTabs id="0" :data='[{"id":"npm"},{"id":"pnpm"},{"id":"yarn"}]' tab-id="npm-to-npm-pnpm-yarn"><template #title0="{ value, isActive }"><VPIcon name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #title2="{ value, isActive }"><VPIcon name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>npm create vuepress-theme-plume@latest
|
||||
</div></template></CodeTabs><CodeTabs id="0" :data='[{"id":"npm"},{"id":"pnpm"},{"id":"yarn"}]' tab-id="npm-to-npm-pnpm-yarn"><template #title0="{ value, isActive }"><VPIcon provider="iconify" name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #title2="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>npm create vuepress-theme-plume@latest
|
||||
|
||||
</code></pre>
|
||||
</div></template><template #tab1="{ value, isActive }"><div class="language-lang"><pre><code>pnpm create vuepress-theme-plume@latest
|
||||
@ -211,7 +211,7 @@ mkdir foo
|
||||
</div></template><template #tab2="{ value, isActive }"><div class="language-lang"><pre><code>yarn create vuepress-theme-plume@latest
|
||||
|
||||
</code></pre>
|
||||
</div></template></CodeTabs><CodeTabs id="0" :data='[{"id":"npm"},{"id":"pnpm"},{"id":"yarn"},{"id":"bun"},{"id":"deno"}]' tab-id="npm-to-npm-pnpm-yarn-bun-deno"><template #title0="{ value, isActive }"><VPIcon name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #title2="{ value, isActive }"><VPIcon name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #title3="{ value, isActive }"><VPIcon name="vscode-icons:file-type-bun"/><span>bun</span></template><template #title4="{ value, isActive }"><VPIcon name="vscode-icons:file-type-light-deno"/><span>deno</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>npx vp-update
|
||||
</div></template></CodeTabs><CodeTabs id="0" :data='[{"id":"npm"},{"id":"pnpm"},{"id":"yarn"},{"id":"bun"},{"id":"deno"}]' tab-id="npm-to-npm-pnpm-yarn-bun-deno"><template #title0="{ value, isActive }"><VPIcon provider="iconify" name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #title2="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #title3="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-bun"/><span>bun</span></template><template #title4="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-light-deno"/><span>deno</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>npx vp-update
|
||||
|
||||
</code></pre>
|
||||
</div></template><template #tab1="{ value, isActive }"><div class="language-lang"><pre><code>pnpm dlx vp-update
|
||||
@ -226,7 +226,7 @@ mkdir foo
|
||||
</div></template><template #tab4="{ value, isActive }"><div class="language-lang"><pre><code>deno run -A vp-update
|
||||
|
||||
</code></pre>
|
||||
</div></template></CodeTabs><CodeTabs id="0" :data='[{"id":"npm"},{"id":"yarn"},{"id":"pnpm"}]' tab-id="npm-to-npm-yarn-pnpm"><template #title0="{ value, isActive }"><VPIcon name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #title2="{ value, isActive }"><VPIcon name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>mkdir foo
|
||||
</div></template></CodeTabs><CodeTabs id="0" :data='[{"id":"npm"},{"id":"yarn"},{"id":"pnpm"}]' tab-id="npm-to-npm-yarn-pnpm"><template #title0="{ value, isActive }"><VPIcon provider="iconify" name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #title2="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>mkdir foo
|
||||
|
||||
</code></pre>
|
||||
</div></template><template #tab1="{ value, isActive }"><div class="language-lang"><pre><code>mkdir foo
|
||||
@ -241,13 +241,13 @@ mkdir foo
|
||||
`;
|
||||
|
||||
exports[`npmToPlugin > should work with default options 1`] = `
|
||||
"<CodeTabs id="0" :data='[{"id":"npm"},{"id":"pnpm"},{"id":"yarn"}]' tab-id="npm-to-npm-pnpm-yarn"><template #title0="{ value, isActive }"><VPIcon name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #title2="{ value, isActive }"><VPIcon name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>
|
||||
"<CodeTabs id="0" :data='[{"id":"npm"},{"id":"pnpm"},{"id":"yarn"}]' tab-id="npm-to-npm-pnpm-yarn"><template #title0="{ value, isActive }"><VPIcon provider="iconify" name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #title2="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>
|
||||
</code></pre>
|
||||
</div></template><template #tab1="{ value, isActive }"><div class="language-lang"><pre><code>
|
||||
</code></pre>
|
||||
</div></template><template #tab2="{ value, isActive }"><div class="language-lang"><pre><code>
|
||||
</code></pre>
|
||||
</div></template></CodeTabs><CodeTabs id="0" :data='[{"id":"npm"},{"id":"pnpm"},{"id":"yarn"}]' tab-id="npm-to-npm-pnpm-yarn"><template #title0="{ value, isActive }"><VPIcon name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #title2="{ value, isActive }"><VPIcon name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>npm install
|
||||
</div></template></CodeTabs><CodeTabs id="0" :data='[{"id":"npm"},{"id":"pnpm"},{"id":"yarn"}]' tab-id="npm-to-npm-pnpm-yarn"><template #title0="{ value, isActive }"><VPIcon provider="iconify" name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #title2="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>npm install
|
||||
|
||||
</code></pre>
|
||||
</div></template><template #tab1="{ value, isActive }"><div class="language-lang"><pre><code>pnpm install
|
||||
@ -256,7 +256,7 @@ exports[`npmToPlugin > should work with default options 1`] = `
|
||||
</div></template><template #tab2="{ value, isActive }"><div class="language-lang"><pre><code>yarn
|
||||
|
||||
</code></pre>
|
||||
</div></template></CodeTabs><CodeTabs id="0" :data='[{"id":"npm"},{"id":"pnpm"},{"id":"yarn"}]' tab-id="npm-to-npm-pnpm-yarn"><template #title0="{ value, isActive }"><VPIcon name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #title2="{ value, isActive }"><VPIcon name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>npm install
|
||||
</div></template></CodeTabs><CodeTabs id="0" :data='[{"id":"npm"},{"id":"pnpm"},{"id":"yarn"}]' tab-id="npm-to-npm-pnpm-yarn"><template #title0="{ value, isActive }"><VPIcon provider="iconify" name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #title2="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>npm install
|
||||
|
||||
</code></pre>
|
||||
</div></template><template #tab1="{ value, isActive }"><div class="language-lang"><pre><code>pnpm install
|
||||
@ -265,7 +265,7 @@ exports[`npmToPlugin > should work with default options 1`] = `
|
||||
</div></template><template #tab2="{ value, isActive }"><div class="language-lang"><pre><code>yarn
|
||||
|
||||
</code></pre>
|
||||
</div></template></CodeTabs><CodeTabs id="0" :data='[{"id":"npm"},{"id":"pnpm"},{"id":"yarn"}]' tab-id="npm-to-npm-pnpm-yarn"><template #title0="{ value, isActive }"><VPIcon name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #title2="{ value, isActive }"><VPIcon name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>npm install
|
||||
</div></template></CodeTabs><CodeTabs id="0" :data='[{"id":"npm"},{"id":"pnpm"},{"id":"yarn"}]' tab-id="npm-to-npm-pnpm-yarn"><template #title0="{ value, isActive }"><VPIcon provider="iconify" name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #title2="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>npm install
|
||||
|
||||
</code></pre>
|
||||
</div></template><template #tab1="{ value, isActive }"><div class="language-lang"><pre><code>pnpm install
|
||||
@ -274,7 +274,7 @@ exports[`npmToPlugin > should work with default options 1`] = `
|
||||
</div></template><template #tab2="{ value, isActive }"><div class="language-lang"><pre><code>yarn
|
||||
|
||||
</code></pre>
|
||||
</div></template></CodeTabs><CodeTabs id="0" :data='[{"id":"npm"},{"id":"pnpm"},{"id":"yarn"}]' tab-id="npm-to-npm-pnpm-yarn"><template #title0="{ value, isActive }"><VPIcon name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #title2="{ value, isActive }"><VPIcon name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>cross-env NODE_ENV=production npm run docs
|
||||
</div></template></CodeTabs><CodeTabs id="0" :data='[{"id":"npm"},{"id":"pnpm"},{"id":"yarn"}]' tab-id="npm-to-npm-pnpm-yarn"><template #title0="{ value, isActive }"><VPIcon provider="iconify" name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #title2="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>cross-env NODE_ENV=production npm run docs
|
||||
|
||||
</code></pre>
|
||||
</div></template><template #tab1="{ value, isActive }"><div class="language-lang"><pre><code>cross-env NODE_ENV=production pnpm docs
|
||||
@ -283,7 +283,7 @@ exports[`npmToPlugin > should work with default options 1`] = `
|
||||
</div></template><template #tab2="{ value, isActive }"><div class="language-lang"><pre><code>cross-env NODE_ENV=production yarn docs
|
||||
|
||||
</code></pre>
|
||||
</div></template></CodeTabs><CodeTabs id="0" :data='[{"id":"npm"},{"id":"pnpm"},{"id":"yarn"}]' tab-id="npm-to-npm-pnpm-yarn"><template #title0="{ value, isActive }"><VPIcon name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #title2="{ value, isActive }"><VPIcon name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>npm i -D package1 package2
|
||||
</div></template></CodeTabs><CodeTabs id="0" :data='[{"id":"npm"},{"id":"pnpm"},{"id":"yarn"}]' tab-id="npm-to-npm-pnpm-yarn"><template #title0="{ value, isActive }"><VPIcon provider="iconify" name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #title2="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>npm i -D package1 package2
|
||||
npm i --save-peer package3
|
||||
npm run docs
|
||||
|
||||
@ -298,7 +298,7 @@ yarn add --peer package3
|
||||
yarn docs
|
||||
|
||||
</code></pre>
|
||||
</div></template></CodeTabs><CodeTabs id="0" :data='[{"id":"npm"},{"id":"pnpm"},{"id":"yarn"}]' tab-id="npm-to-npm-pnpm-yarn"><template #title0="{ value, isActive }"><VPIcon name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #title2="{ value, isActive }"><VPIcon name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>npm install && npm run docs
|
||||
</div></template></CodeTabs><CodeTabs id="0" :data='[{"id":"npm"},{"id":"pnpm"},{"id":"yarn"}]' tab-id="npm-to-npm-pnpm-yarn"><template #title0="{ value, isActive }"><VPIcon provider="iconify" name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #title2="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>npm install && npm run docs
|
||||
mkdir foo
|
||||
|
||||
</code></pre>
|
||||
@ -310,7 +310,7 @@ mkdir foo
|
||||
mkdir foo
|
||||
|
||||
</code></pre>
|
||||
</div></template></CodeTabs><CodeTabs id="0" :data='[{"id":"npm"},{"id":"pnpm"},{"id":"yarn"}]' tab-id="npm-to-npm-pnpm-yarn"><template #title0="{ value, isActive }"><VPIcon name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #title2="{ value, isActive }"><VPIcon name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>npm run docs -- --clean-cache --clean-temp
|
||||
</div></template></CodeTabs><CodeTabs id="0" :data='[{"id":"npm"},{"id":"pnpm"},{"id":"yarn"}]' tab-id="npm-to-npm-pnpm-yarn"><template #title0="{ value, isActive }"><VPIcon provider="iconify" name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #title2="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>npm run docs -- --clean-cache --clean-temp
|
||||
|
||||
|
||||
</code></pre>
|
||||
@ -322,7 +322,7 @@ mkdir foo
|
||||
|
||||
|
||||
</code></pre>
|
||||
</div></template></CodeTabs><CodeTabs id="0" :data='[{"id":"npm"},{"id":"pnpm"},{"id":"yarn"}]' tab-id="npm-to-npm-pnpm-yarn"><template #title0="{ value, isActive }"><VPIcon name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #title2="{ value, isActive }"><VPIcon name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>npm create vuepress-theme-plume@latest
|
||||
</div></template></CodeTabs><CodeTabs id="0" :data='[{"id":"npm"},{"id":"pnpm"},{"id":"yarn"}]' tab-id="npm-to-npm-pnpm-yarn"><template #title0="{ value, isActive }"><VPIcon provider="iconify" name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #title2="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>npm create vuepress-theme-plume@latest
|
||||
|
||||
</code></pre>
|
||||
</div></template><template #tab1="{ value, isActive }"><div class="language-lang"><pre><code>pnpm create vuepress-theme-plume@latest
|
||||
@ -331,7 +331,7 @@ mkdir foo
|
||||
</div></template><template #tab2="{ value, isActive }"><div class="language-lang"><pre><code>yarn create vuepress-theme-plume@latest
|
||||
|
||||
</code></pre>
|
||||
</div></template></CodeTabs><CodeTabs id="0" :data='[{"id":"npm"},{"id":"pnpm"},{"id":"yarn"},{"id":"bun"},{"id":"deno"}]' tab-id="npm-to-npm-pnpm-yarn-bun-deno"><template #title0="{ value, isActive }"><VPIcon name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #title2="{ value, isActive }"><VPIcon name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #title3="{ value, isActive }"><VPIcon name="vscode-icons:file-type-bun"/><span>bun</span></template><template #title4="{ value, isActive }"><VPIcon name="vscode-icons:file-type-light-deno"/><span>deno</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>npx vp-update
|
||||
</div></template></CodeTabs><CodeTabs id="0" :data='[{"id":"npm"},{"id":"pnpm"},{"id":"yarn"},{"id":"bun"},{"id":"deno"}]' tab-id="npm-to-npm-pnpm-yarn-bun-deno"><template #title0="{ value, isActive }"><VPIcon provider="iconify" name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #title2="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #title3="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-bun"/><span>bun</span></template><template #title4="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-light-deno"/><span>deno</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>npx vp-update
|
||||
|
||||
</code></pre>
|
||||
</div></template><template #tab1="{ value, isActive }"><div class="language-lang"><pre><code>pnpm dlx vp-update
|
||||
@ -346,7 +346,7 @@ mkdir foo
|
||||
</div></template><template #tab4="{ value, isActive }"><div class="language-lang"><pre><code>deno run -A vp-update
|
||||
|
||||
</code></pre>
|
||||
</div></template></CodeTabs><CodeTabs id="0" :data='[{"id":"npm"},{"id":"pnpm"},{"id":"yarn"}]' tab-id="npm-to-npm-pnpm-yarn"><template #title0="{ value, isActive }"><VPIcon name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #title2="{ value, isActive }"><VPIcon name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>mkdir foo
|
||||
</div></template></CodeTabs><CodeTabs id="0" :data='[{"id":"npm"},{"id":"pnpm"},{"id":"yarn"}]' tab-id="npm-to-npm-pnpm-yarn"><template #title0="{ value, isActive }"><VPIcon provider="iconify" name="logos:npm-icon"/><span>npm</span></template><template #title1="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-light-pnpm"/><span>pnpm</span></template><template #title2="{ value, isActive }"><VPIcon provider="iconify" name="vscode-icons:file-type-yarn"/><span>yarn</span></template><template #tab0="{ value, isActive }"><div class="language-lang"><pre><code>mkdir foo
|
||||
|
||||
</code></pre>
|
||||
</div></template><template #tab1="{ value, isActive }"><div class="language-lang"><pre><code>mkdir foo
|
||||
|
||||
@ -16,7 +16,7 @@ exports[`timeline > timelinePlugin() > should work 1`] = `
|
||||
</li>
|
||||
</ul>
|
||||
</VPTimelineItem><VPTimelineItem time="q2" color="red"><template #title>这是标题</template><p>这是内容</p>
|
||||
</VPTimelineItem></VPTimeline><VPTimeline placement="right" :card="undefined"><VPTimelineItem icon="xxx" card type="warning"><template #icon><VPIcon name="xxx"/></template><template #title>这是标题</template><p>这是内容</p>
|
||||
</VPTimelineItem></VPTimeline><VPTimeline placement="right" :card="undefined"><VPTimelineItem icon="xxx" card type="warning"><template #icon><VPIcon provider="iconify" name="xxx"/></template><template #title>这是标题</template><p>这是内容</p>
|
||||
</VPTimelineItem><VPTimelineItem type="danger" line="dotted" :card="undefined"><template #title>这是标题</template><p>这是内容</p>
|
||||
</VPTimelineItem></VPTimeline><VPTimeline placement="between" :card="undefined"><VPTimelineItem card placement="right"><template #title>这是标题</template><p>这是内容</p>
|
||||
</VPTimelineItem><VPTimelineItem card placement="left"><template #title>这是标题</template><p>这是内容</p>
|
||||
|
||||
@ -1,39 +1,58 @@
|
||||
import MarkdownIt from 'markdown-it'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { iconPlugin } from '../src/node/inline/icons.js'
|
||||
import { iconPlugin } from '../src/node/icon/icon.js'
|
||||
|
||||
describe('iconsPlugin', () => {
|
||||
it('should work', () => {
|
||||
describe('iconPlugin', () => {
|
||||
it('should work with default', () => {
|
||||
const md = MarkdownIt().use(iconPlugin)
|
||||
|
||||
expect(md.render('::mdi:11::')).toMatchSnapshot()
|
||||
expect(md.render('**strong** ::mdi:11:: ::mdi:11::')).toMatchSnapshot()
|
||||
expect(md.render('**strong**\n::mdi:11::\n ::mdi:11::')).toMatchSnapshot()
|
||||
expect(md.render('::mdi:11::')).toContain('<VPIcon provider="iconify" name="mdi:11" />')
|
||||
expect(md.render('::mdi:11 =32px::')).toContain('<VPIcon provider="iconify" size="32px" name="mdi:11" />')
|
||||
expect(md.render('::mdi:11 /#fff::')).toContain('<VPIcon provider="iconify" color="#fff" name="mdi:11" />')
|
||||
expect(md.render('::mdi:11 =32px /#fff::')).toContain('<VPIcon provider="iconify" size="32px" color="#fff" name="mdi:11" />')
|
||||
expect(md.render('::mdi:11 =32px /#fff fa data-fa-transform="shrink-8::"'))
|
||||
.toContain('<VPIcon provider="iconify" size="32px" color="#fff" name="mdi:11" extra="fa" data-fa-transform=""shrink-8" />')
|
||||
|
||||
expect(md.render('::iconify mdi:11::')).toContain('<VPIcon provider="iconify" name="mdi:11" />')
|
||||
})
|
||||
|
||||
it('should work with options', () => {
|
||||
it('should work with options -> { size, color }', () => {
|
||||
const md = MarkdownIt().use(iconPlugin, { size: '1.25em', color: '#ccc' })
|
||||
|
||||
expect(md.render('::mdi:11::')).toMatchSnapshot()
|
||||
expect(md.render('**strong** ::mdi:11:: ::mdi:11::')).toMatchSnapshot()
|
||||
expect(md.render('::mdi:11::')).toContain('<VPIcon provider="iconify" size="1.25em" color="#ccc" name="mdi:11" />')
|
||||
expect(md.render('::mdi:11 =32px::')).toContain('<VPIcon provider="iconify" size="32px" color="#ccc" name="mdi:11" />')
|
||||
expect(md.render('::mdi:11 /#fff::')).toContain('<VPIcon provider="iconify" size="1.25em" color="#fff" name="mdi:11" />')
|
||||
expect(md.render('::mdi:11 =32px /#fff::')).toContain('<VPIcon provider="iconify" size="32px" color="#fff" name="mdi:11" />')
|
||||
})
|
||||
|
||||
it('should work with single icon options', () => {
|
||||
const md = MarkdownIt().use(iconPlugin)
|
||||
it('should work with options -> { provider: "iconify", prefix } ', () => {
|
||||
const md = MarkdownIt().use(iconPlugin, { prefix: 'mdi' })
|
||||
|
||||
expect(md.render('::mdi:11 =36px::')).toMatchSnapshot()
|
||||
expect(md.render('::mdi:11 =32px /#eee::')).toMatchSnapshot()
|
||||
expect(md.render('::11::')).toMatchSnapshot()
|
||||
expect(md.render('::11 =32px /#eee::')).toMatchSnapshot()
|
||||
expect(md.render('::mdi:11 /#eee::')).toMatchSnapshot()
|
||||
expect(md.render('::mdi:11 =32px/::')).toMatchSnapshot()
|
||||
expect(md.render('::mdi:11 /::')).toMatchSnapshot()
|
||||
expect(md.render('::fas:11 =32px/::')).toMatchSnapshot()
|
||||
})
|
||||
|
||||
const md2 = MarkdownIt().use(iconPlugin, { size: '1.25em', color: '#ccc' })
|
||||
expect(md2.render('::mdi:11::')).toMatchSnapshot()
|
||||
expect(md2.render('::mdi:11 =36px::')).toMatchSnapshot()
|
||||
expect(md2.render('::mdi:11 =32px/#eee::')).toMatchSnapshot()
|
||||
expect(md2.render('::mdi:11 /#eee::')).toMatchSnapshot()
|
||||
expect(md2.render('::mdi:11 =32px/::')).toMatchSnapshot()
|
||||
expect(md2.render('::mdi:11 /::')).toMatchSnapshot()
|
||||
it('should work with options -> { provider: "iconfont", prefix } ', () => {
|
||||
const md = MarkdownIt().use(iconPlugin, { provider: 'iconfont', prefix: 'iconfont icon-' })
|
||||
|
||||
expect(md.render('::home::')).toMatchSnapshot()
|
||||
expect(md.render('::home =32px::')).toMatchSnapshot()
|
||||
expect(md.render('::home /#eee::')).toMatchSnapshot()
|
||||
expect(md.render('::home =32px /#eee::')).toMatchSnapshot()
|
||||
})
|
||||
|
||||
it('should work with options -> { provider: "fontawesome", prefix } ', () => {
|
||||
const md = MarkdownIt().use(iconPlugin, { provider: 'fontawesome', prefix: 'iconfont icon-' })
|
||||
|
||||
expect(md.render('::home::')).toMatchSnapshot()
|
||||
expect(md.render('::home =32px::')).toMatchSnapshot()
|
||||
expect(md.render('::home /#eee::')).toMatchSnapshot()
|
||||
expect(md.render('::home =32px /#eee::')).toMatchSnapshot()
|
||||
|
||||
expect(md.render('::fas:home::')).toMatchSnapshot()
|
||||
expect(md.render('::fas:home 2xl data-fa-transform="shrink-8"::')).toMatchSnapshot()
|
||||
})
|
||||
|
||||
it('should not work with invalid icon', () => {
|
||||
@ -42,7 +61,6 @@ describe('iconsPlugin', () => {
|
||||
expect(md.render(':: mdi:11 ::')).toMatchSnapshot()
|
||||
expect(md.render('::::')).toMatchSnapshot()
|
||||
expect(md.render('::]&')).toMatchSnapshot()
|
||||
expect(md.render('::::')).toMatchSnapshot()
|
||||
expect(md.render('::mdi:11')).toMatchSnapshot()
|
||||
})
|
||||
})
|
||||
|
||||
@ -1,10 +1,5 @@
|
||||
import type { MarkdownPowerPluginOptions } from '../shared/index.js'
|
||||
|
||||
declare const __MD_POWER_INJECT_OPTIONS__: MarkdownPowerPluginOptions
|
||||
declare const __MD_POWER_DASHJS_INSTALLED__: boolean
|
||||
declare const __MD_POWER_HLSJS_INSTALLED__: boolean
|
||||
declare const __MD_POWER_MPEGTSJS_INSTALLED__: boolean
|
||||
|
||||
export const pluginOptions: MarkdownPowerPluginOptions = __MD_POWER_INJECT_OPTIONS__
|
||||
|
||||
export const installed: {
|
||||
|
||||
9
plugins/plugin-md-power/src/client/shim.d.ts
vendored
9
plugins/plugin-md-power/src/client/shim.d.ts
vendored
@ -12,3 +12,12 @@ declare module '@internal/md-power/replEditorData' {
|
||||
const res: ReplEditorData
|
||||
export default res
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
||||
const __MD_POWER_INJECT_OPTIONS__: MarkdownPowerPluginOptions
|
||||
const __MD_POWER_DASHJS_INSTALLED__: boolean
|
||||
const __MD_POWER_HLSJS_INSTALLED__: boolean
|
||||
const __MD_POWER_MPEGTSJS_INSTALLED__: boolean
|
||||
|
||||
}
|
||||
|
||||
@ -52,7 +52,7 @@ export const codeTabs: PluginWithOptions<CodeTabsOptions> = (md, options: CodeTa
|
||||
|
||||
const titlesContent = titles.map((title, index) => {
|
||||
const icon = getIcon(title)
|
||||
return `<template #title${index}="{ value, isActive }">${icon ? `<VPIcon name="${icon}"/>` : ''}<span>${title}</span></template>`
|
||||
return `<template #title${index}="{ value, isActive }">${icon ? `<VPIcon provider="iconify" name="${icon}"/>` : ''}<span>${title}</span></template>`
|
||||
}).join('')
|
||||
|
||||
return `<CodeTabs id="${index}" :data='${stringifyProp(tabsData)}'${active === -1 ? '' : ` :active="${active}"`}${meta.id ? ` tab-id="${meta.id as string}"` : ''}>${titlesContent}`
|
||||
|
||||
@ -129,7 +129,7 @@ export function codeTreePlugin(md: Markdown, app: App, options: CodeTreeOptions
|
||||
filepath: node.filepath,
|
||||
}
|
||||
return `<FileTreeNode${stringifyAttrs(props)}>
|
||||
<template #icon><VPIcon name="${getIcon(node.filename, props.type, mode)}" /></template>
|
||||
<template #icon><VPIcon provider="iconify" name="${getIcon(node.filename, props.type, mode)}" /></template>
|
||||
${node.children?.length ? renderFileTree(node.children, mode) : ''}
|
||||
</FileTreeNode>`
|
||||
})
|
||||
|
||||
@ -117,7 +117,7 @@ export function fileTreePlugin(md: Markdown, options: FileTreeOptions = {}): voi
|
||||
? `<template #comment>${md.renderInline(comment.replaceAll('#', '\#'))}</template>`
|
||||
: ''
|
||||
const renderedIcon = !isOmit
|
||||
? `<template #icon><VPIcon name="${getIcon(filename, nodeType, meta.icon)}" /></template>`
|
||||
? `<template #icon><VPIcon provider="iconify" name="${getIcon(filename, nodeType, meta.icon)}" /></template>`
|
||||
: ''
|
||||
const props: FileTreeNodeProps = {
|
||||
expanded: nodeType === 'folder' ? expanded : false,
|
||||
|
||||
@ -57,7 +57,7 @@ export function timelinePlugin(md: Markdown): void {
|
||||
const attrs = token.meta as TimelineItemMeta
|
||||
attrs.card ??= undefined
|
||||
const icon = attrs.icon
|
||||
return `<VPTimelineItem${stringifyAttrs(attrs, true)}>${icon ? `<template #icon><VPIcon name="${icon}"/></template>` : ''}`
|
||||
return `<VPTimelineItem${stringifyAttrs(attrs, true)}>${icon ? `<template #icon><VPIcon provider="iconify" name="${icon}"/></template>` : ''}`
|
||||
}
|
||||
|
||||
md.renderer.rules.timeline_item_close = () => '</VPTimelineItem>'
|
||||
|
||||
4
plugins/plugin-md-power/src/node/icon/README.md
Normal file
4
plugins/plugin-md-power/src/node/icon/README.md
Normal file
@ -0,0 +1,4 @@
|
||||
# 图标插件
|
||||
|
||||
- 语法支持
|
||||
- 其他跟图标关联的功能增强
|
||||
81
plugins/plugin-md-power/src/node/icon/createIconRule.ts
Normal file
81
plugins/plugin-md-power/src/node/icon/createIconRule.ts
Normal file
@ -0,0 +1,81 @@
|
||||
import type { RuleInline } from 'markdown-it/lib/parser_inline.mjs'
|
||||
|
||||
export function createIconRule(
|
||||
[l1, l2, r1, r2]: readonly [number, number, number, number],
|
||||
deprecated?: boolean,
|
||||
): RuleInline {
|
||||
return (state, silent) => {
|
||||
let found = false
|
||||
const max = state.posMax
|
||||
const start = state.pos
|
||||
|
||||
// ::xxx
|
||||
// ^^
|
||||
if (
|
||||
state.src.charCodeAt(start) !== l1
|
||||
|| state.src.charCodeAt(start + 1) !== l2
|
||||
) {
|
||||
return false
|
||||
}
|
||||
|
||||
const next = state.src.charCodeAt(start + 2)
|
||||
|
||||
// :: xxx | :::xxx
|
||||
// ^ | ^
|
||||
if (next === 0x20 || next === 0x3A)
|
||||
return false
|
||||
|
||||
/* istanbul ignore if -- @preserve */
|
||||
if (silent)
|
||||
return false
|
||||
|
||||
// ::::
|
||||
if (max - start < 5)
|
||||
return false
|
||||
|
||||
state.pos = start + 2
|
||||
|
||||
while (state.pos < max) {
|
||||
// ::xxx::
|
||||
// ^^
|
||||
if (
|
||||
state.src.charCodeAt(state.pos) === r1
|
||||
&& state.src.charCodeAt(state.pos + 1) === r2
|
||||
) {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
|
||||
state.md.inline.skipToken(state)
|
||||
}
|
||||
|
||||
if (
|
||||
!found
|
||||
|| start + 2 === state.pos
|
||||
// ::xxx ::
|
||||
// ^
|
||||
|| state.src.charCodeAt(state.pos - 1) === 0x20
|
||||
) {
|
||||
state.pos = start
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
const info = state.src.slice(start + 2, state.pos)
|
||||
|
||||
// found
|
||||
state.posMax = state.pos
|
||||
state.pos = start + 2
|
||||
|
||||
const icon = state.push('icon', 'i', 0)
|
||||
|
||||
icon.markup = '::'
|
||||
icon.content = info
|
||||
icon.meta = { deprecated }
|
||||
|
||||
state.pos = state.posMax + 2
|
||||
state.posMax = max
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
50
plugins/plugin-md-power/src/node/icon/icon.ts
Normal file
50
plugins/plugin-md-power/src/node/icon/icon.ts
Normal file
@ -0,0 +1,50 @@
|
||||
import type { PluginWithOptions } from 'markdown-it'
|
||||
import type { MarkdownEnv } from 'vuepress/markdown'
|
||||
import type { IconOptions } from '../../shared/index.js'
|
||||
import { colors } from 'vuepress/utils'
|
||||
import { stringifyAttrs } from '../utils/stringifyAttrs.js'
|
||||
import { createIconRule } from './createIconRule.js'
|
||||
import { resolveIcon } from './resolveIcon.js'
|
||||
|
||||
function iconRender(content: string, options: IconOptions): string {
|
||||
const icon = resolveIcon(content, options)
|
||||
return `<VPIcon${stringifyAttrs(icon)} />`
|
||||
}
|
||||
|
||||
export const iconPlugin: PluginWithOptions<IconOptions> = (md, options = {}) => {
|
||||
/**
|
||||
* ::collect:icon_name =size /color::
|
||||
*/
|
||||
md.inline.ruler.before(
|
||||
'link',
|
||||
'icon',
|
||||
// : : : :
|
||||
createIconRule([0x3A, 0x3A, 0x3A, 0x3A]),
|
||||
)
|
||||
/**
|
||||
* :[collect:icon_name size/color]:
|
||||
* @deprecated
|
||||
*/
|
||||
md.inline.ruler.before(
|
||||
'link',
|
||||
'icon_deprecated',
|
||||
// : [ ] :
|
||||
createIconRule([0x3A, 0x5B, 0x5D, 0x3A], true),
|
||||
)
|
||||
|
||||
md.renderer.rules.icon = (tokens, idx, _, env: MarkdownEnv) => {
|
||||
const { content, meta } = tokens[idx]
|
||||
let icon = content
|
||||
|
||||
/* istanbul ignore if -- @preserve */
|
||||
if (meta.deprecated) {
|
||||
const [name, opt = ''] = content.split(' ')
|
||||
const [size, color] = opt.trim().split('/')
|
||||
icon = `${name}${size ? ` =${size}` : ''}${color ? ` /${color}` : ''}`
|
||||
|
||||
console.warn(`The icon syntax of \`${colors.yellow(`:[${content}]:`)}\` is deprecated, please use \`${colors.green(`::${icon}::`)}\` instead. (${colors.gray(env.filePathRelative || env.filePath)})`)
|
||||
}
|
||||
|
||||
return iconRender(icon, options)
|
||||
}
|
||||
}
|
||||
46
plugins/plugin-md-power/src/node/icon/index.ts
Normal file
46
plugins/plugin-md-power/src/node/icon/index.ts
Normal file
@ -0,0 +1,46 @@
|
||||
/**
|
||||
* # Icon
|
||||
*
|
||||
* ## syntax
|
||||
*
|
||||
* ::name::
|
||||
* ::provide name::
|
||||
* ::provide name =size /color extra::
|
||||
*
|
||||
* ## options
|
||||
*
|
||||
* - provide: iconify | iconfont | fontawesome
|
||||
* - prefix:
|
||||
* - iconify: collect:name - prefix = "collect"
|
||||
* - iconfont: iconfont icon-name - prefix = "iconfont icon-"
|
||||
* - fontawesome: fa-solid fa-name -> fas:name - prefix = "fas"
|
||||
*
|
||||
* - assets: url[]
|
||||
*
|
||||
* ## iconify
|
||||
*
|
||||
* - full syntax
|
||||
* ::fluent-mdl2:toggle-filled::
|
||||
* ::fluent-mdl2:toggle-filled =128px /#fff::
|
||||
*
|
||||
* - prefix: fluent-mdl2
|
||||
* ::toggle-filled::
|
||||
* ::toggle-filled =128px /#fff::
|
||||
*
|
||||
* ### iconfont
|
||||
*
|
||||
* ::name::
|
||||
* ::name =size /color::
|
||||
*
|
||||
* ### fontawesome
|
||||
*
|
||||
* ::fa-solid:name:: -> ::fas:name:: -> ::s:name:: -> ::name::
|
||||
* ::fa-brands:name:: -> ::fab:name:: -> ::b:name::
|
||||
* ::fa-regular:name:: -> ::far:name:: -> ::r:name::
|
||||
*
|
||||
* ::name fa-sm::
|
||||
*
|
||||
* @deprecated :[fluent-mdl2:toggle-filled 128px/#fff]: 此语法已废弃
|
||||
*/
|
||||
export * from './icon.js'
|
||||
export * from './prepareIcon.js'
|
||||
88
plugins/plugin-md-power/src/node/icon/prepareIcon.ts
Normal file
88
plugins/plugin-md-power/src/node/icon/prepareIcon.ts
Normal file
@ -0,0 +1,88 @@
|
||||
import type { IconOptions } from '../../shared/index.js'
|
||||
import { notNullish, toArray, uniqueBy } from '@pengzhanbo/utils'
|
||||
import { isLinkAbsolute } from '@vuepress/helper'
|
||||
import { isLinkHttp } from 'vuepress/shared'
|
||||
|
||||
interface AssetInfo {
|
||||
type: 'style' | 'script'
|
||||
link: string
|
||||
provide?: string
|
||||
}
|
||||
|
||||
function getFontAwesomeCDNLink(type: string): string {
|
||||
return `https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6/js/${type}.min.js`
|
||||
}
|
||||
|
||||
export function prepareIcon(
|
||||
imports: Set<string>,
|
||||
options: IconOptions = {},
|
||||
): string {
|
||||
const setupContent: string[] = []
|
||||
const assets: AssetInfo[] = []
|
||||
|
||||
if (options.provider === 'iconfont') {
|
||||
assets.push(
|
||||
...toArray(options.assets)
|
||||
.map(asset => normalizeAsset(asset))
|
||||
.filter(notNullish),
|
||||
)
|
||||
}
|
||||
else if (options.provider === 'fontawesome') {
|
||||
assets.push(...toArray(options.assets || 'fontawesome').map((asset) => {
|
||||
if (asset === 'fontawesome') {
|
||||
return ['solid', 'regular', 'fontawesome']
|
||||
.map(getFontAwesomeCDNLink)
|
||||
.map(asset => normalizeAsset(asset, 'fontawesome'))
|
||||
}
|
||||
if (asset === 'fontawesome-with-brands') {
|
||||
return normalizeAsset(getFontAwesomeCDNLink('brands'), 'fontawesome')
|
||||
}
|
||||
return null
|
||||
}).flat().filter(notNullish))
|
||||
}
|
||||
let hasStyle = false
|
||||
let hasScript = false
|
||||
|
||||
for (const asset of uniqueBy(assets, (a, b) => a.link === b.link)) {
|
||||
if (asset.type === 'style') {
|
||||
hasStyle = true
|
||||
setupContent.push(`useStyleTag('@import url("${asset.link}");')`)
|
||||
}
|
||||
else if (asset.type === 'script') {
|
||||
hasScript = true
|
||||
setupContent.push(asset.provide === 'fontawesome'
|
||||
? `useScriptTag("${asset.link}", () => {}, { attrs: { "data-auto-replace-svg": "nest" } })`
|
||||
: `useScriptTag("${asset.link}")`,
|
||||
)
|
||||
}
|
||||
}
|
||||
if (hasScript || hasStyle) {
|
||||
const exports: string[] = []
|
||||
if (hasScript)
|
||||
exports.push('useScriptTag')
|
||||
if (hasStyle)
|
||||
exports.push('useStyleTag')
|
||||
imports.add(`import { ${exports.join(', ')} } from '@vueuse/core'`)
|
||||
}
|
||||
|
||||
return setupContent.join('\n ')
|
||||
}
|
||||
|
||||
function normalizeAsset(asset: string, provide?: string): AssetInfo | null {
|
||||
const link = normalizeLink(asset)
|
||||
if (asset.endsWith('.js')) {
|
||||
return { type: 'script', link, provide }
|
||||
}
|
||||
if (asset.endsWith('.css')) {
|
||||
return { type: 'style', link, provide }
|
||||
}
|
||||
console.error(`[vuepress:icon] Can not recognize icon link: "${asset}"`)
|
||||
return null
|
||||
}
|
||||
|
||||
function normalizeLink(link: string): string {
|
||||
if (isLinkHttp(link) || isLinkAbsolute(link))
|
||||
return link
|
||||
|
||||
return `//${link}`
|
||||
}
|
||||
57
plugins/plugin-md-power/src/node/icon/resolveIcon.ts
Normal file
57
plugins/plugin-md-power/src/node/icon/resolveIcon.ts
Normal file
@ -0,0 +1,57 @@
|
||||
import type { IconOptions } from '../../shared/index.js'
|
||||
import { kebabCase, omit } from '@pengzhanbo/utils'
|
||||
import { resolveAttrs } from '../utils/resolveAttrs.js'
|
||||
|
||||
export interface ResolvedIcon {
|
||||
provider: Exclude<IconOptions['provider'], undefined>
|
||||
size?: string | number
|
||||
color?: string
|
||||
name: string
|
||||
extra?: string
|
||||
}
|
||||
|
||||
const RE_SIZE = /(?<=\s|^)=(.+?)(?:\s|$)/
|
||||
const RE_COLOR = /(?<=\s|^)\/(.+?)(?:\s|$)/
|
||||
const RE_PROVIDER = /^(iconify|iconfont|fontawesome)\s+/
|
||||
const RE_EXTRA_KEY = /(?:^|-)\d-/g
|
||||
|
||||
export function resolveIcon(content: string, options: IconOptions): ResolvedIcon {
|
||||
let size = options.size
|
||||
let color = options.color
|
||||
let provider = options.provider || 'iconify'
|
||||
|
||||
content = content
|
||||
.replace(RE_PROVIDER, (_, p) => {
|
||||
provider = p
|
||||
return ''
|
||||
})
|
||||
.replace(RE_SIZE, (_, s) => {
|
||||
size = s
|
||||
return ''
|
||||
})
|
||||
.replace(RE_COLOR, (_, c) => {
|
||||
color = c
|
||||
return ''
|
||||
})
|
||||
.trim()
|
||||
|
||||
const index = content.indexOf(' ')
|
||||
const name = index === -1 ? content : content.slice(0, index)
|
||||
const extra = index === -1 ? '' : content.slice(index + 1)
|
||||
const props = { provider, size, color, name }
|
||||
if (!extra) {
|
||||
return props
|
||||
}
|
||||
|
||||
const { attrs } = resolveAttrs(extra)
|
||||
const info: string[] = []
|
||||
const excludes: string[] = []
|
||||
|
||||
for (const key in attrs) {
|
||||
if (attrs[key] === true) {
|
||||
excludes.push(key)
|
||||
info.push(kebabCase(key).replace(RE_EXTRA_KEY, m => `${m.slice(0, -1)}`))
|
||||
}
|
||||
}
|
||||
return { ...props, extra: info.join(' '), ...omit(attrs, excludes) }
|
||||
}
|
||||
@ -1,155 +0,0 @@
|
||||
/**
|
||||
* ::fluent-mdl2:toggle-filled::
|
||||
* ::fluent-mdl2:toggle-filled /#fff::
|
||||
* ::fluent-mdl2:toggle-filled =128px /#fff::
|
||||
*
|
||||
* @deprecated :[fluent-mdl2:toggle-filled 128px/#fff]: 此语法已废弃
|
||||
*/
|
||||
|
||||
import type { PluginWithOptions } from 'markdown-it'
|
||||
import type { RuleInline } from 'markdown-it/lib/parser_inline.mjs'
|
||||
import type { MarkdownEnv } from 'vuepress/markdown'
|
||||
import type { IconsOptions } from '../../shared/index.js'
|
||||
import { colors } from 'vuepress/utils'
|
||||
import { stringifyAttrs } from '../utils/stringifyAttrs.js'
|
||||
|
||||
function createIconRule(
|
||||
[l1, l2, r1, r2]: readonly [number, number, number, number],
|
||||
deprecated?: boolean,
|
||||
): RuleInline {
|
||||
return (state, silent) => {
|
||||
let found = false
|
||||
const max = state.posMax
|
||||
const start = state.pos
|
||||
|
||||
// ::xxx
|
||||
// ^^
|
||||
if (
|
||||
state.src.charCodeAt(start) !== l1
|
||||
|| state.src.charCodeAt(start + 1) !== l2
|
||||
) {
|
||||
return false
|
||||
}
|
||||
|
||||
const next = state.src.charCodeAt(start + 2)
|
||||
|
||||
// :: xxx | :::xxx
|
||||
// ^ | ^
|
||||
if (next === 0x20 || next === 0x3A)
|
||||
return false
|
||||
|
||||
/* istanbul ignore if -- @preserve */
|
||||
if (silent)
|
||||
return false
|
||||
|
||||
// ::::
|
||||
if (max - start < 5)
|
||||
return false
|
||||
|
||||
state.pos = start + 2
|
||||
|
||||
while (state.pos < max) {
|
||||
// ::xxx::
|
||||
// ^^
|
||||
if (
|
||||
state.src.charCodeAt(state.pos) === r1
|
||||
&& state.src.charCodeAt(state.pos + 1) === r2
|
||||
) {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
|
||||
state.md.inline.skipToken(state)
|
||||
}
|
||||
|
||||
if (
|
||||
!found
|
||||
|| start + 2 === state.pos
|
||||
// ::xxx ::
|
||||
// ^
|
||||
|| state.src.charCodeAt(state.pos - 1) === 0x20
|
||||
) {
|
||||
state.pos = start
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
const info = state.src.slice(start + 2, state.pos)
|
||||
|
||||
// found
|
||||
state.posMax = state.pos
|
||||
state.pos = start + 2
|
||||
|
||||
const icon = state.push('icon', 'i', 0)
|
||||
|
||||
icon.markup = '::'
|
||||
icon.content = info
|
||||
icon.meta = { deprecated }
|
||||
|
||||
state.pos = state.posMax + 2
|
||||
state.posMax = max
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
const RE_SIZE = /(?<=\s|^)=(.+?)(?:\s|$)/
|
||||
const RE_COLOR = /(?<=\s|^)\/(.+?)(?:\s|$)/
|
||||
|
||||
function iconRender(content: string, options: IconsOptions): string {
|
||||
let size = options.size
|
||||
let color = options.color
|
||||
|
||||
content = content
|
||||
.replace(RE_SIZE, (_, s) => {
|
||||
size = s
|
||||
return ''
|
||||
})
|
||||
.replace(RE_COLOR, (_, c) => {
|
||||
color = c
|
||||
return ''
|
||||
})
|
||||
.trim()
|
||||
|
||||
const [name, ...extra] = content.split(/\s+/)
|
||||
|
||||
return `<VPIcon${stringifyAttrs({ name, size, color, class: extra.length ? extra.join(' ') : undefined })} />`
|
||||
}
|
||||
|
||||
export const iconPlugin: PluginWithOptions<IconsOptions> = (md, options = {}) => {
|
||||
/**
|
||||
* ::collect:icon_name =size /color::
|
||||
*/
|
||||
md.inline.ruler.before(
|
||||
'link',
|
||||
'icon',
|
||||
// : : : :
|
||||
createIconRule([0x3A, 0x3A, 0x3A, 0x3A]),
|
||||
)
|
||||
/**
|
||||
* :[collect:icon_name size/color]:
|
||||
* @deprecated
|
||||
*/
|
||||
md.inline.ruler.before(
|
||||
'link',
|
||||
'icon_deprecated',
|
||||
// : [ ] :
|
||||
createIconRule([0x3A, 0x5B, 0x5D, 0x3A], true),
|
||||
)
|
||||
|
||||
md.renderer.rules.icon = (tokens, idx, _, env: MarkdownEnv) => {
|
||||
const { content, meta } = tokens[idx]
|
||||
let icon = content
|
||||
|
||||
/* istanbul ignore if -- @preserve */
|
||||
if (meta.deprecated) {
|
||||
const [name, opt = ''] = content.split(' ')
|
||||
const [size, color] = opt.trim().split('/')
|
||||
icon = `${name}${size ? ` =${size}` : ''}${color ? ` /${color}` : ''}`
|
||||
|
||||
console.warn(`The icon syntax of \`${colors.yellow(`:[${content}]:`)}\` is deprecated, please use \`${colors.green(`::${icon}::`)}\` instead. (${colors.gray(env.filePathRelative || env.filePath)})`)
|
||||
}
|
||||
|
||||
return iconRender(icon, options)
|
||||
}
|
||||
}
|
||||
@ -9,7 +9,6 @@ import { tasklist } from '@mdit/plugin-tasklist'
|
||||
import { isPlainObject } from '@vuepress/helper'
|
||||
import { abbrPlugin } from './abbr.js'
|
||||
import { annotationPlugin } from './annotation.js'
|
||||
import { iconPlugin } from './icons.js'
|
||||
import { plotPlugin } from './plot.js'
|
||||
|
||||
export function inlineSyntaxPlugin(
|
||||
@ -41,11 +40,6 @@ export function inlineSyntaxPlugin(
|
||||
md.use(abbrPlugin)
|
||||
}
|
||||
|
||||
if (options.icons) {
|
||||
// ::collect:name::
|
||||
md.use(iconPlugin, isPlainObject(options.icons) ? options.icons : {})
|
||||
}
|
||||
|
||||
if (
|
||||
options.plot === true
|
||||
|| (isPlainObject(options.plot) && options.plot.tag !== false)
|
||||
|
||||
@ -1,15 +1,17 @@
|
||||
import type { Plugin } from 'vuepress/core'
|
||||
import type { MarkdownPowerPluginOptions } from '../shared/index.js'
|
||||
import { isPlainObject } from '@pengzhanbo/utils'
|
||||
import { addViteOptimizeDepsInclude } from '@vuepress/helper'
|
||||
import { isPackageExists } from 'local-pkg'
|
||||
import { extendsPageWithCodeTree } from './container/codeTree.js'
|
||||
import { containerPlugin } from './container/index.js'
|
||||
import { demoPlugin, demoWatcher, extendsPageWithDemo, waitDemoRender } from './demo/index.js'
|
||||
import { embedSyntaxPlugin } from './embed/index.js'
|
||||
import { docsTitlePlugin } from './enhance/docsTitle.js'
|
||||
import { imageSizePlugin } from './enhance/imageSize.js'
|
||||
import { iconPlugin } from './icon/index.js'
|
||||
import { inlineSyntaxPlugin } from './inline/index.js'
|
||||
import { prepareConfigFile } from './prepareConfigFile.js'
|
||||
import { provideData } from './provideData.js'
|
||||
|
||||
export function markdownPowerPlugin(
|
||||
options: MarkdownPowerPluginOptions = {},
|
||||
@ -19,12 +21,7 @@ export function markdownPowerPlugin(
|
||||
|
||||
clientConfigFile: app => prepareConfigFile(app, options),
|
||||
|
||||
define: {
|
||||
__MD_POWER_INJECT_OPTIONS__: options,
|
||||
__MD_POWER_DASHJS_INSTALLED__: isPackageExists('dashjs'),
|
||||
__MD_POWER_HLSJS_INSTALLED__: isPackageExists('hls.js'),
|
||||
__MD_POWER_MPEGTSJS_INSTALLED__: isPackageExists('mpegts.js'),
|
||||
},
|
||||
define: provideData(options),
|
||||
|
||||
extendsBundlerOptions(bundlerOptions, app) {
|
||||
if (options.repl) {
|
||||
@ -47,6 +44,7 @@ export function markdownPowerPlugin(
|
||||
docsTitlePlugin(md)
|
||||
embedSyntaxPlugin(md, options)
|
||||
inlineSyntaxPlugin(md, options)
|
||||
iconPlugin(md, options.icon ?? (isPlainObject(options.icons) ? options.icons : {}))
|
||||
|
||||
if (options.demo)
|
||||
demoPlugin(app, md)
|
||||
|
||||
@ -2,6 +2,7 @@ import type { App } from 'vuepress/core'
|
||||
import type { MarkdownPowerPluginOptions } from '../shared/index.js'
|
||||
import { ensureEndingSlash } from '@vuepress/helper'
|
||||
import { getDirname, path } from 'vuepress/utils'
|
||||
import { prepareIcon } from './icon/index.js'
|
||||
|
||||
const { url: filepath } = import.meta
|
||||
const __dirname = getDirname(filepath)
|
||||
@ -130,6 +131,8 @@ export async function prepareConfigFile(app: App, options: MarkdownPowerPluginOp
|
||||
enhances.add(`app.component('VPField', VPField)`)
|
||||
}
|
||||
|
||||
const setupIcon = prepareIcon(imports, options.icon)
|
||||
|
||||
return app.writeTemp(
|
||||
'md-power/config.js',
|
||||
`\
|
||||
@ -143,6 +146,9 @@ export default defineClientConfig({
|
||||
${Array.from(enhances.values())
|
||||
.map(item => ` ${item}`)
|
||||
.join('\n')}
|
||||
},
|
||||
setup() {
|
||||
${setupIcon}
|
||||
}
|
||||
})
|
||||
`,
|
||||
|
||||
19
plugins/plugin-md-power/src/node/provideData.ts
Normal file
19
plugins/plugin-md-power/src/node/provideData.ts
Normal file
@ -0,0 +1,19 @@
|
||||
import type { MarkdownPowerPluginOptions } from '../shared/index.js'
|
||||
import { isPackageExists } from 'local-pkg'
|
||||
|
||||
export function provideData(options: MarkdownPowerPluginOptions): Record<string, unknown> {
|
||||
const mardownOptions = {
|
||||
plot: options.plot,
|
||||
pdf: options.pdf,
|
||||
}
|
||||
const icon = options.icon ?? { provider: 'iconify' }
|
||||
|
||||
return {
|
||||
__MD_POWER_INJECT_OPTIONS__: mardownOptions,
|
||||
__MD_POWER_DASHJS_INSTALLED__: isPackageExists('dashjs'),
|
||||
__MD_POWER_HLSJS_INSTALLED__: isPackageExists('hls.js'),
|
||||
__MD_POWER_MPEGTSJS_INSTALLED__: isPackageExists('mpegts.js'),
|
||||
__MD_POWER_ICON_PROVIDER__: icon.provider || 'iconify',
|
||||
__MD_POWER_ICON_PREFIX__: icon.prefix || '',
|
||||
}
|
||||
}
|
||||
87
plugins/plugin-md-power/src/shared/icon.ts
Normal file
87
plugins/plugin-md-power/src/shared/icon.ts
Normal file
@ -0,0 +1,87 @@
|
||||
export type IconOptions = IconifyProvider | IconFontProvider | FontAwesomeProvider
|
||||
|
||||
export interface IconProviderBase {
|
||||
/**
|
||||
* The provider of the icon
|
||||
*
|
||||
* 图标提供商
|
||||
* @default 'iconify'
|
||||
*/
|
||||
provider?: 'iconify' | 'iconfont' | 'fontawesome'
|
||||
|
||||
/**
|
||||
* The size of the icon
|
||||
* @default '1em'
|
||||
*/
|
||||
size?: string | number
|
||||
|
||||
/**
|
||||
* The color of the icon
|
||||
* @default 'currentColor'
|
||||
*/
|
||||
color?: string
|
||||
}
|
||||
|
||||
export interface IconFontProvider extends IconProviderBase {
|
||||
provider?: 'iconfont'
|
||||
|
||||
/**
|
||||
* The prefix of the iconfont
|
||||
* @default 'iconfont icon-'
|
||||
*/
|
||||
prefix?: string
|
||||
|
||||
/**
|
||||
* The assets of the iconfont
|
||||
*/
|
||||
assets?: IconAssetLink | IconAssetLink[]
|
||||
}
|
||||
|
||||
export interface FontAwesomeProvider extends IconProviderBase {
|
||||
|
||||
provider?: 'fontawesome'
|
||||
|
||||
/**
|
||||
* The prefix of the fontawesome icon
|
||||
* @default 'fas'
|
||||
*/
|
||||
prefix?: LiteralUnion<FontAwesomePrefix>
|
||||
|
||||
/**
|
||||
* The assets of the fontawesome
|
||||
* @default 'fontawesome'
|
||||
*/
|
||||
assets?: FontAwesomeAssetBuiltIn | IconAssetLink | (IconAssetLink | FontAwesomeAssetBuiltIn)[]
|
||||
}
|
||||
|
||||
export interface IconifyProvider extends IconProviderBase {
|
||||
provider?: 'iconify'
|
||||
|
||||
/**
|
||||
* The prefix of the icon
|
||||
* @default ''
|
||||
*/
|
||||
prefix?: LiteralUnion<IconifyPrefix>
|
||||
}
|
||||
|
||||
export type FontAwesomeAssetBuiltIn = 'fontawesome' | 'fontawesome-with-brands'
|
||||
export type IconAssetLink = `//${string}` | `//${string}` | `https://${string}` | `http://${string}`
|
||||
|
||||
export type FontAwesomePrefix =
|
||||
| 'fas' | 's' // fa-solid fa-name
|
||||
| 'far' | 'r' // fa-regular fa-name
|
||||
| 'fal' | 'l' // fa-light fa-name
|
||||
| 'fat' | 't' // fa-thin fa-name
|
||||
| 'fads' | 'ds' // fa-duotone fa-solid fa-name
|
||||
| 'fass' | 'ss' // fa-sharp fa-solid fa-name
|
||||
| 'fasr' | 'sr' // fa-sharp fa-regular fa-name
|
||||
| 'fasl' | 'sl' // fa-sharp fa-light fa-name
|
||||
| 'fast' | 'st' // fa-sharp fa-thin fa-name
|
||||
| 'fasds' | 'sds' // fa-sharp-duotone fa-solid fa-name
|
||||
| 'fab' | 'b' // fa-brands fa-name
|
||||
|
||||
export type IconifyPrefix = 'material-symbols' | 'material-symbols-light' | 'ic' | 'mdi' | 'mdi-light' | 'line-md' | 'solar' | 'tabler' | 'hugeicons' | 'mingcute' | 'ri' | 'mynaui' | 'iconamoon' | 'iconoir' | 'lucide' | 'lucide-lab' | 'uil' | 'tdesign' | 'si' | 'bx' | 'bxs' | 'majesticons' | 'gg' | 'flowbite' | 'basil' | 'pixelarticons' | 'pixel' | 'akar-icons' | 'ci' | 'proicons' | 'typcn' | 'meteor-icons' | 'prime' | 'circum' | 'fe' | 'eos-icons' | 'bitcoin-icons' | 'humbleicons' | 'uim' | 'uit' | 'uis' | 'gridicons' | 'mi' | 'cuida' | 'weui' | 'duo-icons' | 'svg-spinners' | 'lets-icons' | 'mage' | 'stash' | 'lineicons' | 'icon-park-outline' | 'icon-park-solid' | 'icon-park-twotone' | 'jam' | 'guidance' | 'carbon' | 'ion' | 'famicons' | 'ant-design' | 'lsicon' | 'gravity-ui' | 'cil' | 'ep' | 'charm' | 'quill' | 'bytesize' | 'bi' | 'rivet-icons' | 'nimbus' | 'formkit' | 'fluent' | 'ph' | 'teenyicons' | 'clarity' | 'ix' | 'octicon' | 'memory' | 'system-uicons' | 'radix-icons' | 'zondicons' | 'uiw' | 'maki' | 'codex' | 'ei' | 'heroicons' | 'pepicons-pop' | 'pepicons-print' | 'pepicons-pencil' | 'f7' | 'pajamas' | 'garden' | 'streamline' | 'fa6-solid' | 'fa6-regular' | 'picon' | 'ooui' | 'oui' | 'nrk' | 'qlementine-icons' | 'fluent-color' | 'icon-park' | 'marketeq' | 'vscode-icons' | 'codicon' | 'material-icon-theme' | 'file-icons' | 'devicon' | 'devicon-plain' | 'catppuccin' | 'skill-icons' | 'unjs' | 'simple-icons' | 'logos' | 'cib' | 'fa6-brands' | 'bxl' | 'nonicons' | 'arcticons' | 'cbi' | 'brandico' | 'entypo-social' | 'token' | 'token-branded' | 'cryptocurrency' | 'cryptocurrency-color' | 'openmoji' | 'twemoji' | 'noto' | 'fluent-emoji' | 'fluent-emoji-flat' | 'fluent-emoji-high-contrast' | 'noto-v1' | 'emojione' | 'emojione-monotone' | 'emojione-v1' | 'fxemoji' | 'streamline-emojis' | 'circle-flags' | 'flag' | 'flagpack' | 'cif' | 'gis' | 'map' | 'geo' | 'game-icons' | 'fad' | 'academicons' | 'wi' | 'meteocons' | 'healthicons' | 'medical-icon' | 'covid' | 'la' | 'eva' | 'dashicons' | 'flat-color-icons' | 'entypo' | 'foundation' | 'raphael' | 'icons8' | 'iwwa' | 'gala' | 'heroicons-outline' | 'heroicons-solid' | 'fa-solid' | 'fa-regular' | 'fa-brands' | 'fa' | 'fluent-mdl2' | 'fontisto' | 'icomoon-free' | 'subway' | 'oi' | 'wpf' | 'simple-line-icons' | 'et' | 'el' | 'vaadin' | 'grommet-icons' | 'whh' | 'si-glyph' | 'zmdi' | 'ls' | 'bpmn' | 'flat-ui' | 'vs' | 'topcoat' | 'il' | 'websymbol' | 'fontelico' | 'ps' | 'feather' | 'mono-icons' | 'pepicons'
|
||||
|
||||
export type LiteralUnion<Union extends Base, Base = string> =
|
||||
| Union
|
||||
| (Base & { zz_IGNORE_ME?: never })
|
||||
@ -1,13 +0,0 @@
|
||||
export interface IconsOptions {
|
||||
/**
|
||||
* The size of the icon
|
||||
* @default '1em'
|
||||
*/
|
||||
size?: string | number
|
||||
|
||||
/**
|
||||
* The color of the icon
|
||||
* @default 'currentColor'
|
||||
*/
|
||||
color?: string
|
||||
}
|
||||
@ -4,7 +4,7 @@ export * from './codeSandbox.js'
|
||||
export * from './codeTabs.js'
|
||||
export * from './demo.js'
|
||||
export * from './fileTree.js'
|
||||
export * from './icons.js'
|
||||
export * from './icon.js'
|
||||
export * from './jsfiddle.js'
|
||||
export * from './npmTo.js'
|
||||
export * from './pdf.js'
|
||||
|
||||
@ -2,7 +2,7 @@ import type { CanIUseOptions } from './caniuse.js'
|
||||
import type { CodeTabsOptions } from './codeTabs.js'
|
||||
import type { CodeTreeOptions } from './codeTree.js'
|
||||
import type { FileTreeOptions } from './fileTree.js'
|
||||
import type { IconsOptions } from './icons.js'
|
||||
import type { IconOptions } from './icon.js'
|
||||
import type { NpmToOptions } from './npmTo.js'
|
||||
import type { PDFOptions } from './pdf.js'
|
||||
import type { PlotOptions } from './plot.js'
|
||||
@ -40,14 +40,25 @@ export interface MarkdownPowerPluginOptions {
|
||||
pdf?: boolean | PDFOptions
|
||||
|
||||
// new syntax
|
||||
/**
|
||||
* 是否启用 图标支持
|
||||
* - iconify - `::collect:icon_name::` => `<VPIcon name="collect:icon_name" />`
|
||||
* - iconfont - `::name::` => `<i class="iconfont icon-name"></i>`
|
||||
* - fontawesome - `::fas:name::` => `<i class="fa-solid fa-name"></i>`
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
icon?: IconOptions
|
||||
|
||||
/**
|
||||
* 是否启用 iconify 图标嵌入语法
|
||||
*
|
||||
* `::collect:icon_name::`
|
||||
*
|
||||
* @default false
|
||||
* @deprecated use `icon` instead 该配置已弃用,请使用 `icon` 代替
|
||||
*/
|
||||
icons?: boolean | IconsOptions
|
||||
icons?: boolean | IconOptions
|
||||
/**
|
||||
* 是否启用 隐秘文本 语法
|
||||
*
|
||||
|
||||
@ -1,98 +1,85 @@
|
||||
<script setup lang="ts">
|
||||
import VPIconFa from '@theme/VPIconFa.vue'
|
||||
import VPIconfont from '@theme/VPIconfont.vue'
|
||||
import VPIconify from '@theme/VPIconify.vue'
|
||||
import VPIconImage from '@theme/VPIconImage.vue'
|
||||
import { computed } from 'vue'
|
||||
import { withBase } from 'vuepress/client'
|
||||
import { isLinkHttp } from 'vuepress/shared'
|
||||
import { useIconsData } from '../composables/index.js'
|
||||
|
||||
const props = defineProps<{
|
||||
provider?: 'iconify' | 'iconfont' | 'fontawesome'
|
||||
name: string | { svg: string }
|
||||
size?: string | number
|
||||
color?: string
|
||||
extra?: string
|
||||
}>()
|
||||
|
||||
const iconsData = useIconsData()
|
||||
declare const __MD_POWER_ICON_PROVIDER__: 'iconify' | 'iconfont' | 'fontawesome'
|
||||
declare const __MD_POWER_ICON_PREFIX__: string
|
||||
|
||||
const type = computed(() => {
|
||||
const provider = props.provider || __MD_POWER_ICON_PROVIDER__
|
||||
// name -> https://example.com/icon.svg
|
||||
// name -> /icon.svg
|
||||
if (typeof props.name === 'string' && (isLinkHttp(props.name) || props.name[0] === '/')) {
|
||||
return 'link'
|
||||
}
|
||||
|
||||
// name -> { svg: '<svg></svg>' }
|
||||
if (typeof props.name === 'object' && !!props.name.svg) {
|
||||
return 'svg'
|
||||
}
|
||||
if (typeof props.name === 'string' && iconsData.value[props.name]) {
|
||||
return 'local'
|
||||
|
||||
if (provider === 'iconfont' || provider === 'fontawesome') {
|
||||
return provider
|
||||
}
|
||||
return 'remote'
|
||||
|
||||
return 'iconify'
|
||||
})
|
||||
|
||||
const svg = computed(() => {
|
||||
if (type.value === 'svg')
|
||||
return (props.name as { svg: string }).svg
|
||||
|
||||
return ''
|
||||
})
|
||||
const link = computed(() => {
|
||||
if (type.value === 'link') {
|
||||
const link = props.name as string
|
||||
return isLinkHttp(link) ? link : withBase(link)
|
||||
}
|
||||
return ''
|
||||
})
|
||||
|
||||
const className = computed(() => {
|
||||
if (type.value === 'local') {
|
||||
const name = props.name as string
|
||||
return iconsData.value[name] || ''
|
||||
}
|
||||
return ''
|
||||
})
|
||||
function parseSize(size: string | number): string {
|
||||
if (String(Number(size)) === String(size))
|
||||
return `${size}px`
|
||||
return String(size)
|
||||
}
|
||||
|
||||
const size = computed(() => {
|
||||
const size = props.size
|
||||
if (!size)
|
||||
return undefined
|
||||
if (String(Number(size)) === size)
|
||||
return `${size}px`
|
||||
|
||||
return size
|
||||
const [width, height] = String(size)
|
||||
.replaceAll('px', '[UNIT]')
|
||||
.split('x')
|
||||
.map(s => parseSize(s.replaceAll('[UNIT]', 'px').trim()))
|
||||
|
||||
return { width, height: height || width }
|
||||
})
|
||||
|
||||
const style = computed(() => ({
|
||||
'background-color': props.color,
|
||||
'width': size.value,
|
||||
'height': size.value,
|
||||
const binding = computed(() => ({
|
||||
name: props.name as string,
|
||||
color: props.color,
|
||||
size: size.value,
|
||||
prefix: __MD_POWER_ICON_PREFIX__ as any,
|
||||
}))
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<span v-if="type === 'link'" class="vp-icon-img">
|
||||
<img :src="link" alt="" :style="{ height: size }">
|
||||
</span>
|
||||
<span
|
||||
v-else-if="type === 'svg'"
|
||||
class="vp-icon"
|
||||
:style="style"
|
||||
v-html="svg"
|
||||
<VPIconImage
|
||||
v-if="type === 'link' || type === 'svg'"
|
||||
:type="type" :name="name" :color="color" :size="size"
|
||||
/>
|
||||
<span
|
||||
v-else-if="type === 'local' && className"
|
||||
class="vp-icon" :class="[className]"
|
||||
:style="style"
|
||||
<VPIconfont
|
||||
v-else-if="type === 'iconfont'"
|
||||
v-bind="binding"
|
||||
/>
|
||||
<VPIconFa
|
||||
v-else-if="type === 'fontawesome'"
|
||||
:extra="extra"
|
||||
v-bind="{ ...binding, ...$attrs }"
|
||||
/>
|
||||
<VPIconify
|
||||
v-else-if="type === 'iconify'"
|
||||
:extra="extra"
|
||||
v-bind="binding"
|
||||
/>
|
||||
<VPIconify v-else :name="(name as string)" :size="size" :color="color" />
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.vp-icon-img {
|
||||
display: inline-block;
|
||||
width: max-content;
|
||||
height: 1em;
|
||||
margin: 0 0.3em;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.vp-icon-img img {
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
62
theme/src/client/components/VPIconFa.vue
Normal file
62
theme/src/client/components/VPIconFa.vue
Normal file
@ -0,0 +1,62 @@
|
||||
<script setup lang="ts">
|
||||
import type { FontAwesomePrefix } from 'vuepress-plugin-md-power/client'
|
||||
import { computed } from 'vue'
|
||||
|
||||
const props = defineProps<{
|
||||
name: string
|
||||
size?: { width?: string, height?: string }
|
||||
color?: string
|
||||
prefix?: FontAwesomePrefix
|
||||
extra?: string
|
||||
}>()
|
||||
|
||||
const configs: Record<string, FontAwesomePrefix[]> = {
|
||||
'solid': ['fas', 's'],
|
||||
'regular': ['far', 'r'],
|
||||
'light': ['fal', 'l'],
|
||||
'thin': ['fat', 't'],
|
||||
'duotone solid': ['fads', 'ds'],
|
||||
'sharp solid': ['fass', 'ss'],
|
||||
'sharp regular': ['fasr', 'sr'],
|
||||
'sharp light': ['fasl', 'sl'],
|
||||
'sharp thin': ['fast', 'st'],
|
||||
'sharp-duotone solid': ['fasds', 'sds'],
|
||||
'brands': ['fab', 'b'],
|
||||
}
|
||||
|
||||
const iconName = computed(() => {
|
||||
const icon = props.name.includes(':') ? props.name : `${props.prefix || 'fas'}:${props.name}`
|
||||
const [type, name] = icon.split(':')
|
||||
let prefix = 'solid'
|
||||
for (const [key, alias] of Object.entries(configs)) {
|
||||
if (alias.includes(type as FontAwesomePrefix)) {
|
||||
prefix = key
|
||||
break
|
||||
}
|
||||
}
|
||||
return `${prefix.split(' ').map(v => `fa-${v.trim()}`).join(' ')} fa-${name}`
|
||||
})
|
||||
|
||||
const extraClasses = computed(() => {
|
||||
const extra = props.extra
|
||||
if (!extra)
|
||||
return []
|
||||
return extra.split(' ').map(v => v.trim().startsWith('fa-') ? v : `fa-${v}`)
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<i
|
||||
class="vp-icon fontawesome" :class="[iconName, ...extraClasses]"
|
||||
data-provider="fontawesome" aria-hidden
|
||||
:style="{ color, ...size }"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
.vp-icon.fontawesome {
|
||||
display: inline-block;
|
||||
line-height: inherit;
|
||||
vertical-align: middle;
|
||||
}
|
||||
</style>
|
||||
53
theme/src/client/components/VPIconImage.vue
Normal file
53
theme/src/client/components/VPIconImage.vue
Normal file
@ -0,0 +1,53 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import { withBase } from 'vuepress/client'
|
||||
import { isLinkHttp } from 'vuepress/shared'
|
||||
|
||||
const props = defineProps<{
|
||||
type: 'link' | 'svg'
|
||||
name: string | { svg: string }
|
||||
color?: string
|
||||
size?: { width?: string, height?: string }
|
||||
}>()
|
||||
|
||||
const svg = computed(() => {
|
||||
if (props.type === 'svg' && typeof props.name === 'object' && 'svg' in props.name) {
|
||||
return props.name.svg
|
||||
}
|
||||
return ''
|
||||
})
|
||||
const link = computed(() => {
|
||||
if (props.type === 'link') {
|
||||
const link = props.name as string
|
||||
return isLinkHttp(link) ? link : withBase(link)
|
||||
}
|
||||
return ''
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<span v-if="type === 'link'" class="vp-icon-img" aria-hidden>
|
||||
<img :src="link" alt="" :style="{ height: size?.height }">
|
||||
</span>
|
||||
<span
|
||||
v-else-if="type === 'svg'"
|
||||
class="vp-icon"
|
||||
:style="{ color, ...size }"
|
||||
aria-hidden
|
||||
v-html="svg"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.vp-icon-img {
|
||||
display: inline-block;
|
||||
width: max-content;
|
||||
height: 1em;
|
||||
margin: 0 0.3em;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.vp-icon-img img {
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
22
theme/src/client/components/VPIconfont.vue
Normal file
22
theme/src/client/components/VPIconfont.vue
Normal file
@ -0,0 +1,22 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
|
||||
const props = defineProps<{
|
||||
name: string
|
||||
size?: { width?: string, height?: string }
|
||||
color?: string
|
||||
prefix?: string
|
||||
}>()
|
||||
|
||||
const prefix = computed(() => props.prefix || 'iconfont icon-')
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<i
|
||||
class="vp-icon"
|
||||
:class="`${prefix}${name}`"
|
||||
:style="{ color, 'font-size': size?.height || '1em' }"
|
||||
data-provider="iconfont"
|
||||
aria-hidden
|
||||
/>
|
||||
</template>
|
||||
@ -3,61 +3,63 @@ import type { IconifyIcon } from '@iconify/vue/offline'
|
||||
import { loadIcon } from '@iconify/vue'
|
||||
import { Icon as OfflineIcon } from '@iconify/vue/offline'
|
||||
import { computed, ref, watch } from 'vue'
|
||||
import { useIconsData } from '../composables/index.js'
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
name?: string
|
||||
size?: string | number
|
||||
color?: string
|
||||
}>(),
|
||||
{
|
||||
name: '',
|
||||
size: '',
|
||||
color: '',
|
||||
},
|
||||
)
|
||||
const props = defineProps<{
|
||||
name: string
|
||||
size?: { width?: string, height?: string }
|
||||
color?: string
|
||||
prefix?: string
|
||||
extra?: string
|
||||
}>()
|
||||
|
||||
const icon = ref<IconifyIcon | null>(null)
|
||||
const loaded = ref(false)
|
||||
|
||||
async function loadIconComponent() {
|
||||
const iconsData = useIconsData()
|
||||
|
||||
const iconName = computed(() => {
|
||||
const name = props.name
|
||||
if (name.includes(':'))
|
||||
return name
|
||||
return props.prefix ? `${props.prefix}:${name}` : name
|
||||
})
|
||||
|
||||
const localIconName = computed(() => iconsData.value[iconName.value])
|
||||
|
||||
async function loadRemoteIcon() {
|
||||
if (icon.value)
|
||||
return
|
||||
|
||||
if (!__VUEPRESS_SSR__) {
|
||||
try {
|
||||
loaded.value = false
|
||||
icon.value = await loadIcon(props.name)
|
||||
}
|
||||
finally {
|
||||
loaded.value = true
|
||||
}
|
||||
}
|
||||
else {
|
||||
loaded.value = true
|
||||
if (!localIconName.value) {
|
||||
loaded.value = false
|
||||
icon.value = await loadIcon(props.name)
|
||||
}
|
||||
loaded.value = true
|
||||
}
|
||||
|
||||
watch(() => props.name, loadIconComponent, { immediate: true })
|
||||
|
||||
const size = computed(() => {
|
||||
const size = props.size || '1em'
|
||||
if (String(Number(size)) === size)
|
||||
return `${size}px`
|
||||
|
||||
return size
|
||||
})
|
||||
const color = computed(() => props.color || 'currentColor')
|
||||
if (!__VUEPRESS_SSR__)
|
||||
watch(() => props.name, loadRemoteIcon, { immediate: true })
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ClientOnly>
|
||||
<span v-if="!loaded" class="vp-icon iconify" :style="{ color, width: size, height: size }" />
|
||||
<span
|
||||
v-if="localIconName"
|
||||
class="vp-icon" :class="[localIconName, extra]"
|
||||
:style="{ color, ...size }"
|
||||
aria-hidden
|
||||
data-provider="iconify"
|
||||
/>
|
||||
<ClientOnly v-else>
|
||||
<span v-if="!loaded" class="vp-icon iconify" :style="{ color, ...size }" />
|
||||
<OfflineIcon
|
||||
v-else-if="icon"
|
||||
class="vp-icon iconify"
|
||||
:class="[extra]"
|
||||
:icon="icon"
|
||||
:style="{ color, width: size, height: size }"
|
||||
:style="{ color, ...size }"
|
||||
aria-hidden
|
||||
data-provider="iconify"
|
||||
/>
|
||||
</ClientOnly>
|
||||
</template>
|
||||
|
||||
@ -288,6 +288,10 @@ function onCaretClick() {
|
||||
margin: 0 0.25rem 0 0;
|
||||
}
|
||||
|
||||
.item :deep(.vp-icon.fontawesome) {
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.item:hover .caret {
|
||||
color: var(--vp-c-text-2);
|
||||
}
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
[class^="vpi-"],
|
||||
[class*=" vpi-"],
|
||||
.vp-icon {
|
||||
[class*=" vpi-"] {
|
||||
display: inline-block;
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
@ -8,8 +7,7 @@
|
||||
}
|
||||
|
||||
[class^="vpi-"].bg,
|
||||
[class*=" vpi-"].bg,
|
||||
.vp-icon.bg {
|
||||
[class*=" vpi-"].bg {
|
||||
background-color: transparent;
|
||||
background-image: var(--icon);
|
||||
background-repeat: no-repeat;
|
||||
@ -17,8 +15,7 @@
|
||||
}
|
||||
|
||||
[class^="vpi-"]:not(.bg),
|
||||
[class*=" vpi-"]:not(.bg),
|
||||
.vp-icon:not(.bg) {
|
||||
[class*=" vpi-"]:not(.bg) {
|
||||
color: inherit;
|
||||
background-color: currentcolor;
|
||||
-webkit-mask: var(--icon) no-repeat;
|
||||
|
||||
@ -48,3 +48,70 @@
|
||||
opacity: 0 !important;
|
||||
transform: translateX(-10px) !important;
|
||||
}
|
||||
|
||||
/* ----------------- Read More Link ------------------ */
|
||||
.vp-doc a.read-more,
|
||||
.vp-doc a.readmore {
|
||||
position: relative;
|
||||
display: block;
|
||||
padding: 8px 22px 8px calc(1.25em + 16px);
|
||||
margin: 16px 0;
|
||||
font-size: inherit;
|
||||
font-size: 14px;
|
||||
font-weight: inherit;
|
||||
color: currentcolor;
|
||||
text-decoration: none;
|
||||
background-color: var(--vp-c-bg-safe);
|
||||
border: dashed 1px var(--vp-c-divider);
|
||||
border-radius: 8px;
|
||||
transition: border-color var(--vp-t-color), background-color var(--vp-t-color);
|
||||
}
|
||||
|
||||
.vp-doc a.read-more:hover,
|
||||
.vp-doc a.readmore:hover {
|
||||
color: currentcolor;
|
||||
background-color: var(--vp-c-bg-soft);
|
||||
border: solid 1px var(--vp-c-brand-2);
|
||||
}
|
||||
|
||||
.vp-doc a.read-more::before,
|
||||
.vp-doc a.readmore::before {
|
||||
--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Cpath fill='%23000' d='M20 22H4a1 1 0 0 1-1-1V3a1 1 0 0 1 1-1h16a1 1 0 0 1 1 1v18a1 1 0 0 1-1 1M7 4H5v16h14V4h-5v9l-3.5-2L7 13z'/%3E%3C/svg%3E");
|
||||
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 16px;
|
||||
display: inline-block;
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
color: var(--vp-c-brand-1);
|
||||
vertical-align: middle;
|
||||
content: "";
|
||||
background-color: currentcolor;
|
||||
-webkit-mask: var(--icon) no-repeat;
|
||||
mask: var(--icon) no-repeat;
|
||||
-webkit-mask-size: 100% 100%;
|
||||
mask-size: 100% 100%;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
.vp-doc a.read-more[href*="://"]::after,
|
||||
.vp-doc a.readmore[target=_blank]::after {
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
right: 8px;
|
||||
width: 14px !important;
|
||||
height: 14px !important;
|
||||
margin: 0 !important;
|
||||
color: var(--vp-c-text-3) !important;
|
||||
}
|
||||
|
||||
.vp-doc a.read-more[href*="://"]:hover::after,
|
||||
.vp-doc a.readmore[target=_blank]:hover::after {
|
||||
color: var(--vp-c-brand-2) !important;
|
||||
}
|
||||
|
||||
.vp-doc a.read-more :where(strong),
|
||||
.vp-doc a.readmore :where(strong) {
|
||||
color: var(--vp-c-brand-1);
|
||||
}
|
||||
|
||||
@ -52,7 +52,8 @@ export const MARKDOWN_POWER_FIELDS: (keyof MarkdownPowerPluginOptions)[] = [
|
||||
'demo',
|
||||
'fileTree',
|
||||
'field',
|
||||
'icons',
|
||||
'icons', // deprecated
|
||||
'icon',
|
||||
'imageSize',
|
||||
'jsfiddle',
|
||||
'npmTo',
|
||||
|
||||
@ -43,7 +43,7 @@ export function codePlugins(pluginOptions: ThemeBuiltinPlugins): PluginConfig {
|
||||
langs: uniq([...twoslash ? ['ts', 'js', 'vue', 'json', 'bash', 'sh'] : [], ...langs]),
|
||||
codeBlockTitle: (title, code) => {
|
||||
const icon = getIcon(title)
|
||||
return `<div class="code-block-title" data-title="${title}"><div class="code-block-title-bar"><span class="title">${icon ? `<VPIcon name="${icon}"/>` : ''}${title}</span></div>${code}</div>`
|
||||
return `<div class="code-block-title" data-title="${title}"><div class="code-block-title-bar"><span class="title">${icon ? `<VPIcon provider="iconify" name="${icon}"/>` : ''}${title}</span></div>${code}</div>`
|
||||
},
|
||||
twoslash: isPlainObject(twoslashOptions)
|
||||
? {
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import type { App, Page } from 'vuepress'
|
||||
import type { IconOptions } from 'vuepress-plugin-md-power'
|
||||
import type { ThemeHomeConfig, ThemeNavItem, ThemeOptions, ThemeSidebar } from '../../shared/index.js'
|
||||
import type { FsCache } from '../utils/index.js'
|
||||
import { getIconContentCSS, getIconData } from '@iconify/utils'
|
||||
@ -22,6 +23,7 @@ const ICON_REGEXP = /<(?:VP)?(Icon|Card|LinkCard|Button)([^>]*)>/g
|
||||
const ICON_NAME_REGEXP = /(?:name|icon|suffix-icon)="([^"]+)"/
|
||||
const URL_CONTENT_REGEXP = /(url\([\s\S]+\))/
|
||||
const ICONIFY_NAME = /^[\w-]+:[\w-]+$/
|
||||
|
||||
const JS_FILENAME = 'internal/iconify.js'
|
||||
const CSS_FILENAME = 'internal/iconify.css'
|
||||
|
||||
@ -32,12 +34,6 @@ let fsCache: FsCache<IconDataMap> | null = null
|
||||
// { iconName: { className, content } }
|
||||
const cache: IconDataMap = {}
|
||||
|
||||
function isIconify(icon: any): icon is string {
|
||||
if (!icon || typeof icon !== 'string' || isLinkAbsolute(icon) || isLinkHttp(icon))
|
||||
return false
|
||||
return icon[0] !== '{' && ICONIFY_NAME.test(icon)
|
||||
}
|
||||
|
||||
export async function prepareIcons(app: App): Promise<void> {
|
||||
perf.mark('prepare:icons:total')
|
||||
const options = getThemeConfig()
|
||||
@ -51,9 +47,11 @@ export async function prepareIcons(app: App): Promise<void> {
|
||||
}
|
||||
|
||||
perf.mark('prepare:pages:icons')
|
||||
|
||||
const iconOptions = options.markdown?.icon || {}
|
||||
const iconList: string[] = []
|
||||
app.pages.forEach(page => iconList.push(...getIconsWithPage(page)))
|
||||
iconList.push(...getIconWithThemeConfig(options))
|
||||
app.pages.forEach(page => iconList.push(...getIconsWithPage(page, iconOptions)))
|
||||
iconList.push(...getIconWithThemeConfig(options, iconOptions))
|
||||
|
||||
const collectMap: CollectMap = {}
|
||||
uniq(iconList).filter((icon) => {
|
||||
@ -108,31 +106,49 @@ export async function prepareIcons(app: App): Promise<void> {
|
||||
perf.log('prepare:icons:total')
|
||||
}
|
||||
|
||||
function getIconsWithPage(page: Page): string[] {
|
||||
const list = page.contentRendered
|
||||
.match(ICON_REGEXP)
|
||||
?.map(match => match.match(ICON_NAME_REGEXP)?.[1])
|
||||
.filter(isIconify) as string[] || []
|
||||
function isIconify(icon: any): icon is string {
|
||||
if (!icon || typeof icon !== 'string' || isLinkAbsolute(icon) || isLinkHttp(icon))
|
||||
return false
|
||||
return icon[0] !== '{' && ICONIFY_NAME.test(icon)
|
||||
}
|
||||
|
||||
function withPrefix(icon: string, prefix?: string): string {
|
||||
if (!prefix)
|
||||
return icon
|
||||
return icon.includes(':') ? icon : `${prefix}:${icon}`
|
||||
}
|
||||
|
||||
function getIconsWithPage(page: Page, { provider = 'iconify', prefix }: IconOptions): string[] {
|
||||
const list: string[] = []
|
||||
const matches = page.contentRendered.match(ICON_REGEXP) || []
|
||||
for (const matched of matches) {
|
||||
if (provider === 'iconify' || matched.includes('provider="iconify"')) {
|
||||
const icon = matched.match(ICON_NAME_REGEXP)?.[1]
|
||||
if (isIconify(icon))
|
||||
list.push(withPrefix(icon, prefix))
|
||||
}
|
||||
}
|
||||
|
||||
const addIcon = (icon: unknown): void => {
|
||||
if (isIconify(icon) && (provider === 'iconify' || icon.startsWith('iconify'))) {
|
||||
list.push(withPrefix(icon.replace(/^iconify /, ''), prefix))
|
||||
}
|
||||
}
|
||||
|
||||
const fm = page.frontmatter
|
||||
if (fm.icon && isIconify(fm.icon)) {
|
||||
list.push(fm.icon)
|
||||
}
|
||||
addIcon(fm.icon)
|
||||
|
||||
if ((fm.home || fm.pageLayout === 'home') && (fm.config as ThemeHomeConfig[])?.length) {
|
||||
for (const config of (fm.config as ThemeHomeConfig[])) {
|
||||
if (config.type === 'features' && config.features.length) {
|
||||
for (const feature of config.features) {
|
||||
if (feature.icon && isIconify(feature.icon))
|
||||
list.push(feature.icon)
|
||||
addIcon(feature.icon)
|
||||
}
|
||||
}
|
||||
if (config.type === 'hero' && config.hero?.actions?.length) {
|
||||
for (const action of config.hero.actions) {
|
||||
if (action.icon && isIconify(action.icon))
|
||||
list.push(action.icon)
|
||||
if (action.suffixIcon && isIconify(action.suffixIcon))
|
||||
list.push(action.suffixIcon)
|
||||
addIcon(action.icon)
|
||||
addIcon(action.suffixIcon)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -141,7 +157,7 @@ function getIconsWithPage(page: Page): string[] {
|
||||
return list
|
||||
}
|
||||
|
||||
function getIconWithThemeConfig(options: ThemeOptions): string[] {
|
||||
function getIconWithThemeConfig(options: ThemeOptions, { provider = 'iconify', prefix }: IconOptions): string[] {
|
||||
const list: string[] = []
|
||||
// navbar notes sidebar
|
||||
const locales = options.locales || {}
|
||||
@ -159,7 +175,13 @@ function getIconWithThemeConfig(options: ThemeOptions): string[] {
|
||||
sidebarList.forEach(sidebar => list.push(...getIconWithSidebar(sidebar)))
|
||||
})
|
||||
|
||||
return list.filter(isIconify)
|
||||
const addIcon = (icon: unknown): string | void => {
|
||||
if (isIconify(icon) && (provider === 'iconify' || icon.startsWith('iconify'))) {
|
||||
return withPrefix(icon.replace(/^iconify /, ''), prefix)
|
||||
}
|
||||
}
|
||||
|
||||
return list.map(addIcon).filter(Boolean) as string[]
|
||||
}
|
||||
|
||||
function getIconWithNavbar(navbar: ThemeNavItem[]): string[] {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user