// @flow import React, { Fragment, useCallback, useContext, useEffect, useMemo, useRef, } from 'react'; import { ElementTypeClass, ElementTypeFunction } from 'src/devtools/types'; import { createRegExp } from '../utils'; import { TreeContext } from './TreeContext'; import type { Element } from './types'; import styles from './Element.css'; type Props = { index: number, style: Object, }; export default function ElementView({ index, style }: Props) { const { baseDepth, getElementAtIndex, selectOwner, selectedElementID, selectElementByID, } = useContext(TreeContext); const element = getElementAtIndex(index); const id = element === null ? null : element.id; const isSelected = selectedElementID === id; const handleDoubleClick = useCallback(() => { if (id !== null) { selectOwner(id); } }, [id, selectOwner]); const ref = useRef(null); useEffect(() => { if (isSelected) { if (ref.current !== null) { ref.current.scrollIntoView({ behavior: 'auto', block: 'nearest', inline: 'nearest', }); } } }, [isSelected]); // TODO Add click and key handlers for toggling element open/close state. const handleMouseDown = useCallback( ({ metaKey }) => { if (id !== null) { selectElementByID(metaKey ? null : id); } }, [id, selectElementByID] ); // Handle elements that are removed from the tree while an async render is in progress. if (element == null) { console.warn(` Could not find element at index ${index}`); // This return needs to happen after hooks, since hooks can't be conditional. return null; } const { depth, displayName, key, type } = ((element: any): Element); const showDollarR = isSelected && (type === ElementTypeClass || type === ElementTypeFunction); // TODO styles.SelectedElement is 100% width but it doesn't take horizontal overflow into account. return (
{key && (  key= "{key}" )} {showDollarR &&  == $r}
); } type DisplayNameProps = {| displayName: string | null, id: number, |}; function DisplayName({ displayName, id }: DisplayNameProps) { const { searchIndex, searchResults, searchText } = useContext(TreeContext); const isSearchResult = useMemo(() => { return searchResults.includes(id); }, [id, searchResults]); const isCurrentResult = searchIndex !== null && id === searchResults[searchIndex]; if (!isSearchResult || displayName === null) { return displayName; } const match = createRegExp(searchText).exec(displayName); if (match === null) { return displayName; } const startIndex = match.index; const stopIndex = startIndex + match[0].length; const children = []; if (startIndex > 0) { children.push({displayName.slice(0, startIndex)}); } children.push( {displayName.slice(startIndex, stopIndex)} ); if (stopIndex < displayName.length) { children.push({displayName.slice(stopIndex)}); } return children; }