Skip to content

Commit 734791e

Browse files
committed
Highlight the rect when the corresponding timeline bean is hovered
1 parent e70e116 commit 734791e

File tree

4 files changed

+31
-12
lines changed

4 files changed

+31
-12
lines changed

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
background-color: color-mix(in srgb, var(--color-transition) 5%, transparent);
99
}
1010

11-
.SuspenseRectsContainer:hover:not(:has(.SuspenseRectsBoundary:hover))[data-highlighted='false'] {
12-
outline-width: 1px;
11+
.SuspenseRectsContainer[data-hovered='true'] {
12+
background-color: color-mix(in srgb, var(--color-transition) 15%, transparent);
1313
}
1414

1515
.SuspenseRectsContainer[data-highlighted='true'] {
@@ -65,7 +65,7 @@
6565
}
6666

6767
/* highlight this boundary */
68-
.SuspenseRectsBoundary:hover:not(:has(.SuspenseRectsBoundary:hover)) > .SuspenseRectsRect {
68+
.SuspenseRectsBoundary[data-hovered='true'] > .SuspenseRectsRect {
6969
background-color: color-mix(in srgb, var(--color-background) 50%, var(--color-suspense) 50%);
7070
transition: background-color 0.2s ease-out;
7171
}

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

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ function ScaledRect({
3737
visible,
3838
suspended,
3939
selected,
40+
hovered,
4041
adjust,
4142
...props
4243
}: {
@@ -45,6 +46,7 @@ function ScaledRect({
4546
visible: boolean,
4647
suspended: boolean,
4748
selected?: boolean,
49+
hovered?: boolean,
4850
adjust?: boolean,
4951
...
5052
}): React$Node {
@@ -61,6 +63,7 @@ function ScaledRect({
6163
data-visible={visible}
6264
data-suspended={suspended}
6365
data-selected={selected}
66+
data-hovered={hovered}
6467
style={{
6568
// Shrink one pixel so that the bottom outline will line up with the top outline of the next one.
6669
width: adjust ? 'calc(' + width + ' - 1px)' : width,
@@ -80,7 +83,9 @@ function SuspenseRects({
8083
const store = useContext(StoreContext);
8184
const treeDispatch = useContext(TreeDispatcherContext);
8285
const suspenseTreeDispatch = useContext(SuspenseTreeDispatcherContext);
83-
const {uniqueSuspendersOnly} = useContext(SuspenseTreeStateContext);
86+
const {uniqueSuspendersOnly, timeline, hoveredTimelineIndex} = useContext(
87+
SuspenseTreeStateContext,
88+
);
8489

8590
const {inspectedElementID} = useContext(TreeStateContext);
8691

@@ -148,6 +153,9 @@ function SuspenseRects({
148153
// TODO: Use the nearest Suspense boundary
149154
const selected = inspectedElementID === suspenseID;
150155

156+
const hovered =
157+
hoveredTimelineIndex > -1 && timeline[hoveredTimelineIndex] === suspenseID;
158+
151159
const boundingBox = getBoundingBox(suspense.rects);
152160

153161
return (
@@ -156,7 +164,8 @@ function SuspenseRects({
156164
className={styles.SuspenseRectsBoundary}
157165
visible={visible}
158166
selected={selected}
159-
suspended={suspense.isSuspended}>
167+
suspended={suspense.isSuspended}
168+
hovered={hovered}>
160169
<ViewBox.Provider value={boundingBox}>
161170
{visible &&
162171
suspense.rects !== null &&
@@ -317,7 +326,7 @@ function SuspenseRectsContainer(): React$Node {
317326
const treeDispatch = useContext(TreeDispatcherContext);
318327
const suspenseTreeDispatch = useContext(SuspenseTreeDispatcherContext);
319328
// TODO: This relies on a full re-render of all children when the Suspense tree changes.
320-
const {roots} = useContext(SuspenseTreeStateContext);
329+
const {roots, hoveredTimelineIndex} = useContext(SuspenseTreeStateContext);
321330

322331
// TODO: bbox does not consider uniqueSuspendersOnly filter
323332
const boundingBox = getDocumentBoundingRect(store, roots);
@@ -361,13 +370,15 @@ function SuspenseRectsContainer(): React$Node {
361370
}
362371

363372
const isRootSelected = roots.includes(inspectedElementID);
373+
const isRootHovered = hoveredTimelineIndex === 0;
364374

365375
return (
366376
<div
367377
className={styles.SuspenseRectsContainer}
368378
onClick={handleClick}
369379
onDoubleClick={handleDoubleClick}
370-
data-highlighted={isRootSelected}>
380+
data-highlighted={isRootSelected}
381+
data-hovered={isRootHovered}>
371382
<ViewBox.Provider value={boundingBox}>
372383
<div
373384
className={styles.SuspenseRectsViewBox}

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,7 @@
5454
background: var(--color-transition);
5555
}
5656

57-
.SuspenseScrubberStepHighlight > .SuspenseScrubberBead,
58-
.SuspenseScrubberStep:hover > .SuspenseScrubberBead {
57+
.SuspenseScrubberStepHighlight > .SuspenseScrubberBead {
5958
height: 0.75rem;
6059
transition: all 0.3s ease-out;
6160
}

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

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,19 @@ function SuspenseTimelineInput() {
5353
switchSuspenseNode(timelineIndex);
5454
}
5555

56-
function handleHoverSegment(hoveredValue: number) {
57-
// TODO: Consider highlighting the rect instead.
56+
function handleHoverSegment(hoveredIndex: number) {
57+
const nextSelectedSuspenseID = timeline[hoveredIndex];
58+
suspenseTreeDispatch({
59+
type: 'HOVER_TIMELINE_FOR_ID',
60+
payload: nextSelectedSuspenseID,
61+
});
62+
}
63+
function handleUnhoverSegment() {
64+
suspenseTreeDispatch({
65+
type: 'HOVER_TIMELINE_FOR_ID',
66+
payload: -1,
67+
});
5868
}
59-
function handleUnhoverSegment() {}
6069

6170
function skipPrevious() {
6271
const nextSelectedSuspenseID = timeline[timelineIndex - 1];

0 commit comments

Comments
 (0)