diff --git a/CHANGELOG.md b/CHANGELOG.md index b753d1799..7a68597f0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ and this project adheres to - 🐛(frontend) keep commented text sharp when printing to PDF #2674 - 🐛(docker) pull minio images from quay.io #2675 - ♿️(frontend) restore presenter focus trapping after share links #2533 +- 🐛(frontend) fix find & replace crash when editor becomes read-only #2684 ## [v5.6.1] - 2026-09-04 diff --git a/src/frontend/apps/impress/src/features/docs/doc-find-replace/components/FindReplace.tsx b/src/frontend/apps/impress/src/features/docs/doc-find-replace/components/FindReplace.tsx index a71e4eeeb..5394f400f 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-find-replace/components/FindReplace.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-find-replace/components/FindReplace.tsx @@ -36,6 +36,7 @@ export const FindReplace = () => { const findInputRef = useRef(null); const { + isSupported, query, setQuery, replacement, @@ -70,6 +71,16 @@ export const FindReplace = () => { findInputRef.current?.select(); }, [editor?._tiptapEditor, setQuery, openCount]); + // The editor can lose find & replace support while the panel is open, e.g. + // when a collaborative doc briefly turns read-only after a WebSocket + // disconnect. Close the panel so the floating bar falls back to its normal + // controls instead of rendering nothing. + useEffect(() => { + if (!isSupported) { + close(); + } + }, [isSupported, close]); + const handleClose = () => { close(); restoreFocus(); @@ -151,6 +162,10 @@ export const FindReplace = () => { handleReplaceCurrent(); }; + if (!isSupported) { + return null; + } + return ( { const [matchCount, setMatchCount] = useState(0); const [activeIndex, setActiveIndex] = useState(-1); - const tiptapEditor = editor?._tiptapEditor; + const isSupported = + typeof editor?._tiptapEditor.commands.clearSearch === 'function'; + const tiptapEditor = isSupported ? editor?._tiptapEditor : undefined; const syncFromStorage = useCallback(() => { if (!tiptapEditor) { @@ -111,6 +113,7 @@ export const useFindReplace = (editor: DocsBlockNoteEditor | undefined) => { }, [tiptapEditor]); return { + isSupported, query, setQuery, replacement,