Para mi proyecto draftjs
, quiero permitir que el usuario inserte un enlace. Para hacer eso, había creado una ventana emergente después de presionar el atajo cmk + k
.
Para una mejor experiencia de usuario, actualmente estoy tratando de alinear de forma inteligente la ventana emergente.
Vea la imagen de arriba, puedo colocar la ventana emergente debajo de la línea de enfoque actual. El objeto rect delimitador del contenedor Editor y el rect delimitador de la selección actual contendrían suficiente información para que termine el cálculo.
Sin embargo, en otros casos, cuando solo hay una línea vacía: (La posición del cursor antes de la ventana emergente está al final del editor) El
window.getSelection().getRangeAt(0).getBoundingClientRect()
devolvería el objeto DOMRect con cada valor 0. ¿Hay alguna forma de evitarlo en dom, o en draftjs
que podría obtener suficiente información para alinear inteligentemente la ventana emergente? Entonces, la ventana emergente podría aparecer alrededor de la posición actual del cursor.
Para resolver este problema, utilicé el índice de bloque del cursor multiplicado por la altura de la línea + algunas compensaciones para lograr la ubicación correcta desde la parte superior cuando se selecciona una línea vacía.
Este es el código de mi función "calcular la posición de la ventana emergente". Excluí partes para obtener las posiciones superior/izquierda cuando se selecciona una línea con texto y solo las incluí cuando necesito tener en cuenta las líneas sin texto cuando getBoundingClientRect() devuelve nulo.
const singleLineHeightOffset = 28; const topBlankLineOffset = 15; let position = getVisibleSelectionRect(window); // If there is a visible selection area if (position) { // Get ref of editor via prop and location of div if exists let editorRef = forwardedRef; element = ReactDOM.findDOMNode(editorRef.current) as HTMLElement; if (element) { // Code here to calculate when a line with text is selected } else { // Else if no text selected on line // Get current block position of cursor const currentBlockKey = editorState.getSelection().getStartKey(); const currentBlockIndex = editorState .getCurrentContent() .getBlockMap() .keySeq() .findIndex((k) => k === currentBlockKey); let emptyLineTopHeight = singleLineHeightOffset * (currentBlockIndex + 1) - 5; // If first line of editor, add offset for toolbar/padding if (currentBlockIndex === 0) emptyLineTopHeight += topBlankLineOffset; setTopPosition(emptyLineTopHeight); }
Esto detectará en qué línea está el cursor vacío, luego crea el desplazamiento superior multiplicándolo por la altura de la línea. Es posible que deba jugar con las compensaciones y los casos extremos, como la línea inicial, como hice yo.