[DevTools] Redesign the Profiler empty states around a primary action (#37185)
| Before | After | |--------|--------| | <img width="752" height="835" alt="before" src="https://github.com/user-attachments/assets/225d131c-a09c-44dd-ae79-0d76a8874d70" /> | <img width="751" height="832" alt="after" src="https://github.com/user-attachments/assets/8547a921-adc4-4abb-a40f-5ae74c1287b2" /> |
Ruslan Lesiutin committed
Aug 3, 2026 at 16:32 UTC
0011363766afbea28f1bb76d165cbbbdee67b51f
3 files changed
+63
-28
packages/react-devtools-shared/src/devtools/views/Profiler/NoProfilingData.js
+18
-12
@@ -8,28 +8,34 @@
8
*/
9
10
import * as React from 'react';
11
-import RecordToggle from './RecordToggle';
11
+import {useContext} from 'react';
12
+import {ProfilerContext} from './ProfilerContext';
13
14
import styles from './Profiler.css';
15
16
export default function NoProfilingData(): React.Node {
17
+ const {startProfiling} = useContext(ProfilerContext);
18
+
19
return (
20
<div className={styles.Column}>
18
- <div className={styles.Header}>No profiling data has been recorded.</div>
19
- <div className={styles.Row}>
20
- Click the record button <RecordToggle /> to start recording.
21
- </div>
22
- <div className={`${styles.Row} ${styles.LearnMoreRow}`}>
23
- Click{' '}
21
+ <div className={styles.Header}>No profiling data has been recorded</div>
22
+ <div className={styles.Description}>
23
+ Record a session to see which components rendered, how long they took,
24
+ and why.{' '}
25
<a
25
- className={styles.LearnMoreLink}
26
- href="https://fb.me/react-devtools-profiling"
26
+ className={styles.DescriptionLink}
27
+ href="https://legacy.reactjs.org/blog/2018/09/10/introducing-the-react-profiler.html"
28
rel="noopener noreferrer"
29
target="_blank">
29
- here
30
- </a>{' '}
31
- to learn more about profiling.
30
+ Learn more
31
+ </a>
32
</div>
33
+ <button
34
+ className={styles.CTAButton}
35
+ onClick={startProfiling}
36
+ type="button">
37
+ Start recording
38
+ </button>
39
</div>
40
);
41
}
packages/react-devtools-shared/src/devtools/views/Profiler/Profiler.css
+35
-12
@@ -61,15 +61,44 @@
61
justify-content: center;
62
}
63
64
-.LearnMoreRow {
65
- margin-top: 1rem;
64
+.Header {
65
+ font-size: var(--font-size-sans-large);
66
+ font-weight: bold;
67
+ margin-bottom: 0.25rem;
68
+}
69
+
70
+.Description {
71
+ max-width: 26rem;
72
+ text-align: center;
73
color: var(--color-dim);
67
- font-size: var(--font-size-sans-small);
74
}
75
70
-.Header {
71
- font-size: var(--font-size-sans-large);
72
- margin-bottom: 0.5rem;
76
+.DescriptionLink {
77
+ color: var(--color-link);
78
+ text-decoration: underline;
79
+}
80
+
81
+.CTAButton {
82
+ margin-top: 0.5rem;
83
+ padding: 0.375rem 1rem;
84
+ border: none;
85
+ border-radius: 1rem;
86
+ background: var(--color-background-hover);
87
+ color: var(--color-button-focus);
88
+ font-family: inherit;
89
+ font-size: var(--font-size-sans-normal);
90
+ font-weight: bold;
91
+ cursor: pointer;
92
+}
93
+
94
+.CTAButton:hover {
95
+ background: var(--color-background-selected);
96
+ color: var(--color-text-selected);
97
+}
98
+
99
+.CTAButton:focus-visible {
100
+ outline: 2px solid var(--color-button-active);
101
+ outline-offset: 2px;
102
}
103
104
.Toolbar {
@@ -127,9 +156,3 @@
156
display: flex;
157
align-items: center;
158
}
130
-
131
-.LearnMoreLink {
132
- color: var(--color-link);
133
- margin-left: 0.25rem;
134
- margin-right: 0.25rem;
135
-}
\ No newline at end of file
packages/react-devtools-shared/src/devtools/views/Profiler/RecordingInProgress.js
+10
-4
@@ -8,17 +8,23 @@
8
*/
9
10
import * as React from 'react';
11
-import RecordToggle from './RecordToggle';
11
+import {useContext} from 'react';
12
+import {ProfilerContext} from './ProfilerContext';
13
14
import styles from './Profiler.css';
15
16
export default function RecordingInProgress(): React.Node {
17
+ const {stopProfiling} = useContext(ProfilerContext);
18
+
19
return (
20
<div className={styles.Column}>
21
<div className={styles.Header}>Profiling is in progress...</div>
19
- <div className={styles.Row}>
20
- Click the record button <RecordToggle /> to stop recording.
21
- </div>
22
+ <button
23
+ className={styles.CTAButton}
24
+ onClick={stopProfiling}
25
+ type="button">
26
+ Stop recording
27
+ </button>
28
</div>
29
);
30
}