react-themeable-ts
A CommonJS/ES2015/ES2017 module, inspired by react-themeable and react-themr.
Features:
- Written in typescript and typings are auto generated.
- Unlike
react-themeable
does not handlekey
in returned payload at all. That means that radium users must manually supplykey
to their react elements. You are better off using react-themeable instead. - Main function theme parameter can be empty, in case you do conditional stuff and it ends up being falsely.
- You may mix classnames and style objects, they will be merged in the order you specify the arguments.
- Fully memoized if you use it in combination with the higher order component decorator. That means it's really fast on re-renders, as it only calculates if the
theme
prop changes. - Allows you to do conditional classes if you wrap an object with an array, that is because an object will be used as a
style
prop payload. All other argument payload types will be passed to classname module.
Usage
<MyComponent theme=theme />
Install
npm -S i react-themeable-ts
Or
yarn
Usage
react-themeable-ts
exports themeable
and internal function typescript interfaces.
This function is designed to accept a theme
prop inside of your render
method. This then returns a small helper function that accepts a series of style names.
const theme = ;...<div ... />
This helper function detects whether a theme is class or style based, and creates the appropriate attributes for you.
These attributes are either a style
object or classname
string depending on the payload.
For example:
;; { const theme = ; return <div ...> <div ...>Foo Bar</div> <div ...>Baz</div> </div> ; }
A theme can now be passed to your component like so:
className
prop to elements
CSS Modules - maps to MyComponentTheme.css
;...<MyComponent theme=theme />
Aphrodite
; const theme = StyleSheet;...<MyComponent theme= theme css />
React Style
; const theme = StyleSheet;...<MyComponent theme=theme />
JSS
Import jss from 'jss'; const sheet = jss;...<MyComponent theme=sheetclasses />
Global CSS
const theme = root: 'MyComponent__root' foo: 'MyComponent__foo' bar: 'MyComponent__bar';...<MyComponent theme=theme />
Inline styles
const theme = root: color: 'black' foo: color: 'red' bar: color: 'blue' ;...<MyComponent theme=theme />
HOC - Higher order component
When decorating a stateless function/Class the defaults are:
theme
prop will accept the classes/stylest
prop will become the resulting function invoked withthemeable(props.theme)
from above.- The themable function will be memoized and will return a new function if only the main
theme
object changes. The returning themeable function is in turn also memoized and will not compute unless argument changed which was not already memoized.
Examples:
Defaults
;; @ { const theme = thispropst; return <div ...> <span ...> My test component </span> <p ...> My test component </p> </div> ; } ; // Component usedconst MyJSXElement = <MyComponent theme= root: 'class-root' span1: 'class-span1' p1: 'class-p1' >;
With custom options
;; @ { const theme = thispropsmyThemeableFn; return <div ...> <span ...> My test component </span> <p ...> My test component </p> </div> ; } ; // Component usedconst MyJSXElement = <MyComponent customThemeProp= root: 'class-root' span1: 'class-span1' p1: 'class-p1' >;
ThemeProvider - Wrapper component
Optional HOC you can use if you feel like globally handling themes via React context.
It accepts one single prop reactThemeable
as an object which you can freely nest however you please.
Examples:
;; { return <ThemeProvider reactThemeable= ComponentWithContext2: root: 'class-root' span1: 'class-span1' p1: 'class-p1' > propschildren </ThemeProvider> ; } // Any component can then access the context for example:; const MyStatelessComponent = { const theme = ; return <div ...> My content </div> ;};MyStatelessComponentcontextTypes = reactThemeable: PropTypesobjectisRequired;
Usage with HOC:
;; // First decorate a component with HOCconst decoratorFn = ; const MyStatelessComponent = { const t = props; return <div ...> <span ...> My test SFC component </span> <p ...> My test SFC component </p> </div> ;};MyStatelessComponentcontextTypes = reactThemeable: PropTypesobjectisRequired; const MyDecoratedComponent = ; // Then use in theme provider// This works because the HOC comes with contextTypes enabled for prop reactThemeable.PureComponent { return <ThemeProvider reactThemeable= ComponentWithContext2: root: 'class-root' span1: 'class-span1' p1: 'class-p1' > <MyDecoratedComponent /> </ThemeProvider> ; }
API
themeable
- Main function
;// Or without react as dependency// import { themeable } from 'react-themeable-ts/themeable';
Accepts any number of comma-separated values.
Also accepts nothing, in case you do conditional stuff and it ends up being falsely.
The falsely values will be omitted and string values will be mapped to either className
string or style
object and then merged in order you specify the arguments.
Examples:
className
const theme = root: 'root-class' elephant: ''; const t = ; ;// {// className: 'root-class'// } ;// {// className: 'root-class'// }
style
const theme = root: color: 'red' display: 'none' ; const t = ; ;// {// style: {// color: 'red',// display: 'none'// }// } ;// {// style: {// color: 'red',// display: 'none'// }// }
Advanced className
and style
and conditional mix, the real power of the library.
;
themeDecorator
- HOC
;
Accepts single argument and is an object with props:
Parameter | Default | Type | Description |
---|---|---|---|
themeKey(optional) | theme |
string |
The prop the HOC will use as argument for themeable. |
themeProp(optional) | t |
string |
The prop name passed prop to DecoratedComponent as the returned themeable function. |
memoizeeOpts(optional) | { length: 1, max: 10 } |
Object | options passed to memoizee function. |
contextPath(optional) | undefined | string /string[] |
If truthy will be used as a path variable to navigate in context and will override themeKey . It accepts lodash.get method argument to navigate in context prop. |
Contributing
Requires
npm@4.x
because ofpackage.json
-prepare
script. (only required to run hook when publish)npm -g i gulp-cli jest-cli
oryarn global add gulp-cli jest-cli
.
Usage
gulp --tasks
to get going.
Developing
jest --watchAll
to watch recompiled files and rerun tests.
Testing
Supports:
jest
, needsjest-cli
installed. it will execute the transpiled files from typescript.
Dist
gulp
will run default task which consist of running tasks:lint
,clean
,build
,minify
thenjest
and collect coverage.