From fefbde6c9b200e36d4ebbd324ce51a3e59380963 Mon Sep 17 00:00:00 2001 From: Zhong <58726932+cszhjh@users.noreply.github.com> Date: Wed, 9 Oct 2024 23:44:01 +0800 Subject: [PATCH] feat: support code component (#1791) * feat: support code component * feat: using shiki * types: fix code type * feat(code): optimize logic based on review comment * feat(code): support highlighter-provider * feat(code): fix test cases * feat(code): optimize docs based on review comment * feat(code): optimize according to review comments --- packages/varlet-ui/package.json | 15 +- packages/varlet-ui/src/code/Code.vue | 43 +++ .../__snapshots__/index.spec.js.snap | 52 ++++ .../src/code/__tests__/index.spec.js | 92 ++++++ packages/varlet-ui/src/code/code.less | 21 ++ packages/varlet-ui/src/code/docs/en-US.md | 83 +++++ packages/varlet-ui/src/code/docs/zh-CN.md | 83 +++++ packages/varlet-ui/src/code/example/index.vue | 23 ++ .../src/code/example/locale/en-US.ts | 3 + .../src/code/example/locale/index.ts | 17 ++ .../src/code/example/locale/zh-CN.ts | 3 + packages/varlet-ui/src/code/index.ts | 12 + packages/varlet-ui/src/code/props.ts | 12 + .../HighlighterProvider.vue | 26 ++ .../__snapshots__/index.spec.js.snap | 5 + .../__tests__/index.spec.js | 31 ++ .../src/highlighter-provider/docs/en-US.md | 30 ++ .../src/highlighter-provider/docs/zh-CN.md | 30 ++ .../src/highlighter-provider/index.ts | 10 + .../src/highlighter-provider/props.ts | 24 ++ .../src/highlighter-provider/provide.ts | 22 ++ .../__snapshots__/index.spec.js.snap | 6 + packages/varlet-ui/src/themes/dark/code.ts | 4 + packages/varlet-ui/src/themes/dark/index.ts | 2 + .../varlet-ui/src/themes/md3-dark/code.ts | 4 + .../varlet-ui/src/themes/md3-dark/index.ts | 2 + .../varlet-ui/src/themes/md3-light/code.ts | 4 + .../varlet-ui/src/themes/md3-light/index.ts | 2 + packages/varlet-ui/types/code.d.ts | 17 ++ .../varlet-ui/types/highlighterProvider.d.ts | 26 ++ packages/varlet-ui/types/index.d.ts | 4 + packages/varlet-ui/types/styleVars.d.ts | 2 + packages/varlet-ui/varlet.config.mjs | 8 + pnpm-lock.yaml | 284 ++++++++++++++++++ 34 files changed, 995 insertions(+), 7 deletions(-) create mode 100644 packages/varlet-ui/src/code/Code.vue create mode 100644 packages/varlet-ui/src/code/__tests__/__snapshots__/index.spec.js.snap create mode 100644 packages/varlet-ui/src/code/__tests__/index.spec.js create mode 100644 packages/varlet-ui/src/code/code.less create mode 100644 packages/varlet-ui/src/code/docs/en-US.md create mode 100644 packages/varlet-ui/src/code/docs/zh-CN.md create mode 100644 packages/varlet-ui/src/code/example/index.vue create mode 100644 packages/varlet-ui/src/code/example/locale/en-US.ts create mode 100644 packages/varlet-ui/src/code/example/locale/index.ts create mode 100644 packages/varlet-ui/src/code/example/locale/zh-CN.ts create mode 100644 packages/varlet-ui/src/code/index.ts create mode 100644 packages/varlet-ui/src/code/props.ts create mode 100644 packages/varlet-ui/src/highlighter-provider/HighlighterProvider.vue create mode 100644 packages/varlet-ui/src/highlighter-provider/__tests__/__snapshots__/index.spec.js.snap create mode 100644 packages/varlet-ui/src/highlighter-provider/__tests__/index.spec.js create mode 100644 packages/varlet-ui/src/highlighter-provider/docs/en-US.md create mode 100644 packages/varlet-ui/src/highlighter-provider/docs/zh-CN.md create mode 100644 packages/varlet-ui/src/highlighter-provider/index.ts create mode 100644 packages/varlet-ui/src/highlighter-provider/props.ts create mode 100644 packages/varlet-ui/src/highlighter-provider/provide.ts create mode 100644 packages/varlet-ui/src/themes/dark/code.ts create mode 100644 packages/varlet-ui/src/themes/md3-dark/code.ts create mode 100644 packages/varlet-ui/src/themes/md3-light/code.ts create mode 100644 packages/varlet-ui/types/code.d.ts create mode 100644 packages/varlet-ui/types/highlighterProvider.d.ts diff --git a/packages/varlet-ui/package.json b/packages/varlet-ui/package.json index 2ab9b919a01..c3e371d3065 100644 --- a/packages/varlet-ui/package.json +++ b/packages/varlet-ui/package.json @@ -64,20 +64,21 @@ "decimal.js": "^10.2.1" }, "devDependencies": { + "@types/node": "^18.7.18", "@varlet/cli": "workspace:*", - "@varlet/ui": "workspace: *", "@varlet/touch-emulator": "workspace:*", + "@varlet/ui": "workspace: *", + "@vitest/coverage-istanbul": "2.0.5", "@vue/runtime-core": "3.4.21", "@vue/test-utils": "2.4.1", - "@types/node": "^18.7.18", - "@vitest/coverage-istanbul": "2.0.5", - "zod": "^3.23.8", - "jsdom": "24.1.1", - "vitest": "2.0.5", "clipboard": "^2.0.6", + "jsdom": "24.1.1", "live-server": "^1.2.1", + "shiki": "^1.21.0", "typescript": "^5.1.5", + "vitest": "2.0.5", "vue": "3.4.21", - "vue-router": "4.2.0" + "vue-router": "4.2.0", + "zod": "^3.23.8" } } \ No newline at end of file diff --git a/packages/varlet-ui/src/code/Code.vue b/packages/varlet-ui/src/code/Code.vue new file mode 100644 index 00000000000..cec103e93a0 --- /dev/null +++ b/packages/varlet-ui/src/code/Code.vue @@ -0,0 +1,43 @@ + + + + + diff --git a/packages/varlet-ui/src/code/__tests__/__snapshots__/index.spec.js.snap b/packages/varlet-ui/src/code/__tests__/__snapshots__/index.spec.js.snap new file mode 100644 index 00000000000..701f3aea2f8 --- /dev/null +++ b/packages/varlet-ui/src/code/__tests__/__snapshots__/index.spec.js.snap @@ -0,0 +1,52 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`test code component props > test code content 1`] = ` +"
+
function twoSum(nums, target) {
+  const map = new Map();
+  for (let i = 0; i < nums.length; i++) {
+      const num = nums[i];
+      const theOther = target - num;
+      if (map.has(theOther)) {
+          return [map.get(theOther), i];
+      }
+      map.set(num, i);
+  }
+};
+
+
" +`; + +exports[`test code component props > test code lang 1`] = ` +"
+
+
+
" +`; + +exports[`test code component props > test code theme 1`] = ` +"
+
function twoSum(nums, target) {
+  const map = new Map();
+  for (let i = 0; i < nums.length; i++) {
+      const num = nums[i];
+      const theOther = target - num;
+      if (map.has(theOther)) {
+          return [map.get(theOther), i];
+      }
+      map.set(num, i);
+  }
+};
+
+
" +`; diff --git a/packages/varlet-ui/src/code/__tests__/index.spec.js b/packages/varlet-ui/src/code/__tests__/index.spec.js new file mode 100644 index 00000000000..dd5122c58eb --- /dev/null +++ b/packages/varlet-ui/src/code/__tests__/index.spec.js @@ -0,0 +1,92 @@ +import Code from '..' +import VarCode from '../Code' +import VarHighlighterProvider from '../../highlighter-provider' +import { mount } from '@vue/test-utils' +import { createApp, h } from 'vue' +import { delay } from '../../utils/test' +import { expect, describe, test } from 'vitest' +import { codeToHtml } from 'shiki' + +const code = `function twoSum(nums, target) { + const map = new Map(); + for (let i = 0; i < nums.length; i++) { + const num = nums[i]; + const theOther = target - num; + if (map.has(theOther)) { + return [map.get(theOther), i]; + } + map.set(num, i); + } +};` + +test('test code use', () => { + const app = createApp({}).use(Code) + expect(app.component(Code.name)).toBeTruthy() +}) + +describe('test code component props', () => { + test('test code content', async () => { + const wrapper = mount(VarHighlighterProvider, { + props: { + highlighter: { + codeToHtml, + }, + }, + slots: { + default: () => + h(VarCode, { + code, + language: 'javascript', + theme: 'monokai', + }), + }, + }) + + await delay(300) + expect(wrapper.html()).toMatchSnapshot() + wrapper.unmount() + }) + + test('test code lang', async () => { + const wrapper = mount(VarHighlighterProvider, { + props: { + highlighter: { + codeToHtml, + }, + }, + slots: { + default: () => + h(VarCode, { + content: code, + lang: 'javascript', + }), + }, + }) + + await delay(300) + expect(wrapper.html()).toMatchSnapshot() + wrapper.unmount() + }) + + test('test code theme', async () => { + const wrapper = mount(VarHighlighterProvider, { + props: { + highlighter: { + codeToHtml, + }, + }, + slots: { + default: () => + h(VarCode, { + code, + language: 'javascript', + theme: 'material-theme', + }), + }, + }) + + await delay(300) + expect(wrapper.html()).toMatchSnapshot() + wrapper.unmount() + }) +}) diff --git a/packages/varlet-ui/src/code/code.less b/packages/varlet-ui/src/code/code.less new file mode 100644 index 00000000000..55adc072862 --- /dev/null +++ b/packages/varlet-ui/src/code/code.less @@ -0,0 +1,21 @@ +:root { + --code-border-radius: 4px; + --code-content-padding: 16px; +} + +.var-code { + border-radius: var(--code-border-radius); + position: relative; + overflow: hidden; + width: 100%; + height: 100%; + + pre { + padding: var(--code-content-padding); + border-radius: var(--code-border-radius); + width: 100%; + height: 100%; + margin: 0; + overflow: auto; + } +} diff --git a/packages/varlet-ui/src/code/docs/en-US.md b/packages/varlet-ui/src/code/docs/en-US.md new file mode 100644 index 00000000000..1c2696ce7d0 --- /dev/null +++ b/packages/varlet-ui/src/code/docs/en-US.md @@ -0,0 +1,83 @@ +# Code + +### Intro + +Code component, used to display code blocks and highlight code syntax. + +### Notes + +- Due to package size considerations, Varlet does not include a built-in code highlighter. If you need to use the code block component, please ensure you use the HighlighterProvider component to customize the highlighter. +- Using the HighlighterProvider component, you can set different highlighters for different code blocks. It is recommended to use [Shiki](https://shiki.style/) as the highlighter, as it has built-in support for `codeToHtml` and offers more flexibility in switching languages and themes. + +### Basic Usage + +```html + + + +``` + +## API + +### Props + +#### Code Props + +| Prop | Description | Type | Default | +|------------------|--------------------------------------------------------------|----------------|------------------| +| `code` | Code Snippet | _string_ | `-` | +| `language` | Language | _string_ | `-` | +| `theme` | Theme | _string_ | `-` | + +#### HighlighterProvider Props + +| Prop | Description | Type | Default | +|------------------|--------------------------------------------------------------|----------------|------------------| +| `highlighter` | Shader | `Highlighter` | `-` | +| `theme` | Theme | _string_ | `-` | +| `tag` | Tag name | _string_ | `div` | + + +#### Highlighter + +| Prop | Description | Type | Default | +| ------ | ------ | ------ | ------ | +| `codeToHtml` | Callback this function when the content, theme, or language changes, and specify the lang and theme options. It will return an HTML string. | `(code: string, options: CodeToHtmlOptions) => Promise` | `-` + +#### CodeToHtmlOptions + +| Prop | Description | Type | Default | +| ------ | ------ | ------ | ------ | +| `lang` | language | _string_ | `-` | +| `theme` | theme | _string_ | `-` | + +### Slots + +#### HighlighterProvider Slots + +| Name | Description | SlotProps | +| --- | --- | --- | +| `default` | Component content | `-` | + +### Style Variables + +Here are the CSS variables used by the component. Styles can be customized using [StyleProvider](#/en-US/style-provider). + +| Variable | Default | +| --- | --- | +| `--code-border-radius` | `4px` | +| `--code-content-padding` | `16px` | diff --git a/packages/varlet-ui/src/code/docs/zh-CN.md b/packages/varlet-ui/src/code/docs/zh-CN.md new file mode 100644 index 00000000000..91911210d12 --- /dev/null +++ b/packages/varlet-ui/src/code/docs/zh-CN.md @@ -0,0 +1,83 @@ +# 代码块 + +### 介绍 + +代码块组件,用于显示代码块并突出显示代码语法。 + +### 注意事项 + +- 由于包体积原因,varlet 不内置代码着色器,如果你需要使用代码块组件,请确保使用 HighlighterProvider 组件进行着色器定制。 +- 通过 HighlighterProvider 组件可以为不同的代码块设置不同的着色器。推荐使用 [Shiki](https://shiki.tmrs.site/) 作为着色器,因为它本身就实现了 `codeToHtml`,并且在语言和主题切换上也更加灵活。 + +### 基本使用 + +```html + + + +``` + +## API + +### 属性 + +#### Code Props + +| 参数 | 说明 | 类型 | 默认值 | +|------------------|-------------------------------------------------------------|-----------------|------------------| +| `code` | 代码片段 | _string_ | `-` | +| `language` | 语言 | _string_ | `-` | +| `theme` | 主题 | _string_ | `-` | + +#### HighlighterProvider Props + +| 参数 | 说明 | 类型 | 默认值 | +|------------------|--------------------------------------------------------------|----------------|------------------| +| `highlighter` | 着色器 | `Highlighter` | `-` | +| `theme` | 主题 | _string_ | `-` | +| `tag` | 自定义标签名 | _string_ | `div` | + +#### Highlighter + +| 参数 | 说明 | 类型 | 默认值 | +| ------ | ------ | ------ | ------ | +| `codeToHtml` | 当内容、主题、语言发生改变时回调该函数,并指定 lang 和 theme 选项,它将返回一个 HTML 字符串 | `(code: string, options: CodeToHtmlOptions) => Promise` | `-` + +#### CodeToHtmlOptions + +| 参数 | 说明 | 类型 | 默认值 | +| ------ | ------ | ------ | ------ | +| `lang` | 语言 | _string_ | `-` | +| `theme` | 主题 | _string_ | `-` | + +### 插槽 + +#### HighlighterProvider Slots + +| 插槽名 | 说明 | 参数 | +| --- | --- | --- | +| `default` | 组件内容 | `-` | + + +### 样式变量 + +以下为组件使用的 css 变量,可以使用 [StyleProvider 组件](#/zh-CN/style-provider) 进行样式定制。 + +| 变量名 | 默认值 | +| --- | --- | +| `--code-border-radius` | `4px` | +| `--code-content-padding` | `16px` | diff --git a/packages/varlet-ui/src/code/example/index.vue b/packages/varlet-ui/src/code/example/index.vue new file mode 100644 index 00000000000..70bc12f2182 --- /dev/null +++ b/packages/varlet-ui/src/code/example/index.vue @@ -0,0 +1,23 @@ + + + diff --git a/packages/varlet-ui/src/code/example/locale/en-US.ts b/packages/varlet-ui/src/code/example/locale/en-US.ts new file mode 100644 index 00000000000..2a7a833c3f8 --- /dev/null +++ b/packages/varlet-ui/src/code/example/locale/en-US.ts @@ -0,0 +1,3 @@ +export default { + basicUsage: 'Basic Usage', +} diff --git a/packages/varlet-ui/src/code/example/locale/index.ts b/packages/varlet-ui/src/code/example/locale/index.ts new file mode 100644 index 00000000000..8855457aa5c --- /dev/null +++ b/packages/varlet-ui/src/code/example/locale/index.ts @@ -0,0 +1,17 @@ +import { Locale } from '@varlet/ui' +import zhCN from './zh-CN' +import enUS from './en-US' + +const { add, use: exampleUse, t, merge } = Locale.useLocale() + +const use = (lang: string) => { + Locale.use(lang) + exampleUse(lang) +} + +Locale.add('zh-CN', Locale.zhCN) +Locale.add('en-US', Locale.enUS) +add('zh-CN', zhCN) +add('en-US', enUS) + +export { add, t, merge, use } diff --git a/packages/varlet-ui/src/code/example/locale/zh-CN.ts b/packages/varlet-ui/src/code/example/locale/zh-CN.ts new file mode 100644 index 00000000000..708f6eb2a76 --- /dev/null +++ b/packages/varlet-ui/src/code/example/locale/zh-CN.ts @@ -0,0 +1,3 @@ +export default { + basicUsage: '基本使用', +} diff --git a/packages/varlet-ui/src/code/index.ts b/packages/varlet-ui/src/code/index.ts new file mode 100644 index 00000000000..b1fdd0afb2b --- /dev/null +++ b/packages/varlet-ui/src/code/index.ts @@ -0,0 +1,12 @@ +import Code from './Code.vue' +import { withInstall, withPropsDefaultsSetter } from '../utils/components' +import { props as codeProps } from './props' + +withInstall(Code) +withPropsDefaultsSetter(Code, codeProps) + +export { codeProps } + +export const _CodeComponent = Code + +export default Code diff --git a/packages/varlet-ui/src/code/props.ts b/packages/varlet-ui/src/code/props.ts new file mode 100644 index 00000000000..e783d56e275 --- /dev/null +++ b/packages/varlet-ui/src/code/props.ts @@ -0,0 +1,12 @@ +export const props = { + code: { + type: String, + default: '', + }, + language: { + type: String, + }, + theme: { + type: String, + }, +} diff --git a/packages/varlet-ui/src/highlighter-provider/HighlighterProvider.vue b/packages/varlet-ui/src/highlighter-provider/HighlighterProvider.vue new file mode 100644 index 00000000000..493e23c1a90 --- /dev/null +++ b/packages/varlet-ui/src/highlighter-provider/HighlighterProvider.vue @@ -0,0 +1,26 @@ + diff --git a/packages/varlet-ui/src/highlighter-provider/__tests__/__snapshots__/index.spec.js.snap b/packages/varlet-ui/src/highlighter-provider/__tests__/__snapshots__/index.spec.js.snap new file mode 100644 index 00000000000..7eba65067c3 --- /dev/null +++ b/packages/varlet-ui/src/highlighter-provider/__tests__/__snapshots__/index.spec.js.snap @@ -0,0 +1,5 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`test highlighterProvider highlighter 1`] = `"
"`; + +exports[`test highlighterProvider tag 1`] = `""`; diff --git a/packages/varlet-ui/src/highlighter-provider/__tests__/index.spec.js b/packages/varlet-ui/src/highlighter-provider/__tests__/index.spec.js new file mode 100644 index 00000000000..37a1f510a29 --- /dev/null +++ b/packages/varlet-ui/src/highlighter-provider/__tests__/index.spec.js @@ -0,0 +1,31 @@ +import HighlighterProvider from '../index' +import VarHighlighterProvider from '../HighlighterProvider' +import { createApp } from 'vue' +import { mount } from '@vue/test-utils' +import { expect, test } from 'vitest' +import { codeToHtml } from 'shiki' + +test('test highlighterProvider component plugin', () => { + const app = createApp({}).use(HighlighterProvider) + expect(app.component(HighlighterProvider.name)).toBeTruthy() +}) + +test('test highlighterProvider highlighter', () => { + const wrapper = mount(VarHighlighterProvider, { + props: { + highlighter: { + codeToHtml, + }, + }, + }) + expect(wrapper.html()).toMatchSnapshot() + + wrapper.unmount() +}) + +test('test highlighterProvider tag', () => { + const wrapper = mount(VarHighlighterProvider, { props: { tag: 'span' } }) + expect(wrapper.html()).toMatchSnapshot() + + wrapper.unmount() +}) diff --git a/packages/varlet-ui/src/highlighter-provider/docs/en-US.md b/packages/varlet-ui/src/highlighter-provider/docs/en-US.md new file mode 100644 index 00000000000..3f1ef4bbe58 --- /dev/null +++ b/packages/varlet-ui/src/highlighter-provider/docs/en-US.md @@ -0,0 +1,30 @@ +# Highlighter Provider + +## API + +### Props + +| Prop | Description | Type | Default | +|------------------|--------------------------------------------------------------|----------------|------------------| +| `highlighter` | Shader | `Highlighter` | `-` | +| `theme` | Theme | _string_ | `-` | +| `tag` | Tag name | _string_ | `div` | + +### Highlighter + +| Prop | Description | Type | Default | +| ------ | ------ | ------ | ------ | +| `codeToHtml` | Callback this function when the content, theme, or language changes, and specify the lang and theme options. It will return an HTML string. | `(code: string, options: CodeToHtmlOptions) => Promise` | `-` + +### CodeToHtmlOptions + +| Prop | Description | Type | Default | +| ------ | ------ | ------ | ------ | +| `lang` | language | _string_ | `-` | +| `theme` | theme | _string_ | `-` | + +### Slots + +| Name | Description | SlotProps | +| --- | --- | --- | +| `default` | Component content | `-` | diff --git a/packages/varlet-ui/src/highlighter-provider/docs/zh-CN.md b/packages/varlet-ui/src/highlighter-provider/docs/zh-CN.md new file mode 100644 index 00000000000..d0e516fc2c0 --- /dev/null +++ b/packages/varlet-ui/src/highlighter-provider/docs/zh-CN.md @@ -0,0 +1,30 @@ +# 着色器定制 + +## API + +### 属性 + +| 参数 | 说明 | 类型 | 默认值 | +|------------------|--------------------------------------------------------------|----------------|------------------| +| `highlighter` | 着色器 | `Highlighter` | `-` | +| `theme` | 主题 | _string_ | `-` | +| `tag` | 自定义标签名 | _string_ | `div` | + +### Highlighter + +| 参数 | 说明 | 类型 | 默认值 | +| ------ | ------ | ------ | ------ | +| `codeToHtml` | 当内容、主题、语言发生改变时回调该函数,并指定 lang 和 theme 选项,它将返回一个 HTML 字符串 | `(code: string, options: CodeToHtmlOptions) => Promise` | `-` + +### CodeToHtmlOptions + +| 参数 | 说明 | 类型 | 默认值 | +| ------ | ------ | ------ | ------ | +| `lang` | 语言 | _string_ | `-` | +| `theme` | 主题 | _string_ | `-` | + +### 插槽 + +| 插槽名 | 说明 | 参数 | +| --- | --- | --- | +| `default` | 组件内容 | `-` | diff --git a/packages/varlet-ui/src/highlighter-provider/index.ts b/packages/varlet-ui/src/highlighter-provider/index.ts new file mode 100644 index 00000000000..9944db6ee8d --- /dev/null +++ b/packages/varlet-ui/src/highlighter-provider/index.ts @@ -0,0 +1,10 @@ +import HighlighterProvider from './HighlighterProvider.vue' +import { withInstall, withPropsDefaultsSetter } from '../utils/components' +import { props as highlighterProviderProps } from './props' + +withInstall(HighlighterProvider) +withPropsDefaultsSetter(HighlighterProvider, highlighterProviderProps) + +export const _HighlighterProviderComponent = HighlighterProvider + +export default HighlighterProvider diff --git a/packages/varlet-ui/src/highlighter-provider/props.ts b/packages/varlet-ui/src/highlighter-provider/props.ts new file mode 100644 index 00000000000..80b8efd021e --- /dev/null +++ b/packages/varlet-ui/src/highlighter-provider/props.ts @@ -0,0 +1,24 @@ +import { PropType } from 'vue' + +export interface CodeToHtmlOptions { + lang?: string + theme?: string +} + +export interface Highlighter { + codeToHtml: (code: string, options: CodeToHtmlOptions) => Promise +} + +export const props = { + highlighter: { + type: Object as PropType, + }, + theme: { + type: String, + default: 'nord', + }, + tag: { + type: String, + default: 'div', + }, +} diff --git a/packages/varlet-ui/src/highlighter-provider/provide.ts b/packages/varlet-ui/src/highlighter-provider/provide.ts new file mode 100644 index 00000000000..84119974d1d --- /dev/null +++ b/packages/varlet-ui/src/highlighter-provider/provide.ts @@ -0,0 +1,22 @@ +import { keyInProvides } from '@varlet/use' +import { inject, provide } from 'vue' +import type { Highlighter } from './props' + +export interface HighlighterProvider { + highlighter?: Highlighter + theme?: string +} + +export const HIGHLIGHTER_PROVIDER_KEY = Symbol('HIGHLIGHTER_PROVIDER_KEY') + +export function provideHighlighterProvider(highlighterProvider: HighlighterProvider) { + provide(HIGHLIGHTER_PROVIDER_KEY, highlighterProvider) +} + +export function injectHighlighterProvider() { + if (!keyInProvides(HIGHLIGHTER_PROVIDER_KEY)) { + return { highlighter: undefined } as HighlighterProvider + } + + return inject(HIGHLIGHTER_PROVIDER_KEY)! +} diff --git a/packages/varlet-ui/src/themes/__tests__/__snapshots__/index.spec.js.snap b/packages/varlet-ui/src/themes/__tests__/__snapshots__/index.spec.js.snap index c2beefe473b..3023e33211f 100644 --- a/packages/varlet-ui/src/themes/__tests__/__snapshots__/index.spec.js.snap +++ b/packages/varlet-ui/src/themes/__tests__/__snapshots__/index.spec.js.snap @@ -216,6 +216,8 @@ exports[`test dark theme 1`] = ` "--chip-warning-color": "var(--color-warning-container)", "--chip-warning-plain-color": "var(--color-warning)", "--chip-warning-text-color": "var(--color-on-warning-container)", + "--code-border-radius": "4px", + "--code-content-padding": "16px", "--collapse-background": "var(--color-surface-container-highest)", "--collapse-border-top": "thin solid var(--color-outline)", "--collapse-content-font-size": "var(--font-size-md)", @@ -1063,6 +1065,8 @@ exports[`test md3Dark theme 1`] = ` "--chip-warning-color": "var(--color-warning-container)", "--chip-warning-plain-color": "var(--color-warning)", "--chip-warning-text-color": "var(--color-on-warning-container)", + "--code-border-radius": "4px", + "--code-content-padding": "16px", "--collapse-background": "var(--color-surface-container-highest)", "--collapse-border-top": "thin solid var(--color-outline)", "--collapse-content-font-size": "var(--font-size-md)", @@ -1894,6 +1898,8 @@ exports[`test md3Light theme 1`] = ` "--chip-warning-color": "var(--color-warning-container)", "--chip-warning-plain-color": "var(--color-warning)", "--chip-warning-text-color": "var(--color-on-warning-container)", + "--code-border-radius": "4px", + "--code-content-padding": "16px", "--collapse-background": "var(--color-surface-container-low)", "--collapse-border-top": "thin solid var(--color-outline)", "--collapse-content-font-size": "var(--font-size-md)", diff --git a/packages/varlet-ui/src/themes/dark/code.ts b/packages/varlet-ui/src/themes/dark/code.ts new file mode 100644 index 00000000000..348fa405b6f --- /dev/null +++ b/packages/varlet-ui/src/themes/dark/code.ts @@ -0,0 +1,4 @@ +export default { + '--code-border-radius': '4px', + '--code-content-padding': '16px', +} diff --git a/packages/varlet-ui/src/themes/dark/index.ts b/packages/varlet-ui/src/themes/dark/index.ts index f662ca6ff65..7fc7b44e562 100644 --- a/packages/varlet-ui/src/themes/dark/index.ts +++ b/packages/varlet-ui/src/themes/dark/index.ts @@ -62,6 +62,7 @@ import space from './space' import swipe from './swipe' import tooltip from './tooltip' import select from './select' +import code from './code' export default { '--font-size-xs': '10px', @@ -204,4 +205,5 @@ export default { ...swipe, ...tooltip, ...select, + ...code, } as StyleVars diff --git a/packages/varlet-ui/src/themes/md3-dark/code.ts b/packages/varlet-ui/src/themes/md3-dark/code.ts new file mode 100644 index 00000000000..348fa405b6f --- /dev/null +++ b/packages/varlet-ui/src/themes/md3-dark/code.ts @@ -0,0 +1,4 @@ +export default { + '--code-border-radius': '4px', + '--code-content-padding': '16px', +} diff --git a/packages/varlet-ui/src/themes/md3-dark/index.ts b/packages/varlet-ui/src/themes/md3-dark/index.ts index 7e52e431876..0c7a8dac426 100644 --- a/packages/varlet-ui/src/themes/md3-dark/index.ts +++ b/packages/varlet-ui/src/themes/md3-dark/index.ts @@ -62,6 +62,7 @@ import overlay from './overlay' import ripple from './ripple' import space from './space' import swipe from './swipe' +import code from './code' export default { '--font-size-xs': '10px', @@ -204,4 +205,5 @@ export default { ...ripple, ...space, ...swipe, + ...code, } as StyleVars diff --git a/packages/varlet-ui/src/themes/md3-light/code.ts b/packages/varlet-ui/src/themes/md3-light/code.ts new file mode 100644 index 00000000000..348fa405b6f --- /dev/null +++ b/packages/varlet-ui/src/themes/md3-light/code.ts @@ -0,0 +1,4 @@ +export default { + '--code-border-radius': '4px', + '--code-content-padding': '16px', +} diff --git a/packages/varlet-ui/src/themes/md3-light/index.ts b/packages/varlet-ui/src/themes/md3-light/index.ts index 096b10decc0..6afee9045e5 100644 --- a/packages/varlet-ui/src/themes/md3-light/index.ts +++ b/packages/varlet-ui/src/themes/md3-light/index.ts @@ -62,6 +62,7 @@ import step from './step' import swipe from './swipe' import watermark from './watermark' import appBar from './appBar' +import code from './code' export default { '--font-size-xs': '10px', @@ -204,4 +205,5 @@ export default { ...swipe, ...watermark, ...appBar, + ...code, } as StyleVars diff --git a/packages/varlet-ui/types/code.d.ts b/packages/varlet-ui/types/code.d.ts new file mode 100644 index 00000000000..dc7f17a75d0 --- /dev/null +++ b/packages/varlet-ui/types/code.d.ts @@ -0,0 +1,17 @@ +import { VarComponent, BasicAttributes, SetPropsDefaults } from './varComponent' + +export declare const codeProps: Record + +export interface CodeProps extends BasicAttributes { + code?: string + language?: string + theme?: string +} + +export class Code extends VarComponent { + static setPropsDefaults: SetPropsDefaults + + $props: CodeProps +} + +export class _CodeComponent extends Code {} diff --git a/packages/varlet-ui/types/highlighterProvider.d.ts b/packages/varlet-ui/types/highlighterProvider.d.ts new file mode 100644 index 00000000000..49827eca87c --- /dev/null +++ b/packages/varlet-ui/types/highlighterProvider.d.ts @@ -0,0 +1,26 @@ +import { VarComponent, BasicAttributes, SetPropsDefaults } from './varComponent' + +export declare const highlighterProps: Record + +export interface CodeToHtmlOptions { + lang?: string + theme?: string +} + +export interface Highlighter { + codeToHtml: (code: string, options: CodeToHtmlOptions) => Promise +} + +export interface HighlighterProviderProps extends BasicAttributes { + highlighter?: Highlighter + theme?: string + tag?: string +} + +export class HighlighterProvider extends VarComponent { + static setPropsDefaults: SetPropsDefaults + + $props: HighlighterProviderProps +} + +export class _HighlighterProviderComponent extends HighlighterProvider {} diff --git a/packages/varlet-ui/types/index.d.ts b/packages/varlet-ui/types/index.d.ts index 945c0b1ec7f..c241817b5d1 100644 --- a/packages/varlet-ui/types/index.d.ts +++ b/packages/varlet-ui/types/index.d.ts @@ -21,6 +21,7 @@ export * from './cell' export * from './checkbox' export * from './checkboxGroup' export * from './chip' +export * from './code' export * from './col' export * from './collapse' export * from './collapseItem' @@ -37,6 +38,7 @@ export * from './fab' export * from './floatingPanel' export * from './form' export * from './formDetails' +export * from './highlighterProvider' export * from './hover' export * from './hoverOverlay' export * from './icon' @@ -115,6 +117,7 @@ declare module 'vue' { VarCheckbox: typeof import('@varlet/ui')['_CheckboxComponent'] VarCheckboxGroup: typeof import('@varlet/ui')['_CheckboxGroupComponent'] VarChip: typeof import('@varlet/ui')['_ChipComponent'] + VarCode: typeof import('@varlet/ui')['_CodeComponent'] VarCol: typeof import('@varlet/ui')['_ColComponent'] VarCollapse: typeof import('@varlet/ui')['_CollapseComponent'] VarCollapseItem: typeof import('@varlet/ui')['_CollapseItemComponent'] @@ -131,6 +134,7 @@ declare module 'vue' { VarFloatingPanel: typeof import('@varlet/ui')['_FloatingPanelComponent'] VarForm: typeof import('@varlet/ui')['_FormComponent'] VarFormDetails: typeof import('@varlet/ui')['_FormDetailsComponent'] + VarHighlighterProvider: typeof import('@varlet/ui')['_HighlighterProviderComponent'] VarHoverOverlay: typeof import('@varlet/ui')['_HoverOverlayComponent'] VarIcon: typeof import('@varlet/ui')['_IconComponent'] VarImage: typeof import('@varlet/ui')['_ImageComponent'] diff --git a/packages/varlet-ui/types/styleVars.d.ts b/packages/varlet-ui/types/styleVars.d.ts index c5ba414ef0a..c17dc989242 100644 --- a/packages/varlet-ui/types/styleVars.d.ts +++ b/packages/varlet-ui/types/styleVars.d.ts @@ -224,6 +224,8 @@ interface BaseStyleVars { '--chip-small-font-size'?: string '--chip-normal-font-size'?: string '--chip-large-font-size'?: string + '--code-border-radius'?: string + '--code-content-padding'?: string '--collapse-background'?: string '--collapse-text-color'?: string '--collapse-header-font-size'?: string diff --git a/packages/varlet-ui/varlet.config.mjs b/packages/varlet-ui/varlet.config.mjs index 69bb7c81645..ec0e376f60d 100644 --- a/packages/varlet-ui/varlet.config.mjs +++ b/packages/varlet-ui/varlet.config.mjs @@ -391,6 +391,14 @@ export default defineConfig({ doc: 'watermark', type: 2, }, + { + text: { + 'zh-CN': 'Code 代码块', + 'en-US': 'Code', + }, + doc: 'code', + type: 2, + }, { text: { 'zh-CN': '导航组件', diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 34afce4ad66..7b866cbb6be 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -346,6 +346,9 @@ importers: live-server: specifier: ^1.2.1 version: 1.2.2 + shiki: + specifier: ^1.21.0 + version: 1.21.0 typescript: specifier: ^5.1.5 version: 5.1.5 @@ -1588,6 +1591,21 @@ packages: cpu: [x64] os: [win32] + '@shikijs/core@1.21.0': + resolution: {integrity: sha512-zAPMJdiGuqXpZQ+pWNezQAk5xhzRXBNiECFPcJLtUdsFM3f//G95Z15EHTnHchYycU8kIIysqGgxp8OVSj1SPQ==} + + '@shikijs/engine-javascript@1.21.0': + resolution: {integrity: sha512-jxQHNtVP17edFW4/0vICqAVLDAxmyV31MQJL4U/Kg+heQALeKYVOWo0sMmEZ18FqBt+9UCdyqGKYE7bLRtk9mg==} + + '@shikijs/engine-oniguruma@1.21.0': + resolution: {integrity: sha512-AIZ76XocENCrtYzVU7S4GY/HL+tgHGbVU+qhiDyNw1qgCA5OSi4B4+HY4BtAoJSMGuD/L5hfTzoRVbzEm2WTvg==} + + '@shikijs/types@1.21.0': + resolution: {integrity: sha512-tzndANDhi5DUndBtpojEq/42+dpUF2wS7wdCDQaFtIXm3Rd1QkrcVgSSRLOvEwexekihOXfbYJINW37g96tJRw==} + + '@shikijs/vscode-textmate@9.2.2': + resolution: {integrity: sha512-TMp15K+GGYrWlZM8+Lnj9EaHEFmOen0WJBrfa17hF7taDOYthuPPV0GWzfd/9iMij0akS/8Yw2ikquH7uVi/fg==} + '@types/babel__core@7.20.1': resolution: {integrity: sha512-aACu/U/omhdk15O4Nfb+fHgH/z3QsfQzpnvRZhYhThms83ZnAOZz7zZAWO7mn2yyNQaA4xTO8GLK3uqFU4bYYw==} @@ -1618,6 +1636,9 @@ packages: '@types/hash-sum@1.0.0': resolution: {integrity: sha512-FdLBT93h3kcZ586Aee66HPCVJ6qvxVjBlDWNmxSGSbCZe9hTsjRKdSsl4y1T+3zfujxo9auykQMnFsfyHWD7wg==} + '@types/hast@3.0.4': + resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} + '@types/json-schema@7.0.11': resolution: {integrity: sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==} @@ -1630,6 +1651,9 @@ packages: '@types/markdown-it@12.2.3': resolution: {integrity: sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==} + '@types/mdast@4.0.4': + resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} + '@types/mdurl@1.0.2': resolution: {integrity: sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==} @@ -1666,6 +1690,9 @@ packages: '@types/sharp@0.31.1': resolution: {integrity: sha512-5nWwamN9ZFHXaYEincMSuza8nNfOof8nmO+mcI+Agx1uMUk4/pQnNIcix+9rLPXzKrm1pS34+6WRDbDV0Jn7ag==} + '@types/unist@3.0.3': + resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} + '@types/vscode@1.70.0': resolution: {integrity: sha512-3/9Fz0F2eBgwciazc94Ien+9u1elnjFg9YAhvAb3qDy/WeFWD9VrOPU7CIytryOVUdbxus8uzL4VZYONA0gDtA==} @@ -1730,6 +1757,9 @@ packages: resolution: {integrity: sha512-xEYIxKcultP6E/RMKqube11pGjXH1DCo60mQoWhVYyKfLkwbIVVjYxmOenNMxILx0TjCujPTjjnTIVzm09TXIw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + '@ungap/structured-clone@1.2.0': + resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} + '@unocss/astro@0.58.5': resolution: {integrity: sha512-LtuVnj8oFAK9663OVhQO8KpdJFiOyyPsYfnOZlDCOFK3gHb/2WMrzdBwr1w8LoQF3bDedkFMKirVF7gWjyZiaw==} peerDependencies: @@ -2260,6 +2290,9 @@ packages: caniuse-lite@1.0.30001642: resolution: {integrity: sha512-3XQ0DoRgLijXJErLSl+bLnJ+Et4KqV1PY6JJBGAFlsNsz31zeAIncyeZfLCabHK/jtSh+671RM9YMldxjUPZtA==} + ccount@2.0.1: + resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} + chai@5.1.1: resolution: {integrity: sha512-pT1ZgP8rPNqUgieVaEY+ryQr6Q4HXNg8Ei9UnLUrjN4IA7dvQC5JB+/kxVcPNDHyBcc/26CXPkbNzq3qwrOEKA==} engines: {node: '>=12'} @@ -2276,6 +2309,12 @@ packages: resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + character-entities-html4@2.1.0: + resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} + + character-entities-legacy@3.0.0: + resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} + chardet@0.7.0: resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} @@ -2363,6 +2402,9 @@ packages: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} engines: {node: '>= 0.8'} + comma-separated-tokens@2.0.3: + resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} + commander@10.0.1: resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==} engines: {node: '>=14'} @@ -2649,6 +2691,10 @@ packages: resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} engines: {node: '>= 0.8'} + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + destr@2.0.3: resolution: {integrity: sha512-2N3BOUU4gYMpTP24s5rF5iP7BDr7uNTCs4ozw3kf/eKfvWSIu93GEBi5m427YoyJoeOzQ5smuu4nNAPGb8idSQ==} @@ -2660,6 +2706,9 @@ packages: resolution: {integrity: sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==} engines: {node: '>=8'} + devlop@1.1.0: + resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + didyoumean@1.2.2: resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} @@ -3227,6 +3276,12 @@ packages: resolution: {integrity: sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==} engines: {node: '>= 0.4'} + hast-util-to-html@9.0.3: + resolution: {integrity: sha512-M17uBDzMJ9RPCqLMO92gNNUDuBSq10a25SDBI08iCCxmorf4Yy6sYHK57n9WAbRAAaU+DuR4W6GN9K4DFZesYg==} + + hast-util-whitespace@3.0.0: + resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} + highlight.js@10.7.3: resolution: {integrity: sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==} @@ -3252,6 +3307,9 @@ packages: resolution: {integrity: sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==} engines: {node: '>=8'} + html-void-elements@3.0.0: + resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} + htmlparser2@8.0.1: resolution: {integrity: sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA==} @@ -3761,6 +3819,9 @@ packages: resolution: {integrity: sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==} hasBin: true + mdast-util-to-hast@13.2.0: + resolution: {integrity: sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==} + mdn-data@2.0.30: resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==} @@ -3785,6 +3846,21 @@ packages: microbuffer@1.0.0: resolution: {integrity: sha512-O/SUXauVN4x6RaEJFqSPcXNtLFL+QzJHKZlyDVYFwcDDRVca3Fa/37QXXC+4zAGGa4YhHrHxKXuuHvLDIQECtA==} + micromark-util-character@2.1.0: + resolution: {integrity: sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==} + + micromark-util-encode@2.0.0: + resolution: {integrity: sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==} + + micromark-util-sanitize-uri@2.0.0: + resolution: {integrity: sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==} + + micromark-util-symbol@2.0.0: + resolution: {integrity: sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==} + + micromark-util-types@2.0.0: + resolution: {integrity: sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==} + micromatch@3.1.10: resolution: {integrity: sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==} engines: {node: '>=0.10.0'} @@ -4051,6 +4127,9 @@ packages: resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} engines: {node: '>=12'} + oniguruma-to-js@0.4.3: + resolution: {integrity: sha512-X0jWUcAlxORhOqqBREgPMgnshB7ZGYszBNspP+tS9hPD3l13CdaXcHbgImoHUHlrvGx/7AvFEkTRhAGYh+jzjQ==} + opn@6.0.0: resolution: {integrity: sha512-I9PKfIZC+e4RXZ/qr1RhgyCnGgYX0UEIlXgWnCOVACIvFgaC9rz6Won7xbdhoHrd8IIhV7YEpHjreNUNkqCGkQ==} engines: {node: '>=8'} @@ -4290,6 +4369,9 @@ packages: process-nextick-args@2.0.1: resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + property-information@6.5.0: + resolution: {integrity: sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==} + proto-list@1.2.4: resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==} @@ -4392,6 +4474,9 @@ packages: resolution: {integrity: sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==} engines: {node: '>=0.10.0'} + regex@4.3.3: + resolution: {integrity: sha512-r/AadFO7owAq1QJVeZ/nq9jNS1vyZt+6t1p/E59B56Rn2GCya+gr1KSyOzNL/er+r+B7phv5jG2xU2Nz1YkmJg==} + remove-trailing-separator@1.1.0: resolution: {integrity: sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==} @@ -4558,6 +4643,9 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} + shiki@1.21.0: + resolution: {integrity: sha512-apCH5BoWTrmHDPGgg3RF8+HAAbEL/CdbYr8rMw7eIrdhCkZHdVGat5mMNlRtd1erNG01VPMIKHNQ0Pj2HMAiog==} + siginfo@2.0.0: resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} @@ -4637,6 +4725,9 @@ packages: resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==} engines: {node: '>= 8'} + space-separated-tokens@2.0.2: + resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + spdx-correct@3.1.1: resolution: {integrity: sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==} @@ -4701,6 +4792,9 @@ packages: string_decoder@1.3.0: resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + stringify-entities@4.0.4: + resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} + strip-ansi@6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} @@ -4877,6 +4971,9 @@ packages: resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} hasBin: true + trim-lines@3.0.1: + resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} + trim-newlines@3.0.1: resolution: {integrity: sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==} engines: {node: '>=8'} @@ -5005,6 +5102,21 @@ packages: resolution: {integrity: sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==} engines: {node: '>=0.10.0'} + unist-util-is@6.0.0: + resolution: {integrity: sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==} + + unist-util-position@5.0.0: + resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} + + unist-util-stringify-position@4.0.0: + resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} + + unist-util-visit-parents@6.0.1: + resolution: {integrity: sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==} + + unist-util-visit@5.0.0: + resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==} + universalify@0.2.0: resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==} engines: {node: '>= 4.0.0'} @@ -5087,6 +5199,12 @@ packages: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} + vfile-message@4.0.2: + resolution: {integrity: sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==} + + vfile@6.0.3: + resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} + vite-node@2.0.5: resolution: {integrity: sha512-LdsW4pxj0Ot69FAoXZ1yTnA9bjGohr2yNBU7QKRxpz8ITSkhuDl6h3zS/tvgz4qrNjeRnvrWeXQ8ZF7Um4W00Q==} engines: {node: ^18.0.0 || >=20.0.0} @@ -5372,6 +5490,9 @@ packages: zod@3.23.8: resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==} + zwitch@2.0.4: + resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} + snapshots: '@alloc/quick-lru@5.2.0': {} @@ -6279,6 +6400,33 @@ snapshots: '@rollup/rollup-win32-x64-msvc@4.22.0': optional: true + '@shikijs/core@1.21.0': + dependencies: + '@shikijs/engine-javascript': 1.21.0 + '@shikijs/engine-oniguruma': 1.21.0 + '@shikijs/types': 1.21.0 + '@shikijs/vscode-textmate': 9.2.2 + '@types/hast': 3.0.4 + hast-util-to-html: 9.0.3 + + '@shikijs/engine-javascript@1.21.0': + dependencies: + '@shikijs/types': 1.21.0 + '@shikijs/vscode-textmate': 9.2.2 + oniguruma-to-js: 0.4.3 + + '@shikijs/engine-oniguruma@1.21.0': + dependencies: + '@shikijs/types': 1.21.0 + '@shikijs/vscode-textmate': 9.2.2 + + '@shikijs/types@1.21.0': + dependencies: + '@shikijs/vscode-textmate': 9.2.2 + '@types/hast': 3.0.4 + + '@shikijs/vscode-textmate@9.2.2': {} + '@types/babel__core@7.20.1': dependencies: '@babel/parser': 7.21.8 @@ -6317,6 +6465,10 @@ snapshots: '@types/hash-sum@1.0.0': {} + '@types/hast@3.0.4': + dependencies: + '@types/unist': 3.0.3 + '@types/json-schema@7.0.11': {} '@types/json5@0.0.29': {} @@ -6328,6 +6480,10 @@ snapshots: '@types/linkify-it': 3.0.2 '@types/mdurl': 1.0.2 + '@types/mdast@4.0.4': + dependencies: + '@types/unist': 3.0.3 + '@types/mdurl@1.0.2': {} '@types/minimatch@3.0.5': {} @@ -6358,6 +6514,8 @@ snapshots: dependencies: '@types/node': 18.7.20 + '@types/unist@3.0.3': {} + '@types/vscode@1.70.0': {} '@types/wrap-ansi@3.0.0': {} @@ -6446,6 +6604,8 @@ snapshots: '@typescript-eslint/types': 5.60.1 eslint-visitor-keys: 3.4.1 + '@ungap/structured-clone@1.2.0': {} + '@unocss/astro@0.58.5(rollup@4.22.0)(vite@5.4.6(@types/node@18.7.20)(less@3.13.1)(sass@1.77.4))': dependencies: '@unocss/core': 0.58.5 @@ -7181,6 +7341,8 @@ snapshots: caniuse-lite@1.0.30001642: {} + ccount@2.0.1: {} + chai@5.1.1: dependencies: assertion-error: 2.0.1 @@ -7202,6 +7364,10 @@ snapshots: chalk@5.3.0: {} + character-entities-html4@2.1.0: {} + + character-entities-legacy@3.0.0: {} + chardet@0.7.0: {} check-error@2.1.1: {} @@ -7327,6 +7493,8 @@ snapshots: dependencies: delayed-stream: 1.0.0 + comma-separated-tokens@2.0.3: {} + commander@10.0.1: {} commander@11.1.0: {} @@ -7577,12 +7745,18 @@ snapshots: depd@2.0.0: {} + dequal@2.0.3: {} + destr@2.0.3: {} destroy@1.2.0: {} detect-libc@2.0.2: {} + devlop@1.1.0: + dependencies: + dequal: 2.0.3 + didyoumean@1.2.2: {} dir-glob@3.0.1: @@ -8335,6 +8509,24 @@ snapshots: dependencies: function-bind: 1.1.2 + hast-util-to-html@9.0.3: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + ccount: 2.0.1 + comma-separated-tokens: 2.0.3 + hast-util-whitespace: 3.0.0 + html-void-elements: 3.0.0 + mdast-util-to-hast: 13.2.0 + property-information: 6.5.0 + space-separated-tokens: 2.0.2 + stringify-entities: 4.0.4 + zwitch: 2.0.4 + + hast-util-whitespace@3.0.0: + dependencies: + '@types/hast': 3.0.4 + highlight.js@10.7.3: {} hosted-git-info@2.8.9: {} @@ -8355,6 +8547,8 @@ snapshots: html-tags@3.3.1: {} + html-void-elements@3.0.0: {} + htmlparser2@8.0.1: dependencies: domelementtype: 2.3.0 @@ -8889,6 +9083,18 @@ snapshots: mdurl: 1.0.1 uc.micro: 1.0.6 + mdast-util-to-hast@13.2.0: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@ungap/structured-clone': 1.2.0 + devlop: 1.1.0 + micromark-util-sanitize-uri: 2.0.0 + trim-lines: 3.0.1 + unist-util-position: 5.0.0 + unist-util-visit: 5.0.0 + vfile: 6.0.3 + mdn-data@2.0.30: {} mdurl@1.0.1: {} @@ -8916,6 +9122,23 @@ snapshots: microbuffer@1.0.0: {} + micromark-util-character@2.1.0: + dependencies: + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + + micromark-util-encode@2.0.0: {} + + micromark-util-sanitize-uri@2.0.0: + dependencies: + micromark-util-character: 2.1.0 + micromark-util-encode: 2.0.0 + micromark-util-symbol: 2.0.0 + + micromark-util-symbol@2.0.0: {} + + micromark-util-types@2.0.0: {} + micromatch@3.1.10: dependencies: arr-diff: 4.0.0 @@ -9201,6 +9424,10 @@ snapshots: dependencies: mimic-fn: 4.0.0 + oniguruma-to-js@0.4.3: + dependencies: + regex: 4.3.3 + opn@6.0.0: dependencies: is-wsl: 1.1.0 @@ -9438,6 +9665,8 @@ snapshots: process-nextick-args@2.0.1: {} + property-information@6.5.0: {} + proto-list@1.2.4: {} proxy-from-env@1.1.0: {} @@ -9558,6 +9787,8 @@ snapshots: extend-shallow: 3.0.2 safe-regex: 1.1.0 + regex@4.3.3: {} + remove-trailing-separator@1.1.0: {} repeat-element@1.1.4: {} @@ -9744,6 +9975,15 @@ snapshots: shebang-regex@3.0.0: {} + shiki@1.21.0: + dependencies: + '@shikijs/core': 1.21.0 + '@shikijs/engine-javascript': 1.21.0 + '@shikijs/engine-oniguruma': 1.21.0 + '@shikijs/types': 1.21.0 + '@shikijs/vscode-textmate': 9.2.2 + '@types/hast': 3.0.4 + siginfo@2.0.0: {} signal-exit@3.0.7: {} @@ -9821,6 +10061,8 @@ snapshots: dependencies: whatwg-url: 7.1.0 + space-separated-tokens@2.0.2: {} + spdx-correct@3.1.1: dependencies: spdx-expression-parse: 3.0.1 @@ -9886,6 +10128,11 @@ snapshots: dependencies: safe-buffer: 5.2.1 + stringify-entities@4.0.4: + dependencies: + character-entities-html4: 2.1.0 + character-entities-legacy: 3.0.0 + strip-ansi@6.0.1: dependencies: ansi-regex: 5.0.1 @@ -10080,6 +10327,8 @@ snapshots: tree-kill@1.2.2: {} + trim-lines@3.0.1: {} + trim-newlines@3.0.1: {} ts-interface-checker@0.1.13: {} @@ -10247,6 +10496,29 @@ snapshots: is-extendable: 0.1.1 set-value: 2.0.1 + unist-util-is@6.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-position@5.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-stringify-position@4.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-visit-parents@6.0.1: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.0 + + unist-util-visit@5.0.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.0 + unist-util-visit-parents: 6.0.1 + universalify@0.2.0: {} universalify@2.0.0: {} @@ -10329,6 +10601,16 @@ snapshots: vary@1.1.2: {} + vfile-message@4.0.2: + dependencies: + '@types/unist': 3.0.3 + unist-util-stringify-position: 4.0.0 + + vfile@6.0.3: + dependencies: + '@types/unist': 3.0.3 + vfile-message: 4.0.2 + vite-node@2.0.5(@types/node@18.7.18)(less@3.13.1)(sass@1.77.4): dependencies: cac: 6.7.14 @@ -10628,3 +10910,5 @@ snapshots: yoctocolors-cjs@2.1.2: {} zod@3.23.8: {} + + zwitch@2.0.4: {}