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>
You can pass components as an element type.
const Button = jsx(MyComp, css);
where
const MyComp = (props) => {
return <button {...props} />
};
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} />;
};
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
});
Simply install jsx
addon and its dependencies:
cache
rule()
Read more about the Addon Installation.