/** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @flow */ import {copy} from 'clipboard-js'; import * as React from 'react'; import {OptionsContext} from '../context'; import Button from '../Button'; import ButtonIcon from '../ButtonIcon'; import KeyValue from './KeyValue'; import NewKeyValue from './NewKeyValue'; import {alphaSortEntries, serializeDataForCopy} from '../utils'; import Store from '../../store'; import styles from './InspectedElementSharedStyles.css'; import {ElementTypeClass} from 'react-devtools-shared/src/types'; import type {InspectedElement} from './types'; import type {FrontendBridge} from 'react-devtools-shared/src/bridge'; import type {Element} from 'react-devtools-shared/src/devtools/views/Components/types'; type Props = { bridge: FrontendBridge, element: Element, inspectedElement: InspectedElement, store: Store, }; export default function InspectedElementPropsTree({ bridge, element, inspectedElement, store, }: Props): React.Node { const {readOnly} = React.useContext(OptionsContext); const { canEditFunctionProps, canEditFunctionPropsDeletePaths, canEditFunctionPropsRenamePaths, props, type, } = inspectedElement; const canDeletePaths = type === ElementTypeClass || canEditFunctionPropsDeletePaths; const canEditValues = !readOnly && (type === ElementTypeClass || canEditFunctionProps); const canRenamePaths = type === ElementTypeClass || canEditFunctionPropsRenamePaths; const entries = props != null ? Object.entries(props) : null; if (entries !== null) { entries.sort(alphaSortEntries); } const isEmpty = entries === null || entries.length === 0; const handleCopy = () => copy(serializeDataForCopy(((props: any): Object))); return (