New App Design Considerations - Part 8 BS4 Themes Sample Project

As BS4 seems to be one of the main choices of controls we’ll have to use in AppStudio IDE to build apps for at least the near future, then themes should be considered during the design process. This sample program allows you to see the differences in BS4 themes, eg, the default colors, sizes, etc. so that you can make appropriate decisions about what theme or themes you might use in a new app.

Project17b.appstudio.zip (539.0 KB) This comes with no guarantees. :blush:

First notice all controls are put on the form without consideration for positioning or sizing. EG, it looks ok (ish) in the default bootstrap theme on most devices, but the sketchy theme, for example, is all jumbled. What does this mean to you? If you’re designing your app for multiple devices, then make sure you use grids and flex so that these controls flow appropriately. If you allow for changing of themes in your app, like for light and dark modes, then verifying your flow in each theme should be check when you are checking multiple devices and rotation, etc.

The setting of themes requires you to provide the BS4 theme css file. I put them in the BS4 CSS folder of this project, and even included the bootstrap default theme in that same folder, even though it is already in the toolbox folder. This is so I could easily change back to the default css with one simple CSS replacement command.

How did I replace, or override the CSS? Before I realized I was going to publish this, I added a container to the form and then copied the necessary link tag into the innerHTML of the container. Since the container is after the original link files included by AS, they override those styles. As you change the theme in the drop down, the new link tag is then copied over then old innerHTML. I left that code and container commented out in the project.

Was this the best way? Is it elegant? So I rewrote it to use getElementsByTagName(‘link’) and found the original bootstrap link, keep a pointer to the element for later update, and then update the tag for each theme selected. What I did not do was actually verify that I choose the correct link tag. I just choose the 6th as I knew that’s where it was in this project. You should look at all of the link tags of type = 4 and then check the href to find the correct one. Then just keep a pointer to it to update it’s href. This method was incorporated in the sample.

I also added the ability to change the project properties backgroundColor and color with a radio button. Selecting inherit provides you with the ability to see how each devices dark mode works with each theme.

I placed the container (no longer used for link HTML) at 2000 pixels from the top, forcing most device browsers to have a vertical scroll. Be sure to look at the background and foreground colors of the area that was off screen before the scroll. They have the colors determined by @media definitions that are included by AS in the asStyles.css file. There is a light and dark @media definition that is controlled by the device if you inherit the @media settings. Currently the AS light and dark are black and white vs white and black only. Any combination of colors are allowed.

I added a button to copy the body colors to the 1st and 2nd @media definitions, the light and dark definitions. So after changing a theme in the drop down, you can fix the off screen area colors with this button.

These are the key pieces of code of how to set the theme and @media colors;

/*  the 6th link is the one in this particular compile that is the bootstrap theme.
    I recommend searching the collection for the correct link tag.  */

var linkTag = document.getElementsByTagName('link')[5]

Radiobutton2.onchange=function(){
// bodystyle is where the project properties for color are stored. 
var bodystyle = document.getElementsByTagName('body').item(0).style;
  switch(Radiobutton2.value) {
    case 0:
      bodystyle.backgroundColor = '';
      bodystyle.color = '';
      break;
    case 1:
      bodystyle.backgroundColor = 'white';
      bodystyle.color = 'black';
      break;
    case 2:
      bodystyle.backgroundColor = 'black';
      bodystyle.color = 'white';
      break;
    case 3:
      bodystyle.backgroundColor = 'inherit';
      bodystyle.color = 'inherit';
      break;
    };
}

Button2.onclick=function(){
/* a new button to propagate the forms backcolor/color to the @media CSS definition
 first get the body colors
 getComputedStyle(document.getElementsByTagName('body').item(0)).color;
 getComputedStyle(document.getElementsByTagName('body').item(0)).backgroundColor;
 then set the @media colors
 document.styleSheets[0].cssRules[0].cssRules[0].style.color
 document.styleSheets[0].cssRules[0].cssRules[0].style.backgroundColor
 but you may have to set them for all type = 4 (media) and set them all just to cover all bases, or
 you could read the current prefers-color mode setting and then look for it in the media entries and 
 adjust it only - it's more efficient - who cares
*/
 document.styleSheets[0].cssRules[0].cssRules[0].style.color = getComputedStyle(document.getElementsByTagName('body').item(0)).color; // light
 document.styleSheets[0].cssRules[0].cssRules[0].style.backgroundColor = getComputedStyle(document.getElementsByTagName('body').item(0)).backgroundColor;
 document.styleSheets[0].cssRules[1].cssRules[0].style.color = getComputedStyle(document.getElementsByTagName('body').item(0)).color; // dark
 document.styleSheets[0].cssRules[1].cssRules[0].style.backgroundColor = getComputedStyle(document.getElementsByTagName('body').item(0)).backgroundColor;
}

Dropdown1.onclick=function(){
console.log(Dropdown1.selection);
if (typeof(Dropdown1.selection) == 'string') {
    Dropdown1.value = Dropdown1.selection;
//    Container1.innerHTML = '<link href="BS4 CSS/' + Dropdown1.selection + '.min.css" rel="stylesheet">';
    linkTag.attributes[0].value = 'BS4 CSS/' + Dropdown1.selection + '.min.css';
    }
}

Thanks for posting this. It will help people understand how themes work, especially if they want to have more than one theme available in project.