main
js 108 lines 2.59 KB
Raw
1 /**
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 *
7 * @flow
8 */
9
10 import * as React from 'react';
11 import {useState} from 'react';
12 import Store from '../../store';
13 import EditableName from './EditableName';
14 import {smartParse} from '../../utils';
15 import {parseHookPathForEdit} from './utils';
16 import styles from './NewArrayValue.css';
17
18 import type {InspectedElement} from 'react-devtools-shared/src/frontend/types';
19 import type {FrontendBridge} from 'react-devtools-shared/src/bridge';
20
21 type Props = {
22 bridge: FrontendBridge,
23 depth: number,
24 hidden: boolean,
25 hookID?: ?number,
26 index: number,
27 inspectedElement: InspectedElement,
28 path: Array<string | number>,
29 store: Store,
30 type: 'props' | 'context' | 'hooks' | 'state',
31 };
32
33 export default function NewArrayValue({
34 bridge,
35 depth,
36 hidden,
37 hookID,
38 index,
39 inspectedElement,
40 path,
41 store,
42 type,
43 }: Props): React.Node {
44 const [key, setKey] = useState<number>(0);
45 const [isInvalid, setIsInvalid] = useState(false);
46
47 // This is a bit of an unusual usage of the EditableName component,
48 // but otherwise it acts the way we want for a new Array entry.
49 // $FlowFixMe[missing-local-annot]
50 const overrideName = (oldPath: any, newPath) => {
51 const value = newPath[newPath.length - 1];
52
53 let parsedValue;
54 let newIsInvalid = true;
55 try {
56 parsedValue = smartParse(value);
57 newIsInvalid = false;
58 } catch (error) {}
59
60 if (isInvalid !== newIsInvalid) {
61 setIsInvalid(newIsInvalid);
62 }
63
64 if (!newIsInvalid) {
65 setKey(key + 1);
66
67 const {id} = inspectedElement;
68 const rendererID = store.getRendererIDForElement(id);
69 if (rendererID !== null) {
70 let basePath = path;
71 if (hookID != null) {
72 basePath = parseHookPathForEdit(basePath);
73 }
74
75 bridge.send('overrideValueAtPath', {
76 type,
77 hookID,
78 id,
79 path: [...basePath, index],
80 rendererID,
81 value: parsedValue,
82 });
83 }
84 }
85 };
86
87 return (
88 <div
89 key={key}
90 hidden={hidden}
91 style={{
92 paddingLeft: `${(depth - 1) * 0.75}rem`,
93 }}>
94 <div className={styles.NewArrayValue}>
95 <EditableName
96 allowWhiteSpace={true}
97 autoFocus={key > 0}
98 className={[styles.EditableName, isInvalid && styles.Invalid].join(
99 ' ',
100 )}
101 initialValue=""
102 overrideName={overrideName}
103 path={path}
104 />
105 </div>
106 </div>
107 );
108 }