Themes are defined in OUI via https://github.com/opensearch-project/oui/blob/main/src/themes/themes.ts. When Building OUI, there are several theming artifacts generated (beyond the react components) for each mode (light/dark) of each theme:
- Theme compiled stylesheets (e.g.
@elastic/eui/dist/eui_theme_dark.css
). Consumed as entry files in /packages/osd-ui-shared-deps/webpack.config.js and republished byosd-ui-shared-deps
(e.g. UiSharedDeps.themeCssDistFilenames). - Theme compiled and minified stylesheets (e.g.
@elastic/eui/dist/eui_theme_dark.min.css
). These appear unused by OpenSearch Dashboards - Theme computed SASS variables as JSON (e.g.
@elastic/eui/dist/eui_theme_dark.json
). Consumed by /packages/osd-ui-shared-deps/theme.ts and made available to other components via the mode and theme awareeuiThemeVars
. In general, these should not be consumed by any other component directly. - Theme type definition file for SASS variables as JSON (e.g.
@elastic/eui/dist/eui_theme_dark.json.d.ts
)
Note that all of these artifacts should ideally only be imported or used directly in one place (by osd-ui-shared-deps
).
In addition to these artifacts, OpenSearch Dashboards also makes heavy use of the theme SASS variables and mixins as defined in the source files (e.g. @elastic/eui/src/theme_dark.scss
).
- Theme tags are defined in /packages/osd-optimizer/src/common/theme_tags.ts corresponding to each mode (light/dark) of each OUI theme.
- These tags must correspond to entrypoint SCSS files in /src/core/public/core_app/styles/, because they are imported by all SCSS files as part of the
sass-loader
in /packages/osd-optimizer/src/worker/webpack.config.ts and /packages/osd-optimizer/src/worker/theme_loader.ts. Note that the optimizer webpack will compile a separate stylesheet for each unique mode and theme combination. - OUI SCSS source files are also imported by
osd-ui-framework
, which generates the legacy KUI stylesheets (e.g. /packages/osd-ui-framework/src/kui_next_dark.scss). KUI is a UI library that predates EUI/OUI, and should be deprecated and fully removed via #1060. Because it's a legacy package it has its own build process that doesn't use webpack; it just compiles the SCSS files with grunt. But similarly to 2., a separate stylesheet is generated for each mode and theme combination.
In general, most themed assests can be found in /src/core/server/core_app/assets (it also includes non-themed assets such as favicons
, which could easily be themed if desired in the future).
Most of the graphics/images are only dark/light mode-specific, not theme-specific:
default_branding
markslogos
This directory also includes legacy CSS files (/src/core/server/core_app/assets/legacy_dark_theme.css and /src/core/server/core_app/assets/legacy_light_theme.css), which predate even KUI, and are still used by some plugins (notably discover
). See #4385 for an experiment in removing these. Unlike KUI, they don't rely on OUI themes at all.
Finally, font assets are a bit of a special case. Theme-specific fonts are defined by OUI, but it doesn't include the font definitions directly. Instead, the font assets are in /src/core/server/core_app/assets/fonts. The corresponding @font-face
style definitions are generated at runtime via /src/core/server/rendering/views/fonts.tsx.
sequenceDiagram
autonumber
critical Setup
core/server->>core/server/rendering: setup rendering service
core/server/rendering->>core/server: provide render() method
core/server->>core/server: setup legacy service
core/server->>legacy: create legacy server
legacy->>legacy: start ui mixin to<br>handle special routes
core/server->>core/server/core_app: setup core app
core/server/core_app->>core/server/core_app: register default routes
core/server/core_app->>core/server/core_app: register static asset dir routes
end
Browser->>core/server: OSD page request (e.g. /app/home#/ )
core/server->>core/server/core_app: request to default route<br>(via `http` service)
core/server/core_app->>core/server: call renderCoreApp()
core/server->>core/server/rendering: call render()
critical Initial page bootstrap
core/server/rendering->>core/server/rendering: get theme settings from config
core/server/rendering->>core/server/rendering: assign branding values \<br>(including dark mode)
core/server/rendering->>Browser: return static loading page template
Note over core/server/rendering,Browser: includes inlined font-face styles and static loading page styles
critical <head> (render blocking)
Browser->>Browser: define injection points
Browser->>Browser: load static loading page styles
Browser->>Browser: load font-face styles
Browser->>legacy: load startup.js special route
legacy->>legacy: build startup.js from template
Note over legacy: inject theme settings and font sources
legacy->>Browser: startup.js
critical startup.js
Browser->>Browser: get theme preferences from local storage
Browser->>Browser: set global theme tag
Browser->>Browser: inject theme-specific loading page styles
Browser->>Browser: inject theme-specific font css vars
end
end
Browser->>Browser: render loading/error page<br>(with loaders hidden)
Browser->>legacy: load bootstrap.js special route
legacy->>legacy: build bootstrap.js from template
legacy->>Browser: bootstrap.js
critical bootstrap.js
Browser->>Browser: toggle visibility of errors/loaders
Browser->>Browser: get theme preferences from local storage
Browser->>core/server/core_app: load js bundles
core/server/core_app->>Browser: (React application)
Browser->>core/server/core_app: load theme-specific stylesheets<br>(base, OUI, KUI, legacy)
core/server/core_app->>Browser: themed css
end
end
src/legacy/ui/ui_render/ui_render_mixin.js
via src/legacy/ui/ui_render/bootstrap/template.js.hbs
and src/legacy/ui/ui_render/bootstrap/app_bootstrap.js
. Aliased in src/legacy/ui/ui_mixin.js
, called by src/legacy/server/osd_server.js
. Called by src/core/server/legacy/legacy_service.ts
via src/core/server/server.ts
src/core/server/rendering/views/styles.tsx
- depends on dark/light mode and injects style tag in headsrc/core/server/rendering/views/fonts.tsx
- depends on theme version and injects font style tag in head- Monaco editor styles
- Ace styles
- Ace TM overrides
- Ace error styles
- Component styles
Each of the following are loaded in the browser by the bootstrap script in this order. Currently, these are never unloaded.
- Monaco editor styles (e.g. /packages/osd-ui-shared-deps/target/osd-ui-shared-deps.css), packaged by /packages/osd-ui-shared-deps/webpack.config.js. In theory, this file could include styles from other shared dependencies, but currently
osd-monaco
is the only package that exports styles. Note that these are the default, un-themed styles; theming of monaco editors is handled by /src/plugins/opensearch_dashboards_react/public/code_editor/editor_theme.ts. - Theme and mode-specific OUI styles (e.g. , compiled by
packages/osd-ui-shared-deps/webpack.config.js
). - Theme and mode-specific KUI styles (e.g.
packages/osd-ui-framework/src/kui_next_dark.scss
, compiled bypackages/osd-ui-framework/Gruntfile.js
). Separate stylesheets for each theme version/dark mode combo (colors). - Mode-specific legacy styles (e.g. /src/core/server/core_app/assets/legacy_dark_theme.css)
Component styles are not loaded as stylesheets.
- Defined by
packages/osd-ui-shared-deps/theme.ts
- Used by
src/plugins/charts/public/static/color_maps/color_maps.ts
to set vis colors - Used by
src/plugins/discover/public/application/components/chart/histogram/histogram.tsx
to define Discover histogram Elastic Chart styling - Used by
src/plugins/maps_legacy/public/map/opensearch_dashboards_map.js
andsrc/plugins/region_map/public/choropleth_layer.js
for minor map UI styling (line color, empty shade) - Used by
src/plugins/vis_type_vega/public/data_model/vega_parser.ts
for Vega/Vega-Lite theming
- Used by
- Used by
src/plugins/vis_type_vislib/public/vislib/components/tooltip/tooltip.js
for tooltip spacing - Used by
src/plugins/expressions/public/react_expression_renderer.tsx
to define padding options. - Used by
src/core/server/rendering/views/theme.ts
to inject values intosrc/core/server/rendering/views/styles.tsx
- Used (incorrectly) to style a badge color in
src/plugins/index_pattern_management/public/components/create_button/create_button.tsx
- Used by
src/plugins/opensearch_dashboards_react/public/code_editor/editor_theme.ts
to create Monaco theme styles
Update DEFAULT_THEME_VERSION
in src/core/server/ui_settings/ui_settings_config.ts
to point to the desired theme version.
- Add a a new theme to OUI and publish new OUI version
- Update OSD to consume new OUI version
- Make the following changes in OSD:
- Load your theme by creating sass files in
src/core/public/core_app/styles
- Update webpack config to create css files for your theme
- Add kui css files:
- Create kui sass files for your theme in
packages/osd-ui-framework/src/
- Update
packages/osd-ui-framework/Gruntfile.js
to build these files - Generate the files by running
npx grunt compileCss
from this package root
- Create kui sass files for your theme in
- Add fonts to OSD:
- Make sure your theme fonts are in /src/core/server/core_app/assets/fonts
- Update
src/core/server/rendering/views/fonts.tsx
to reference those files - Update src/core/server/core_app/assets/fonts/readme.md to reference the fonts
- Update
packages/osd-ui-shared-deps/theme_config.js
:- Add version and label for version to
THEME_VERSION_LABEL_MAP
- Update
kuiCssDistFilenames
map for new theme - Update
ThemeTag
type in corresponding definition file (theme_config.d.ts
)
- Add version and label for version to
- Load variables for new theme in
packages/osd-ui-shared-deps/theme.ts'
- Update `src/legacy/ui/ui_render/ui_render_mixin.js':
- Load variables for your theme in
THEME_SOURCES
- Define the text font for your theme in
fontText
- Define the code font for your theme in
fontCode
- Load variables for your theme in
- Load your theme by creating sass files in