Search code examples
reactjsoffice-ui-fabricfluent-uifluentui-react

How to generate a Fluent UI theme with in the library?


I was creating a react application with Fluent UI - React, I want something like each user can pick a Primary Color, Text Color, and Background Color when they sign up and their app will be in that theme like the same way done in the Theming Designer

The theming designer gives me the following output.

const appTheme: PartialTheme = createTheme({
  palette: {
    themePrimary: "#ff5460",
    themeLighterAlt: "#0a0304",
    themeLighter: "#290d0f",
    themeLight: "#4d191d",
    themeTertiary: "#993239",
    themeSecondary: "#e04a54",
    themeDarkAlt: "#ff656f",
    themeDark: "#ff7d86",
    themeDarker: "#ff9fa6",
    neutralLighterAlt: "#000000",
    neutralLighter: "#000000",
    neutralLight: "#000000",
    neutralQuaternaryAlt: "#000000",
    neutralQuaternary: "#000000",
    neutralTertiaryAlt: "#000000",
    neutralTertiary: "#c8c8c8",
    neutralSecondary: "#d0d0d0",
    neutralPrimaryAlt: "#dadada",
    neutralPrimary: "#ffffff",
    neutralDark: "#f4f4f4",
    black: "#f8f8f8",
    white: "#000000",
  },
});

Is there a function that generates theme in Fluent UI in which I just want to provide Primary Color, Text Color, and Background Color and it gives the entire theme so that I can add it to the Theme Provider component.


Solution

  • Resolved it by creating a function,

    import {
      BaseSlots,
      createTheme,
      getColorFromString,
      isDark,
      Theme,
      ThemeGenerator,
      themeRulesStandardCreator,
    } from "@fluentui/react";
    
    const generateTheme = (
      primaryColor: string,
      textColor: string,
      backgroundColor: string
    ): Theme => {
      const themeRules = themeRulesStandardCreator();
      const colors = {
        pColor: getColorFromString(primaryColor)!,
        tColor: getColorFromString(textColor)!,
        bColor: getColorFromString(backgroundColor)!,
      };
    
      const currentIsDark = isDark(
        themeRules[BaseSlots[BaseSlots.backgroundColor]].color!
      );
    
      ThemeGenerator.insureSlots(themeRules, currentIsDark);
      ThemeGenerator.setSlot(
        themeRules[BaseSlots[BaseSlots.primaryColor]],
        colors.pColor,
        currentIsDark,
        true,
        true
      );
      ThemeGenerator.setSlot(
        themeRules[BaseSlots[BaseSlots.foregroundColor]],
        colors.tColor,
        currentIsDark,
        true,
        true
      );
      ThemeGenerator.setSlot(
        themeRules[BaseSlots[BaseSlots.backgroundColor]],
        colors.bColor,
        currentIsDark,
        true,
        true
      );
    
      const themeAsJson: {
        [key: string]: string;
      } = ThemeGenerator.getThemeAsJson(themeRules);
    
      const finalTheme = createTheme({
        ...{ palette: themeAsJson },
        isInverted: currentIsDark,
      });
    
      return finalTheme;
    };
    
    export default generateTheme;
    

    Actually, this must be part of Fluent UI