@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