UNPKG

tldraw

Version:

A tiny little drawing editor.

122 lines (121 loc) 3.31 kB
import { getPointerInfo, noop, stopEventPropagation, tlenv, useEditor, useValue } from "@tldraw/editor"; import { useCallback, useEffect, useRef } from "react"; import { TextHelpers } from "./TextHelpers.mjs"; function useEditablePlainText(shapeId, type, text) { const commonUseEditableTextHandlers = useEditableTextCommon(shapeId); const isEditing = commonUseEditableTextHandlers.isEditing; const editor = useEditor(); const rInput = useRef(null); const isEmpty = (text || "").trim().length === 0; useEffect(() => { function selectAllIfEditing(event) { if (event.shapeId === shapeId) { rInput.current?.select?.(); } } editor.on("select-all-text", selectAllIfEditing); return () => { editor.off("select-all-text", selectAllIfEditing); }; }, [editor, shapeId, isEditing]); useEffect(() => { if (!isEditing) return; if (document.activeElement !== rInput.current) { rInput.current?.focus(); } if (editor.getInstanceState().isCoarsePointer) { rInput.current?.select(); } if (tlenv.isSafari) { rInput.current?.blur(); rInput.current?.focus(); } }, [editor, isEditing]); const handleKeyDown = useCallback( (e) => { if (editor.getEditingShapeId() !== shapeId) return; switch (e.key) { case "Enter": { if (e.ctrlKey || e.metaKey) { editor.complete(); } break; } } }, [editor, shapeId] ); const handleChange = useCallback( ({ plaintext }) => { if (editor.getEditingShapeId() !== shapeId) return; const normalizedPlaintext = TextHelpers.normalizeText(plaintext || ""); editor.updateShape({ id: shapeId, type, props: { text: normalizedPlaintext } }); }, [editor, shapeId, type] ); return { rInput, handleKeyDown, handleChange, isEmpty, ...commonUseEditableTextHandlers }; } function useIsReadyForEditing(editor, shapeId) { return useValue( "isReadyForEditing", () => { const editingShapeId = editor.getEditingShapeId(); return ( // something's being editing... and either it's this shape OR this shape is hovered (editingShapeId !== null && (editingShapeId === shapeId || editor.getHoveredShapeId() === shapeId)) ); }, [editor, shapeId] ); } function useEditableTextCommon(shapeId) { const editor = useEditor(); const isEditing = useValue("isEditing", () => editor.getEditingShapeId() === shapeId, [editor]); const isReadyForEditing = useIsReadyForEditing(editor, shapeId); const handleInputPointerDown = useCallback( (e) => { editor.dispatch({ ...getPointerInfo(e), type: "pointer", name: "pointer_down", target: "shape", shape: editor.getShape(shapeId) }); stopEventPropagation(e); }, [editor, shapeId] ); return { handleFocus: noop, handleBlur: noop, handleInputPointerDown, handleDoubleClick: stopEventPropagation, isEditing, isReadyForEditing }; } const useEditableText = useEditablePlainText; export { useEditablePlainText, useEditableText, useEditableTextCommon, useIsReadyForEditing }; //# sourceMappingURL=useEditablePlainText.mjs.map