vitepress-plugin-sfc 2.0.0-beta.2 → 2.0.0-beta.4
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 +20 -4
- package/dist/GroupTabs-voGdJiur.mjs +1 -0
- package/dist/client.d.mts +2 -0
- package/dist/client.mjs +1 -0
- package/dist/export-helper-9pbmIWWh.mjs +1 -0
- package/dist/index-DHKDP_Um.d.mts +22 -0
- package/dist/index.d.mts +10 -1067
- package/dist/index.mjs +5 -5
- package/dist/style.css +58 -0
- package/package.json +16 -9
- package/src/client/ComponentView.vue +0 -165
- package/src/client/index.ts +0 -23
- package/src/client/useLocaleMappings.ts +0 -31
package/dist/index.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import e from"node:crypto";import{createMarkdownRenderer as t}from"vitepress";function n(e,t,n){function r(e){return e.trim().split(` `,2)[0]===t}function i(e,n,r,i,a){return e[n].nesting===1&&e[n].attrJoin(`class`,t),a.renderToken(e,n,r,i,a)}n||={};let a=n.marker||`:`,o=a.charCodeAt(0),s=a.length,c=n.validate||r,l=n.render||i;function u(e,n,r,i){let l,u=!1,d=e.bMarks[n]+e.tShift[n],f=e.eMarks[n];if(o!==e.src.charCodeAt(d))return!1;for(l=d+1;l<=f&&a[(l-d)%s]===e.src[l];l++);let p=Math.floor((l-d)/s);if(p<3)return!1;l-=(l-d)%s;let m=e.src.slice(d,l),h=e.src.slice(l,f);if(!c(h,m))return!1;if(i)return!0;let g=n;for(;g++,!(g>=r||(d=e.bMarks[g]+e.tShift[g],f=e.eMarks[g],d<f&&e.sCount[g]<e.blkIndent));)if(o===e.src.charCodeAt(d)&&!(e.sCount[g]-e.blkIndent>=4)){for(l=d+1;l<=f&&a[(l-d)%s]===e.src[l];l++);if(!(Math.floor((l-d)/s)<p)&&(l-=(l-d)%s,l=e.skipSpaces(l),!(l<f))){u=!0;break}}let _=e.parentType,v=e.lineMax;e.parentType=`container`,e.lineMax=g;let y=e.push(`container_`+t+`_open`,`div`,1);y.markup=m,y.block=!0,y.info=h,y.map=[n,g],e.md.block.tokenize(e,n+1,g);let b=e.push(`container_`+t+`_close`,`div`,-1);return b.markup=e.src.slice(d,l),b.block=!0,e.parentType=_,e.lineMax=v,e.line=g+ +!!u,!0}e.block.ruler.before(`fence`,`container_`+t,u,{alt:[`paragraph`,`reference`,`blockquote`,`list`]}),e.renderer.rules[`container_`+t+`_open`]=l,e.renderer.rules[`container_`+t+`_close`]=l}const r=/<script\b[^>]*>([\s\S]*?)<\/script>/,i=/^virtual:VP_SFC_/;function a(){return{content:`<script setup>
|
|
2
2
|
<\/script>`,tagOpen:`<script setup>`,type:`script`,contentStripped:`
|
|
3
|
-
`,tagClose:`<\/script>`}}function o(
|
|
3
|
+
`,tagClose:`<\/script>`}}function o(e){let t=s(e),n=`VP_SFC_${t}`,r=`virtual:${n}.vue`;return{hash:t,name:n,importer:r,renderedContent:`// [vitepress-plugin-sfc] injected vue virtual imports
|
|
4
4
|
// REGION START
|
|
5
|
-
import ${
|
|
5
|
+
import ${n} from '${r}'
|
|
6
6
|
// REGION END
|
|
7
|
-
|
|
8
|
-
`),n=e.env.sfcs||[],r;function
|
|
9
|
-
`),
|
|
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
|
+
`),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};
|
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,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vitepress-plugin-sfc",
|
|
3
|
-
"version": "2.0.0-beta.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "2.0.0-beta.4",
|
|
4
|
+
"description": "Allows you to write Vue SFC within Markdown files and render them in VitePress.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"component",
|
|
7
7
|
"plugin",
|
|
@@ -11,6 +11,9 @@
|
|
|
11
11
|
"vitepress-plugin",
|
|
12
12
|
"vue"
|
|
13
13
|
],
|
|
14
|
+
"bugs": {
|
|
15
|
+
"url": "https://github.com/heroui-vue/vitepress-plugin-sfc/issues"
|
|
16
|
+
},
|
|
14
17
|
"license": "MIT",
|
|
15
18
|
"author": "hotdogc1017@gmail.com",
|
|
16
19
|
"repository": {
|
|
@@ -18,25 +21,28 @@
|
|
|
18
21
|
"url": "https://github.com/heroui-vue/vitepress-plugin-sfc"
|
|
19
22
|
},
|
|
20
23
|
"files": [
|
|
21
|
-
"dist"
|
|
22
|
-
"src/client"
|
|
24
|
+
"dist"
|
|
23
25
|
],
|
|
24
26
|
"type": "module",
|
|
25
|
-
"main": "dist/index.
|
|
26
|
-
"module": "dist/index.
|
|
27
|
-
"types": "./dist/index.d.mts",
|
|
27
|
+
"main": "./dist/index.mjs",
|
|
28
|
+
"module": "./dist/index.mjs",
|
|
28
29
|
"exports": {
|
|
29
30
|
".": {
|
|
30
31
|
"types": "./dist/index.d.mts",
|
|
31
32
|
"default": "./dist/index.mjs"
|
|
32
33
|
},
|
|
33
|
-
"./client":
|
|
34
|
+
"./client": {
|
|
35
|
+
"types": "./dist/client.d.mts",
|
|
36
|
+
"default": "./dist/client.mjs"
|
|
37
|
+
},
|
|
38
|
+
"./style": "./dist/style.css"
|
|
34
39
|
},
|
|
35
40
|
"publishConfig": {
|
|
36
41
|
"access": "public",
|
|
37
42
|
"registry": "https://registry.npmjs.org/"
|
|
38
43
|
},
|
|
39
44
|
"devDependencies": {
|
|
45
|
+
"@tsdown/css": "^0.23.2",
|
|
40
46
|
"@types/markdown-it": "^14.2.0",
|
|
41
47
|
"@types/markdown-it-container": "^2.0.10",
|
|
42
48
|
"@types/node": "^22.17.0",
|
|
@@ -54,12 +60,13 @@
|
|
|
54
60
|
"scripts": {
|
|
55
61
|
"dev": "tsdown -w",
|
|
56
62
|
"build": "tsdown --minify",
|
|
63
|
+
"build:check": "tsdown",
|
|
57
64
|
"bump": "bumpp --sign",
|
|
58
65
|
"pub": "npm run build && npm publish --registry=https://registry.npmjs.org/",
|
|
59
66
|
"dev:docs": "pnpm -C playground dev",
|
|
60
67
|
"fmt": "oxfmt",
|
|
61
68
|
"fmt:check": "oxfmt --check",
|
|
62
69
|
"lint": "oxlint",
|
|
63
|
-
"
|
|
70
|
+
"test": "vitest run -r __tests__"
|
|
64
71
|
}
|
|
65
72
|
}
|
|
@@ -1,165 +0,0 @@
|
|
|
1
|
-
<script setup lang="ts" generic="T">
|
|
2
|
-
import { computed, ref, useId, watch } from "vue";
|
|
3
|
-
import { useData } from "vitepress";
|
|
4
|
-
import { useLocaleMappings } from "./useLocaleMappings";
|
|
5
|
-
|
|
6
|
-
import type { LocaleMappings } from "./useLocaleMappings";
|
|
7
|
-
|
|
8
|
-
const localMappings: LocaleMappings = {
|
|
9
|
-
en: {
|
|
10
|
-
previewLabel: "Preview",
|
|
11
|
-
codeLabel: "Source Code",
|
|
12
|
-
},
|
|
13
|
-
zh: {
|
|
14
|
-
previewLabel: "预览",
|
|
15
|
-
codeLabel: "源代码",
|
|
16
|
-
},
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
const props = defineProps<{
|
|
20
|
-
src: string;
|
|
21
|
-
highlightedSrc?: string;
|
|
22
|
-
previewLabel?: string;
|
|
23
|
-
codeLabel?: string;
|
|
24
|
-
}>();
|
|
25
|
-
|
|
26
|
-
const { lang } = useData();
|
|
27
|
-
const { get } = useLocaleMappings();
|
|
28
|
-
|
|
29
|
-
const labels = computed(() => {
|
|
30
|
-
const mappings = { ...localMappings, ...get() };
|
|
31
|
-
// Default to English mappings if no locale-specific mappings are found
|
|
32
|
-
const { previewLabel: preview, codeLabel: code } = mappings[lang.value] ?? localMappings.en;
|
|
33
|
-
return [
|
|
34
|
-
{
|
|
35
|
-
label: preview,
|
|
36
|
-
value: "preview",
|
|
37
|
-
},
|
|
38
|
-
{ label: code, value: "code" },
|
|
39
|
-
] as const;
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
const decodedSrc = ref("");
|
|
43
|
-
const highlightedSrc = ref("");
|
|
44
|
-
const activedTab = ref<"preview" | "code">("preview");
|
|
45
|
-
const tabGroupId = useId();
|
|
46
|
-
|
|
47
|
-
watch(
|
|
48
|
-
[() => props.src, () => props.highlightedSrc],
|
|
49
|
-
async ([src, highlight = ""]) => {
|
|
50
|
-
try {
|
|
51
|
-
decodedSrc.value = atob(src);
|
|
52
|
-
} catch (e) {
|
|
53
|
-
decodedSrc.value = src;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
try {
|
|
57
|
-
highlightedSrc.value = atob(highlight);
|
|
58
|
-
} catch (e) {
|
|
59
|
-
highlightedSrc.value = highlight;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
try {
|
|
63
|
-
atob(src);
|
|
64
|
-
} catch (e) {}
|
|
65
|
-
},
|
|
66
|
-
{
|
|
67
|
-
immediate: true,
|
|
68
|
-
},
|
|
69
|
-
);
|
|
70
|
-
</script>
|
|
71
|
-
|
|
72
|
-
<template>
|
|
73
|
-
<div class="vp-component-tabs">
|
|
74
|
-
<header>
|
|
75
|
-
<template v-for="{ label, value } in labels" :key="value">
|
|
76
|
-
<input
|
|
77
|
-
:id="`tab-${tabGroupId}-${value}`"
|
|
78
|
-
type="radio"
|
|
79
|
-
:name="`vp-component-tabs-${tabGroupId}`"
|
|
80
|
-
style="position: fixed; opacity: 0; pointer-events: none"
|
|
81
|
-
:data-checked="activedTab === value" />
|
|
82
|
-
<label :for="`tab-${tabGroupId}-${value}`" @click="activedTab = value">{{ label }}</label>
|
|
83
|
-
</template>
|
|
84
|
-
</header>
|
|
85
|
-
|
|
86
|
-
<main v-show="activedTab === 'preview'">
|
|
87
|
-
<!-- <slot /> -->
|
|
88
|
-
<slot name="v3" />
|
|
89
|
-
</main>
|
|
90
|
-
|
|
91
|
-
<div
|
|
92
|
-
v-show="activedTab === 'code'"
|
|
93
|
-
:class="`language-vue${activedTab === 'code' ? ' active' : ''}`"
|
|
94
|
-
style="margin: 0px">
|
|
95
|
-
<button title="copy source code" class="copy"></button>
|
|
96
|
-
<span class="lang">Vue</span>
|
|
97
|
-
<slot name="highlight" />
|
|
98
|
-
</div>
|
|
99
|
-
</div>
|
|
100
|
-
</template>
|
|
101
|
-
|
|
102
|
-
<style>
|
|
103
|
-
.vp-component-tabs {
|
|
104
|
-
margin: 16px 0;
|
|
105
|
-
display: grid;
|
|
106
|
-
grid-template-columns: 1fr;
|
|
107
|
-
grid-template-rows: min-content 1fr;
|
|
108
|
-
row-gap: 16px;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
.vp-component-tabs > header {
|
|
112
|
-
display: flex;
|
|
113
|
-
position: relative;
|
|
114
|
-
border-radius: 8px;
|
|
115
|
-
overflow-x: auto;
|
|
116
|
-
overflow-y: hidden;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
.vp-component-tabs > header input + label {
|
|
120
|
-
box-sizing: border-box;
|
|
121
|
-
display: inline-block;
|
|
122
|
-
position: relative;
|
|
123
|
-
padding: 8px 12px;
|
|
124
|
-
font-size: 14px;
|
|
125
|
-
font-weight: 500;
|
|
126
|
-
color: var(--vp-code-tab-text-color);
|
|
127
|
-
white-space: nowrap;
|
|
128
|
-
cursor: pointer;
|
|
129
|
-
transition:
|
|
130
|
-
color 0.25s,
|
|
131
|
-
background-color 0.25s;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
.vp-component-tabs > header input + label::after {
|
|
135
|
-
content: "";
|
|
136
|
-
position: absolute;
|
|
137
|
-
height: 4px;
|
|
138
|
-
border-radius: 2px;
|
|
139
|
-
left: 8px;
|
|
140
|
-
right: 8px;
|
|
141
|
-
bottom: -1px;
|
|
142
|
-
transition: background-color 0.25s;
|
|
143
|
-
}
|
|
144
|
-
.vp-component-tabs > header input[data-checked="true"] + label::after {
|
|
145
|
-
background-color: var(--vp-code-tab-active-bar-color);
|
|
146
|
-
}
|
|
147
|
-
.vp-component-tabs > header input[data-checked="true"] + label,
|
|
148
|
-
.vp-component-tabs > header label:hover {
|
|
149
|
-
color: var(--vp-code-tab-active-text-color);
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
.vp-component-tabs > main {
|
|
153
|
-
padding: 20px;
|
|
154
|
-
background-color: var(--vp-nav-bg-color);
|
|
155
|
-
border-radius: 8px;
|
|
156
|
-
outline: 1px solid var(--vp-c-divider);
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
.vp-component-tabs > section {
|
|
160
|
-
background-color: var(--vp-code-block-bg);
|
|
161
|
-
border-radius: 8px;
|
|
162
|
-
padding: 24px;
|
|
163
|
-
overflow: auto;
|
|
164
|
-
}
|
|
165
|
-
</style>
|
package/src/client/index.ts
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import ComponentView from "./ComponentView.vue";
|
|
2
|
-
import { useLocaleMappings } from "./useLocaleMappings";
|
|
3
|
-
|
|
4
|
-
import type { App } from "vue";
|
|
5
|
-
import type { LocaleMappings } from "./useLocaleMappings";
|
|
6
|
-
|
|
7
|
-
export const COMPONENT_NAME = "ComponentView";
|
|
8
|
-
|
|
9
|
-
export function enhanceAppWithComponentView(
|
|
10
|
-
app: App,
|
|
11
|
-
options?: {
|
|
12
|
-
localeMappings?: LocaleMappings;
|
|
13
|
-
},
|
|
14
|
-
): void {
|
|
15
|
-
const { localeMappings = {} } = options || {};
|
|
16
|
-
|
|
17
|
-
app.component(COMPONENT_NAME, ComponentView);
|
|
18
|
-
|
|
19
|
-
const { set } = useLocaleMappings(app);
|
|
20
|
-
set(localeMappings);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export { ComponentView };
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { provide, inject, getCurrentInstance } from "vue";
|
|
2
|
-
import type { App } from "vue";
|
|
3
|
-
|
|
4
|
-
export type LocaleMappings = Record<string, { previewLabel: string; codeLabel: string }>;
|
|
5
|
-
|
|
6
|
-
const localeMappingSymbol = Symbol("__vitepress_plugin_component_localeMapping");
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Initialize locale mappings for the application.
|
|
10
|
-
* @param app - The Vue application instance. If not provided, the mappings will be provided to the current component.
|
|
11
|
-
*/
|
|
12
|
-
export function useLocaleMappings(app?: App) {
|
|
13
|
-
return {
|
|
14
|
-
set: (localeMapping: LocaleMappings) => {
|
|
15
|
-
const instance = getCurrentInstance();
|
|
16
|
-
if (app) {
|
|
17
|
-
app?.provide(localeMappingSymbol, localeMapping);
|
|
18
|
-
} else {
|
|
19
|
-
if (!instance) {
|
|
20
|
-
throw new Error(
|
|
21
|
-
"useLocaleMappings must be called within a Vue component if not providing an app",
|
|
22
|
-
);
|
|
23
|
-
}
|
|
24
|
-
provide(localeMappingSymbol, localeMapping);
|
|
25
|
-
}
|
|
26
|
-
},
|
|
27
|
-
get: () => {
|
|
28
|
-
return inject<LocaleMappings | undefined>(localeMappingSymbol, undefined);
|
|
29
|
-
},
|
|
30
|
-
};
|
|
31
|
-
}
|