Styling

There are 4 different mechanisms you can use to style the widgets in a MobxSchemaForm. All but the first can be seen in the mobx-forms-demo Demo.

Most of the mechanisms rely on proper webpack configuraton for SASS and CSS Modules. See webpack.config.js in the demo repository.

Field-specific CSS Module style file

In the props object in Form Field Metadata, you can pass the style object that results from importing a CSS Module in the theme property:

import myFieldStyle from './myFieldStyle.css';

import schemaJson from './schema.json';

schemaJson.form.find((field) => field.key === 'myField').props = { theme: myFieldStyle };

In the above example the field must be in the form array as an object, not a string. Also, if it's nested inside a fieldset, you need to first find the fieldset and then find the field in the items array of the fieldset.

react-css-themr ThemeProvider

Install react-css-themr with npm install react-css-themr --save

Create a CSS Module theme style file for each widget type. The demo project has one for button and datepicker. The documentation for each React-Toolbox widget lists the class names used in the widget that you can customize. To override the default styling you will need to match the rule specificity or use !important.

# /css/button.css

.button {
  text-transform: uppercase;
}

Create a theme file that imports each widget's theme style under the special theme key listed in that widgets's documentation, i.e. (from the demo):

# theme.js

import RTButton from './css/button.css';
import RTDatePicker from './css/datepicker.css';

export default {
  RTButton, RTDatePicker,
};

Wrap your component tree with ThemeProvider at the desired level in your component hierarchy. You can maintain different themes, each importing differently styled css files (i.e. import RTButton from './css/adminAreaButton.css') and can provide each one at different points in the tree. In the demo, there is just one at the App level:

import React from 'react';
import { ThemeProvider } from 'react-css-themr';
import theme from './theme';

class App extends React.Component {
  render() {
    return (
      <ThemeProvider theme={theme}>
        <div>
          ...
        </div>
      </ThemeProvider>
    );
  }
}
export default App;

React Toolbox Variables

React Toolbox 1.x used SASS variables which could be set as described under Theming on http://react-toolbox.com/\#/install

React Toolbox 2.x (currently beta.5 works well but not beta.6) uses CSS Custom Properties internally which you can override at build-time by supplying an object with these variable names and your desired values to the PostCSS customProperties plugin. i.e. if using postcss-next in webpack:

{
...
    postcss: () => {
    return [
      /* eslint-disable global-require */
      require('postcss-cssnext')({
        features: {
          customProperties: {
            variables: { 
              'color-text': '#444548',
            },
          },
        },
      }),
      require('postcss-modules-values'),
      /* eslint-enable global-require */
    ];
  },
}

There is no documentation that lists these variables, so you have to look at each React-Toolbox's component config.css file (2.x is currently in the dev branch), i.e. for a button - https://github.com/react-toolbox/react-toolbox/blob/dev/components/button/config.module.css

Using CSS Module Values

Defining CSS variables in JavaScript is a bit awkward, so the demo uses CSS Module Values and the modules-values-extract utility instead to customize variables in the same file where the widget's style overrides are defined (i.e. /css/button.css).

CSS Module Values also offer the advantage that importing a css file with @value declarations makes these values properties of the imported style object, i.e.:

# variables.css

@value buttonPrimaryBackgroundColor: #9c3990;
import styleVariables from './css/variables.css';

styleVariables.buttonPrimaryBackgroundColor

In the demo, modules-values-extract utility is used to extract all @values with dashes in their name from all css files in the /css folder and to feed them to customProperties in webpack. In the demo, variables that are not specific to a particular component are in variables.css and button-specific variables are in button.css. Note that button.css also imports certain values from variables.css just to demonstrate this capability (the import can also be used in a @value declaration) and it uses CSS overrides instead of color variables that exist in the React-Toolbox Button component to show an alternative method if the variables are not sufficient.

IMPORTANT: Changes to the module values do not take effect immediately with Webpack Hot-Module-Reload - webpack / webpack-dev-server must be restarted!

Styling with FieldWrapper

FieldWrapper is an optional Component that can be used to wrap each widget in some html (DL/DD,DT) that can display the field title (in DD) and makes it easy to style some html elements that the default mobx-schema-form widgets use in addition to the React-Toolbox widgets (i.e. the description in <abbr> in switch and range/slider widgets and the range/slider tick labels in OL/LI tags).

In the demo, index.scss uses a combination of global classes (webpack in the demo is configured to process this particular file as plain/global css, not as a css module), data- attributes and specific html tags to control the layout of the widgets and set some styling.

The default FieldWrapper layout in the demo is side-by-side but some fields in the demo in Form Field Metadata have className of hideFieldTitlefor a full-width layout without a title (used at the top of the form) or fullWidthField for full-width layout with a title above the widget (used for the range/slider). These classes are defined towards the bottom of index.scss.

Last updated