JSX for Substance writer.
This library allows usage of regular JSX syntax with Newspilot Writer's flavor of Substance (a react fork).
render($$) {
// substance with JSX
return (
<div>
<MyComponent />
</div>
);
}
// vs
// regular substance element creation
render($$) {
const el = $$('div');
el.append(MyComponent);
return el;
}
- Differing from React, Substance requires each component to return a regular HTML DOM node as the root element from the
render
method. Seediv
element in the previous example.
render($$) {
// Will not work, root HTML element missing.
return (
<MyComponent />
);
}
This is a feature of substance, and there's nothing il-substance-jsx
can do to circumvent it.
- Substance uses render method's parameter
$$
for element creation. Because of this, the variable$$
needs to be available when using JSX.
- Install
il-substance-jsx
. - Set JSX pragma to use the custom
dom
function. - In code, import the custom
dom
function, used by JSX pragma.
This module:
npm install --save-dev git+ssh://[email protected]/almamedia/il-substance-jsx.git
Other modules:
npm install --save-dev babel babel-plugin-transform-react-jsx
This module:
yarn add git+ssh://[email protected]/almamedia/il-substance-jsx.git
Other modules:
yarn add babel babel-plugin-transform-react-jsx
Babel plugin transform-react-jsx
allows parsing JSX, and setting a different pragma for parsing JSX.
By default transform-react-jsx
uses React.createElement
as the pragma that is used to transform JSX into regular javascript.
As a relatively little known feature, its possible to configure the plugin to use a different JSX pragma, than the default React.createElement
.
In order to transform JSX defined elements into Substance's element structure, the JSX pragma needs to point to a custom transformation function. In this case that function is dom.bind({$$})
(no spaces allowed).
This can be done in two ways:
- In
.babelrc
config file (for whole project). - With
@jsx
pragma definition comment (for each file separately).
In .babelrc
, add the following first level object to the configuration:
{
"plugins": [
["transform-react-jsx", {
"pragma": "dom.bind({$$})"
}]
]
}
More information can be found in the plugin's documentation.
If you don't want to use .babelrc
, or don't want to set the pragma globally, you can also set it in each file separately.
This step needs to be done for each file separately.
The following comment specifies that in this file, the pragma will use function dom
for parsing JSX (dom
is defined in the next step).
// Top of file, before any JSX calls.
/* @jsx dom.bind({$$}) */
As the last step, in order for the pragma to be able to call the mapping function dom
, the file with JSX in it needs to import the function.
This needs to be done in every file, just like you would import react
in every file, when you want to use jsx with react.
// in the beginning of the file
import 'dom' from 'il-substance-jsx';
- This library is tested using Infomaker's Newspilot writer's flavor of Substance. It might differ from vanilla Substance.
- Only the basic functionality of JSX is currently implemented. Feel free to submit issue, if any bugs arise.