@nuxtjs/mdc 0.1.0
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/LICENSE +21 -0
- package/README.md +64 -0
- package/dist/module.cjs +5 -0
- package/dist/module.d.mts +55 -0
- package/dist/module.d.ts +55 -0
- package/dist/module.json +5 -0
- package/dist/module.mjs +174 -0
- package/dist/runtime/components/MDC.vue +36 -0
- package/dist/runtime/components/MDCRenderer.vue +293 -0
- package/dist/runtime/components/MDCRenderer.vue.d.ts +92 -0
- package/dist/runtime/components/MDCSlot.vue +60 -0
- package/dist/runtime/components/MDCSlot.vue.d.ts +5 -0
- package/dist/runtime/components/prose/ProseA.vue +22 -0
- package/dist/runtime/components/prose/ProseBlockquote.vue +5 -0
- package/dist/runtime/components/prose/ProseCode.vue +3 -0
- package/dist/runtime/components/prose/ProseEm.vue +5 -0
- package/dist/runtime/components/prose/ProseH1.vue +20 -0
- package/dist/runtime/components/prose/ProseH2.vue +20 -0
- package/dist/runtime/components/prose/ProseH3.vue +20 -0
- package/dist/runtime/components/prose/ProseH4.vue +20 -0
- package/dist/runtime/components/prose/ProseH5.vue +20 -0
- package/dist/runtime/components/prose/ProseH6.vue +20 -0
- package/dist/runtime/components/prose/ProseHr.vue +3 -0
- package/dist/runtime/components/prose/ProseImg.vue +42 -0
- package/dist/runtime/components/prose/ProseLi.vue +3 -0
- package/dist/runtime/components/prose/ProseOl.vue +5 -0
- package/dist/runtime/components/prose/ProseP.vue +3 -0
- package/dist/runtime/components/prose/ProsePre.vue +39 -0
- package/dist/runtime/components/prose/ProseStrong.vue +5 -0
- package/dist/runtime/components/prose/ProseTable.vue +5 -0
- package/dist/runtime/components/prose/ProseTbody.vue +5 -0
- package/dist/runtime/components/prose/ProseTd.vue +5 -0
- package/dist/runtime/components/prose/ProseTh.vue +5 -0
- package/dist/runtime/components/prose/ProseThead.vue +5 -0
- package/dist/runtime/components/prose/ProseTr.vue +5 -0
- package/dist/runtime/components/prose/ProseUl.vue +5 -0
- package/dist/runtime/index.d.ts +3 -0
- package/dist/runtime/index.mjs +3 -0
- package/dist/runtime/parser/compiler.d.ts +1 -0
- package/dist/runtime/parser/compiler.mjs +78 -0
- package/dist/runtime/parser/handlers/code.d.ts +5 -0
- package/dist/runtime/parser/handlers/code.mjs +31 -0
- package/dist/runtime/parser/handlers/containerComponent.d.ts +10 -0
- package/dist/runtime/parser/handlers/containerComponent.mjs +15 -0
- package/dist/runtime/parser/handlers/emphasis.d.ts +6 -0
- package/dist/runtime/parser/handlers/emphasis.mjs +10 -0
- package/dist/runtime/parser/handlers/html.d.ts +3 -0
- package/dist/runtime/parser/handlers/html.mjs +14 -0
- package/dist/runtime/parser/handlers/image.d.ts +6 -0
- package/dist/runtime/parser/handlers/image.mjs +13 -0
- package/dist/runtime/parser/handlers/index.d.ts +22 -0
- package/dist/runtime/parser/handlers/index.mjs +22 -0
- package/dist/runtime/parser/handlers/inlineCode.d.ts +6 -0
- package/dist/runtime/parser/handlers/inlineCode.mjs +12 -0
- package/dist/runtime/parser/handlers/link.d.ts +6 -0
- package/dist/runtime/parser/handlers/link.mjs +18 -0
- package/dist/runtime/parser/handlers/list.d.ts +4 -0
- package/dist/runtime/parser/handlers/list.mjs +26 -0
- package/dist/runtime/parser/handlers/paragraph.d.ts +4 -0
- package/dist/runtime/parser/handlers/paragraph.mjs +19 -0
- package/dist/runtime/parser/handlers/strong.d.ts +6 -0
- package/dist/runtime/parser/handlers/strong.mjs +10 -0
- package/dist/runtime/parser/handlers/utils.d.ts +19 -0
- package/dist/runtime/parser/handlers/utils.mjs +33 -0
- package/dist/runtime/parser/index.d.ts +11 -0
- package/dist/runtime/parser/index.mjs +60 -0
- package/dist/runtime/parser/options.d.ts +2 -0
- package/dist/runtime/parser/options.mjs +50 -0
- package/dist/runtime/parser/shiki.d.ts +8 -0
- package/dist/runtime/parser/shiki.mjs +55 -0
- package/dist/runtime/parser/toc.d.ts +3 -0
- package/dist/runtime/parser/toc.mjs +59 -0
- package/dist/runtime/parser/utils/html-tags-list.d.ts +2 -0
- package/dist/runtime/parser/utils/html-tags-list.mjs +119 -0
- package/dist/runtime/parser/utils/plugins.d.ts +3 -0
- package/dist/runtime/parser/utils/plugins.mjs +10 -0
- package/dist/runtime/parser/utils/props.d.ts +5 -0
- package/dist/runtime/parser/utils/props.mjs +33 -0
- package/dist/runtime/shiki/event-handler.d.ts +8 -0
- package/dist/runtime/shiki/event-handler.mjs +15 -0
- package/dist/runtime/shiki/highlighter.d.ts +25 -0
- package/dist/runtime/shiki/highlighter.mjs +298 -0
- package/dist/runtime/shiki/mdc.tmLanguage.d.ts +323 -0
- package/dist/runtime/shiki/mdc.tmLanguage.mjs +582 -0
- package/dist/runtime/shiki/types.d.ts +32 -0
- package/dist/runtime/shiki/types.mjs +0 -0
- package/dist/runtime/types/hast.d.ts +255 -0
- package/dist/runtime/types/hast.mjs +0 -0
- package/dist/runtime/types/index.d.ts +3 -0
- package/dist/runtime/types/index.mjs +3 -0
- package/dist/runtime/types/parser.d.ts +30 -0
- package/dist/runtime/types/parser.mjs +0 -0
- package/dist/runtime/types/toc.d.ts +12 -0
- package/dist/runtime/types/toc.mjs +0 -0
- package/dist/runtime/types/tree.d.ts +17 -0
- package/dist/runtime/types/tree.mjs +0 -0
- package/dist/runtime/types/unist.d.ts +107 -0
- package/dist/runtime/types/unist.mjs +0 -0
- package/dist/runtime/utils/ast.d.ts +6 -0
- package/dist/runtime/utils/ast.mjs +29 -0
- package/dist/runtime/utils/node.d.ts +37 -0
- package/dist/runtime/utils/node.mjs +75 -0
- package/dist/runtime/utils/slot.d.ts +3 -0
- package/dist/runtime/utils/slot.mjs +8 -0
- package/dist/runtime/utils/ssrSlot.d.ts +1 -0
- package/dist/runtime/utils/ssrSlot.mjs +8 -0
- package/dist/types.d.mts +7 -0
- package/dist/types.d.ts +7 -0
- package/package.json +99 -0
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import { h, resolveComponent, Text, defineComponent, toRaw } from "vue";
|
|
3
|
+
import destr from "destr";
|
|
4
|
+
import { pascalCase } from "scule";
|
|
5
|
+
import { find, html } from "property-information";
|
|
6
|
+
import { useRoute, useRuntimeConfig } from "#app";
|
|
7
|
+
import htmlTags from "../parser/utils/html-tags-list";
|
|
8
|
+
const DEFAULT_SLOT = "default";
|
|
9
|
+
const rxOn = /^@|^v-on:/;
|
|
10
|
+
const rxBind = /^:|^v-bind:/;
|
|
11
|
+
const rxModel = /^v-model/;
|
|
12
|
+
const nativeInputs = ["select", "textarea", "input"];
|
|
13
|
+
const proseComponentMap = Object.fromEntries(["p", "a", "blockquote", "code", "pre", "code", "em", "h1", "h2", "h3", "h4", "h5", "h6", "hr", "img", "ul", "ol", "li", "strong", "table", "thead", "tbody", "td", "th", "tr"].map((t) => [t, `prose-${t}`]));
|
|
14
|
+
export default defineComponent({
|
|
15
|
+
name: "MDCRenderer",
|
|
16
|
+
props: {
|
|
17
|
+
/**
|
|
18
|
+
* Content to render
|
|
19
|
+
*/
|
|
20
|
+
body: {
|
|
21
|
+
type: Object,
|
|
22
|
+
required: true
|
|
23
|
+
},
|
|
24
|
+
data: {
|
|
25
|
+
type: Object,
|
|
26
|
+
default: () => ({})
|
|
27
|
+
},
|
|
28
|
+
/**
|
|
29
|
+
* Render only the excerpt
|
|
30
|
+
*/
|
|
31
|
+
excerpt: {
|
|
32
|
+
type: Boolean,
|
|
33
|
+
default: false
|
|
34
|
+
},
|
|
35
|
+
/**
|
|
36
|
+
* Root tag to use for rendering
|
|
37
|
+
*/
|
|
38
|
+
tag: {
|
|
39
|
+
type: String,
|
|
40
|
+
default: void 0
|
|
41
|
+
},
|
|
42
|
+
/**
|
|
43
|
+
* Whether or not to render Prose components instead of HTML tags
|
|
44
|
+
*/
|
|
45
|
+
prose: {
|
|
46
|
+
type: Boolean,
|
|
47
|
+
default: void 0
|
|
48
|
+
},
|
|
49
|
+
/**
|
|
50
|
+
* The map of custom components to use for rendering.
|
|
51
|
+
*/
|
|
52
|
+
components: {
|
|
53
|
+
type: Object,
|
|
54
|
+
default: () => ({})
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
async setup(props) {
|
|
58
|
+
const { mdc } = useRuntimeConfig().public;
|
|
59
|
+
const tags = {
|
|
60
|
+
...mdc.components.prose && props.prose !== false ? proseComponentMap : {},
|
|
61
|
+
...mdc.components.map,
|
|
62
|
+
...toRaw(props.data?.mdc?.components || {}),
|
|
63
|
+
...props.components
|
|
64
|
+
};
|
|
65
|
+
await resolveContentComponents(props.body, { tags });
|
|
66
|
+
return { tags };
|
|
67
|
+
},
|
|
68
|
+
render(ctx) {
|
|
69
|
+
const { tags, tag, body, data } = ctx;
|
|
70
|
+
if (!body) {
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
const meta = { ...data, tags };
|
|
74
|
+
let component = tag || meta.component?.name || meta.component || "div";
|
|
75
|
+
component = resolveVueComponent(component);
|
|
76
|
+
return h(
|
|
77
|
+
component,
|
|
78
|
+
{
|
|
79
|
+
...meta.component?.props,
|
|
80
|
+
...this.$attrs
|
|
81
|
+
},
|
|
82
|
+
renderSlots(body, h, meta, meta)
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
function renderNode(node, h2, documentMeta, parentScope = {}) {
|
|
87
|
+
if (node.type === "text") {
|
|
88
|
+
return h2(Text, node.value);
|
|
89
|
+
}
|
|
90
|
+
if (node.tag === "script") {
|
|
91
|
+
return h2(Text, renderToText(node));
|
|
92
|
+
}
|
|
93
|
+
const originalTag = node.tag;
|
|
94
|
+
const renderTag = typeof node.props?.__ignoreMap === "undefined" && documentMeta.tags[originalTag] || originalTag;
|
|
95
|
+
if (node.tag === "binding") {
|
|
96
|
+
return renderBinding(node, h2, documentMeta, parentScope);
|
|
97
|
+
}
|
|
98
|
+
const component = resolveVueComponent(renderTag);
|
|
99
|
+
if (typeof component === "object") {
|
|
100
|
+
component.tag = originalTag;
|
|
101
|
+
}
|
|
102
|
+
const props = propsToData(node, documentMeta);
|
|
103
|
+
return h2(
|
|
104
|
+
component,
|
|
105
|
+
props,
|
|
106
|
+
renderSlots(node, h2, documentMeta, { ...parentScope, ...props })
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
function renderToText(node) {
|
|
110
|
+
if (node.type === "text") {
|
|
111
|
+
return node.value;
|
|
112
|
+
}
|
|
113
|
+
if (!node.children?.length) {
|
|
114
|
+
return `<${node.tag}>`;
|
|
115
|
+
}
|
|
116
|
+
return `<${node.tag}>${node.children?.map(renderToText).join("") || ""}</${node.tag}>`;
|
|
117
|
+
}
|
|
118
|
+
function renderBinding(node, h2, documentMeta, parentScope = {}) {
|
|
119
|
+
const data = {
|
|
120
|
+
...parentScope,
|
|
121
|
+
$route: () => useRoute(),
|
|
122
|
+
$document: documentMeta,
|
|
123
|
+
$doc: documentMeta
|
|
124
|
+
};
|
|
125
|
+
const splitter = /\.|\[(\d+)\]/;
|
|
126
|
+
const keys = node.props?.value.trim().split(splitter).filter(Boolean);
|
|
127
|
+
const value = keys.reduce((data2, key) => {
|
|
128
|
+
if (key in data2) {
|
|
129
|
+
if (typeof data2[key] === "function") {
|
|
130
|
+
return data2[key]();
|
|
131
|
+
} else {
|
|
132
|
+
return data2[key];
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return {};
|
|
136
|
+
}, data);
|
|
137
|
+
return h2(Text, value);
|
|
138
|
+
}
|
|
139
|
+
function renderSlots(node, h2, documentMeta, parentProps) {
|
|
140
|
+
const children = node.children || [];
|
|
141
|
+
const slotNodes = children.reduce((data, node2) => {
|
|
142
|
+
if (!isTemplate(node2)) {
|
|
143
|
+
data[DEFAULT_SLOT].push(node2);
|
|
144
|
+
return data;
|
|
145
|
+
}
|
|
146
|
+
const slotName = getSlotName(node2);
|
|
147
|
+
data[slotName] = data[slotName] || [];
|
|
148
|
+
if (node2.type === "element") {
|
|
149
|
+
data[slotName].push(...node2.children || []);
|
|
150
|
+
}
|
|
151
|
+
return data;
|
|
152
|
+
}, {
|
|
153
|
+
[DEFAULT_SLOT]: []
|
|
154
|
+
});
|
|
155
|
+
const slots = Object.entries(slotNodes).reduce((slots2, [name, children2]) => {
|
|
156
|
+
if (!children2.length) {
|
|
157
|
+
return slots2;
|
|
158
|
+
}
|
|
159
|
+
slots2[name] = () => {
|
|
160
|
+
const vNodes = children2.map((child) => renderNode(child, h2, documentMeta, parentProps));
|
|
161
|
+
return mergeTextNodes(vNodes);
|
|
162
|
+
};
|
|
163
|
+
return slots2;
|
|
164
|
+
}, {});
|
|
165
|
+
return slots;
|
|
166
|
+
}
|
|
167
|
+
function propsToData(node, documentMeta) {
|
|
168
|
+
const { tag = "", props = {} } = node;
|
|
169
|
+
return Object.keys(props).reduce(function(data, key) {
|
|
170
|
+
if (key === "__ignoreMap") {
|
|
171
|
+
return data;
|
|
172
|
+
}
|
|
173
|
+
const value = props[key];
|
|
174
|
+
if (rxModel.test(key) && !nativeInputs.includes(tag)) {
|
|
175
|
+
return propsToDataRxModel(key, value, data, documentMeta);
|
|
176
|
+
}
|
|
177
|
+
if (key === "v-bind") {
|
|
178
|
+
return propsToDataVBind(key, value, data, documentMeta);
|
|
179
|
+
}
|
|
180
|
+
if (rxOn.test(key)) {
|
|
181
|
+
return propsToDataRxOn(key, value, data, documentMeta);
|
|
182
|
+
}
|
|
183
|
+
if (rxBind.test(key)) {
|
|
184
|
+
return propsToDataRxBind(key, value, data, documentMeta);
|
|
185
|
+
}
|
|
186
|
+
const { attribute } = find(html, key);
|
|
187
|
+
if (Array.isArray(value) && value.every((v) => typeof v === "string")) {
|
|
188
|
+
data[attribute] = value.join(" ");
|
|
189
|
+
return data;
|
|
190
|
+
}
|
|
191
|
+
data[attribute] = value;
|
|
192
|
+
return data;
|
|
193
|
+
}, {});
|
|
194
|
+
}
|
|
195
|
+
function propsToDataRxModel(key, value, data, documentMeta) {
|
|
196
|
+
const number = (d) => +d;
|
|
197
|
+
const trim = (d) => d.trim();
|
|
198
|
+
const noop = (d) => d;
|
|
199
|
+
const mods = key.replace(rxModel, "").split(".").filter((d) => d).reduce((d, k) => {
|
|
200
|
+
d[k] = true;
|
|
201
|
+
return d;
|
|
202
|
+
}, {});
|
|
203
|
+
const field = "value";
|
|
204
|
+
const event = mods.lazy ? "change" : "input";
|
|
205
|
+
const processor = mods.number ? number : mods.trim ? trim : noop;
|
|
206
|
+
data[field] = evalInContext(value, documentMeta);
|
|
207
|
+
data.on = data.on || {};
|
|
208
|
+
data.on[event] = (e) => documentMeta[value] = processor(e);
|
|
209
|
+
return data;
|
|
210
|
+
}
|
|
211
|
+
function propsToDataVBind(_key, value, data, documentMeta) {
|
|
212
|
+
const val = evalInContext(value, documentMeta);
|
|
213
|
+
data = Object.assign(data, val);
|
|
214
|
+
return data;
|
|
215
|
+
}
|
|
216
|
+
function propsToDataRxOn(key, value, data, documentMeta) {
|
|
217
|
+
key = key.replace(rxOn, "");
|
|
218
|
+
data.on = data.on || {};
|
|
219
|
+
data.on[key] = () => evalInContext(value, documentMeta);
|
|
220
|
+
return data;
|
|
221
|
+
}
|
|
222
|
+
function propsToDataRxBind(key, value, data, documentMeta) {
|
|
223
|
+
key = key.replace(rxBind, "");
|
|
224
|
+
data[key] = evalInContext(value, documentMeta);
|
|
225
|
+
return data;
|
|
226
|
+
}
|
|
227
|
+
const resolveVueComponent = (component) => {
|
|
228
|
+
if (!htmlTags.includes(component) && !component?.render) {
|
|
229
|
+
const componentFn = resolveComponent(pascalCase(component), false);
|
|
230
|
+
if (typeof componentFn === "object") {
|
|
231
|
+
return componentFn;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
return component;
|
|
235
|
+
};
|
|
236
|
+
function evalInContext(code, context) {
|
|
237
|
+
const result = code.split(".").reduce((o, k) => typeof o === "object" ? o[k] : void 0, context);
|
|
238
|
+
return typeof result === "undefined" ? destr(code) : result;
|
|
239
|
+
}
|
|
240
|
+
function getSlotName(node) {
|
|
241
|
+
let name = "";
|
|
242
|
+
for (const propName of Object.keys(node.props || {})) {
|
|
243
|
+
if (!propName.startsWith("#") && !propName.startsWith("v-slot:")) {
|
|
244
|
+
continue;
|
|
245
|
+
}
|
|
246
|
+
name = propName.split(/[:#]/, 2)[1];
|
|
247
|
+
break;
|
|
248
|
+
}
|
|
249
|
+
return name || DEFAULT_SLOT;
|
|
250
|
+
}
|
|
251
|
+
function isTemplate(node) {
|
|
252
|
+
return node.tag === "template";
|
|
253
|
+
}
|
|
254
|
+
function mergeTextNodes(nodes) {
|
|
255
|
+
const mergedNodes = [];
|
|
256
|
+
for (const node of nodes) {
|
|
257
|
+
const previousNode = mergedNodes[mergedNodes.length - 1];
|
|
258
|
+
if (node.type === Text && previousNode?.type === Text) {
|
|
259
|
+
previousNode.children = previousNode.children + node.children;
|
|
260
|
+
} else {
|
|
261
|
+
mergedNodes.push(node);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
return mergedNodes;
|
|
265
|
+
}
|
|
266
|
+
async function resolveContentComponents(body, meta) {
|
|
267
|
+
const components = Array.from(new Set(loadComponents(body, meta)));
|
|
268
|
+
await Promise.all(components.map(async (c) => {
|
|
269
|
+
if (c?.render || c?.ssrRender) {
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
const resolvedComponent = resolveComponent(c);
|
|
273
|
+
if (resolvedComponent?.__asyncLoader && !resolvedComponent.__asyncResolved) {
|
|
274
|
+
await resolvedComponent.__asyncLoader();
|
|
275
|
+
}
|
|
276
|
+
}));
|
|
277
|
+
function loadComponents(node, documentMeta) {
|
|
278
|
+
const tag = node.tag;
|
|
279
|
+
if (node.type === "text" || tag === "binding") {
|
|
280
|
+
return [];
|
|
281
|
+
}
|
|
282
|
+
const renderTag = typeof node.props?.__ignoreMap === "undefined" && documentMeta.tags[tag] || tag;
|
|
283
|
+
const components2 = [];
|
|
284
|
+
if (node.type !== "root" && !htmlTags.includes(renderTag)) {
|
|
285
|
+
components2.push(renderTag);
|
|
286
|
+
}
|
|
287
|
+
for (const child of node.children || []) {
|
|
288
|
+
components2.push(...loadComponents(child, documentMeta));
|
|
289
|
+
}
|
|
290
|
+
return components2;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
</script>
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import type { PropType, DefineComponent } from 'vue';
|
|
2
|
+
import type { MDCRoot } from '../types';
|
|
3
|
+
declare const _default: DefineComponent<{
|
|
4
|
+
/**
|
|
5
|
+
* Content to render
|
|
6
|
+
*/
|
|
7
|
+
body: {
|
|
8
|
+
type: PropType<MDCRoot>;
|
|
9
|
+
required: true;
|
|
10
|
+
};
|
|
11
|
+
data: {
|
|
12
|
+
type: ObjectConstructor;
|
|
13
|
+
default: () => {};
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Render only the excerpt
|
|
17
|
+
*/
|
|
18
|
+
excerpt: {
|
|
19
|
+
type: BooleanConstructor;
|
|
20
|
+
default: boolean;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Root tag to use for rendering
|
|
24
|
+
*/
|
|
25
|
+
tag: {
|
|
26
|
+
type: StringConstructor;
|
|
27
|
+
default: undefined;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Whether or not to render Prose components instead of HTML tags
|
|
31
|
+
*/
|
|
32
|
+
prose: {
|
|
33
|
+
type: BooleanConstructor;
|
|
34
|
+
default: undefined;
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* The map of custom components to use for rendering.
|
|
38
|
+
*/
|
|
39
|
+
components: {
|
|
40
|
+
type: PropType<Record<string, string | DefineComponent<any, any, any>>>;
|
|
41
|
+
default: () => {};
|
|
42
|
+
};
|
|
43
|
+
}, {
|
|
44
|
+
tags: any;
|
|
45
|
+
}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{
|
|
46
|
+
/**
|
|
47
|
+
* Content to render
|
|
48
|
+
*/
|
|
49
|
+
body: {
|
|
50
|
+
type: PropType<MDCRoot>;
|
|
51
|
+
required: true;
|
|
52
|
+
};
|
|
53
|
+
data: {
|
|
54
|
+
type: ObjectConstructor;
|
|
55
|
+
default: () => {};
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* Render only the excerpt
|
|
59
|
+
*/
|
|
60
|
+
excerpt: {
|
|
61
|
+
type: BooleanConstructor;
|
|
62
|
+
default: boolean;
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* Root tag to use for rendering
|
|
66
|
+
*/
|
|
67
|
+
tag: {
|
|
68
|
+
type: StringConstructor;
|
|
69
|
+
default: undefined;
|
|
70
|
+
};
|
|
71
|
+
/**
|
|
72
|
+
* Whether or not to render Prose components instead of HTML tags
|
|
73
|
+
*/
|
|
74
|
+
prose: {
|
|
75
|
+
type: BooleanConstructor;
|
|
76
|
+
default: undefined;
|
|
77
|
+
};
|
|
78
|
+
/**
|
|
79
|
+
* The map of custom components to use for rendering.
|
|
80
|
+
*/
|
|
81
|
+
components: {
|
|
82
|
+
type: PropType<Record<string, string | DefineComponent<any, any, any>>>;
|
|
83
|
+
default: () => {};
|
|
84
|
+
};
|
|
85
|
+
}>>, {
|
|
86
|
+
tag: string;
|
|
87
|
+
data: Record<string, any>;
|
|
88
|
+
components: Record<string, string | DefineComponent<any, any, any>>;
|
|
89
|
+
excerpt: boolean;
|
|
90
|
+
prose: boolean;
|
|
91
|
+
}, {}>;
|
|
92
|
+
export default _default;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import { defineComponent, getCurrentInstance, useSlots, computed, h } from "#imports";
|
|
3
|
+
import { flatUnwrap } from "../utils/node";
|
|
4
|
+
export default defineComponent({
|
|
5
|
+
name: "MDCSlot",
|
|
6
|
+
functional: true,
|
|
7
|
+
props: {
|
|
8
|
+
name: {
|
|
9
|
+
type: String,
|
|
10
|
+
default: "default"
|
|
11
|
+
},
|
|
12
|
+
/**
|
|
13
|
+
* Tags to unwrap separated by spaces
|
|
14
|
+
* Example: 'ul li'
|
|
15
|
+
*/
|
|
16
|
+
unwrap: {
|
|
17
|
+
type: [Boolean, String],
|
|
18
|
+
default: false
|
|
19
|
+
},
|
|
20
|
+
/**
|
|
21
|
+
* VNode to render
|
|
22
|
+
* This is only useful for render functions
|
|
23
|
+
*/
|
|
24
|
+
use: {
|
|
25
|
+
type: Function,
|
|
26
|
+
default: void 0
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
setup(props) {
|
|
30
|
+
const { parent } = getCurrentInstance();
|
|
31
|
+
const { default: fallbackSlot } = useSlots();
|
|
32
|
+
const tags = computed(() => {
|
|
33
|
+
if (typeof props.unwrap === "string") {
|
|
34
|
+
return props.unwrap.split(" ");
|
|
35
|
+
}
|
|
36
|
+
return ["*"];
|
|
37
|
+
});
|
|
38
|
+
return {
|
|
39
|
+
fallbackSlot,
|
|
40
|
+
tags,
|
|
41
|
+
parent
|
|
42
|
+
};
|
|
43
|
+
},
|
|
44
|
+
render({ use, unwrap, fallbackSlot, tags, parent }) {
|
|
45
|
+
try {
|
|
46
|
+
let slot = use;
|
|
47
|
+
if (typeof use === "string") {
|
|
48
|
+
slot = parent?.slots[use] || parent?.parent?.slots[use];
|
|
49
|
+
console.warn(`Please set :use="$slots.${use}" in <MDCSlot> component to enable reactivity`);
|
|
50
|
+
}
|
|
51
|
+
if (!slot) {
|
|
52
|
+
return fallbackSlot ? fallbackSlot() : h("div");
|
|
53
|
+
}
|
|
54
|
+
return unwrap ? flatUnwrap(slot(), tags) : [slot()];
|
|
55
|
+
} catch (e) {
|
|
56
|
+
return h("div");
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
</script>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<NuxtLink
|
|
3
|
+
:href="href"
|
|
4
|
+
:target="target"
|
|
5
|
+
>
|
|
6
|
+
<slot />
|
|
7
|
+
</NuxtLink>
|
|
8
|
+
</template>
|
|
9
|
+
|
|
10
|
+
<script setup lang="ts">
|
|
11
|
+
defineProps({
|
|
12
|
+
href: {
|
|
13
|
+
type: String,
|
|
14
|
+
default: ''
|
|
15
|
+
},
|
|
16
|
+
target: {
|
|
17
|
+
type: String,
|
|
18
|
+
default: undefined,
|
|
19
|
+
required: false
|
|
20
|
+
}
|
|
21
|
+
})
|
|
22
|
+
</script>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<h1 :id="id">
|
|
3
|
+
<a
|
|
4
|
+
v-if="generate"
|
|
5
|
+
:href="`#${id}`"
|
|
6
|
+
>
|
|
7
|
+
<slot />
|
|
8
|
+
</a>
|
|
9
|
+
<slot v-else />
|
|
10
|
+
</h1>
|
|
11
|
+
</template>
|
|
12
|
+
|
|
13
|
+
<script setup lang="ts">
|
|
14
|
+
import { computed, useRuntimeConfig } from '#imports'
|
|
15
|
+
|
|
16
|
+
const props = defineProps<{ id?: string }>()
|
|
17
|
+
|
|
18
|
+
const { headings } = useRuntimeConfig().public.mdc
|
|
19
|
+
const generate = computed(() => props.id && headings.anchorLinks.h1)
|
|
20
|
+
</script>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<h2 :id="id">
|
|
3
|
+
<a
|
|
4
|
+
v-if="id && generate"
|
|
5
|
+
:href="`#${id}`"
|
|
6
|
+
>
|
|
7
|
+
<slot />
|
|
8
|
+
</a>
|
|
9
|
+
<slot v-else />
|
|
10
|
+
</h2>
|
|
11
|
+
</template>
|
|
12
|
+
|
|
13
|
+
<script setup lang="ts">
|
|
14
|
+
import { computed, useRuntimeConfig } from '#imports'
|
|
15
|
+
|
|
16
|
+
const props = defineProps<{ id?: string }>()
|
|
17
|
+
|
|
18
|
+
const { headings } = useRuntimeConfig().public.mdc
|
|
19
|
+
const generate = computed(() => props.id && headings.anchorLinks.h2)
|
|
20
|
+
</script>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<h3 :id="id">
|
|
3
|
+
<a
|
|
4
|
+
v-if="id && generate"
|
|
5
|
+
:href="`#${id}`"
|
|
6
|
+
>
|
|
7
|
+
<slot />
|
|
8
|
+
</a>
|
|
9
|
+
<slot v-else />
|
|
10
|
+
</h3>
|
|
11
|
+
</template>
|
|
12
|
+
|
|
13
|
+
<script setup lang="ts">
|
|
14
|
+
import { computed, useRuntimeConfig } from '#imports'
|
|
15
|
+
|
|
16
|
+
const props = defineProps<{ id?: string }>()
|
|
17
|
+
|
|
18
|
+
const { headings } = useRuntimeConfig().public.mdc
|
|
19
|
+
const generate = computed(() => props.id && headings.anchorLinks.h3)
|
|
20
|
+
</script>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<h4 :id="id">
|
|
3
|
+
<a
|
|
4
|
+
v-if="id && generate"
|
|
5
|
+
:href="`#${id}`"
|
|
6
|
+
>
|
|
7
|
+
<slot />
|
|
8
|
+
</a>
|
|
9
|
+
<slot v-else />
|
|
10
|
+
</h4>
|
|
11
|
+
</template>
|
|
12
|
+
|
|
13
|
+
<script setup lang="ts">
|
|
14
|
+
import { computed, useRuntimeConfig } from '#imports'
|
|
15
|
+
|
|
16
|
+
const props = defineProps<{ id?: string }>()
|
|
17
|
+
|
|
18
|
+
const { headings } = useRuntimeConfig().public.mdc
|
|
19
|
+
const generate = computed(() => props.id && headings.anchorLinks.h4)
|
|
20
|
+
</script>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<h5 :id="id">
|
|
3
|
+
<a
|
|
4
|
+
v-if="id && generate"
|
|
5
|
+
:href="`#${id}`"
|
|
6
|
+
>
|
|
7
|
+
<slot />
|
|
8
|
+
</a>
|
|
9
|
+
<slot v-else />
|
|
10
|
+
</h5>
|
|
11
|
+
</template>
|
|
12
|
+
|
|
13
|
+
<script setup lang="ts">
|
|
14
|
+
import { computed, useRuntimeConfig } from '#imports'
|
|
15
|
+
|
|
16
|
+
const props = defineProps<{ id?: string }>()
|
|
17
|
+
|
|
18
|
+
const { headings } = useRuntimeConfig().public.mdc
|
|
19
|
+
const generate = computed(() => props.id && headings.anchorLinks.h5)
|
|
20
|
+
</script>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<h6 :id="id">
|
|
3
|
+
<a
|
|
4
|
+
v-if="id && generate"
|
|
5
|
+
:href="`#${id}`"
|
|
6
|
+
>
|
|
7
|
+
<slot />
|
|
8
|
+
</a>
|
|
9
|
+
<slot v-else />
|
|
10
|
+
</h6>
|
|
11
|
+
</template>
|
|
12
|
+
|
|
13
|
+
<script setup lang="ts">
|
|
14
|
+
import { computed, useRuntimeConfig } from '#imports'
|
|
15
|
+
|
|
16
|
+
const props = defineProps<{ id?: string }>()
|
|
17
|
+
|
|
18
|
+
const { headings } = useRuntimeConfig().public.mdc
|
|
19
|
+
const generate = computed(() => props.id && headings.anchorLinks.h6)
|
|
20
|
+
</script>
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<img
|
|
3
|
+
:src="refinedSrc"
|
|
4
|
+
:alt="alt"
|
|
5
|
+
:width="width"
|
|
6
|
+
:height="height"
|
|
7
|
+
>
|
|
8
|
+
</template>
|
|
9
|
+
|
|
10
|
+
<script setup lang="ts">
|
|
11
|
+
import { withTrailingSlash, withLeadingSlash, joinURL } from 'ufo'
|
|
12
|
+
import { useRuntimeConfig, computed } from '#imports'
|
|
13
|
+
|
|
14
|
+
const props = defineProps({
|
|
15
|
+
src: {
|
|
16
|
+
type: String,
|
|
17
|
+
default: ''
|
|
18
|
+
},
|
|
19
|
+
alt: {
|
|
20
|
+
type: String,
|
|
21
|
+
default: ''
|
|
22
|
+
},
|
|
23
|
+
width: {
|
|
24
|
+
type: [String, Number],
|
|
25
|
+
default: undefined
|
|
26
|
+
},
|
|
27
|
+
height: {
|
|
28
|
+
type: [String, Number],
|
|
29
|
+
default: undefined
|
|
30
|
+
}
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
const refinedSrc = computed(() => {
|
|
34
|
+
if (props.src?.startsWith('/') && !props.src.startsWith('//')) {
|
|
35
|
+
const _base = withLeadingSlash(withTrailingSlash(useRuntimeConfig().app.baseURL))
|
|
36
|
+
if (_base !== '/' && !props.src.startsWith(_base)) {
|
|
37
|
+
return joinURL(_base, props.src)
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return props.src
|
|
41
|
+
})
|
|
42
|
+
</script>
|