In order to use animus with your custom theme you must redeclare the emotion global Theme
.
import { theme } from './theme';export type ThemeShape = typeof theme;declare module '@emotion/react' {export interface Theme extends ThemeShape {}}
To help you create this strongly typed theme we've provided a few helpers to make it easier to progressively create a strongly typed and dynamic theme that will adhere to the correct types.
This method is a set of chainable methods that will progressively add tokens, relationships, and core features to a theme object.
While many frameworks restrict theme scales to very specific sets we leave many of the particulars up to the user to define as the only key that we require for baseline functionality is breakpoints
.
We do however offer optional but opinionated handling of both colors
+ colorModes
.
import { createTheme } from '@animus-ui/theming';import { AnimusProvider } from '@animus-ui/components';export const theme = createTheme({breakpoints: {xs: '@media screen and (min-width: 480px)',sm: '@media screen and (min-width: 768px)',md: '@media screen and (min-width: 1024px)',lg: '@media screen and (min-width: 1200px)',xl: '@media screen and (min-width: 1440px)',},spacing: {4: '0.25rem',8: '0.5rem',12: '0.75rem',16: '1rem',},}).addColors({white: '#ffffff',hyper: '3A10E5',navy: '#10162f',yellow: '#FFD300',}).createColorModes('light', {light: {primary: 'hyper',secondary: 'navy',text: 'navy',background: 'white',},dark: {primary: 'yellow',secondary: 'white',text: 'white',background: 'navy',},}).addVariables('spacing').build();
A theme creator method that progressively build and decorate a type safe theme object. This allows us to create a build separate themes that will be compatible with animus props. The raw theme must have a valid breakpoint scale to ensure breakpoint variable serialization.
Standard Methods - These are the core methods to add scales and variables to the theme object
addScale(scaleKey, updateFunction)
- Adds a set of tokens to the theme on the provided scale key. The current theme can be used as reference for this new scale for shared value reference.updateScale(scaleKey, updateFunction)
- Updates an existing scale with new or computed value without them being explicitly declared. This can also be used to update or extend a theme for a different context (restrictions or expansions).createScaleVariables(scaleKey)
- Takes a top level key of the current theme and serialized them as CSS variables. The theme will include references to CSS Variables and adds the actual token values to the root scope of our variable object.Special Methods - these have specific behavior that is non standard, these are both required for all features to work
addColors(tokens)
- Adds color tokens to the theme and creates root color variables by default. Calling this method required to access getColorValue
and addColorModes
. You will not be able to add colors through addScale
and be able to build color modes as they have different internal behaviors. However if you do not want either features you may use it without any issue.addColorModes(initialMode, colorModes)
- This method takes a configuration of color aliases that have semantic meaning between contexts such as light
and dark
modes. This will take a map of modes and an initial mode.
addColors
to ensure this works correctly.Finalization
build()
- Called when all mutations are finished and we get the finalized and fully typed design system objects.These are some under the hood utilities that you can use outside of root theme creation. createTheme
may use some of these internally but they can also be used independently.
tokens
any set of tokens.prefix
a string to prefix any tokenstheme
to reference existing tokens specifically for breakpoints.This method predictably maps token literal values to CSS variables. We use this to store relational or contextual information in a single reference.
const { tokens, variables } = serializeTokens({black: '#000000',white: '#FFFFFF'}, 'color', {});// tokens{ black: 'var(--color-black)', white: 'var(--color-white)' }// variables{ '--color-black': '#000000', '--color-white': '#FFFFFF' };
This will also work with possible nested selectors like breakpoints:
const {tokens, //An object of the same keys as the first argument but with values that point to variable referencesvariables // Valid CSS variables that are prefixed with the same keys.} = serializeTokens({height: { _: '4rem', lg: '5rem' },}, 'header', theme);// tokens{ height: 'var(--header-height)' }// variables{'--header-height': '4rem','@media screen and (min-width: 1024px)': {'--header-height': '5rem',}}
To use your new theme you must do 3 things.
import { theme } from './theme';import { AnimusProvider } from '@animus-ui/components';export type ThemeShape = typeof theme;declare module '@emotion/react' {export interface Theme extends ThemeShape {}}const App = () => {return (<AnimusProvider theme={theme}><Component /></AnimusProvider>);};