iTwin/iTwinUI-react

ThemeProvider removes background color from body

Closed this issue · 6 comments

Describe the bug (actual behavior)

When ThemeProvider is used in from react SPA, body will loose 'iui-root' class

Expected behavior

React rendered website still contains background

Reproduction

https://codesandbox.io/s/itwinui-react-example-forked-ohl4nl?file=/src/index.tsx

Steps to reproduce
  1. Render SPA react app
  2. Use ThemeProvider
  3. Background gone

image

It is not "removing" the body background so much as never adding it. There are two things going on here:

  1. <ThemeProvider> is what is being rendered, so if you don't render it in place of <body> then it has no reason to touch <body>.
  2. Our css intentionally doesn't set a background on iui-root if it is not used on <body>. This is because you might want to created scoped roots that only toggle the theme without any side effects.

Are you able to use the <html> element as the react root and render

ReactDOMClient.createRoot(document.documentElement).render(
  <React.StrictMode>
    <ThemeProvider theme='dark' as='body'>
      <App />
    </ThemeProvider>
  </React.StrictMode>
)

@mayank99 It does not make sense.
If you just use iTwinUI components (do not use ThemeProvider), the styles ARE set on body and everything works fine.
Now if you use ThemeProvider in your app, then those are NOT set. It is not obvious behavior and I do not think its explainable.
And default setup of Vite, CRA, etc is index.html and all the setup there. So now just to make theming of iTwinUI work, you need to change all of these things.

Maybe we can add a prop that sets the background if ThemeProvider is used as a child of body?

I think there is just 2 different cases.
One is literally managing the theme of the app (usual case and in v1 using useTheme was really comfortable and nice, IMO). So this one should be simple and should not need some advanced configuration.
And rarer case (at least currently) is scoping themes.

So with v2, 2nd one is really nice, API is super and comfortable. But now the 1st one is not that obvious and more complex :/

Usually SPA react app is rendered on a <div id=root>
So it won't always be a child of body.

I think it would make sense if ThemeProvider had prop called "applyBackground" or something similar. That would set the background-color css on the div or whatever the underlying element is.

@Woyken Forgot to reply here but this is now fixed/added in 2.1.0. It should work as expected right out of the box, and you can also override the default behavior by passing themeOptions.applyBackground. See the PR description in #974 for more details.