Theming
In this guide you will learn about theming in JUI. You will read about what a theme is, how to create and provide it, and how to use it to created your own themed components.
Theme
Styling in JUI is implemented with styled-components, and it requires an object of type
Theme
to be provided by styled-component's theme context.
Theme
class implements the interface for accessing common colors, resolving theme values, icons, etc.
ThemeProvider
Similar to styled-component's ThemeProvider, provides ThemeContext. With a few additions and nuances:
- It also provides the default font styles (overridable via props), as well as a minimal normalization style on
body
. Global styles can be disabled viaThemeProviderProps#globalStyles
, if needed. - Unlike styled-component's
ThemeProvider
, it doesn't merge nested themes, into a plain object. That's important, because a theme must be an instance ofTheme
class.
Creating a theme
Use Theme
constructor to create a theme object:
import { Theme } from "@intellij-platform/core";
import darculaThemeJson from "@intellij-platform/core/themes/darcula.theme.json";
const theme = new Theme(darculaThemeJson);
Theme json
The only required arguments for creating a Theme is a plain theme object of type ThemeJson
, which is usually imported
from a .theme.json
file. The following .theme.json
files from Intellij Community are
available out of the box:
@intellij-platform/core/themes/darcula.theme.json
@intellij-platform/core/themes/intelijlaf.theme.json
@intellij-platform/core/themes/HighContrast.theme.json
You can also find many theme plugins, each containing a
.theme.json
file.
Nord theme example
In the example below, nord.theme.json from Nord theme's github repo is fetched and used:
IconResolver
Theme depends on an IconResolver
implementation for resolving svg icons. By default GithubIconResolver
is used,
which fetches icons from Intellij Community repo.
An alternative implementation can be passed to the iconResolver
argument in Theme
's constructor:
import { Theme, IconResolver } from "@intellij-platform/core";
class MyIconResolver implements IconResolver {
//...
}
const theme = new Theme(themeJson, new MyIconResolver());
Operating system
Properties in ThemeJson
can have os-dependent values. See selectionBackground in darcula theme
as an example. In order to resolve os-dependent values, a theme needs to know what the current operating system is.
While the default value is detected based on the window.navigator
, you can override that and set the value in
Theme
's constructor:
const theme = new Theme(
themeJson,
undefined /* going with the default icon resolver */,
"windows"
);
Theming your own components
Resolving values
🚧 TODO: explain .color()
and more generic .value()
methods. 🚧
Fallback when resolving values
🚧 TODO: explain star fallback and difference with fallback
argument. 🚧
Accessing theme in components
The best way to use theme in styling your own components is to use styled components:
import { styled } from "@intellij-platform/core";
const MyComponent = styled`
background: ${({ theme }) => theme.color("Panel.background")};
`;
You can also use styled-component API for getting the theme without styled components:
import { useTheme } from "@intellij-platform/core";
function MyComponent() {
const theme = useTheme();
// ...
}
In order to get the right type for theme
in your styled components, import styled
, css
or useTheme
, etc. from
@intellij-platform/core, instead of styled-components. They are the same as the ones from styled-components,
only with the adjusted theme type.
If you wish to import from styled-components
, you need to create a declarations file to
extend styled-component's DefaultTheme
.