import { forwardRef, useCallback, useEffect, useRef, useState } from 'react' import Block from '../Primitives/Block/Block' import { useResponsiveTokens } from '../../hooks/useResponsiveTokens' import type { CodeEditorV2Tokens } from './codeEditorV2.tokens' import { CodeEditorV2Variant } from './codeEditorV2.types' import type { CodeEditorV2Props } from './codeEditorV2.types' import { copyToClipboardWithTemporaryFeedback, isDiffEditorMode, shouldShowLineNumbers, getCodeEditorV2ContainerStyles, toCssValue, } from './utils' import { CodeEditorV2Header } from './CodeEditorV2Header' import { MonacoEditorWrapper } from './MonacoEditor/MonacoEditorWrapper' import { filterBlockedProps } from '../../utils/prop-helpers' const DEFAULT_HEADER: NonNullable = { showHeader: true, title: 'Editor', leftSlot: null, rightSlot: null, showCopyButton: true, } const CodeEditorV2 = forwardRef( ( { value, onChange, variant = CodeEditorV2Variant.DEFAULT, showLineNumbers, header: headerProp, language = 'javascript', placeholder, readOnly = false, disabled = false, minHeight = '300px', maxHeight, height, width, maxWidth, minWidth, onBlur, onFocus, autoFocus = false, diff = false, originalValue, renderSideBySide = true, isDiffUnchangedCollapsed = true, diffContextLines = 3, diffExpandChunk = 20, ...rest }, ref ) => { const filteredRest = filterBlockedProps(rest) const header = { ...DEFAULT_HEADER, ...headerProp } const tokens = useResponsiveTokens('CODEEDITORV2') const [isCopied, setIsCopied] = useState(false) const copyFeedbackTimeoutRef = useRef | null>(null) useEffect(() => { return () => { if (copyFeedbackTimeoutRef.current !== null) { clearTimeout(copyFeedbackTimeoutRef.current) } } }, []) // Determine if line numbers should be shown const shouldShowLineNumbersValue = shouldShowLineNumbers( showLineNumbers, variant ) const isDiff = isDiffEditorMode(diff, variant) const copyToClipboard = useCallback(() => { copyToClipboardWithTemporaryFeedback( value, setIsCopied, copyFeedbackTimeoutRef ) }, [value]) // Fixed editor height applies to the Monaco region only; omit outer minHeight // when `height` is set so the default minHeight (e.g. 300px) cannot force the // whole shell taller than header + editor. const resolvedEditorHeight = toCssValue(height) const hasFixedEditorHeight = Boolean(resolvedEditorHeight) const editorMinHeight = hasFixedEditorHeight ? height! : minHeight const containerStyles = getCodeEditorV2ContainerStyles( hasFixedEditorHeight ? undefined : minHeight, maxHeight ) return ( {header.showHeader && ( )} ) } ) CodeEditorV2.displayName = 'CodeEditorV2' export default CodeEditorV2