FelaComponent is an alternative component to the createComponent-HoC leveraging the render-props pattern. It uses FelaTheme internally in order to access the theme directly.
| Property | Type | Default | Description |
|---|---|---|---|
| style | Rule StyleObject Array[Rule, StyleObject] |
Either a valid style object, and rule or an array of both | |
| children | any | Either a render function or a primitive child. If passing a render function is receives the specified render interface. |
|
| as | string | div |
If children is passed a primitive child, the component will render an as-type DOM element with the className attached and the primitive child as content. |
| Property | Type | Default | Description |
|---|---|---|---|
| className | string | The class names for the rendered style object | |
| children | Element | The component children | |
| theme | Object | {} |
The theme object which is passed down via context |
| as | string | div |
The as property that is passed to the component |
import { FelaComponent } from 'react-fela'
import { FelaComponent } from 'preact-fela'
import { FelaComponent } from 'inferno-fela'<FelaComponent
style={{
backgroundColor: 'blue',
color: 'red'
}}>
{({ className, theme }) => (
<div className={className}>I am red on blue.</div>
)}
</FelaComponent>In order to create dynamically styled components using props, just like createComponent, we can create a component that itself renders a FelaComponent.
const Button = ({ color, big = false, text }) => (
<FelaComponent
style={{
backgroundColor: color,
fontSize: big ? 18 : 15
}}>
{({ className }) => (
<button className={className}>{text}</button>
)}
</FelaComponent>
)To access theme properties, we can simply pass a function of theme.
const style = ({ theme }) => ({
backgroundColor: theme.bgPrimary,
color: 'red'
})
<FelaComponent style={rule}>
{({ className, theme }) => (
<div className={className}>I am red on {theme.bgPrimary}.</div>
)}
/>Sometimes it is desirable to style a component as a function of both theme and
props. The style prop takes a callback, and passes it an object with theme
and all props passed to FelaComponent except style and children.
This provides an API that is both compatible with createComponent, and allows using an externally defined function in such use cases. Hopefully, this can be help performance in hot paths by not requiring a function to be created on every render.
const rule = ({ theme, bgc }) => ({
backgroundColor: bgc || 'red',
color: theme.bgPrimary,
})
<FelaComponent bgc='blue' style={rule}>
{({ className, theme }) => (
<div className={className}>I am {theme.bgPrimary} on {bgc || 'red'}.</div>
)}
/>Instead of a render function, we can also specify a primitive element to render into.
Children will automatically be passed down. If not specified at all, it will render into a div.
<FelaComponent
style={{
backgroundColor: 'blue',
color: 'red'
}}
as='span'
>
I am red on blue
</FelaComponent>In order to compose multiple FelaComponents we can't just concatenate classNames as they might overwrite each other due to the atomic CSS design and specificity.
We have to use a built-in API to correctly combine those rules and styles: combineRules.
With FelaComponent we can leverage that API automatically by passing an array to the style prop.
const baseStyle = {
backgroundColor: 'red',
fontSize: 15
}
const Button = ({ style, ...props }) => (
<FelaComponent style={[baseStyle, style]} {...props} as="button" />
)
const ExtendedButton = ({ style, children }) => (
<Button style={{ color: 'blue' }}>Click</Button>
)The array accepts both style objects, rule functions and even nested arrays again.