Match theme of Dynamics 365 App in Power Apps Control Framework – Part 2

By | October 30, 2020

In the last blog, we saw how we could match the theme of the Dynamics 365 App in PCF when we know what should be the color scheme at the time of designing.

In this blog, we will see how we can apply the theme to the Fluent UI component dynamically based on the main color set in the Dynamics 365 App Theme record.

Retrieve theme record

To know what the main color is set in the theme record, we would need to retrieve the theme record first. Use webApi.retrieveMultipleRecords method in the updateView method of the PCF and on success, render the react component. Pass the object of the theme record to the root main component.

public updateView(context: ComponentFramework.Context<IInputs>): void {

//retrieve theme

let options = “?$filter=isdefaulttheme eq true”;

this._context.webAPI.retrieveMultipleRecords(“theme”, options).then((result) => {

this._themeRecord = result.entities[0];

// Add code to update control view

ReactDOM.render(

React.createElement(App, { context: this._context, themeRecord: this._themeRecord }), this._container);

}, (error) => {

});

This theme records contains the maincolor value.

Match theme of Dynamics 365 App in Power Apps Control Framework – Part 2

Generate Fluent UI Palette color slots

We now have maincolor but do not have the palette color slots. We want different shades of the main color, which we saw, in our previous blog; we copied the color slots from Fluent UI Theme designer.
To generate color slots programmatically, we would need to use ThemeGenerator Class.  I have created a ThemeProvider.ts as a separate file with the below code.

import { loadTheme } from ‘@uifabric/styling’;

import {

IThemeRules,

ThemeGenerator,

themeRulesStandardCreator,

} from ‘office-ui-fabric-react/lib/ThemeGenerator’;

import { getColorFromString } from ‘office-ui-fabric-react/lib/utilities/color/getColorFromString’;

import { IColor } from ‘office-ui-fabric-react/lib/utilities/color/interfaces’;

 

export default class ThemeProvider {

private themeRules: IThemeRules;

constructor() {

const themeRules = themeRulesStandardCreator();

ThemeGenerator.insureSlots(this.themeRules, false);

ThemeGenerator.setSlot(themeRules.backgroundColor, getColorFromString(‘#ffffff’) || “”, false, true, true);

ThemeGenerator.setSlot(themeRules.foregroundColor, getColorFromString(‘#000000’) || “”, false, true, true);

this.themeRules = themeRules;

}

public loadThemeForColor(hexColor: string): void {

let col: IColor = { str: “#0078D4”, r: 0, g: 120, b: 212, hex: “0078d4”, h: 0, s: 0, v: 0 };

const newColor: IColor = getColorFromString(hexColor) || col;

 

const themeRules = this.themeRules;

ThemeGenerator.setSlot(themeRules.primaryColor, newColor.str || “”, false, true, true);

this.themeRules = themeRules;

const theme = ThemeGenerator.getThemeAsJson(this.themeRules);

loadTheme({

…{ palette: theme },

isInverted: false,

});

}

}

This ThemeProvider.ts has “loadThemeForColor” method, which accepts the color string and then generates theme and loads it.

Load theme in the root component

Import the above-created “ThemeProvider” class in the main root component and then call “loadThemeForColor” method by passing the maincolor that we have retrieved from the Dynamics 365 Theme record. The theme loaded in the root component will get applied to all the child components.

import ThemeProvider from “../ThemeProvider”

Match theme of Dynamics 365 App in Power Apps Control Framework – Part 2

Call “loadThemeForColor” method before any app code. Here I have called this function in the root component’s constructor.

    constructor(props: AppProps) {

super(props);

//get main theme color

let mainColor = props.themeRecord[“maincolor”];

 

let themeProvider = new ThemeProvider();

themeProvider.loadThemeForColor(mainColor);

}

Match theme of Dynamics 365 App in Power Apps Control Framework – Part 2

This way we can dynamically set the theme for the Fluent UI components.

Test the app

Deploy the control to Dynamics 365 environment, change the default theme main color, and publish.

Match theme of Dynamics 365 App in Power Apps Control Framework – Part 2

Our component will read this main color form the theme record and will apply the generated theme.

Match theme of Dynamics 365 App in Power Apps Control Framework – Part 2
In some cases, you may require to modify individual components style. As mentioned in the previous blog, we can modify individual component style using https://github.com/microsoft/fluentui/wiki/Component-Styling

Conclusion

We can apply the theme to the Fluent UI component dynamically based on the main color set in the Dynamics 365 App Theme record.