draft blockrendererfn javascript reactjs typescript autocomplete draftjs

javascript - blockrendererfn - Implementar Autocompletar en el borrador JS pero sin un "disparador" como "@"



draft js plugins (1)

Quiero implementar algo como un editor de etiquetas. Sin embargo, está pensado solo para esas etiquetas, por lo que quiero que el usuario vea el mensaje emergente de autocompletar sugerencias sin tener que escribir algo como @ o # , solo el texto en sí.

Tengo algo que funciona un poco , pero la ventana emergente se muestra en posiciones extrañas en la pantalla:

  • cuando escribo algo por primera vez y aparece la ventana emergente, aparece en algún lugar cerca de la esquina superior izquierda de la pantalla
  • después de crear la primera entidad, al presionar ESPACIO y comenzar a escribir nuevamente, la ventana emergente aparece un par de píxeles a la derecha desde su posición intuitiva (es decir, debajo de la primera letra de la palabra)

Este es un ejemplo de un editor conocido de este tipo (aunque no se implementó con Draft), para que pueda comprender mejor lo que quiero implementar.

Lo primero es lo primero, aquí está la función que activa la ventana emergente de sugerencias:

private onChange(editorState: EditorState) { const content = editorState.getCurrentContent(); const selection = editorState.getSelection(); const currentBlock = content.getBlockForKey(selection.getAnchorKey()); if (selection.isCollapsed()) { const blockText = currentBlock.getText(); const wordMeta = getWordAt(blockText, selection.getAnchorOffset()); const categoryRegex = /([/w]*)/; const matches = wordMeta.word.match(categoryRegex); const existingEntity = currentBlock.getEntityAt(wordMeta.begin); if (!existingEntity && matches) { const categorySearch = matches[1]; const selection = window.getSelection(); if (this.state.autoComplete.search !== categorySearch && selection.rangeCount > 0) { const range = selection.getRangeAt(0); const boundingRect = getRangeBoundingClientRect(range); this.setState((prevState: StateType) => { let state = { autoComplete: { active: true, search: categorySearch, searchMeta: { begin: wordMeta.begin, end: wordMeta.end, }, }, selectionRect: prevState.selectionRect, }; if (prevState.autoComplete.active === false) { state.selectionRect = boundingRect; } return state; }); } } } this.props.onChange(editorState); }

Aquí está la función getWordAt :

function getWordAt(text: string, pos: number): WordMeta { const left = text.slice(0, pos + 1).search(//S+$/); const right = text.slice(pos).search(//s/); if (right < 0) { return { word: text.slice(left), begin: left, end: text.length, }; } return { word: text.slice(left, right + pos), begin: left, end: right + pos, }; }

¿Cuál sería una mejor manera de manejar la posición de la ventana emergente y tal vez incluso la estrategia para completar este tipo también? ¡Gracias!


En lugar de draft-js-typeahead - TypeaheadEditor es un componente de reacción que envuelve el editor de draft. Puede utilizar el componente React-Autosuggest que cumpla con los requisitos. Tiene renderizado personalizado que funciona de forma nativa con elementos React. Es rápido y bastante fácilmente personalizable. Tener control total sobre la prestación de sugerencias.

Podemos hacer que maneje objetos JS en lugar de cadenas simples.

  1. los accesorios onSuggestionSelected son una devolución de llamada para obtener la sugerencia seleccionada
  2. suggestionRenderer método suggestionRenderer toma la sugerencia y devuelve el marcado React

Echa un vistazo a React-Autosuggest .

Puede usar el componente anterior utilizando un renderizador de bloques personalizado , es posible introducir interacciones complejas y ricas dentro del marco de su editor.

Tienes que romperte la cabeza para lograr lo que quieres, no es sencillo. Esta fue mi sugerencia a través de la cual puedes lograrlo, pero no es tan fácil.