@mott-macdonald/smi-react-ui-kit
v3.2.2
Published
The MUI theme for Mott MacDonald Moata Apps
Downloads
2,946
Readme
This is the latest version. The legacy version (v1) can be found on the branch v1.
Moata React UI Kit
Moata React UI Kit is a MUI theme for Mott MacDonald Moata projects.
This UI Kit is for Mott MacDonald authorized projects only. Please refer to the LICENSE section if you intend to download the published source code.
Installation
Installation for a new project
Add this package and its peer dependencies to your project:
pnpm add @mott-macdonald/smi-react-ui-kit @emotion/react @emotion/styled @mui/lab @mui/material
with ThemeProvider (the default approach)
At the very top level of your react app (usually it is the top level ts/tsx file that contains ReactDOM.render()
), inject the Moata fonts and use the Material-UI theme provider to inject the default 'light' Mott Macdonal theme from this library. It is usually also a good idea to use the CssBaseline
component from Material-UI at this point.
import { ThemeProvider, CssBaseline } from '@mui/material';
import { themes } from '@mott-macdonald/smi-react-ui-kit';
import '@mott-macdonald/smi-react-ui-kit/fonts.css';
ReactDOM.render(
<React.StrictMode>
<ThemeProvider theme={themes.light}>
<CssBaseline />
<App />
</ThemeProvider>
</React.StrictMode>,
document.getElementById('root')
);
From this point on, use any component from the Material-UI library and follow the usage guidelines and examples provided from that project.
with CssVarsProvider
The CSS variables theme gives us a way to reference the theme variables in our own CSS/SCSS files.
All CSS variables are prefixed with --moata-
to avoid conflicts with other CSS variables.
In MUI components, you can use the theme.vars.palette.*
to reference the CSS variables version of the theme values. (Notice the .vars
in the path)
Check out the Material-UI documentation for more information.
import { CssBaseline } from '@mui/material';
import { Experimental_CssVarsProvider as CssVarsProvider } from '@mui/material/styles';
// this would patch the typing of the `theme` under MUI components' `sx`,
// so that we can reference the CSS variables version of the theme values from `theme.vars.*`.
import type {} from '@mui/material/themeCssVarsAugmentation';
import { cssVarsTheme as theme } from '@mott-macdonald/smi-react-ui-kit';
import '@mott-macdonald/smi-react-ui-kit/fonts.css';
ReactDOM.render(
<React.StrictMode>
<CssVarsProvider theme={theme} defaultMode="light">
<CssBaseline />
<App />
</CssVarsProvider>
</React.StrictMode>,
document.getElementById('root')
);
Installation alongside legacy version (v1) for a staged upgrade to the latest version
This library can be installed alongside the previous version. To achieve this:
First edit the
package.json
as follows:- "@mott-macdonald/smi-react-ui-kit": "{VERSION}", + "@mott-macdonald/legacy-smi-react-ui-kit": "npm:@mott-macdonald/smi-react-ui-kit@legacy",
Update all import from
"@mott-macdonald/smi-react-ui-kit"
to use"@mott-macdonald/legacy-smi-react-ui-kit"
Rename the
ThemeProvider
component imported from the legacy version toLegacyThemeProvider
Install the latest version using the process above, including adding the
ThemeProvider
component.Add a new file in the root of the document called
muiClassNameSetup.ts
. And add a customClassNameGenerator
so that the Mui class names don't clash. As described here.import { unstable_ClassNameGenerator as ClassNameGenerator } from '@mui/material/className'; ClassNameGenerator.configure((componentName) => `moata-${componentName}`);
Import this at the top of your
index.tsx
file.
Your index.tsx
file should now look something like this:
import './muiClassNameSetup';
import {
ThemeProvider as LegacyThemeProvider,
GlobalStyles as LegacyGlobalStyles,
} from '@mott-macdonald/legacy-smi-react-ui-kit';
import { themes } from '@mott-macdonald/smi-react-ui-kit';
import { ThemeProvider, CssBaseline } from '@mui/material';
import '@mott-macdonald/smi-react-ui-kit/fonts.css';
ReactDOM.render(
<React.StrictMode>
<LegacyThemeProvider>
<LegacyGlobalStyles />
<ThemeProvider theme={themes.light}>
<CssBaseline />
<App />
</ThemeProvider>
</LegacyThemeProvider>
</React.StrictMode>,
document.getElementById('root')
);
Both version of the UI library can now be used in the same project. The components used from V1 can then be migrated to use the new approach one by one.
Usage
In the most part, once the theme is added to the project, you should follow the guidelines and examples provided in the Material-UI documentation, and by the wider community.
Additionally, the Storybook in this project is a good place to look for some useful examples of common UI components found in Moata projects. Examples include how to build a "Detail menu", "Product header", and an expandable "Detail panel"
Using the theme value in JS
The active theme can be accessed by using the useTheme
hook available from @mui/material
.
Using Icons
Importing
The icons are packaged separately and can be imported using:
import { Alert as AlertIcon } from '@mott-macdonald/smi-react-ui-kit/icons';
View all of the available icons in the storybook here
If there are icons missing that you need, please email:
They can arrange for the new icon to be created, exported, and added to this project.
Styling
The icons are MUI SvgIcon components.
By default, the icons inherit the color
and font-size
of the parent element. When we want to adjust the color and size of icons, we should adjust them by changing the color
and font-size
CSS properties.
with sx
prop:
import { Alert as AlertIcon } from '@mott-macdonald/smi-react-ui-kit/icons';
import styles from './example-button.module.scss';
export const ExampleButton = () => (
<button type="button">
<AlertIcon sx={{ color: '#333', fontSize: '1.5rem' }} />
</button>
);
with SCSS Modules:
import { Alert as AlertIcon } from '@mott-macdonald/smi-react-ui-kit/icons';
import styles from './example-button.module.scss';
export const ExampleButton = () => (
<button type="button">
<AlertIcon className={styles.icon} />
</button>
);
// example-button.module.scss
.icon {
color: #333;
font-size: 1.5rem;
}
Styling library recommendations
We would recommend that new projects use the recommended approach to styling components for Material-UI, which is to use the sx
prop and the styled
function provided by material-ui. See the help here.
The aim should be to never use the basic html elements. e.g. You should never use a div
element. We should always use the Box
provided by the Material-UI library, or the other layout elements provided by the library.
See the storybook for good examples of this.
However, a number of styling approaches are supported, as documented in the Material-UI documentation here
~~Nesting the theme (for dark backgrounds)~~ [deprecated]
The new Design System has dropped scenarios of nesting the theme to enable the possibility of switching the theme dynamically in the future.
As described here, it is possible to nest the theme. This is very useful as many Moata app have sections with dark backgrounds, where the dark theme should be used.
with ThemeProvider
<ThemeProvider theme={themes.light}>
<LightBackgroundContent />
<ThemeProvider theme={themes.dark}>
<DarkBackgroundContent />
</ThemeProvider>
</ThemeProvider>
Check out Nesting the theme
with CssVarsProvider
<CssVarsProvider theme={theme} defaultMode="light">
<LightBackgroundContent />
<div data-mui-color-scheme="dark">
<DarkBackgroundContent />
</div>
</CssVarsProvider>
Check out Force a specific color scheme
Development
Prerequisites
- Node.js LTS v18 or above - LTS versions are preferred Download Node
- Recommend using
fnm
ornvm
to manage Node.js versions. Checkout fnm, nvm for macOS, nvm-windows for Windows
- Recommend using
pnpm
>= 8.10.0 Install pnpm- Github Package Token
- Login to Github and Navigate to https://github.com/settings/tokens
- Select "Personal access tokens", and then click on "Generate new token"
- Pick a name for your new token, in the scopes section, select only
read:packages
- Click "Generate token" near the bottom of the page, and make sure to copy and save the token to a secure place
- Make sure that the environment variable
NPM_AUTH_TOKEN
is made available in your system. For example, if you are using bash, make sure the variable is set to the token acquired in step 4. For windows, see How to Set Env Variables in Windows 10
If you run into NPM errors related to credentials when running pnpm install
, please check:
- Check with your lead if you have necessary access rights including access to internal NPM packages used in this repository.
- The environment variable
NPM_AUTH_TOKEN
is made available in your system. - The repository is cloned with SSH instead of HTTPS.
Quick start
Clone the repository and develop components with storybook.
Note: It's important to clone the repository with SSH, HTTPS won't work in the dependency installation step.
# Clone the repository
git clone [email protected]:mottmac-moata/moata-react-ui-kit.git
# Install dependencies
pnpm install
# Start Storybook dev server (and watch changes)
pnpm storybook
# Go to http://localhost:6006
Start Storybook dev server over HTTPS
By default, without pre-generating a trusted certificate, the Storybook dev server will start over HTTP.
Recommand using mkcert to generate a locally trusted certificate.
- Install the mkcert.
- Run the following commands to generate a trusted certificate in the root repo directory.
# Created a new local CA
mkcert -install
# Create certificate folder
mkdir .https
# Created a new certificate
mkcert -key-file .https/key.pem -cert-file .https/cert.pem localhost
Build
To build a new version, bundle this kit:
pnpm build
Linting
Eslint and prettier runs automatically after each git commit
command.
To run eslint
manually:
pnpm lint
Adding New Icons
- Icons must be created by the Mott Macdonald design team.
- All icons should be included in the "Motata Library" Figma file.
- Icons must be 24x24 pixels with an live area 20x20 pixels.
(refer to Material Design Icon Principles for more information)
To add a new icon
- Select the icon element in the Moata library Figma file. (Make sure the selected element is the icon with the correct size)
- Use the Export feature to download the icon as an SVG file. (Make sure the Export settings are set to the values below )
- Add the icon SVG file to
/icon-svgs
. (Make sure the SVG file name is inPascalCase
) - Run the build icons script to generate the new icon component.
Figma export settings
Ensure the following settings are used.
- [x] Ignore overlapping layers
- [x] Simplify stroke
- [ ] Include "id" attribute
Build Icons
pnpm build:icons
The script used to build the icons (/scripts/build-icons.js
) can be used in other projects to build custom icon sets.
But all icons should be approved by the Moata design team (email: [email protected]), and preferably, all icons should be added to this package
so that they are available to other projects.
CHANGELOG
We use changesets to manage package versions and changelogs.
Use pnpm changeset
to trigger change log and follow the steps. Please remember
to add and commit the change log after it has been created.
Use pnpm changeset --empty
to create a empty change log without a version bump when you are only doing repo maintenance that does not affect the built artifacts.
Best practices and documentation can be found here - Adding a changeset
License
See LICENSE file - or this public copy
License subject to change: current version: v20190514.