diff --git a/src/common/components/ContentEditable.tsx b/src/common/components/ContentEditable.tsx index 3c99b93..b8e8894 100644 --- a/src/common/components/ContentEditable.tsx +++ b/src/common/components/ContentEditable.tsx @@ -27,7 +27,8 @@ function setCaretOffset(el: HTMLElement, offset: number) { function traverse(node: Node): boolean { if (node.nodeType === Node.TEXT_NODE) { - const len = node.textContent?.length ?? 0; + const text = node.textContent || '' + const len = text.length; if (remaining <= len) { range.setStart(node, remaining); range.collapse(true); @@ -56,7 +57,7 @@ function resizeToContent(el: HTMLElement) { el.style.height = el.scrollHeight + 'px'; } -export const ContentEditable = ({ value, placeholder, autoLines, onInput, class: externalClass, ...props }: Props) => { +export const ContentEditable = ({ value, placeholder, autoLines, onInput, onKeyDown, class: externalClass, ...props }: Props) => { const ref = useRef(null); useEffect(() => { @@ -70,7 +71,10 @@ export const ContentEditable = ({ value, placeholder, autoLines, onInput, class: }, [value]); const handleKeyDown: JSX.KeyboardEventHandler = (e) => { - if (e.key !== 'Enter' || !ref.current) return; + if (e.key !== 'Enter' || !ref.current) { + onKeyDown?.(e); + return; + }; e.preventDefault(); const sel = window.getSelection(); @@ -79,8 +83,8 @@ export const ContentEditable = ({ value, placeholder, autoLines, onInput, class: const range = sel.getRangeAt(0); range.deleteContents(); - const endsWithNewline = ref.current.textContent?.endsWith('\n'); - const caretAtEnd = getCaretOffset(ref.current) === (ref.current.textContent?.length ?? 0); + const endsWithNewline = ref.current.innerText?.endsWith('\n'); + const caretAtEnd = getCaretOffset(ref.current) === (ref.current.innerText?.length ?? 0); const newline = document.createTextNode('\n'.repeat((endsWithNewline || !caretAtEnd) ? 1 : 2)); range.insertNode(newline); @@ -90,14 +94,15 @@ export const ContentEditable = ({ value, placeholder, autoLines, onInput, class: sel.removeAllRanges(); sel.addRange(range); - (ref.current as any).value = ref.current.textContent; + (ref.current as any).value = ref.current.innerText; ref.current?.dispatchEvent(new InputEvent('input', { bubbles: true })); + onKeyDown?.(e); }; const handleInput: JSX.EventHandler> = (e) => { if (autoLines && ref.current) resizeToContent(ref.current); if (ref.current) { - (ref.current as any).value = ref.current.textContent; + (ref.current as any).value = ref.current.innerText; } onInput?.(e); }; @@ -105,12 +110,12 @@ export const ContentEditable = ({ value, placeholder, autoLines, onInput, class: return (
); };