Introduction

Dojo promotes encapsulated structural styling of individual widgets for maximum reuse, as well as simplified presentational theming across all widgets within an application. This pattern gives users a predictable way to style and theme their applications, even when using a mixture of widgets from , a third-party provider, or any that may be developed in-house for a particular application.

Basic usage

These examples assume an application with the following name:

package.json

The application name becomes relevant when specifying .

  • Defining a CSS module for a widget
  • Using the corresponding typed style classes within the widget’s TypeScript code
  1. .root {
  2. font-family: sans-serif;
  3. }

src/widgets/MyWidget.tsx

  1. import { create, tsx } from '@dojo/framework/core/vdom';
  2. import * as css from '../styles/MyWidget.m.css';
  3. const factory = create();
  4. export default factory(function MyWidget() {
  5. return <div classes={[css.root]}>My Widget</div>;
  6. });

Making a widget themeable

  1. import { create, tsx } from '@dojo/framework/core/vdom';
  2. import theme from '@dojo/framework/core/middleware/theme';
  3. import * as css from '../styles/MyWidget.m.css';
  4. const factory = create({ theme });
  5. export default factory(function MyWidget({ middleware: { theme } }) {
  6. return <div classes={[root]}>My Widget</div>;
  7. });
  • Set the theme.variant class on the widget’s root.
  • css-properties get applied at the correct DOM level and do not leak out of the widget’s DOM.

src/widgets/MyWidget.tsx

Creating a theme

  • Overriding a widget’s default CSS class with custom theme style properties
  • Linking one or more overrides via the appropriate widget theme keys into a

src/themes/MyTheme/MyWidget.m.css

  1. .root {
  2. color: hotpink;
  3. background-color: slategray;

src/themes/MyTheme/theme.ts

  1. import * as myWidgetCss from './MyWidget.m.css';
  2. export default {
  3. 'my-app/MyWidget': myWidgetCss
  4. };
  • Placing theme variables into a variant module as CSS custom properties
  • Referring to the custom properties via var()
  • Not relying on local variables or a common variables.css file.
  1. /* single root class */
  2. .root {
  3. --foreground: hotpink;
  4. --background: slategray;
  5. }

src/themes/MyTheme/MyWidget.m.css

src/themes/MyTheme/index.tsx

  1. import * as defaultVariant from './variants/default.m.css';
  2. import * as myWidgetCss from './MyWidget.m.css';
  3. export default {
  4. theme: {
  5. 'my-app/MyWidget': myWidgetCss
  6. },
  7. variants: {
  8. default: defaultVariant
  9. }

Specifying a default application theme

The theme middleware can be used to set the application theme. To set a “default” or initial theme, the theme.set function can be used with the theme.get function to determine if the theme needs to be set. Setting the default theme should be done in the application’s top level widget.

src/App.tsx

  1. import { create, tsx } from '@dojo/framework/core/vdom';
  2. import theme from '@dojo/framework/core/middleware/theme';
  3. import myTheme from '../themes/MyTheme/theme';
  4. const factory = create({ theme });
  5. export default factory(function App({ middleware: { theme }}) {
  6. // if the theme isn't set, set the default theme
  7. if (!theme.get()) {
  8. theme.set(myTheme);
  9. }
  10. return (
  11. // the application's widgets
  12. );
  13. });

Note: When using both function-based and class-based widgets, the theme needs to be registered with the application registry. This is true when using any class-based widget dependencies such as @dojo/widgets. Please see the class-based theming section for more details.

  1. import { create, tsx } from '@dojo/framework/core/vdom';
  2. import theme from '@dojo/framework/core/middleware/theme';
  3. import myTheme from '../themes/MyTheme/theme';
  4. const factory = create({ theme });
  5. export default factory(function App({ middleware: { theme }}) {
  6. // if the theme isn't set, set the default theme
  7. if (!theme.get()) {
  8. theme.set(myTheme, 'variant-name');
  9. }
  10. return (
  11. // the application's widgets
  12. );

Changing the theme within an application