react-spectrum icon indicating copy to clipboard operation
react-spectrum copied to clipboard

Improve theming docs

Open vladinator1000 opened this issue 1 year ago • 4 comments

🙋 Documentation Request

Hey folks, I'm struggling to understand how to customize the themes. The docs say

React Spectrum is built to support theming.

But it's very hard to find information on how to practically change how things look. Like, for example how do I change the default styles of the inputs?

It seems like the theme you pass to the provider points to the classes and then you need to make sure the classes are present in your CSS, but what do you actually put in these classes to start meaningfully customizing Spectrum's appearance? For example I'm using emotion, but I'd recon you can do this with any styling solution.

// spectrum.ts
import { Theme } from '@react-types/provider'
import { darkTheme } from '@adobe/react-spectrum'

export const spectrumTheme: Theme = {
  ...darkTheme,
  global: {
    spectrum: 'spectrum-global',
// Should I put anything else here?
  },
}


const spectrumGlobalStyles: Style = (theme) => ({
  '.spectrum-global': {
    backgroundColor: theme.backgroundColors.primary,
    // Do I just shove all my overrides here?
    // Should I just manually comb through this file to find what I need? https://github.com/adobe/react-spectrum/blob/main/packages/%40adobe/spectrum-css-temp/vars/spectrum-dark.css
  },
})

My app that has a lot of existing styling already.

import React from 'react'
import { Global } from '@emotion/react'
import { Provider as SpectrumProvider } from '@adobe/react-spectrum';

import globalStyles from '../../style/globalStyles'
import { spectrumGlobalStyles, spectrumTheme } from "../../style/themes/spectrum";


const App: React.FC = () => {
  return (
    <SpectrumProvider theme={spectrumTheme} locale="en-GB">
        <Global styles={[globalStyles, spectrumGlobalStyles]} />

        <h1>Hello, world!</h1>
    </SpectrumProvider>
  )
}

export default App

I'd be down to make a PR if I figure out how to do it properly. Essentially, I'm trying to "normalize" spectrum so that its default styles behave with my styles.

vladinator1000 avatar Aug 01 '22 23:08 vladinator1000

Your hunch is correct, creating your own custom theme would require reproducing the set of variables/tokens that our Spectrum themes have and replacing the values with your own colors (e.g. you could set --spectrum-global-color-gray-800: red in your own css file and set that file as your 'light' theme object that your provide to our Provider). We don't recommend that users do so since many of the color and size choices were made with color contrast and mobile + desktop accessibility in mind.

Since you are building your own app that has its own styling in place, it may be easier to create the components with the aria/stately hooks instead so that you have full control over the styling yourself

LFDanLu avatar Aug 03 '22 21:08 LFDanLu

I'd like to overwrite the primary blue to be some other colour - but that seems to be far more complex than initially indicated by the homepage saying React Spectrum supports custom themes to match your brand. Applying @vladinator1000 approach with emotion somewhat works, but also gives me side effects e.g deleting all background colours.

I'd like to create some type of super set of the existing light and dark themes, only overriding one colour e.g "--spectrum-global-color-blue-400"

export const spectrumTheme: Theme = {
  ...defaultTheme,
  dark: {
    spectrum: 'spectrum-global',
    ...defaultTheme.dark
  },
  light: {
    spectrum: 'spectrum-global',
    ...defaultTheme.light
  },
}

export const spectrumGlobalStyles = (theme : any) => ({
  '.spectrum-global': {
    "--spectrum-global-color-blue-400": "rgb(255,0,0)"
  },
})

But this of course doesn't work because one completly overrides the other. Is there no other way than to copy all of the values into a new css-file? If there was a way to superset the existing dark and light themes, it would still be mostly maintained by the dependency, only with some changed values added on top.

image

Any input would be much appreciated.

greenpixels avatar Aug 31 '22 14:08 greenpixels

Hello, I also would like to have a solution for this...

DCubix avatar Sep 14 '22 12:09 DCubix

I'd like to just reiterate that the preferable approach would be to use the aria/stately hooks to recreate the components you need so that you can have full control over the styling. I understand this may represent a lot more work but the spectrum tokens themselves have actually gone through several breaking changes over time that would've broken the "overriding variable" approach. Additionally, IMO having a hybrid of our Spectrum styles and user defined overrides is a bit dangerous since any changes to the Spectrum Design color choices could invalidate/conflict with your own overrides.

LFDanLu avatar Sep 14 '22 18:09 LFDanLu

@LFDanLu if I understand you correctly, does that mean that my components will always have the blue-400 as the primary color, and if I want a button with a different primary color, I need to create a new one, reimplement all the logic using aria/stately? Something like <MyCustomGreenButton />? And all the other components will still be blue-400? How about increasing the default font-sizes and input-heights?

After struggling for some hours setting up Spectrum, I'm shocked that theming is ~NOT~ customizable at all, which is quite the opposite of what you can find in the homepage and in the docs.

hugomn avatar Oct 10 '22 02:10 hugomn