Jimu classes not updating color when theme changes

1435
4
Jump to solution
03-30-2017 08:14 AM
by Anonymous User
Not applicable

I am using the CSS Framework in a custom widget and I am finding that when I change the color of my foldable theme, it does not update the colors in the jimu classes (.jimu-panel-title, jimu-btn, etc.).  I guess I was under the impression that by conforming to the jimu css, it would create "visual consistency" across the app.  In my case, I have just changed the theme style color to green, and only the widget title (of .title-label class) is updated with the new color:

Obviously, this can be fixed with simply overriding the jimu classes in my widget to match the color I chose in the theme:

However, this is not a good solution as it is essentially hard coded into the widget and a client will not understand why the widget colors aren't changing with the theme.  Is there a special trick I'm missing to make this work?  Before overriding the colors in my css for the widget, I am only setting up some minor css for the various elements to use flex boxes so everything is aligned nicely, not doing anything with modifying the jimu classes.

I am using WAB Developer Edition 2.3.

I did see this disclaimer on the css frameworks page mentioned above:

Note:

You may notice that these CSS classes have not yet applied to all of the widgets and themes in this release. Code refactoring will continue in the coming releases.

Does this mean it does not work with any of the themes yet?  I am using the basic foldable theme, so I would think that if any, it would work with this one.  Are there any themes that the jimu css framework will currently work with as of version 2.3?

1 Solution

Accepted Solutions
RobertScheitlin__GISP
MVP Emeritus

Caleb,

   The themes color is as you see only applied to the widget titlebar and header controller widget and such. You will notice that on screen widget placeholders and Zoom control buttons, etc are not using the theme color either. There is just no css rules in place to make those other components use the theme color yet. I setup css rules in my widgets to handle the matching of the theme color to components in my widget UI. I am not sure the dev team has any plans to make all widget components take on the theme color, but for now you are not missing something simple, you just jsut need to add css rules to your widgets.

View solution in original post

4 Replies
RobertScheitlin__GISP
MVP Emeritus

Caleb,

   The themes color is as you see only applied to the widget titlebar and header controller widget and such. You will notice that on screen widget placeholders and Zoom control buttons, etc are not using the theme color either. There is just no css rules in place to make those other components use the theme color yet. I setup css rules in my widgets to handle the matching of the theme color to components in my widget UI. I am not sure the dev team has any plans to make all widget components take on the theme color, but for now you are not missing something simple, you just jsut need to add css rules to your widgets.

by Anonymous User
Not applicable

Ok, so I took your advice and added a method within my widget to match the current theme.  It is pretty sloppy and could probably be handled much better, but this is what I came up with (I use jquery in most of my widgets):

      _matchTheme: function(){
        // update css properties to match theme color
        var selectors = this.config.widgetThemeSelectors.join(', ');
        var bg_color = $('div.jimu-widget-header-controller').css('background-color');
        var widgetSelector = $('div.' + this.config.rootHtmlClass);
        widgetSelector.parent().find(selectors).css('background-color', bg_color);
        // set color for hover to have 70% opacity
        var rgb_vals;
        if (bg_color.startsWith('rgb(')){
          rgb_vals = bg_color.split('(')[1].split(')')[0].split(',');
          rgb_vals.push('0.7');
        } else if (bg_color.startsWith('rgba(')){
          rgb_vals = bg_color.split('(')[1].split(')')[0].split(',');
          rgb_vals[3] = '0.7';
        }
        if (rgb_vals){
          widgetSelector.find('.jimu-btn').hover(function(){
            $(this).css('background-color', 'rgba(' + rgb_vals.join(',') + ')');
          }, function(){
            $(this).css('background-color', bg_color);
          });
        }
      },

I wanted to make the selectors to stylize configurable, so those are properties that get set within the configuration file, in the case of this widget, this part of the config looks like this:

{  
  "rootHtmlClass": "rental-density",
  "widgetThemeSelectors": [
    ".jimu-panel-title",
    ".jimu-title",
    ".jimu-footer",
    ".jimu-widget-title",
    ".jimu-panel",
    ".jimu-btn"
  ],
  ... // more unrelated config
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

This seems to work pretty well, but feels like too much of a hack and I'm not sure if I like it.  Robert, how are you handling this?  Do you have a snippet of code you could share?  You are the widget master, so I'm sure you're handling it way better/cleaner than me

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Caleb,

  Honestly I have a bunch of hard coded css rules in some of my widgets handling this:

Here is just some examples of my rules in my widget css

.FoldableTheme.default .jimu-on-screen-widget-panel > .jimu-panel-title,
.FoldableTheme.default .search-btn,
.FoldableTheme.default .jimu-draw-box .draw-item.jimu-state-active,
.FoldableTheme.default .esriPopup .titlePane {
  background-color: rgb(89, 102, 121);
  background-color: rgba(89, 102, 121, 1);
}‍‍‍‍‍‍‍

.JewelryBoxTheme.black .jimu-on-screen-widget-panel > .jimu-panel-title,
.FoldableTheme.black .jimu-on-screen-widget-panel > .jimu-panel-title,
.TabTheme.default .jimu-on-screen-widget-panel > .jimu-panel-title,
.FoldableTheme.black .search-btn,
.TabTheme.default .search-btn,
.JewelryBoxTheme.black .search-btn,
.PlateauTheme.black .search-btn,
.FoldableTheme.black .jimu-draw-box .draw-item.jimu-state-active,
.TabTheme.default .jimu-draw-box .draw-item.jimu-state-active,
.JewelryBoxTheme.black .jimu-draw-box .draw-item.jimu-state-active,
.PlateauTheme.black .jimu-draw-box .draw-item.jimu-state-active,
.FoldableTheme.black .esriPopup .titlePane,
.JewelryBoxTheme.black .esriPopup .titlePane,
.TabTheme.default .esriPopup .titlePane,
.PlateauTheme.black .esriPopup .titlePane {
  background-color: rgb(0, 0, 0);
  background-color: rgba(0, 0, 0, 1);
}
by Anonymous User
Not applicable

Since this is something I may be using in many future widgets, I have created a module to change the style of elements in the widget to match Web App Builder App's theme (or based on the color of any element).  I have called it "ThemeStyle.js", and it can be downloaded from GitHub in case anyone else is having this issue and wants an easy way to style the widget to match the theme.   

I have ported the jquery code I used before to dojo.  To use, place the "ThemeStyle.js" file in the project folder and use the AMD loader to bring it in:

define(['./ThemeStyle'], function(ThemeStyle){
  // do stuff with ThemeStyle here
})‍‍‍‍‍‍

To match a theme style, you can do the following:

ThemeStyle.matchThemeColor('div.jimu-widget-header-controller', 'div.rental-density', [
  ".jimu-panel-title",
  ".jimu-title",
  ".jimu-footer",
  ".jimu-widget-title",
  ".jimu-panel",
  ".jimu-btn"
], '.jimu-btn');
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

The arguments are as follows:

/* matches colors of a specific template element
*
* Arguments:
*  `templateElement` - css selector for the element that has the desired "background-color" css attribute (string)
*  `rootSelector` - parent node for which to apply color scheme to children (string)
*  `childSelectors` - array of css selectors for children to apply "background-color" css to [string, string, ...]
*  `buttonSelector` - (optional) css selector for buttons/elements for which to apply a hover event. The hover event
*                     creates animation to show the button with 70% opacity. (string)
*/‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

And here is a video showing it in action:

widget using Theme Style in action