// @flow import React, { useEffect, useRef, useState } from 'react'; import type { Element } from 'react'; import EditableValue from './EditableValue'; import ExpandCollapseToggle from './ExpandCollapseToggle'; import { getMetaValueLabel } from '../utils'; import { meta } from '../../../hydration'; import styles from './KeyValue.css'; import type { InspectPath } from './SelectedElement'; type OverrideValueFn = (path: Array, value: any) => void; type KeyValueProps = {| depth: number, hidden?: boolean, inspectPath?: InspectPath, name: string, overrideValueFn?: ?OverrideValueFn, path: Array, value: any, |}; export default function KeyValue({ depth, inspectPath, hidden, name, overrideValueFn, path, value, }: KeyValueProps) { const [isOpen, setIsOpen] = useState(false); const prevIsOpenRef = useRef(isOpen); const isInspectable = value !== null && typeof value === 'object' && value[meta.inspectable] && value[meta.size] !== 0; useEffect(() => { if ( isInspectable && isOpen && !prevIsOpenRef.current && typeof inspectPath === 'function' ) { inspectPath(path); } prevIsOpenRef.current = isOpen; }, [inspectPath, isInspectable, isOpen, path]); const toggleIsOpen = () => setIsOpen(prevIsOpen => !prevIsOpen); const dataType = typeof value; const isSimpleType = dataType === 'number' || dataType === 'string' || dataType === 'boolean' || value == null; const style = { paddingLeft: `${(depth - 1) * 0.75}rem`, }; let children = null; if (isSimpleType) { let displayValue = value; if (dataType === 'string') { displayValue = `"${value}"`; } else if (dataType === 'boolean') { displayValue = value ? 'true' : 'false'; } else if (value === null) { displayValue = 'null'; } else if (value === undefined) { displayValue = 'undefined'; } const nameClassName = typeof overrideValueFn === 'function' ? styles.EditableName : styles.Name; children = (