@mantine-vue/code-highlight 3.2.0 → 3.4.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/cjs/index.cjs +144 -39
- package/cjs/index.cjs.map +1 -1
- package/esm/index.mjs +143 -41
- package/esm/index.mjs.map +1 -1
- package/lib/CodeHighlight/CodeHighlight.types.d.ts +2 -0
- package/lib/CodeHighlight/InlineCodeHighlight.types.d.ts +2 -0
- package/lib/CodeHighlightProvider/CodeHighlightProvider.d.ts +7 -1
- package/lib/CodeHighlightProvider/CodeHighlightProvider.types.d.ts +4 -0
- package/lib/CodeHighlightProvider/adapters/shiki-adapter.d.ts +2 -1
- package/lib/index.d.mts +3 -1
- package/lib/index.d.ts +3 -1
- package/lib/normalize-code.d.ts +6 -0
- package/package.json +3 -3
package/esm/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createSlots, createStaticVNode, createTextVNode, createVNode, defineComponent, guardReactiveProps, inject, mergeProps, normalizeProps,
|
|
1
|
+
import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createSlots, createStaticVNode, createTextVNode, createVNode, defineComponent, guardReactiveProps, inject, mergeProps, normalizeProps, openBlock, provide, ref, renderList, renderSlot, resolveDynamicComponent, toDisplayString, unref, useAttrs, useSlots, watch, watchEffect, withCtx } from "vue";
|
|
2
2
|
import { ActionIcon, Box, ScrollArea, Tooltip, UnstyledButton, createSafeContext, createVarsResolver, getRadius, getThemeColor, rem, useMantineContext, useProps, useStyles } from "@mantine-vue/core";
|
|
3
3
|
import { useClipboard, useUncontrolled } from "@mantine-vue/hooks";
|
|
4
4
|
//#region src/CodeHighlightProvider/adapters/plain-text-adapter.ts
|
|
@@ -18,15 +18,49 @@ var CodeHighlightAdapterProvider_default = /* @__PURE__ */ defineComponent({
|
|
|
18
18
|
setup(__props) {
|
|
19
19
|
const props = __props;
|
|
20
20
|
const context = ref(null);
|
|
21
|
+
const contextLoaded = ref(false);
|
|
22
|
+
const loadedLanguages = ref([]);
|
|
23
|
+
const requestedLanguages = /* @__PURE__ */ new Set();
|
|
24
|
+
let generation = 0;
|
|
21
25
|
const highlight = computed(() => props.adapter.getHighlighter(context.value));
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
26
|
+
watch(() => props.adapter, async (adapter) => {
|
|
27
|
+
const currentGeneration = ++generation;
|
|
28
|
+
context.value = null;
|
|
29
|
+
contextLoaded.value = !adapter.loadContext;
|
|
30
|
+
loadedLanguages.value = [];
|
|
31
|
+
requestedLanguages.clear();
|
|
32
|
+
if (adapter.loadContext) {
|
|
33
|
+
const value = await adapter.loadContext();
|
|
34
|
+
if (currentGeneration === generation) {
|
|
35
|
+
context.value = value;
|
|
36
|
+
contextLoaded.value = true;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}, { immediate: true });
|
|
40
|
+
function loadLanguage(language) {
|
|
41
|
+
if (!contextLoaded.value || !language || !props.adapter.loadLanguage || requestedLanguages.has(language)) return;
|
|
42
|
+
const currentGeneration = generation;
|
|
43
|
+
requestedLanguages.add(language);
|
|
44
|
+
let result;
|
|
45
|
+
try {
|
|
46
|
+
result = props.adapter.loadLanguage(context.value, language);
|
|
47
|
+
} catch {
|
|
48
|
+
requestedLanguages.delete(language);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
result?.then(() => {
|
|
52
|
+
if (currentGeneration === generation && !loadedLanguages.value.includes(language)) loadedLanguages.value = [...loadedLanguages.value, language];
|
|
53
|
+
}, () => currentGeneration === generation && requestedLanguages.delete(language));
|
|
54
|
+
}
|
|
25
55
|
provideCodeHighlightAdapterContext({
|
|
26
|
-
adapter
|
|
56
|
+
get adapter() {
|
|
57
|
+
return props.adapter;
|
|
58
|
+
},
|
|
27
59
|
get highlight() {
|
|
28
60
|
return highlight.value;
|
|
29
|
-
}
|
|
61
|
+
},
|
|
62
|
+
loadLanguage,
|
|
63
|
+
isLanguageLoaded: (language) => !language || !props.adapter.loadLanguage || loadedLanguages.value.includes(language)
|
|
30
64
|
});
|
|
31
65
|
return (_ctx, _cache) => {
|
|
32
66
|
return openBlock(), createElementBlock("div", _hoisted_1$1, [renderSlot(_ctx.$slots, "default")]);
|
|
@@ -40,10 +74,24 @@ function provideCodeHighlightAdapterContext(value) {
|
|
|
40
74
|
provide(CodeHighlightContext, value);
|
|
41
75
|
}
|
|
42
76
|
function useHighlight() {
|
|
43
|
-
|
|
77
|
+
const ctx = inject(CodeHighlightContext, null);
|
|
78
|
+
const fallback = plainTextAdapter.getHighlighter(null);
|
|
79
|
+
return (input) => (ctx?.highlight || fallback)(input);
|
|
80
|
+
}
|
|
81
|
+
function useLoadLanguage() {
|
|
82
|
+
return inject(CodeHighlightContext, null)?.loadLanguage || (() => {});
|
|
83
|
+
}
|
|
84
|
+
function useIsLanguageLoaded() {
|
|
85
|
+
return inject(CodeHighlightContext, null)?.isLanguageLoaded || (() => true);
|
|
44
86
|
}
|
|
45
87
|
var CodeHighlightAdapterProvider = CodeHighlightAdapterProvider_default;
|
|
46
88
|
//#endregion
|
|
89
|
+
//#region src/normalize-code.ts
|
|
90
|
+
/** Removes blank leading lines and trailing whitespace before highlighting or copying code. */
|
|
91
|
+
function normalizeCode(code, { withFirstLineIndentation } = {}) {
|
|
92
|
+
return withFirstLineIndentation ? code.replace(/^(?:[^\S\r\n]*\r?\n)+|\s+$/g, "") : code.trim();
|
|
93
|
+
}
|
|
94
|
+
//#endregion
|
|
47
95
|
//#region src/CodeHighlight/CodeHighlight.context.ts
|
|
48
96
|
var [provideCodeHighlightContext, useCodeHighlightContext] = createSafeContext("CodeHighlightProvider was not found in the component tree");
|
|
49
97
|
//#endregion
|
|
@@ -162,7 +210,7 @@ var CopyCodeButton_default = /* @__PURE__ */ defineComponent({
|
|
|
162
210
|
variant: "none",
|
|
163
211
|
"tooltip-label": unref(clipboard).copied.value ? props.copiedLabel : props.copyLabel,
|
|
164
212
|
"aria-label": unref(clipboard).copied.value ? props.copiedLabel : `${props.copyLabel} code`,
|
|
165
|
-
onClick: _cache[0] || (_cache[0] = ($event) => unref(clipboard).copy(props.code
|
|
213
|
+
onClick: _cache[0] || (_cache[0] = ($event) => unref(clipboard).copy(props.code))
|
|
166
214
|
}, {
|
|
167
215
|
default: withCtx(() => [createVNode(CopyIcon_default, { copied: unref(clipboard).copied.value }, null, 8, ["copied"])]),
|
|
168
216
|
_: 1
|
|
@@ -308,7 +356,8 @@ var CodeHighlight_default = /* @__PURE__ */ defineComponent({
|
|
|
308
356
|
default: false
|
|
309
357
|
},
|
|
310
358
|
controls: {},
|
|
311
|
-
codeColorScheme: {}
|
|
359
|
+
codeColorScheme: {},
|
|
360
|
+
withFirstLineIndentation: { type: Boolean }
|
|
312
361
|
},
|
|
313
362
|
emits: ["update:expanded", "expanded-change"],
|
|
314
363
|
setup(__props, { emit: __emit }) {
|
|
@@ -341,21 +390,28 @@ var CodeHighlight_default = /* @__PURE__ */ defineComponent({
|
|
|
341
390
|
}
|
|
342
391
|
});
|
|
343
392
|
const highlight = useHighlight();
|
|
393
|
+
const loadLanguage = useLoadLanguage();
|
|
394
|
+
const isLanguageLoaded = useIsLanguageLoaded();
|
|
395
|
+
const normalizedCode = computed(() => normalizeCode(props.code, { withFirstLineIndentation: props.withFirstLineIndentation }));
|
|
396
|
+
watchEffect(() => loadLanguage(props.language));
|
|
344
397
|
function resolveColorScheme(value) {
|
|
345
398
|
if (value !== "auto") return value;
|
|
346
399
|
return typeof window !== "undefined" && window.matchMedia?.("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
|
347
400
|
}
|
|
348
|
-
const highlighted = computed(() =>
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
401
|
+
const highlighted = computed(() => {
|
|
402
|
+
isLanguageLoaded(props.language);
|
|
403
|
+
return highlight({
|
|
404
|
+
code: normalizedCode.value,
|
|
405
|
+
language: props.language,
|
|
406
|
+
colorScheme: props.codeColorScheme ?? resolveColorScheme(mantine.colorScheme.value)
|
|
407
|
+
});
|
|
408
|
+
});
|
|
353
409
|
const renderedControls = computed(() => {
|
|
354
410
|
const value = props.controls !== void 0 ? typeof props.controls === "function" ? props.controls() : props.controls : slots.controls?.();
|
|
355
411
|
return Array.isArray(value) ? value : value ? [value] : [];
|
|
356
412
|
});
|
|
357
413
|
const shouldDisplayControls = computed(() => renderedControls.value.length > 0 || props.withExpandButton || props.withCopyButton);
|
|
358
|
-
const lineNumbers = computed(() =>
|
|
414
|
+
const lineNumbers = computed(() => normalizedCode.value.split("\n").map((_, index) => index + 1));
|
|
359
415
|
const renderControls = () => renderedControls.value;
|
|
360
416
|
provideCodeHighlightContext({
|
|
361
417
|
getStyles,
|
|
@@ -381,7 +437,7 @@ var CodeHighlight_default = /* @__PURE__ */ defineComponent({
|
|
|
381
437
|
className: [highlighted.value.codeElementProps?.class, unref(attrs).class],
|
|
382
438
|
style: [highlighted.value.codeElementProps?.style, unref(attrs).style]
|
|
383
439
|
})
|
|
384
|
-
}, { "data-with-border": unref(props).withBorder || void 0 }), toDisplayString(
|
|
440
|
+
}, { "data-with-border": unref(props).withBorder || void 0 }), toDisplayString(normalizedCode.value), 17, _hoisted_2)) : (openBlock(), createBlock(unref(Box), mergeProps({ key: 2 }, {
|
|
385
441
|
...unref(attrs),
|
|
386
442
|
...unref(getStyles)("codeHighlight")
|
|
387
443
|
}, {
|
|
@@ -406,7 +462,7 @@ var CodeHighlight_default = /* @__PURE__ */ defineComponent({
|
|
|
406
462
|
])) : createCommentVNode("", true),
|
|
407
463
|
unref(props).withCopyButton ? (openBlock(), createBlock(CopyCodeButton_default, {
|
|
408
464
|
key: 1,
|
|
409
|
-
code:
|
|
465
|
+
code: normalizedCode.value,
|
|
410
466
|
"copied-label": unref(props).copiedLabel,
|
|
411
467
|
"copy-label": unref(props).copyLabel
|
|
412
468
|
}, null, 8, [
|
|
@@ -437,7 +493,7 @@ var CodeHighlight_default = /* @__PURE__ */ defineComponent({
|
|
|
437
493
|
className: highlighted.value.codeElementProps?.class,
|
|
438
494
|
style: highlighted.value.codeElementProps?.style
|
|
439
495
|
})
|
|
440
|
-
})), toDisplayString(
|
|
496
|
+
})), toDisplayString(normalizedCode.value), 17))], 16, _hoisted_5)], 16)]),
|
|
441
497
|
_: 1
|
|
442
498
|
}, 16, ["data-collapsed"]),
|
|
443
499
|
createVNode(unref(UnstyledButton), mergeProps(unref(getStyles)("showCodeButton"), {
|
|
@@ -482,6 +538,7 @@ var InlineCodeHighlight = Object.assign(/* @__PURE__ */ defineComponent({
|
|
|
482
538
|
type: Boolean,
|
|
483
539
|
default: false
|
|
484
540
|
},
|
|
541
|
+
withFirstLineIndentation: { type: Boolean },
|
|
485
542
|
classNames: {},
|
|
486
543
|
styles: {},
|
|
487
544
|
vars: {},
|
|
@@ -592,7 +649,8 @@ var CodeHighlightTabs = Object.assign(/* @__PURE__ */ defineComponent({
|
|
|
592
649
|
default: false
|
|
593
650
|
},
|
|
594
651
|
controls: {},
|
|
595
|
-
codeColorScheme: {}
|
|
652
|
+
codeColorScheme: {},
|
|
653
|
+
withFirstLineIndentation: { type: Boolean }
|
|
596
654
|
},
|
|
597
655
|
emits: [
|
|
598
656
|
"update:activeTab",
|
|
@@ -694,6 +752,7 @@ var CodeHighlightTabs = Object.assign(/* @__PURE__ */ defineComponent({
|
|
|
694
752
|
controls: unref(props).controls,
|
|
695
753
|
"code-color-scheme": unref(props).codeColorScheme,
|
|
696
754
|
"with-line-numbers": unref(props).withLineNumbers,
|
|
755
|
+
"with-first-line-indentation": unref(props).withFirstLineIndentation,
|
|
697
756
|
"__with-offset": "",
|
|
698
757
|
"__static-selector": "CodeHighlightTabs",
|
|
699
758
|
onExpandedChange: unref(setExpanded),
|
|
@@ -720,6 +779,7 @@ var CodeHighlightTabs = Object.assign(/* @__PURE__ */ defineComponent({
|
|
|
720
779
|
"controls",
|
|
721
780
|
"code-color-scheme",
|
|
722
781
|
"with-line-numbers",
|
|
782
|
+
"with-first-line-indentation",
|
|
723
783
|
"onExpandedChange",
|
|
724
784
|
"class-names",
|
|
725
785
|
"styles"
|
|
@@ -735,7 +795,7 @@ function createHighlightJsAdapter(hljs) {
|
|
|
735
795
|
return { getHighlighter: () => ({ code, language }) => {
|
|
736
796
|
const lang = hljs.getLanguage(language) ? language : "plaintext";
|
|
737
797
|
return {
|
|
738
|
-
highlightedCode: hljs.highlight(code
|
|
798
|
+
highlightedCode: hljs.highlight(code, { language: lang }).value,
|
|
739
799
|
isHighlighted: true,
|
|
740
800
|
codeElementProps: { class: `hljs ${lang}` }
|
|
741
801
|
};
|
|
@@ -1888,28 +1948,70 @@ function stripElement(openTag, data) {
|
|
|
1888
1948
|
function stripShikiCodeBlocks(data) {
|
|
1889
1949
|
return stripElement("code", stripElement("pre", data));
|
|
1890
1950
|
}
|
|
1891
|
-
var
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1951
|
+
var specialLanguages = [
|
|
1952
|
+
"text",
|
|
1953
|
+
"plaintext",
|
|
1954
|
+
"txt",
|
|
1955
|
+
"plain",
|
|
1956
|
+
"ansi"
|
|
1957
|
+
];
|
|
1958
|
+
function isLanguageAvailable(ctx, language) {
|
|
1959
|
+
return !language || specialLanguages.includes(language) || typeof ctx.getLoadedLanguages !== "function" || ctx.getLoadedLanguages().includes(language);
|
|
1960
|
+
}
|
|
1961
|
+
var createShikiAdapter = (loadShiki, { forceColorScheme, resolveLanguage } = {}) => {
|
|
1962
|
+
const warnedLanguages = /* @__PURE__ */ new Set();
|
|
1963
|
+
const warnUnavailable = (language, reason) => {
|
|
1964
|
+
if (warnedLanguages.has(language)) return;
|
|
1965
|
+
warnedLanguages.add(language);
|
|
1966
|
+
console.warn(`[@mantine-vue/code-highlight] Language \`${language}\` ${reason}, code is rendered as plain text.`);
|
|
1967
|
+
};
|
|
1968
|
+
return {
|
|
1969
|
+
loadContext: loadShiki,
|
|
1970
|
+
loadLanguage: resolveLanguage ? (ctx, language) => {
|
|
1971
|
+
if (isLanguageAvailable(ctx, language)) return void 0;
|
|
1972
|
+
const onLoadError = (error) => {
|
|
1973
|
+
warnUnavailable(language, "could not be loaded");
|
|
1974
|
+
throw error;
|
|
1908
1975
|
};
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1976
|
+
try {
|
|
1977
|
+
const grammar = resolveLanguage(language);
|
|
1978
|
+
if (!grammar) {
|
|
1979
|
+
warnUnavailable(language, "was not resolved by `resolveLanguage`");
|
|
1980
|
+
return;
|
|
1981
|
+
}
|
|
1982
|
+
return Promise.resolve(ctx.loadLanguage(grammar)).catch(onLoadError);
|
|
1983
|
+
} catch (error) {
|
|
1984
|
+
return Promise.reject(error).catch(onLoadError);
|
|
1985
|
+
}
|
|
1986
|
+
} : void 0,
|
|
1987
|
+
getHighlighter: (ctx) => {
|
|
1988
|
+
if (!ctx) return ({ code }) => ({
|
|
1989
|
+
highlightedCode: code,
|
|
1990
|
+
isHighlighted: false
|
|
1991
|
+
});
|
|
1992
|
+
return ({ code, language, colorScheme }) => {
|
|
1993
|
+
if (!isLanguageAvailable(ctx, language)) {
|
|
1994
|
+
if (!resolveLanguage && language) warnUnavailable(language, "is not loaded");
|
|
1995
|
+
return {
|
|
1996
|
+
highlightedCode: code,
|
|
1997
|
+
isHighlighted: false
|
|
1998
|
+
};
|
|
1999
|
+
}
|
|
2000
|
+
let _colorScheme = colorScheme;
|
|
2001
|
+
if (colorScheme === "light") _colorScheme = light;
|
|
2002
|
+
else if (colorScheme === "dark") _colorScheme = dark;
|
|
2003
|
+
return {
|
|
2004
|
+
isHighlighted: true,
|
|
2005
|
+
highlightedCode: stripShikiCodeBlocks(ctx.codeToHtml(code, {
|
|
2006
|
+
lang: language,
|
|
2007
|
+
theme: forceColorScheme || _colorScheme
|
|
2008
|
+
}))
|
|
2009
|
+
};
|
|
2010
|
+
};
|
|
2011
|
+
}
|
|
2012
|
+
};
|
|
2013
|
+
};
|
|
1912
2014
|
//#endregion
|
|
1913
|
-
export { CodeHighlight, CodeHighlightAdapterProvider, CodeHighlightControl_default as CodeHighlightControl, CodeHighlightTabs, InlineCodeHighlight, createHighlightJsAdapter, createShikiAdapter, plainTextAdapter, stripShikiCodeBlocks, useCodeHighlightContext, useHighlight };
|
|
2015
|
+
export { CodeHighlight, CodeHighlightAdapterProvider, CodeHighlightControl_default as CodeHighlightControl, CodeHighlightTabs, InlineCodeHighlight, createHighlightJsAdapter, createShikiAdapter, normalizeCode, plainTextAdapter, stripShikiCodeBlocks, useCodeHighlightContext, useHighlight, useIsLanguageLoaded, useLoadLanguage };
|
|
1914
2016
|
|
|
1915
2017
|
//# sourceMappingURL=index.mjs.map
|