adobe / react-spectrum

A collection of libraries and tools that help you build adaptive, accessible, and robust user experiences.
https://react-spectrum.adobe.com
Apache License 2.0
12.22k stars 1.07k forks source link

Unexpected background-color in next.js setup #2151

Closed jkwchui closed 2 years ago

jkwchui commented 2 years ago

🐛 Bug Report

In a next.js setup of React Spectrum, where only the <Provider> and <SSRProvider> is wrapped around the app, no visual effect should be seen. However, a black (--spectrum-global-color-gray-100) background-color is applied over a <div> that occupies the height of the viewport. The height of this div funkily depends on the initial viewport height.

🤔 Expected Behavior

No visual change when only Provider/SSRProvider are wrapped, and should remain as:

😯 Current Behavior

A css class

._spectrum_eb688 {
    background-color: var(--spectrum-global-color-gray-100);
    -webkit-tap-highlight-color: rgba(0,0,0,0);
}

is applied to the inner <div> through a skin.css

  background-color: var(--spectrum-alias-background-color-default);

  /* Prevent tap highlights */
  -webkit-tap-highlight-color: rgba(0,0,0,0);
}

when none is expected.

🔦 Context

The unintended visual artifact makes it not possible to use react-spectrum in the project.

💻 Code Sample

// _app.js

import '@/css/tailwind.css'
import { ThemeProvider } from 'next-themes'
import {
  Provider,
  darkTheme, // whether darkTheme or defaultTheme was provided in <Provider> made no difference
  defaultTheme,
  SSRProvider
} from '@adobe/react-spectrum';

import Head from 'next/head'

import LayoutWrapper from '@/components/LayoutWrapper'

export default function App({ Component, pageProps }) {
  return (
    <SSRProvider>
      <Provider theme={defaultTheme} locale="en-US"> // <- offending line, which when commented out removed the visual artifact
      <ThemeProvider attribute="class"> 
          <Head>
            <meta content="width=device-width, initial-scale=1" name="viewport" />
          </Head>
          <LayoutWrapper>
            <Component {...pageProps} />
          </LayoutWrapper>
        </ThemeProvider>
      </Provider>
    </SSRProvider>
  )
}

FWIW this is the next.config.js:

// next.config.cs

const withPlugins = require('next-compose-plugins');
const withTM = require("next-transpile-modules")([
  "@adobe/react-spectrum",
  "@react-spectrum/actiongroup",
  "@react-spectrum/breadcrumbs",
  "@react-spectrum/button",
  "@react-spectrum/buttongroup",
  "@react-spectrum/checkbox",
  "@react-spectrum/combobox",
  "@react-spectrum/dialog",
  "@react-spectrum/divider",
  "@react-spectrum/form",
  "@react-spectrum/icon",
  "@react-spectrum/illustratedmessage",
  "@react-spectrum/image",
  "@react-spectrum/label",
  "@react-spectrum/layout",
  "@react-spectrum/link",
  "@react-spectrum/listbox",
  "@react-spectrum/menu",
  "@react-spectrum/meter",
  "@react-spectrum/numberfield",
  "@react-spectrum/overlays",
  "@react-spectrum/picker",
  "@react-spectrum/progress",
  "@react-spectrum/provider",
  "@react-spectrum/radio",
  "@react-spectrum/slider",
  "@react-spectrum/searchfield",
  "@react-spectrum/statuslight",
  "@react-spectrum/switch",
  "@react-spectrum/tabs",
  "@react-spectrum/text",
  "@react-spectrum/textfield",
  "@react-spectrum/theme-dark",
  "@react-spectrum/theme-default",
  "@react-spectrum/theme-light",
  "@react-spectrum/tooltip",
  "@react-spectrum/view",
  "@react-spectrum/well",
  "@spectrum-icons/ui",
  "@spectrum-icons/workflow"
]);

const withBundleAnalyzer = require('@next/bundle-analyzer')({
  enabled: process.env.ANALYZE === 'true',
})

module.exports = withPlugins([withBundleAnalyzer, withTM], 

[...]

🌍 Your Environment

Software Version(s)
react-spectrum 3.12.0
next.js 11.0.1
Browser Firefox, chrome, safari
Operating System MacOS
devongovett commented 2 years ago

The Provider component includes a background corresponding to the theme you've provided. In this case, it looks like dark mode is active so you are seeing a dark gray background.

I suspect the CSS for spectrum is conflicting with Tailwind CSS in some way as well.

jkwchui commented 2 years ago

Thanks @devongovett for pointing out that this is by design. Is there a way to override the behaviour? I'm hoping to incrementally adopt Spectrum.

devongovett commented 2 years ago

Provider has an UNSAFE_className prop. You could use that to override the background color potentially.

jkwchui commented 2 years ago

Oh I didn't see that. Thank you very much; I've slapped on a dirty fix while swapping out Tailwind.

<!-- in _app.js -->
<Provider theme={darkTheme} locale="en-US" UNSAFE_className="dark:bg-gray-900">
deadcoder0904 commented 2 years ago

i'm facing this same issue & my font-size has also been reduced & different font is used just bcz i wrapped it in SSRProvider & Provider. i don't want all of that to change at all. how do i do it?

also, is there any way to use it without having to wrap it in SSRProvider & Provider or is it necessary with Next.js? my sentiment is like this comment right now?

snowystinger commented 2 years ago

From one of your other comments, I gather you are not using React Spectrum, but are instead using React-Aria to create your own components?

React Spectrum itself isn't meant to be super approachable with theming, not yet anyways. It's meant to enforce our design system. The hooks are there for you to make your own, giving you full control of all rendering. We have plans to eventually make the variable theming easier, but it's a low priority. For now, they are meant for making small changes when React Spectrum is already very close to what you want.

SSRProvider is necessary and will continue to be necessary because it makes ID's predictable across SSR and hydration. It'll be needed until we can take advantage of React 18's useId.

If you're only using our hooks to make your own components, I don't think you need the Provider though. I could be wrong on that, but the order of dependencies is stately->aria->react-spectrum. Nothing can go the other direction, so no aria package should depend on react-spectrum.

deadcoder0904 commented 2 years ago

From one of your other comments, I gather you are not using React Spectrum, but are instead using React-Aria to create your own components?

i was still using spectrum, my mistake. i switched to aria to use my own combobox using tailwind like this example

removed Provider & kept SSRProvider & it worked fine, thanks :)