main
js 171 lines 5.02 KB
Raw
1 /**
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 *
7 * @flow
8 */
9
10 import * as React from 'react';
11 import {useContext, useMemo} from 'react';
12 import {SettingsContext} from './SettingsContext';
13 import {StoreContext} from '../context';
14 import {CHANGE_LOG_URL} from 'react-devtools-shared/src/devtools/constants';
15 import {isInternalFacebookBuild} from 'react-devtools-feature-flags';
16
17 import styles from './SettingsShared.css';
18
19 import CodeEditorOptions from './CodeEditorOptions';
20 import CodeEditorByDefault from './CodeEditorByDefault';
21 import {LOCAL_STORAGE_ALWAYS_OPEN_IN_EDITOR} from '../../../constants';
22 import {useLocalStorage} from '../hooks';
23
24 function getChangeLogUrl(version: ?string): string | null {
25 if (!version) {
26 return null;
27 }
28
29 // Version numbers are in the format of: <major>.<minor>.<patch>-<sha>
30 // e.g. "4.23.0-f0dd459e0"
31 // GitHub CHANGELOG headers are in the format of: <major>.<minor>.<patch>
32 // but the "." are stripped from anchor tags, becomming: <major><minor><patch>
33 const versionAnchor = version.replace(/^(\d+)\.(\d+)\.(\d+).*/, '$1$2$3');
34 return `${CHANGE_LOG_URL}#${versionAnchor}`;
35 }
36
37 export default function GeneralSettings(_: {}): React.Node {
38 const {
39 displayDensity,
40 setDisplayDensity,
41 setTheme,
42 setTraceUpdatesEnabled,
43 theme,
44 traceUpdatesEnabled,
45 } = useContext(SettingsContext);
46
47 const {backendVersion, supportsTraceUpdates} = useContext(StoreContext);
48 const frontendVersion = process.env.DEVTOOLS_VERSION;
49
50 const showBackendVersion =
51 backendVersion && backendVersion !== frontendVersion;
52
53 const [alwaysOpenInEditor] = useLocalStorage<boolean>(
54 LOCAL_STORAGE_ALWAYS_OPEN_IN_EDITOR,
55 false,
56 );
57
58 return (
59 <div className={styles.SettingList}>
60 {isInternalFacebookBuild && (
61 <div className={styles.SettingWrapper}>
62 This is an internal build of React DevTools for Meta
63 </div>
64 )}
65
66 <div className={styles.SettingWrapper}>
67 <div className={styles.RadioLabel}>Theme</div>
68 <select
69 value={theme}
70 onChange={({currentTarget}) => setTheme(currentTarget.value)}>
71 <option value="auto">Auto</option>
72 <option value="light">Light</option>
73 <option value="dark">Dark</option>
74 </select>
75 </div>
76
77 <div className={styles.SettingWrapper}>
78 <div className={styles.RadioLabel}>Display density</div>
79 <select
80 value={displayDensity}
81 onChange={({currentTarget}) =>
82 setDisplayDensity(currentTarget.value)
83 }>
84 <option value="compact">Compact</option>
85 <option value="comfortable">Comfortable</option>
86 </select>
87 </div>
88
89 <div className={styles.SettingWrapper}>
90 <label className={styles.SettingRow}>
91 <div className={styles.RadioLabel}>Open in Editor URL</div>
92 <CodeEditorOptions />
93 </label>
94 </div>
95
96 <div className={styles.SettingWrapper}>
97 <CodeEditorByDefault />
98 {alwaysOpenInEditor && (__IS_CHROME__ || __IS_EDGE__) ? (
99 <div>
100 To enable link handling in your browser's DevTools settings, look
101 for the option Extension -> Link Handling. Select "React Developer
102 Tools".
103 </div>
104 ) : null}
105 </div>
106
107 {supportsTraceUpdates && (
108 <div className={styles.SettingWrapper}>
109 <label className={styles.SettingRow}>
110 <input
111 type="checkbox"
112 checked={traceUpdatesEnabled}
113 onChange={({currentTarget}) =>
114 setTraceUpdatesEnabled(currentTarget.checked)
115 }
116 className={styles.SettingRowCheckbox}
117 />
118 Highlight updates when components render
119 </label>
120 </div>
121 )}
122
123 <div className={styles.ReleaseNotes}>
124 {showBackendVersion && (
125 <div>
126 <ul className={styles.VersionsList}>
127 <li>
128 <Version
129 label="DevTools backend version:"
130 version={backendVersion}
131 />
132 </li>
133 <li>
134 <Version
135 label="DevTools frontend version:"
136 version={frontendVersion}
137 />
138 </li>
139 </ul>
140 </div>
141 )}
142 {!showBackendVersion && (
143 <Version label="DevTools version:" version={frontendVersion} />
144 )}
145 </div>
146 </div>
147 );
148 }
149
150 function Version({label, version}: {label: string, version: ?string}) {
151 const changelogLink = useMemo(() => {
152 return getChangeLogUrl(version);
153 }, [version]);
154
155 if (version == null) {
156 return null;
157 } else {
158 return (
159 <>
160 {label}{' '}
161 <a
162 className={styles.ReleaseNotesLink}
163 target="_blank"
164 rel="noopener noreferrer"
165 href={changelogLink}>
166 {version}
167 </a>
168 </>
169 );
170 }
171 }