CommonDOMRenderer
by default supports functional components:
1linkconst style = raise => `
2link display: inline-block;
3link width: 200px;
4link background: white;
5link margin: 8px; padding: 8px;
6link border-radius: 3px;
7link box-shadow: 0 ${raise}px ${raise * 3}px rgba(0, 0, 0, .2)
8link`;
9link
10linkexport function Card(props, renderer, children) {
11link const raise = props?.raise || 1;
12link return <div style={style(raise)}>
13link {children}
14link </div>;
15link}
1linkimport { CommonDOMRenderer } from 'render-jsx/dom';
2linkimport { Card } from './card'; // @see [Component](tab:Component)
3link
4linkconst renderer = new CommonDOMRenderer();
5link
6linkrenderer.render(<div>
7link <Card>Hellow <i>World!</i></Card>
8link <Card raise={4}>Goodbye <b>Blue Sky!</b></Card>
9link</div>).on(document.body);
info IMPORTANT
For most JSX transpilers, component names MUST start with uppercase letters, as otherwise the tag will be interpreted by the transpiler as a string tag.
So this is wrong:
1linkfunction component(_, renderer) { ... }2link/*~*/<component/>~~~~~~~~~~~~/*~*/But this is correct:
1linkfunction Component(_, renderer) { ... }2link<Component/>
info IMPORTANT
Note that your component functions MUST always have a second argument named
renderer
, as otherwise the JSX in your component scope cannot be transpiled.So this is wrong:
1linkfunction Component() {2link return /*~*/<div>~~~~~hellow~~~~~~</div>~~~~~~/*~*/3link}But this is correct:
1linkfunction Component(_, renderer) {2link return <div>hellow</div>3link}
For slotting other DOM elements into your components, you can
simply use props
:
1linkconst style = raise => `
2link display: inline-block;
3link width: 200px;
4link background: white;
5link margin: 8px; padding: 8px;
6link border-radius: 3px;
7link box-shadow: 0 ${raise}px ${raise * 3}px rgba(0, 0, 0, .2)
8link`;
9link
10linkexport function Card(props, renderer, children) {
11link const raise = props?.raise || 1;
12link return <div style={style(raise)}>
13link {children}
14link {
15link props?.actions?
16link <div style='text-align: right'>{props.actions}</div>
17link :''
18link }
19link </div>;
20link}
1linkimport { CommonDOMRenderer } from 'render-jsx/dom';
2linkimport { Card } from './card'; // @see [Component](tab:Component)
3link
4linkconst renderer = new CommonDOMRenderer();
5link
6linkrenderer.render(<div>
7link <Card actions={
8link <button onclick={() => alert('Hellow')}>Say Hi</button>
9link }>
10link Hellow <i>World!</i>
11link </Card>
12link</div>).on(document.body);
Sometimes you want your components to return a group of DOM elements
without wrapping them inside a container element. For example, your
component might want to return a bunch of columns (td
elements)
that should sit inside a bigger table.
For this situation, you can use fragments (<>...</>
):
1linkexport function Columns(_, renderer) {
2link return <>
3link <td>Hellow</td>
4link <td>World</td>
5link </>
6link}
1linkimport { CommonDOMRenderer } from 'render-jsx/dom';
2linkimport { Columns } from './columns'; // @see [Component](tab:Component)
3link
4linkconst renderer = new CommonDOMRenderer();
5link
6linkrenderer.render(<table>
7link <tr><Columns/></tr>
8link</table>).on(document.body);