10
import * as React from 'react';
11
import {Fragment, useContext, useMemo, useState} from 'react';
12
import Store from 'react-devtools-shared/src/devtools/store';
13
-import Badge from './Badge';
13
import ButtonIcon from '../ButtonIcon';
15
-import {createRegExp} from '../utils';
14
import {TreeDispatcherContext, TreeStateContext} from './TreeContext';
15
import {SettingsContext} from '../Settings/SettingsContext';
16
import {StoreContext} from '../context';
17
import {useSubscription} from '../hooks';
18
import {logEvent} from 'react-devtools-shared/src/Logger';
19
+import IndexableElementBadges from './IndexableElementBadges';
20
+import IndexableDisplayName from './IndexableDisplayName';
21
22
import type {ItemData} from './Tree';
23
import type {Element as ElementType} from 'react-devtools-shared/src/frontend/types';
121
hocDisplayNames,
122
isStrictModeNonCompliant,
123
key,
124
- type,
124
+ compiledWithForget,
125
} = element;
126
127
// Only show strict mode non-compliance badges for top level elements.
155
// We must use padding rather than margin/left because of the selected background color.
156
transform: `translateX(calc(${depth} * var(--indentation-size)))`,
157
}}>
158
- {ownerID === null ? (
158
+ {ownerID === null && (
159
<ExpandCollapseToggle element={element} store={store} />
160
- ) : null}
160
+ )}
161
162
- <DisplayName displayName={displayName} id={((id: any): number)} />
162
+ <IndexableDisplayName displayName={displayName} id={id} />
163
164
{key && (
165
<Fragment>
174
</Fragment>
175
)}
176
177
- {hocDisplayNames !== null && hocDisplayNames.length > 0 ? (
178
- <Badge
179
- className={styles.Badge}
180
- hocDisplayNames={hocDisplayNames}
181
- type={type}>
182
- <DisplayName displayName={hocDisplayNames[0]} id={id} />
183
- </Badge>
184
- ) : null}
177
+ <IndexableElementBadges
178
+ hocDisplayNames={hocDisplayNames}
179
+ compiledWithForget={compiledWithForget}
180
+ elementID={id}
181
+ className={styles.BadgesBlock}
182
+ />
183
184
{showInlineWarningsAndErrors && errorCount > 0 && (
185
<Icon
260
</div>
261
);
262
}
265
-
266
-type DisplayNameProps = {
267
- displayName: string | null,
268
- id: number,
269
-};
270
-
271
-function DisplayName({displayName, id}: DisplayNameProps) {
272
- const {searchIndex, searchResults, searchText} = useContext(TreeStateContext);
273
- const isSearchResult = useMemo(() => {
274
- return searchResults.includes(id);
275
- }, [id, searchResults]);
276
- const isCurrentResult =
277
- searchIndex !== null && id === searchResults[searchIndex];
278
-
279
- if (!isSearchResult || displayName === null) {
280
- return displayName;
281
- }
282
-
283
- const match = createRegExp(searchText).exec(displayName);
284
-
285
- if (match === null) {
286
- return displayName;
287
- }
288
-
289
- const startIndex = match.index;
290
- const stopIndex = startIndex + match[0].length;
291
-
292
- const children = [];
293
- if (startIndex > 0) {
294
- children.push(<span key="begin">{displayName.slice(0, startIndex)}</span>);
295
- }
296
- children.push(
297
- <mark
298
- key="middle"
299
- className={isCurrentResult ? styles.CurrentHighlight : styles.Highlight}>
300
- {displayName.slice(startIndex, stopIndex)}
301
- </mark>,
302
- );
303
- if (stopIndex < displayName.length) {
304
- children.push(<span key="end">{displayName.slice(stopIndex)}</span>);
305
- }
306
-
307
- return children;
308
-}