import React, { useState, useCallback, useMemo } from 'react' import { Slate, Editable, withReact } from 'slate-react' import { Text, Descendant, createEditor } from 'slate' import { css } from '@emotion/css' import { withHistory } from 'slate-history' import { Icon, Toolbar } from './components' const SearchHighlightingExample = () => { const [search, setSearch] = useState() const editor = useMemo(() => withHistory(withReact(createEditor())), []) const decorate = useCallback( ([node, path]) => { const ranges = [] if ( search && Array.isArray(node.children) && node.children.every(Text.isText) ) { const texts = node.children.map(it => it.text) const str = texts.join('') const length = search.length let start = str.indexOf(search) let index = 0 let iterated = 0 while (start !== -1) { // Skip already iterated strings while ( index < texts.length && start >= iterated + texts[index].length ) { iterated = iterated + texts[index].length index++ } // Find the index of array and relative position let offset = start - iterated let remaining = length while (index < texts.length && remaining > 0) { const currentText = texts[index] const currentPath = [...path, index] const taken = Math.min(remaining, currentText.length - offset) ranges.push({ anchor: { path: currentPath, offset }, focus: { path: currentPath, offset: offset + taken }, highlight: true, }) remaining = remaining - taken if (remaining > 0) { iterated = iterated + currentText.length // Next block will be indexed from 0 offset = 0 index++ } } // Looking for next search block start = str.indexOf(search, start + search.length) } } return ranges }, [search] ) return (
search setSearch(e.target.value)} className={css` padding-left: 2.5em; width: 100%; `} />
} />
) } const Leaf = ({ attributes, children, leaf }) => { return ( {children} ) } const initialValue: Descendant[] = [ { type: 'paragraph', children: [ { text: 'This is editable text that you can search. As you search, it looks for matching strings of text, and adds ', }, { text: 'decorations', bold: true }, { text: ' to them in realtime.' }, ], }, { type: 'paragraph', children: [ { text: 'Try it out for yourself by typing in the search box above!' }, ], }, ] export default SearchHighlightingExample