Skip to content
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

[Emotion] Nested EuiThemeProviders now render a wrapper setting the correct inherited text color #6775

Merged
merged 12 commits into from
May 17, 2023

Conversation

cee-chen
Copy link
Member

@cee-chen cee-chen commented May 15, 2023

Summary

closes #6353

I strongly recommend following along by commit - the existing issue is already fairly complex, and there's some additional cleanup happening.

Non-portalled content

Nested content would previously require an extra nested <EuiText color="default"> in order for text color to inherit properly:

Now, an extra configurable <span className="euiThemeProvider> wrapper is added automatically to nested EuiThemeProviders, removing the need for the extra manual EuiText:

Consumers can optionally pass <EuiThemeProvider wrapperProps={{ cloneElement: true }}> to clone the necessary CSS class onto a single passed child, if they wish to avoid the wrapper for layout or other reasons:

ℹ️ Note that the top level EuiProvider will never render a wrapper - only nested EuiThemeChildren.

Portalled content

Portalled content needs to be handled separately, as it will not inherit from the added wrapper, and will instead almost certainly be positioned to inherit directly from <body>. As a result, I added some extra logic in 3c71c2a that sets the color CSS directly on the data-euiportal div wrapper. In an attempt to reduce downstream snapshot churn, I set up portals to only add this CSS if their inherited color is different from the global body color.

ℹ️ Note: I deliberately avoided using this type of conditional logic for the un-portalled <EuiThemeProvider> spans - the unpredictability of an entire DOM wrapper conditionally appearing and disappearing has far more consequences on layout breakage than just a className. In contrast, the data-euiportal div is always present for portals.

QA

  • Go to https://eui.elastic.co/pr_6775/#/theming/color-mode#rendering-a-specific-color-mode
  • Confirm that text in the panels render as the correct colors
  • Confirm that popovers, modals, and flyouts opened from the nested theme providers render as the correct colors
  • On the main page bar, switch the docs color mode to the opposite of what you had it as (likely dark)
  • Confirm that the inverse panels correctly updated, and the first two light/dark mode panels did not
  • Confirm that the inverse popovers, modals, and flyouts updated correctly

General checklist

  • Checked in both light and dark modes
  • Checked in mobile
  • Checked in Chrome, Safari, Edge, and Firefox
  • Props have proper autodocs (using @default if default values are missing) and playground toggles
  • Added documentation
  • Added or updated jest and cypress tests
  • A changelog entry exists and is marked appropriately
  • Checked for breaking changes and labeled appropriately

- [ ] Checked Code Sandbox works for any docs examples
- [ ] Checked for accessibility including keyboard-only and screenreader modes
- [ ] Updated the Figma library counterpart

context sets up:
- whether the current theme should render a `span` (i.e., is global theme or is nested)
- sets up a resable `className` string that can be reused across both React elements and DOM nodes (important for portals)
- for consumers who have a single child / where an extra rendered wrapper will cause layout issues

+ update `EuiButton`s with `color="ghost"` to use cloneElement
- it's causing a snapshot diff when it shouldn't/doesn't need to; in general we should no longer be taking mounted snapshots
+ add a 3rd level nested demo w/ `cloneElement`
-  there's already a `data-euiportal` wrapper around all portals to bogart, so no need to create one

- in an attempt to reduce snapshot churn in Kibana's side of things, I've opted to only render a CSS class if the theme color is different from the `body` color

+ [tech debt] switch `portal.test.tsx` tests to RTL render
- e.g., EuiModal, EuiFlyout

+ [tech debt] Add missing overlay mask tests using RTL
- should use `cloneElement` behavior instead of a wrapper

- no longer needs to set `color`

+ [tech debt] update tests to use RTL
- appears to have been replaced by `color_mode/inverse` instead
@cee-chen cee-chen force-pushed the emotion/nested-color-modes branch from 75e5835 to c7ce7ef Compare May 15, 2023 23:55
@kibanamachine
Copy link

Preview documentation changes for this PR: https://eui.elastic.co/pr_6775/

@cee-chen cee-chen marked this pull request as ready for review May 16, 2023 00:29
@cee-chen
Copy link
Member Author

cee-chen commented May 16, 2023

Hey @elastic/eui-team! Does anyone on here have a spare half hour to an hour to review this PR this week? Following the QA steps checklist and performing a quick code review (that I strongly recommend following by commit for) should hopefully be all that's needed. This PR is not urgent and does not need to get in before Tuesday's release.

Once this merges and hits Kibana, we'll almost certainly need to audit all usages of <EuiThemeProvider> in Kibana to ensure no layout issues occur as a result of this change. I can assist with whoever is is handling the Kibana upgrade for that week; please ping me for that.

I'll also be making use of Matthias's kibana a-la-carte w/ this branch ahead of time to see what fails and passes in Kibana CI ahead of time. Fingers crossed!

Copy link
Contributor

@breehall breehall left a comment

Choose a reason for hiding this comment

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

This is great Cee! It's an elegant solution to a complex problem. I followed commit-by-commit and also used your testing steps. Here are a few of my overall thoughts:

  1. This was great walkthrough on some of our theming. Sometimes, our theming feels complex to me and this was a great exercise.
  2. I really like the new documentation and examples that were added! I can see this being more helpful to consumers and reducing the frequency that we see this question (and variants) pop up in the EUI channel. I can also see this being very helpful for our team for visually testing.
  3. I'm very happy this addresses the EuiBottomBar theming issue. We've also seen that popup quite a few times as well.
  4. The consideration for layout fluctuation and the addition of cloneElement in wrapperProps is handy!

@@ -41,6 +43,8 @@ export interface EuiPortalProps {
}

export class EuiPortal extends Component<EuiPortalProps> {
static contextType = EuiNestedThemeContext;
Copy link
Contributor

Choose a reason for hiding this comment

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

I haven't really seen static since my Java days. This was a good refresher.

@cee-chen
Copy link
Member Author

Thanks for the thorough review Bree!

@cee-chen cee-chen merged commit f516c12 into elastic:main May 17, 2023
@cee-chen cee-chen deleted the emotion/nested-color-modes branch May 17, 2023 16:14
cee-chen added a commit to elastic/kibana that referenced this pull request May 31, 2023
## Summary

`@elastic/eui@80.0.0` ⏩ `@elastic/eui@81.0.0`

---

## [`81.0.0`](https://github.com/elastic/eui/tree/v81.0.0)

- Added ability to set `options.checked` to "mixed" in `EuiSelectable`
([#6774](elastic/eui#6774))

**Bug fixes**

- Portalled components (e.g. `EuiPopover`, `EuiModal`, `EuiFlyout`) will
correctly inherit text color from its nearest `EuiThemeProvider` parent.
`<EuiText color="default">` is no longer needed.
([#6775](elastic/eui#6775))

**Breaking changes**

- `EuiSelectable` no longer renders a `data-test-selected` attribute on
its list items. Use the `aria-checked` property instead
([#6774](elastic/eui#6774))
- Nested `EuiThemeProvider`s now render a wrapping `<span>` element in
order to correctly set the inherited text `color` of all descendants.
`<EuiText color="default">` is no longer needed.
([#6775](elastic/eui#6775))

---------

Co-authored-by: Stratoula Kalafateli <efstratia.kalafateli@elastic.co>
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
Co-authored-by: Constance Chen <constance.chen@elastic.co>
sloanelybutsurely pushed a commit to sloanelybutsurely/kibana that referenced this pull request Jun 6, 2023
## Summary

`@elastic/eui@80.0.0` ⏩ `@elastic/eui@81.0.0`

---

## [`81.0.0`](https://github.com/elastic/eui/tree/v81.0.0)

- Added ability to set `options.checked` to "mixed" in `EuiSelectable`
([elastic#6774](elastic/eui#6774))

**Bug fixes**

- Portalled components (e.g. `EuiPopover`, `EuiModal`, `EuiFlyout`) will
correctly inherit text color from its nearest `EuiThemeProvider` parent.
`<EuiText color="default">` is no longer needed.
([elastic#6775](elastic/eui#6775))

**Breaking changes**

- `EuiSelectable` no longer renders a `data-test-selected` attribute on
its list items. Use the `aria-checked` property instead
([elastic#6774](elastic/eui#6774))
- Nested `EuiThemeProvider`s now render a wrapping `<span>` element in
order to correctly set the inherited text `color` of all descendants.
`<EuiText color="default">` is no longer needed.
([elastic#6775](elastic/eui#6775))

---------

Co-authored-by: Stratoula Kalafateli <efstratia.kalafateli@elastic.co>
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
Co-authored-by: Constance Chen <constance.chen@elastic.co>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Emotion] Global styles aren't overridden by color mode changes
3 participants