jsx()
Addon
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
h
of your virtual DOM library when creating anano-css
instance. In case of React, this is thecreateElement
function: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 aref
to 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:
cache
rule()
Read more about the Addon Installation.