Skip to content

fix(devtools): expose css vars to reach-ui portal components #22716

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Nov 8, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 2 additions & 7 deletions packages/react-devtools-shared/src/devtools/views/Button.js
Original file line number Diff line number Diff line change
@@ -8,10 +8,9 @@
*/

import * as React from 'react';
import Tooltip from '@reach/tooltip';

import styles from './Button.css';
import tooltipStyles from './Tooltip.css';
import Tooltip from './Components/reach-ui/tooltip';

type Props = {
children: React$Node,
@@ -35,11 +34,7 @@ export default function Button({
);

if (title) {
button = (
<Tooltip className={tooltipStyles.Tooltip} label={title}>
{button}
</Tooltip>
);
button = <Tooltip label={title}>{button}</Tooltip>;
}

return button;
Original file line number Diff line number Diff line change
@@ -16,8 +16,6 @@ import {
useRef,
useState,
} from 'react';
import Tooltip from '@reach/tooltip';
import {Menu, MenuList, MenuButton, MenuItem} from '@reach/menu-button';
import Button from '../Button';
import ButtonIcon from '../ButtonIcon';
import Toggle from '../Toggle';
@@ -26,6 +24,13 @@ import {OwnersListContext} from './OwnersListContext';
import {TreeDispatcherContext, TreeStateContext} from './TreeContext';
import {useIsOverflowing} from '../hooks';
import {StoreContext} from '../context';
import Tooltip from '../Components/reach-ui/tooltip';
import {
Menu,
MenuList,
MenuButton,
MenuItem,
} from '../Components/reach-ui/menu-button';

import type {SerializedElement} from './types';

Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/

import * as React from 'react';
import {
Menu,
MenuList as ReachMenuList,
MenuButton,
MenuItem,
} from '@reach/menu-button';
import useThemeStyles from '../../useThemeStyles';

const MenuList = ({children, ...props}: {children: React$Node, ...}) => {
const style = useThemeStyles();
return (
<ReachMenuList style={style} {...props}>
{children}
</ReachMenuList>
);
};

export {MenuItem, MenuButton, MenuList, Menu};
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/

import * as React from 'react';
import ReachTooltip from '@reach/tooltip';
import tooltipStyles from './Tooltip.css';
import useThemeStyles from '../../useThemeStyles';

const Tooltip = ({
children,
className = '',
...props
}: {
children: React$Node,
className: string,
...
}) => {
const style = useThemeStyles();
return (
<ReachTooltip
className={`${tooltipStyles.Tooltip} ${className}`}
style={style}
{...props}>
{children}
</ReachTooltip>
);
};

export default Tooltip;
Original file line number Diff line number Diff line change
@@ -248,28 +248,6 @@ function SettingsContextController({
);
}

function setStyleVariable(
name: string,
value: string,
documentElements: DocumentElements,
) {
documentElements.forEach(documentElement =>
documentElement.style.setProperty(name, value),
);
}

function updateStyleHelper(
themeKey: string,
style: string,
documentElements: DocumentElements,
) {
setStyleVariable(
`--${style}`,
`var(--${themeKey}-${style})`,
documentElements,
);
}

export function updateDisplayDensity(
displayDensity: DisplayDensity,
documentElements: DocumentElements,
@@ -296,12 +274,6 @@ export function updateThemeVariables(
// $FlowFixMe scrollbarColor is missing in CSSStyleDeclaration
documentElement.style.scrollbarColor = `var(${`--${theme}-color-scroll-thumb`}) var(${`--${theme}-color-scroll-track`})`;
});

// The ThemeProvider works by writing DOM style variables to an HTMLDivElement.
// Because Portals render in a different DOM subtree, these variables don't propagate.
// So we need to also set @reach/tooltip specific styles on the root.
updateStyleHelper(theme, 'color-tooltip-background', documentElements);
updateStyleHelper(theme, 'color-tooltip-text', documentElements);
}

export {SettingsContext, SettingsContextController};
5 changes: 2 additions & 3 deletions packages/react-devtools-shared/src/devtools/views/TabBar.js
Original file line number Diff line number Diff line change
@@ -9,11 +9,10 @@

import * as React from 'react';
import {Fragment, useCallback} from 'react';
import Tooltip from '@reach/tooltip';
import Icon from './Icon';

import styles from './TabBar.css';
import tooltipStyles from './Tooltip.css';
import Tooltip from './Components/reach-ui/tooltip';

import type {IconType} from './Icon';

@@ -127,7 +126,7 @@ export default function TabBar({

if (title) {
button = (
<Tooltip key={id} className={tooltipStyles.Tooltip} label={title}>
<Tooltip key={id} label={title}>
{button}
</Tooltip>
);
18 changes: 7 additions & 11 deletions packages/react-devtools-shared/src/devtools/views/ThemeProvider.js
Original file line number Diff line number Diff line change
@@ -8,22 +8,18 @@
*/

import * as React from 'react';
import {useContext, useMemo} from 'react';
import {SettingsContext} from './Settings/SettingsContext';
import {THEME_STYLES} from '../../constants';
import useThemeStyles from './useThemeStyles';

export default function ThemeProvider({children}: {|children: React$Node|}) {
const {theme, displayDensity, browserTheme} = useContext(SettingsContext);
const themeStyle = useThemeStyles();

const style = useMemo(
() => ({
const style = React.useMemo(() => {
return {
...themeStyle,
width: '100%',
height: '100%',
...THEME_STYLES[displayDensity],
...THEME_STYLES[theme === 'auto' ? browserTheme : theme],
}),
[theme, browserTheme, displayDensity],
);
};
}, [themeStyle]);

return <div style={style}>{children}</div>;
}
9 changes: 2 additions & 7 deletions packages/react-devtools-shared/src/devtools/views/Toggle.js
Original file line number Diff line number Diff line change
@@ -9,10 +9,9 @@

import * as React from 'react';
import {useCallback} from 'react';
import Tooltip from '@reach/tooltip';

import styles from './Toggle.css';
import tooltipStyles from './Tooltip.css';
import Tooltip from './Components/reach-ui/tooltip';

type Props = {
children: React$Node,
@@ -58,11 +57,7 @@ export default function Toggle({
);

if (title) {
toggle = (
<Tooltip className={tooltipStyles.Tooltip} label={title}>
{toggle}
</Tooltip>
);
toggle = <Tooltip label={title}>{toggle}</Tooltip>;
}

return toggle;
28 changes: 1 addition & 27 deletions packages/react-devtools-shared/src/devtools/views/root.css
Original file line number Diff line number Diff line change
@@ -1,36 +1,10 @@
:root {
/**
* The light and dark theme styles below should be kept in sync with 'react-devtools-shared/src/constants'
* They are repeated here because they're used by e.g. tooltips or context menus
* which get rendered outside of the DOM subtree (where normal theme/styles are written).
*/

/* Light theme */
--light-color-scroll-thumb: #c2c2c2;
--light-color-scroll-track: #fafafa;
--light-color-tooltip-background: rgba(0, 0, 0, 0.9);
--light-color-tooltip-text: #ffffff;

/* Dark theme */
--dark-color-scroll-thumb: #afb3b9;
--dark-color-scroll-track: #313640;
--dark-color-tooltip-background: rgba(255, 255, 255, 0.95);
--dark-color-tooltip-text: #000000;

/* Font smoothing */
--font-smoothing: auto;

/* Compact density */
--compact-line-height-data: 18px;
--compact-root-font-size: 16px;

/* Comfortable density */
--comfortable-line-height-data: 22px;
--comfortable-root-font-size: 20px;

/* GitHub.com system fonts */
--font-family-monospace: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo,
Courier, monospace;
--font-family-sans: -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica,
Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/

import {useContext, useMemo} from 'react';
import {SettingsContext} from './Settings/SettingsContext';
import {THEME_STYLES} from '../../constants';

const useThemeStyles = () => {
const {theme, displayDensity, browserTheme} = useContext(SettingsContext);

const style = useMemo(
() => ({
...THEME_STYLES[displayDensity],
...THEME_STYLES[theme === 'auto' ? browserTheme : theme],
}),
[theme, browserTheme, displayDensity],
Comment on lines +18 to +22
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This style just focuses on theme-based vars

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I dig this change.

);

return style;
};

export default useThemeStyles;