@sanity/code-input

7.2.67.2.7
dist/_chunks-es/CodeMirrorProxy.js
+dist/_chunks-es/CodeMirrorProxy.jsNew file
+446
Index: package/dist/_chunks-es/CodeMirrorProxy.js
===================================================================
--- package/dist/_chunks-es/CodeMirrorProxy.js
+++ package/dist/_chunks-es/CodeMirrorProxy.js
@@ -0,0 +1,446 @@
+import { t as CodeInputConfigContext } from "./CodeModeContext.js";
+import { c } from "react/compiler-runtime";
+import { rem, useRootTheme, useTheme } from "@sanity/ui";
+import { useContext, useEffect, useState } from "react";
+import { jsx } from "react/jsx-runtime";
+import { Decoration, EditorView, lineNumbers } from "@codemirror/view";
+import CodeMirror from "@uiw/react-codemirror";
+import { StreamLanguage } from "@codemirror/language";
+import { StateEffect, StateField } from "@codemirror/state";
+import { rgba } from "@sanity/ui/theme";
+import { tags } from "@lezer/highlight";
+import { createTheme } from "@uiw/codemirror-themes";
+const defaultCodeModes = [
+	{
+		name: "groq",
+		loader: () => import("@sanity/lezer-groq").then(({ groq }) => groq())
+	},
+	{
+		name: "javascript",
+		loader: () => import("@codemirror/lang-javascript").then(({ javascript }) => javascript({ jsx: !1 }))
+	},
+	{
+		name: "jsx",
+		loader: () => import("@codemirror/lang-javascript").then(({ javascript }) => javascript({ jsx: !0 }))
+	},
+	{
+		name: "typescript",
+		loader: () => import("@codemirror/lang-javascript").then(({ javascript }) => javascript({
+			jsx: !1,
+			typescript: !0
+		}))
+	},
+	{
+		name: "tsx",
+		loader: () => import("@codemirror/lang-javascript").then(({ javascript }) => javascript({
+			jsx: !0,
+			typescript: !0
+		}))
+	},
+	{
+		name: "php",
+		loader: () => import("@codemirror/lang-php").then(({ php }) => php())
+	},
+	{
+		name: "sql",
+		loader: () => import("@codemirror/lang-sql").then(({ sql }) => sql())
+	},
+	{
+		name: "mysql",
+		loader: () => import("@codemirror/lang-sql").then(({ sql, MySQL }) => sql({ dialect: MySQL }))
+	},
+	{
+		name: "json",
+		loader: () => import("@codemirror/lang-json").then(({ json }) => json())
+	},
+	{
+		name: "markdown",
+		loader: () => import("@codemirror/lang-markdown").then(({ markdown }) => markdown())
+	},
+	{
+		name: "java",
+		loader: () => import("@codemirror/lang-java").then(({ java }) => java())
+	},
+	{
+		name: "html",
+		loader: () => import("@codemirror/lang-html").then(({ html }) => html())
+	},
+	{
+		name: "csharp",
+		loader: () => import("@codemirror/legacy-modes/mode/clike").then(({ csharp }) => StreamLanguage.define(csharp))
+	},
+	{
+		name: "sh",
+		loader: () => import("@codemirror/legacy-modes/mode/shell").then(({ shell }) => StreamLanguage.define(shell))
+	},
+	{
+		name: "css",
+		loader: () => import("@codemirror/legacy-modes/mode/css").then(({ css }) => StreamLanguage.define(css))
+	},
+	{
+		name: "scss",
+		loader: () => import("@codemirror/legacy-modes/mode/css").then(({ css }) => StreamLanguage.define(css))
+	},
+	{
+		name: "sass",
+		loader: () => import("@codemirror/legacy-modes/mode/sass").then(({ sass }) => StreamLanguage.define(sass))
+	},
+	{
+		name: "ruby",
+		loader: () => import("@codemirror/legacy-modes/mode/ruby").then(({ ruby }) => StreamLanguage.define(ruby))
+	},
+	{
+		name: "python",
+		loader: () => import("@codemirror/legacy-modes/mode/python").then(({ python }) => StreamLanguage.define(python))
+	},
+	{
+		name: "xml",
+		loader: () => import("@codemirror/legacy-modes/mode/xml").then(({ xml }) => StreamLanguage.define(xml))
+	},
+	{
+		name: "yaml",
+		loader: () => import("@codemirror/legacy-modes/mode/yaml").then(({ yaml }) => StreamLanguage.define(yaml))
+	},
+	{
+		name: "golang",
+		loader: () => import("@codemirror/legacy-modes/mode/go").then(({ go }) => StreamLanguage.define(go))
+	},
+	{
+		name: "text",
+		loader: () => void 0
+	},
+	{
+		name: "batch",
+		loader: () => void 0
+	}
+];
+/**
+* `@sanity/[email protected]` introduced two new tones; "neutral" and "suggest",
+* which maps to "default" and "primary" respectively in the old theme.
+* This function returns the "backwards compatible" tone value.
+*
+* @returns The tone value that is backwards compatible with the old theme.
+* @internal
+*/
+function getBackwardsCompatibleTone(themeCtx) {
+	return themeCtx.tone !== "neutral" && themeCtx.tone !== "suggest" ? themeCtx.tone : themeCtx.tone === "neutral" ? "default" : "primary";
+}
+const highlightLineClass = "cm-highlight-line", addLineHighlight = StateEffect.define(), removeLineHighlight = StateEffect.define(), lineHighlightField = StateField.define({
+	create() {
+		return Decoration.none;
+	},
+	update(lines, tr) {
+		lines = lines.map(tr.changes);
+		for (let e of tr.effects) e.is(addLineHighlight) && (lines = lines.update({ add: [lineHighlightMark.range(e.value)] })), e.is(removeLineHighlight) && (lines = lines.update({ filter: (from) => from !== e.value }));
+		return lines;
+	},
+	toJSON(value, state) {
+		let highlightLines = [], iter = value.iter();
+		for (; iter.value;) {
+			let lineNumber = state.doc.lineAt(iter.from).number;
+			highlightLines.includes(lineNumber) || highlightLines.push(lineNumber), iter.next();
+		}
+		return highlightLines;
+	},
+	fromJSON(value, state) {
+		let lines = state.doc.lines, highlights = value.filter((line) => line <= lines).map((line) => lineHighlightMark.range(state.doc.line(line).from));
+		highlights.sort((a, b) => a.from - b.from);
+		try {
+			return Decoration.none.update({ add: highlights });
+		} catch (e) {
+			return console.error(e), Decoration.none;
+		}
+	},
+	provide: (f) => EditorView.decorations.from(f)
+}), lineHighlightMark = Decoration.line({ class: highlightLineClass }), highlightState = { highlight: lineHighlightField };
+function createCodeMirrorTheme(options) {
+	let { themeCtx } = options, fallbackTone = getBackwardsCompatibleTone(themeCtx), dark = { color: themeCtx.theme.color.dark[fallbackTone] }, light = { color: themeCtx.theme.color.light[fallbackTone] };
+	return EditorView.baseTheme({
+		".cm-lineNumbers": { cursor: "default" },
+		".cm-line.cm-line": { position: "relative" },
+		[`.${highlightLineClass}::before`]: {
+			position: "absolute",
+			top: 0,
+			bottom: 0,
+			left: 0,
+			right: 0,
+			zIndex: -3,
+			content: "''",
+			boxSizing: "border-box"
+		},
+		[`&dark .${highlightLineClass}::before`]: { background: rgba(dark.color.muted.caution.pressed.bg, .5) },
+		[`&light .${highlightLineClass}::before`]: { background: rgba(light.color.muted.caution.pressed.bg, .75) }
+	});
+}
+const highlightLine = (config) => {
+	let highlightTheme = createCodeMirrorTheme({ themeCtx: config.theme });
+	return [
+		lineHighlightField,
+		config.readOnly ? [] : lineNumbers({ domEventHandlers: { mousedown: (editorView, lineInfo) => {
+			let line = editorView.state.doc.lineAt(lineInfo.from), isHighlighted = !1;
+			return editorView.state.field(lineHighlightField).between(line.from, line.to, (_from, _to, value) => {
+				if (value) return isHighlighted = !0, !1;
+			}), isHighlighted ? editorView.dispatch({ effects: removeLineHighlight.of(line.from) }) : editorView.dispatch({ effects: addLineHighlight.of(line.from) }), config?.onHighlightChange && config.onHighlightChange(editorView.state.toJSON(highlightState).highlight), !0;
+		} } }),
+		highlightTheme
+	];
+};
+/**
+* Adds and removes highlights to the provided view using highlightLines
+* @param view
+* @param highlightLines
+*/
+function setHighlightedLines(view, highlightLines) {
+	let doc = view.state.doc, lines = doc.lines, allLineNumbers = Array.from({ length: lines }, (_x, i) => i + 1);
+	view.dispatch({ effects: allLineNumbers.map((lineNumber) => {
+		let line = doc.line(lineNumber);
+		return highlightLines?.includes(lineNumber) ? addLineHighlight.of(line.from) : removeLineHighlight.of(line.from);
+	}) });
+}
+function useThemeExtension() {
+	let $ = c(6), themeCtx = useRootTheme(), t0;
+	$[0] === themeCtx ? t0 = $[1] : (t0 = getBackwardsCompatibleTone(themeCtx), $[0] = themeCtx, $[1] = t0);
+	let fallbackTone = t0, t1 = themeCtx.theme.color.dark[fallbackTone], t2;
+	if ($[2] !== fallbackTone || $[3] !== t1 || $[4] !== themeCtx.theme.color.light) {
+		let dark = { color: t1 }, light = { color: themeCtx.theme.color.light[fallbackTone] };
+		t2 = EditorView.baseTheme({
+			"&.cm-editor": { height: "100%" },
+			"&.cm-editor.cm-focused": { outline: "none" },
+			"&.cm-editor.cm-focused .cm-matchingBracket": { backgroundColor: "transparent" },
+			"&.cm-editor.cm-focused .cm-nonmatchingBracket": { backgroundColor: "transparent" },
+			"&dark.cm-editor.cm-focused .cm-matchingBracket": { outline: `1px solid ${dark.color.base.border}` },
+			"&dark.cm-editor.cm-focused .cm-nonmatchingBracket": { outline: `1px solid ${dark.color.base.border}` },
+			"&light.cm-editor.cm-focused .cm-matchingBracket": { outline: `1px solid ${light.color.base.border}` },
+			"&light.cm-editor.cm-focused .cm-nonmatchingBracket": { outline: `1px solid ${light.color.base.border}` },
+			"& .cm-lineNumbers .cm-gutterElement": {
+				minWidth: "32px !important",
+				padding: "0 8px !important"
+			},
+			"& .cm-gutter.cm-foldGutter": { width: "0px !important" },
+			"&dark .cm-gutters": {
+				color: `${rgba(dark.color.card.enabled.code.fg, .5)} !important`,
+				borderRight: `1px solid ${rgba(dark.color.base.border, .5)}`
+			},
+			"&light .cm-gutters": {
+				color: `${rgba(light.color.card.enabled.code.fg, .5)} !important`,
+				borderRight: `1px solid ${rgba(light.color.base.border, .5)}`
+			}
+		}), $[2] = fallbackTone, $[3] = t1, $[4] = themeCtx.theme.color.light, $[5] = t2;
+	} else t2 = $[5];
+	return t2;
+}
+function useCodeMirrorTheme() {
+	let $ = c(19), theme = useTheme(), { code: codeFont } = theme.sanity.fonts, { base, card, dark, syntax } = theme.sanity.color, t0 = dark ? "dark" : "light", t1;
+	return $[0] !== base.focusRing || $[1] !== card.disabled.bg || $[2] !== card.disabled.code.fg || $[3] !== card.enabled.bg || $[4] !== card.enabled.code.fg || $[5] !== card.enabled.fg || $[6] !== codeFont.family || $[7] !== syntax.attrName || $[8] !== syntax.boolean || $[9] !== syntax.className || $[10] !== syntax.comment || $[11] !== syntax.function || $[12] !== syntax.keyword || $[13] !== syntax.number || $[14] !== syntax.operator || $[15] !== syntax.property || $[16] !== syntax.string || $[17] !== t0 ? (t1 = createTheme({
+		theme: t0,
+		settings: {
+			background: card.enabled.bg,
+			foreground: card.enabled.code.fg,
+			lineHighlight: card.enabled.bg,
+			fontFamily: codeFont.family,
+			caret: base.focusRing,
+			selection: rgba(base.focusRing, .2),
+			selectionMatch: rgba(base.focusRing, .4),
+			gutterBackground: card.disabled.bg,
+			gutterForeground: card.disabled.code.fg,
+			gutterActiveForeground: card.enabled.fg
+		},
+		styles: [
+			{
+				tag: [
+					tags.heading,
+					tags.heading2,
+					tags.heading3,
+					tags.heading4,
+					tags.heading5,
+					tags.heading6
+				],
+				color: card.enabled.fg
+			},
+			{
+				tag: tags.angleBracket,
+				color: card.enabled.code.fg
+			},
+			{
+				tag: tags.atom,
+				color: syntax.keyword
+			},
+			{
+				tag: tags.attributeName,
+				color: syntax.attrName
+			},
+			{
+				tag: tags.bool,
+				color: syntax.boolean
+			},
+			{
+				tag: tags.bracket,
+				color: card.enabled.code.fg
+			},
+			{
+				tag: tags.className,
+				color: syntax.className
+			},
+			{
+				tag: tags.comment,
+				color: syntax.comment
+			},
+			{
+				tag: tags.definition(tags.typeName),
+				color: syntax.function
+			},
+			{
+				tag: [
+					tags.definition(tags.variableName),
+					tags.function(tags.variableName),
+					tags.className,
+					tags.attributeName
+				],
+				color: syntax.function
+			},
+			{
+				tag: [tags.function(tags.propertyName), tags.propertyName],
+				color: syntax.function
+			},
+			{
+				tag: tags.keyword,
+				color: syntax.keyword
+			},
+			{
+				tag: tags.null,
+				color: syntax.number
+			},
+			{
+				tag: tags.number,
+				color: syntax.number
+			},
+			{
+				tag: tags.meta,
+				color: card.enabled.code.fg
+			},
+			{
+				tag: tags.operator,
+				color: syntax.operator
+			},
+			{
+				tag: tags.propertyName,
+				color: syntax.property
+			},
+			{
+				tag: [tags.string, tags.special(tags.brace)],
+				color: syntax.string
+			},
+			{
+				tag: tags.tagName,
+				color: syntax.className
+			},
+			{
+				tag: tags.typeName,
+				color: syntax.keyword
+			}
+		]
+	}), $[0] = base.focusRing, $[1] = card.disabled.bg, $[2] = card.disabled.code.fg, $[3] = card.enabled.bg, $[4] = card.enabled.code.fg, $[5] = card.enabled.fg, $[6] = codeFont.family, $[7] = syntax.attrName, $[8] = syntax.boolean, $[9] = syntax.className, $[10] = syntax.comment, $[11] = syntax.function, $[12] = syntax.keyword, $[13] = syntax.number, $[14] = syntax.operator, $[15] = syntax.property, $[16] = syntax.string, $[17] = t0, $[18] = t1) : t1 = $[18], t1;
+}
+function useFontSizeExtension(props) {
+	let $ = c(3), { fontSize: fontSizeProp } = props, { code: codeFont } = useTheme().sanity.fonts, { fontSize, lineHeight } = codeFont.sizes[fontSizeProp] || codeFont.sizes[2], t0;
+	return $[0] !== fontSize || $[1] !== lineHeight ? (t0 = EditorView.baseTheme({
+		"&": { fontSize: rem(fontSize) },
+		"& .cm-scroller": { lineHeight: `${lineHeight / fontSize} !important` }
+	}), $[0] = fontSize, $[1] = lineHeight, $[2] = t0) : t0 = $[2], t0;
+}
+/**
+* CodeMirrorProxy is a wrapper component around CodeMirror that we lazy load to reduce initial bundle size.
+*
+* It is also responsible for integrating any CodeMirror extensions.
+*/
+function CodeMirrorProxy(props) {
+	let $ = c(42), basicSetupProp, codeMirrorProps, highlightLines, languageMode, onHighlightChange, readOnly, ref, value;
+	$[0] === props ? (basicSetupProp = $[1], codeMirrorProps = $[2], highlightLines = $[3], languageMode = $[4], onHighlightChange = $[5], readOnly = $[6], ref = $[7], value = $[8]) : ({basicSetup: basicSetupProp, highlightLines, languageMode, onHighlightChange, readOnly, value, ref, ...codeMirrorProps} = props, $[0] = props, $[1] = basicSetupProp, $[2] = codeMirrorProps, $[3] = highlightLines, $[4] = languageMode, $[5] = onHighlightChange, $[6] = readOnly, $[7] = ref, $[8] = value);
+	let themeCtx = useRootTheme(), codeMirrorTheme = useCodeMirrorTheme(), [editorView, setEditorView] = useState(void 0), themeExtension = useThemeExtension(), t0;
+	$[9] === Symbol.for("react.memo_cache_sentinel") ? (t0 = { fontSize: 1 }, $[9] = t0) : t0 = $[9];
+	let fontSizeExtension = useFontSizeExtension(t0), languageExtension = useLanguageExtension(languageMode), t1;
+	$[10] !== onHighlightChange || $[11] !== readOnly || $[12] !== themeCtx ? (t1 = highlightLine({
+		onHighlightChange,
+		readOnly,
+		theme: themeCtx
+	}), $[10] = onHighlightChange, $[11] = readOnly, $[12] = themeCtx, $[13] = t1) : t1 = $[13];
+	let highlightLineExtension = t1, t2;
+	bb0: {
+		let t3;
+		$[14] !== fontSizeExtension || $[15] !== highlightLineExtension || $[16] !== themeExtension ? (t3 = [
+			themeExtension,
+			fontSizeExtension,
+			highlightLineExtension,
+			EditorView.lineWrapping
+		], $[14] = fontSizeExtension, $[15] = highlightLineExtension, $[16] = themeExtension, $[17] = t3) : t3 = $[17];
+		let baseExtensions = t3;
+		if (languageExtension) {
+			let t4;
+			$[18] !== baseExtensions || $[19] !== languageExtension ? (t4 = [...baseExtensions, languageExtension], $[18] = baseExtensions, $[19] = languageExtension, $[20] = t4) : t4 = $[20], t2 = t4;
+			break bb0;
+		}
+		t2 = baseExtensions;
+	}
+	let extensions = t2, t3;
+	$[21] !== editorView || $[22] !== highlightLines ? (t3 = () => {
+		editorView && setHighlightedLines(editorView, highlightLines ?? []);
+	}, $[21] = editorView, $[22] = highlightLines, $[23] = t3) : t3 = $[23];
+	let t4;
+	$[24] !== editorView || $[25] !== highlightLines || $[26] !== value ? (t4 = [
+		editorView,
+		highlightLines,
+		value
+	], $[24] = editorView, $[25] = highlightLines, $[26] = value, $[27] = t4) : t4 = $[27], useEffect(t3, t4);
+	let t5;
+	$[28] !== highlightLines || $[29] !== value ? (t5 = () => ({
+		json: {
+			doc: value ?? "",
+			selection: {
+				main: 0,
+				ranges: [{
+					anchor: 0,
+					head: 0
+				}]
+			},
+			highlight: highlightLines ?? []
+		},
+		fields: highlightState
+	}), $[28] = highlightLines, $[29] = value, $[30] = t5) : t5 = $[30];
+	let [initialState] = useState(t5), t6;
+	$[31] === Symbol.for("react.memo_cache_sentinel") ? (t6 = (view) => {
+		setEditorView(view);
+	}, $[31] = t6) : t6 = $[31];
+	let handleCreateEditor = t6, t7;
+	$[32] === basicSetupProp ? t7 = $[33] : (t7 = basicSetupProp ?? { highlightActiveLine: !1 }, $[32] = basicSetupProp, $[33] = t7);
+	let basicSetup = t7, t8;
+	return $[34] !== basicSetup || $[35] !== codeMirrorProps || $[36] !== codeMirrorTheme || $[37] !== extensions || $[38] !== initialState || $[39] !== ref || $[40] !== value ? (t8 = /* @__PURE__ */ jsx(CodeMirror, {
+		...codeMirrorProps,
+		value,
+		ref,
+		extensions,
+		theme: codeMirrorTheme,
+		onCreateEditor: handleCreateEditor,
+		initialState,
+		basicSetup
+	}), $[34] = basicSetup, $[35] = codeMirrorProps, $[36] = codeMirrorTheme, $[37] = extensions, $[38] = initialState, $[39] = ref, $[40] = value, $[41] = t8) : t8 = $[41], t8;
+}
+function useLanguageExtension(mode) {
+	let $ = c(6), codeConfig = useContext(CodeInputConfigContext), [languageExtension, setLanguageExtension] = useState(), t0;
+	$[0] !== codeConfig?.codeModes || $[1] !== mode ? (t0 = () => {
+		let codeMode = [...codeConfig?.codeModes ?? [], ...defaultCodeModes].find((m) => m.name === mode);
+		codeMode?.loader || console.warn(`Found no codeMode for language mode ${mode}, syntax highlighting will be disabled.`);
+		let active = !0;
+		return Promise.resolve(codeMode?.loader()).then((extension) => {
+			active && setLanguageExtension(extension);
+		}).catch((e) => {
+			console.error(`Failed to load language mode ${mode}`, e), active && setLanguageExtension(void 0);
+		}), () => {
+			active = !1;
+		};
+	}, $[0] = codeConfig?.codeModes, $[1] = mode, $[2] = t0) : t0 = $[2];
+	let t1;
+	return $[3] !== codeConfig || $[4] !== mode ? (t1 = [mode, codeConfig], $[3] = codeConfig, $[4] = mode, $[5] = t1) : t1 = $[5], useEffect(t0, t1), languageExtension;
+}
+export { CodeMirrorProxy as default };
+
+//# sourceMappingURL=CodeMirrorProxy.js.map
\ No newline at end of file