Skip to content

Commit

Permalink
Made some inline tweaks
Browse files Browse the repository at this point in the history
  • Loading branch information
Brian Vaughn committed Sep 10, 2019
1 parent 389010a commit 0373472
Show file tree
Hide file tree
Showing 7 changed files with 198 additions and 200 deletions.
34 changes: 32 additions & 2 deletions packages/react-devtools-shared/src/devtools/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,40 @@ export function printStore(store: Store, includeWeight: boolean = false) {
// so this method replaces e.g. 'foo' with "foo"
export function sanitizeForParse(value: any) {
if (typeof value === 'string') {
if (value.charAt(0) === "'" && value.charAt(value.length - 1) === "'") {
if (
value.length >= 2 &&
value.charAt(0) === "'" &&
value.charAt(value.length - 1) === "'"
) {
return '"' + value.substr(1, value.length - 2) + '"';
}
}

return value;
}

export function smartParse(value: any) {
switch (value) {
case 'Infinity':
return Infinity;
case 'NaN':
return NaN;
case 'undefined':
return undefined;
default:
return JSON.parse(sanitizeForParse(value));
}
}

export function smartStringify(value: any) {
if (typeof value === 'number') {
if (Number.isNaN(value)) {
return 'NaN';
} else if (!Number.isFinite(value)) {
return 'Infinity';
}
} else if (value === undefined) {
return 'undefined';
}

return JSON.stringify(value);
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
.Input {
width: 100px;
background: none;
border: 1px solid transparent;
color: var(--color-attribute-name);
border-radius: 0.125rem;
font-family: var(--font-family-monospace);
font-size: var(--font-size-monospace-normal);
flex: 0 1 auto;
padding: 1px;
box-shadow: 0px 1px 3px transparent;
}

.Input:focus {
color: var(--color-attribute-editable-value);
background-color: var(--color-button-background-focus);
outline: none;
}
color: var(--color-text);
box-shadow: 0px 1px 3px var(--color-shadow);
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,25 @@
* @flow
*/

import React, {useRef, useCallback, useEffect, useState} from 'react';
import React, {useCallback, useState} from 'react';
import AutoSizeInput from './NativeStyleEditor/AutoSizeInput';
import styles from './EditableName.css';

type OverrideNameFn = (path: Array<string | number>, value: any) => void;

type EditableNameProps = {|
autoFocus?: boolean,
initialValue?: string,
overrideNameFn: OverrideNameFn,
|};

export default function EditableName({
autoFocus = false,
initialValue = '',
overrideNameFn,
}: EditableNameProps) {
const [editableName, setEditableName] = useState(initialValue);
const [isValid, setIsValid] = useState(false);
const inputRef = useRef<HTMLInputElement | null>(null);

useEffect(() => {
if (inputRef.current !== null) {
inputRef.current.focus();
}
}, []);

const handleChange = useCallback(
({target}) => {
Expand All @@ -51,23 +47,30 @@ export default function EditableName({
// Prevent keydown events from e.g. change selected element in the tree
event.stopPropagation();

const eventKey = event.key;

if ((eventKey === 'Enter' || eventKey === 'Tab') && isValid) {
overrideNameFn(editableName);
} else if (eventKey === 'Escape') {
setEditableName(initialValue);
switch (event.key) {
case 'Enter':
case 'Tab':
if (isValid) {
overrideNameFn(editableName);
}
break;
case 'Escape':
setEditableName(initialValue);
break;
default:
break;
}
},
[editableName, setEditableName, isValid, initialValue, overrideNameFn],
);

return (
<input
<AutoSizeInput
autoFocus={autoFocus}
className={styles.Input}
onChange={handleChange}
onKeyDown={handleKeyDown}
ref={inputRef}
placeholder="new prop"
type="text"
value={editableName}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,161 +7,89 @@
* @flow
*/

import React, {Fragment, useCallback, useRef, useState} from 'react';
import React, {Fragment, useCallback, useRef} from 'react';
import Button from '../Button';
import ButtonIcon from '../ButtonIcon';
import styles from './EditableValue.css';
import {sanitizeForParse} from '../../utils';
import {useEditableValue} from '../hooks';

type OverrideValueFn = (path: Array<string | number>, value: any) => void;

type EditableValueProps = {|
dataType: string,
initialValue: any,
overrideValueFn: OverrideValueFn,
path: Array<string | number>,
initialValue: any,
|};

export default function EditableValue({
dataType,
initialValue,
overrideValueFn,
path,
initialValue,
}: EditableValueProps) {
const [isValid, setIsValid] = useState(true);
const [hasPendingChanges, setHasPendingChanges] = useState(false);
const [editableValue, setEditableValue] = useEditableValue(initialValue);
const inputRef = useRef<HTMLInputElement | null>(null);

if (hasPendingChanges && editableValue === JSON.stringify(initialValue)) {
setHasPendingChanges(false);
}

const handleChange = useCallback(
({target}) => {
if (dataType === 'boolean') {
setEditableValue(target.checked, {shouldStringify: true});
overrideValueFn(path, target.checked);
} else {
let isValidJSON = false;
try {
JSON.parse(sanitizeForParse(target.value));
isValidJSON = true;
} catch (error) {}

setIsValid(isValidJSON);
setEditableValue(target.value);
}
setHasPendingChanges(true);
},
[dataType, overrideValueFn, path],
);

const handleReset = useCallback(
() => {
setEditableValue(initialValue, {shouldStringify: true});
setHasPendingChanges(false);
setIsValid(true);

if (inputRef.current !== null) {
inputRef.current.focus();
}
},
[initialValue],
);
const {
editableValue,
hasPendingChanges,
isValid,
parsedValue,
reset,
update,
} = useEditableValue(initialValue);

const handleChange = useCallback(({target}) => update(target.value), [
update,
]);

const handleKeyDown = useCallback(
event => {
// Prevent keydown events from e.g. change selected element in the tree
event.stopPropagation();

const {key} = event;

if (key === 'Enter' && isValid) {
const parsedEditableValue = JSON.parse(sanitizeForParse(editableValue));

if (initialValue !== parsedEditableValue) {
overrideValueFn(path, parsedEditableValue);
}

// Don't reset the pending change flag here.
// The inspected fiber won't be updated until after the next "inspectElement" message.
// We'll reset that flag during a subsequent render.
} else if (key === 'Escape') {
setEditableValue(initialValue, {shouldStringify: true});
setHasPendingChanges(false);
setIsValid(true);
switch (event.key) {
case 'Enter':
if (isValid && hasPendingChanges) {
overrideValueFn(path, parsedValue);
}
break;
case 'Escape':
reset();
break;
default:
break;
}
},
[editableValue, isValid, dataType, overrideValueFn, path, initialValue],
[hasPendingChanges, isValid, overrideValueFn, parsedValue, reset],
);

let inputValue =
initialValue === undefined ? '' : JSON.stringify(initialValue);
if (hasPendingChanges) {
inputValue = editableValue;
}

let placeholder = '';
if (initialValue === undefined) {
if (editableValue === undefined) {
placeholder = '(undefined)';
} else {
placeholder = 'Enter valid JSON';
}

return (
<Fragment>
{dataType === 'boolean' && (
<label className={styles.CheckboxLabel}>
<input
checked={inputValue === 'true'}
className={styles.Checkbox}
onChange={handleChange}
onKeyDown={handleKeyDown}
ref={inputRef}
type="checkbox"
/>
</label>
<input
autoComplete="new-password"
className={isValid ? styles.Input : styles.Invalid}
onChange={handleChange}
onKeyDown={handleKeyDown}
placeholder={placeholder}
ref={inputRef}
type="text"
value={editableValue}
/>
{hasPendingChanges && (
<Button
className={styles.ResetButton}
onClick={reset}
title="Reset value">
<ButtonIcon type="undo" />
</Button>
)}
{dataType !== 'boolean' && (
<input
className={isValid ? styles.Input : styles.Invalid}
onChange={handleChange}
onKeyDown={handleKeyDown}
placeholder={placeholder}
ref={inputRef}
type="text"
value={inputValue}
/>
)}
{hasPendingChanges &&
dataType !== 'boolean' && (
<Button
className={styles.ResetButton}
onClick={handleReset}
title="Reset value">
<ButtonIcon type="undo" />
</Button>
)}
</Fragment>
);
}

function useEditableValue(initialValue: any): [any, Function] {
const [editableValue, setEditableValue] = useState(
JSON.stringify(initialValue),
);

function setEditableValueWithStringify(
value: any,
{shouldStringify}: Object = {},
) {
if (shouldStringify) {
setEditableValue(JSON.stringify(value));
} else {
setEditableValue(value);
}
}

return [editableValue, setEditableValueWithStringify];
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@
}

.AddEntry {
padding-left: 1rem;
white-space: nowrap;
display: flex;
padding-left: 0.9rem;
align-items: center;
}
Loading

0 comments on commit 0373472

Please sign in to comment.