/
index.ts
62 lines (51 loc) · 2.41 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
import { StringUtils, UIDLUtils } from '@teleporthq/teleport-shared'
import { ASTUtils, StyleBuilders } from '@teleporthq/teleport-plugin-common'
import { ComponentPluginFactory, ComponentPlugin } from '@teleporthq/teleport-types'
import { generateStyledJSXTag } from './utils'
interface StyledJSXConfig {
componentChunkName: string
}
export const createReactStyledJSXPlugin: ComponentPluginFactory<StyledJSXConfig> = (config) => {
const { componentChunkName = 'jsx-component' } = config || {}
const reactStyledJSXPlugin: ComponentPlugin = async (structure) => {
const { uidl, chunks } = structure
const { node } = uidl
const componentChunk = chunks.find((chunk) => chunk.name === componentChunkName)
if (!componentChunk) {
return structure
}
const jsxNodesLookup = componentChunk.meta.nodesLookup
const propsPrefix = componentChunk.meta.dynamicRefPrefix.prop
const styleJSXString: string[] = []
UIDLUtils.traverseElements(node, (element) => {
const { style, key } = element
if (style && Object.keys(style).length > 0) {
const root = jsxNodesLookup[key]
const className = StringUtils.camelCaseToDashCase(key)
// Generating the string templates for the dynamic styles
const styleRules = UIDLUtils.transformDynamicStyles(style, (styleValue) => {
if (styleValue.content.referenceType === 'prop') {
return `\$\{${propsPrefix}.${styleValue.content.id}\}`
}
throw new Error(
`Error running transformDynamicStyles in reactStyledJSXChunkPlugin. Unsupported styleValue.content.referenceType value ${styleValue.content.referenceType}`
)
})
styleJSXString.push(StyleBuilders.createCSSClass(className, styleRules))
ASTUtils.addClassStringOnJSXTag(root, className)
}
})
if (!styleJSXString || !styleJSXString.length) {
return structure
}
const jsxASTNodeReference = generateStyledJSXTag(styleJSXString.join('\n'))
// We have the ability to insert the tag into the existig JSX structure, or do something else with it.
// Here we take the JSX <style> tag and we insert it as the last child of the JSX structure
// inside the React Component
const rootJSXNode = jsxNodesLookup[uidl.node.content.key]
rootJSXNode.children.push(jsxASTNodeReference)
return structure
}
return reactStyledJSXPlugin
}
export default createReactStyledJSXPlugin()