mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Use @reach tooltips for TabBar, cleanup supports-profiling subscription
This commit is contained in:
@@ -865,8 +865,9 @@ export default class Store extends EventEmitter {
|
||||
if (hasOwnerMetadata) {
|
||||
this._hasOwnerMetadata = true;
|
||||
}
|
||||
if (supportsProfiling) {
|
||||
if (!this._supportsProfiling && supportsProfiling) {
|
||||
this._supportsProfiling = true;
|
||||
this.emit('supportsProfiling');
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
import '@reach/menu-button/styles.css';
|
||||
import '@reach/tooltip/styles.css';
|
||||
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import React, { useMemo, useState } from 'react';
|
||||
import Store from '../store';
|
||||
import { BridgeContext, StoreContext } from './context';
|
||||
import Components from './Components/Components';
|
||||
@@ -18,6 +18,7 @@ import ViewElementSourceContext from './Components/ViewElementSourceContext';
|
||||
import { ProfilerContextController } from './Profiler/ProfilerContext';
|
||||
import { ModalDialogContextController } from './ModalDialog';
|
||||
import ReactLogo from './ReactLogo';
|
||||
import { useSubscription } from './hooks';
|
||||
|
||||
import styles from './DevTools.css';
|
||||
|
||||
@@ -71,8 +72,7 @@ const settingsTab = {
|
||||
title: 'React Settings',
|
||||
};
|
||||
|
||||
const tabsWithProfiler = [componentsTab, profilerTab, settingsTab];
|
||||
const tabsWithoutProfiler = [componentsTab, settingsTab];
|
||||
const tabs = [componentsTab, profilerTab, settingsTab];
|
||||
|
||||
export default function DevTools({
|
||||
bridge,
|
||||
@@ -92,27 +92,19 @@ export default function DevTools({
|
||||
setTab(overrideTab);
|
||||
}
|
||||
|
||||
const [supportsProfiling, setSupportsProfiling] = useState(
|
||||
store.supportsProfiling
|
||||
const supportsProfilingSubscription = useMemo(
|
||||
() => ({
|
||||
getCurrentValue: () => store.supportsProfiling,
|
||||
subscribe: (callback: Function) => {
|
||||
store.addListener('supportsProfiling', callback);
|
||||
return () => store.removeListener('supportsProfiling', callback);
|
||||
},
|
||||
}),
|
||||
[store]
|
||||
);
|
||||
const supportsProfiling = useSubscription<boolean, Store>(
|
||||
supportsProfilingSubscription
|
||||
);
|
||||
|
||||
// Show/hide the "Profiler" button depending on if profiling is supported.
|
||||
useEffect(() => {
|
||||
if (supportsProfiling !== store.supportsProfiling) {
|
||||
setSupportsProfiling(store.supportsProfiling);
|
||||
}
|
||||
|
||||
const handleRoots = () => {
|
||||
if (supportsProfiling !== store.supportsProfiling) {
|
||||
setSupportsProfiling(store.supportsProfiling);
|
||||
}
|
||||
};
|
||||
|
||||
store.addListener('roots', handleRoots);
|
||||
return () => {
|
||||
store.removeListener('roots', handleRoots);
|
||||
};
|
||||
}, [store, supportsProfiling]);
|
||||
|
||||
return (
|
||||
<BridgeContext.Provider value={bridge}>
|
||||
@@ -140,11 +132,7 @@ export default function DevTools({
|
||||
id="DevTools"
|
||||
selectTab={setTab}
|
||||
size="large"
|
||||
tabs={
|
||||
supportsProfiling
|
||||
? tabsWithProfiler
|
||||
: tabsWithoutProfiler
|
||||
}
|
||||
tabs={tabs}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -2,9 +2,11 @@
|
||||
|
||||
import classNames from 'classnames';
|
||||
import React, { Fragment, useCallback } from 'react';
|
||||
import Tooltip from '@reach/tooltip';
|
||||
import Icon from './Icon';
|
||||
|
||||
import styles from './TabBar.css';
|
||||
import tooltipStyles from './Tooltip.css';
|
||||
|
||||
import type { IconType } from './Icon';
|
||||
|
||||
@@ -59,42 +61,53 @@ export default function TabBar({
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
{tabs.map(({ icon, id, label, title }) => (
|
||||
<label
|
||||
className={classNames(
|
||||
tabClassName,
|
||||
disabled ? styles.TabDisabled : styles.Tab,
|
||||
!disabled && currentTab === id ? styles.TabCurrent : null
|
||||
)}
|
||||
key={id}
|
||||
onKeyDown={handleKeyDown}
|
||||
onMouseDown={() => selectTab(id)}
|
||||
title={title || label}
|
||||
>
|
||||
<input
|
||||
type="radio"
|
||||
className={styles.Input}
|
||||
checked={currentTab === id}
|
||||
disabled={disabled}
|
||||
name={groupName}
|
||||
value={id}
|
||||
onChange={onChange}
|
||||
/>
|
||||
<Icon
|
||||
className={`${disabled ? styles.IconDisabled : ''} ${
|
||||
size === 'large' ? styles.IconSizeLarge : styles.IconSizeSmall
|
||||
}`}
|
||||
type={icon}
|
||||
/>
|
||||
<span
|
||||
className={
|
||||
size === 'large' ? styles.TabLabelLarge : styles.TabLabelSmall
|
||||
}
|
||||
{tabs.map(({ icon, id, label, title }) => {
|
||||
let button = (
|
||||
<label
|
||||
className={classNames(
|
||||
tabClassName,
|
||||
disabled ? styles.TabDisabled : styles.Tab,
|
||||
!disabled && currentTab === id ? styles.TabCurrent : null
|
||||
)}
|
||||
key={id}
|
||||
onKeyDown={handleKeyDown}
|
||||
onMouseDown={() => selectTab(id)}
|
||||
>
|
||||
{label}
|
||||
</span>
|
||||
</label>
|
||||
))}
|
||||
<input
|
||||
type="radio"
|
||||
className={styles.Input}
|
||||
checked={currentTab === id}
|
||||
disabled={disabled}
|
||||
name={groupName}
|
||||
value={id}
|
||||
onChange={onChange}
|
||||
/>
|
||||
<Icon
|
||||
className={`${disabled ? styles.IconDisabled : ''} ${
|
||||
size === 'large' ? styles.IconSizeLarge : styles.IconSizeSmall
|
||||
}`}
|
||||
type={icon}
|
||||
/>
|
||||
<span
|
||||
className={
|
||||
size === 'large' ? styles.TabLabelLarge : styles.TabLabelSmall
|
||||
}
|
||||
>
|
||||
{label}
|
||||
</span>
|
||||
</label>
|
||||
);
|
||||
|
||||
if (title) {
|
||||
button = (
|
||||
<Tooltip className={tooltipStyles.Tooltip} label={title}>
|
||||
{button}
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
|
||||
return button;
|
||||
})}
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user