Skip to content

Commit 6fb7754

Browse files
authored
[DevTools] Render selected outline on top of every other rect (facebook#35012)
When rects are close together (or overlapping) the outline can end up being covered up by sibling rects or deeper rects. This renders the selected outline on top of everything so it's always visible. <img width="275" height="730" alt="Screenshot 2025-10-29 at 8 43 28 PM" src="https://github.com/user-attachments/assets/69224883-f548-45ec-ada1-1a04ec17eaf5" /> <img width="266" height="737" alt="Screenshot 2025-10-29 at 8 58 53 PM" src="https://github.com/user-attachments/assets/946f7dde-450d-49fd-9fbd-57487f67f461" /> Additionally, this makes it so that it's not part of the translucent tree when things are hidden by the timeline. That way it's easier to see what is selected inside a hidden tree. <img width="498" height="196" alt="Screenshot 2025-10-29 at 8 45 24 PM" src="https://github.com/user-attachments/assets/723107ab-a92c-42c2-8a7d-a548ac3332d0" /> <img width="571" height="735" alt="Screenshot 2025-10-29 at 8 59 06 PM" src="https://github.com/user-attachments/assets/d653f1a7-4096-45c3-b92a-ef155d4742e6" />
1 parent 3a0ab8a commit 6fb7754

File tree

2 files changed

+38
-14
lines changed

2 files changed

+38
-14
lines changed

packages/react-devtools-shared/src/devtools/views/SuspenseTab/SuspenseRects.css

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,6 @@
66
border-radius: 0.25rem;
77
}
88

9-
.SuspenseRectsContainer[data-highlighted='true'] {
10-
outline-color: var(--color-transition);
11-
outline-style: solid;
12-
outline-width: 4px;
13-
}
14-
159
.SuspenseRectsRoot {
1610
cursor: pointer;
1711
outline-color: var(--color-transition);
@@ -106,6 +100,10 @@
106100
pointer-events: none;
107101
}
108102

103+
.SuspenseRectOutlineRoot {
104+
outline-color: var(--color-transition);
105+
}
106+
109107
.SuspenseRectsBoundary[data-selected='true'] > .SuspenseRectsRect {
110108
box-shadow: none;
111109
}

packages/react-devtools-shared/src/devtools/views/SuspenseTab/SuspenseRects.js

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -236,13 +236,6 @@ function SuspenseRects({
236236
<span>{suspense.name}</span>
237237
</ScaledRect>
238238
) : null}
239-
{selected && visible ? (
240-
<ScaledRect
241-
className={styles.SuspenseRectOutline}
242-
rect={boundingBox}
243-
adjust={true}
244-
/>
245-
) : null}
246239
</ViewBox.Provider>
247240
</ScaledRect>
248241
);
@@ -514,6 +507,28 @@ function SuspenseRectsContainer({
514507
scaleRef.current = boundingBoxWidth;
515508
}, [boundingBoxWidth]);
516509

510+
let selectedBoundingBox = null;
511+
let selectedEnvironment = null;
512+
if (isRootSelected) {
513+
selectedBoundingBox = boundingBox;
514+
selectedEnvironment = rootEnvironment;
515+
} else if (inspectedElementID !== null) {
516+
const selectedSuspenseNode = store.getSuspenseByID(inspectedElementID);
517+
if (
518+
selectedSuspenseNode !== null &&
519+
(selectedSuspenseNode.hasUniqueSuspenders || !uniqueSuspendersOnly)
520+
) {
521+
selectedBoundingBox = getBoundingBox(selectedSuspenseNode.rects);
522+
for (let i = 0; i < timeline.length; i++) {
523+
const timelineStep = timeline[i];
524+
if (timelineStep.id === inspectedElementID) {
525+
selectedEnvironment = timelineStep.environment;
526+
break;
527+
}
528+
}
529+
}
530+
}
531+
517532
return (
518533
<div
519534
className={
@@ -524,7 +539,6 @@ function SuspenseRectsContainer({
524539
}
525540
onClick={handleClick}
526541
onDoubleClick={handleDoubleClick}
527-
data-highlighted={isRootSelected}
528542
data-hovered={isRootHovered}>
529543
<ViewBox.Provider value={boundingBox}>
530544
<div
@@ -533,6 +547,18 @@ function SuspenseRectsContainer({
533547
{roots.map(rootID => {
534548
return <SuspenseRectsRoot key={rootID} rootID={rootID} />;
535549
})}
550+
{selectedBoundingBox !== null ? (
551+
<ScaledRect
552+
className={
553+
styles.SuspenseRectOutline +
554+
(isRootSelected ? ' ' + styles.SuspenseRectOutlineRoot : '') +
555+
' ' +
556+
getClassNameForEnvironment(selectedEnvironment)
557+
}
558+
rect={selectedBoundingBox}
559+
adjust={true}
560+
/>
561+
) : null}
536562
</div>
537563
</ViewBox.Provider>
538564
</div>

0 commit comments

Comments
 (0)