@samitouri / QOS-React-2 / commits / 0011363766

[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 }