@teleporthq/teleport-plugin-react-jss 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +14 -0
- package/__tests__/component-referenced.ts +88 -0
- package/__tests__/index.ts +57 -0
- package/__tests__/mocks.ts +35 -0
- package/__tests__/referenced-styles.ts +118 -0
- package/__tests__/style-sheet.ts +122 -0
- package/dist/cjs/index.d.ts +14 -0
- package/dist/cjs/index.js +247 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/style-sheet.d.ts +6 -0
- package/dist/cjs/style-sheet.js +129 -0
- package/dist/cjs/style-sheet.js.map +1 -0
- package/dist/cjs/tsconfig.tsbuildinfo +1 -0
- package/dist/cjs/utils.d.ts +12 -0
- package/dist/cjs/utils.js +93 -0
- package/dist/cjs/utils.js.map +1 -0
- package/dist/esm/index.d.ts +14 -0
- package/dist/esm/index.js +224 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/style-sheet.d.ts +6 -0
- package/dist/esm/style-sheet.js +106 -0
- package/dist/esm/style-sheet.js.map +1 -0
- package/dist/esm/tsconfig.tsbuildinfo +1 -0
- package/dist/esm/utils.d.ts +12 -0
- package/dist/esm/utils.js +67 -0
- package/dist/esm/utils.js.map +1 -0
- package/package.json +33 -0
- package/src/index.ts +302 -0
- package/src/style-sheet.ts +97 -0
- package/src/utils.ts +111 -0
- package/tsconfig.json +9 -0
package/src/index.ts
ADDED
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
/*
|
|
2
|
+
teleport-plugin-react-jss
|
|
3
|
+
|
|
4
|
+
Plugin is responsible for generating styles from
|
|
5
|
+
- Styles defined on individual nodes.
|
|
6
|
+
- Styles defined in the project's global stylesheet.
|
|
7
|
+
- Styles present in the component style sheeet.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import * as types from '@babel/types'
|
|
11
|
+
import { StringUtils, UIDLUtils } from '@teleporthq/teleport-shared'
|
|
12
|
+
import { ASTUtils, ASTBuilders, ParsedASTNode } from '@teleporthq/teleport-plugin-common'
|
|
13
|
+
import {
|
|
14
|
+
ComponentPluginFactory,
|
|
15
|
+
ComponentPlugin,
|
|
16
|
+
ChunkType,
|
|
17
|
+
FileType,
|
|
18
|
+
PluginReactJSS,
|
|
19
|
+
} from '@teleporthq/teleport-types'
|
|
20
|
+
import {
|
|
21
|
+
generateStylesFromStyleObj,
|
|
22
|
+
createStylesHookDecleration,
|
|
23
|
+
generateStylesFromStyleSetDefinitions,
|
|
24
|
+
convertMediaAndStylesToObject,
|
|
25
|
+
} from './utils'
|
|
26
|
+
import { createStyleSheetPlugin } from './style-sheet'
|
|
27
|
+
|
|
28
|
+
interface JSSConfig {
|
|
29
|
+
styleChunkName?: string
|
|
30
|
+
importChunkName?: string
|
|
31
|
+
componentChunkName: string
|
|
32
|
+
jssDeclarationName?: string
|
|
33
|
+
classAttributeName?: string
|
|
34
|
+
styleObjectImportName?: string
|
|
35
|
+
}
|
|
36
|
+
const EXPORT_IDENTIFIER = 'createUseStyles'
|
|
37
|
+
|
|
38
|
+
export const createReactJSSPlugin: ComponentPluginFactory<JSSConfig> = (config) => {
|
|
39
|
+
const {
|
|
40
|
+
componentChunkName = 'jsx-component',
|
|
41
|
+
importChunkName = 'import-local',
|
|
42
|
+
styleChunkName = 'jss-style-definition',
|
|
43
|
+
jssDeclarationName = 'useStyles',
|
|
44
|
+
classAttributeName = 'className',
|
|
45
|
+
styleObjectImportName = 'classes',
|
|
46
|
+
} = config || {}
|
|
47
|
+
|
|
48
|
+
const reactJSSPlugin: ComponentPlugin = async (structure) => {
|
|
49
|
+
const { uidl, chunks, dependencies, options } = structure
|
|
50
|
+
const { projectStyleSet } = options
|
|
51
|
+
const { node, styleSetDefinitions: componentStyleSheet = {} } = uidl
|
|
52
|
+
|
|
53
|
+
const componentChunk = chunks.find((chunkItem) => chunkItem.name === componentChunkName)
|
|
54
|
+
if (!componentChunk) {
|
|
55
|
+
return structure
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const jssStyleMap: Record<string, unknown> = {}
|
|
59
|
+
const mediaStyles: Record<string, Record<string, unknown>> = {}
|
|
60
|
+
const tokensUsed: string[] = []
|
|
61
|
+
|
|
62
|
+
const propsPrefix = componentChunk.meta.dynamicRefPrefix.prop as string
|
|
63
|
+
const jsxNodesLookup = componentChunk.meta.nodesLookup || {}
|
|
64
|
+
let isProjectReferenced: boolean = false
|
|
65
|
+
const propsUsed: string[] = []
|
|
66
|
+
|
|
67
|
+
UIDLUtils.traverseElements(node, (element) => {
|
|
68
|
+
const { style, key, referencedStyles } = element
|
|
69
|
+
if (!style && !referencedStyles) {
|
|
70
|
+
return
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const jsxTag = jsxNodesLookup[key] as types.JSXElement
|
|
74
|
+
if (!jsxTag) {
|
|
75
|
+
return
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const className = StringUtils.camelCaseToDashCase(key)
|
|
79
|
+
const classNamesToAppend: Set<types.MemberExpression | types.Identifier> = new Set()
|
|
80
|
+
const nodeStyleIdentifier = types.memberExpression(
|
|
81
|
+
types.identifier(styleObjectImportName),
|
|
82
|
+
types.identifier(`'${className}'`),
|
|
83
|
+
true
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
if (Object.keys(style || {}).length > 0) {
|
|
87
|
+
jssStyleMap[className] = generateStylesFromStyleObj(style, tokensUsed, propsUsed)
|
|
88
|
+
classNamesToAppend.add(nodeStyleIdentifier)
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (referencedStyles && Object.keys(referencedStyles || {}).length > 0) {
|
|
92
|
+
Object.values(referencedStyles).forEach((styleRef) => {
|
|
93
|
+
switch (styleRef.content.mapType) {
|
|
94
|
+
case 'inlined': {
|
|
95
|
+
const { conditions } = styleRef.content
|
|
96
|
+
const [condition] = conditions
|
|
97
|
+
|
|
98
|
+
if (Object.keys(styleRef.content.styles || {}).length === 0) {
|
|
99
|
+
return
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (condition.conditionType === 'screen-size') {
|
|
103
|
+
mediaStyles[condition.maxWidth] = {
|
|
104
|
+
...mediaStyles[condition.maxWidth],
|
|
105
|
+
[className]: generateStylesFromStyleObj(
|
|
106
|
+
styleRef.content.styles,
|
|
107
|
+
tokensUsed,
|
|
108
|
+
propsUsed
|
|
109
|
+
),
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (condition.conditionType === 'element-state') {
|
|
114
|
+
jssStyleMap[className] = {
|
|
115
|
+
...(jssStyleMap[className] as Record<string, string>),
|
|
116
|
+
[`&:${condition.content}`]: generateStylesFromStyleObj(
|
|
117
|
+
styleRef.content.styles,
|
|
118
|
+
tokensUsed,
|
|
119
|
+
propsUsed
|
|
120
|
+
),
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
classNamesToAppend.add(nodeStyleIdentifier)
|
|
125
|
+
return
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
case 'component-referenced': {
|
|
129
|
+
const classContent = styleRef.content.content
|
|
130
|
+
if (classContent.type === 'static') {
|
|
131
|
+
classNamesToAppend.add(types.identifier(`'${classContent.content}'`))
|
|
132
|
+
return
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (
|
|
136
|
+
classContent.type === 'dynamic' &&
|
|
137
|
+
classContent.content.referenceType === 'prop'
|
|
138
|
+
) {
|
|
139
|
+
classNamesToAppend.add(
|
|
140
|
+
types.memberExpression(
|
|
141
|
+
types.identifier(styleObjectImportName),
|
|
142
|
+
types.memberExpression(
|
|
143
|
+
types.identifier(propsPrefix),
|
|
144
|
+
types.identifier(classContent.content.id)
|
|
145
|
+
),
|
|
146
|
+
true
|
|
147
|
+
)
|
|
148
|
+
)
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if (
|
|
152
|
+
classContent.type === 'dynamic' &&
|
|
153
|
+
classContent.content.referenceType === 'comp'
|
|
154
|
+
) {
|
|
155
|
+
classNamesToAppend.add(
|
|
156
|
+
types.memberExpression(
|
|
157
|
+
types.identifier(styleObjectImportName),
|
|
158
|
+
types.identifier(`'${classContent.content.id}'`),
|
|
159
|
+
true
|
|
160
|
+
)
|
|
161
|
+
)
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
return
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
case 'project-referenced': {
|
|
168
|
+
if (!projectStyleSet) {
|
|
169
|
+
throw new PluginReactJSS(
|
|
170
|
+
`Project Style Sheet is missing, but the node is referring to it ${JSON.stringify(
|
|
171
|
+
element,
|
|
172
|
+
null,
|
|
173
|
+
2
|
|
174
|
+
)}`
|
|
175
|
+
)
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
const { content } = styleRef
|
|
179
|
+
const referedStyle = projectStyleSet.styleSetDefinitions[content.referenceId]
|
|
180
|
+
if (!referedStyle) {
|
|
181
|
+
throw new PluginReactJSS(
|
|
182
|
+
`Style used from global stylesheet is missing - ${content.referenceId}`
|
|
183
|
+
)
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
classNamesToAppend.add(
|
|
187
|
+
types.memberExpression(
|
|
188
|
+
types.identifier('projectStyles'),
|
|
189
|
+
types.identifier(`'${content.referenceId}'`),
|
|
190
|
+
true
|
|
191
|
+
)
|
|
192
|
+
)
|
|
193
|
+
isProjectReferenced = true
|
|
194
|
+
return
|
|
195
|
+
}
|
|
196
|
+
default: {
|
|
197
|
+
throw new PluginReactJSS(`
|
|
198
|
+
We support only inlined and project-referenced styles as of now, received ${JSON.stringify(
|
|
199
|
+
styleRef.content,
|
|
200
|
+
null,
|
|
201
|
+
2
|
|
202
|
+
)}
|
|
203
|
+
`)
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
})
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
ASTUtils.addMultipleDynamicAttributesToJSXTag(
|
|
210
|
+
jsxTag,
|
|
211
|
+
classAttributeName,
|
|
212
|
+
Array.from(classNamesToAppend)
|
|
213
|
+
)
|
|
214
|
+
})
|
|
215
|
+
|
|
216
|
+
if (Object.keys(componentStyleSheet).length > 0) {
|
|
217
|
+
generateStylesFromStyleSetDefinitions({
|
|
218
|
+
styleSetDefinitions: componentStyleSheet,
|
|
219
|
+
styleSet: jssStyleMap,
|
|
220
|
+
mediaStyles,
|
|
221
|
+
tokensUsed,
|
|
222
|
+
})
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
const { content: astContent } = componentChunk
|
|
226
|
+
const parser = new ParsedASTNode(astContent)
|
|
227
|
+
|
|
228
|
+
const astNode = (parser.ast as types.VariableDeclaration)
|
|
229
|
+
.declarations[0] as types.VariableDeclarator
|
|
230
|
+
if (astNode.type === 'VariableDeclarator') {
|
|
231
|
+
const isPropsInjected = (astNode.init as types.ArrowFunctionExpression).params?.some(
|
|
232
|
+
(prop: types.Identifier) => prop.name === propsPrefix
|
|
233
|
+
)
|
|
234
|
+
if (!isPropsInjected && propsUsed.length > 0) {
|
|
235
|
+
;(astNode.init as types.ArrowFunctionExpression).params.push(types.identifier(propsPrefix))
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
if (tokensUsed.length > 0) {
|
|
240
|
+
dependencies.TOKENS = {
|
|
241
|
+
type: 'local',
|
|
242
|
+
path: `${projectStyleSet.path}${projectStyleSet.fileName}`,
|
|
243
|
+
meta: {
|
|
244
|
+
namedImport: true,
|
|
245
|
+
},
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
if (isProjectReferenced) {
|
|
250
|
+
dependencies.useProjectStyles = {
|
|
251
|
+
type: 'local',
|
|
252
|
+
path: `${projectStyleSet.path}${projectStyleSet.fileName}`,
|
|
253
|
+
meta: {
|
|
254
|
+
namedImport: true,
|
|
255
|
+
},
|
|
256
|
+
}
|
|
257
|
+
;((astNode.init as types.ArrowFunctionExpression).body as types.BlockStatement).body.unshift(
|
|
258
|
+
createStylesHookDecleration('projectStyles', 'useProjectStyles')
|
|
259
|
+
)
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
if (!Object.keys(jssStyleMap).length && !Object.keys(mediaStyles).length) {
|
|
263
|
+
return structure
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
;((astNode.init as types.ArrowFunctionExpression).body as types.BlockStatement).body.unshift(
|
|
267
|
+
propsUsed.length > 0
|
|
268
|
+
? createStylesHookDecleration(styleObjectImportName, 'useStyles', propsPrefix)
|
|
269
|
+
: createStylesHookDecleration(styleObjectImportName, 'useStyles')
|
|
270
|
+
)
|
|
271
|
+
|
|
272
|
+
dependencies[EXPORT_IDENTIFIER] = {
|
|
273
|
+
type: 'package',
|
|
274
|
+
path: 'react-jss',
|
|
275
|
+
version: '10.4.0',
|
|
276
|
+
meta: {
|
|
277
|
+
namedImport: true,
|
|
278
|
+
},
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
chunks.push({
|
|
282
|
+
type: ChunkType.AST,
|
|
283
|
+
fileType: FileType.JS,
|
|
284
|
+
name: styleChunkName,
|
|
285
|
+
linkAfter: [importChunkName],
|
|
286
|
+
content: ASTBuilders.createConstAssignment(
|
|
287
|
+
jssDeclarationName,
|
|
288
|
+
types.callExpression(types.identifier(EXPORT_IDENTIFIER), [
|
|
289
|
+
convertMediaAndStylesToObject(jssStyleMap, mediaStyles),
|
|
290
|
+
])
|
|
291
|
+
),
|
|
292
|
+
})
|
|
293
|
+
|
|
294
|
+
return structure
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
return reactJSSPlugin
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
export { createStyleSheetPlugin }
|
|
301
|
+
|
|
302
|
+
export default createReactJSSPlugin()
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import * as types from '@babel/types'
|
|
2
|
+
import { ASTUtils } from '@teleporthq/teleport-plugin-common'
|
|
3
|
+
import {
|
|
4
|
+
ComponentPlugin,
|
|
5
|
+
ComponentPluginFactory,
|
|
6
|
+
ChunkType,
|
|
7
|
+
FileType,
|
|
8
|
+
} from '@teleporthq/teleport-types'
|
|
9
|
+
import { StringUtils } from '@teleporthq/teleport-shared'
|
|
10
|
+
import { generateStylesFromStyleSetDefinitions, convertMediaAndStylesToObject } from './utils'
|
|
11
|
+
|
|
12
|
+
interface StyleSheetPlugin {
|
|
13
|
+
fileName?: string
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const createStyleSheetPlugin: ComponentPluginFactory<StyleSheetPlugin> = (config) => {
|
|
17
|
+
const { fileName } = config || { fileName: 'style' }
|
|
18
|
+
const styleSheetPlugin: ComponentPlugin = async (structure) => {
|
|
19
|
+
const { uidl, chunks, dependencies } = structure
|
|
20
|
+
const { styleSetDefinitions = {}, designLanguage: { tokens = {} } = {} } = uidl
|
|
21
|
+
|
|
22
|
+
if (Object.keys(styleSetDefinitions).length === 0 && Object.keys(tokens).length === 0) {
|
|
23
|
+
return structure
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const tokensMap: Record<string, string | number> = Object.keys(tokens || {}).reduce(
|
|
27
|
+
(acc: Record<string, string | number>, key: string) => {
|
|
28
|
+
const style = tokens[key]
|
|
29
|
+
const name: string = StringUtils.capitalize(StringUtils.dashCaseToCamelCase(key))
|
|
30
|
+
acc[name] = style.content as string
|
|
31
|
+
return acc
|
|
32
|
+
},
|
|
33
|
+
{}
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
const styleSet: Record<string, unknown> = {}
|
|
37
|
+
const mediaStyles: Record<string, Record<string, unknown>> = {}
|
|
38
|
+
if (Object.keys(styleSetDefinitions).length > 0) {
|
|
39
|
+
generateStylesFromStyleSetDefinitions({
|
|
40
|
+
styleSetDefinitions,
|
|
41
|
+
styleSet,
|
|
42
|
+
mediaStyles,
|
|
43
|
+
})
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
uidl.outputOptions = uidl.outputOptions || {}
|
|
47
|
+
uidl.outputOptions.fileName = fileName
|
|
48
|
+
|
|
49
|
+
dependencies.createUseStyles = {
|
|
50
|
+
type: 'package',
|
|
51
|
+
path: 'react-jss',
|
|
52
|
+
version: '10.4.0',
|
|
53
|
+
meta: {
|
|
54
|
+
namedImport: true,
|
|
55
|
+
},
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (Object.keys(tokens).length > 0) {
|
|
59
|
+
chunks.push({
|
|
60
|
+
name: 'tokens-chunk',
|
|
61
|
+
type: ChunkType.AST,
|
|
62
|
+
fileType: FileType.JS,
|
|
63
|
+
content: types.exportNamedDeclaration(
|
|
64
|
+
types.variableDeclaration('const', [
|
|
65
|
+
types.variableDeclarator(
|
|
66
|
+
types.identifier('TOKENS'),
|
|
67
|
+
ASTUtils.objectToObjectExpression(tokensMap)
|
|
68
|
+
),
|
|
69
|
+
])
|
|
70
|
+
),
|
|
71
|
+
linkAfter: ['import-local'],
|
|
72
|
+
})
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (Object.keys(styleSet).length > 0) {
|
|
76
|
+
chunks.push({
|
|
77
|
+
name: fileName,
|
|
78
|
+
type: ChunkType.AST,
|
|
79
|
+
fileType: FileType.JS,
|
|
80
|
+
content: types.exportNamedDeclaration(
|
|
81
|
+
types.variableDeclaration('const', [
|
|
82
|
+
types.variableDeclarator(
|
|
83
|
+
types.identifier('useProjectStyles'),
|
|
84
|
+
types.callExpression(types.identifier('createUseStyles'), [
|
|
85
|
+
convertMediaAndStylesToObject(styleSet, mediaStyles),
|
|
86
|
+
])
|
|
87
|
+
),
|
|
88
|
+
])
|
|
89
|
+
),
|
|
90
|
+
linkAfter: ['tokens-chunk'],
|
|
91
|
+
})
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return structure
|
|
95
|
+
}
|
|
96
|
+
return styleSheetPlugin
|
|
97
|
+
}
|
package/src/utils.ts
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import * as types from '@babel/types'
|
|
2
|
+
import { StringUtils, UIDLUtils } from '@teleporthq/teleport-shared'
|
|
3
|
+
import { ParsedASTNode, ASTBuilders, ASTUtils } from '@teleporthq/teleport-plugin-common'
|
|
4
|
+
import { UIDLStyleSetDefinition, UIDLStyleValue } from '@teleporthq/teleport-types'
|
|
5
|
+
|
|
6
|
+
export const generateStylesFromStyleSetDefinitions = (params: {
|
|
7
|
+
styleSetDefinitions: Record<string, UIDLStyleSetDefinition>
|
|
8
|
+
styleSet: Record<string, unknown>
|
|
9
|
+
mediaStyles: Record<string, Record<string, unknown>>
|
|
10
|
+
tokensUsed?: string[]
|
|
11
|
+
formatClassName?: boolean
|
|
12
|
+
}) => {
|
|
13
|
+
const {
|
|
14
|
+
styleSetDefinitions,
|
|
15
|
+
styleSet,
|
|
16
|
+
tokensUsed,
|
|
17
|
+
formatClassName = false,
|
|
18
|
+
mediaStyles = {},
|
|
19
|
+
} = params
|
|
20
|
+
Object.keys(styleSetDefinitions).forEach((styleId) => {
|
|
21
|
+
const style = styleSetDefinitions[styleId]
|
|
22
|
+
const className = formatClassName ? StringUtils.dashCaseToCamelCase(styleId) : styleId
|
|
23
|
+
const { conditions = [], content } = style
|
|
24
|
+
styleSet[className] = generateStylesFromStyleObj(content, tokensUsed)
|
|
25
|
+
|
|
26
|
+
if (conditions.length > 0) {
|
|
27
|
+
conditions.forEach((styleRef) => {
|
|
28
|
+
if (Object.keys(styleRef.content).length === 0) {
|
|
29
|
+
return
|
|
30
|
+
}
|
|
31
|
+
if (styleRef.type === 'screen-size') {
|
|
32
|
+
mediaStyles[styleRef.meta.maxWidth] = {
|
|
33
|
+
...mediaStyles[styleRef.meta.maxWidth],
|
|
34
|
+
[className]: generateStylesFromStyleObj(styleRef.content, tokensUsed),
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (styleRef.type === 'element-state') {
|
|
39
|
+
styleSet[className] = {
|
|
40
|
+
...((styleSet[className] as Record<string, unknown>) || {}),
|
|
41
|
+
...{
|
|
42
|
+
[`&:${styleRef.meta.state}`]: generateStylesFromStyleObj(
|
|
43
|
+
styleRef.content,
|
|
44
|
+
tokensUsed
|
|
45
|
+
),
|
|
46
|
+
},
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
})
|
|
50
|
+
}
|
|
51
|
+
})
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export const generateStylesFromStyleObj = (
|
|
55
|
+
style: Record<string, UIDLStyleValue>,
|
|
56
|
+
tokensUsed?: string[],
|
|
57
|
+
propsUsed?: string[]
|
|
58
|
+
) => {
|
|
59
|
+
return UIDLUtils.transformDynamicStyles(style, (styleValue) => {
|
|
60
|
+
switch (styleValue.content.referenceType) {
|
|
61
|
+
case 'prop':
|
|
62
|
+
propsUsed?.push(styleValue.content.id)
|
|
63
|
+
return new ParsedASTNode(
|
|
64
|
+
ASTBuilders.createArrowFunctionWithMemberExpression('props', styleValue.content.id)
|
|
65
|
+
)
|
|
66
|
+
case 'token':
|
|
67
|
+
const token = StringUtils.capitalize(StringUtils.dashCaseToCamelCase(styleValue.content.id))
|
|
68
|
+
tokensUsed?.push(token)
|
|
69
|
+
return new ParsedASTNode(
|
|
70
|
+
types.memberExpression(types.identifier('TOKENS'), types.identifier(token))
|
|
71
|
+
)
|
|
72
|
+
default:
|
|
73
|
+
throw new Error(
|
|
74
|
+
`Error running transformDynamicStyles in reactJSSComponentStyleChunksPlugin. Unsupported styleValue.content.referenceType value ${styleValue.content.referenceType}`
|
|
75
|
+
)
|
|
76
|
+
}
|
|
77
|
+
})
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export const createStylesHookDecleration = (
|
|
81
|
+
assignee: string,
|
|
82
|
+
hookName: string,
|
|
83
|
+
dynamicValueIdentifier?: string
|
|
84
|
+
) =>
|
|
85
|
+
types.variableDeclaration('const', [
|
|
86
|
+
types.variableDeclarator(
|
|
87
|
+
types.identifier(assignee),
|
|
88
|
+
types.callExpression(
|
|
89
|
+
types.identifier(hookName),
|
|
90
|
+
dynamicValueIdentifier ? [types.identifier(dynamicValueIdentifier)] : []
|
|
91
|
+
)
|
|
92
|
+
),
|
|
93
|
+
])
|
|
94
|
+
|
|
95
|
+
export const convertMediaAndStylesToObject = (
|
|
96
|
+
styleSet: Record<string, unknown>,
|
|
97
|
+
mediaStyles: Record<string, Record<string, unknown>>
|
|
98
|
+
): types.ObjectExpression => {
|
|
99
|
+
const styles = ASTUtils.objectToObjectExpression(styleSet)
|
|
100
|
+
|
|
101
|
+
Object.keys(mediaStyles).forEach((mediaKey: string) => {
|
|
102
|
+
styles.properties.push(
|
|
103
|
+
types.objectProperty(
|
|
104
|
+
types.identifier(`'@media(max-width: ${mediaKey}px)'`),
|
|
105
|
+
ASTUtils.objectToObjectExpression(mediaStyles[mediaKey])
|
|
106
|
+
)
|
|
107
|
+
)
|
|
108
|
+
}, [])
|
|
109
|
+
|
|
110
|
+
return styles
|
|
111
|
+
}
|