@teleporthq/teleport-plugin-css 0.40.0-alpha.0 → 0.40.1
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/__tests__/component-scoped.ts +4 -2
- package/__tests__/style-sheet.ts +3 -3
- package/dist/cjs/index.d.ts +0 -1
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +148 -37
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/style-sheet.d.ts +1 -0
- package/dist/cjs/style-sheet.d.ts.map +1 -1
- package/dist/cjs/style-sheet.js +41 -10
- package/dist/cjs/style-sheet.js.map +1 -1
- package/dist/cjs/tsconfig.tsbuildinfo +1 -1
- package/dist/cjs/utils.d.ts +3 -0
- package/dist/cjs/utils.d.ts.map +1 -0
- package/dist/cjs/utils.js +29 -0
- package/dist/cjs/utils.js.map +1 -0
- package/dist/esm/index.d.ts +0 -1
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +149 -38
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/style-sheet.d.ts +1 -0
- package/dist/esm/style-sheet.d.ts.map +1 -1
- package/dist/esm/style-sheet.js +41 -10
- package/dist/esm/style-sheet.js.map +1 -1
- package/dist/esm/tsconfig.tsbuildinfo +1 -1
- package/dist/esm/utils.d.ts +3 -0
- package/dist/esm/utils.d.ts.map +1 -0
- package/dist/esm/utils.js +25 -0
- package/dist/esm/utils.js.map +1 -0
- package/package.json +5 -5
- package/src/index.ts +196 -44
- package/src/style-sheet.ts +58 -12
- package/src/utils.ts +36 -0
package/src/index.ts
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { StringUtils, UIDLUtils } from '@teleporthq/teleport-shared'
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
StyleUtils,
|
|
4
|
+
StyleBuilders,
|
|
5
|
+
HASTUtils,
|
|
6
|
+
ASTUtils,
|
|
7
|
+
createBinaryExpression,
|
|
8
|
+
} from '@teleporthq/teleport-plugin-common'
|
|
3
9
|
import * as types from '@babel/types'
|
|
4
10
|
import {
|
|
5
11
|
ComponentPluginFactory,
|
|
@@ -12,8 +18,11 @@ import {
|
|
|
12
18
|
UIDLElementNodeReferenceStyles,
|
|
13
19
|
UIDLStyleMediaQueryScreenSizeCondition,
|
|
14
20
|
PluginCSS,
|
|
21
|
+
UIDLElement,
|
|
22
|
+
UIDLElementNode,
|
|
15
23
|
} from '@teleporthq/teleport-types'
|
|
16
24
|
import { createStyleSheetPlugin } from './style-sheet'
|
|
25
|
+
import { createConditionalStatement } from './utils'
|
|
17
26
|
|
|
18
27
|
interface CSSPluginConfig {
|
|
19
28
|
chunkName: string
|
|
@@ -21,7 +30,6 @@ interface CSSPluginConfig {
|
|
|
21
30
|
componentDecoratorChunkName: string
|
|
22
31
|
inlineStyleAttributeKey: string // style vs :style vs ...
|
|
23
32
|
classAttributeName: string // class vs className
|
|
24
|
-
forceScoping: boolean // class names get the component name prefix
|
|
25
33
|
templateStyle: 'html' | 'jsx'
|
|
26
34
|
declareDependency: 'import' | 'decorator' | 'none'
|
|
27
35
|
dynamicVariantPrefix?: string
|
|
@@ -37,14 +45,18 @@ const createCSSPlugin: ComponentPluginFactory<CSSPluginConfig> = (config) => {
|
|
|
37
45
|
classAttributeName = 'class',
|
|
38
46
|
templateStyle = 'html',
|
|
39
47
|
declareDependency = 'none',
|
|
40
|
-
forceScoping = false,
|
|
41
48
|
dynamicVariantPrefix,
|
|
42
49
|
staticPropReferences = false,
|
|
43
50
|
} = config || {}
|
|
44
51
|
|
|
45
52
|
const cssPlugin: ComponentPlugin = async (structure) => {
|
|
46
53
|
const { uidl, chunks, dependencies, options } = structure
|
|
47
|
-
const {
|
|
54
|
+
const {
|
|
55
|
+
node,
|
|
56
|
+
styleSetDefinitions: componentStyleSet = {},
|
|
57
|
+
propDefinitions = {},
|
|
58
|
+
stateDefinitions = {},
|
|
59
|
+
} = uidl
|
|
48
60
|
const { projectStyleSet, designLanguage: { tokens = {} } = {}, isRootComponent } = options || {}
|
|
49
61
|
const {
|
|
50
62
|
styleSetDefinitions = {},
|
|
@@ -71,7 +83,7 @@ const createCSSPlugin: ComponentPluginFactory<CSSPluginConfig> = (config) => {
|
|
|
71
83
|
(chunk) => chunk.name === componentDecoratorChunkName
|
|
72
84
|
)
|
|
73
85
|
|
|
74
|
-
const
|
|
86
|
+
const jsxNodesLookup = templateChunk.meta.nodesLookup as Record<
|
|
75
87
|
string,
|
|
76
88
|
HastNode | types.JSXElement
|
|
77
89
|
>
|
|
@@ -86,27 +98,33 @@ const createCSSPlugin: ComponentPluginFactory<CSSPluginConfig> = (config) => {
|
|
|
86
98
|
Array<{ [x: string]: Record<string, string | number> }>
|
|
87
99
|
> = {}
|
|
88
100
|
|
|
89
|
-
|
|
101
|
+
const generateStylesForElementNode = (element: UIDLElement) => {
|
|
90
102
|
const classNamesToAppend: Set<string> = new Set()
|
|
91
|
-
const dynamicVariantsToAppend: Set<string> = new Set()
|
|
103
|
+
const dynamicVariantsToAppend: Set<string | types.ConditionalExpression> = new Set()
|
|
92
104
|
const {
|
|
93
105
|
style = {},
|
|
94
106
|
key,
|
|
95
107
|
referencedStyles = {},
|
|
96
|
-
dependency,
|
|
97
108
|
attrs = {},
|
|
98
109
|
elementType,
|
|
110
|
+
dependency,
|
|
99
111
|
} = element
|
|
100
|
-
const elementClassName = StringUtils.camelCaseToDashCase(key)
|
|
101
112
|
|
|
102
|
-
|
|
113
|
+
const root = jsxNodesLookup[key]
|
|
114
|
+
if (!root) {
|
|
115
|
+
return
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Refer to line 323 all component scoped styles are appended with component name by default
|
|
119
|
+
if (dependency?.type === 'local') {
|
|
103
120
|
StyleBuilders.setPropValueForCompStyle({
|
|
104
121
|
attrs,
|
|
105
|
-
|
|
106
|
-
jsxNodesLookup: templateLookup,
|
|
122
|
+
root,
|
|
107
123
|
templateStyle,
|
|
124
|
+
// elementType is used here in-order to target the component name that the class is actually defined.
|
|
125
|
+
// Here we are appendigng to the node where the component is being called.
|
|
108
126
|
getClassName: (styleName: string) =>
|
|
109
|
-
|
|
127
|
+
StringUtils.camelCaseToDashCase(elementType + styleName),
|
|
110
128
|
})
|
|
111
129
|
}
|
|
112
130
|
|
|
@@ -118,12 +136,7 @@ const createCSSPlugin: ComponentPluginFactory<CSSPluginConfig> = (config) => {
|
|
|
118
136
|
return
|
|
119
137
|
}
|
|
120
138
|
|
|
121
|
-
const
|
|
122
|
-
if (!root) {
|
|
123
|
-
throw new PluginCSS(`Node - ${key} is missing from the template chunk`)
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
const className = getClassName(forceScoping, uidl.name, elementClassName)
|
|
139
|
+
const className = StringUtils.camelCaseToDashCase(key)
|
|
127
140
|
|
|
128
141
|
const { staticStyles, dynamicStyles, tokenStyles } =
|
|
129
142
|
UIDLUtils.splitDynamicAndStaticStyles(style)
|
|
@@ -206,24 +219,21 @@ const createCSSPlugin: ComponentPluginFactory<CSSPluginConfig> = (config) => {
|
|
|
206
219
|
propDefinitions[styleRef.content.content.content.id]?.defaultValue
|
|
207
220
|
|
|
208
221
|
if (defaultPropValue) {
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
propDefinitions[styleRef.content.content.content.id].defaultValue = getClassName(
|
|
212
|
-
forceScoping,
|
|
213
|
-
uidl.name,
|
|
214
|
-
String(defaultPropValue)
|
|
215
|
-
)
|
|
222
|
+
propDefinitions[styleRef.content.content.content.id].defaultValue =
|
|
223
|
+
StringUtils.camelCaseToDashCase(String(defaultPropValue))
|
|
216
224
|
}
|
|
217
225
|
|
|
226
|
+
// staticPropReferences flag is only used for just html-code generation.
|
|
227
|
+
// This is used to append the class name to the node where the component is being called.
|
|
228
|
+
// Instead of how frameworks handle them using props at runtime. This makes the props
|
|
229
|
+
// to behave statically during the generation time instead by appending them directly.
|
|
218
230
|
if (staticPropReferences) {
|
|
219
|
-
if (
|
|
231
|
+
if (defaultPropValue === undefined || typeof defaultPropValue !== 'string') {
|
|
220
232
|
return
|
|
221
233
|
}
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
)
|
|
226
|
-
}
|
|
234
|
+
classNamesToAppend.add(
|
|
235
|
+
StringUtils.camelCaseToDashCase(uidl.name + defaultPropValue)
|
|
236
|
+
)
|
|
227
237
|
} else {
|
|
228
238
|
dynamicVariantsToAppend.add(styleRef.content.content.content.id)
|
|
229
239
|
}
|
|
@@ -239,7 +249,7 @@ const createCSSPlugin: ComponentPluginFactory<CSSPluginConfig> = (config) => {
|
|
|
239
249
|
)
|
|
240
250
|
}
|
|
241
251
|
classNamesToAppend.add(
|
|
242
|
-
|
|
252
|
+
StringUtils.camelCaseToDashCase(uidl.name + styleRef.content.content.content.id)
|
|
243
253
|
)
|
|
244
254
|
}
|
|
245
255
|
|
|
@@ -255,7 +265,138 @@ const createCSSPlugin: ComponentPluginFactory<CSSPluginConfig> = (config) => {
|
|
|
255
265
|
)
|
|
256
266
|
}
|
|
257
267
|
|
|
258
|
-
|
|
268
|
+
if (styleRef.content.condition) {
|
|
269
|
+
if (templateStyle === 'html') {
|
|
270
|
+
const {
|
|
271
|
+
value: staticValue,
|
|
272
|
+
reference,
|
|
273
|
+
expression: { conditions, matchingCriteria },
|
|
274
|
+
} = styleRef.content.condition
|
|
275
|
+
|
|
276
|
+
const {
|
|
277
|
+
content: { referenceType, id, refPath = [] },
|
|
278
|
+
} = reference
|
|
279
|
+
|
|
280
|
+
switch (referenceType) {
|
|
281
|
+
case 'prop': {
|
|
282
|
+
const usedProp = propDefinitions[id]
|
|
283
|
+
if (usedProp === undefined || usedProp.defaultValue === undefined) {
|
|
284
|
+
throw new PluginCSS(`Prop with ${id} is missing in the propDefinitions.`)
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
let defaultValue = usedProp.defaultValue
|
|
288
|
+
for (const path of refPath) {
|
|
289
|
+
defaultValue = (defaultValue as Record<string, unknown[]>)?.[path]
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
// If defaultValue is undefined or null after path traversal, use original default
|
|
293
|
+
defaultValue = defaultValue ?? usedProp.defaultValue
|
|
294
|
+
|
|
295
|
+
// Since we know the operand and the default value from the prop.
|
|
296
|
+
// We can try building the condition and check if the condition is true or false.
|
|
297
|
+
// @todo: You can only use a 'value' in UIDL or 'conditions' but not both.
|
|
298
|
+
// UIDL validations need to be improved on this aspect.
|
|
299
|
+
const dynamicConditions = createConditionalStatement(
|
|
300
|
+
staticValue !== undefined
|
|
301
|
+
? [{ operand: staticValue, operation: '===' }]
|
|
302
|
+
: conditions,
|
|
303
|
+
defaultValue
|
|
304
|
+
)
|
|
305
|
+
const matchCondition =
|
|
306
|
+
matchingCriteria && matchingCriteria === 'all' ? '&&' : '||'
|
|
307
|
+
const conditionString = dynamicConditions.join(` ${matchCondition} `)
|
|
308
|
+
|
|
309
|
+
// tslint:disable-next-line function-constructor
|
|
310
|
+
const isConditionPassing = new Function(`return ${conditionString}`)()
|
|
311
|
+
if (isConditionPassing) {
|
|
312
|
+
classNamesToAppend.add(styleRef.content.referenceId)
|
|
313
|
+
return
|
|
314
|
+
}
|
|
315
|
+
return
|
|
316
|
+
}
|
|
317
|
+
case 'state': {
|
|
318
|
+
const usedState = stateDefinitions[id]
|
|
319
|
+
if (usedState === undefined || usedState.defaultValue === undefined) {
|
|
320
|
+
throw new PluginCSS(`State with ${id} is missing in the stateDefinitions.`)
|
|
321
|
+
}
|
|
322
|
+
let defaultValue = usedState.defaultValue
|
|
323
|
+
for (const path of refPath) {
|
|
324
|
+
defaultValue = (defaultValue as Record<string, unknown[]>)?.[path]
|
|
325
|
+
}
|
|
326
|
+
// If defaultValue is undefined or null after path traversal, use original default
|
|
327
|
+
defaultValue = defaultValue ?? usedState.defaultValue
|
|
328
|
+
// Since we know the operand and the default value from the state.
|
|
329
|
+
// We can try building the condition and check if the condition is true or false.
|
|
330
|
+
|
|
331
|
+
const dynamicConditions = createConditionalStatement(
|
|
332
|
+
staticValue !== undefined
|
|
333
|
+
? [{ operand: staticValue, operation: '===' }]
|
|
334
|
+
: conditions,
|
|
335
|
+
defaultValue
|
|
336
|
+
)
|
|
337
|
+
const matchCondition =
|
|
338
|
+
matchingCriteria && matchingCriteria === 'all' ? '&&' : '||'
|
|
339
|
+
const conditionString = dynamicConditions.join(` ${matchCondition} `)
|
|
340
|
+
// tslint:disable-next-line function-constructor
|
|
341
|
+
const isConditionPassing = new Function(`return ${conditionString}`)()
|
|
342
|
+
if (isConditionPassing) {
|
|
343
|
+
classNamesToAppend.add(styleRef.content.referenceId)
|
|
344
|
+
return
|
|
345
|
+
}
|
|
346
|
+
return
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
default: {
|
|
350
|
+
classNamesToAppend.add(styleRef.content.referenceId)
|
|
351
|
+
return
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
} else {
|
|
355
|
+
const nameToAppend = styleRef.content.condition.reference.content.id
|
|
356
|
+
|
|
357
|
+
const { conditions } = styleRef.content.condition.expression
|
|
358
|
+
|
|
359
|
+
const operator = conditions[0].operation as '===' | '!==' | '<' | '<=' | '>' | '>='
|
|
360
|
+
const right = conditions[0].operand as string | number | boolean
|
|
361
|
+
const referenceType = styleRef.content.condition.reference.content.referenceType
|
|
362
|
+
|
|
363
|
+
let binaryExpressionType = ''
|
|
364
|
+
switch (referenceType) {
|
|
365
|
+
case 'prop': {
|
|
366
|
+
binaryExpressionType = propDefinitions[nameToAppend].type
|
|
367
|
+
break
|
|
368
|
+
}
|
|
369
|
+
case 'state': {
|
|
370
|
+
binaryExpressionType = stateDefinitions[nameToAppend].type
|
|
371
|
+
break
|
|
372
|
+
}
|
|
373
|
+
default: {
|
|
374
|
+
throw new PluginCSS(
|
|
375
|
+
`Un-supported reference type ${referenceType} for ${nameToAppend}`
|
|
376
|
+
)
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
const binaryExpression = createBinaryExpression(
|
|
381
|
+
{ operation: operator, operand: right },
|
|
382
|
+
{
|
|
383
|
+
key: (referenceType === 'prop' ? 'props?.' : '') + nameToAppend,
|
|
384
|
+
type: binaryExpressionType,
|
|
385
|
+
}
|
|
386
|
+
)
|
|
387
|
+
|
|
388
|
+
const conditionalExpression = types.conditionalExpression(
|
|
389
|
+
binaryExpression,
|
|
390
|
+
types.stringLiteral(content.referenceId),
|
|
391
|
+
types.stringLiteral('')
|
|
392
|
+
)
|
|
393
|
+
|
|
394
|
+
dynamicVariantsToAppend.add(conditionalExpression)
|
|
395
|
+
return
|
|
396
|
+
}
|
|
397
|
+
} else {
|
|
398
|
+
classNamesToAppend.add(content.referenceId)
|
|
399
|
+
}
|
|
259
400
|
return
|
|
260
401
|
}
|
|
261
402
|
|
|
@@ -296,18 +437,35 @@ const createCSSPlugin: ComponentPluginFactory<CSSPluginConfig> = (config) => {
|
|
|
296
437
|
? types.identifier(dynamicVariantPrefix)
|
|
297
438
|
: types.identifier(propsPrefix)
|
|
298
439
|
|
|
299
|
-
|
|
440
|
+
if (typeof variant === 'string') {
|
|
441
|
+
return types.memberExpression(dynamicAttrValueIdentifier, types.identifier(variant))
|
|
442
|
+
} else {
|
|
443
|
+
// variant is a ConditionalExpression, so return it directly
|
|
444
|
+
return variant
|
|
445
|
+
}
|
|
300
446
|
})
|
|
301
447
|
)
|
|
302
448
|
}
|
|
303
|
-
}
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
UIDLUtils.traverseElements(node, generateStylesForElementNode)
|
|
452
|
+
for (const prop of Object.values(propDefinitions)) {
|
|
453
|
+
if (prop.type === 'element' && prop.defaultValue) {
|
|
454
|
+
UIDLUtils.traverseElements(
|
|
455
|
+
prop.defaultValue as UIDLElementNode,
|
|
456
|
+
generateStylesForElementNode
|
|
457
|
+
)
|
|
458
|
+
}
|
|
459
|
+
}
|
|
304
460
|
|
|
305
461
|
if (Object.keys(componentStyleSet).length > 0) {
|
|
306
462
|
StyleBuilders.generateStylesFromStyleSetDefinitions(
|
|
307
463
|
componentStyleSet,
|
|
308
464
|
cssMap,
|
|
309
465
|
mediaStylesMap,
|
|
310
|
-
(styleName: string) =>
|
|
466
|
+
(styleName: string) => {
|
|
467
|
+
return StringUtils.camelCaseToDashCase(uidl.name + styleName)
|
|
468
|
+
}
|
|
311
469
|
)
|
|
312
470
|
}
|
|
313
471
|
|
|
@@ -348,7 +506,7 @@ const createCSSPlugin: ComponentPluginFactory<CSSPluginConfig> = (config) => {
|
|
|
348
506
|
type: ChunkType.STRING,
|
|
349
507
|
name: chunkName,
|
|
350
508
|
fileType: FileType.CSS,
|
|
351
|
-
content: cssMap.join('\n'),
|
|
509
|
+
content: cssMap.join('\n \n'),
|
|
352
510
|
linkAfter: [],
|
|
353
511
|
})
|
|
354
512
|
}
|
|
@@ -370,9 +528,3 @@ const createDynamicInlineStyle = (styles: UIDLStyleDefinitions) => {
|
|
|
370
528
|
})
|
|
371
529
|
.join(', ')
|
|
372
530
|
}
|
|
373
|
-
|
|
374
|
-
const getClassName = (scoping: boolean, uidlName: string, nodeStyleName: string) => {
|
|
375
|
-
return scoping
|
|
376
|
-
? StringUtils.camelCaseToDashCase(`${uidlName}-${nodeStyleName}`)
|
|
377
|
-
: StringUtils.camelCaseToDashCase(nodeStyleName)
|
|
378
|
-
}
|
package/src/style-sheet.ts
CHANGED
|
@@ -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 || {
|
|
19
|
+
const { fileName = 'style', relativeFontPath = false } = config || {
|
|
20
|
+
fileName: 'style',
|
|
21
|
+
relativeFontPath: false,
|
|
22
|
+
}
|
|
23
|
+
|
|
15
24
|
const styleSheetPlugin: ComponentPlugin = async (structure) => {
|
|
16
|
-
const {
|
|
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
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
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
|
|
96
|
+
(styleName) => styleName
|
|
48
97
|
)
|
|
49
98
|
}
|
|
50
99
|
|
|
@@ -54,14 +103,11 @@ 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,
|
|
63
109
|
fileType: FileType.CSS,
|
|
64
|
-
content: cssMap.join('\n'),
|
|
110
|
+
content: cssMap.join('\n \n'),
|
|
65
111
|
linkAfter: [],
|
|
66
112
|
})
|
|
67
113
|
|
package/src/utils.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { ASTUtils } from '@teleporthq/teleport-plugin-common'
|
|
2
|
+
import { PluginCSS, UIDLConditionalNode, UIDLPropDefinition } from '@teleporthq/teleport-types'
|
|
3
|
+
|
|
4
|
+
export const createConditionalStatement = (
|
|
5
|
+
conditions: UIDLConditionalNode['content']['condition']['conditions'],
|
|
6
|
+
leftOperand: UIDLPropDefinition['defaultValue']
|
|
7
|
+
) => {
|
|
8
|
+
return conditions.map((condition) => {
|
|
9
|
+
const { operation, operand } = condition
|
|
10
|
+
|
|
11
|
+
if (operand === undefined) {
|
|
12
|
+
return `${ASTUtils.convertToUnaryOperator(operation)}${getValueType(operand)}`
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
return `${getValueType(leftOperand)} ${ASTUtils.convertToBinaryOperator(
|
|
16
|
+
operation
|
|
17
|
+
)} ${getValueType(operand)}`
|
|
18
|
+
})
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const getValueType = (value: UIDLPropDefinition['defaultValue']) => {
|
|
22
|
+
const valueType = typeof value
|
|
23
|
+
switch (valueType) {
|
|
24
|
+
case 'string':
|
|
25
|
+
return `"${value}"`
|
|
26
|
+
case 'number':
|
|
27
|
+
return value
|
|
28
|
+
case 'boolean':
|
|
29
|
+
return value
|
|
30
|
+
default:
|
|
31
|
+
throw new PluginCSS(
|
|
32
|
+
`Conditional node received an operand of type ${valueType} \n
|
|
33
|
+
Received ${JSON.stringify(value)}`
|
|
34
|
+
)
|
|
35
|
+
}
|
|
36
|
+
}
|