Use the redux pattern to control CSS Variables. You provide redux-style reducers that set your variable values when changed, allowing you to style your app in many new ways.
At the moment, this will only operate on the top-level documentElement. If you
define variables at higher levels they will continue to take precedence. It is
handled through style.setProperty
and getComputedStyle(...).getPropertyValue
.
yarn add redux-css
or
npm install --save redux-css
import { createStore, applyMiddleware, compose } from 'redux'
import reduxCSS from 'redux-css'
import reducers from './reducers'
/*
initial styles are the variables that we should set immediately.
Note that '--' is optional, it will be added for you if you don't
include it.
*/
const initialStyles = {
primaryBG: '#303641',
navbarHeight: '55px',
navbarPaddingTop: '0px'
}
const styleReducer = (vars = initialStyles, action, state) => {
switch(action.type) {
case 'DEVICE_ORIENTATION': {
return {
...vars,
navbarHeight: action.orientation === 'portrait'
? '55px'
: '50px',
navbarPaddingTop: action.orientation === 'portrait'
: '5px'
: '0px'
}
}
}
return vars
}
const configureStore = (initialState = {}) => {
// exposes: css.getVariable, css.setVariable, css.removeVariable, css.middleware
const {
middleware: cssMiddleware,
...css
} = reduxCSS(
// our style reducers
styleReducer
)
const enhancers = compose(
applyMiddleware(
cssMiddleware
)
)
const store = createStore(
reducers,
initialState,
enhancers
)
return { store, css }
}
/*navbar.css*/
:root {
/* optionally provide fallback values */
--primaryBG: "#303641";
--navbarHeight: 50px;
--navbarPaddingTop: 5px;
}
.navbar-container {
background-color: var(--primaryBG);
height: var(--navbarHeight);
padding-top: var(--navbarPaddingTop);
}
Set a CSS Variable if changed from it's current value. Returns the previous value of the variable (if any).
css.setVariable("primaryBG", "#303641");
Take an Object Literal and sets each of its keys as CSS Variables with their values.
css.setAllVariables({
primaryBG: "#303641",
secondaryBG: "#121519"
});
Gets the given CSS Variables current value.
const primaryBG = css.getVariable("primaryBG");
Gets all of the current variables. Currently this only captures the variables that redux-css is handling.
const variables = css.getAllVariables();
Remove the given CSS Variable.
css.removeVariable("navbarPadding");
Redux CSS Middleware to be passed to redux.
applyMiddleware(css.middleware);
If you are using postcss-cssnext or postcss-custom-properties then you will want to set your configuration:
// postcss.config.js
module.exports = {
plugins: [
require("postcss-cssnext")({
features: {
customProperties: {
preserve: true
}
}
})
]
};