@teleporthq/teleport-plugin-css 0.36.0-alpha.0 → 0.36.2

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
@@ -12,6 +12,8 @@ import {
12
12
  UIDLElementNodeReferenceStyles,
13
13
  UIDLStyleMediaQueryScreenSizeCondition,
14
14
  PluginCSS,
15
+ UIDLElement,
16
+ UIDLElementNode,
15
17
  } from '@teleporthq/teleport-types'
16
18
  import { createStyleSheetPlugin } from './style-sheet'
17
19
 
@@ -21,7 +23,6 @@ interface CSSPluginConfig {
21
23
  componentDecoratorChunkName: string
22
24
  inlineStyleAttributeKey: string // style vs :style vs ...
23
25
  classAttributeName: string // class vs className
24
- forceScoping: boolean // class names get the component name prefix
25
26
  templateStyle: 'html' | 'jsx'
26
27
  declareDependency: 'import' | 'decorator' | 'none'
27
28
  dynamicVariantPrefix?: string
@@ -37,7 +38,6 @@ const createCSSPlugin: ComponentPluginFactory<CSSPluginConfig> = (config) => {
37
38
  classAttributeName = 'class',
38
39
  templateStyle = 'html',
39
40
  declareDependency = 'none',
40
- forceScoping = false,
41
41
  dynamicVariantPrefix,
42
42
  staticPropReferences = false,
43
43
  } = config || {}
@@ -71,7 +71,7 @@ const createCSSPlugin: ComponentPluginFactory<CSSPluginConfig> = (config) => {
71
71
  (chunk) => chunk.name === componentDecoratorChunkName
72
72
  )
73
73
 
74
- const templateLookup = templateChunk.meta.nodesLookup as Record<
74
+ const jsxNodesLookup = templateChunk.meta.nodesLookup as Record<
75
75
  string,
76
76
  HastNode | types.JSXElement
77
77
  >
@@ -86,27 +86,29 @@ const createCSSPlugin: ComponentPluginFactory<CSSPluginConfig> = (config) => {
86
86
  Array<{ [x: string]: Record<string, string | number> }>
87
87
  > = {}
88
88
 
89
- UIDLUtils.traverseElements(node, (element) => {
89
+ const generateStylesForElementNode = (element: UIDLElement) => {
90
90
  const classNamesToAppend: Set<string> = new Set()
91
91
  const dynamicVariantsToAppend: Set<string> = new Set()
92
92
  const {
93
93
  style = {},
94
94
  key,
95
95
  referencedStyles = {},
96
- dependency,
97
96
  attrs = {},
98
97
  elementType,
98
+ dependency,
99
99
  } = element
100
- const elementClassName = StringUtils.camelCaseToDashCase(key)
101
100
 
102
- if (forceScoping && dependency?.type === 'local') {
101
+ // Refer to line 323 all component scoped styles are appended with component name by default
102
+ if (dependency?.type === 'local') {
103
103
  StyleBuilders.setPropValueForCompStyle({
104
104
  attrs,
105
105
  key,
106
- jsxNodesLookup: templateLookup,
106
+ jsxNodesLookup,
107
107
  templateStyle,
108
+ // elementType is used here in-order to target the component name that the class is actually defined.
109
+ // Here we are appendigng to the node where the component is being called.
108
110
  getClassName: (styleName: string) =>
109
- getClassName(forceScoping, StringUtils.camelCaseToDashCase(elementType), styleName),
111
+ StringUtils.camelCaseToDashCase(elementType + styleName),
110
112
  })
111
113
  }
112
114
 
@@ -118,12 +120,18 @@ const createCSSPlugin: ComponentPluginFactory<CSSPluginConfig> = (config) => {
118
120
  return
119
121
  }
120
122
 
121
- const root = templateLookup[key]
123
+ const root = jsxNodesLookup[key]
122
124
  if (!root) {
123
- throw new PluginCSS(`Node - ${key} is missing from the template chunk`)
125
+ throw new PluginCSS(
126
+ `Element \n ${JSON.stringify(
127
+ element,
128
+ null,
129
+ 2
130
+ )} \n with key ${key} is missing from the template chunk of component ${uidl.name}`
131
+ )
124
132
  }
125
133
 
126
- const className = getClassName(forceScoping, uidl.name, elementClassName)
134
+ const className = StringUtils.camelCaseToDashCase(key)
127
135
 
128
136
  const { staticStyles, dynamicStyles, tokenStyles } =
129
137
  UIDLUtils.splitDynamicAndStaticStyles(style)
@@ -206,24 +214,21 @@ const createCSSPlugin: ComponentPluginFactory<CSSPluginConfig> = (config) => {
206
214
  propDefinitions[styleRef.content.content.content.id]?.defaultValue
207
215
 
208
216
  if (defaultPropValue) {
209
- /* Changing the default value of the prop.
210
- When forceScoping is enabled the classnames change. So, we need to change the default prop too. */
211
- propDefinitions[styleRef.content.content.content.id].defaultValue = getClassName(
212
- forceScoping,
213
- uidl.name,
214
- String(defaultPropValue)
215
- )
217
+ propDefinitions[styleRef.content.content.content.id].defaultValue =
218
+ StringUtils.camelCaseToDashCase(String(defaultPropValue))
216
219
  }
217
220
 
221
+ // staticPropReferences flag is only used for just html-code generation.
222
+ // This is used to append the class name to the node where the component is being called.
223
+ // Instead of how frameworks handle them using props at runtime. This makes the props
224
+ // to behave statically during the generation time instead by appending them directly.
218
225
  if (staticPropReferences) {
219
- if (!defaultPropValue) {
226
+ if (defaultPropValue === undefined || typeof defaultPropValue !== 'string') {
220
227
  return
221
228
  }
222
- if (staticPropReferences) {
223
- classNamesToAppend.add(
224
- getClassName(forceScoping, uidl.name, String(defaultPropValue))
225
- )
226
- }
229
+ classNamesToAppend.add(
230
+ StringUtils.camelCaseToDashCase(uidl.name + defaultPropValue)
231
+ )
227
232
  } else {
228
233
  dynamicVariantsToAppend.add(styleRef.content.content.content.id)
229
234
  }
@@ -239,7 +244,7 @@ const createCSSPlugin: ComponentPluginFactory<CSSPluginConfig> = (config) => {
239
244
  )
240
245
  }
241
246
  classNamesToAppend.add(
242
- getClassName(forceScoping, uidl.name, String(styleRef.content.content.content.id))
247
+ StringUtils.camelCaseToDashCase(uidl.name + styleRef.content.content.content.id)
243
248
  )
244
249
  }
245
250
 
@@ -300,14 +305,26 @@ const createCSSPlugin: ComponentPluginFactory<CSSPluginConfig> = (config) => {
300
305
  })
301
306
  )
302
307
  }
303
- })
308
+ }
309
+
310
+ UIDLUtils.traverseElements(node, generateStylesForElementNode)
311
+ for (const prop of Object.values(propDefinitions)) {
312
+ if (prop.type === 'element' && prop.defaultValue) {
313
+ UIDLUtils.traverseElements(
314
+ prop.defaultValue as UIDLElementNode,
315
+ generateStylesForElementNode
316
+ )
317
+ }
318
+ }
304
319
 
305
320
  if (Object.keys(componentStyleSet).length > 0) {
306
321
  StyleBuilders.generateStylesFromStyleSetDefinitions(
307
322
  componentStyleSet,
308
323
  cssMap,
309
324
  mediaStylesMap,
310
- (styleName: string) => getClassName(forceScoping, uidl.name, styleName)
325
+ (styleName: string) => {
326
+ return StringUtils.camelCaseToDashCase(uidl.name + styleName)
327
+ }
311
328
  )
312
329
  }
313
330
 
@@ -370,9 +387,3 @@ const createDynamicInlineStyle = (styles: UIDLStyleDefinitions) => {
370
387
  })
371
388
  .join(', ')
372
389
  }
373
-
374
- const getClassName = (scoping: boolean, uidlName: string, nodeStyleName: string) => {
375
- return scoping
376
- ? StringUtils.camelCaseToDashCase(`${uidlName}-${nodeStyleName}`)
377
- : StringUtils.camelCaseToDashCase(nodeStyleName)
378
- }
@@ -5,22 +5,42 @@ import {
5
5
  ChunkType,
6
6
  FileType,
7
7
  } from '@teleporthq/teleport-types'
8
+ import { join, relative } from 'path'
8
9
 
9
10
  interface StyleSheetPlugin {
10
11
  fileName?: string
12
+ /*
13
+ Frameworks with dev servers don't need relative path mapping.
14
+ */
15
+ relativeFontPath?: boolean
11
16
  }
12
17
 
13
18
  export const createStyleSheetPlugin: ComponentPluginFactory<StyleSheetPlugin> = (config) => {
14
- const { fileName } = config || { fileName: 'style' }
19
+ const { fileName = 'style', relativeFontPath = false } = config || {
20
+ fileName: 'style',
21
+ relativeFontPath: false,
22
+ }
23
+
15
24
  const styleSheetPlugin: ComponentPlugin = async (structure) => {
16
- const { uidl, chunks } = structure
25
+ const {
26
+ uidl,
27
+ chunks,
28
+ options: { assets },
29
+ } = structure
17
30
  const { styleSetDefinitions = {}, designLanguage: { tokens = {} } = {} } = uidl
31
+ const {
32
+ localFonts = [],
33
+ fontsFolder,
34
+ identifier: assetIdentifier,
35
+ } = assets || { localFonts: [] }
18
36
 
19
- if (
20
- (!styleSetDefinitions && !tokens) ||
21
- (Object.keys(styleSetDefinitions).length === 0 && Object.keys(tokens).length === 0)
22
- ) {
23
- return
37
+ const canSkipThePlugin =
38
+ localFonts?.length === 0 &&
39
+ Object.keys(styleSetDefinitions).length === 0 &&
40
+ Object.keys(tokens).length === 0
41
+
42
+ if (canSkipThePlugin) {
43
+ return structure
24
44
  }
25
45
 
26
46
  const cssMap: string[] = []
@@ -29,6 +49,35 @@ export const createStyleSheetPlugin: ComponentPluginFactory<StyleSheetPlugin> =
29
49
  Array<{ [x: string]: Record<string, string | number> }>
30
50
  > = {}
31
51
 
52
+ uidl.outputOptions = uidl.outputOptions || {}
53
+ uidl.outputOptions.styleFileName = fileName
54
+
55
+ if (localFonts.length > 0) {
56
+ localFonts.forEach((font) => {
57
+ const properties = StyleUtils.getContentOfStyleObject(font.properties) as Record<
58
+ string,
59
+ string | number
60
+ >
61
+ const format = properties?.format ? `format('${properties.format}')` : ''
62
+ /* tslint:disable:no-string-literal */
63
+ delete properties['format']
64
+
65
+ const fontPath = relativeFontPath
66
+ ? join(
67
+ relative(join(...(uidl.outputOptions?.folderPath || [])), './'),
68
+ join(fontsFolder || '', font.path)
69
+ )
70
+ : join('/', assetIdentifier || '', 'fonts', font.path)
71
+
72
+ cssMap.push(
73
+ StyleBuilders.createFontDecleration({
74
+ ...properties,
75
+ src: `url("${fontPath}") ${format}`,
76
+ })
77
+ )
78
+ })
79
+ }
80
+
32
81
  if (Object.keys(tokens).length > 0) {
33
82
  cssMap.push(
34
83
  StyleBuilders.createCSSClassWithSelector(
@@ -44,7 +93,7 @@ export const createStyleSheetPlugin: ComponentPluginFactory<StyleSheetPlugin> =
44
93
  styleSetDefinitions,
45
94
  cssMap,
46
95
  mediaStylesMap,
47
- (styleName: string) => styleName
96
+ (styleName) => styleName
48
97
  )
49
98
  }
50
99
 
@@ -54,9 +103,6 @@ export const createStyleSheetPlugin: ComponentPluginFactory<StyleSheetPlugin> =
54
103
  return structure
55
104
  }
56
105
 
57
- uidl.outputOptions = uidl.outputOptions || {}
58
- uidl.outputOptions.styleFileName = fileName
59
-
60
106
  chunks.push({
61
107
  name: fileName,
62
108
  type: ChunkType.STRING,