From f92d2bbf83360b358ecf08c0db85cff6fd08cbff Mon Sep 17 00:00:00 2001 From: Brian Vaughn Date: Wed, 3 Apr 2019 09:29:33 -0700 Subject: [PATCH] Fixed editing props for memo and forwardRef components --- shells/dev/app/EditableProps/index.js | 47 +++++++++++++++---- src/devtools/views/Components/HooksTree.css | 5 ++ src/devtools/views/Components/HooksTree.js | 18 +++---- src/devtools/views/Components/KeyValue.css | 5 ++ src/devtools/views/Components/KeyValue.js | 11 +++-- .../views/Components/SelectedElement.js | 14 +++++- 6 files changed, 77 insertions(+), 23 deletions(-) diff --git a/shells/dev/app/EditableProps/index.js b/shells/dev/app/EditableProps/index.js index c86d717ee3..f5a39fc92f 100644 --- a/shells/dev/app/EditableProps/index.js +++ b/shells/dev/app/EditableProps/index.js @@ -3,7 +3,9 @@ import React, { createContext, Component, + forwardRef, Fragment, + memo, useCallback, useDebugValue, useEffect, @@ -38,7 +40,7 @@ function StatefulFunction({ name }: StatefulFunctionProps) { ); return ( - + ); } @@ -76,7 +78,7 @@ class StatefulClass extends Component { render() { return ( - +
  • Name: {this.props.name}
  • Toggle: {this.props.toggle ? 'true' : 'false'}
  • @@ -84,19 +86,48 @@ class StatefulClass extends Component {
  • Cities: {this.state.cities.join(', ')}
  • Context: {this.context ? 'true' : 'false'}
  • - +
); } } +const MemoizedStatefulClass = memo(StatefulClass); +const MemoizedStatefulFunction = memo(StatefulFunction); + +const ForwardRef = forwardRef<{| name: string |}, HTMLUListElement>( + ({ name }, ref) => { + const [count, updateCount] = useState(0); + const debouncedCount = useDebounce(count, 1000); + const handleUpdateCountClick = useCallback(() => updateCount(count + 1), [ + count, + ]); + return ( +
    +
  • Name: {name}
  • +
  • + +
  • +
+ ); + } +); + export default function EditableProps() { return (

Editable props

-
    - - -
+ Class + + Function + + Memoized Class + + Memoized Function + + Forward Ref +
); } diff --git a/src/devtools/views/Components/HooksTree.css b/src/devtools/views/Components/HooksTree.css index ad07918e4a..57a6fe39dc 100644 --- a/src/devtools/views/Components/HooksTree.css +++ b/src/devtools/views/Components/HooksTree.css @@ -25,6 +25,11 @@ color: var(--color-dim); flex: 0 0 auto; } +.EditableName { + color: var(--color-attribute-name); + flex: 0 0 auto; +} +.EditableName:after, .Name:after { color: var(--color-text-color); content: ': '; diff --git a/src/devtools/views/Components/HooksTree.js b/src/devtools/views/Components/HooksTree.js index 65cfb9cc22..c95f6b9b3c 100644 --- a/src/devtools/views/Components/HooksTree.js +++ b/src/devtools/views/Components/HooksTree.js @@ -110,12 +110,7 @@ function HookView({ canEditHooks, hook, id, path = [] }: HookViewProps) {
{name}
- + @@ -170,7 +164,15 @@ function HookView({ canEditHooks, hook, id, path = [] }: HookViewProps) { return (
- {name} + + {name} + {typeof overrideValueFn === 'function' ? ( , value: any) => void; type KeyValueProps = {| depth: number, name: string, - nameClassName?: string, overrideValueFn?: ?OverrideValueFn, path?: Array, value: any, @@ -20,7 +19,6 @@ type KeyValueProps = {| export default function KeyValue({ depth, name, - nameClassName = styles.Name, overrideValueFn, path = [], value, @@ -47,6 +45,9 @@ export default function KeyValue({ displayValue = 'undefined'; } + const nameClassName = + typeof overrideValueFn === 'function' ? styles.EditableName : styles.Name; + children = (
{name} @@ -66,7 +67,7 @@ export default function KeyValue({ // TODO Is this type even necessary? Can we just drop it? children = (
- {name} + {name} {getMetaValueLabel(value)}
); @@ -88,7 +89,7 @@ export default function KeyValue({ className={styles.Item} style={{ paddingLeft }} > - {name} + {name} Array
); @@ -110,7 +111,7 @@ export default function KeyValue({ className={styles.Item} style={{ paddingLeft }} > - {name} + {name} Object
); diff --git a/src/devtools/views/Components/SelectedElement.js b/src/devtools/views/Components/SelectedElement.js index 2cec5677ba..76b338feec 100644 --- a/src/devtools/views/Components/SelectedElement.js +++ b/src/devtools/views/Components/SelectedElement.js @@ -15,7 +15,12 @@ import HooksTree from './HooksTree'; import InspectedElementTree from './InspectedElementTree'; import { hydrate } from 'src/hydration'; import styles from './SelectedElement.css'; -import { ElementTypeClass, ElementTypeFunction } from '../../types'; +import { + ElementTypeClass, + ElementTypeForwardRef, + ElementTypeFunction, + ElementTypeMemo, +} from '../../types'; import type { InspectedElement } from './types'; import type { DehydratedData, Element } from './types'; @@ -145,7 +150,12 @@ function InspectedElementView({ const rendererID = store.getRendererIDForElement(id); bridge.send('overrideState', { id, path, rendererID, value }); }; - } else if (type === ElementTypeFunction && canEditFunctionProps) { + } else if ( + (type === ElementTypeFunction || + type === ElementTypeMemo || + type === ElementTypeForwardRef) && + canEditFunctionProps + ) { overridePropsFn = (path: Array, value: any) => { const rendererID = store.getRendererIDForElement(id); bridge.send('overrideProps', { id, path, rendererID, value });