Cory Crowley
Cory Crowley

Reputation: 324

Fluent UI React - how to apply global component styles with Fluent ThemeProvider

I'm working with the theming code below. I'm able to apply a global Fluent theme with the ThemeProvider and createTheme utility, but when I add component specific themes, I'm not getting any typings, which makes theming very difficult.

So my question is: how do I apply global component-specific styles using Fluent ThemeProvider with strong typing.

If, for example, I wanted to add a box shadow to all Fluent PrimaryButtons, I wouldn't know what properties to access on the components key passed into createTheme.

If you've done any global component theming, please let me know what pattern you used and if I'm on the right track, thanks!

import { createTheme } from '@fluentui/react';
import { PartialTheme } from '@fluentui/react-theme-provider';

// Trying to add global component styles (not getting typings)
const customComponentStyles = {
    PrimaryButton: {
        styles: {
            root: {
                background: 'red'
            }
        }
    }
};

export const fluentLightTheme: PartialTheme = createTheme({
    components: customComponentStyles, // Want to apply component styles
    palette: {
        themePrimary: '#0078d4',
        themeLighterAlt: '#eff6fc',
        themeLighter: '#deecf9',
        themeLight: '#c7e0f4',
        themeTertiary: '#71afe5',
        themeSecondary: '#2b88d8',
        themeDarkAlt: '#106ebe',
        themeDark: '#005a9e',
        themeDarker: '#004578',
        neutralLighterAlt: '#faf9f8',
        neutralLighter: '#f3f2f1',
        neutralLight: '#edebe9',
        neutralQuaternaryAlt: '#e1dfdd',
        neutralQuaternary: '#d0d0d0',
        neutralTertiaryAlt: '#c8c6c4',
        neutralTertiary: '#a19f9d',
        neutralSecondary: '#605e5c',
        neutralPrimaryAlt: '#3b3a39',
        neutralPrimary: '#323130',
        neutralDark: '#201f1e',
        black: '#000000',
        white: '#ffffff'
    }
});

Upvotes: 3

Views: 3143

Answers (1)

alex3683
alex3683

Reputation: 1565

The problem here is, that components is just a Record<string, ComponentStyles>, where ComponentStyles then just is a quite unspecific object of the form { styles?: IStyleFunctionOrObject<any, any>}. They would have to add an entry for every possible I<Component>Styles interface to ComponentsStyles, which I guess would be too much work and errorprone (e.g. forgetting to add a new component here ...).

Since all the I<Component>Styles interfaces are exported by Fluent, I always define the styles for each component separately and than merge them in the components object:

const buttonStyles: IButtonStyles = {
  root: {
    backgroundColor: 'red'
  }
};

export const fluentLightTheme: PartialTheme = createTheme({
    components: { PrimaryButton: { styles: buttonStyles } },
});

Here is a codepen example I created by using one of Fluent UIs basic Button examples: https://codepen.io/alex3683/pen/WNjmdWo

Upvotes: 2

Related Questions