Skip to content

Commit

Permalink
Devtools: Refactor imperative theme code (facebook#21950)
Browse files Browse the repository at this point in the history
Co-authored-by: Brian Vaughn <bvaughn@fb.com>
  • Loading branch information
2 people authored and zhengjitf committed Apr 15, 2022
1 parent 1249374 commit 7819f89
Show file tree
Hide file tree
Showing 8 changed files with 375 additions and 635 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
useContext,
useDeferredValue,
useLayoutEffect,
useRef,
useState,
} from 'react';
import {SettingsContext} from 'react-devtools-shared/src/devtools/views/Settings/SettingsContext';
Expand All @@ -30,6 +31,8 @@ export function SchedulingProfiler(_: {||}) {
SchedulingProfilerContext,
);

const ref = useRef(null);

// HACK: Canvas rendering uses an imperative API,
// but DevTools colors are stored in CSS variables (see root.css and SettingsContext).
// When the theme changes, we need to trigger update the imperative colors and re-draw the Canvas.
Expand All @@ -42,7 +45,7 @@ export function SchedulingProfiler(_: {||}) {
const [key, setKey] = useState<string>(theme);
useLayoutEffect(() => {
const pollForTheme = () => {
if (updateColorsToMatchTheme()) {
if (updateColorsToMatchTheme(((ref.current: any): HTMLDivElement))) {
clearInterval(intervalID);
setKey(deferredTheme);
}
Expand All @@ -56,7 +59,7 @@ export function SchedulingProfiler(_: {||}) {
}, [deferredTheme]);

return (
<div className={styles.Content}>
<div className={styles.Content} ref={ref}>
{schedulingProfilerData ? (
<Suspense fallback={<ProcessingData />}>
<DataResourceComponent
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,8 @@ export let COLORS = {
WARNING_TEXT_INVERED: '',
};

export function updateColorsToMatchTheme(): boolean {
const computedStyle = getComputedStyle((document.body: any));
export function updateColorsToMatchTheme(element: Element): boolean {
const computedStyle = getComputedStyle(element);

// Check to see if styles have been initialized...
if (computedStyle.getPropertyValue('--color-background') == null) {
Expand Down
311 changes: 287 additions & 24 deletions packages/react-devtools-shared/src/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,33 +55,296 @@ export const UNSUPPORTED_VERSION_URL =
export const REACT_DEVTOOLS_WORKPLACE_URL =
'https://fburl.com/react-devtools-workplace-group';

import type {
Theme,
DisplayDensity,
} from './devtools/views/Settings/SettingsContext';

export const THEME_STYLES: {[style: Theme | DisplayDensity]: any} = {
light: {
'--color-attribute-name': '#ef6632',
'--color-attribute-name-not-editable': '#23272f',
'--color-attribute-name-inverted': 'rgba(255, 255, 255, 0.7)',
'--color-attribute-value': '#1a1aa6',
'--color-attribute-value-inverted': '#ffffff',
'--color-attribute-editable-value': '#1a1aa6',
'--color-background': '#ffffff',
'--color-background-hover': 'rgba(0, 136, 250, 0.1)',
'--color-background-inactive': '#e5e5e5',
'--color-background-invalid': '#fff0f0',
'--color-background-selected': '#0088fa',
'--color-button-background': '#ffffff',
'--color-button-background-focus': '#ededed',
'--color-button': '#5f6673',
'--color-button-disabled': '#cfd1d5',
'--color-button-active': '#0088fa',
'--color-button-focus': '#23272f',
'--color-button-hover': '#23272f',
'--color-border': '#eeeeee',
'--color-commit-did-not-render-fill': '#cfd1d5',
'--color-commit-did-not-render-fill-text': '#000000',
'--color-commit-did-not-render-pattern': '#cfd1d5',
'--color-commit-did-not-render-pattern-text': '#333333',
'--color-commit-gradient-0': '#37afa9',
'--color-commit-gradient-1': '#63b19e',
'--color-commit-gradient-2': '#80b393',
'--color-commit-gradient-3': '#97b488',
'--color-commit-gradient-4': '#abb67d',
'--color-commit-gradient-5': '#beb771',
'--color-commit-gradient-6': '#cfb965',
'--color-commit-gradient-7': '#dfba57',
'--color-commit-gradient-8': '#efbb49',
'--color-commit-gradient-9': '#febc38',
'--color-commit-gradient-text': '#000000',
'--color-component-name': '#6a51b2',
'--color-component-name-inverted': '#ffffff',
'--color-component-badge-background': 'rgba(0, 0, 0, 0.1)',
'--color-component-badge-background-inverted': 'rgba(255, 255, 255, 0.25)',
'--color-component-badge-count': '#777d88',
'--color-component-badge-count-inverted': 'rgba(255, 255, 255, 0.7)',
'--color-console-error-badge-text': '#ffffff',
'--color-console-error-background': '#fff0f0',
'--color-console-error-border': '#ffd6d6',
'--color-console-error-icon': '#eb3941',
'--color-console-error-text': '#fe2e31',
'--color-console-warning-badge-text': '#000000',
'--color-console-warning-background': '#fffbe5',
'--color-console-warning-border': '#fff5c1',
'--color-console-warning-icon': '#f4bd00',
'--color-console-warning-text': '#64460c',
'--color-context-background': 'rgba(0,0,0,.9)',
'--color-context-background-hover': 'rgba(255, 255, 255, 0.1)',
'--color-context-background-selected': '#178fb9',
'--color-context-border': '#3d424a',
'--color-context-text': '#ffffff',
'--color-context-text-selected': '#ffffff',
'--color-dim': '#777d88',
'--color-dimmer': '#cfd1d5',
'--color-dimmest': '#eff0f1',
'--color-error-background': 'hsl(0, 100%, 97%)',
'--color-error-border': 'hsl(0, 100%, 92%)',
'--color-error-text': '#ff0000',
'--color-expand-collapse-toggle': '#777d88',
'--color-link': '#0000ff',
'--color-modal-background': 'rgba(255, 255, 255, 0.75)',
'--color-bridge-version-npm-background': '#eff0f1',
'--color-bridge-version-npm-text': '#000000',
'--color-bridge-version-number': '#0088fa',
'--color-primitive-hook-badge-background': '#e5e5e5',
'--color-primitive-hook-badge-text': '#5f6673',
'--color-record-active': '#fc3a4b',
'--color-record-hover': '#3578e5',
'--color-record-inactive': '#0088fa',
'--color-resize-bar': '#eeeeee',
'--color-resize-bar-active': '#dcdcdc',
'--color-resize-bar-border': '#d1d1d1',
'--color-resize-bar-dot': '#333333',
'--color-scheduling-profiler-native-event': '#ccc',
'--color-scheduling-profiler-native-event-hover': '#aaa',
'--color-scheduling-profiler-priority-background': '#f6f6f6',
'--color-scheduling-profiler-priority-border': '#eeeeee',
'--color-scheduling-profiler-user-timing': '#c9cacd',
'--color-scheduling-profiler-user-timing-hover': '#93959a',
'--color-scheduling-profiler-react-idle': '#d3e5f6',
'--color-scheduling-profiler-react-idle-hover': '#c3d9ef',
'--color-scheduling-profiler-react-render': '#9fc3f3',
'--color-scheduling-profiler-react-render-hover': '#83afe9',
'--color-scheduling-profiler-react-commit': '#c88ff0',
'--color-scheduling-profiler-react-commit-hover': '#b281d6',
'--color-scheduling-profiler-react-layout-effects': '#b281d6',
'--color-scheduling-profiler-react-layout-effects-hover': '#9d71bd',
'--color-scheduling-profiler-react-passive-effects': '#b281d6',
'--color-scheduling-profiler-react-passive-effects-hover': '#9d71bd',
'--color-scheduling-profiler-react-schedule': '#9fc3f3',
'--color-scheduling-profiler-react-schedule-hover': '#2683E2',
'--color-scheduling-profiler-react-suspense-rejected': '#f1cc14',
'--color-scheduling-profiler-react-suspense-rejected-hover': '#ffdf37',
'--color-scheduling-profiler-react-suspense-resolved': '#a6e59f',
'--color-scheduling-profiler-react-suspense-resolved-hover': '#89d281',
'--color-scheduling-profiler-react-suspense-unresolved': '#c9cacd',
'--color-scheduling-profiler-react-suspense-unresolved-hover': '#93959a',
'--color-scheduling-profiler-text-color': '#000000',
'--color-scheduling-profiler-react-work-border': '#ffffff',
'--color-scroll-thumb': '#c2c2c2',
'--color-scroll-track': '#fafafa',
'--color-search-match': 'yellow',
'--color-search-match-current': '#f7923b',
'--color-selected-tree-highlight-active': 'rgba(0, 136, 250, 0.1)',
'--color-selected-tree-highlight-inactive': 'rgba(0, 0, 0, 0.05)',
'--color-scroll-caret': 'rgba(150, 150, 150, 0.5)',
'--color-tab-selected-border': '#0088fa',
'--color-text': '#000000',
'--color-text-invalid': '#ff0000',
'--color-text-selected': '#ffffff',
'--color-toggle-background-invalid': '#fc3a4b',
'--color-toggle-background-on': '#0088fa',
'--color-toggle-background-off': '#cfd1d5',
'--color-toggle-text': '#ffffff',
'--color-tooltip-background': 'rgba(0, 0, 0, 0.9)',
'--color-tooltip-text': '#ffffff',
'--color-warning-background': '#fb3655',
'--color-warning-background-hover': '#f82042',
'--color-warning-text-color': '#ffffff',
'--color-warning-text-color-inverted': '#fd4d69',
},
dark: {
'--color-attribute-name': '#9d87d2',
'--color-attribute-name-not-editable': '#ededed',
'--color-attribute-name-inverted': '#282828',
'--color-attribute-value': '#cedae0',
'--color-attribute-value-inverted': '#ffffff',
'--color-attribute-editable-value': 'yellow',
'--color-background': '#282c34',
'--color-background-hover': 'rgba(255, 255, 255, 0.1)',
'--color-background-inactive': '#3d424a',
'--color-background-invalid': '#5c0000',
'--color-background-selected': '#178fb9',
'--color-button-background': '#282c34',
'--color-button-background-focus': '#3d424a',
'--color-button': '#afb3b9',
'--color-button-active': '#61dafb',
'--color-button-disabled': '#4f5766',
'--color-button-focus': '#a2e9fc',
'--color-button-hover': '#ededed',
'--color-border': '#3d424a',
'--color-commit-did-not-render-fill': '#777d88',
'--color-commit-did-not-render-fill-text': '#000000',
'--color-commit-did-not-render-pattern': '#666c77',
'--color-commit-did-not-render-pattern-text': '#ffffff',
'--color-commit-gradient-0': '#37afa9',
'--color-commit-gradient-1': '#63b19e',
'--color-commit-gradient-2': '#80b393',
'--color-commit-gradient-3': '#97b488',
'--color-commit-gradient-4': '#abb67d',
'--color-commit-gradient-5': '#beb771',
'--color-commit-gradient-6': '#cfb965',
'--color-commit-gradient-7': '#dfba57',
'--color-commit-gradient-8': '#efbb49',
'--color-commit-gradient-9': '#febc38',
'--color-commit-gradient-text': '#000000',
'--color-component-name': '#61dafb',
'--color-component-name-inverted': '#282828',
'--color-component-badge-background': 'rgba(255, 255, 255, 0.25)',
'--color-component-badge-background-inverted': 'rgba(0, 0, 0, 0.25)',
'--color-component-badge-count': '#8f949d',
'--color-component-badge-count-inverted': 'rgba(255, 255, 255, 0.7)',
'--color-console-error-badge-text': '#000000',
'--color-console-error-background': '#290000',
'--color-console-error-border': '#5c0000',
'--color-console-error-icon': '#eb3941',
'--color-console-error-text': '#fc7f7f',
'--color-console-warning-badge-text': '#000000',
'--color-console-warning-background': '#332b00',
'--color-console-warning-border': '#665500',
'--color-console-warning-icon': '#f4bd00',
'--color-console-warning-text': '#f5f2ed',
'--color-context-background': 'rgba(255,255,255,.95)',
'--color-context-background-hover': 'rgba(0, 136, 250, 0.1)',
'--color-context-background-selected': '#0088fa',
'--color-context-border': '#eeeeee',
'--color-context-text': '#000000',
'--color-context-text-selected': '#ffffff',
'--color-dim': '#8f949d',
'--color-dimmer': '#777d88',
'--color-dimmest': '#4f5766',
'--color-error-background': '#200',
'--color-error-border': '#900',
'--color-error-text': '#f55',
'--color-expand-collapse-toggle': '#8f949d',
'--color-link': '#61dafb',
'--color-modal-background': 'rgba(0, 0, 0, 0.75)',
'--color-bridge-version-npm-background': 'rgba(0, 0, 0, 0.25)',
'--color-bridge-version-npm-text': '#ffffff',
'--color-bridge-version-number': 'yellow',
'--color-primitive-hook-badge-background': 'rgba(0, 0, 0, 0.25)',
'--color-primitive-hook-badge-text': 'rgba(255, 255, 255, 0.7)',
'--color-record-active': '#fc3a4b',
'--color-record-hover': '#a2e9fc',
'--color-record-inactive': '#61dafb',
'--color-resize-bar': '#282c34',
'--color-resize-bar-active': '#31363f',
'--color-resize-bar-border': '#3d424a',
'--color-resize-bar-dot': '#cfd1d5',
'--color-scheduling-profiler-native-event': '#b2b2b2',
'--color-scheduling-profiler-native-event-hover': '#949494',
'--color-scheduling-profiler-priority-background': '#1d2129',
'--color-scheduling-profiler-priority-border': '#282c34',
'--color-scheduling-profiler-user-timing': '#c9cacd',
'--color-scheduling-profiler-user-timing-hover': '#93959a',
'--color-scheduling-profiler-react-idle': '#3d485b',
'--color-scheduling-profiler-react-idle-hover': '#465269',
'--color-scheduling-profiler-react-render': '#2683E2',
'--color-scheduling-profiler-react-render-hover': '#1a76d4',
'--color-scheduling-profiler-react-commit': '#731fad',
'--color-scheduling-profiler-react-commit-hover': '#611b94',
'--color-scheduling-profiler-react-layout-effects': '#611b94',
'--color-scheduling-profiler-react-layout-effects-hover': '#51167a',
'--color-scheduling-profiler-react-passive-effects': '#611b94',
'--color-scheduling-profiler-react-passive-effects-hover': '#51167a',
'--color-scheduling-profiler-react-schedule': '#2683E2',
'--color-scheduling-profiler-react-schedule-hover': '#1a76d4',
'--color-scheduling-profiler-react-suspense-rejected': '#f1cc14',
'--color-scheduling-profiler-react-suspense-rejected-hover': '#e4c00f',
'--color-scheduling-profiler-react-suspense-resolved': '#a6e59f',
'--color-scheduling-profiler-react-suspense-resolved-hover': '#89d281',
'--color-scheduling-profiler-react-suspense-unresolved': '#c9cacd',
'--color-scheduling-profiler-react-suspense-unresolved-hover': '#93959a',
'--color-scheduling-profiler-text-color': '#000000',
'--color-scheduling-profiler-react-work-border': '#ffffff',
'--color-scroll-thumb': '#afb3b9',
'--color-scroll-track': '#313640',
'--color-search-match': 'yellow',
'--color-search-match-current': '#f7923b',
'--color-selected-tree-highlight-active': 'rgba(23, 143, 185, 0.15)',
'--color-selected-tree-highlight-inactive': 'rgba(255, 255, 255, 0.05)',
'--color-scroll-caret': '#4f5766',
'--color-shadow': 'rgba(0, 0, 0, 0.5)',
'--color-tab-selected-border': '#178fb9',
'--color-text': '#ffffff',
'--color-text-invalid': '#ff8080',
'--color-text-selected': '#ffffff',
'--color-toggle-background-invalid': '#fc3a4b',
'--color-toggle-background-on': '#178fb9',
'--color-toggle-background-off': '#777d88',
'--color-toggle-text': '#ffffff',
'--color-tooltip-background': 'rgba(255, 255, 255, 0.95)',
'--color-tooltip-text': '#000000',
'--color-warning-background': '#ee1638',
'--color-warning-background-hover': '#da1030',
'--color-warning-text-color': '#ffffff',
'--color-warning-text-color-inverted': '#ee1638',
},
compact: {
'--font-size-monospace-small': '9px',
'--font-size-monospace-normal': '11px',
'--font-size-monospace-large': '15px',
'--font-size-sans-small': '10px',
'--font-size-sans-normal': '12px',
'--font-size-sans-large': '14px',
'--line-height-data': '18px',
},
comfortable: {
'--font-size-monospace-small': '10px',
'--font-size-monospace-normal': '13px',
'--font-size-monospace-large': '17px',
'--font-size-sans-small': '12px',
'--font-size-sans-normal': '14px',
'--font-size-sans-large': '16px',
'--line-height-data': '22px',
},
};

// HACK
//
// Extracting during build time avoids a temporarily invalid state for the inline target.
// Sometimes the inline target is rendered before root styles are applied,
// which would result in e.g. NaN itemSize being passed to react-window list.
//
let COMFORTABLE_LINE_HEIGHT;
let COMPACT_LINE_HEIGHT;

try {
// $FlowFixMe
const rawStyleString = require('!!raw-loader!react-devtools-shared/src/devtools/views/root.css')
.default;

const extractVar = varName => {
const regExp = new RegExp(`${varName}: ([0-9]+)`);
const match = rawStyleString.match(regExp);
return parseInt(match[1], 10);
};

COMFORTABLE_LINE_HEIGHT = extractVar('comfortable-line-height-data');
COMPACT_LINE_HEIGHT = extractVar('compact-line-height-data');
} catch (error) {
// We can't use the Webpack loader syntax in the context of Jest,
// so tests need some reasonably meaningful fallback value.
COMFORTABLE_LINE_HEIGHT = 15;
COMPACT_LINE_HEIGHT = 10;
}
const COMFORTABLE_LINE_HEIGHT = parseInt(
THEME_STYLES.comfortable['--line-height-data'],
10,
);
const COMPACT_LINE_HEIGHT = parseInt(
THEME_STYLES.compact['--line-height-data'],
10,
);

export {COMFORTABLE_LINE_HEIGHT, COMPACT_LINE_HEIGHT};
Loading

0 comments on commit 7819f89

Please sign in to comment.