/** * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates * SPDX-License-Identifier: MIT */ import React, { useEffect, useRef } from 'react'; import { ActiveLinePlaceholder, createRenderer, EditorProvider, InferValues, } from '@flowgram.ai/coze-editor/react'; import preset, { type EditorAPI } from '@flowgram.ai/coze-editor/preset-code'; import { EditorView } from '@codemirror/view'; import { getSuffixByLanguageId } from './utils'; import './styles.css'; const OriginCodeEditor = createRenderer(preset, [ EditorView.theme({ '&.cm-focused': { outline: 'none', }, }), ]); const MINI_EXTENSIONS = [EditorView.lineWrapping]; // CSS styles are in styles.css type Preset = typeof preset; type Options = Partial>; export interface CodeEditorPropsType extends React.PropsWithChildren<{}> { value?: string; onChange?: (value: string) => void; languageId: 'python' | 'typescript' | 'shell' | 'json' | 'sql'; theme?: 'dark' | 'light'; placeholder?: string; activeLinePlaceholder?: string; readonly?: boolean; options?: Options; mini?: boolean; } export function BaseCodeEditor({ value, onChange, languageId = 'python', theme = 'light', children, placeholder, activeLinePlaceholder, options, readonly, mini, }: CodeEditorPropsType) { const editorRef = useRef(null); const editorValue = String(value || ''); useEffect(() => { // listen to value change if (editorRef.current?.getValue() !== editorValue) { // apply updates on readonly mode const editorView = editorRef.current?.$view; editorView?.dispatch({ changes: { from: 0, to: editorView?.state.doc.length, insert: editorValue, }, }); } }, [editorValue]); return (
{ editorRef.current = editor; }} onChange={(e) => onChange?.(e.value)} > {activeLinePlaceholder && ( {activeLinePlaceholder} )} {children}
); }