Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Cover image for Theming with Dojo Middleware
Rene Rubalcava
Rene Rubalcava

Posted on • Originally published atlearn-dojo.com

     

Theming with Dojo Middleware

Recently, we looked at the newwidget middleware that is available in Dojo. Aside from maintaining widget state or application stores, you can also use thetheme middleware tostyle your widgets.

Let's take aprevious example that used the function based widgets and add a theme to it.

Themes

Themes are a great way to build applications and widgts that could be used by others. You might build alibrary of widgets to share with others. You can release the widgets with a default generic theme, but also allow others to provide their own themes. This lets developers repurpose widgets and applications for blogs, dashboards, or other applications and let them use a uniform theme.

You could even let users of your application choose their theme, such as providing a dark and light theme.

To add themes to our own applicaun, we can add athemes folder withdark andlight folders to organize our themes. Then we can add aUsers folder to each one for the themeable widget. To make the css available as themes, we need to create a module to export our themes.

/* src/themes/dark/Users/theme.ts *//* src/themes/light/Users/theme.ts */import*ascssfrom"./Users.m.css";exportdefault{"dojo-function-based-widgets-themeable/Users":css};
Enter fullscreen modeExit fullscreen mode

To export a theme, you need to export an object with thewidget theme key and the referenced css. Note the format is as follows.

{package-name}/{widget-css-module-name}: {css}

Now, we can update our widget to make it themeable.

Themeable Widget

Here is what the original widget looked like.

// src/widgets/Users/Users.tsx...exportdefaultrender(functionUsers({middleware:{store}}){const{get,path,executor}=store;constusers=get(path("users"));if(!users){executor(fetchUsersProcess)(null);return<em>Loading users...</em>;}return(<divclasses={[css.root]}><h1>Users</h1><ulclasses={[css.list]}>{userList(users)}</ul></div>);});
Enter fullscreen modeExit fullscreen mode

We can update it with thetheme middleware.

import{create,tsx}from"@dojo/framework/core/vdom";// theme middlewareimportthemefrom"@dojo/framework/core/middleware/theme";importicachefrom"@dojo/framework/core/middleware/icache";// dojo theme and dojo checkboximportdojoThemefrom"@dojo/themes/dojo";importCheckbox,{Mode}from"@dojo/widgets/checkbox";// base css and themesimport*ascssfrom"./Users.m.css";importdarkfrom"../../themes/dark/theme";importlightfrom"../../themes/light/theme";...// add the theme middleware to the widgetconstrender=create({icache,store,theme});...exportdefaultrender(functionUsers({middleware:{icache,store,theme}}){const{get,path,executor}=store;constusers=get(path("users"));if(!users){executor(fetchUsersProcess)(null);return<em>Loading users...</em>;}constchecked=icache.getOrSet("checked",false);// if no theme set, default to the light themeif(!theme.get()){theme.set(light);}// extract the themed css to useconstthemedCss=theme.classes(css);return(<divclasses={[themedCss.root]}><Checkboxtheme={dojoTheme}mode={Mode.toggle}checked={checked}onChange={()=>{// use checkbox to toggle themeicache.set("checked",!checked);if(!checked){theme.set(dark);}else{theme.set(light);}}}/><h1>Users</h1><ulclasses={[themedCss.list]}>{userList(users,themedCss)}</ul></div>);});
Enter fullscreen modeExit fullscreen mode

There is a bit going on here. We're adding some new imports.

// theme middlewareimportthemefrom"@dojo/framework/core/middleware/theme";importicachefrom"@dojo/framework/core/middleware/icache";// dojo theme and dojo checkboximportdojoThemefrom"@dojo/themes/dojo";importCheckbox,{Mode}from"@dojo/widgets/checkbox";// base css and themesimport*ascssfrom"./Users.m.css";importdarkfrom"../../themes/dark/theme";importlightfrom"../../themes/light/theme";constrender=create({icache,store,theme});
Enter fullscreen modeExit fullscreen mode

We're adding thetheme middleware and theicache for the Dojo checkbox so that we can toggle themes. Then we import the base css and our light and dark themes. We then provide these as middleware to the function based widget.

Then we need to use them in the widget.

exportdefaultrender(functionUsers({middleware:{icache,store,theme}}){...constchecked=icache.getOrSet("checked",false);// if no theme set, default to the light themeif(!theme.get()){theme.set(light);}// extract the themed css to useconstthemedCss=theme.classes(css);return(<divclasses={[themedCss.root]}><Checkboxtheme={dojoTheme}mode={Mode.toggle}checked={checked}onChange={()=>{// use checkbox to toggle themeicache.set("checked",!checked);if(!checked){theme.set(dark);}else{theme.set(light);}}}/><h1>Users</h1><ulclasses={[themedCss.list]}>{userList(users,themedCss)}</ul></div>);});
Enter fullscreen modeExit fullscreen mode

We can toggle the theme by usingtheme.set(customTheme) and then useconst themedCss = theme.classes(css) to get our themed css classes to apply to the widget. ThisthemedCss is what we can use to apply our scoped css class names to the widget.

You can see the result below. Use the toggle button to toggle between light and dark theme.

Once you get the pattern down, applying themes to your widgets can be a lot of fun.

If you are looking at providing a light and dark theme in your own applications, you could even use the preference set by users of Mac OS. You could usematchMedia to detectprefers-color-scheme.

if(window.matchMedia("(prefers-color-scheme: dark)").matches){theme.set(dark);}
Enter fullscreen modeExit fullscreen mode

Things to remember

In general, it too me a little bit to really understand themes in Dojo, and I think I've finally got a good grasp on it.

Here are some things to remember.

  • Theme class names must match widget default class names.
    • The theme will only be applied to class names in the defaultcss of your widget, even if they are empty, make sure they match.
  • {package-name}/{widget-css-module-name} - This is thewidget theme key.
    • This threw me off a bit, thanks to the Dojo team ondiscord for helping me grasp this one!
  • Use avariables.css to maintaincommon theme properties.
  • Read thedocumentation.
    • It's incredibly well written and contains all the details you need.

Summary

Theming widgets can be a lot of fun, and you can find yourself diving down a rabbit hole of tweaks and css hacking to make some really cool things. Don't forget you can scaffold themes for@dojo/widgets using@dojo/cli-create-theme. This will let you pick and choose which widgets you want to apply themes to.

Building themeable widgets also allows you to build more reusable widgets. This way you can drop your widgets into any other applications and quickly provide new themes without putting in a lot of effort to start from scratch!

Top comments(0)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

Blogger, author, youtuber, webdev, geodev
  • Location
    Redlands, CA
  • Work
    Principal SoftWhere Engineer at Esri
  • Joined

More fromRene Rubalcava

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp