UNPKG

@blocknote/react

Version:

A "Notion-style" block-based extensible text editor built on top of Prosemirror and Tiptap.

58 lines (49 loc) 1.91 kB
import { BlockNoteEditor, SourceBlockWithPreviewExtension, } from "@blocknote/core"; import { useExtension, useExtensionState, } from "../../../hooks/useExtension.js"; import type { SourcePreviewPopup } from "../SourcePreviewPopup.js"; /** * Controls the source popup of a block with a preview, e.g. to open it from a * custom preview element. A block's popup is toggled explicitly - `open` and * `close` set a flag, separate from the selection. The popup state itself is * managed by the `SourceBlockWithPreviewExtension` registered with the block * spec (so it survives node view re-creation and stays in sync with the * keyboard handling) - this hook is the React API to it. */ export const useSourceBlockPreviewPopup = (props: { editor: BlockNoteEditor<any, any, any>; block: { id: string }; }): SourcePreviewPopup => { const { editor, block } = props; const { store } = useExtension(SourceBlockWithPreviewExtension, { editor }); const isOpen = useExtensionState(SourceBlockWithPreviewExtension, { editor, selector: (state) => state.popupOpen === block.id, }); const isSelected = useExtensionState(SourceBlockWithPreviewExtension, { editor, selector: (state) => state.selected === block.id, }); // Opens the popup with the cursor at the end of the source. const open = () => { if (!editor.isEditable) { return; } store.setState((state) => ({ ...state, popupOpen: block.id })); editor.setTextCursorPosition(block.id, "end"); editor.focus(); }; const close = () => { store.setState((state) => ({ ...state, popupOpen: undefined })); // Restores focus in case closing was triggered by clicking the "OK" // button, which moves focus to it - otherwise keyboard interactions (e.g. // Enter to re-open the popup) stop reaching the editor. editor.focus(); }; return { isOpen, isSelected, open, close }; };