A flexible library for styling React components. Intended for projects using global CSS, JSS, CSS Modules, or any other CSS in JS based library that compiles CSS classname objects.
- A higher-order React component for injecting and customizing styles.
- A provider component for supplying context themes.
- Tools for theme composition and transformation.
Install the stable version:
$ npm i --save react-themed
A plain object containing CSS classnames used by one or more React components.
The merging of two or more theme objects, where values for overlapping keys are concatenated.
const theme1 = { list: 'list', item: 'list-item' }
const theme2 = { list: 'list-inline' }
compose(theme1, theme2)
// => { list: 'list list-inline', item: 'list-item' }
The HOC provided by react-themed
can be used as a ES7 decorator, or a curried function. It allows you to inject themes into a React component (as a prop), customize themed components, and configure the wrapping component.
import themed from 'react-themed'
import styles from './Button.css'
@themed(styles)
export default ({ theme, ...props }) => (
<button {...props} className={theme.button} />
)
import themed from 'react-themed'
import styles from './Button.css'
const Button = ({ theme, ...props }) => (
<button {...props} className={theme.button} />
)
export default themed(styles)(Button)
import themed from 'react-themed'
import styles from './Button.css'
@themed(styles, {
pure: true, // extend PureComponent
propName: 'classes', // customize the prop name, defaults to "theme"
})
export default ({ classes, ...props }) => (
<button {...props} className={classes.button} />
)
Themes can be composed in the following ways:
import { compose } from 'react-themed'
import defaultStyles from './Button.css'
import primaryStyles from './ButtonPrimary.css'
export default compose({}, defaultStyles, primaryStyles)
import themed from 'react-themed'
import defaultStyles from './Button.css'
import primaryStyles from './ButtonPrimary.css'
const Button = ({ theme, ...props }) => (
<button {...props} className={theme.button} />
)
const Default = themed(defaultStyles)(Button)
const Primary = themed(primaryStyles)(Default)
import themed from 'react-themed'
import Button from './Button'
import styles from './Form.css'
const buttonStyles = {
button: styles.button,
}
export default props => (
<form className={styles.form}>
<Button theme={buttonStyles}>Submit</Button>
</form>
)
import themed from 'react-themed'
import Button from './Button'
import primaryStyles from './ButtonPrimary.css'
export default themed(prevStyles => ({
...prevStyles,
...primaryStyles,
}))(Button)
While this library does not require a specific shape for context theme objects, the following tend to work well:
// Flat
const theme = {
Button: 'button',
Button_primary: 'button-primary'
}
// Nested
const theme = {
Button: {
button: 'button',
primary: 'button-primary',
},
}
import { ThemeProvider } from 'react-themed'
const App = props => (
<ThemeProvider theme={props.theme} />
{props.children}
</ThemeProvider>
)
import themed from 'react-themed'
const Button = ({ theme, ...props }) => (
<button {...props} className={theme.Button} />
)
// select entire context theme
themed('*')(Button)
// select single classname (or nested theme)
themed('Button')(Button)
// select multiple classnames
themed(['Button', 'Button_primary'])(Button)
// select all classnames starting with "Button"
themed(/^Button/)(Button)
import themed from 'react-themed'
import styles from './Button.css'
@themed((prevTheme, contextTheme) => ({
...contextTheme.Button,
...styles,
}))
export default ({ theme, ...props }) => (
<button {...props} className={theme.button} />
)
Adds theme to a React component context, making it available to themed()
calls.
theme
(Object|Function): Can be either a theme object, or a function that receives a previously added theme, and is expected to return the final theme to use.compose
(Bool): Indicates whether the theme should be composed with previously added themes (does not apply to function themes). Defaults totrue
.
Creates a new HOC for generating a Themed
component.
theme
(Object|String|Array|Function): The theme to bind to the component. Can be either a plain object, a string/array for selecting context theme(s), or a function that receives the previously assigned theme (if any) and context theme (if any), and is expected to return the final theme to use.options
(Object): Configures the default options for theThemed
component.propName
(String): The name of the prop that receives the theme, defaults totheme
.pure
(Bool): Indicates the component should inherit fromPureComponent
.compose
(Func): Specifies the default function to use when composing themes.mergeProps(ownProps, themeProps): props
(Function): If specified, it is passed the parent props and theme props, and is expected to return a merged object to pass as props to the wrapped component.
Creates a new themed
function that uses a customized set of default options when generating themed components.
options
(Object): The options to merge into the previous default options.
The themed component created by the themed
decorator.
theme
(Object|String|Array|Function): A theme or context theme (selector) that should be composed with the previous theme, or a function that customizes the previous theme.childRef
(Function*): Specifies a ref callback function to pass to the wrapped component.
Recursively merges theme objects by concatenating values for overlapping keys, and copies result into a target object.
MIT