vitepress-plugin-sfc 2.0.0-beta.3 → 2.0.0-beta.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -7,7 +7,7 @@ Allows you to write Vue SFC within Markdown files and render them in VitePress.
7
7
  ## Install
8
8
 
9
9
  ```shell
10
- npm install -D vitepress-plugin-sfc@latest
10
+ npm install -D vitepress-plugin-sfc@2.0.0-beta.5
11
11
  ```
12
12
 
13
13
  ## Configuration
@@ -37,11 +37,12 @@ export default defineConfig({
37
37
  ```ts
38
38
  import DefaultTheme from "vitepress/theme";
39
39
  import { enhanceAppWithComponentView } from "vitepress-plugin-sfc/client";
40
+ import "vitepress-plugin-sfc/style";
40
41
 
41
42
  export default {
42
43
  extends: DefaultTheme,
43
- enhanceApp({ app }) {
44
- enhanceAppWithComponentView(app);
44
+ async enhanceApp({ app }) {
45
+ await enhanceAppWithComponentView(app);
45
46
  },
46
47
  };
47
48
  ```
@@ -0,0 +1 @@
1
+ import{t as e}from"./export-helper-9pbmIWWh.mjs";import{useData as t}from"vitepress";import{Fragment as n,computed as r,createElementBlock as i,createElementVNode as a,defineComponent as o,normalizeClass as s,openBlock as c,ref as l,renderList as u,renderSlot as d,toDisplayString as f,useId as p,vShow as m,withDirectives as h}from"vue";var g=o({__name:`GroupTabs`,props:{locale:{type:Object,required:!1}},setup(e,{expose:n}){n();let i={en:{label:{preview:`Preview`,code:`Source Code`}},zh:{label:{preview:`预览`,code:`源代码`}}},a=e,{lang:o}=t(),s={DEFAULT_LOCALE:i,props:a,lang:o,currentLocale:r(()=>a.locale?.[o.value]||i[o.value]),activedTab:l(`preview`),tabGroupId:p()};return Object.defineProperty(s,`__isScriptSetup`,{enumerable:!1,value:!0}),s}});const _={class:`vp-component-tabs`},v=[`id`,`name`,`data-checked`],y=[`for`,`onClick`];function b(e,t,r,o,l,p){return c(),i(`div`,_,[a(`header`,null,[(c(!0),i(n,null,u(o.currentLocale.label,(e,t)=>(c(),i(n,{key:t},[a(`input`,{id:`tab-${o.tabGroupId}-${t}`,type:`radio`,name:`vp-component-tabs-${o.tabGroupId}`,style:{position:`fixed`,opacity:`0`,"pointer-events":`none`},"data-checked":o.activedTab===t},null,8,v),a(`label`,{for:`tab-${o.tabGroupId}-${t}`,onClick:e=>o.activedTab=t},f(e),9,y)],64))),128))]),h(a(`main`,null,[d(e.$slots,`default`)],512),[[m,o.activedTab===`preview`]]),h(a(`div`,{class:s(`language-vue${o.activedTab===`code`?` active`:``}`),style:{margin:`0px`}},[t[0]||=a(`button`,{title:`copy source code`,class:`copy`},null,-1),t[1]||=a(`span`,{class:`lang`},`Vue`,-1),d(e.$slots,`highlight`)],2),[[m,o.activedTab===`code`]])])}var x=e(g,[[`render`,b],[`__file`,`/home/runner/work/vitepress-plugin-sfc/vitepress-plugin-sfc/src/client/GroupTabs.vue`]]);export{x as default};
@@ -0,0 +1,2 @@
1
+ import { a as enhanceAppWithComponentView, i as configSymbol, n as Config, r as GroupTabsProps, t as ComponentViewProps } from "./index-DHKDP_Um.mjs";
2
+ export { ComponentViewProps, Config, GroupTabsProps, configSymbol, enhanceAppWithComponentView };
@@ -0,0 +1 @@
1
+ import{t as e}from"./export-helper-9pbmIWWh.mjs";import{computed as t,createBlock as n,createElementBlock as r,defineComponent as i,getCurrentInstance as a,inject as o,openBlock as s,renderSlot as c,resolveDynamicComponent as l,withCtx as u}from"vue";var d=i({__name:`ComponentView`,props:{render:{type:[String,Object],required:!1},disableRender:{type:Boolean,required:!1,default:!1}},setup(e,{expose:n}){n();let r=e,i=o(m),s=a(),c={props:r,injectedConfig:i,instance:s,config:t(()=>{let{render:e,disableRender:t}=i,n={render:e||r.render,disableRender:t??r.disableRender},a=s.appContext.app.component(n.render);return a||console.warn(`[vitepress-plugin-sfc] Unregistered component: ${n.render}`),{...n,render:a}})};return Object.defineProperty(c,`__isScriptSetup`,{enumerable:!1,value:!0}),c}});function f(e,t,i,a,o,d){return s(),r(`div`,null,[!a.config.render||a.config.disableRender?c(e.$slots,`default`,{key:0}):(s(),n(l(a.config.render),{key:1},{highlight:u(()=>[c(e.$slots,`highlight`)]),default:u(()=>[c(e.$slots,`default`)]),_:3}))])}var p=e(d,[[`render`,f],[`__file`,`/home/runner/work/vitepress-plugin-sfc/vitepress-plugin-sfc/src/client/ComponentView.vue`]]);const m=Symbol(`__vitepress_plugin_sfc_config`),h={render:`GroupTabs`};async function g(e,t){e.component(`ComponentView`,p);let n={...h,...t};if(e)e.provide(m,n);else throw Error("[vitepress-plugin-sfc] The `useConfig` must be called within a Vue component if not providing an app");let{render:r,disableRender:i}=n;if(!i&&r===`GroupTabs`){let t=await import(`./GroupTabs-voGdJiur.mjs`);e.component(`GroupTabs`,t.default)}}export{m as configSymbol,g as enhanceAppWithComponentView};
@@ -0,0 +1 @@
1
+ var e=(e,t)=>{let n=e.__vccOpts||e;for(let[e,r]of t)n[e]=r;return n};export{e as t};
@@ -0,0 +1,22 @@
1
+ import { EnhanceAppContext } from "vitepress";
2
+
3
+ //#region src/client/index.d.ts
4
+ interface ComponentViewProps {
5
+ render?: "GroupTabs" | "SourceCodeButton" | (string & {});
6
+ disableRender?: boolean;
7
+ }
8
+ interface GroupTabsProps {
9
+ locale?: Record<string, {
10
+ label: {
11
+ preview: string;
12
+ code: string;
13
+ };
14
+ }>;
15
+ }
16
+ type Config = ComponentViewProps & {
17
+ groupTabs?: GroupTabsProps;
18
+ };
19
+ declare const configSymbol: unique symbol;
20
+ declare function enhanceAppWithComponentView(app: EnhanceAppContext["app"], config?: Config): Promise<void>;
21
+ //#endregion
22
+ export { enhanceAppWithComponentView as a, configSymbol as i, Config as n, GroupTabsProps as r, ComponentViewProps as t };
package/dist/index.d.mts CHANGED
@@ -1,11 +1,6 @@
1
+ import { t as ComponentViewProps } from "./index-DHKDP_Um.mjs";
1
2
  import { MarkdownEnv, MarkdownRenderer, Plugin, SfcBlock } from "vitepress";
2
3
 
3
- //#region src/client/index.d.ts
4
- interface ComponentViewProps {
5
- render?: "GroupTabs" | "SourceCodeButton" | (string & {});
6
- disableRender?: boolean;
7
- }
8
- //#endregion
9
4
  //#region src/node/markdown.d.ts
10
5
  declare const SCRIPT_RE: RegExp;
11
6
  declare const SFC_IMPORTER_RE: RegExp;
@@ -27,6 +22,9 @@ declare function plugin(md: MarkdownRenderer): void;
27
22
  declare const sfcPlugin: typeof plugin;
28
23
  //#endregion
29
24
  //#region src/node/vite.d.ts
30
- declare function sfcRegistryVitePlugin(): Promise<Plugin>;
25
+ declare function sfcVitePlugin(): Promise<Plugin>;
26
+ //#endregion
27
+ //#region src/node/index.d.ts
28
+ declare const version: string;
31
29
  //#endregion
32
- export { MarkdownEnvExt, SCRIPT_RE, SFC, SFC_IMPORTER_RE, createDefaultSfcBlock, createVirtualImport, sfcPlugin, sfcRegistryVitePlugin };
30
+ export { MarkdownEnvExt, SCRIPT_RE, SFC, SFC_IMPORTER_RE, createDefaultSfcBlock, createVirtualImport, sfcPlugin, sfcVitePlugin, version };
package/dist/index.mjs CHANGED
@@ -6,4 +6,4 @@ import ${n} from '${r}'
6
6
  // REGION END
7
7
  `}}function s(t){return e.createHash(`sha256`).update(t).digest(`hex`)}function c(e){if(!e)return{};let t=e.split(`,`);return Object.fromEntries(t.map(e=>{let[,t,n]=e.match(/([^=]+)=?(.*)/)||[];return t===`disableRender`?[`disableRender`,!n||n===`true`?`true`:`false`]:t&&n?[t,n]:void 0}).filter(Boolean))}function l(e){e.use(n,`sfc`,{validate:e=>RegExp(`^sfc`).test(e.trim()),render:(e,t,n,r)=>{let{__matched_sfc_set__:i,sfcBlocks:o}=r;o.scripts.length||o.scripts.push(a());let[s]=o.scripts??[],c=e[t];if(c.nesting===1){let{hash:e,name:t,content:r,renderedContent:a,markupParams:o}=c.meta.sfc;if(!i.has(e)){let{tagOpen:t,tagClose:n,contentStripped:r}=s,o=r+a;s.contentStripped=o,s.content=t+o+n,i.add(e)}let{render:l=``,disableRender:u}=o;return`<ComponentView render="${l}" :disableRender="${u}">\n<${t} />\n<template #highlight>${n.highlight(r,`vue`,``)}</template>\n</ComponentView>\n`}else return``}}),e.core.ruler.after(`block`,`extract_sfc`,e=>{let t=e.src.split(`
8
8
  `),n=e.env.sfcs||[],r;function i(e){let{type:n,nesting:r,map:i,info:a}=e;if(n!==`container_sfc_open`||r!==1||!i)return;let[s,l]=i,u=t.slice(s+1,l).join(`
9
- `),d=o(u),[,f]=(a??``).split(` `);return{...d,content:u,markupParams:c(f)}}for(let t of e.tokens){let{map:e}=t,a=i(t);if(a){r=t,t.meta={...t.meta,sfc:a};let e=n.some(({name:e})=>a?.name===e);a&&!e&&n.push(a)}if(r&&r!==t){let[n]=e||[-1],[i,a]=r.map;n>i&&n<a?t.content=``:r=void 0}}let a=e.env;a.sfcs=[...n],a.__matched_sfc_set__=new Set})}const u=l;async function d(){let e=await t(``,{html:!0});e.use(u);let n=new Map;return{name:`vite-plugin-sfc-registry`,enforce:`pre`,resolveId:{filter:{id:new RegExp(i,`gi`)},handler(e){if(n.has(e))return e}},load:{filter:{id:new RegExp(i,`gi`)},handler(e){if(n.has(e))return n.get(e)}},transform(t,r){if(/.md$/gi.test(r)){let r={};e.render(t,r);let i=r.sfcs||[];for(let{importer:e,content:t}of i)n.set(e,t)}}}}export{r as SCRIPT_RE,i as SFC_IMPORTER_RE,a as createDefaultSfcBlock,o as createVirtualImport,u as sfcPlugin,d as sfcRegistryVitePlugin};
9
+ `),d=o(u),[,f]=(a??``).split(` `);return{...d,content:u,markupParams:c(f)}}for(let t of e.tokens){let{map:e}=t,a=i(t);if(a){r=t,t.meta={...t.meta,sfc:a};let e=n.some(({name:e})=>a?.name===e);a&&!e&&n.push(a)}if(r&&r!==t){let[n]=e||[-1],[i,a]=r.map;n>i&&n<a?t.content=``:r=void 0}}let a=e.env;a.sfcs=[...n],a.__matched_sfc_set__=new Set})}const u=l;async function d(){let e=await t(``,{html:!0});e.use(u);let n=new Map;return{name:`vite-plugin-sfc-registry`,enforce:`pre`,resolveId:{filter:{id:new RegExp(i,`gi`)},handler(e){if(n.has(e))return e}},load:{filter:{id:new RegExp(i,`gi`)},handler(e){if(n.has(e))return n.get(e)}},transform(t,r){if(/.md$/gi.test(r)){let r={};e.render(t,r);let i=r.sfcs||[];for(let{importer:e,content:t}of i)n.set(e,t)}}}}const f=`2.0.0-beta.5`;export{r as SCRIPT_RE,i as SFC_IMPORTER_RE,a as createDefaultSfcBlock,o as createVirtualImport,u as sfcPlugin,d as sfcVitePlugin,f as version};
package/dist/style.css ADDED
@@ -0,0 +1,58 @@
1
+
2
+ .vp-component-tabs {
3
+ margin: 16px 0;
4
+ display: grid;
5
+ grid-template-columns: 1fr;
6
+ grid-template-rows: min-content 1fr;
7
+ row-gap: 16px;
8
+ }
9
+ .vp-component-tabs > header {
10
+ display: flex;
11
+ position: relative;
12
+ border-radius: 8px;
13
+ overflow-x: auto;
14
+ overflow-y: hidden;
15
+ }
16
+ .vp-component-tabs > header input + label {
17
+ box-sizing: border-box;
18
+ display: inline-block;
19
+ position: relative;
20
+ padding: 8px 12px;
21
+ font-size: 14px;
22
+ font-weight: 500;
23
+ color: var(--vp-code-tab-text-color);
24
+ white-space: nowrap;
25
+ cursor: pointer;
26
+ transition:
27
+ color 0.25s,
28
+ background-color 0.25s;
29
+ }
30
+ .vp-component-tabs > header input + label::after {
31
+ content: "";
32
+ position: absolute;
33
+ height: 4px;
34
+ border-radius: 2px;
35
+ left: 8px;
36
+ right: 8px;
37
+ bottom: -1px;
38
+ transition: background-color 0.25s;
39
+ }
40
+ .vp-component-tabs > header input[data-checked="true"] + label::after {
41
+ background-color: var(--vp-code-tab-active-bar-color);
42
+ }
43
+ .vp-component-tabs > header input[data-checked="true"] + label,
44
+ .vp-component-tabs > header label:hover {
45
+ color: var(--vp-code-tab-active-text-color);
46
+ }
47
+ .vp-component-tabs > main {
48
+ padding: 20px;
49
+ background-color: var(--vp-nav-bg-color);
50
+ border-radius: 8px;
51
+ outline: 1px solid var(--vp-c-divider);
52
+ }
53
+ .vp-component-tabs > section {
54
+ background-color: var(--vp-code-block-bg);
55
+ border-radius: 8px;
56
+ padding: 24px;
57
+ overflow: auto;
58
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vitepress-plugin-sfc",
3
- "version": "2.0.0-beta.3",
3
+ "version": "2.0.0-beta.5",
4
4
  "description": "Allows you to write Vue SFC within Markdown files and render them in VitePress.",
5
5
  "keywords": [
6
6
  "component",
@@ -21,18 +21,21 @@
21
21
  "url": "https://github.com/heroui-vue/vitepress-plugin-sfc"
22
22
  },
23
23
  "files": [
24
- "dist",
25
- "src/client"
24
+ "dist"
26
25
  ],
27
26
  "type": "module",
28
- "main": "dist/index.mjs",
29
- "module": "dist/index.mjs",
27
+ "main": "./dist/index.mjs",
28
+ "module": "./dist/index.mjs",
30
29
  "exports": {
31
30
  ".": {
32
31
  "types": "./dist/index.d.mts",
33
32
  "default": "./dist/index.mjs"
34
33
  },
35
- "./client": "./src/client/index.ts"
34
+ "./client": {
35
+ "types": "./dist/client.d.mts",
36
+ "default": "./dist/client.mjs"
37
+ },
38
+ "./style": "./dist/style.css"
36
39
  },
37
40
  "publishConfig": {
38
41
  "access": "public",
@@ -57,9 +60,10 @@
57
60
  "scripts": {
58
61
  "dev": "tsdown -w",
59
62
  "build": "tsdown --minify",
63
+ "build:check": "tsdown",
60
64
  "bump": "bumpp --sign",
61
65
  "pub": "npm run build && npm publish --registry=https://registry.npmjs.org/",
62
- "dev:docs": "pnpm -C playground dev",
66
+ "dev:docs": "pnpm build:check && pnpm -C playground dev",
63
67
  "fmt": "oxfmt",
64
68
  "fmt:check": "oxfmt --check",
65
69
  "lint": "oxlint",
@@ -1,46 +0,0 @@
1
- <script setup lang="ts">
2
- import { inject, computed, getCurrentInstance, withDefaults, type Component } from "vue";
3
- import { configSymbol, type Config, type ComponentViewProps } from "./index";
4
-
5
- interface Props extends Omit<ComponentViewProps, "render"> {
6
- render: Component | undefined;
7
- }
8
-
9
- const props = withDefaults(defineProps<ComponentViewProps>(), {
10
- disableRender: false,
11
- });
12
-
13
- const config = computed<Props>(() => {
14
- const { render, disableRender } = inject<Config>(configSymbol);
15
- const resolveConfig = {
16
- render: render || props.render,
17
- disableRender:
18
- disableRender === null || disableRender === undefined ? props.disableRender : disableRender,
19
- };
20
-
21
- const renderInstance = getCurrentInstance().appContext.app.component(
22
- resolveConfig.render as string,
23
- );
24
- if (!renderInstance) {
25
- console.warn(`[vitepress-plugin-sfc] Unregistered component: ${resolveConfig.render}`);
26
- }
27
- return {
28
- ...resolveConfig,
29
- render: renderInstance,
30
- };
31
- });
32
- </script>
33
-
34
- <template>
35
- <div>
36
- <slot v-if="!config.render || config.disableRender"></slot>
37
- <component v-else :is="config.render">
38
- <slot />
39
- <template #highlight>
40
- <slot name="highlight"></slot>
41
- </template>
42
- </component>
43
- </div>
44
- </template>
45
-
46
- <style></style>
@@ -1,126 +0,0 @@
1
- <script setup lang="ts">
2
- import { computed, ref, useId, onMounted } from "vue";
3
- import { useData } from "vitepress";
4
- import { type GroupTabsProps } from "./index";
5
-
6
- const DEFAULT_LOCALE: GroupTabsProps["locale"] = {
7
- en: {
8
- label: {
9
- preview: "Preview",
10
- code: "Source Code",
11
- },
12
- },
13
- zh: {
14
- label: {
15
- preview: "预览",
16
- code: "源代码",
17
- },
18
- },
19
- };
20
-
21
- const props = defineProps<GroupTabsProps>();
22
-
23
- const { lang } = useData();
24
-
25
- const currentLocale = computed(() => {
26
- const locale = props.locale;
27
- return locale?.[lang.value] || DEFAULT_LOCALE[lang.value];
28
- });
29
-
30
- const activedTab = ref<"preview" | "code">("preview");
31
- const tabGroupId = useId();
32
- </script>
33
-
34
- <template>
35
- <div class="vp-component-tabs">
36
- <header>
37
- <template v-for="(value, key) in currentLocale.label" :key="key">
38
- <input
39
- :id="`tab-${tabGroupId}-${key}`"
40
- type="radio"
41
- :name="`vp-component-tabs-${tabGroupId}`"
42
- style="position: fixed; opacity: 0; pointer-events: none"
43
- :data-checked="activedTab === key" />
44
- <label :for="`tab-${tabGroupId}-${key}`" @click="activedTab = key">{{ value }}</label>
45
- </template>
46
- </header>
47
-
48
- <main v-show="activedTab === 'preview'">
49
- <slot />
50
- </main>
51
-
52
- <div
53
- v-show="activedTab === 'code'"
54
- :class="`language-vue${activedTab === 'code' ? ' active' : ''}`"
55
- style="margin: 0px">
56
- <button title="copy source code" class="copy"></button>
57
- <span class="lang">Vue</span>
58
- <slot name="highlight" />
59
- </div>
60
- </div>
61
- </template>
62
-
63
- <style>
64
- .vp-component-tabs {
65
- margin: 16px 0;
66
- display: grid;
67
- grid-template-columns: 1fr;
68
- grid-template-rows: min-content 1fr;
69
- row-gap: 16px;
70
- }
71
-
72
- .vp-component-tabs > header {
73
- display: flex;
74
- position: relative;
75
- border-radius: 8px;
76
- overflow-x: auto;
77
- overflow-y: hidden;
78
- }
79
-
80
- .vp-component-tabs > header input + label {
81
- box-sizing: border-box;
82
- display: inline-block;
83
- position: relative;
84
- padding: 8px 12px;
85
- font-size: 14px;
86
- font-weight: 500;
87
- color: var(--vp-code-tab-text-color);
88
- white-space: nowrap;
89
- cursor: pointer;
90
- transition:
91
- color 0.25s,
92
- background-color 0.25s;
93
- }
94
-
95
- .vp-component-tabs > header input + label::after {
96
- content: "";
97
- position: absolute;
98
- height: 4px;
99
- border-radius: 2px;
100
- left: 8px;
101
- right: 8px;
102
- bottom: -1px;
103
- transition: background-color 0.25s;
104
- }
105
- .vp-component-tabs > header input[data-checked="true"] + label::after {
106
- background-color: var(--vp-code-tab-active-bar-color);
107
- }
108
- .vp-component-tabs > header input[data-checked="true"] + label,
109
- .vp-component-tabs > header label:hover {
110
- color: var(--vp-code-tab-active-text-color);
111
- }
112
-
113
- .vp-component-tabs > main {
114
- padding: 20px;
115
- background-color: var(--vp-nav-bg-color);
116
- border-radius: 8px;
117
- outline: 1px solid var(--vp-c-divider);
118
- }
119
-
120
- .vp-component-tabs > section {
121
- background-color: var(--vp-code-block-bg);
122
- border-radius: 8px;
123
- padding: 24px;
124
- overflow: auto;
125
- }
126
- </style>
@@ -1,49 +0,0 @@
1
- import ComponentView from "./ComponentView.vue";
2
- import type { EnhanceAppContext } from "vitepress";
3
-
4
- export interface ComponentViewProps {
5
- render?: "GroupTabs" | "SourceCodeButton" | (string & {});
6
- disableRender?: boolean;
7
- }
8
-
9
- export interface GroupTabsProps {
10
- locale?: Record<string, { label: { preview: string; code: string } }>;
11
- }
12
-
13
- // export interface SourceCodeButtonProps {
14
- // icon: string;
15
- // }
16
-
17
- export type Config = ComponentViewProps & {
18
- groupTabs?: GroupTabsProps;
19
- };
20
-
21
- export const configSymbol = Symbol("__vitepress_plugin_sfc_config");
22
-
23
- const DEFUALT_CONFIG: Config = {
24
- render: "GroupTabs",
25
- };
26
-
27
- export async function enhanceAppWithComponentView(app: EnhanceAppContext["app"], config?: Config) {
28
- app.component("ComponentView", ComponentView);
29
-
30
- const resolvedConfig = { ...DEFUALT_CONFIG, ...config };
31
-
32
- if (app) {
33
- app.provide(configSymbol, resolvedConfig);
34
- } else {
35
- throw new Error(
36
- "[vitepress-plugin-sfc] The `useConfig` must be called within a Vue component if not providing an app",
37
- );
38
- }
39
-
40
- const { render, disableRender } = resolvedConfig;
41
- if (disableRender) {
42
- return;
43
- }
44
-
45
- if (render === "GroupTabs") {
46
- const importer = await import("./GroupTabs.vue");
47
- app.component("GroupTabs", importer.default);
48
- }
49
- }