Theming in Canvas Apps

In this post, I’ll show you how to make branding your controls 10x easier after one step of creating custom theming in your app, where you’re then after able to brand all your controls by changing code in one place or by doing things… READ MORE [https://lewisdoes.dev/blog/theming-in-canvas-apps]
multicolored paint drippings
Photo by Alexander Grey on Pexels.com
In: Low Code Lewis Content 🚀

In this post, I’ll show you how to make branding your controls 10x easier after one step of creating custom theming in your app, where you’re then after able to brand all your controls by changing code in one place or by doing things like ‘selecting another theme’!

Creating the theme

So to create our themes, we could do this in our App OnStart property. You could alternatively do this in a timer’s OnTimerStart property and using the OnTimerEnd property use the Navigate() function to navigate to your intended homescreen. This way if your app doesn’t load your themes in time, which could well be the case, you’ve created time for this where it loads your themes and you don’t get any flicker between controls looking odd and them being rendered as they should be. I’d definitely recommend doing this if you’re going to take this to the next level and store your users preferences in a data table so that you can do a LookUp() on the record their marked against and then reflect their preferences in your app when they come back to it.

Anyway… moving onto creating our theme. Some people like to use collections to do this, I’m going to use global variables and records, because I find it easier to then use variables and the dot notation to access my theme values.

In my timer OnTimerStart property, I’m going to set a global variable with a record holding all the colours I’ll want to use in my theme.

// Theme settings - Colours
Set(
    gblColours,
    {
        DarkBlue: ColorValue("#1c2d47"),
        MidBlue: ColorValue("#0066AF"),
        LightBlue: ColorValue("#41B6EB"),
        DarkGrey: ColorValue("#4D5054"),
        MidGrey: ColorValue("#B1B3B3"),
        DarkYellow: ColorValue("#F7A800"),
        Green: ColorValue("#99BD12"),
        Purple: ColorValue("#9D1D96"),
        Turquoise: ColorValue("#71DBD4"),
        Orange: ColorValue("#F26703"),
        Teal: ColorValue("#005E62"),
        TransparentWhite: RGBA(
            255,
            255,
            255,
            0.5
        ),
        White: White
    }
);

Here you can see I’ve set the global variable ‘gblColours’ with a record that has a field for each colour I want to store. Then the value I’m storing against each field is the hex value of the colour I want to use inside the ColorValue() function.

Now I’ve built out the colours I’m going to use, I can build out my theme in a similar way. I’m going to set a global variable with a record that has a number of nested records for each of the controls I’ll theme in my app! This is a short snippet of something I might use in a theme like situation…

Set(
    gblTheme,
    {
            TitleLabel: {
                Weight: Bold,
                Size: 12,
                Colour: varColours.White
            },
            Text: {
                Weight: Normal,
                Size: 12,
                Colour: varColours.White
            },
            Form: {
                RequiredMarker: {Colour: varColours.Orange},
                Label: {
                     Size: 12,
                     Height: 22,
                     Weight: Bold,
                     Colour: varColours.DarkBlue
                },
                Field: {Outline: varColours.LightBlue}
            }
   }
)

Now I’ve set the variable gblTheme with this data. All I need to do is head to the controls I want to style and instead of using hard coded values, reference the values in my variable.

For example, if I want to style a TitleLabel. I’ll take the label control I want to use and instead of using ’12’ in the Font Size property, I’ll use…

gblTheme.TitleLabel.Size

Now I can continue to use this same idea with all of my other controls, referencing the records and values in my gblTheme variable to style them.

Now if I ever need to change my theme I can do this by changing the code in one place and not needing to worry about changing every control.

Multiple Themes

But hold on… what if I want multiple themes… that’s easy! All I need to do is use another variable and an Switch() statement to determine how my controls get themed.

I’ll create a settings screen in my app with a dropdown that lets me change my theme. Using that dropdown I’ll use the OnChange property to set a global variable with the choice I selected. Let’s say I chose “Light Mode” in my dropdown and now I’ve set the variable gblChosenTheme to “Light Mode”.

Now in my timer OnTimerStart property I’ll use an If() statement and say…

Switch(gblChosenTheme, "Light Mode", Set(gblTheme, {the appropriate theme JSON},"Dark Mode",Set(gblTheme,{the appropriate theme JSON}, "Monochrome", Set(gblTheme,{the appropriate theme JSON},Set(gblTheme,{the appropriate theme JSON for light mode})

In this Switch() function, I’m saying that if the chosen theme is equal to light mode, I’ll set my gblTheme variable to the correct styling for a light theme. Then I’m saying if it’s equal to dark mode, I’ll set my gblTheme variable to the correct styling for a dark theme, and then I’m saying that if it’s equal to monochrome I’ll set gblTheme with the correct styling for a monochrome theme. Now my controls are being styled based on the theme I’ve chosen, and I’m also using a backup of light mode in case one of the values “Light Mode”, “Dark Mode”, or “Monochrome” isn’t matched in my Switch().

User Preferences

This is an important step with the way I’ve implemented this here, but will also add some extra functionality. In your screen where you’re setting your theme, using the OnChange property of the dropdown, we’ll want to do a LookUp() on a table where we can store theme values. All we need to store is a string of the person’s email and a string of the value chosen for theme.

We’ll create a new record using Patch() and set the theme to “Light Mode” at the start of our timer OnTimerStart if there isn’t already a record found using LookUp() in our OnTimerStart.

Now using our OnChange of our dropdown on our screen to change the theme, we’ll patch that record and do a lookup against the users email using User().Email to pass the data in, to change the theme in that record to the one they’ve chosen.

Now back to our timer’s OnTimerStart when we launch our app, in here when we do a LookUp() on our user preferences table, if in fact we do find a record, we won’t create another one now, but we’ll take the value in the theme field and set our variable gblChosenTheme with this value.

Now further down in our syntax, we’re setting gblTheme in our Switch() using the chosen theme in gblChosenTheme.

Here we end up with functionality where our user can set the theme in their app and have it remembered for when they return 🙂

Written by
Lewis Baybutt
Microsoft Business Applications MVP • Power Platform Consultant • Blogger • Community Contributor • #CommunityRocks • #SharingIsCaring
Comments
Great! You’ve successfully signed up.
Welcome back! You've successfully signed in.
You've successfully subscribed to LewisDoesDev.
Your link has expired.
Success! Check your email for magic link to sign-in.
Success! Your billing info has been updated.
Your billing was not updated.