@teleporthq/teleport-plugin-react-jss 0.20.0 → 0.21.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/src/index.ts CHANGED
@@ -9,18 +9,24 @@
9
9
 
10
10
  import * as types from '@babel/types'
11
11
  import { StringUtils, UIDLUtils } from '@teleporthq/teleport-shared'
12
- import { ASTUtils, ASTBuilders, ParsedASTNode } from '@teleporthq/teleport-plugin-common'
12
+ import {
13
+ ASTUtils,
14
+ ASTBuilders,
15
+ ParsedASTNode,
16
+ StyleBuilders,
17
+ } from '@teleporthq/teleport-plugin-common'
13
18
  import {
14
19
  ComponentPluginFactory,
15
20
  ComponentPlugin,
16
21
  ChunkType,
17
22
  FileType,
18
23
  PluginReactJSS,
24
+ UIDLElementNodeInlineReferencedStyle,
19
25
  } from '@teleporthq/teleport-types'
20
26
  import {
21
27
  generateStylesFromStyleObj,
22
28
  createStylesHookDecleration,
23
- generateStylesFromStyleSetDefinitions,
29
+ generateProjectStyleSheet,
24
30
  convertMediaAndStylesToObject,
25
31
  } from './utils'
26
32
  import { createStyleSheetPlugin } from './style-sheet'
@@ -48,25 +54,38 @@ export const createReactJSSPlugin: ComponentPluginFactory<JSSConfig> = (config)
48
54
  const reactJSSPlugin: ComponentPlugin = async (structure) => {
49
55
  const { uidl, chunks, dependencies, options } = structure
50
56
  const { projectStyleSet } = options
51
- const { node, styleSetDefinitions: componentStyleSheet = {} } = uidl
57
+ const { node, styleSetDefinitions: componentStyleSheet = {}, propDefinitions = {} } = uidl
52
58
 
53
59
  const componentChunk = chunks.find((chunkItem) => chunkItem.name === componentChunkName)
54
60
  if (!componentChunk) {
55
61
  return structure
56
62
  }
57
63
 
58
- const jssStyleMap: Record<string, unknown> = {}
59
- const mediaStyles: Record<string, Record<string, unknown>> = {}
64
+ const jssStyleMap: Array<Record<string, unknown>> = []
65
+ const mediaStyles: Record<string, Array<{ [x: string]: Record<string, string | number> }>> = {}
60
66
  const tokensUsed: string[] = []
61
67
 
62
68
  const propsPrefix = componentChunk.meta.dynamicRefPrefix.prop as string
63
- const jsxNodesLookup = componentChunk.meta.nodesLookup || {}
69
+ const jsxNodesLookup: Record<string, types.JSXElement> =
70
+ (componentChunk.meta.nodesLookup as Record<string, types.JSXElement>) || {}
64
71
  let isProjectReferenced: boolean = false
65
72
  const propsUsed: string[] = []
66
73
 
67
74
  UIDLUtils.traverseElements(node, (element) => {
68
- const { style, key, referencedStyles } = element
69
- if (!style && !referencedStyles) {
75
+ const { style, key, referencedStyles, dependency, attrs = {} } = element
76
+ if (dependency?.type === 'local') {
77
+ StyleBuilders.setPropValueForCompStyle({
78
+ attrs,
79
+ key,
80
+ jsxNodesLookup,
81
+ getClassName,
82
+ })
83
+ }
84
+
85
+ if (
86
+ Object.keys(style || {}).length === 0 &&
87
+ Object.keys(referencedStyles || {}).length === 0
88
+ ) {
70
89
  return
71
90
  }
72
91
 
@@ -75,7 +94,7 @@ export const createReactJSSPlugin: ComponentPluginFactory<JSSConfig> = (config)
75
94
  return
76
95
  }
77
96
 
78
- const className = StringUtils.camelCaseToDashCase(key)
97
+ const className = getClassName(key)
79
98
  const classNamesToAppend: Set<types.MemberExpression | types.Identifier> = new Set()
80
99
  const nodeStyleIdentifier = types.memberExpression(
81
100
  types.identifier(styleObjectImportName),
@@ -84,7 +103,7 @@ export const createReactJSSPlugin: ComponentPluginFactory<JSSConfig> = (config)
84
103
  )
85
104
 
86
105
  if (Object.keys(style || {}).length > 0) {
87
- jssStyleMap[className] = generateStylesFromStyleObj(style, tokensUsed, propsUsed)
106
+ jssStyleMap.push({ [className]: generateStylesFromStyleObj(style, tokensUsed, propsUsed) })
88
107
  classNamesToAppend.add(nodeStyleIdentifier)
89
108
  }
90
109
 
@@ -100,25 +119,32 @@ export const createReactJSSPlugin: ComponentPluginFactory<JSSConfig> = (config)
100
119
  }
101
120
 
102
121
  if (condition.conditionType === 'screen-size') {
103
- mediaStyles[condition.maxWidth] = {
104
- ...mediaStyles[condition.maxWidth],
122
+ if (!mediaStyles[String(condition.maxWidth)]) {
123
+ mediaStyles[String(condition.maxWidth)] = []
124
+ }
125
+
126
+ mediaStyles[String(condition.maxWidth)].push({
105
127
  [className]: generateStylesFromStyleObj(
106
128
  styleRef.content.styles,
107
129
  tokensUsed,
108
130
  propsUsed
109
131
  ),
110
- }
132
+ })
111
133
  }
112
134
 
113
135
  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
- }
136
+ const { content } = condition
137
+ jssStyleMap.find((item) => {
138
+ if (item.hasOwnProperty(className)) {
139
+ Object.assign(item[className], {
140
+ [`&:${content}`]: generateStylesFromStyleObj(
141
+ (styleRef as UIDLElementNodeInlineReferencedStyle).content.styles,
142
+ tokensUsed,
143
+ propsUsed
144
+ ),
145
+ })
146
+ }
147
+ })
122
148
  }
123
149
 
124
150
  classNamesToAppend.add(nodeStyleIdentifier)
@@ -152,6 +178,18 @@ export const createReactJSSPlugin: ComponentPluginFactory<JSSConfig> = (config)
152
178
  true
153
179
  )
154
180
  )
181
+
182
+ const defaultPropValue = propDefinitions[classContent.content.id]?.defaultValue
183
+ if (!defaultPropValue) {
184
+ return
185
+ }
186
+ /*
187
+ Changing the default value of the prop.
188
+ When forceScoping is enabled the classnames change. So, we need to change the default prop too.
189
+ */
190
+ propDefinitions[classContent.content.id].defaultValue = getClassName(
191
+ String(defaultPropValue)
192
+ )
155
193
  }
156
194
 
157
195
  if (
@@ -161,7 +199,7 @@ export const createReactJSSPlugin: ComponentPluginFactory<JSSConfig> = (config)
161
199
  classNamesToAppend.add(
162
200
  types.memberExpression(
163
201
  types.identifier(styleObjectImportName),
164
- types.identifier(`'${classContent.content.id}'`),
202
+ types.identifier(`'${getClassName(classContent.content.id)}'`),
165
203
  true
166
204
  )
167
205
  )
@@ -192,7 +230,7 @@ export const createReactJSSPlugin: ComponentPluginFactory<JSSConfig> = (config)
192
230
  classNamesToAppend.add(
193
231
  types.memberExpression(
194
232
  types.identifier('projectStyles'),
195
- types.identifier(`'${content.referenceId}'`),
233
+ types.identifier(`'${getClassName(content.referenceId)}'`),
196
234
  true
197
235
  )
198
236
  )
@@ -201,11 +239,7 @@ export const createReactJSSPlugin: ComponentPluginFactory<JSSConfig> = (config)
201
239
  }
202
240
  default: {
203
241
  throw new PluginReactJSS(`
204
- We support only inlined and project-referenced styles as of now, received ${JSON.stringify(
205
- styleRef.content,
206
- null,
207
- 2
208
- )}
242
+ Un-supported stlyle reference received ${JSON.stringify(styleRef.content, null, 2)}
209
243
  `)
210
244
  }
211
245
  }
@@ -219,14 +253,12 @@ export const createReactJSSPlugin: ComponentPluginFactory<JSSConfig> = (config)
219
253
  )
220
254
  })
221
255
 
222
- if (Object.keys(componentStyleSheet).length > 0) {
223
- generateStylesFromStyleSetDefinitions({
224
- styleSetDefinitions: componentStyleSheet,
225
- styleSet: jssStyleMap,
226
- mediaStyles,
227
- tokensUsed,
228
- })
229
- }
256
+ generateProjectStyleSheet({
257
+ styleSetDefinitions: componentStyleSheet,
258
+ jssStyleMap,
259
+ mediaStyles,
260
+ tokensUsed,
261
+ })
230
262
 
231
263
  const { content: astContent } = componentChunk
232
264
  const parser = new ParsedASTNode(astContent)
@@ -265,7 +297,7 @@ export const createReactJSSPlugin: ComponentPluginFactory<JSSConfig> = (config)
265
297
  )
266
298
  }
267
299
 
268
- if (!Object.keys(jssStyleMap).length && !Object.keys(mediaStyles).length) {
300
+ if (jssStyleMap.length === 0 && Object.keys(mediaStyles).length === 0) {
269
301
  return structure
270
302
  }
271
303
 
@@ -306,3 +338,5 @@ export const createReactJSSPlugin: ComponentPluginFactory<JSSConfig> = (config)
306
338
  export { createStyleSheetPlugin }
307
339
 
308
340
  export default createReactJSSPlugin()
341
+
342
+ const getClassName = (str: string) => StringUtils.dashCaseToCamelCase(str)
@@ -7,7 +7,7 @@ import {
7
7
  FileType,
8
8
  } from '@teleporthq/teleport-types'
9
9
  import { StringUtils } from '@teleporthq/teleport-shared'
10
- import { generateStylesFromStyleSetDefinitions, convertMediaAndStylesToObject } from './utils'
10
+ import { convertMediaAndStylesToObject, generateProjectStyleSheet } from './utils'
11
11
 
12
12
  interface StyleSheetPlugin {
13
13
  fileName?: string
@@ -33,12 +33,12 @@ export const createStyleSheetPlugin: ComponentPluginFactory<StyleSheetPlugin> =
33
33
  {}
34
34
  )
35
35
 
36
- const styleSet: Record<string, unknown> = {}
37
- const mediaStyles: Record<string, Record<string, unknown>> = {}
36
+ const jssStyleMap: Array<Record<string, unknown>> = []
37
+ const mediaStyles: Record<string, Array<{ [x: string]: Record<string, string | number> }>> = {}
38
38
  if (Object.keys(styleSetDefinitions).length > 0) {
39
- generateStylesFromStyleSetDefinitions({
39
+ generateProjectStyleSheet({
40
40
  styleSetDefinitions,
41
- styleSet,
41
+ jssStyleMap,
42
42
  mediaStyles,
43
43
  })
44
44
  }
@@ -72,7 +72,7 @@ export const createStyleSheetPlugin: ComponentPluginFactory<StyleSheetPlugin> =
72
72
  })
73
73
  }
74
74
 
75
- if (Object.keys(styleSet).length > 0) {
75
+ if (jssStyleMap.length > 0) {
76
76
  chunks.push({
77
77
  name: fileName,
78
78
  type: ChunkType.AST,
@@ -82,7 +82,7 @@ export const createStyleSheetPlugin: ComponentPluginFactory<StyleSheetPlugin> =
82
82
  types.variableDeclarator(
83
83
  types.identifier('useProjectStyles'),
84
84
  types.callExpression(types.identifier('createUseStyles'), [
85
- convertMediaAndStylesToObject(styleSet, mediaStyles),
85
+ convertMediaAndStylesToObject(jssStyleMap, mediaStyles),
86
86
  ])
87
87
  ),
88
88
  ])
package/src/utils.ts CHANGED
@@ -3,49 +3,50 @@ import { StringUtils, UIDLUtils } from '@teleporthq/teleport-shared'
3
3
  import { ParsedASTNode, ASTBuilders, ASTUtils } from '@teleporthq/teleport-plugin-common'
4
4
  import { UIDLStyleSetDefinition, UIDLStyleValue } from '@teleporthq/teleport-types'
5
5
 
6
- export const generateStylesFromStyleSetDefinitions = (params: {
6
+ export const generateProjectStyleSheet = (params: {
7
7
  styleSetDefinitions: Record<string, UIDLStyleSetDefinition>
8
- styleSet: Record<string, unknown>
9
- mediaStyles: Record<string, Record<string, unknown>>
8
+ jssStyleMap: Array<Record<string, unknown>>
9
+ mediaStyles: Record<string, Array<{ [x: string]: Record<string, string | number> }>>
10
10
  tokensUsed?: string[]
11
- formatClassName?: boolean
12
11
  }) => {
13
- const {
14
- styleSetDefinitions,
15
- styleSet,
16
- tokensUsed,
17
- formatClassName = false,
18
- mediaStyles = {},
19
- } = params
12
+ const { styleSetDefinitions = {}, jssStyleMap, tokensUsed, mediaStyles = {} } = params
20
13
  Object.keys(styleSetDefinitions).forEach((styleId) => {
21
14
  const style = styleSetDefinitions[styleId]
22
- const className = formatClassName ? StringUtils.dashCaseToCamelCase(styleId) : styleId
15
+ const className = StringUtils.dashCaseToCamelCase(styleId)
23
16
  const { conditions = [], content } = style
24
- styleSet[className] = generateStylesFromStyleObj(content, tokensUsed)
17
+ jssStyleMap.push({ [className]: generateStylesFromStyleObj(content, tokensUsed) })
25
18
 
26
19
  if (conditions.length > 0) {
27
- conditions.forEach((styleRef) => {
28
- if (Object.keys(styleRef.content).length === 0) {
20
+ conditions.forEach(({ content: styleContent, meta, type }) => {
21
+ if (Object.keys(styleContent).length === 0) {
29
22
  return
30
23
  }
31
- if (styleRef.type === 'screen-size') {
32
- mediaStyles[styleRef.meta.maxWidth] = {
33
- ...mediaStyles[styleRef.meta.maxWidth],
34
- [className]: generateStylesFromStyleObj(styleRef.content, tokensUsed),
24
+
25
+ if (type === 'screen-size') {
26
+ if (!mediaStyles[String(meta.maxWidth)]) {
27
+ mediaStyles[String(meta.maxWidth)] = []
35
28
  }
36
- }
37
29
 
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
- },
30
+ if (style.type === 'reusable-component-style-map') {
31
+ mediaStyles[String(meta.maxWidth)].unshift({
32
+ [className]: generateStylesFromStyleObj(styleContent, tokensUsed),
33
+ })
34
+ } else {
35
+ mediaStyles[String(meta.maxWidth)].push({
36
+ [className]: generateStylesFromStyleObj(styleContent, tokensUsed),
37
+ })
47
38
  }
48
39
  }
40
+
41
+ if (type === 'element-state') {
42
+ jssStyleMap.find((item) => {
43
+ if (style.hasOwnProperty(className)) {
44
+ Object.assign(item[className], {
45
+ [`&:${meta.state}`]: generateStylesFromStyleObj(styleContent, tokensUsed),
46
+ })
47
+ }
48
+ })
49
+ }
49
50
  })
50
51
  }
51
52
  })
@@ -93,19 +94,30 @@ export const createStylesHookDecleration = (
93
94
  ])
94
95
 
95
96
  export const convertMediaAndStylesToObject = (
96
- styleSet: Record<string, unknown>,
97
- mediaStyles: Record<string, Record<string, unknown>>
97
+ jssStyleMap: Array<Record<string, unknown>>,
98
+ mediaStyles: Record<string, Array<{ [x: string]: Record<string, string | number> }>>
98
99
  ): types.ObjectExpression => {
99
- const styles = ASTUtils.objectToObjectExpression(styleSet)
100
+ const styles = ASTUtils.objectToObjectExpression(convertArraytoObject(jssStyleMap))
100
101
 
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])
102
+ Object.keys(mediaStyles)
103
+ .map((id) => Number(id))
104
+ .sort((a, b) => b - a)
105
+ .forEach((mediaOffset) => {
106
+ styles.properties.push(
107
+ types.objectProperty(
108
+ types.identifier(`'@media(max-width: ${mediaOffset}px)'`),
109
+ ASTUtils.objectToObjectExpression(
110
+ convertArraytoObject(mediaStyles[String(mediaOffset)] || [])
111
+ )
112
+ )
106
113
  )
107
- )
108
- }, [])
114
+ }, [])
109
115
 
110
116
  return styles
111
117
  }
118
+
119
+ const convertArraytoObject = (list: Array<Record<string, unknown>>): Record<string, unknown> =>
120
+ list.reduce((acc, item) => {
121
+ Object.assign(acc, item)
122
+ return acc
123
+ }, {})