nit
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
* Wherever this editor is used, it provides the same features (syntax highlighting + Nunjucks).
|
||||
* The parent (node) provides the expected base language for highlighting.
|
||||
*/
|
||||
import React, { useCallback, useRef } from 'react'
|
||||
import React, { useCallback, useLayoutEffect, useRef } from 'react'
|
||||
import Editor from 'react-simple-code-editor'
|
||||
import { highlight, type HighlightLanguage } from '@/lib/syntaxHighlight'
|
||||
|
||||
@@ -53,6 +53,7 @@ export function CodeEditor({
|
||||
minHeight = 120,
|
||||
}: CodeEditorProps) {
|
||||
const containerRef = useRef<HTMLDivElement | null>(null)
|
||||
const selectionRestoreRef = useRef<{ start: number; end: number } | null>(null)
|
||||
|
||||
const highlightCode = useCallback(
|
||||
(code: string) => highlight(code, language),
|
||||
@@ -69,17 +70,27 @@ export function CodeEditor({
|
||||
(textareaId ? document.getElementById(textareaId) : containerRef.current?.querySelector('textarea')) as HTMLTextAreaElement | null
|
||||
const start = ta?.selectionStart ?? newValue.length
|
||||
const end = ta?.selectionEnd ?? newValue.length
|
||||
selectionRestoreRef.current = { start, end }
|
||||
onValueChange(newValue)
|
||||
requestAnimationFrame(() => {
|
||||
const el = (textareaId
|
||||
? document.getElementById(textareaId)
|
||||
: containerRef.current?.querySelector('textarea')) as HTMLTextAreaElement | null
|
||||
if (el) el.setSelectionRange(start, end)
|
||||
})
|
||||
},
|
||||
[onValueChange, readOnly, textareaId]
|
||||
)
|
||||
|
||||
useLayoutEffect(() => {
|
||||
const pending = selectionRestoreRef.current
|
||||
if (pending == null) return
|
||||
selectionRestoreRef.current = null
|
||||
const el = (textareaId
|
||||
? document.getElementById(textareaId)
|
||||
: containerRef.current?.querySelector('textarea')) as HTMLTextAreaElement | null
|
||||
if (el) {
|
||||
const { start, end } = pending
|
||||
const safeEnd = Math.min(end, el.value.length)
|
||||
const safeStart = Math.min(start, safeEnd)
|
||||
el.setSelectionRange(safeStart, safeEnd)
|
||||
}
|
||||
}, [value, textareaId])
|
||||
|
||||
return (
|
||||
<div ref={containerRef} className="code-editor" style={{ minHeight: 0 }}>
|
||||
<Editor
|
||||
|
||||
Reference in New Issue
Block a user