cancel
Showing results for 
Search instead for 
Did you mean: 
wyotim

Creating a dynamic color scheme system with optional user personalization

Intro
In this blog post we will explore a method for color control that not only aims to make app creation and color maintenance simpler but can also be easily extended to give users personalization options.

 

We will start by setting up a basic color scheme data structure, use collections to pull that data into an app and reference them to color components, and lastly enable users to personalize a color selection that will persist between app sessions on a device.


One note on the reasoning and benefits of this approach: what this method allows is essentially a “server-side” approach to the coloring of apps. If any color schemes need to be changed, be it through rebranding or to simply put on a fresh coat of paint, it becomes a trivial task as any changes can be populated to the app easily. And this applies for any and all apps that use this method. Pretty cool, right? Right!


Also, it means that applying those color schemes to apps in the development stage is also super easy, barely an inconvenience. The app developer would not need to reference any color code cheat sheet or color code at all. The colorizing of the app is dynamic and able to be adjusted on the fly. Furthermore, cutting and pasting app elements and even components (yes, this method works in components!) results in those items immediately being the right color. Or, at worst, requiring a very minor code change to bring them in line with where they are being placed the existing app.


Let’s get cracking!

 

Data Structure
The example color scheme I am using is loosely based on the Material Design color system, primarily because it is simple in premise and easy to implement. As someone without a background in design or visual arts of any kind, simple has been a good place for me to start. Of course, nearly any color scheme could be used, and this method adapted accordingly. The main color components in this example are as follows:

 

  • PrimaryColor - the main app color used
  • PrimaryAltColor - a variant of the primary color, used for hover colors, subheadings, etc.
  • OnPrimaryColor – used for text and icons that are “on” the primary colors
  • SecondaryColor – color used as a contrast to the primary color, such as buttons, links, progress bars, etc.
  • SecondaryAltColor - a variant of the secondary color, used for hover colors on buttons, links, etc.
  • OnSecondaryColor – used for text and icons that are “on” the secondary colors
  • BackgroundColor – used for the app background and gallery fill colors
  • OnBackgroundColor - used for text and icons that are “on” the background colors
  • SurfaceColor – used for surfaces of components, like gallery template fill
  • OnSurfaceColor - used for text and icons that are “on” the surface colors


Each of these items will store a text color code in hexadecimal format (“#FFFFFF”, for example). In addition to these fields, our table will also have a primary key and a Name field. One could also add other fields for filtering and sorting color schemes as needed, but for this example we will keep it basic. There is an Excel spreadsheet with some examples of this color scheme attached below, containing some Power Platform-inspired color schemes among a few other example themes. Please note that my code examples are for SQL but could work for SharePoint, Excel, etc.


Once the data structure has been created, it needs to be filled with data. If your company already has a style guide or branding guidelines, this step is straightforward for the most part. But what if you are developing for a company or department that has no official branding guidelines? In that case, feel free to visit the following abbreviated list of websites for assistance in finding/creating color schemes:

 

 

Side note: I happen to work for a small company with no real branding guidelines of any kind and I am getting the opportunity to expand my horizons in learning more about the design arena. As such, I am happy to get feedback from those with more experience or discuss this topic with others who are in a similar position to myself. It is an important area that citizen developers may not have any reference point for, so let’s help each other out and start having those conversations!

 

Code Structure
The code structure has two basic parts:

 

  1. Gathering/storing the color table, and
  2. Defining the colors for each component within the app.

Furthermore, we will look at two different scenarios for Step 1: Having multiple color schemes in an app or having a single color scheme.


Step 1, Scenario A - Multiple color schemes
While the data gathering process depends on a few factors, the general method would be to pull either the whole theme table or whatever subset you need for your app into a collection. If you are pulling in the entire color scheme table (or more than one row of that table), you would also need to create a collection to hold the currently selected theme, as well as an initial value for when the app is first launched. This selected theme collection will be stored using the SaveData function so that the next time the user opens the app their theme will persist. We’ll touch more on this topic later in the User Personalization section.

 

/* ClearCollect the color scheme table; Collect could be used for OnStart */
ClearCollect(
    colAppColorScheme,
    '[dbo].[AppColorScheme]' // Your color scheme table goes here!
);
/* Load saved color scheme; Collect initial color scheme if no selected color scheme exisits */
LoadData(
    colCurrentColorScheme, 
    "CurrentColorScheme", 
    true
);
If(
    IsEmpty(colCurrentColorScheme),
    Collect(
        colCurrentColorScheme,
        Filter(
            colAppColorScheme, 
            ID = 1 // or whatever criteria you need to use to filter your initial color scheme
        )
    );
    SaveData(
        colCurrentColorScheme, 
        "CurrentColorScheme"
    )
)

 

Step 1, Scenario B - A single color scheme
If one theme is all you want, you would simply bypass the initial collection step and filter for the theme you want. When taking this route, I would recommend naming the single collection the same as you would a user-selected theme collection. That way, if you decide you want to expand the color themes and allow user selection the conversion will be much simpler as code could be reused.

 

Also, for apps that are used online or in Teams, the single theme approach would be best as SaveData/LoadData won’t work and the user would have to re-select their theme every time they opened the app. (Of course, their selection could be stored in another table and recalled when the app opens to bypass this limitation, but this is about simplifying our approach, yes?)

 

/* ClearCollect of the single color scheme to be used in the app; Collect could be used for OnStart */
ClearCollect(
    colCurrentColorScheme, 
    Filter(
        '[dbo].[AppColorScheme]', // Your color scheme table goes here!
        ID = 1 // or whatever criteria you need to use to filter your color scheme 
    ) 
)

 

Step 2
To define the colors for each element, we are going to use the ColorValue function and the naming convention we established earlier. The code is simple:

 

/* To reference the Primary color, use this code */
ColorValue(
    First(
        colCurrentColorScheme
    ).PrimaryColor // change this part for the color you desire to use, i.e. SecondaryAltColor, OnSurfaceColor, etc.
)


Putting this code in the applicable color property field in each item is the key that makes this method work. That said, you may find that some additional effort may be required as you try multiple color schemes in the same app. Truly, not every color combination will look equally pleasing in every app, especially when it comes to phone apps versus tablet apps. Pre-planning as well as a standardized styling approach can help a lot. Refactoring an existing app can be difficult.


A tip on this method: having a set of preconfigured controls available to copy and paste is very helpful. That way setting up combo boxes, labels, icons/shapes, etc. can be much easier. Galleries and forms are the major exception here. They must be set up individually, item by item, which is super tedious.

 

And, wouldn’t you know it but I have attached an app below that has nearly every control, icon, shape, and text type pre-configured for using this method. I originally made this app for my own use to copy and paste items into apps to save some time. Hopefully it will do the same for you! (Note: one of the icons has a method built in to take hexadecimal color formats and convert them into RGBA color formats, giving transparency control over hex colors! I’ll leave it to you, dear reader, to discover that item for yourself, though I left an obvious clue for finding it in the app.)


*edit* Wouldn't you also know it but icons have been updated. It is now much easier to resuse an exisiting, colored icon with a simple copy paste as the icon itself is now a property! Great work PowerApps team!

User Personalization
The following code will take the selected color scheme data, ClearCollect it to our current color scheme collection, and use SaveData to store that selection on the device. This code would be placed in the OnChange or OnSelect field, depending on the control used to show the color schemes available to the user.

 

/* Replace the previously selected color scheme and save that choice */
ClearCollect(
    colCurrentColorScheme, 
    drpColorSchemeSelector.Selected // or whatever control is being used to select the color scheme
);
SaveData( colCurrentColorScheme, "CurrentColorScheme" )


We would also need to be sure to add a LoadData expression to pull in the saved data during our initial loading sequence, be that in the OnStart section or in the OnVisible section of a loading screen if you use that methodology. This was included in the first code example in the Code Structure section, so if that code was used everything is good to go!

 

In the aforementioned example app, I used a simple combo box to enable personalization control, which is one approach to this. Another way would be as follows:

 

  1. Create a mockup of an app screen in a gallery
  2. Make the color scheme table the data source for the gallery
  3. Use the color definition code from above to color it.

This makes a great looking way for users to visualize the color scheme before applying it. If you are interested in seeing this method, drop a comment or shoot me a message and I will make an example app up.

 

App challenge: Or better yet, build one yourself and show off your great work by commenting or sending me a message with a screen shot!

 

Wrap-up
So to recap, we have defined a basic color scheme structure, put that data in an app and used some simple code to reference the various color components of our app, and made a way for users to choose what color scheme they want with that choice being saved to their device.


This is but one way of accomplishing this task, so if you have a favorite approach please feel free to share it! And as I mentioned before, it seems to me that there is room for more conversation regarding design and UI/UX for citizen developers of varying experience and ability levels. As a beginner myself, I would love to take part in these conversations.


At any rate, I hope you have enjoyed this walk-through of how to create a dynamic and simple color scheme structure for your apps. Happy PowerApping!

Comments

Hi there, I like the concept and great work with the sample App.  Just wanted to know why you went for hex codes.  I was looking at doing something similar using RGBA to allow for transparency settings in the theme. 

Just curious ....
Andre

@AndreSchlender That is a great question! The primary reason I went with hex colors was that I couldn't find a better way than storing each part of the RGB color as it's own integer, which meant storing three columns of data for each color instead of one. That made the ten color fields grow up to thirty, and also made the reference code more complex as there would be three references per color. Also, I work primarily in SQL and I didn't (and still don't!) know if SharePoint or CDS have a Color data type that would make it easy to work with RGB colors in Power Apps. As such, I was trying to make the simplest data design and implementation possible for anyone who wanted to do something like this.

Since that time, I have found hex colors to be very easy to use for multiple situations that I hadn't thought of back then. A big one for me is for implementing SVG graphics in my color system. Because the hex code is stored as text and SVG graphics are text as well, I can use a simple Substitute function to easily tie that graphic in. It made it super easy to add custom icons to reference tables and make my apps look much more appealing to my users with very little work on my part. If there was a Color data type that stored RGB colors, they would have to be converted to Text to be used in the same way, which might not be difficult but would be another step to take.

 

Two things on the transparency issue: I actually wrote an inline converter to make transparency possibly on one of the icons in that app. It's the Items icon and it has the text "Check this one out..." beside it (in the middle row on the far right side). It was a pretty rough method and I have since found more elegant ways to do the same, but it works! 

The second thing is that not long after I published this, the ability to add the alpha (transparency) channel to hex colors was added, so you can now add transparency to those color types! Here is some documentation that talks about that, right at the top. It's as simple as adding a small amount of text. Here is an example of a 50% transparency on the primary color from my method: 

ColorValue(
    First(
        colCurrentColorScheme
    ).PrimaryColor & "80"
)

Probably the toughest aspect is having to convert from a base 10 number to a base 16 one. Personally, I use the same few transparency levels all the time so I have come to memorize the common ones, like 99 is 60% for instance. You could also use a little math and the Adobe Color Wheel website to do the same (take 255 * the percentage of transparency you desire, put that into one of the RGB fields on the Adobe Color Wheel website, then note the resulting hex code).

 

Let me know it that answers your question adequately. Also, if you have found a great way to store RGB colors, feel free to share! I would love to see it!

 

Thanks for the great question!

Thanks for getting back so quickly and for the detailed answer. All your points make perfect sense. I need to start looking as SVG as well soon so using hex in that scenario will be a lot easier.
I saw the "converter" you put in as an example. Just seemed to be a bit too much overhead to do with a lot of properties.  Also thank you for reminding me of the Hex transparency option. I had seen that before but it did slip my mind.  That will probably work for me at this point. 
For your information there is no "color" data type in SharePoint, so trying to do something using RGBA would increase the complexity quickly if you start adding columns to the data structure.

Appreciate the resource you provided here.

Nicely done, I'm working on building out a dark theme.  Main hurdle boils down to achieving the elevation effect in PowerApps, which is not impossible.

@brendon-colburn Thank you! Not to be overly self-promoting, but if you are looking for a way to do drop shadows in Power Apps, feel free to check out this blog post. It covers one way to do it using HTML text boxes, among some other things that can be done. Feel free to hit me up if I can clarify anything with that post.

 

You can also do this using SVGs and Image controls. @R3dKap has a component sample that shows a way to do this.