Your window into the Elastic Stack
Find a file
Pierre Gayvallet 523e91b63a
Implement system option for theme:darkMode uiSetting (#173044)
## Summary

Fix https://github.com/elastic/kibana/issues/89340

Implements a third option, `system`, for the `theme:darkMode`
uiSettings, which will follow the system's theme preference (light/dark)
when Kibana loads.


82078697-8bf5-41df-add1-4ecfed6e1dea

**Note: system theme refresh still requires the user to reload Kibana -
please see the next section for the reasons if you're interested**


## How theming works in Kibana, again?

This is an excellent question, thanks for asking. And the answer is,
"well, it's complicated".

We have multiples sources of "themed" styles in Kibana, ordered from
"best" to "worse":

#### 1. the EUI/JSS Theming

It was initially implemented in
https://github.com/elastic/kibana/pull/117368. All react applications
and react mountpoints are supposed to be wrapped by a
`KibanaThemeProvider` that bridges core's `theme$` values to the
`EuiProvider`.


477505a2dd/packages/core/theme/core-theme-browser-internal/src/core_theme_provider.tsx (L11)

This one was already dynamic and just works perfectly. If
`core.theme.theme$` changes, the new values is received by the theme
provider, which automatically changes the styles accordingly, creating
this sexy "it just works" effect:


f3e61ca7-f3ed-4c37-aa46-76ee68c1a628

If everything theme-related was using this approach, dynamic theme
reload would have been possible. However, Kibana has a lot of legacy, so
as you can imagine, it wasn't that easy.

So, **don't get false hopes** (as I did when I tried it...) from this
video. Dynamic theme swap **could not** be implemented in this PR. And
the reasons are just below.

#### 2. Per-theme css files


6443b57164/packages/core/rendering/core-rendering-server-internal/src/render_utils.ts (L40-L54)

We have a bunch of dark/light variations of some css files that are
computed in the rendering service, server-side, to be injected into the
page template.

Of course, this doesn't play well with dynamic theming, given the UI
then doesn't know which css should be swapped, and which one should be
added instead.

However, porting the responsibilities of which theme css files to load
to the browser was achievable, and done in this PR. core's browser-side
`theme` provider now receives the list of theme files for both light and
dark theme (via the injected metadata), and inject them in the document
(instead of having them pre-injected in the page template by the
rendering service server-side).

So this one wasn't a blocker for dynamic theme reload.  

#### 3. Plugin styles 

This is where the problems start.

Plugins can ship their own styles too, by importing them from components
or from their entrypoint.

E.g this component


f1dc1e1869/src/plugins/controls/public/control_group/component/control_group_component.tsx (L9)

importing this file:


bafb23580b/src/plugins/controls/public/control_group/control_group.scss (L107-L110)

Which relies on a theme variable, `$euiFormBackgroundColor`

So how does it works under the hood? How is that
`$euiFormBackgroundColor` variable interpolated? Using which theme?

Well, technically, how the styles are effectively loaded differs
slightly between dev and production (different webpack loaders/config),
but in both cases, it depends on the `__kbnThemeTag__` variable that is
injected to the global scope by the `bootstrap.js` script.

This `__kbnThemeTag__` tag (apparently) **can** be modified after page
load. However it doesn't magically reload everything, so styles already
loaded for one theme will not reload. If a component and its imported
styles were already compiled / injected, then they won't reload

As a short video is better than 3 blocks of text, just see:


3087ffd6-80d8-42bf-ab17-691ec408ea6f

That was the first blocker for supporting "dynamic" reloads of the
system theme.

#### 4. Static inline styles

Last but not least, we have some static style injected in the template,
that also depend on the current theme.


6443b57164/packages/core/rendering/core-rendering-server-internal/src/views/styles.tsx (L52-L54)

Of course this plays very badly with dynamic theming. And worth noting,
those styles are used by the "Loading Elastic" screen, where Core (and
therefore Core's theming service) isn't loaded yet, which made the
things even more complicated.

This was the second blocker for supporting "dynamic" reloads of the
system theme.

#### 5. `euiThemeVars`

Actually TIL (not that I was asking for it)

We're exposing the EUI theme variable via the `euiThemeVars` of the
`@kbn/ui-theme` package:

E.g.


c7e785383a/src/plugins/chart_expressions/expression_metric/public/components/metric_vis.tsx (L41)


c7e785383a/src/plugins/chart_expressions/expression_metric/public/components/metric_vis.tsx (L50)

So I did my best, and made it that this export was a proxy, and that
Core's theme service was dynamically swapping the target of the proxy
depending on the system's theme...


b0a0017811/packages/kbn-ui-theme/src/theme.ts (L30-L42)

Unfortunately it doesn't fully work for dynamic system theme switch,
given modules/code can keep references of the property directly (e.g.
the snippet a few lines on top), and there's nothing to dynamically
reload components when the proxy changes.

So yet another blocker for dynamic theme switch. 


## Release Notes

Add a new option, `system`, to the `theme:darkMode` Kibana advanced
setting, that can be used to have Kibana's theme follow the system's
(light or dark)

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
2024-02-20 06:48:58 -07:00
.buildkite skip failing suites (#177084) 2024-02-15 15:16:06 -06:00
.github [Dataset quality] Filters for timeRange, integrations and datasetQuery (#176611) 2024-02-19 08:16:47 -07:00
api_docs [api-docs] 2024-02-20 Daily api_docs build (#177249) 2024-02-20 06:15:49 +00:00
config [browser logging] allow to configure root level (#176397) 2024-02-12 05:26:57 -07:00
dev_docs [build] Add Docker images with FIPS (#175946) 2024-02-07 12:09:52 -08:00
docs Implement system option for theme:darkMode uiSetting (#173044) 2024-02-20 06:48:58 -07:00
examples [Core] Deprecate nav link status (#176383) 2024-02-16 11:06:33 -07:00
kbn_pm Replace deprecated node-sass with sass #2 (#173942) 2023-12-28 10:35:17 -06:00
legacy_rfcs rename @elastic/* packages to @kbn/* (#138957) 2022-08-18 08:54:42 -07:00
licenses Elastic License 2.0 (#90099) 2021-02-03 18:12:39 -08:00
packages Implement system option for theme:darkMode uiSetting (#173044) 2024-02-20 06:48:58 -07:00
plugins
scripts [Ops] Create CLI for rewriting buildkite agent targeting rules (#174688) 2024-01-18 10:29:08 +01:00
src Implement system option for theme:darkMode uiSetting (#173044) 2024-02-20 06:48:58 -07:00
test [DataViews] Improve management functional tests for serverless (#177146) 2024-02-20 10:52:48 +01:00
typings Remove legacy kibana react code editor (#171047) 2024-01-05 14:35:09 +01:00
x-pack Implement system option for theme:darkMode uiSetting (#173044) 2024-02-20 06:48:58 -07:00
.backportrc.json chore(NA): adds 8.14 into backportrc (#176936) 2024-02-14 19:48:14 +00:00
.bazelignore Bazel config maintenance (#135442) 2022-07-05 10:20:26 -05:00
.bazeliskversion chore(NA): upgrade bazelisk into v1.11.0 (#125070) 2022-02-09 20:43:57 +00:00
.bazelrc chore(NA): use new and more performant BuildBuddy servers (#130350) 2022-04-18 02:01:38 +01:00
.bazelrc.common Transpile packages on demand, validate all TS projects (#146212) 2022-12-22 19:00:29 -06:00
.bazelversion chore(NA): revert bazel upgrade for v5.2.0 (#135096) 2022-06-24 03:57:21 +01:00
.browserslistrc [browserslist] remove unnecessary browsers (#89186) 2021-01-25 16:30:18 -07:00
.editorconfig .editorconfig MDX files should follow the same rules as MD (#96942) 2021-04-13 11:40:42 -04:00
.eslintignore Remove Gainsight from cloud plugin (#172318) 2024-01-09 10:21:56 +00:00
.eslintrc.js [Security Solution] Data quality dashboard persistence (#173185) 2024-01-24 10:20:49 -07:00
.gitattributes
.gitignore [FTR] add service to test user roles on serverless (#170417) 2023-12-04 12:09:05 -07:00
.i18nrc.json [Obs ai assistant][ESQL] Visualizes a query (#174677) 2024-02-05 17:55:13 +02:00
.node-version chore(NA): bump node into v20 (#173461) 2024-01-02 14:49:19 -06:00
.npmrc
.nvmrc chore(NA): bump node into v20 (#173461) 2024-01-02 14:49:19 -06:00
.prettierignore [dev] Replace sass-lint with stylelint (#86177) 2021-01-15 11:52:29 -06:00
.prettierrc
.stylelintignore chore(NA): stop grouping bazel out symlink folders (#96066) 2021-04-01 14:16:14 -05:00
.stylelintrc Bump stylelint to ^14 (#136693) 2022-07-20 10:11:00 -05:00
.telemetryrc.json [Telemetry] Fix telemetry-tools TS parser for packages (#149819) 2023-01-31 04:09:09 +03:00
.yarnrc chore(NA): manage npm dependencies within bazel (#92864) 2021-03-03 12:37:20 -05:00
BUILD.bazel Transpile packages on demand, validate all TS projects (#146212) 2022-12-22 19:00:29 -06:00
catalog-info.yaml [ci] Create kibana-emergency-release pipeline (#176101) 2024-02-02 15:11:11 -06:00
CODE_OF_CONDUCT.md Add CODE_OF_CONDUCT.md (#87439) 2021-02-23 09:01:51 +01:00
CONTRIBUTING.md Update doc slugs to improve analytic tracking, move to appropriate folders (#113630) 2021-10-04 13:36:45 -04:00
FAQ.md Fix small typos in the root md files (#134609) 2022-06-23 09:36:11 -05:00
fleet_packages.json [main] Sync bundled packages with Package Storage (#177251) 2024-02-20 01:31:05 -07:00
github_checks_reporter.json
kibana.d.ts fix all violations 2022-04-16 01:37:30 -05:00
LICENSE.txt Elastic License 2.0 (#90099) 2021-02-03 18:12:39 -08:00
nav-kibana-dev.docnav.json Consolidate shared ux team dev docs (#172966) 2023-12-11 15:20:23 +01:00
NOTICE.txt Remove Gainsight from cloud plugin (#172318) 2024-01-09 10:21:56 +00:00
package.json [Dataset quality] Filters for timeRange, integrations and datasetQuery (#176611) 2024-02-19 08:16:47 -07:00
preinstall_check.js Always throw error objects - never strings (#171498) 2023-11-20 09:23:16 -05:00
README.md [README] Update version Compatibility with Elasticsearch (#116040) 2022-01-10 10:31:21 -05:00
renovate.json Remove unused Renovate config package rule (#176819) 2024-02-14 08:51:52 +01:00
RISK_MATRIX.mdx Add "Risk Matrix" section to the PR template (#100649) 2021-06-02 14:43:47 +02:00
SECURITY.md
sonar-project.properties [ci] Run sonarqube daily (#173961) 2024-01-03 15:43:29 -06:00
STYLEGUIDE.mdx [styleguide] update path to scss theme (#140742) 2022-09-15 10:41:14 -04:00
tsconfig.base.json [Dataset quality] Filters for timeRange, integrations and datasetQuery (#176611) 2024-02-19 08:16:47 -07:00
tsconfig.browser.json
tsconfig.browser_bazel.json [build_ts_refs] improve caches, allow building a subset of projects (#107981) 2021-08-10 22:12:45 -07:00
tsconfig.json Transpile packages on demand, validate all TS projects (#146212) 2022-12-22 19:00:29 -06:00
TYPESCRIPT.md Fix small typos in the root md files (#134609) 2022-06-23 09:36:11 -05:00
versions.json chore(NA): update versions after v8.14.0 bump (#176933) 2024-02-14 19:48:28 +00:00
WORKSPACE.bazel Upgrade yarn to 1.22.21 in WORKSPACE.bazel (#175632) 2024-01-25 14:39:36 -06:00
yarn.lock [Dataset quality] Filters for timeRange, integrations and datasetQuery (#176611) 2024-02-19 08:16:47 -07:00

Kibana

Kibana is your window into the Elastic Stack. Specifically, it's a browser-based analytics and search dashboard for Elasticsearch.

Getting Started

If you just want to try Kibana out, check out the Elastic Stack Getting Started Page to give it a whirl.

If you're interested in diving a bit deeper and getting a taste of Kibana's capabilities, head over to the Kibana Getting Started Page.

Using a Kibana Release

If you want to use a Kibana release in production, give it a test run, or just play around:

Building and Running Kibana, and/or Contributing Code

You might want to build Kibana locally to contribute some code, test out the latest features, or try out an open PR:

Documentation

Visit Elastic.co for the full Kibana documentation.

For information about building the documentation, see the README in elastic/docs.

Version Compatibility with Elasticsearch

Ideally, you should be running Elasticsearch and Kibana with matching version numbers. If your Elasticsearch has an older version number or a newer major number than Kibana, then Kibana will fail to run. If Elasticsearch has a newer minor or patch number than Kibana, then the Kibana Server will log a warning.

Note: The version numbers below are only examples, meant to illustrate the relationships between different types of version numbers.

Situation Example Kibana version Example ES version Outcome
Versions are the same. 7.15.1 7.15.1 💚 OK
ES patch number is newer. 7.15.0 7.15.1 ⚠️ Logged warning
ES minor number is newer. 7.14.2 7.15.0 ⚠️ Logged warning
ES major number is newer. 7.15.1 8.0.0 🚫 Fatal error
ES patch number is older. 7.15.1 7.15.0 ⚠️ Logged warning
ES minor number is older. 7.15.1 7.14.2 🚫 Fatal error
ES major number is older. 8.0.0 7.15.1 🚫 Fatal error

Questions? Problems? Suggestions?

  • If you've found a bug or want to request a feature, please create a GitHub Issue. Please check to make sure someone else hasn't already created an issue for the same topic.
  • Need help using Kibana? Ask away on our Kibana Discuss Forum and a fellow community member or Elastic engineer will be glad to help you out.