[Theme] Support theme level overrides#8558
Conversation
f0b75e1 to
988ed53
Compare
tkajtoch
left a comment
There was a problem hiding this comment.
The changes look and work good. I want to take a quick look on how the computed works in more detail and what performance implications it has before I approve this. This code is executed early and has direct impact on initial app render
tkajtoch
left a comment
There was a problem hiding this comment.
I checked the computed performance and the difference is insignificant.
LGTM ![]()
- ensures inherited colors are updated if the base is changed
- while ink and ghost are not defined for the theme, there is a use case for pure black and white tokens, expecially for HCM
- updates due to ink token change in HCM
- udpate after rebase
- ensures that provider level overrides apply ontop of theme level overrides
988ed53 to
95fe71d
Compare
|
@tkajtoch I rebased with main and additionally added another update (commit) that ensures the following override order (first item = lowest level; each following item overrides the previous):
ℹ️ HCM specific overrides in |
💚 Build Succeededcc @mgadewoll |
|
Preview staging links for this PR:
|
💚 Build Succeeded
History
cc @mgadewoll |
| const hcmBaseValue = _hcmBaseOverrides | ||
| ? _hcmBaseOverrides[key] instanceof Computed || | ||
| isComputedLike<T>(_hcmBaseOverrides[key]) | ||
| ? _hcmBaseOverrides[key].getValue( | ||
| base.root, | ||
| _hcmBaseOverrides.root, | ||
| output, | ||
| colorMode | ||
| ) | ||
| : _hcmBaseOverrides[key] | ||
| : undefined; | ||
| const hcmOverValue = _hcmOverOverrides | ||
| ? _hcmOverOverrides[key] instanceof Computed || | ||
| isComputedLike<T>(_hcmOverOverrides[key]) | ||
| ? _hcmOverOverrides[key].getValue( | ||
| base.root, | ||
| _hcmOverrides.root, | ||
| _hcmOverOverrides.root, | ||
| output, | ||
| colorMode | ||
| ) | ||
| : _hcmOverrides[key] | ||
| : _hcmOverOverrides[key] | ||
| : undefined; | ||
|
|
||
| const hcmCombinedOverValue = hcmOverValue ?? hcmBaseValue; |
There was a problem hiding this comment.
This feels not easily readable but upon further inspection it's very similar to the rest of the file, so I'm good with it for now.
We probably should eventually circle back to this and the whole theming logic.
There was a problem hiding this comment.
Yes, totally agree. I mentioned it in the description that for now we're just updating the existing logic but long term we should really refactor this. But I did not want to open this can of worms just now 😅
`101.3.0` ⏩ `101.4.0` [Questions? Please see our Kibana upgrade FAQ.](https://github.com/elastic/eui/blob/main/wiki/eui-team-processes/upgrading-kibana.md#faq-for-kibana-teams) ## Changes This PR only updates tests and snapshots related to changes on EUI side: - updated `aria-current="true"` to `aria-current="page"` - updated icon usage `userAvatar` to `user` ## Package updates ### `@elastic/eui` #### [`v101.4.0`](https://github.com/elastic/eui/releases/v101.4.0) - Spread `labelProps` to the `label` element in `EuiCheckableCard` ([#8586](elastic/eui#8586)) - Add `controls`, `flask`, `comment`, and `readOnly` glyphs to `EuiIcon` ([#8580](elastic/eui#8580)) - Refactored `EuiExpression`, `EuiFacetGroup`, `EuiFacetButton`, `EuiFilterGroup`, `EuiHeader`, `EuiImage` and `EuiListGroup` to memoize their internal Emotion styles ([#8565](elastic/eui#8565)) - Updated global `border.radius.medium` token value for default `Borealis` theme to `4px` ([#8563](elastic/eui#8563)) - Updated `EuiProvider` to build themes including `highContrastMode` ([#8558](elastic/eui#8558)) **Accessibility** - Removed the `aria-label` attribute from the `ul` element in `EuiPagination` to avoid duplicate screen reader output ([#8597](elastic/eui#8597)) - Set a more specific `aria-current="page"` on list items in `EuiPagination` ([#8597](elastic/eui#8597)) - Added `aria-modal` to `EuiFlyout` with `type="overlay"` ([#8591](elastic/eui#8591)) **Dependency updates** - Updated `@elastic/prismjs-esql` to v1.1.0 ([#8587](elastic/eui#8587)) ### `@elastic/eui-theme-borealis@0.2.0` - Updated component tokens to use `computed` values to ensure correct inheritance from theme overrides ([#8558](elastic/eui#8558)) - Added `overrides.HCM` to `euiThemeBorealis` to support theme internal overrides ([#8558](elastic/eui#8558)) - Updated `border.radius.medium` token value to `4px` ([#8563](elastic/eui#8563)) ### `@elastic/eui-theme-common@0.2.0` - Added support for theme `overrides` as optional part of `EuiThemeShape` ([#8558](elastic/eui#8558)) - Updated `getComputed` to support high contrast mode overrides defined on `overrides.HCM` ([#8558](elastic/eui#8558)) --------- Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
`101.3.0` ⏩ `101.4.0` [Questions? Please see our Kibana upgrade FAQ.](https://github.com/elastic/eui/blob/main/wiki/eui-team-processes/upgrading-kibana.md#faq-for-kibana-teams) ## Changes This PR only updates tests and snapshots related to changes on EUI side: - updated `aria-current="true"` to `aria-current="page"` - updated icon usage `userAvatar` to `user` ## Package updates ### `@elastic/eui` #### [`v101.4.0`](https://github.com/elastic/eui/releases/v101.4.0) - Spread `labelProps` to the `label` element in `EuiCheckableCard` ([elastic#8586](elastic/eui#8586)) - Add `controls`, `flask`, `comment`, and `readOnly` glyphs to `EuiIcon` ([elastic#8580](elastic/eui#8580)) - Refactored `EuiExpression`, `EuiFacetGroup`, `EuiFacetButton`, `EuiFilterGroup`, `EuiHeader`, `EuiImage` and `EuiListGroup` to memoize their internal Emotion styles ([elastic#8565](elastic/eui#8565)) - Updated global `border.radius.medium` token value for default `Borealis` theme to `4px` ([elastic#8563](elastic/eui#8563)) - Updated `EuiProvider` to build themes including `highContrastMode` ([elastic#8558](elastic/eui#8558)) **Accessibility** - Removed the `aria-label` attribute from the `ul` element in `EuiPagination` to avoid duplicate screen reader output ([elastic#8597](elastic/eui#8597)) - Set a more specific `aria-current="page"` on list items in `EuiPagination` ([elastic#8597](elastic/eui#8597)) - Added `aria-modal` to `EuiFlyout` with `type="overlay"` ([elastic#8591](elastic/eui#8591)) **Dependency updates** - Updated `@elastic/prismjs-esql` to v1.1.0 ([elastic#8587](elastic/eui#8587)) ### `@elastic/eui-theme-borealis@0.2.0` - Updated component tokens to use `computed` values to ensure correct inheritance from theme overrides ([elastic#8558](elastic/eui#8558)) - Added `overrides.HCM` to `euiThemeBorealis` to support theme internal overrides ([elastic#8558](elastic/eui#8558)) - Updated `border.radius.medium` token value to `4px` ([elastic#8563](elastic/eui#8563)) ### `@elastic/eui-theme-common@0.2.0` - Added support for theme `overrides` as optional part of `EuiThemeShape` ([elastic#8558](elastic/eui#8558)) - Updated `getComputed` to support high contrast mode overrides defined on `overrides.HCM` ([elastic#8558](elastic/eui#8558)) --------- Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com> (cherry picked from commit d2d2765) # Conflicts: # x-pack/solutions/security/plugins/security_solution/public/explore/components/paginated_table/__snapshots__/index.test.tsx.snap # x-pack/solutions/security/plugins/security_solution/public/explore/components/paginated_table/index.test.tsx # x-pack/solutions/security/plugins/security_solution/public/explore/hosts/components/uncommon_process_table/__snapshots__/index.test.tsx.snap # x-pack/solutions/security/plugins/security_solution/public/explore/network/components/network_dns_table/__snapshots__/index.test.tsx.snap # x-pack/solutions/security/plugins/security_solution/public/explore/network/components/network_http_table/__snapshots__/index.test.tsx.snap # x-pack/solutions/security/plugins/security_solution/public/explore/network/components/network_top_countries_table/__snapshots__/index.test.tsx.snap # x-pack/solutions/security/plugins/security_solution/public/explore/network/components/network_top_n_flow_table/__snapshots__/index.test.tsx.snap # x-pack/solutions/security/plugins/security_solution/public/explore/network/components/tls_table/__snapshots__/index.test.tsx.snap # x-pack/solutions/security/plugins/security_solution/public/explore/network/components/users_table/__snapshots__/index.test.tsx.snap
`101.3.0` ⏩ `101.4.0` [Questions? Please see our Kibana upgrade FAQ.](https://github.com/elastic/eui/blob/main/wiki/eui-team-processes/upgrading-kibana.md#faq-for-kibana-teams) >[!IMPORTANT] This PR is a direct sibling to this [upgrade PR](#218778) to `main`. The difference is that it adds a standalone EUI package with the previous "Amsterdam" theme. Apart from the theme difference, **there are no further changes added**. ## Changes This PR only updates tests and snapshots related to changes on EUI side: - updated `aria-current="true"` to `aria-current="page"` - updated icon usage `userAvatar` to `user` ## Package updates ### `@elastic/eui` #### [`v101.4.0`](https://github.com/elastic/eui/releases/v101.4.0) - Spread `labelProps` to the `label` element in `EuiCheckableCard` ([#8586](elastic/eui#8586)) - Add `controls`, `flask`, `comment`, and `readOnly` glyphs to `EuiIcon` ([#8580](elastic/eui#8580)) - Refactored `EuiExpression`, `EuiFacetGroup`, `EuiFacetButton`, `EuiFilterGroup`, `EuiHeader`, `EuiImage` and `EuiListGroup` to memoize their internal Emotion styles ([#8565](elastic/eui#8565)) - Updated global `border.radius.medium` token value for default `Borealis` theme to `4px` ([#8563](elastic/eui#8563)) - Updated `EuiProvider` to build themes including `highContrastMode` ([#8558](elastic/eui#8558)) **Accessibility** - Removed the `aria-label` attribute from the `ul` element in `EuiPagination` to avoid duplicate screen reader output ([#8597](elastic/eui#8597)) - Set a more specific `aria-current="page"` on list items in `EuiPagination` ([#8597](elastic/eui#8597)) - Added `aria-modal` to `EuiFlyout` with `type="overlay"` ([#8591](elastic/eui#8591)) **Dependency updates** - Updated `@elastic/prismjs-esql` to v1.1.0 ([#8587](elastic/eui#8587)) ### `@elastic/eui-theme-borealis@0.2.0` - Updated component tokens to use `computed` values to ensure correct inheritance from theme overrides ([#8558](elastic/eui#8558)) - Added `overrides.HCM` to `euiThemeBorealis` to support theme internal overrides ([#8558](elastic/eui#8558)) - Updated `border.radius.medium` token value to `4px` ([#8563](elastic/eui#8563)) ### `@elastic/eui-theme-common@0.2.0` - Added support for theme `overrides` as optional part of `EuiThemeShape` ([#8558](elastic/eui#8558)) - Updated `getComputed` to support high contrast mode overrides defined on `overrides.HCM` ([#8558](elastic/eui#8558))
`101.3.0` ⏩ `101.4.0` [Questions? Please see our Kibana upgrade FAQ.](https://github.com/elastic/eui/blob/main/wiki/eui-team-processes/upgrading-kibana.md#faq-for-kibana-teams) ## Changes This PR only updates tests and snapshots related to changes on EUI side: - updated `aria-current="true"` to `aria-current="page"` - updated icon usage `userAvatar` to `user` ## Package updates ### `@elastic/eui` #### [`v101.4.0`](https://github.com/elastic/eui/releases/v101.4.0) - Spread `labelProps` to the `label` element in `EuiCheckableCard` ([elastic#8586](elastic/eui#8586)) - Add `controls`, `flask`, `comment`, and `readOnly` glyphs to `EuiIcon` ([elastic#8580](elastic/eui#8580)) - Refactored `EuiExpression`, `EuiFacetGroup`, `EuiFacetButton`, `EuiFilterGroup`, `EuiHeader`, `EuiImage` and `EuiListGroup` to memoize their internal Emotion styles ([elastic#8565](elastic/eui#8565)) - Updated global `border.radius.medium` token value for default `Borealis` theme to `4px` ([elastic#8563](elastic/eui#8563)) - Updated `EuiProvider` to build themes including `highContrastMode` ([elastic#8558](elastic/eui#8558)) **Accessibility** - Removed the `aria-label` attribute from the `ul` element in `EuiPagination` to avoid duplicate screen reader output ([elastic#8597](elastic/eui#8597)) - Set a more specific `aria-current="page"` on list items in `EuiPagination` ([elastic#8597](elastic/eui#8597)) - Added `aria-modal` to `EuiFlyout` with `type="overlay"` ([elastic#8591](elastic/eui#8591)) **Dependency updates** - Updated `@elastic/prismjs-esql` to v1.1.0 ([elastic#8587](elastic/eui#8587)) ### `@elastic/eui-theme-borealis@0.2.0` - Updated component tokens to use `computed` values to ensure correct inheritance from theme overrides ([elastic#8558](elastic/eui#8558)) - Added `overrides.HCM` to `euiThemeBorealis` to support theme internal overrides ([elastic#8558](elastic/eui#8558)) - Updated `border.radius.medium` token value to `4px` ([elastic#8563](elastic/eui#8563)) ### `@elastic/eui-theme-common@0.2.0` - Added support for theme `overrides` as optional part of `EuiThemeShape` ([elastic#8558](elastic/eui#8558)) - Updated `getComputed` to support high contrast mode overrides defined on `overrides.HCM` ([elastic#8558](elastic/eui#8558)) --------- Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
Summary
Closes https://github.com/elastic/eui-private/issues/281
This PR adds support for theme-specific overrides directly on the theme definition layer.
While we already have ways to override theme tokens (using the
modifyprop on theEuiProvider) this way is limited to what's available to the provider (e.g. it does not have access to the primitive tokens).Note
HCM: Currently we add overrides for high contrast mode here.
This use passes overrides via the
modifyprop to the provider. Anything added there currently is applied to any theme active on the provider, it's a global override.For theme-specific overrides we instead would want to provide the overrides directly on the definition layer (e.g. here).
A use case we'll need to support this way soon: specific sets of data vis colors in high contrast mode.
The suggested change enables the current theming functionality to support an optional
overrideskey on theEuiThemeShapeand updates thegetComputedtheming function to include the required overrides (the implementation so far considersHCM(high contrast mode) overrides. The approach follows what's already available for definingLIGHTandDARKvariants per color mode. Theoverrideskey is part of theEuiThemeShape(input theme) only, it will not be included on theEuiThemeComputed(output theme).usage

Note
The code for building and updating themes is old, not that easy to follow and overall rather cumbersome. This PR only adds onto the code for now. In the future (likely once we have fully migrated off Amsterdam and finished Borealis) we might want to consider refactoring those functions in general to improve functionality and maintainability.
Changes
getComputedto supporthighContrastModeviaoverrides.HCMon the theme objectcomputedvalues (where possible) to ensure tokens are updated accordingly by overrides they inherit from (the alternative would be to have to override each token manually, which a) is still possible but mainly b) seems less favorable in terms of devX)@deprecatedmark oninkandghosttokens - while those are not expected in the theme, there is a use case for having true black and white tokens (currently at least for HCM)inkandghosttokens (resets them to primitive black and white to ensure highest possible contrasts)QA
EuiButtonwithfill={true}here - the custom overrides (code) should apply (and be inherited by the button tokens)(code)Screen.Recording.2025-04-07.at.17.51.07.mov
General checklist
Checked in mobileChecked for accessibility including keyboard-only and screenreader modesAdded documentationProps have proper autodocs (using@defaultif default values are missing) and playground togglesChecked Code Sandbox works for any docs examplesAdded or updated jest and cypress testsIf applicable, added the breaking change issue label (and filled out the breaking change checklist)If applicable, file an issue to update EUI's Figma library with any corresponding UI changes. (This is an internal repo, if you are external to Elastic, ask a maintainer to submit this request)