Reputation: 85
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.
Upvotes: 2
Views: 2626
Reputation: 1920
The code given in the answer by Aravid Jaimon did produce incomplete results for me.
This is the solution I came up with for this purposes. It is mostly condensed from the ThemingDesigner.tsx source code:
import {
BaseSlots,
createTheme,
getColorFromString,
isDark,
IThemeRules,
ThemeGenerator,
themeRulesStandardCreator,
} from '@fluentui/react';
function generateTheme(
{
primaryColor, textColor, backgroundColor,
}: {
primaryColor: string, textColor: string, backgroundColor: string,
},
) {
const themeRules = themeRulesStandardCreator();
const colors = {
primaryColor: getColorFromString(primaryColor)!,
textColor: getColorFromString(textColor)!,
backgroundColor: getColorFromString(backgroundColor)!,
};
const isCustomization = false;
const overwriteCustomColor = true;
ThemeGenerator.setSlot(
themeRules[BaseSlots[BaseSlots.backgroundColor]],
colors.backgroundColor,
undefined,
isCustomization,
overwriteCustomColor,
);
const currentIsDark = isDark(themeRules[BaseSlots[BaseSlots.backgroundColor]].color!);
ThemeGenerator.setSlot(
themeRules[BaseSlots[BaseSlots.primaryColor]],
colors.primaryColor,
currentIsDark,
isCustomization,
overwriteCustomColor,
);
ThemeGenerator.setSlot(
themeRules[BaseSlots[BaseSlots.foregroundColor]],
colors.textColor,
currentIsDark,
isCustomization,
overwriteCustomColor,
);
// strip out the unnecessary shade slots from the final output theme
const abridgedTheme: IThemeRules = Object.entries(themeRules).reduce(
(acc, [ruleName, ruleValue]) => (
(
ruleName.indexOf('ColorShade') === -1
&& ruleName !== 'primaryColor'
&& ruleName !== 'backgroundColor'
&& ruleName !== 'foregroundColor'
&& ruleName.indexOf('body') === -1
)
? {
...acc,
[ruleName]: ruleValue,
}
: acc
),
{} as IThemeRules,
);
return createTheme({ palette: ThemeGenerator.getThemeAsJson(abridgedTheme) });
}
Upvotes: 1
Reputation: 85
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
Upvotes: 3