jsx() Addon
March 20, 2018 · View on GitHub
jsx() is a 5th generation
interface for creating styling blocks — components similar to "styled components",
but which are more powerful.
const Button = jsx('button', {
display: 'inline-block',
borderRadius: '3px',
padding: '0.5rem 0',
margin: '0.5rem 1rem',
width: '11rem',
background: 'transparent',
color: 'white',
border: '2px solid white',
});
<Button>Click me!</Button>
Nota Bene
To use this interface you need to provide the hyperscript function
hof your virtual DOM library when creating anano-cssinstance. In case of React, this is thecreateElementfunction:import {create} from 'nano-css'; import {createElement} from 'react'; const nano = create({ h: createElement });
Optionally, you can name your styling block:
const Button = jsx('button', css, 'MyButton');
Styling blocks pass all their props to the underlying element:
<Button
disabled
aria-label="something"
onClick={() => {}}
>
Click me!
</Button>
However, some props have special meaning and are not passed through:
css— a CSS-like object of dynamic style overrides$as— allows to overwrite the underlying element type$ref— allows to pass arefto the underlying element
Add custom styling:
<Button css={{background: primary ? 'blue' : 'grey'}}>Click me!</Button>
Overwrite underlying element type:
<Button $as='a'>Click me!</Button>
// <a>Click me!</a>
Component as a Type
You can pass components as an element type.
const Button = jsx(MyComp, css);
where
const MyComp = (props) => {
return <button {...props} />
};
Composition
The above feature of passing component as a type allows you to do composition.
const BaseButton = jsx('button', {
color: 'red',
border: '1px solid red',
});
const SmallButton = jsx(BaseButton, {
fontSize: '11px',
});
However, composition of styling blocks is not something that is encouraged, instead you might
consider using dynamic styling css prop:
const BaseButton = jsx('button', {
color: 'red',
border: '1px solid red',
});
const Button = (props) => {
const {small, ...rest} = props;
const css = {};
if (small) {
css.fontSize = '11px';
}
return <BaseButton {...rest} css={css} />;
};
Changing Element Type
Let's say you created a <button> component like so.
const Button = jsx('button', {
display: 'inline-block',
borderRadius: '3px',
padding: '0.5rem 0',
margin: '0.5rem 1rem',
width: '11rem',
background: 'transparent',
color: 'white',
border: '2px solid white',
});
But you wanted to have the same looking button, which used <a> tag instead.
Just wrap it in another component and overwrite the $as prop.
const Link = (props) => Button({
...props,
$as: 'a'
});
<Link>Click me!</Link>
// <a>Click me!</a>
Other libraries provide a method like withComponent:
const Link = withComponent(Button, 'a');
You can make one yourself:
const withComponent = (styledComp, comp) => (props) => styledComp({
...props,
$as: comp
});
Installation
Simply install jsx addon and its dependencies:
cacherule()
Read more about the Addon Installation.