From 56faffdcc84d36810f317cbddc2d6ddd4d5b542a Mon Sep 17 00:00:00 2001 From: Test Date: Fri, 3 Apr 2026 23:24:03 +0200 Subject: [PATCH] =?UTF-8?q?fix:=20editor=20title=20textarea=20clips=20wrap?= =?UTF-8?q?ped=20lines=20=E2=80=94=20add=20field-sizing=20+=20robust=20aut?= =?UTF-8?q?o-resize?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The textarea auto-resize was not reliably expanding for wrapped titles because scrollHeight could be stale on the first read (e.g. during tab switches). Added CSS field-sizing: content as the primary solution, plus requestAnimationFrame and ResizeObserver fallbacks for older WebKit versions. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/components/Editor.css | 1 + src/components/TitleField.tsx | 19 +++++++++++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/components/Editor.css b/src/components/Editor.css index 544f9ab9..ba230b18 100644 --- a/src/components/Editor.css +++ b/src/components/Editor.css @@ -336,6 +336,7 @@ resize: none; overflow: hidden; font-family: inherit; + field-sizing: content; } .title-field__input::placeholder { diff --git a/src/components/TitleField.tsx b/src/components/TitleField.tsx index 83c97780..146d679f 100644 --- a/src/components/TitleField.tsx +++ b/src/components/TitleField.tsx @@ -67,7 +67,7 @@ export function TitleField({ title, filename, editable = true, notePath, vaultPa const { value, isEditing, handleFocus, commitTitle, revert, setEdit } = useOptimisticTitle(title, onTitleChange) - // Auto-resize textarea to fit content + // Auto-resize textarea to fit content (fallback for browsers without field-sizing: content) const autoResize = useCallback(() => { const el = inputRef.current if (!el) return @@ -75,7 +75,22 @@ export function TitleField({ title, filename, editable = true, notePath, vaultPa el.style.height = el.scrollHeight + 'px' }, []) - useEffect(() => { autoResize() }, [value, autoResize]) + useEffect(() => { + autoResize() + // Schedule a second measurement after the browser has painted, to catch + // cases where scrollHeight is stale on the first read (e.g. tab switch). + const id = requestAnimationFrame(autoResize) + return () => cancelAnimationFrame(id) + }, [value, autoResize]) + + // Re-measure when container width changes (text may re-wrap) + useEffect(() => { + const el = inputRef.current + if (!el) return + const ro = new ResizeObserver(autoResize) + ro.observe(el) + return () => ro.disconnect() + }, [autoResize]) useEffect(() => { const handler = (e: Event) => {