Skip to main content Skip to footer

How to Style JavaScript Components Using Sass

Styling an entire set of JavaScript components can be quite a challenge. Luckily, Sass, a powerful CSS tool, can simplify it! Our toolset, Wijmo, contains many components, including some very complex ones, like FlexGrid. We decided to fully leverage Sass to make our own work easier, but more importantly, it makes building a theme for all components easy for customers. Let’s walk through the steps below to build a complete Wijmo theme using just a few lines of Sass:

  1. Start with a JavaScript App
  2. Add a New Theme
  3. Reference the New Theme
  4. Run the App
  5. Customize the Theme
  6. Reuse the Theme

You can download this sample app and follow along yourself.

Ready to Try It Out? Download Wijmo Today!

Start with a JavaScript App

First, we will start with a simple JavaScript app that has a few Wijmo components in it (we won’t walk through building this app) and uses Sass for CSS, assuming we already installed Wijmo in our app using:

npm install @mescius/wijmo.purejs.all 

All Wijmo themes are installed with this command (which includes everything we need to build our theme). The Wijmo Sass and CSS files are all inside this single package: @mescius/wijmo.styles

Here is a breakdown of what is inside the package:

📄wijmo.scss

Main file that compiles all parts together and applies variables.

📁 misc

Contains utilities for themes. It is good to reference _variables.scss in here to understand all available variables in Wijmo themes.

📁 parts

You won’t need to use this, but it contains all the CSS rules for our individual components. Feel free to take a look, though!

📁 themes

Contains all themes available for Wijmo. It’s good to look through these to find a theme close to what you want or to get an idea of how we build themes.

Add a New Theme

Now, we want to find a theme that is close to what our theme will look like. You can test different themes from our demo site. Choose themes from the dropdown in the top right to see how components look.

Style JavaScript Components

After you decide on a theme you want to start with, find it in the node_modules\@mescius\wijmo.styles\themes directory.

For this tutorial, we will use Cleanlight. Let’s copy and paste that wijmo.theme.cleanlight.scss file into our root directory (you can put it anywhere you keep CSS files). You don’t want to keep your theme in the Wijmo package directory so that it will never get lost or overwritten. It should always exist in your own app (or in your own package if you plan to share it across apps).

Rename the file to give it a name that you like. We will name this one: wijmo.theme.custom.scss.

Our application now has a custom Wijmo theme in it:

Style JavaScript Components

The theme file has two parts:

  1. This first section sets (overrides default) variables
  2. The second section imports the wijmo.scss file and applies those variables

Since we moved the theme from node_modules into our root directory, we will need to change the path of the @import statement at the end of the theme file.

The new path should look like this:

@import "../node_modules/@mescius/wijmo.styles/wijmo.scss";

Referencing the New Theme

Our application has a styles.scss file with basic CSS rules and previously imported a Wijmo theme. Now, we want to import our new theme instead. At the end of this file, let’s import our new theme (in this sample, it's in the same directory as our styles.scss file)

@import "wijmo.theme.custom.scss";

As for the app itself, we just import the compiled CSS files in app.js

import './styles.css';

Run the App

This app already uses Sass, but let’s make sure it's clear how. First, we need the Sass package in our package.json dependencies:

"sass": "^1.60.0",

Next, we modify our scripts to add a “sass-dev” command to compile our scss files into CSS files. We also modify our “start” command to run the “sass-dev” command before running the app.

"scripts": {
    "sass-dev": "sass --style=expanded src:src",
    "start": "npm run sass-dev && lite-server"
}

After those things are set up in our app (assuming we already ran “npm install”), we can run the following:

npm run start

Now we see our app running using our new theme!

Style JavaScript Components

Customizing Our Theme

Now that our new theme is running in our app, it's time to customize it to our liking.

As a convenience, we recommend opening _variables.scss file and copying its contents into the top of the new theme, then commenting them out. These variables already have little comments next to them that describe what they style, and you can also see their default values. Here is an example of the top of our custom theme file with all possible variables commented out:

// all variables with defaults
// $wj-bkg: white !default; // content background
// $wj-txt: black !default; // content foreground
// $wj-bdr-clr: rgba(0,0,0,.2) !default; // content border color
// $wj-bdr-wid: 1px !default; // content border width
// $wj-bdr: $wj-bdr-wid solid $wj-bdr-clr !default; // content border
// $wj-bdr-rad: 4px !default; // content border radius
// $wj-box-shadow: 0 6px 13px rgba(0,0,0,.2) !default; // box shadow for drop-downs/dialogs
// $wj-invalid: red !default; // invalid state markers
// $wj-item-pdg: 4px 6px 3px 6px !default; // item padding (listbox items, grid cells, etc)
// $wj-item-hvr: rgba(0,0,0,.05) !default; // item hover
// $wj-tdn-focus: .4s !default; // focus/hover transition duration
// $wj-disabled-opacity: .6 !default; // opacity for disabled controls/items
// $wj-disabled-bkg: safechangecolor($wj-bkg, 6%) !default; // background for disabled controls/items

// $wj-hdr-bkg: #eee !default; // header element background
// $wj-hdr-hvr: safedarken($wj-hdr-bkg, 5%) !default; // header element hover background
// $wj-hdr-txt: #444 !default; // header element foreground

// $wj-btn-bkg: #eee !default; // button background
// $wj-btn-hvr: safedarken($wj-btn-bkg, 5%) !default; // button hover background
// $wj-btn-txt: $wj-txt !default; // button text
// $wj-btn-grp-bdr: $wj-bdr !default; // button group border

// $wj-sel-bkg: #0085c7 !default; // selected element background
// $wj-sel-txt: white !default; // selected element foreground
// $wj-msel-bkg: #80adbf !default; // extended selection background
// $wj-msel-txt: white !default; // extended selection foreground
// $wj-accent-bkg: $wj-sel-bkg !default; // accent background (like drag markers)
// $wj-accent-txt: $wj-sel-txt !default; // accent background (like drag markers)

// $wj-cell: $wj-bkg !default; // cell background
// $wj-cell-alt: safedarken($wj-cell, 3%) !default; // alternating cell background
// $wj-cell-frz: null !default; // frozen cell background
// $wj-cell-frz-alt: null !default; // alternating frozen cell background
// $wj-cell-frz-txt: $wj-txt !default; // frozen cell foreground
// $wj-cell-pdg: $wj-item-pdg !default; // cell padding
// $wj-cell-bdr-clr: rgba(0,0,0,.2) !default; // cell border color
// $wj-cell-bdr: 1px solid $wj-cell-bdr-clr !default; // cell border
// $wj-cell-bdr-vrt: $wj-cell-bdr !default; // cell vertical border
// $wj-cell-bdr-hrz: $wj-cell-bdr !default; // cell horizontal border
// $wj-cell-grp-bkg: safedarken($wj-hdr-bkg, 5%) !default; // group row background
// $wj-cell-grp-txt: $wj-hdr-txt !default; // group row foreground
// $wj-cell-frz-bdr-clr: safedarken($wj-hdr-bkg, 30%) !default; // frozen cell border color
// $wj-cell-frz-bdr: 1px solid $wj-cell-frz-bdr-clr !default; // frozen cell border
// $wj-cell-frz-bdr-vrt: $wj-cell-frz-bdr !default; // frozen area vertical border
// $wj-cell-frz-bdr-hrz: $wj-cell-frz-bdr !default; // frozen area horizontal border

// $wj-tooltip: $wj-bkg !default; // tooltip background
// $wj-tooltip-txt: $wj-txt !default; // tooltip text
// $wj-error-tooltip: red !default; // error tooltip background
// $wj-error-tooltip-txt: white !default; // error tooltip text

// $wj-bkg-grd: false !default; // content background gradient
// $wj-btn-grd: false !default; // button background gradient
// $wj-hdr-grd: false !default; // header background gradient
// $wj-input-grd: false !default; // input element background gradient

Note: most Wijmo themes don’t override all variables. You only need to override what you want to change from our default. Usually, it's just a small subset of them.

Okay, now we will customize our new theme. Here is a short list of things we want in this new theme:

  • Larger padding (in cells, buttons, etc.) for a more modern look
  • Black/dark gray text
  • Nice purplish grays for headers
  • White background for the main content
  • Teal color for highlights
  • Remove cell borders in the grid
  • Purple tooltip

Here are the contents of our entire theme. It's just a few lines of setting variables to style every JavaScript component in Wijmo!

////////////////////////////////////////////////////////////////
// set variables
//
$wj-bkg: rgb(255, 255, 255);
$wj-txt: #000000;

$wj-item-pdg: 8px 6px 7px 6px !default; // item padding (listbox items, grid cells, etc)

$wj-hdr-bkg: rgb(234, 227, 236);
$wj-hdr-txt: #2e2e2e;

$wj-sel-bkg: rgb(13, 148, 119);
$wj-sel-txt: #fff;
$wj-msel-bkg: rgb(31, 167, 137);
$wj-msel-txt: #fff;
$wj-cell-grp-bkg: rgb(196, 186, 199);
$wj-cell-grp-txt: #202020;
$wj-cell-frz: #d6e6ed;
$wj-cell-frz-alt: #c4dbe5;
$wj-cell-bdr-clr: rgba(0,0,0,.2);
$wj-cell-bdr: 0px solid $wj-cell-bdr-clr !default; // cell border

$wj-btn-bkg: rgb(13, 148, 119);
$wj-btn-txt: #fff; 
$wj-btn-grp-bdr: none;

$wj-tooltip: rgb(213, 179, 245);
$wj-tooltip-txt: #2b2121;

////////////////////////////////////////////////////////////////
// apply variables
//
@import "../node_modules/@mescius/wijmo.styles/wijmo.scss";

The results are as shown:

Style JavaScript Components

That’s it! You can continue to refine the theme as much or as little as you like.

Reusing Your Theme

We already finished building a theme, but what if you want to share this theme across many apps? Of course, you can copy and paste it, but there is another option.

Optionally, you can manage this theme in a separate project and publish only this theme on npm (or your own private registry). Then, any of your apps can install and import the shared theme via npm. This is the best option for large companies that share a theme across many teams and apps. If you do end up publishing a theme publicly, please let us know. We would love to take a look and even share it if you like.

Ready to Try It Out? Download Wijmo Today!

Tags:

comments powered by Disqus