Theme
Theme is central to how our whole design system functions. It is the single most important component in our design system. Our theme component is a Styled Components ThemeProvider that specifies fonts, colors, breakpoints, spacing sizes and more. Each app using Mesh components should have a single high-level theme wrapping the rendered output.
Components must be wrapped by this Theme
Installation
npm install @nib-components/theme
Usage
import Theme, {nib} from '@nib-components/theme';const App = () => (<Theme theme={nib}>{children}</Theme>);
Interactive demo
Requirements for use
There are two requirements which prevent problems with individual components rendering incorrectly:
- You should always include the
Theme
component once, at the root of your app. - Never should an nib component be rendered outside of the
Theme
component.
Props
Prop | Type | Default | Description |
---|---|---|---|
theme (required) | object | The brand theme to use. Must be one of [nib , gu , iman ]. | |
mode | object | {form: 'light'} | The value of mode.form will override the theme.mode.form value in the theme passed down to all styled components via the ThemeProvider . Must have shape: {form: oneOf(['light', 'white'])} . |
Selectors
Our components look to our theme for a lot of their styling information. Navigating the theme tree structure to find the value that you need can be tiresome. It also requires you to know the structure of the theme.
Selectors offer a shorthand to pull values from the theme. Below is a comparison between the two methods. As you can see, the selector pattern simplifies the process significantly. These selectors are mapped to every section of the theme and their values can differ based on the theme brand.
Navigating the theme structure:
const Heading = styled.h1`font-family: ${props => props.theme.headings.h1.fontFamily};font-size: ${props => props.theme.headings.h1.fontSize};color: ${props => props.theme.colors.shades.darkest};`;
Using theme selectors:
import {h1FontFamily, h1FontSize, colorDarkest} from '@nib-components/theme';const Heading = styled.h1`font-family: ${h1FontFamily};font-size: ${h1FontSize};color: ${colorDarkest};`;
For the full list of selectors provided by the theme, see the selectors documentation.
Using selectors
These selectors are used by our design system components and should also be used for in-app styling.
Selectors should be used over the chained navigation of the theme to find the value you desire for simplicity, code readability and to protect against breakage if the theme's structure changes.
Color selectors
Color selectors are deprecated
With the introduction of design tokens, color selectors are considered deprecated. They will continue to work but do not source their values from tokens, and as such will not respond to their surrounding mode.
This is because these color selectors are not semantic and therefore would be difficult to point to a token as a sensible default value.
See tokens documentation for more information.
The most useful selectors are those that provide the colors used by the theme. These color selectors are:
Brand:
- base:
colorBrandBase
- light:
colorBrandLight
- dark:
colorBrandDark
Accent:
- accent:
colorAccent
Shades:
- black:
colorBlack
- darkest:
colorDarkest
- darker:
colorDarker
- dark:
colorDark
- light:
colorLight
- lighter:
colorLighter
- lightest:
colorLightest
- white:
colorWhite
Product:
- hospital:
colorHospital
- extras:
colorExtras
- combined:
colorCombined
- hightlightBg:
colorHighlightBg
- hightlightText:
colorHighlightText
Focus state selectors
We provide selectors for our standard focus styling across each brand. These selectors are:
- outlineColor:
focusOutlineColor
- outlineStyle:
focusOutlineStyle
- outlineWidth:
focusOutlineWidth
- outlineOffset:
focusOutlineOffset
These can be used to add our standard styling to the focus state of custom components:
&:focus-visible {outline: ${focusOutlineWidth} ${focusOutlineStyle} ${focusOutlineColor};outline-offset: ${focusOutlineOffset};}
We also provide an equivalent shorthand utility for applying a standard focus style to interactive elements:
&:focus-visible {${standardFocusStyleDeclarations};}
Whitelabelling
Pulling styling information from the theme helps us to keep our pages consistent and provides us the added benefit of being able to swap out different themes to support multiple brands.
Currently, we have themes to support the following brands:
- nib (
nib
) - GU Health (
gu
) - IMAN (
iman
)
Colors
Each whitelabelled theme has a set of colors that are suitable for key uses across each brand. Pulling color directly from the theme ensures that it will work across all brands, as the colors housed within the theme are more limited but referred to by universal names.
- nib
- GU
- IMAN
nib colors
Brand Base
Brand Light
Brand Dark
Accent
Black
Darkest
Darker
Dark
Light
Lighter
Lightest
White
ModeProvider
In v7.0.0
a new ModeProvider
component was introduced to allow for the setting of a mode for a subtree of components.
Check out the ModeProvider docs for usage and guidelines.
token
A "token getter" function. The token
function is typed to enable autocomplete and typescript errors when invalid token paths are provided.
The token
function has a second parameter to provide a fallback value if the token cannot be found for whatever reason. During the initial migration to tokens it is recommended that fallbacks be provided for all token references. The fallback can be a string or a selector:
import {token, colorWhite} from '@nib-components/theme';const Component = styled.div`background-color: ${token('theme.color.bg.surface', colorWhite)};color: ${token('theme.color.fg', '#444')};padding: ${token('common.dimension.spacing.4', '1rem')};`;