mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Alpha-sort props/state/context keys
This commit is contained in:
@@ -164,6 +164,7 @@ function HookView({
|
||||
) : (
|
||||
<KeyValue
|
||||
depth={1}
|
||||
alphaSort={false}
|
||||
inspectPath={inspectPath}
|
||||
name="subHooks"
|
||||
path={path.concat(['subHooks'])}
|
||||
@@ -186,6 +187,7 @@ function HookView({
|
||||
<div className={styles.Children} hidden={!isOpen}>
|
||||
<KeyValue
|
||||
depth={1}
|
||||
alphaSort={false}
|
||||
inspectPath={inspectPath}
|
||||
name="DebugValue"
|
||||
path={path.concat(['value'])}
|
||||
@@ -242,6 +244,7 @@ function HookView({
|
||||
<div className={styles.Hook}>
|
||||
<KeyValue
|
||||
depth={1}
|
||||
alphaSort={false}
|
||||
inspectPath={inspectPath}
|
||||
name={name}
|
||||
overrideValueFn={overrideValueFn}
|
||||
|
||||
@@ -5,7 +5,7 @@ import React, { useCallback } from 'react';
|
||||
import Button from '../Button';
|
||||
import ButtonIcon from '../ButtonIcon';
|
||||
import KeyValue from './KeyValue';
|
||||
import { serializeDataForCopy } from '../utils';
|
||||
import { alphaSortEntries, serializeDataForCopy } from '../utils';
|
||||
import styles from './InspectedElementTree.css';
|
||||
|
||||
import type { InspectPath } from './SelectedElement';
|
||||
@@ -27,7 +27,12 @@ export default function InspectedElementTree({
|
||||
overrideValueFn,
|
||||
showWhenEmpty = false,
|
||||
}: Props) {
|
||||
const isEmpty = data === null || Object.keys(data).length === 0;
|
||||
const entries = data != null ? Object.entries(data) : null;
|
||||
if (entries !== null) {
|
||||
entries.sort(alphaSortEntries);
|
||||
}
|
||||
|
||||
const isEmpty = entries === null || entries.length === 0;
|
||||
|
||||
const handleCopy = useCallback(() => copy(serializeDataForCopy(data)), [
|
||||
data,
|
||||
@@ -48,15 +53,16 @@ export default function InspectedElementTree({
|
||||
</div>
|
||||
{isEmpty && <div className={styles.Empty}>None</div>}
|
||||
{!isEmpty &&
|
||||
Object.keys((data: any)).map(name => (
|
||||
(entries: any).map(([name, value]) => (
|
||||
<KeyValue
|
||||
key={name}
|
||||
alphaSort={true}
|
||||
depth={1}
|
||||
inspectPath={inspectPath}
|
||||
name={name}
|
||||
overrideValueFn={overrideValueFn}
|
||||
path={[name]}
|
||||
value={(data: any)[name]}
|
||||
value={value}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
||||
@@ -4,7 +4,7 @@ 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 { alphaSortEntries, getMetaValueLabel } from '../utils';
|
||||
import { meta } from '../../../hydration';
|
||||
import styles from './KeyValue.css';
|
||||
|
||||
@@ -13,6 +13,7 @@ import type { InspectPath } from './SelectedElement';
|
||||
type OverrideValueFn = (path: Array<string | number>, value: any) => void;
|
||||
|
||||
type KeyValueProps = {|
|
||||
alphaSort: boolean,
|
||||
depth: number,
|
||||
hidden?: boolean,
|
||||
inspectPath?: InspectPath,
|
||||
@@ -24,6 +25,7 @@ type KeyValueProps = {|
|
||||
|};
|
||||
|
||||
export default function KeyValue({
|
||||
alphaSort,
|
||||
depth,
|
||||
inspectPath,
|
||||
isReadOnly,
|
||||
@@ -127,6 +129,7 @@ export default function KeyValue({
|
||||
children = value.map((innerValue, index) => (
|
||||
<KeyValue
|
||||
key={index}
|
||||
alphaSort={alphaSort}
|
||||
depth={depth + 1}
|
||||
inspectPath={inspectPath}
|
||||
isReadOnly={isReadOnly}
|
||||
@@ -162,15 +165,24 @@ export default function KeyValue({
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
const hasChildren = Object.entries(value).length > 0;
|
||||
// TRICKY
|
||||
// It's important to use Object.entries() rather than Object.keys()
|
||||
// because of the hidden meta Symbols used for hydration and unserializable values.
|
||||
const entries = Object.entries(value);
|
||||
if (alphaSort) {
|
||||
entries.sort(alphaSortEntries);
|
||||
}
|
||||
|
||||
const hasChildren = entries.length > 0;
|
||||
const displayName = value.hasOwnProperty(meta.unserializable)
|
||||
? getMetaValueLabel(value)
|
||||
: 'Object';
|
||||
|
||||
let areChildrenReadOnly = isReadOnly || !!value[meta.readonly];
|
||||
children = Object.entries(value).map<Element<any>>(([name, value]) => (
|
||||
children = entries.map<Element<any>>(([name, value]) => (
|
||||
<KeyValue
|
||||
key={name}
|
||||
alphaSort={alphaSort}
|
||||
depth={depth + 1}
|
||||
inspectPath={inspectPath}
|
||||
isReadOnly={areChildrenReadOnly}
|
||||
|
||||
@@ -5,6 +5,21 @@ import { meta } from '../../hydration';
|
||||
|
||||
import type { HooksTree } from 'src/backend/types';
|
||||
|
||||
export function alphaSortEntries(
|
||||
entryA: [string, mixed],
|
||||
entryB: [string, mixed]
|
||||
): number {
|
||||
const a = entryA[0];
|
||||
const b = entryB[0];
|
||||
if ('' + +a === a) {
|
||||
if ('' + +b !== b) {
|
||||
return -1;
|
||||
}
|
||||
return +a < +b ? -1 : 1;
|
||||
}
|
||||
return a < b ? -1 : 1;
|
||||
}
|
||||
|
||||
export function createRegExp(string: string): RegExp {
|
||||
// Allow /regex/ syntax with optional last /
|
||||
if (string[0] === '/') {
|
||||
|
||||
Reference in New Issue
Block a user