@teleporthq/teleport-plugin-css 0.42.35 → 0.43.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/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +144 -26
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/tsconfig.tsbuildinfo +1 -1
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +144 -26
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/tsconfig.tsbuildinfo +1 -1
- package/package.json +5 -5
- package/src/index.ts +167 -19
package/src/index.ts
CHANGED
|
@@ -27,6 +27,7 @@ import {
|
|
|
27
27
|
PropDefaultValueTypes,
|
|
28
28
|
UIDLStyleInlineAsset,
|
|
29
29
|
UIDLFontAsset,
|
|
30
|
+
UIDLGlobalStateDefinition,
|
|
30
31
|
} from '@teleporthq/teleport-types'
|
|
31
32
|
import { createStyleSheetPlugin } from './style-sheet'
|
|
32
33
|
import { createConditionalStatement } from './utils'
|
|
@@ -85,7 +86,12 @@ const createCSSPlugin: ComponentPluginFactory<CSSPluginConfig> = (config) => {
|
|
|
85
86
|
propDefinitions = {},
|
|
86
87
|
stateDefinitions = {},
|
|
87
88
|
} = uidl
|
|
88
|
-
const {
|
|
89
|
+
const {
|
|
90
|
+
projectStyleSet,
|
|
91
|
+
designLanguage: { tokens = {} } = {},
|
|
92
|
+
isRootComponent,
|
|
93
|
+
globalStateDefinitions = {},
|
|
94
|
+
} = options || {}
|
|
89
95
|
const {
|
|
90
96
|
styleSetDefinitions = {},
|
|
91
97
|
fileName: projectStyleSheetName,
|
|
@@ -138,6 +144,9 @@ const createCSSPlugin: ComponentPluginFactory<CSSPluginConfig> = (config) => {
|
|
|
138
144
|
elementType,
|
|
139
145
|
dependency,
|
|
140
146
|
} = element
|
|
147
|
+
const { dynamicStyleBindings } = element
|
|
148
|
+
const hasDynamicBindings =
|
|
149
|
+
dynamicStyleBindings && Object.keys(dynamicStyleBindings).length > 0
|
|
141
150
|
|
|
142
151
|
const root = jsxNodesLookup[key]
|
|
143
152
|
if (!root) {
|
|
@@ -160,7 +169,8 @@ const createCSSPlugin: ComponentPluginFactory<CSSPluginConfig> = (config) => {
|
|
|
160
169
|
if (
|
|
161
170
|
Object.keys(style).length === 0 &&
|
|
162
171
|
Object.keys(referencedStyles).length === 0 &&
|
|
163
|
-
Object.keys(componentStyleSet).length === 0
|
|
172
|
+
Object.keys(componentStyleSet).length === 0 &&
|
|
173
|
+
!hasDynamicBindings
|
|
164
174
|
) {
|
|
165
175
|
return
|
|
166
176
|
}
|
|
@@ -180,28 +190,58 @@ const createCSSPlugin: ComponentPluginFactory<CSSPluginConfig> = (config) => {
|
|
|
180
190
|
classNamesToAppend.add(className)
|
|
181
191
|
}
|
|
182
192
|
|
|
193
|
+
let jsxInlineStyles: Record<string, unknown> | null = null
|
|
194
|
+
|
|
183
195
|
if (Object.keys(dynamicStyles).length > 0) {
|
|
196
|
+
for (const styleValue of Object.values(dynamicStyles)) {
|
|
197
|
+
if (
|
|
198
|
+
styleValue.type === 'dynamic' &&
|
|
199
|
+
styleValue.content.referenceType === 'global' &&
|
|
200
|
+
templateChunk.meta.globalReferences
|
|
201
|
+
) {
|
|
202
|
+
;(templateChunk.meta.globalReferences as string[]).push(styleValue.content.id)
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
184
206
|
/* If dynamic styles are on nested-styles they are unfortunately lost,
|
|
185
207
|
since inline style does not support that */
|
|
186
208
|
if (templateStyle === 'html') {
|
|
187
209
|
const inlineStyles = createDynamicInlineStyle(dynamicStyles)
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
)
|
|
210
|
+
const bindingParts = hasDynamicBindings
|
|
211
|
+
? createDynamicBindingInlineStyle(dynamicStyleBindings)
|
|
212
|
+
: ''
|
|
213
|
+
const combined = bindingParts ? `${inlineStyles}, ${bindingParts}` : inlineStyles
|
|
214
|
+
HASTUtils.addAttributeToNode(root as HastNode, inlineStyleAttributeKey, `{${combined}}`)
|
|
193
215
|
} else {
|
|
194
|
-
|
|
216
|
+
jsxInlineStyles = UIDLUtils.transformDynamicStyles(dynamicStyles, (styleValue) =>
|
|
195
217
|
StyleBuilders.createDynamicStyleExpression(styleValue, propsPrefix)
|
|
196
218
|
)
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
219
|
+
}
|
|
220
|
+
} else if (hasDynamicBindings && templateStyle === 'html') {
|
|
221
|
+
const bindingParts = createDynamicBindingInlineStyle(dynamicStyleBindings)
|
|
222
|
+
HASTUtils.addAttributeToNode(root as HastNode, inlineStyleAttributeKey, `{${bindingParts}}`)
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
if (hasDynamicBindings && templateStyle !== 'html') {
|
|
226
|
+
if (!jsxInlineStyles) {
|
|
227
|
+
jsxInlineStyles = {}
|
|
228
|
+
}
|
|
229
|
+
for (const [cssProperty, binding] of Object.entries(dynamicStyleBindings)) {
|
|
230
|
+
const camelCaseProperty = cssProperty.replace(/-([a-z])/g, (_, letter: string) =>
|
|
231
|
+
letter.toUpperCase()
|
|
201
232
|
)
|
|
233
|
+
jsxInlineStyles[camelCaseProperty] = StyleBuilders.createDynamicBindingExpression(binding)
|
|
202
234
|
}
|
|
203
235
|
}
|
|
204
236
|
|
|
237
|
+
if (jsxInlineStyles) {
|
|
238
|
+
ASTUtils.addAttributeToJSXTag(
|
|
239
|
+
root as types.JSXElement,
|
|
240
|
+
inlineStyleAttributeKey,
|
|
241
|
+
jsxInlineStyles
|
|
242
|
+
)
|
|
243
|
+
}
|
|
244
|
+
|
|
205
245
|
Object.values(referencedStyles).forEach((styleRef: UIDLElementNodeReferenceStyles) => {
|
|
206
246
|
switch (styleRef.content.mapType) {
|
|
207
247
|
case 'inlined': {
|
|
@@ -289,9 +329,7 @@ const createCSSPlugin: ComponentPluginFactory<CSSPluginConfig> = (config) => {
|
|
|
289
329
|
const { content } = styleRef
|
|
290
330
|
const referedStyle = styleSetDefinitions[content.referenceId]
|
|
291
331
|
if (!referedStyle) {
|
|
292
|
-
|
|
293
|
-
`Style used from global stylesheet is missing - ${content.referenceId}`
|
|
294
|
-
)
|
|
332
|
+
return
|
|
295
333
|
}
|
|
296
334
|
|
|
297
335
|
usedProjectStyleIds.add(content.referenceId)
|
|
@@ -391,10 +429,18 @@ const createCSSPlugin: ComponentPluginFactory<CSSPluginConfig> = (config) => {
|
|
|
391
429
|
for (const path of refPath) {
|
|
392
430
|
defaultValue = (defaultValue as Record<string, unknown[]>)?.[path]
|
|
393
431
|
}
|
|
394
|
-
|
|
432
|
+
if (
|
|
433
|
+
typeof defaultValue === 'object' &&
|
|
434
|
+
defaultValue !== null &&
|
|
435
|
+
'type' in (defaultValue as Record<string, unknown>) &&
|
|
436
|
+
'content' in (defaultValue as Record<string, unknown>)
|
|
437
|
+
) {
|
|
438
|
+
const entry = defaultValue as { type: string; content: unknown }
|
|
439
|
+
if (entry.type === 'static') {
|
|
440
|
+
defaultValue = entry.content as typeof defaultValue
|
|
441
|
+
}
|
|
442
|
+
}
|
|
395
443
|
defaultValue = defaultValue ?? usedState.defaultValue
|
|
396
|
-
// Since we know the operand and the default value from the state.
|
|
397
|
-
// We can try building the condition and check if the condition is true or false.
|
|
398
444
|
|
|
399
445
|
const dynamicConditions = createConditionalStatement(
|
|
400
446
|
staticValue !== undefined
|
|
@@ -414,6 +460,38 @@ const createCSSPlugin: ComponentPluginFactory<CSSPluginConfig> = (config) => {
|
|
|
414
460
|
return
|
|
415
461
|
}
|
|
416
462
|
|
|
463
|
+
case 'globalState' as any: {
|
|
464
|
+
const gsDef = findGlobalStateDefinitionById(id, globalStateDefinitions)
|
|
465
|
+
if (!gsDef) {
|
|
466
|
+
classNamesToAppend.add(styleRef.content.referenceId)
|
|
467
|
+
return
|
|
468
|
+
}
|
|
469
|
+
let defaultValue: StateDefaultValueTypes | PropDefaultValueTypes =
|
|
470
|
+
gsDef.defaultValue as StateDefaultValueTypes
|
|
471
|
+
for (const path of refPath) {
|
|
472
|
+
defaultValue = (defaultValue as Record<string, unknown>)?.[
|
|
473
|
+
path
|
|
474
|
+
] as typeof defaultValue
|
|
475
|
+
}
|
|
476
|
+
defaultValue = defaultValue ?? (gsDef.defaultValue as StateDefaultValueTypes)
|
|
477
|
+
const dynamicConditions = createConditionalStatement(
|
|
478
|
+
staticValue !== undefined
|
|
479
|
+
? [{ operand: staticValue, operation: '===' }]
|
|
480
|
+
: conditions,
|
|
481
|
+
defaultValue
|
|
482
|
+
)
|
|
483
|
+
const matchCondition =
|
|
484
|
+
matchingCriteria && matchingCriteria === 'all' ? '&&' : '||'
|
|
485
|
+
const conditionString = dynamicConditions.join(` ${matchCondition} `)
|
|
486
|
+
// tslint:disable-next-line function-constructor
|
|
487
|
+
const isConditionPassing = new Function(`return ${conditionString}`)()
|
|
488
|
+
if (isConditionPassing) {
|
|
489
|
+
classNamesToAppend.add(styleRef.content.referenceId)
|
|
490
|
+
return
|
|
491
|
+
}
|
|
492
|
+
return
|
|
493
|
+
}
|
|
494
|
+
|
|
417
495
|
default: {
|
|
418
496
|
classNamesToAppend.add(styleRef.content.referenceId)
|
|
419
497
|
return
|
|
@@ -447,16 +525,34 @@ const createCSSPlugin: ComponentPluginFactory<CSSPluginConfig> = (config) => {
|
|
|
447
525
|
break
|
|
448
526
|
}
|
|
449
527
|
default: {
|
|
528
|
+
if ((referenceType as string) === 'globalState') {
|
|
529
|
+
const gsDef = findGlobalStateDefinitionById(
|
|
530
|
+
nameToAppend,
|
|
531
|
+
globalStateDefinitions
|
|
532
|
+
)
|
|
533
|
+
if (gsDef) {
|
|
534
|
+
binaryExpressionType = gsDef.type
|
|
535
|
+
}
|
|
536
|
+
break
|
|
537
|
+
}
|
|
450
538
|
throw new PluginCSS(
|
|
451
539
|
`Un-supported reference type ${referenceType} for ${nameToAppend}`
|
|
452
540
|
)
|
|
453
541
|
}
|
|
454
542
|
}
|
|
455
543
|
|
|
544
|
+
let binaryKey = nameToAppend
|
|
545
|
+
if (referenceType === 'prop') {
|
|
546
|
+
binaryKey = 'props?.' + nameToAppend
|
|
547
|
+
} else if ((referenceType as string) === 'globalState') {
|
|
548
|
+
const gsDef = findGlobalStateDefinitionById(nameToAppend, globalStateDefinitions)
|
|
549
|
+
binaryKey = gsDef ? gsDef.name : nameToAppend
|
|
550
|
+
}
|
|
551
|
+
|
|
456
552
|
const binaryExpression = createBinaryExpression(
|
|
457
553
|
{ operation: operator, operand: right },
|
|
458
554
|
{
|
|
459
|
-
key:
|
|
555
|
+
key: binaryKey,
|
|
460
556
|
type: binaryExpressionType,
|
|
461
557
|
}
|
|
462
558
|
)
|
|
@@ -651,6 +747,23 @@ const createCSSPlugin: ComponentPluginFactory<CSSPluginConfig> = (config) => {
|
|
|
651
747
|
if (className && usedProjectStyles.includes(className)) {
|
|
652
748
|
return true
|
|
653
749
|
}
|
|
750
|
+
// Include compound selectors where the base class (before the dot or space) is a used style
|
|
751
|
+
// e.g., "dashboard-sidebar.collapsed" should be included if "dashboard-sidebar" is used
|
|
752
|
+
// e.g., "dashboard-sidebar.collapsed .sidebar-brand-text" should also be included
|
|
753
|
+
const dotIdx = key.indexOf('.')
|
|
754
|
+
const spaceIdx = key.indexOf(' ')
|
|
755
|
+
if (dotIdx > 0) {
|
|
756
|
+
const baseClass = key.substring(0, dotIdx)
|
|
757
|
+
if (usedProjectStyles.includes(baseClass)) {
|
|
758
|
+
return true
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
if (spaceIdx > 0 && dotIdx < 0) {
|
|
762
|
+
const baseClass = key.substring(0, spaceIdx)
|
|
763
|
+
if (usedProjectStyles.includes(baseClass)) {
|
|
764
|
+
return true
|
|
765
|
+
}
|
|
766
|
+
}
|
|
654
767
|
return false
|
|
655
768
|
})
|
|
656
769
|
)
|
|
@@ -789,6 +902,18 @@ export { createStyleSheetPlugin, createCSSPlugin }
|
|
|
789
902
|
|
|
790
903
|
export default createCSSPlugin()
|
|
791
904
|
|
|
905
|
+
const findGlobalStateDefinitionById = (
|
|
906
|
+
id: string,
|
|
907
|
+
definitions: Record<string, UIDLGlobalStateDefinition>
|
|
908
|
+
): UIDLGlobalStateDefinition | undefined => {
|
|
909
|
+
for (const def of Object.values(definitions)) {
|
|
910
|
+
if (def.id === id) {
|
|
911
|
+
return def
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
return undefined
|
|
915
|
+
}
|
|
916
|
+
|
|
792
917
|
const createDynamicInlineStyle = (styles: UIDLStyleDefinitions) => {
|
|
793
918
|
return Object.keys(styles)
|
|
794
919
|
.map((styleKey) => {
|
|
@@ -796,3 +921,26 @@ const createDynamicInlineStyle = (styles: UIDLStyleDefinitions) => {
|
|
|
796
921
|
})
|
|
797
922
|
.join(', ')
|
|
798
923
|
}
|
|
924
|
+
|
|
925
|
+
const createDynamicBindingInlineStyle = (
|
|
926
|
+
bindings: Record<
|
|
927
|
+
string,
|
|
928
|
+
{
|
|
929
|
+
referenceType: string
|
|
930
|
+
stateKey: string
|
|
931
|
+
defaultValue: string
|
|
932
|
+
contextName?: string
|
|
933
|
+
stateDefinitionId?: string
|
|
934
|
+
}
|
|
935
|
+
>
|
|
936
|
+
): string => {
|
|
937
|
+
return Object.entries(bindings)
|
|
938
|
+
.map(([prop, binding]) => {
|
|
939
|
+
const value =
|
|
940
|
+
binding.referenceType === 'ctx' && binding.contextName
|
|
941
|
+
? `${binding.contextName}.${binding.stateKey}`
|
|
942
|
+
: binding.stateKey
|
|
943
|
+
return `${prop}: ${value} != null ? ${value} : '${binding.defaultValue || ''}'`
|
|
944
|
+
})
|
|
945
|
+
.join(', ')
|
|
946
|
+
}
|