[Emotion] Nested EuiThemeProviders now render a wrapper setting the correct inherited text color#6775
Conversation
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)
+ document new behavior
- 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
75e5835 to
c7ce7ef
Compare
|
Preview documentation changes for this PR: https://eui.elastic.co/pr_6775/ |
|
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 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! |
breehall
left a comment
There was a problem hiding this comment.
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:
- This was great walkthrough on some of our theming. Sometimes, our theming feels complex to me and this was a great exercise.
- 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.
- I'm very happy this addresses the
EuiBottomBartheming issue. We've also seen that popup quite a few times as well. - The consideration for layout fluctuation and the addition of
cloneElementinwrapperPropsis handy!
| } | ||
|
|
||
| export class EuiPortal extends Component<EuiPortalProps> { | ||
| static contextType = EuiNestedThemeContext; |
There was a problem hiding this comment.
I haven't really seen static since my Java days. This was a good refresher.
|
Thanks for the thorough review Bree! |
## 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>
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 nestedEuiThemeProviders, removing the need for the extra manualEuiText: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
EuiProviderwill never render a wrapper - only nestedEuiThemeChildren.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 thecolorCSS directly on thedata-euiportaldiv 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 globalbodycolor.ℹ️ 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, thedata-euiportaldiv is always present for portals.QA
inversepanels correctly updated, and the first twolight/darkmode panels did notinversepopovers, modals, and flyouts updated correctlyGeneral checklist
@defaultif default values are missing) and playground toggles- [ ] Checked Code Sandbox works for any docs examples- [ ] Checked for accessibility including keyboard-only and screenreader modes- [ ] Updated the Figma library counterpart