Skip to content

[DevTools] Refactor imperative theme code #21900

@bvaughn

Description

@bvaughn

DevTools defaults a "light" and a "dark" theme in a root-level CSS file:
https://github.com/facebook/react/blob/310187264d01a31bc3079358f13662d31a079d9e/packages/react-devtools-shared/src/devtools/views/root.css#L1-L188

The current theme value ("light", "dark", or "auto") is stored in the ThemeContext and persisted between sessions using the localStorage API:
https://github.com/facebook/react/blob/310187264d01a31bc3079358f13662d31a079d9e/packages/react-devtools-shared/src/devtools/views/Settings/SettingsContext.js#L86-L89

When the theme changes, a layout effect updates root-level CSS variables:
https://github.com/facebook/react/blob/310187264d01a31bc3079358f13662d31a079d9e/packages/react-devtools-shared/src/devtools/views/Settings/SettingsContext.js#L149-L163

This has an unfortunate side effect of creating a race condition between any other imperative code (e.g. a Canvas rendering component) that may want to read the current CSS variables. This code cannot run before the code above or it will read previous/stale values.

We should refactor this code to declaratively share theme variables to its subtree, e.g.:

function ThemeProvider({ value, children }) {
  // ...

  return (
    <ThemeContext.Provider value={theme}>
      <div
        style={{
          '--color-attribute-name': '#ef6632',
          '--color-attribute-name-not-editable': '#23272f',
          // ...
        }}
      >
        {children}
      </div>
    </ThemeContext.Provider>
  );
}

We will also need to update any place that reads these computed styles, e.g.
https://github.com/facebook/react/blob/310187264d01a31bc3079358f13662d31a079d9e/packages/react-devtools-shared/src/devtools/views/Settings/SettingsContext.js#L274-L281

A similar approach is used for font size ("comfortable" or "compact"). We should do the same refactor for this.

Metadata

Metadata

Assignees

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions