@alauda/react-code-editor 0.1.0-next.20260812.1786527360 → 0.1.0-next.20260903.1788425608
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
CHANGED
|
@@ -10,6 +10,10 @@
|
|
|
10
10
|
Console 业务 plugin 直接消费本包;`console-ui` 可以提供编辑器外围的页面、表单和反馈组件,但不拥有
|
|
11
11
|
Monaco、worker、language service 或 Code Editor 公共 API。
|
|
12
12
|
|
|
13
|
+
编辑器主题会优先读取 Host 写入的 `html[data-aui-theme-mode]`(`light`、`dark` 或 `system`),并在
|
|
14
|
+
`system` 下跟随 `prefers-color-scheme`。没有该 attribute 时,编辑器回退到 MUI `ThemeProvider` 的
|
|
15
|
+
`palette.mode`,因此也可独立运行于普通 React 应用。
|
|
16
|
+
|
|
13
17
|
独立拆包依据、OCP Code Editor 对比和最终选型见
|
|
14
18
|
[Code Editor 独立拆包与 OCP 调研结论](docs/research/code-editor-package-and-ocp-evaluation.md)。
|
|
15
19
|
|
|
@@ -6,7 +6,7 @@ import IconButton from "@mui/material/IconButton";
|
|
|
6
6
|
import Tooltip from "@mui/material/Tooltip";
|
|
7
7
|
import Typography from "@mui/material/Typography";
|
|
8
8
|
import { useTheme } from "@mui/material/styles";
|
|
9
|
-
import { forwardRef, useCallback, useEffect, useId, useImperativeHandle, useRef, useState } from "react";
|
|
9
|
+
import { forwardRef, useCallback, useEffect, useId, useImperativeHandle, useRef, useState, useSyncExternalStore } from "react";
|
|
10
10
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
11
11
|
//#region src/monacoEnvironment.ts
|
|
12
12
|
function configureMonacoEnvironment() {
|
|
@@ -77,6 +77,52 @@ function acquireModelOwnership(monaco, ownerId, modelPath, language) {
|
|
|
77
77
|
};
|
|
78
78
|
}
|
|
79
79
|
//#endregion
|
|
80
|
+
//#region src/themeAppearance.ts
|
|
81
|
+
const systemDarkQuery = "(prefers-color-scheme: dark)";
|
|
82
|
+
function hostThemeSelection() {
|
|
83
|
+
if (typeof document === "undefined") return void 0;
|
|
84
|
+
const value = document.documentElement.dataset.auiThemeMode;
|
|
85
|
+
return value === "light" || value === "dark" || value === "system" ? value : void 0;
|
|
86
|
+
}
|
|
87
|
+
function prefersDark() {
|
|
88
|
+
return typeof window !== "undefined" && typeof window.matchMedia === "function" && window.matchMedia(systemDarkQuery).matches;
|
|
89
|
+
}
|
|
90
|
+
function resolveCodeEditorThemeMode(selection, fallback, systemPrefersDark) {
|
|
91
|
+
if (selection === "dark") return "dark";
|
|
92
|
+
if (selection === "light") return "light";
|
|
93
|
+
if (selection === "system") return systemPrefersDark ? "dark" : "light";
|
|
94
|
+
return fallback;
|
|
95
|
+
}
|
|
96
|
+
function readEffectiveThemeMode(fallback) {
|
|
97
|
+
return resolveCodeEditorThemeMode(hostThemeSelection(), fallback, prefersDark());
|
|
98
|
+
}
|
|
99
|
+
function subscribeToThemeAppearance(listener) {
|
|
100
|
+
if (typeof document === "undefined") return () => void 0;
|
|
101
|
+
const root = document.documentElement;
|
|
102
|
+
const observer = typeof MutationObserver === "undefined" ? void 0 : new MutationObserver((records) => {
|
|
103
|
+
if (records.some((record) => record.attributeName === "data-aui-theme-mode")) listener();
|
|
104
|
+
});
|
|
105
|
+
observer?.observe(root, {
|
|
106
|
+
attributes: true,
|
|
107
|
+
attributeFilter: ["data-aui-theme-mode"]
|
|
108
|
+
});
|
|
109
|
+
const mediaQuery = typeof window !== "undefined" && typeof window.matchMedia === "function" ? window.matchMedia(systemDarkQuery) : void 0;
|
|
110
|
+
const mediaListener = () => listener();
|
|
111
|
+
mediaQuery?.addEventListener("change", mediaListener);
|
|
112
|
+
return () => {
|
|
113
|
+
observer?.disconnect();
|
|
114
|
+
mediaQuery?.removeEventListener("change", mediaListener);
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Reads the Host's CSS-backed appearance while retaining MUI compatibility for
|
|
119
|
+
* standalone consumers that do not publish data-aui-theme-mode.
|
|
120
|
+
*/
|
|
121
|
+
function useCodeEditorThemeMode() {
|
|
122
|
+
const fallback = useTheme().palette.mode;
|
|
123
|
+
return useSyncExternalStore(subscribeToThemeAppearance, () => readEffectiveThemeMode(fallback), () => fallback);
|
|
124
|
+
}
|
|
125
|
+
//#endregion
|
|
80
126
|
//#region src/CodeEditor.tsx
|
|
81
127
|
const defaultLabels = {
|
|
82
128
|
copy: "Copy",
|
|
@@ -139,6 +185,7 @@ function mapDiagnostics(markers, monaco) {
|
|
|
139
185
|
}
|
|
140
186
|
const CodeEditor = forwardRef(function CodeEditor({ value, onChange, onBlur, language, modelPath, ariaLabel, readOnly = false, disabled = false, height = 400, actions = defaultActions, labels: labelOverrides, error, onDiagnostics, toolbarStart, toolbarEnd }, ref) {
|
|
141
187
|
const theme = useTheme();
|
|
188
|
+
const appearanceMode = useCodeEditorThemeMode();
|
|
142
189
|
const ownerId = useId();
|
|
143
190
|
const editorRef = useRef(null);
|
|
144
191
|
const disposablesRef = useRef([]);
|
|
@@ -352,7 +399,7 @@ const CodeEditor = forwardRef(function CodeEditor({ value, onChange, onBlur, lan
|
|
|
352
399
|
height: "100%",
|
|
353
400
|
language,
|
|
354
401
|
path: modelPath,
|
|
355
|
-
theme:
|
|
402
|
+
theme: appearanceMode === "dark" ? "vs-dark" : "vs",
|
|
356
403
|
defaultValue: value,
|
|
357
404
|
keepCurrentModel: true,
|
|
358
405
|
onMount,
|
|
@@ -426,6 +473,6 @@ const CodeEditor = forwardRef(function CodeEditor({ value, onChange, onBlur, lan
|
|
|
426
473
|
});
|
|
427
474
|
});
|
|
428
475
|
//#endregion
|
|
429
|
-
export { getSharedRuntimeState as i,
|
|
476
|
+
export { getSharedRuntimeState as a, loadMonacoRuntime as i, useCodeEditorThemeMode as n, acquireModelOwnership as r, CodeEditor as t };
|
|
430
477
|
|
|
431
|
-
//# sourceMappingURL=CodeEditor-
|
|
478
|
+
//# sourceMappingURL=CodeEditor-BI8PAcmS.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CodeEditor-BI8PAcmS.js","names":[],"sources":["../../../src/monacoEnvironment.ts","../../../src/runtime/runtimeState.ts","../../../src/runtime/loadMonaco.ts","../../../src/runtime/modelOwnership.ts","../../../src/themeAppearance.ts","../../../src/CodeEditor.tsx"],"sourcesContent":["declare global {\n interface Window {\n MonacoEnvironment: {\n getWorker: (_moduleId: string, label: string) => Worker;\n };\n }\n}\n\nexport function configureMonacoEnvironment(): void {\n if (typeof window === 'undefined') return;\n const existing = Reflect.get(window, 'MonacoEnvironment') as\n | { readonly getWorker?: unknown }\n | undefined;\n if (typeof existing?.getWorker === 'function') return;\n\n window.MonacoEnvironment = {\n getWorker: (_moduleId, label) => {\n if (label === 'yaml') {\n return new Worker(new URL('./yaml/yaml.worker.js', import.meta.url));\n }\n if (label === 'json') {\n return new Worker(new URL(\n 'monaco-editor/esm/vs/language/json/json.worker.js',\n import.meta.url,\n ));\n }\n return new Worker(new URL(\n 'monaco-editor/esm/vs/editor/editor.worker.js',\n import.meta.url,\n ));\n },\n };\n}\n","import type * as Monaco from 'monaco-editor/esm/vs/editor/editor.main.js';\n\nexport interface SharedCodeEditorRuntimeState {\n monaco?: typeof Monaco;\n monacoPromise?: Promise<typeof Monaco>;\n models?: Map<string, unknown>;\n yaml?: unknown;\n}\n\nconst runtimeKey = Symbol.for('alauda.react-code-editor.runtime');\n\nexport function getSharedRuntimeState(): SharedCodeEditorRuntimeState {\n const target = globalThis as typeof globalThis & {\n [runtimeKey]?: SharedCodeEditorRuntimeState;\n };\n target[runtimeKey] ??= {};\n return target[runtimeKey];\n}\n","import { loader } from '@monaco-editor/react';\nimport type * as Monaco from 'monaco-editor/esm/vs/editor/editor.main.js';\n\nimport { configureMonacoEnvironment } from '../monacoEnvironment';\nimport { getSharedRuntimeState } from './runtimeState';\n\nexport function loadMonacoRuntime(): Promise<typeof Monaco> {\n const runtime = getSharedRuntimeState();\n if (runtime.monacoPromise) return runtime.monacoPromise;\n const promise = (async () => {\n configureMonacoEnvironment();\n const monaco = await import(\n 'monaco-editor/esm/vs/editor/editor.main.js'\n );\n loader.config({ monaco });\n runtime.monaco = monaco;\n return monaco;\n })();\n runtime.monacoPromise = promise;\n void promise.catch(() => {\n if (runtime.monacoPromise === promise) runtime.monacoPromise = undefined;\n });\n return promise;\n}\n","import type * as Monaco from 'monaco-editor/esm/vs/editor/editor.main.js';\n\nimport { getSharedRuntimeState } from './runtimeState';\n\ninterface ModelOwnership {\n readonly language: string;\n readonly owners: Set<string>;\n readonly uri: Monaco.Uri;\n readonly ownedByPackage: boolean;\n}\n\nfunction ownershipRegistry(): Map<string, ModelOwnership> {\n const runtime = getSharedRuntimeState();\n runtime.models ??= new Map();\n return runtime.models as Map<string, ModelOwnership>;\n}\n\nexport function acquireModelOwnership(\n monaco: typeof Monaco,\n ownerId: string,\n modelPath: string,\n language: string,\n): () => void {\n const registry = ownershipRegistry();\n const existing = registry.get(modelPath);\n if (existing && existing.language !== language) {\n throw new Error(\n `Conflicting editor languages for ${modelPath}: `\n + `${existing.language} and ${language}`,\n );\n }\n\n const ownership = existing ?? (() => {\n const uri = monaco.Uri.parse(modelPath);\n return {\n language,\n owners: new Set<string>(),\n uri,\n ownedByPackage: !monaco.editor.getModel(uri),\n } satisfies ModelOwnership;\n })();\n ownership.owners.add(ownerId);\n registry.set(modelPath, ownership);\n\n let active = true;\n return () => {\n if (!active) return;\n active = false;\n ownership.owners.delete(ownerId);\n if (ownership.owners.size > 0) return;\n registry.delete(modelPath);\n if (ownership.ownedByPackage) {\n monaco.editor.getModel(ownership.uri)?.dispose();\n }\n };\n}\n","import { useSyncExternalStore } from 'react';\nimport { useTheme, type PaletteMode } from '@mui/material/styles';\n\nexport type CodeEditorThemeMode = PaletteMode;\nexport type HostThemeSelection = 'light' | 'dark' | 'system';\n\nconst systemDarkQuery = '(prefers-color-scheme: dark)';\n\nfunction hostThemeSelection(): HostThemeSelection | undefined {\n if (typeof document === 'undefined') return undefined;\n const value = document.documentElement.dataset.auiThemeMode;\n return value === 'light' || value === 'dark' || value === 'system'\n ? value\n : undefined;\n}\n\nfunction prefersDark(): boolean {\n return typeof window !== 'undefined'\n && typeof window.matchMedia === 'function'\n && window.matchMedia(systemDarkQuery).matches;\n}\n\nexport function resolveCodeEditorThemeMode(\n selection: HostThemeSelection | undefined,\n fallback: PaletteMode,\n systemPrefersDark: boolean,\n): CodeEditorThemeMode {\n if (selection === 'dark') return 'dark';\n if (selection === 'light') return 'light';\n if (selection === 'system') return systemPrefersDark ? 'dark' : 'light';\n return fallback;\n}\n\nfunction readEffectiveThemeMode(fallback: PaletteMode): CodeEditorThemeMode {\n return resolveCodeEditorThemeMode(hostThemeSelection(), fallback, prefersDark());\n}\n\nfunction subscribeToThemeAppearance(listener: () => void): () => void {\n if (typeof document === 'undefined') return () => undefined;\n\n const root = document.documentElement;\n const observer = typeof MutationObserver === 'undefined'\n ? undefined\n : new MutationObserver(records => {\n if (records.some(record => record.attributeName === 'data-aui-theme-mode')) {\n listener();\n }\n });\n observer?.observe(root, { attributes: true, attributeFilter: ['data-aui-theme-mode'] });\n\n const mediaQuery = typeof window !== 'undefined' && typeof window.matchMedia === 'function'\n ? window.matchMedia(systemDarkQuery)\n : undefined;\n const mediaListener = () => listener();\n mediaQuery?.addEventListener('change', mediaListener);\n\n return () => {\n observer?.disconnect();\n mediaQuery?.removeEventListener('change', mediaListener);\n };\n}\n\n/**\n * Reads the Host's CSS-backed appearance while retaining MUI compatibility for\n * standalone consumers that do not publish data-aui-theme-mode.\n */\nexport function useCodeEditorThemeMode(): CodeEditorThemeMode {\n const theme = useTheme();\n const fallback = theme.palette.mode;\n return useSyncExternalStore(\n subscribeToThemeAppearance,\n () => readEffectiveThemeMode(fallback),\n () => fallback,\n );\n}\n","import Editor, { type OnMount } from '@monaco-editor/react';\nimport Alert from '@mui/material/Alert';\nimport Box from '@mui/material/Box';\nimport CircularProgress from '@mui/material/CircularProgress';\nimport IconButton from '@mui/material/IconButton';\nimport Tooltip from '@mui/material/Tooltip';\nimport Typography from '@mui/material/Typography';\nimport { useTheme } from '@mui/material/styles';\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useId,\n useImperativeHandle,\n useRef,\n useState,\n type FC,\n type ReactNode,\n} from 'react';\nimport type * as Monaco from 'monaco-editor/esm/vs/editor/editor.main.js';\n\nimport { loadMonacoRuntime } from './runtime/loadMonaco';\nimport { acquireModelOwnership } from './runtime/modelOwnership';\nimport { useCodeEditorThemeMode } from './themeAppearance';\n\nexport type CodeEditorLanguage =\n | 'json'\n | 'markdown'\n | 'plaintext'\n | 'yaml';\n\nexport type CodeEditorAction =\n | 'copy'\n | 'find'\n | 'format'\n | 'fullscreen'\n | 'redo'\n | 'undo';\n\nexport type CodeEditorDiagnosticSeverity =\n | 'error'\n | 'warning'\n | 'info'\n | 'hint';\n\nexport interface CodeEditorDiagnostic {\n readonly severity: CodeEditorDiagnosticSeverity;\n readonly message: string;\n readonly line: number;\n readonly column: number;\n readonly endLine: number;\n readonly endColumn: number;\n readonly code?: string;\n}\n\nexport interface CodeEditorLabels {\n readonly copy: string;\n readonly copied: string;\n readonly copyFailed: string;\n readonly find: string;\n readonly format: string;\n readonly fullscreen: string;\n readonly exitFullscreen: string;\n readonly undo: string;\n readonly redo: string;\n readonly loading: string;\n readonly valid: string;\n readonly errors: (count: number) => string;\n readonly lineColumn: (line: number, column: number) => string;\n}\n\nexport interface CodeEditorHandle {\n focus(): void;\n find(): Promise<void>;\n format(): Promise<void>;\n undo(): void;\n redo(): void;\n validate(): Promise<readonly CodeEditorDiagnostic[]>;\n}\n\nexport interface CodeEditorProps {\n readonly value: string;\n readonly onChange: (value: string) => void;\n readonly onBlur?: () => void;\n readonly language: CodeEditorLanguage;\n readonly modelPath: string;\n readonly ariaLabel: string;\n readonly readOnly?: boolean;\n readonly disabled?: boolean;\n readonly height?: number | string;\n readonly actions?: readonly CodeEditorAction[];\n readonly labels?: Partial<CodeEditorLabels>;\n readonly error?: string | null;\n readonly onDiagnostics?: (\n diagnostics: readonly CodeEditorDiagnostic[],\n ) => void;\n readonly toolbarStart?: ReactNode;\n readonly toolbarEnd?: ReactNode;\n}\n\nconst defaultLabels: CodeEditorLabels = {\n copy: 'Copy',\n copied: 'Copied',\n copyFailed: 'Copy failed',\n find: 'Search',\n format: 'Format',\n fullscreen: 'Enter fullscreen',\n exitFullscreen: 'Exit fullscreen',\n undo: 'Undo',\n redo: 'Redo',\n loading: 'Loading editor',\n valid: 'Validation passed',\n errors: count => `${count} validation error${count === 1 ? '' : 's'}`,\n lineColumn: (line, column) => `Ln ${line}, Col ${column}`,\n};\n\nconst defaultActions: readonly CodeEditorAction[] = [\n 'find',\n 'copy',\n 'format',\n 'undo',\n 'redo',\n 'fullscreen',\n];\n\nconst paths = {\n copy: 'M16 1H4a2 2 0 0 0-2 2v14h2V3h12zm3 4H8a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h11a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2m0 16H8V7h11z',\n find: 'M9.5 3a6.5 6.5 0 1 0 3.98 11.64L19.85 21 21 19.85l-6.36-6.37A6.5 6.5 0 0 0 9.5 3m0 2a4.5 4.5 0 1 1 0 9 4.5 4.5 0 0 1 0-9',\n format: 'M3 5h18v2H3zm0 6h12v2H3zm0 6h18v2H3z',\n fullscreen: 'M4 4h6v2H6v4H4zm10 0h6v6h-2V6h-4zM4 14h2v4h4v2H4zm14 0h2v6h-6v-2h4z',\n redo: 'M15 6V3l5 5-5 5v-3c-4 0-7 1-9 5 1-6 4-9 9-9',\n undo: 'M9 6V3L4 8l5 5v-3c4 0 7 1 9 5-1-6-4-9-9-9',\n} satisfies Record<CodeEditorAction, string>;\n\nconst ToolIcon: FC<{ readonly path: string }> = ({ path }) => (\n <Box\n component=\"svg\"\n aria-hidden=\"true\"\n viewBox=\"0 0 24 24\"\n sx={{ width: 20, height: 20, fill: 'currentColor' }}\n >\n <path d={path} />\n </Box>\n);\n\nfunction markerSeverity(\n marker: Monaco.editor.IMarker,\n monaco: typeof Monaco,\n): CodeEditorDiagnosticSeverity {\n if (marker.severity === monaco.MarkerSeverity.Error) return 'error';\n if (marker.severity === monaco.MarkerSeverity.Warning) return 'warning';\n if (marker.severity === monaco.MarkerSeverity.Info) return 'info';\n return 'hint';\n}\n\nfunction mapDiagnostics(\n markers: readonly Monaco.editor.IMarker[],\n monaco: typeof Monaco,\n): readonly CodeEditorDiagnostic[] {\n return markers.map(marker => ({\n severity: markerSeverity(marker, monaco),\n message: marker.message,\n line: marker.startLineNumber,\n column: marker.startColumn,\n endLine: marker.endLineNumber,\n endColumn: marker.endColumn,\n ...(marker.code === undefined ? {} : { code: String(marker.code) }),\n }));\n}\n\nexport const CodeEditor = forwardRef<CodeEditorHandle, CodeEditorProps>(\n function CodeEditor({\n value,\n onChange,\n onBlur,\n language,\n modelPath,\n ariaLabel,\n readOnly = false,\n disabled = false,\n height = 400,\n actions = defaultActions,\n labels: labelOverrides,\n error,\n onDiagnostics,\n toolbarStart,\n toolbarEnd,\n }, ref) {\n const theme = useTheme();\n const appearanceMode = useCodeEditorThemeMode();\n const ownerId = useId();\n const editorRef = useRef<Monaco.editor.IStandaloneCodeEditor | null>(null);\n const disposablesRef = useRef<Monaco.IDisposable[]>([]);\n const diagnosticsRef = useRef<readonly CodeEditorDiagnostic[]>([]);\n const externalValueSyncRef = useRef(false);\n const pendingLocalValuesRef = useRef<string[]>([]);\n const modelPathRef = useRef(modelPath);\n const valueRef = useRef(value);\n const [monaco, setMonaco] = useState<typeof Monaco | null>(null);\n const [runtimeError, setRuntimeError] = useState<string>();\n const [position, setPosition] = useState({ lineNumber: 1, column: 1 });\n const [diagnosticCount, setDiagnosticCount] = useState(0);\n const [copyState, setCopyState] = useState<'idle' | 'copied' | 'failed'>('idle');\n const [fullscreen, setFullscreen] = useState(false);\n const labels = { ...defaultLabels, ...labelOverrides };\n valueRef.current = value;\n\n const synchronizeExternalValue = useCallback((\n editor: Monaco.editor.IStandaloneCodeEditor,\n nextValue: string,\n ): void => {\n const model = editor.getModel();\n if (!model) return;\n\n const pending = pendingLocalValuesRef.current;\n const acknowledgedIndex = pending.lastIndexOf(nextValue);\n if (acknowledgedIndex >= 0) {\n pending.splice(0, acknowledgedIndex + 1);\n return;\n }\n if (model.getValue() === nextValue) return;\n\n pending.length = 0;\n const selections = editor.getSelections();\n const scrollPosition = {\n scrollLeft: editor.getScrollLeft(),\n scrollTop: editor.getScrollTop(),\n };\n externalValueSyncRef.current = true;\n try {\n editor.pushUndoStop();\n const applied = editor.executeEdits(\n 'alauda.react-code-editor.external-value',\n [{\n range: model.getFullModelRange(),\n text: nextValue,\n forceMoveMarkers: true,\n }],\n selections ?? undefined,\n );\n if (!applied) model.setValue(nextValue);\n editor.pushUndoStop();\n if (selections) editor.setSelections(selections);\n editor.setScrollPosition(scrollPosition);\n } finally {\n externalValueSyncRef.current = false;\n }\n }, []);\n\n useEffect(() => {\n let active = true;\n let release: (() => void) | undefined;\n setMonaco(null);\n setRuntimeError(undefined);\n void loadMonacoRuntime()\n .then(instance => {\n if (!active) return;\n release = acquireModelOwnership(\n instance,\n ownerId,\n modelPath,\n language,\n );\n if (active) setMonaco(instance);\n else release();\n })\n .catch(errorValue => {\n if (active) {\n setRuntimeError(\n errorValue instanceof Error\n ? errorValue.message\n : String(errorValue),\n );\n }\n });\n return () => {\n active = false;\n release?.();\n };\n }, [language, modelPath, ownerId]);\n\n useEffect(() => () => {\n disposablesRef.current.forEach(disposable => disposable.dispose());\n disposablesRef.current = [];\n editorRef.current = null;\n }, []);\n\n useEffect(() => {\n if (modelPathRef.current !== modelPath) {\n modelPathRef.current = modelPath;\n pendingLocalValuesRef.current = [];\n }\n const editor = editorRef.current;\n if (editor) synchronizeExternalValue(editor, value);\n }, [modelPath, synchronizeExternalValue, value]);\n\n const find = async (): Promise<void> => {\n editorRef.current?.focus();\n await editorRef.current?.getAction('actions.find')?.run();\n };\n const format = async (): Promise<void> => {\n editorRef.current?.focus();\n await editorRef.current?.getAction('editor.action.formatDocument')?.run();\n };\n\n useImperativeHandle(ref, () => ({\n focus: () => editorRef.current?.focus(),\n find,\n format,\n undo: () => editorRef.current?.trigger('code-editor', 'undo', null),\n redo: () => editorRef.current?.trigger('code-editor', 'redo', null),\n validate: async () => diagnosticsRef.current,\n }));\n\n const onMount: OnMount = editor => {\n editorRef.current = editor;\n synchronizeExternalValue(editor, valueRef.current);\n disposablesRef.current.forEach(disposable => disposable.dispose());\n disposablesRef.current = [\n editor.onDidChangeCursorPosition(event => setPosition(event.position)),\n editor.onDidBlurEditorText(() => onBlur?.()),\n ];\n const currentPosition = editor.getPosition();\n if (currentPosition) setPosition(currentPosition);\n };\n\n const copy = async (): Promise<void> => {\n try {\n await navigator.clipboard.writeText(\n editorRef.current?.getModel()?.getValue() ?? valueRef.current,\n );\n setCopyState('copied');\n } catch {\n setCopyState('failed');\n }\n };\n\n const runAction = (action: CodeEditorAction): void => {\n if (action === 'find') void find();\n if (action === 'copy') void copy();\n if (action === 'format') void format();\n if (action === 'undo') {\n editorRef.current?.trigger('code-editor', 'undo', null);\n }\n if (action === 'redo') {\n editorRef.current?.trigger('code-editor', 'redo', null);\n }\n if (action === 'fullscreen') setFullscreen(current => !current);\n };\n\n const actionLabel = (action: CodeEditorAction): string => {\n if (action === 'copy' && copyState === 'copied') return labels.copied;\n if (action === 'copy' && copyState === 'failed') return labels.copyFailed;\n if (action === 'fullscreen' && fullscreen) return labels.exitFullscreen;\n return labels[action];\n };\n\n if (runtimeError) {\n return <Alert severity=\"error\" role=\"alert\">{runtimeError}</Alert>;\n }\n\n if (!monaco) {\n return (\n <Box\n role=\"status\"\n aria-label={labels.loading}\n sx={{ display: 'grid', height, minHeight: 160, placeItems: 'center' }}\n >\n <CircularProgress aria-hidden=\"true\" />\n </Box>\n );\n }\n\n return (\n <Box\n role=\"region\"\n aria-label={`${ariaLabel} editor`}\n sx={{\n position: fullscreen ? 'fixed' : 'relative',\n inset: fullscreen ? 0 : undefined,\n zIndex: fullscreen ? theme.zIndex.modal : undefined,\n display: 'flex',\n flexDirection: 'column',\n height: fullscreen ? '100dvh' : height,\n minHeight: 160,\n overflow: 'hidden',\n bgcolor: 'background.paper',\n border: 1,\n borderColor: error ? 'error.main' : 'divider',\n borderRadius: fullscreen ? 0 : 1,\n }}\n >\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n gap: 1,\n minHeight: 40,\n px: 1,\n borderBottom: 1,\n borderColor: 'divider',\n }}\n >\n {toolbarStart}\n <Box sx={{ flex: 1 }} />\n {actions.map(action => (\n <Tooltip key={action} title={actionLabel(action)}>\n <span>\n <IconButton\n aria-label={actionLabel(action)}\n aria-pressed={action === 'fullscreen' ? fullscreen : undefined}\n disabled={disabled || (\n readOnly && ['format', 'undo', 'redo'].includes(action)\n )}\n size=\"small\"\n onClick={() => runAction(action)}\n >\n <ToolIcon path={paths[action]} />\n </IconButton>\n </span>\n </Tooltip>\n ))}\n {toolbarEnd}\n </Box>\n <Box sx={{ flex: '1 1 auto', minHeight: 0, overflow: 'hidden' }}>\n <Editor\n height=\"100%\"\n language={language}\n path={modelPath}\n theme={appearanceMode === 'dark' ? 'vs-dark' : 'vs'}\n defaultValue={value}\n keepCurrentModel\n onMount={onMount}\n onChange={nextValue => {\n if (externalValueSyncRef.current) return;\n const normalized = nextValue ?? '';\n const pending = pendingLocalValuesRef.current;\n if (pending.at(-1) !== normalized) {\n pending.push(normalized);\n if (pending.length > 64) {\n pending.splice(0, pending.length - 64);\n }\n }\n onChange(normalized);\n }}\n onValidate={markers => {\n const diagnostics = mapDiagnostics(markers, monaco);\n diagnosticsRef.current = diagnostics;\n setDiagnosticCount(diagnostics.filter(item => (\n item.severity === 'error'\n )).length);\n onDiagnostics?.(diagnostics);\n }}\n options={{\n ariaLabel,\n automaticLayout: true,\n bracketPairColorization: { enabled: true },\n folding: true,\n fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace',\n fontSize: 13,\n formatOnPaste: true,\n insertSpaces: true,\n lineHeight: 22,\n minimap: { enabled: false },\n padding: { top: 12, bottom: 12 },\n readOnly: readOnly || disabled,\n renderValidationDecorations: 'on',\n scrollBeyondLastLine: false,\n tabSize: 2,\n }}\n />\n </Box>\n <Box\n aria-live=\"polite\"\n sx={{\n display: 'flex',\n justifyContent: 'space-between',\n gap: 2,\n minHeight: 28,\n px: 1.5,\n py: 0.5,\n borderTop: 1,\n borderColor: 'divider',\n }}\n >\n <Typography variant=\"caption\">{language.toUpperCase()}</Typography>\n <Typography\n variant=\"caption\"\n color={error || diagnosticCount ? 'error' : 'text.secondary'}\n >\n {error ?? (\n diagnosticCount ? labels.errors(diagnosticCount) : labels.valid\n )}\n </Typography>\n <Typography variant=\"caption\">\n {labels.lineColumn(position.lineNumber, position.column)}\n </Typography>\n </Box>\n </Box>\n );\n },\n);\n"],"mappings":"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"}
|
package/index.js
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
import { n as
|
|
1
|
+
import { i as loadMonacoRuntime, n as useCodeEditorThemeMode, r as acquireModelOwnership, t as CodeEditor } from "./chunks/CodeEditor-BI8PAcmS.js";
|
|
2
2
|
import { DiffEditor } from "@monaco-editor/react";
|
|
3
3
|
import Alert from "@mui/material/Alert";
|
|
4
4
|
import Box from "@mui/material/Box";
|
|
5
5
|
import CircularProgress from "@mui/material/CircularProgress";
|
|
6
|
-
import { useTheme } from "@mui/material/styles";
|
|
7
6
|
import { useEffect, useId, useRef, useState } from "react";
|
|
8
7
|
import { jsx } from "react/jsx-runtime";
|
|
9
8
|
//#region src/DiffCodeEditor.tsx
|
|
10
9
|
function DiffCodeEditor({ originalValue, value, onChange, language, originalModelPath, modelPath, ariaLabel, readOnly = false, height = 400 }) {
|
|
11
|
-
const
|
|
10
|
+
const appearanceMode = useCodeEditorThemeMode();
|
|
12
11
|
const ownerId = useId();
|
|
13
12
|
const contentListenerRef = useRef(null);
|
|
14
13
|
const valueRef = useRef(value);
|
|
@@ -74,7 +73,7 @@ function DiffCodeEditor({ originalValue, value, onChange, language, originalMode
|
|
|
74
73
|
modified: value,
|
|
75
74
|
originalModelPath,
|
|
76
75
|
modifiedModelPath: modelPath,
|
|
77
|
-
theme:
|
|
76
|
+
theme: appearanceMode === "dark" ? "vs-dark" : "vs",
|
|
78
77
|
keepCurrentOriginalModel: true,
|
|
79
78
|
keepCurrentModifiedModel: true,
|
|
80
79
|
onMount: (editor) => {
|
package/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/DiffCodeEditor.tsx"],"sourcesContent":["import { DiffEditor } from '@monaco-editor/react';\nimport Alert from '@mui/material/Alert';\nimport Box from '@mui/material/Box';\nimport CircularProgress from '@mui/material/CircularProgress';\nimport {
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/DiffCodeEditor.tsx"],"sourcesContent":["import { DiffEditor } from '@monaco-editor/react';\nimport Alert from '@mui/material/Alert';\nimport Box from '@mui/material/Box';\nimport CircularProgress from '@mui/material/CircularProgress';\nimport { useEffect, useId, useRef, useState } from 'react';\nimport type * as Monaco from 'monaco-editor/esm/vs/editor/editor.main.js';\n\nimport type { CodeEditorLanguage } from './CodeEditor';\nimport { loadMonacoRuntime } from './runtime/loadMonaco';\nimport { acquireModelOwnership } from './runtime/modelOwnership';\nimport { useCodeEditorThemeMode } from './themeAppearance';\n\nexport interface DiffCodeEditorProps {\n readonly originalValue: string;\n readonly value: string;\n readonly onChange?: (value: string) => void;\n readonly language: CodeEditorLanguage;\n readonly originalModelPath: string;\n readonly modelPath: string;\n readonly ariaLabel: string;\n readonly readOnly?: boolean;\n readonly height?: number | string;\n}\n\nexport function DiffCodeEditor({\n originalValue,\n value,\n onChange,\n language,\n originalModelPath,\n modelPath,\n ariaLabel,\n readOnly = false,\n height = 400,\n}: DiffCodeEditorProps) {\n const appearanceMode = useCodeEditorThemeMode();\n const ownerId = useId();\n const contentListenerRef = useRef<Monaco.IDisposable | null>(null);\n const valueRef = useRef(value);\n const [ready, setReady] = useState(false);\n const [runtimeError, setRuntimeError] = useState<string>();\n valueRef.current = value;\n\n useEffect(() => {\n let active = true;\n const releases: Array<() => void> = [];\n setReady(false);\n setRuntimeError(undefined);\n void loadMonacoRuntime()\n .then(monaco => {\n if (!active) return;\n if (originalModelPath === modelPath) {\n throw new Error('Diff editor model paths must be different');\n }\n releases.push(acquireModelOwnership(\n monaco,\n `${ownerId}:original`,\n originalModelPath,\n language,\n ));\n releases.push(acquireModelOwnership(\n monaco,\n `${ownerId}:modified`,\n modelPath,\n language,\n ));\n if (active) setReady(true);\n else releases.splice(0).reverse().forEach(release => release());\n })\n .catch(errorValue => {\n releases.splice(0).reverse().forEach(release => release());\n if (active) {\n setRuntimeError(\n errorValue instanceof Error\n ? errorValue.message\n : String(errorValue),\n );\n }\n });\n return () => {\n active = false;\n contentListenerRef.current?.dispose();\n contentListenerRef.current = null;\n releases.splice(0).reverse().forEach(release => release());\n };\n }, [language, modelPath, originalModelPath, ownerId]);\n\n if (runtimeError) {\n return <Alert severity=\"error\" role=\"alert\">{runtimeError}</Alert>;\n }\n\n if (!ready) {\n return (\n <Box\n role=\"status\"\n aria-label={`Loading ${ariaLabel}`}\n sx={{ display: 'grid', height, minHeight: 160, placeItems: 'center' }}\n >\n <CircularProgress aria-hidden=\"true\" />\n </Box>\n );\n }\n\n return (\n <Box\n role=\"region\"\n aria-label={ariaLabel}\n sx={{ height, minHeight: 160, overflow: 'hidden' }}\n >\n <DiffEditor\n height=\"100%\"\n language={language}\n original={originalValue}\n modified={value}\n originalModelPath={originalModelPath}\n modifiedModelPath={modelPath}\n theme={appearanceMode === 'dark' ? 'vs-dark' : 'vs'}\n keepCurrentOriginalModel\n keepCurrentModifiedModel\n onMount={editor => {\n contentListenerRef.current?.dispose();\n const modifiedEditor = editor.getModifiedEditor();\n contentListenerRef.current = modifiedEditor\n .onDidChangeModelContent(() => {\n const nextValue = modifiedEditor.getValue();\n if (nextValue !== valueRef.current) onChange?.(nextValue);\n });\n }}\n options={{\n ariaLabel,\n automaticLayout: true,\n minimap: { enabled: false },\n originalEditable: false,\n readOnly,\n renderSideBySide: true,\n scrollBeyondLastLine: false,\n }}\n />\n </Box>\n );\n}\n"],"mappings":";;;;;;;;AAwBA,SAAgB,eAAe,EAC7B,eACA,OACA,UACA,UACA,mBACA,WACA,WACA,WAAW,OACX,SAAS,OACa;CACtB,MAAM,iBAAiB,uBAAuB;CAC9C,MAAM,UAAU,MAAM;CACtB,MAAM,qBAAqB,OAAkC,IAAI;CACjE,MAAM,WAAW,OAAO,KAAK;CAC7B,MAAM,CAAC,OAAO,YAAY,SAAS,KAAK;CACxC,MAAM,CAAC,cAAc,mBAAmB,SAAiB;CACzD,SAAS,UAAU;CAEnB,gBAAgB;EACd,IAAI,SAAS;EACb,MAAM,WAA8B,CAAC;EACrC,SAAS,KAAK;EACd,gBAAgB,KAAA,CAAS;EACzB,kBAAuB,CAAC,CACrB,MAAK,WAAU;GACd,IAAI,CAAC,QAAQ;GACb,IAAI,sBAAsB,WACxB,MAAM,IAAI,MAAM,2CAA2C;GAE7D,SAAS,KAAK,sBACZ,QACA,GAAG,QAAQ,YACX,mBACA,QACF,CAAC;GACD,SAAS,KAAK,sBACZ,QACA,GAAG,QAAQ,YACX,WACA,QACF,CAAC;GACD,IAAI,QAAQ,SAAS,IAAI;QACpB,SAAS,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,SAAQ,YAAW,QAAQ,CAAC;EAChE,CAAC,CAAC,CACD,OAAM,eAAc;GACnB,SAAS,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,SAAQ,YAAW,QAAQ,CAAC;GACzD,IAAI,QACF,gBACE,sBAAsB,QAClB,WAAW,UACX,OAAO,UAAU,CACvB;EAEJ,CAAC;EACH,aAAa;GACX,SAAS;GACT,mBAAmB,SAAS,QAAQ;GACpC,mBAAmB,UAAU;GAC7B,SAAS,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,SAAQ,YAAW,QAAQ,CAAC;EAC3D;CACF,GAAG;EAAC;EAAU;EAAW;EAAmB;CAAO,CAAC;CAEpD,IAAI,cACF,OAAO,oBAAC,OAAD;EAAO,UAAS;EAAQ,MAAK;YAAS;CAAoB,CAAA;CAGnE,IAAI,CAAC,OACH,OACE,oBAAC,KAAD;EACE,MAAK;EACL,cAAY,WAAW;EACvB,IAAI;GAAE,SAAS;GAAQ;GAAQ,WAAW;GAAK,YAAY;EAAS;YAEpE,oBAAC,kBAAD,EAAkB,eAAY,OAAQ,CAAA;CACnC,CAAA;CAIT,OACE,oBAAC,KAAD;EACE,MAAK;EACL,cAAY;EACZ,IAAI;GAAE;GAAQ,WAAW;GAAK,UAAU;EAAS;YAEjD,oBAAC,YAAD;GACE,QAAO;GACG;GACV,UAAU;GACV,UAAU;GACS;GACnB,mBAAmB;GACnB,OAAO,mBAAmB,SAAS,YAAY;GAC/C,0BAAA;GACA,0BAAA;GACA,UAAS,WAAU;IACjB,mBAAmB,SAAS,QAAQ;IACpC,MAAM,iBAAiB,OAAO,kBAAkB;IAChD,mBAAmB,UAAU,eAC1B,8BAA8B;KAC7B,MAAM,YAAY,eAAe,SAAS;KAC1C,IAAI,cAAc,SAAS,SAAS,WAAW,SAAS;IAC1D,CAAC;GACL;GACA,SAAS;IACP;IACA,iBAAiB;IACjB,SAAS,EAAE,SAAS,MAAM;IAC1B,kBAAkB;IAClB;IACA,kBAAkB;IAClB,sBAAsB;GACxB;EACD,CAAA;CACE,CAAA;AAET"}
|
package/package.json
CHANGED
package/yaml/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { a as getSharedRuntimeState, i as loadMonacoRuntime, t as CodeEditor } from "../chunks/CodeEditor-BI8PAcmS.js";
|
|
2
2
|
import Alert from "@mui/material/Alert";
|
|
3
3
|
import Box from "@mui/material/Box";
|
|
4
4
|
import CircularProgress from "@mui/material/CircularProgress";
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"CodeEditor-CEfhCmSA.js","names":[],"sources":["../../../src/monacoEnvironment.ts","../../../src/runtime/runtimeState.ts","../../../src/runtime/loadMonaco.ts","../../../src/runtime/modelOwnership.ts","../../../src/CodeEditor.tsx"],"sourcesContent":["declare global {\n interface Window {\n MonacoEnvironment: {\n getWorker: (_moduleId: string, label: string) => Worker;\n };\n }\n}\n\nexport function configureMonacoEnvironment(): void {\n if (typeof window === 'undefined') return;\n const existing = Reflect.get(window, 'MonacoEnvironment') as\n | { readonly getWorker?: unknown }\n | undefined;\n if (typeof existing?.getWorker === 'function') return;\n\n window.MonacoEnvironment = {\n getWorker: (_moduleId, label) => {\n if (label === 'yaml') {\n return new Worker(new URL('./yaml/yaml.worker.js', import.meta.url));\n }\n if (label === 'json') {\n return new Worker(new URL(\n 'monaco-editor/esm/vs/language/json/json.worker.js',\n import.meta.url,\n ));\n }\n return new Worker(new URL(\n 'monaco-editor/esm/vs/editor/editor.worker.js',\n import.meta.url,\n ));\n },\n };\n}\n","import type * as Monaco from 'monaco-editor/esm/vs/editor/editor.main.js';\n\nexport interface SharedCodeEditorRuntimeState {\n monaco?: typeof Monaco;\n monacoPromise?: Promise<typeof Monaco>;\n models?: Map<string, unknown>;\n yaml?: unknown;\n}\n\nconst runtimeKey = Symbol.for('alauda.react-code-editor.runtime');\n\nexport function getSharedRuntimeState(): SharedCodeEditorRuntimeState {\n const target = globalThis as typeof globalThis & {\n [runtimeKey]?: SharedCodeEditorRuntimeState;\n };\n target[runtimeKey] ??= {};\n return target[runtimeKey];\n}\n","import { loader } from '@monaco-editor/react';\nimport type * as Monaco from 'monaco-editor/esm/vs/editor/editor.main.js';\n\nimport { configureMonacoEnvironment } from '../monacoEnvironment';\nimport { getSharedRuntimeState } from './runtimeState';\n\nexport function loadMonacoRuntime(): Promise<typeof Monaco> {\n const runtime = getSharedRuntimeState();\n if (runtime.monacoPromise) return runtime.monacoPromise;\n const promise = (async () => {\n configureMonacoEnvironment();\n const monaco = await import(\n 'monaco-editor/esm/vs/editor/editor.main.js'\n );\n loader.config({ monaco });\n runtime.monaco = monaco;\n return monaco;\n })();\n runtime.monacoPromise = promise;\n void promise.catch(() => {\n if (runtime.monacoPromise === promise) runtime.monacoPromise = undefined;\n });\n return promise;\n}\n","import type * as Monaco from 'monaco-editor/esm/vs/editor/editor.main.js';\n\nimport { getSharedRuntimeState } from './runtimeState';\n\ninterface ModelOwnership {\n readonly language: string;\n readonly owners: Set<string>;\n readonly uri: Monaco.Uri;\n readonly ownedByPackage: boolean;\n}\n\nfunction ownershipRegistry(): Map<string, ModelOwnership> {\n const runtime = getSharedRuntimeState();\n runtime.models ??= new Map();\n return runtime.models as Map<string, ModelOwnership>;\n}\n\nexport function acquireModelOwnership(\n monaco: typeof Monaco,\n ownerId: string,\n modelPath: string,\n language: string,\n): () => void {\n const registry = ownershipRegistry();\n const existing = registry.get(modelPath);\n if (existing && existing.language !== language) {\n throw new Error(\n `Conflicting editor languages for ${modelPath}: `\n + `${existing.language} and ${language}`,\n );\n }\n\n const ownership = existing ?? (() => {\n const uri = monaco.Uri.parse(modelPath);\n return {\n language,\n owners: new Set<string>(),\n uri,\n ownedByPackage: !monaco.editor.getModel(uri),\n } satisfies ModelOwnership;\n })();\n ownership.owners.add(ownerId);\n registry.set(modelPath, ownership);\n\n let active = true;\n return () => {\n if (!active) return;\n active = false;\n ownership.owners.delete(ownerId);\n if (ownership.owners.size > 0) return;\n registry.delete(modelPath);\n if (ownership.ownedByPackage) {\n monaco.editor.getModel(ownership.uri)?.dispose();\n }\n };\n}\n","import Editor, { type OnMount } from '@monaco-editor/react';\nimport Alert from '@mui/material/Alert';\nimport Box from '@mui/material/Box';\nimport CircularProgress from '@mui/material/CircularProgress';\nimport IconButton from '@mui/material/IconButton';\nimport Tooltip from '@mui/material/Tooltip';\nimport Typography from '@mui/material/Typography';\nimport { useTheme } from '@mui/material/styles';\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useId,\n useImperativeHandle,\n useRef,\n useState,\n type FC,\n type ReactNode,\n} from 'react';\nimport type * as Monaco from 'monaco-editor/esm/vs/editor/editor.main.js';\n\nimport { loadMonacoRuntime } from './runtime/loadMonaco';\nimport { acquireModelOwnership } from './runtime/modelOwnership';\n\nexport type CodeEditorLanguage =\n | 'json'\n | 'markdown'\n | 'plaintext'\n | 'yaml';\n\nexport type CodeEditorAction =\n | 'copy'\n | 'find'\n | 'format'\n | 'fullscreen'\n | 'redo'\n | 'undo';\n\nexport type CodeEditorDiagnosticSeverity =\n | 'error'\n | 'warning'\n | 'info'\n | 'hint';\n\nexport interface CodeEditorDiagnostic {\n readonly severity: CodeEditorDiagnosticSeverity;\n readonly message: string;\n readonly line: number;\n readonly column: number;\n readonly endLine: number;\n readonly endColumn: number;\n readonly code?: string;\n}\n\nexport interface CodeEditorLabels {\n readonly copy: string;\n readonly copied: string;\n readonly copyFailed: string;\n readonly find: string;\n readonly format: string;\n readonly fullscreen: string;\n readonly exitFullscreen: string;\n readonly undo: string;\n readonly redo: string;\n readonly loading: string;\n readonly valid: string;\n readonly errors: (count: number) => string;\n readonly lineColumn: (line: number, column: number) => string;\n}\n\nexport interface CodeEditorHandle {\n focus(): void;\n find(): Promise<void>;\n format(): Promise<void>;\n undo(): void;\n redo(): void;\n validate(): Promise<readonly CodeEditorDiagnostic[]>;\n}\n\nexport interface CodeEditorProps {\n readonly value: string;\n readonly onChange: (value: string) => void;\n readonly onBlur?: () => void;\n readonly language: CodeEditorLanguage;\n readonly modelPath: string;\n readonly ariaLabel: string;\n readonly readOnly?: boolean;\n readonly disabled?: boolean;\n readonly height?: number | string;\n readonly actions?: readonly CodeEditorAction[];\n readonly labels?: Partial<CodeEditorLabels>;\n readonly error?: string | null;\n readonly onDiagnostics?: (\n diagnostics: readonly CodeEditorDiagnostic[],\n ) => void;\n readonly toolbarStart?: ReactNode;\n readonly toolbarEnd?: ReactNode;\n}\n\nconst defaultLabels: CodeEditorLabels = {\n copy: 'Copy',\n copied: 'Copied',\n copyFailed: 'Copy failed',\n find: 'Search',\n format: 'Format',\n fullscreen: 'Enter fullscreen',\n exitFullscreen: 'Exit fullscreen',\n undo: 'Undo',\n redo: 'Redo',\n loading: 'Loading editor',\n valid: 'Validation passed',\n errors: count => `${count} validation error${count === 1 ? '' : 's'}`,\n lineColumn: (line, column) => `Ln ${line}, Col ${column}`,\n};\n\nconst defaultActions: readonly CodeEditorAction[] = [\n 'find',\n 'copy',\n 'format',\n 'undo',\n 'redo',\n 'fullscreen',\n];\n\nconst paths = {\n copy: 'M16 1H4a2 2 0 0 0-2 2v14h2V3h12zm3 4H8a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h11a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2m0 16H8V7h11z',\n find: 'M9.5 3a6.5 6.5 0 1 0 3.98 11.64L19.85 21 21 19.85l-6.36-6.37A6.5 6.5 0 0 0 9.5 3m0 2a4.5 4.5 0 1 1 0 9 4.5 4.5 0 0 1 0-9',\n format: 'M3 5h18v2H3zm0 6h12v2H3zm0 6h18v2H3z',\n fullscreen: 'M4 4h6v2H6v4H4zm10 0h6v6h-2V6h-4zM4 14h2v4h4v2H4zm14 0h2v6h-6v-2h4z',\n redo: 'M15 6V3l5 5-5 5v-3c-4 0-7 1-9 5 1-6 4-9 9-9',\n undo: 'M9 6V3L4 8l5 5v-3c4 0 7 1 9 5-1-6-4-9-9-9',\n} satisfies Record<CodeEditorAction, string>;\n\nconst ToolIcon: FC<{ readonly path: string }> = ({ path }) => (\n <Box\n component=\"svg\"\n aria-hidden=\"true\"\n viewBox=\"0 0 24 24\"\n sx={{ width: 20, height: 20, fill: 'currentColor' }}\n >\n <path d={path} />\n </Box>\n);\n\nfunction markerSeverity(\n marker: Monaco.editor.IMarker,\n monaco: typeof Monaco,\n): CodeEditorDiagnosticSeverity {\n if (marker.severity === monaco.MarkerSeverity.Error) return 'error';\n if (marker.severity === monaco.MarkerSeverity.Warning) return 'warning';\n if (marker.severity === monaco.MarkerSeverity.Info) return 'info';\n return 'hint';\n}\n\nfunction mapDiagnostics(\n markers: readonly Monaco.editor.IMarker[],\n monaco: typeof Monaco,\n): readonly CodeEditorDiagnostic[] {\n return markers.map(marker => ({\n severity: markerSeverity(marker, monaco),\n message: marker.message,\n line: marker.startLineNumber,\n column: marker.startColumn,\n endLine: marker.endLineNumber,\n endColumn: marker.endColumn,\n ...(marker.code === undefined ? {} : { code: String(marker.code) }),\n }));\n}\n\nexport const CodeEditor = forwardRef<CodeEditorHandle, CodeEditorProps>(\n function CodeEditor({\n value,\n onChange,\n onBlur,\n language,\n modelPath,\n ariaLabel,\n readOnly = false,\n disabled = false,\n height = 400,\n actions = defaultActions,\n labels: labelOverrides,\n error,\n onDiagnostics,\n toolbarStart,\n toolbarEnd,\n }, ref) {\n const theme = useTheme();\n const ownerId = useId();\n const editorRef = useRef<Monaco.editor.IStandaloneCodeEditor | null>(null);\n const disposablesRef = useRef<Monaco.IDisposable[]>([]);\n const diagnosticsRef = useRef<readonly CodeEditorDiagnostic[]>([]);\n const externalValueSyncRef = useRef(false);\n const pendingLocalValuesRef = useRef<string[]>([]);\n const modelPathRef = useRef(modelPath);\n const valueRef = useRef(value);\n const [monaco, setMonaco] = useState<typeof Monaco | null>(null);\n const [runtimeError, setRuntimeError] = useState<string>();\n const [position, setPosition] = useState({ lineNumber: 1, column: 1 });\n const [diagnosticCount, setDiagnosticCount] = useState(0);\n const [copyState, setCopyState] = useState<'idle' | 'copied' | 'failed'>('idle');\n const [fullscreen, setFullscreen] = useState(false);\n const labels = { ...defaultLabels, ...labelOverrides };\n valueRef.current = value;\n\n const synchronizeExternalValue = useCallback((\n editor: Monaco.editor.IStandaloneCodeEditor,\n nextValue: string,\n ): void => {\n const model = editor.getModel();\n if (!model) return;\n\n const pending = pendingLocalValuesRef.current;\n const acknowledgedIndex = pending.lastIndexOf(nextValue);\n if (acknowledgedIndex >= 0) {\n pending.splice(0, acknowledgedIndex + 1);\n return;\n }\n if (model.getValue() === nextValue) return;\n\n pending.length = 0;\n const selections = editor.getSelections();\n const scrollPosition = {\n scrollLeft: editor.getScrollLeft(),\n scrollTop: editor.getScrollTop(),\n };\n externalValueSyncRef.current = true;\n try {\n editor.pushUndoStop();\n const applied = editor.executeEdits(\n 'alauda.react-code-editor.external-value',\n [{\n range: model.getFullModelRange(),\n text: nextValue,\n forceMoveMarkers: true,\n }],\n selections ?? undefined,\n );\n if (!applied) model.setValue(nextValue);\n editor.pushUndoStop();\n if (selections) editor.setSelections(selections);\n editor.setScrollPosition(scrollPosition);\n } finally {\n externalValueSyncRef.current = false;\n }\n }, []);\n\n useEffect(() => {\n let active = true;\n let release: (() => void) | undefined;\n setMonaco(null);\n setRuntimeError(undefined);\n void loadMonacoRuntime()\n .then(instance => {\n if (!active) return;\n release = acquireModelOwnership(\n instance,\n ownerId,\n modelPath,\n language,\n );\n if (active) setMonaco(instance);\n else release();\n })\n .catch(errorValue => {\n if (active) {\n setRuntimeError(\n errorValue instanceof Error\n ? errorValue.message\n : String(errorValue),\n );\n }\n });\n return () => {\n active = false;\n release?.();\n };\n }, [language, modelPath, ownerId]);\n\n useEffect(() => () => {\n disposablesRef.current.forEach(disposable => disposable.dispose());\n disposablesRef.current = [];\n editorRef.current = null;\n }, []);\n\n useEffect(() => {\n if (modelPathRef.current !== modelPath) {\n modelPathRef.current = modelPath;\n pendingLocalValuesRef.current = [];\n }\n const editor = editorRef.current;\n if (editor) synchronizeExternalValue(editor, value);\n }, [modelPath, synchronizeExternalValue, value]);\n\n const find = async (): Promise<void> => {\n editorRef.current?.focus();\n await editorRef.current?.getAction('actions.find')?.run();\n };\n const format = async (): Promise<void> => {\n editorRef.current?.focus();\n await editorRef.current?.getAction('editor.action.formatDocument')?.run();\n };\n\n useImperativeHandle(ref, () => ({\n focus: () => editorRef.current?.focus(),\n find,\n format,\n undo: () => editorRef.current?.trigger('code-editor', 'undo', null),\n redo: () => editorRef.current?.trigger('code-editor', 'redo', null),\n validate: async () => diagnosticsRef.current,\n }));\n\n const onMount: OnMount = editor => {\n editorRef.current = editor;\n synchronizeExternalValue(editor, valueRef.current);\n disposablesRef.current.forEach(disposable => disposable.dispose());\n disposablesRef.current = [\n editor.onDidChangeCursorPosition(event => setPosition(event.position)),\n editor.onDidBlurEditorText(() => onBlur?.()),\n ];\n const currentPosition = editor.getPosition();\n if (currentPosition) setPosition(currentPosition);\n };\n\n const copy = async (): Promise<void> => {\n try {\n await navigator.clipboard.writeText(\n editorRef.current?.getModel()?.getValue() ?? valueRef.current,\n );\n setCopyState('copied');\n } catch {\n setCopyState('failed');\n }\n };\n\n const runAction = (action: CodeEditorAction): void => {\n if (action === 'find') void find();\n if (action === 'copy') void copy();\n if (action === 'format') void format();\n if (action === 'undo') {\n editorRef.current?.trigger('code-editor', 'undo', null);\n }\n if (action === 'redo') {\n editorRef.current?.trigger('code-editor', 'redo', null);\n }\n if (action === 'fullscreen') setFullscreen(current => !current);\n };\n\n const actionLabel = (action: CodeEditorAction): string => {\n if (action === 'copy' && copyState === 'copied') return labels.copied;\n if (action === 'copy' && copyState === 'failed') return labels.copyFailed;\n if (action === 'fullscreen' && fullscreen) return labels.exitFullscreen;\n return labels[action];\n };\n\n if (runtimeError) {\n return <Alert severity=\"error\" role=\"alert\">{runtimeError}</Alert>;\n }\n\n if (!monaco) {\n return (\n <Box\n role=\"status\"\n aria-label={labels.loading}\n sx={{ display: 'grid', height, minHeight: 160, placeItems: 'center' }}\n >\n <CircularProgress aria-hidden=\"true\" />\n </Box>\n );\n }\n\n return (\n <Box\n role=\"region\"\n aria-label={`${ariaLabel} editor`}\n sx={{\n position: fullscreen ? 'fixed' : 'relative',\n inset: fullscreen ? 0 : undefined,\n zIndex: fullscreen ? theme.zIndex.modal : undefined,\n display: 'flex',\n flexDirection: 'column',\n height: fullscreen ? '100dvh' : height,\n minHeight: 160,\n overflow: 'hidden',\n bgcolor: 'background.paper',\n border: 1,\n borderColor: error ? 'error.main' : 'divider',\n borderRadius: fullscreen ? 0 : 1,\n }}\n >\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n gap: 1,\n minHeight: 40,\n px: 1,\n borderBottom: 1,\n borderColor: 'divider',\n }}\n >\n {toolbarStart}\n <Box sx={{ flex: 1 }} />\n {actions.map(action => (\n <Tooltip key={action} title={actionLabel(action)}>\n <span>\n <IconButton\n aria-label={actionLabel(action)}\n aria-pressed={action === 'fullscreen' ? fullscreen : undefined}\n disabled={disabled || (\n readOnly && ['format', 'undo', 'redo'].includes(action)\n )}\n size=\"small\"\n onClick={() => runAction(action)}\n >\n <ToolIcon path={paths[action]} />\n </IconButton>\n </span>\n </Tooltip>\n ))}\n {toolbarEnd}\n </Box>\n <Box sx={{ flex: '1 1 auto', minHeight: 0, overflow: 'hidden' }}>\n <Editor\n height=\"100%\"\n language={language}\n path={modelPath}\n theme={theme.palette.mode === 'dark' ? 'vs-dark' : 'vs'}\n defaultValue={value}\n keepCurrentModel\n onMount={onMount}\n onChange={nextValue => {\n if (externalValueSyncRef.current) return;\n const normalized = nextValue ?? '';\n const pending = pendingLocalValuesRef.current;\n if (pending.at(-1) !== normalized) {\n pending.push(normalized);\n if (pending.length > 64) {\n pending.splice(0, pending.length - 64);\n }\n }\n onChange(normalized);\n }}\n onValidate={markers => {\n const diagnostics = mapDiagnostics(markers, monaco);\n diagnosticsRef.current = diagnostics;\n setDiagnosticCount(diagnostics.filter(item => (\n item.severity === 'error'\n )).length);\n onDiagnostics?.(diagnostics);\n }}\n options={{\n ariaLabel,\n automaticLayout: true,\n bracketPairColorization: { enabled: true },\n folding: true,\n fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace',\n fontSize: 13,\n formatOnPaste: true,\n insertSpaces: true,\n lineHeight: 22,\n minimap: { enabled: false },\n padding: { top: 12, bottom: 12 },\n readOnly: readOnly || disabled,\n renderValidationDecorations: 'on',\n scrollBeyondLastLine: false,\n tabSize: 2,\n }}\n />\n </Box>\n <Box\n aria-live=\"polite\"\n sx={{\n display: 'flex',\n justifyContent: 'space-between',\n gap: 2,\n minHeight: 28,\n px: 1.5,\n py: 0.5,\n borderTop: 1,\n borderColor: 'divider',\n }}\n >\n <Typography variant=\"caption\">{language.toUpperCase()}</Typography>\n <Typography\n variant=\"caption\"\n color={error || diagnosticCount ? 'error' : 'text.secondary'}\n >\n {error ?? (\n diagnosticCount ? labels.errors(diagnosticCount) : labels.valid\n )}\n </Typography>\n <Typography variant=\"caption\">\n {labels.lineColumn(position.lineNumber, position.column)}\n </Typography>\n </Box>\n </Box>\n );\n },\n);\n"],"mappings":"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"}
|