# Custom Component Generator
All the preconfigured component generators are exposing an instance of the teleport-component-generator
package. Naturally, you can install the package and build your own generator with plugins, mappings and postprocessors.
Let's configure a React
component generator that uses styled-components
and formats all code with prettier
:
First install the dependencies:
npm install @teleporthq/teleport-component-generator
npm install @teleporthq/teleport-plugin-react-base-component
npm install @teleporthq/teleport-plugin-react-styled-components
npm install @teleporthq/teleport-plugin-import-statements
npm install @teleporthq/teleport-postprocessor-prettier-js
TIP
teleport-plugin-import-statements
will handle all the import statements that need to be generated, both from local dependencies as well as project or lib dependencies
Then, we import all dependencies and we create the component generator, using the factory, a named export from the module:
import { createComponentGenerator } from '@teleporthq/teleport-component-generator'
import reactPlugin from '@teleporthq/teleport-plugin-react-base-component'
import styledComponentsPlugin from '@teleporthq/teleport-plugin-react-styled-components'
import importStatementsPlugin from '@teleporthq/teleport-plugin-import-statements'
import prettierJS from '@teleporthq/teleport-postprocessor-prettier-js'
const generator = createComponentGenerator()
Next, we have to consider any specific mapping for React. By default, the teleport-component-generator
performs a mapping from the abstract UIDL elements to HTML elements.
Jump to the mappings section to better understand the structure of a mapping file. A React mapping could look like this:
{
"elements": {
"group": {
"elementType": "Fragment",
"dependency": {
"type": "library",
"path": "react",
"meta": {
"namedImport": true
}
}
}
}
}
The official React
mapping is maintained inside teleport-component-generator-react
(opens new window)
Add the mapping:
import reactMapping from './react-mapping.json'
generator.addMapping(reactMapping)
TIP
You can add as many mappings as you wish on one generator, they will override the elements and events that were previously mapped with the same key.
Next, we can add all our plugins to the existing generator. Note that the order of the plugins is important as they will be run in sequence on the input UIDL:
generator.addPlugin(reactPlugin)
generator.addPlugin(styledComponentsPlugin)
generator.addPlugin(importStatementsPlugin)
WARNING
The plugins are called in the exact order in which they are added. The import
statements plugins hence should be the last one added, to take into consideration all the dependencies added by all the previous plugins. Also the framework base component should naturally be the first one added, since it is generating the initial chunks in the pipeline.
Finally, we can add the post-processors:
generator.addPostProcessor(prettierJS)
Now, we can test the generator. Considering the following UIDL:
{
"name": "React Component",
"node": {
"type": "element",
"content": {
"elementType": "container",
"children": [
{
"type": "element",
"content": {
"elementType": "text",
"style": {
"color": {
"type": "static",
"content": "red"
}
},
"children": [
{
"type": "static",
"content": "World!"
}
]
}
}
]
}
}
}
calling the generator:
await generator.generateComponent(uidl)
should yield:
import React from 'react'
import styled from 'styled-components'
const ReactComponent = (props) => {
return (
<div>
<Text>World!</Text>
</div>
)
}
export default ReactComponent
const Text = styled.span`
color: red;
`
Here's the full running code snippet:
import { createComponentGenerator } from '@teleporthq/teleport-component-generator'
import reactPlugin from '@teleporthq/teleport-plugin-react-base-component'
import styledComponentsPlugin from '@teleporthq/teleport-plugin-react-styled-components'
import importStatementsPlugin from '@teleporthq/teleport-plugin-import-statements'
import prettierJS from '@teleporthq/teleport-postprocessor-prettier-js'
import reactMapping from './react-mapping.json'
import uidl from './uidl.json'
const generator = createComponentGenerator()
generator.addMapping(reactMapping)
generator.addPlugin(reactPlugin)
generator.addPlugin(styledComponentsPlugin)
generator.addPlugin(importStatementsPlugin)
generator.addPostProcessor(prettierJS)
const run = async() => {
const result = await generator.generateComponent(uidl)
console.log(result.files[0])
}
If you want to play with a similar configuration, you can check out this codesandbox (opens new window), where you can edit the input UIDL, the mapping, or just try out different plugins and post-processors.