Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature]: Add dark theme support to Jaeger-UI #1911

Open
anshgoyalevil opened this issue Oct 24, 2023 · 6 comments
Open

[Feature]: Add dark theme support to Jaeger-UI #1911

anshgoyalevil opened this issue Oct 24, 2023 · 6 comments

Comments

@anshgoyalevil
Copy link
Member

anshgoyalevil commented Oct 24, 2023

Requirement

Since Jaeger is a distributed tracing platform, we sometimes need to look at the traces the whole day. Working with a high-contrast UI becomes a pain for the eye in such cases.

Problem

Jaeger-UI currently supports only the light theme. A dark theme would help users focus on observability rather than eye strain.

Proposal

Since react v18, and ant-design v5, the support for dynamic theming and state management has improved.

ant-design provides three theme algorithms: defaultAlgorithm, darkAlgorithm, and compactAlgorithm. Our concern is with the first two.

We can change the jaegerTheme's default algorithm based on the current state of the theme. For example:

const jaegerTheme = {
+ algorithm: theme.darkAlgorithm, <-- should be a state variable rather than hardcoded. Example: algorithm: currTheme
  token: {
    ...defaultTheme.token,
    colorPrimary: '#199',
  },
  components: {
    ...defaultTheme.components,
    Layout: {
      ...defaultTheme.components.Layout,
      bodyBg: '#fff',
      headerBg: '#404040',
      footerBg: '#fff',
      headerHeight: 48,
      headerPadding: '0 50',
....rest of code

will change the whole Jaeger-UI to dark mode, but currently, since we haven't designed the whole UI that way, there are many areas where the theme still remains the same, i.e., light.

State management features of react (ex, useState in react 18) can be used to manage the current algorithm's value and can be used to set the theme dynamically based on the click of a button, like in most applications.

Actionable items:

  • Introduce enableThemes config option (default: false) to allow to experiment with dark theme
  • Add a Switch kind of component to the NavBar to toggle between dark and light modes (guarded by enableThemes)
  • Remove the hard-coded themes from the codebase, and make use of colors based on the current theme state's algorithm
  • Go step-by-step, with small code changes/PRs at each step.
  • Use state management to change/store the current theme.

Relevant documentation:

Feel free to create child issues and relevant PRs related to this issue

@yurishkuro
Copy link
Member

This is not a small issue in itself, but can be broken into many small changes that are actually good-first-issues

@yurishkuro
Copy link
Member

@anshgoyalevil this section describes a lot of pre-defined names/tokens. Is the intention that our higher-level components should be using those tokens for their styles as well? We have a bunch of custom styles, I am wondering if they all need to be migrated, or if the approach that we can keep those custom tokens but migrate them into the themes framework to allow switching.

@anshgoyalevil
Copy link
Member Author

anshgoyalevil commented Oct 24, 2023

Yes. Most probably, we would have to create the two themes, light, and dark. Both have their own algorithms, and design tokens according to the style we want to apply to that specific component. The useToken() hook would allow us to consume the design tokens specified in the theme object.

For example:

const darkTheme = {
  algorithm: theme.darkAlgorithm,
  token: {
    ...defaultTheme.token,
    colorPrimary: '#fff', // Primary color for dark mode
  },
...rest of the theme object
const lightTheme = {
  algorithm: theme.defaultAlgorithm,
  token: {
    ...defaultTheme.token,
    colorPrimary: '#000', // Primary color for light mode
  },
...rest of the theme object

We can toggle between these two themes using the useState hook, or any other such thing. Now to consume the values defined over here, we can do it using the useToken hook like useToken().colorPrimary etc.
This useToken() hook can be consumed via the props received from withRouteProps HOC, or any other such approach because we are using class components and can't directly use hooks inside them.
(Not 100% sure about this approach. I haven't used it practically. Some additional research is required from the person working on it :) )

So yes, that would be a lot of work to do, since we are trying to introduce dark mode support to a large codebase.

@AHB102
Copy link

AHB102 commented Nov 5, 2023

@yurishkuro So is this good for someone like me ? I am new to open source, would like to contribute but don't know how to, if so, can I start contributing ?

@yurishkuro
Copy link
Member

you're welcome to try. For general OSS contributing background see https://contribute.cncf.io/contributors/getting-started

@zacanger
Copy link
Contributor

zacanger commented Jan 14, 2024

I found this issue because I'm looking at customizing the theme. Two things that might be useful:

  • Allowing end-user theme config (merging with or overriding the default theme) from jaeger-ui.json
  • A hook to auto-set dark mode based on user preferences, something like:
  const [darkMode, setDark] = useState(false)
  useEffect(() => {
    const useDark = window.matchMedia('(prefers-color-scheme:dark)').matches
    setDark(useDark)
    return
  })

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants