@teleporthq/teleport-plugin-css-modules 0.43.0-alpha.0 → 0.43.3
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 -3
- package/__tests__/index.ts +4 -4
- package/__tests__/mocks.ts +7 -2
- package/__tests__/style-sheet.ts +2 -1
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +44 -20
- 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 +27 -9
- package/dist/cjs/style-sheet.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 +44 -20
- 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 +27 -9
- package/dist/esm/style-sheet.js.map +1 -1
- package/dist/esm/tsconfig.tsbuildinfo +1 -1
- package/package.json +5 -5
- package/src/index.ts +65 -30
- package/src/style-sheet.ts +51 -10
package/src/index.ts
CHANGED
|
@@ -27,9 +27,12 @@ import {
|
|
|
27
27
|
UIDLStyleMediaQueryScreenSizeCondition,
|
|
28
28
|
PluginCssModules,
|
|
29
29
|
HastNode,
|
|
30
|
+
UIDLElement,
|
|
31
|
+
UIDLElementNode,
|
|
30
32
|
} from '@teleporthq/teleport-types'
|
|
31
33
|
import { createStyleSheetPlugin } from './style-sheet'
|
|
32
34
|
import { generateStyledFromStyleContent } from './utils'
|
|
35
|
+
import { isJSXElement } from '@teleporthq/teleport-plugin-common/dist/cjs/utils/ast-utils'
|
|
33
36
|
|
|
34
37
|
interface CSSModulesConfig {
|
|
35
38
|
componentChunkName?: string
|
|
@@ -104,26 +107,44 @@ export const createCSSModulesPlugin: ComponentPluginFactory<CSSModulesConfig> =
|
|
|
104
107
|
(componentChunk.meta.nodesLookup as Record<string, HastNode | types.JSXElement>) || {}
|
|
105
108
|
const propsPrefix = componentChunk.meta.dynamicRefPrefix.prop as string
|
|
106
109
|
|
|
107
|
-
|
|
108
|
-
const {
|
|
109
|
-
|
|
110
|
-
|
|
110
|
+
const generateStylesForElementNode = (element: UIDLElement) => {
|
|
111
|
+
const {
|
|
112
|
+
style,
|
|
113
|
+
key,
|
|
114
|
+
referencedStyles,
|
|
115
|
+
dependency,
|
|
116
|
+
attrs = {},
|
|
117
|
+
elementType,
|
|
118
|
+
dynamicStyleBindings,
|
|
119
|
+
} = element
|
|
120
|
+
const jsxTag = astNodesLookup[key]
|
|
121
|
+
const classNamesToAppend: Set<
|
|
122
|
+
types.MemberExpression | types.Identifier | types.StringLiteral
|
|
123
|
+
> = new Set()
|
|
124
|
+
const hasDynamicBindings =
|
|
125
|
+
dynamicStyleBindings && Object.keys(dynamicStyleBindings).length > 0
|
|
126
|
+
|
|
127
|
+
if (!jsxTag || !isJSXElement(jsxTag)) {
|
|
128
|
+
return
|
|
129
|
+
}
|
|
111
130
|
|
|
112
131
|
if (dependency?.type === 'local') {
|
|
113
132
|
StyleBuilders.setPropValueForCompStyle({
|
|
114
133
|
attrs,
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
134
|
+
root: jsxTag,
|
|
135
|
+
getClassName: (styleName: string) =>
|
|
136
|
+
StringUtils.camelCaseToDashCase(elementType + styleName),
|
|
118
137
|
})
|
|
119
138
|
}
|
|
120
139
|
|
|
121
|
-
if (!
|
|
140
|
+
if (!style && !referencedStyles && !hasDynamicBindings) {
|
|
122
141
|
return
|
|
123
142
|
}
|
|
124
143
|
|
|
125
|
-
if (!
|
|
126
|
-
|
|
144
|
+
if (!key) {
|
|
145
|
+
throw new PluginCssModules(
|
|
146
|
+
'Element node does not have a key \n' + JSON.stringify(element, null, 2)
|
|
147
|
+
)
|
|
127
148
|
}
|
|
128
149
|
|
|
129
150
|
const className = StringUtils.camelCaseToDashCase(key)
|
|
@@ -133,6 +154,8 @@ export const createCSSModulesPlugin: ComponentPluginFactory<CSSModulesConfig> =
|
|
|
133
154
|
true
|
|
134
155
|
)
|
|
135
156
|
|
|
157
|
+
let jsxInlineStyles: Record<string, unknown> | null = null
|
|
158
|
+
|
|
136
159
|
/* Generating styles from UIDLElementNode to component style sheet */
|
|
137
160
|
if (Object.keys(style || {}).length > 0) {
|
|
138
161
|
const { staticStyles, dynamicStyles, tokenStyles } =
|
|
@@ -146,18 +169,28 @@ export const createCSSModulesPlugin: ComponentPluginFactory<CSSModulesConfig> =
|
|
|
146
169
|
}
|
|
147
170
|
|
|
148
171
|
if (Object.keys(dynamicStyles).length) {
|
|
149
|
-
|
|
172
|
+
jsxInlineStyles = UIDLUtils.transformDynamicStyles(dynamicStyles, (styleValue) =>
|
|
150
173
|
StyleBuilders.createDynamicStyleExpression(styleValue, propsPrefix)
|
|
151
174
|
)
|
|
175
|
+
}
|
|
176
|
+
}
|
|
152
177
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
178
|
+
if (hasDynamicBindings) {
|
|
179
|
+
if (!jsxInlineStyles) {
|
|
180
|
+
jsxInlineStyles = {}
|
|
181
|
+
}
|
|
182
|
+
for (const [cssProperty, binding] of Object.entries(dynamicStyleBindings)) {
|
|
183
|
+
const camelCaseProperty = cssProperty.replace(/-([a-z])/g, (_, letter: string) =>
|
|
184
|
+
letter.toUpperCase()
|
|
185
|
+
)
|
|
186
|
+
jsxInlineStyles[camelCaseProperty] = StyleBuilders.createDynamicBindingExpression(binding)
|
|
158
187
|
}
|
|
159
188
|
}
|
|
160
189
|
|
|
190
|
+
if (jsxInlineStyles && Object.keys(jsxInlineStyles).length > 0) {
|
|
191
|
+
ASTUtils.addAttributeToJSXTag(jsxTag, 'style', jsxInlineStyles)
|
|
192
|
+
}
|
|
193
|
+
|
|
161
194
|
/* Any media-styles, component-scoped styles, global style sheet styles are handled here */
|
|
162
195
|
if (Object.keys(referencedStyles || {}).length > 0) {
|
|
163
196
|
Object.values(referencedStyles).forEach((styleRef: UIDLElementNodeReferenceStyles) => {
|
|
@@ -194,13 +227,7 @@ export const createCSSModulesPlugin: ComponentPluginFactory<CSSModulesConfig> =
|
|
|
194
227
|
case 'component-referenced': {
|
|
195
228
|
const classContent = styleRef.content.content
|
|
196
229
|
if (classContent.type === 'static') {
|
|
197
|
-
classNamesToAppend.add(
|
|
198
|
-
types.memberExpression(
|
|
199
|
-
types.identifier(styleObjectImportName),
|
|
200
|
-
types.identifier(`'${getClassName(String(classContent.content))}'`),
|
|
201
|
-
true
|
|
202
|
-
)
|
|
203
|
-
)
|
|
230
|
+
classNamesToAppend.add(types.stringLiteral(String(classContent.content)))
|
|
204
231
|
return
|
|
205
232
|
}
|
|
206
233
|
|
|
@@ -223,8 +250,8 @@ export const createCSSModulesPlugin: ComponentPluginFactory<CSSModulesConfig> =
|
|
|
223
250
|
if (!defaultPropValue) {
|
|
224
251
|
return
|
|
225
252
|
}
|
|
226
|
-
/*
|
|
227
|
-
Changing the default value of the prop.
|
|
253
|
+
/*
|
|
254
|
+
Changing the default value of the prop.
|
|
228
255
|
When forceScoping is enabled the classnames change. So, we need to change the default prop too. */
|
|
229
256
|
propDefinitions[classContent.content.id].defaultValue = getClassName(
|
|
230
257
|
String(defaultPropValue)
|
|
@@ -253,9 +280,7 @@ export const createCSSModulesPlugin: ComponentPluginFactory<CSSModulesConfig> =
|
|
|
253
280
|
isProjectStyleReferred = true
|
|
254
281
|
const referedStyle = globalStyleSheet[content.referenceId]
|
|
255
282
|
if (!referedStyle) {
|
|
256
|
-
|
|
257
|
-
`Style used from global stylesheet is missing - ${content.referenceId}`
|
|
258
|
-
)
|
|
283
|
+
return
|
|
259
284
|
}
|
|
260
285
|
classNamesToAppend.add(
|
|
261
286
|
types.memberExpression(
|
|
@@ -279,7 +304,17 @@ export const createCSSModulesPlugin: ComponentPluginFactory<CSSModulesConfig> =
|
|
|
279
304
|
classAttributeName,
|
|
280
305
|
Array.from(classNamesToAppend)
|
|
281
306
|
)
|
|
282
|
-
}
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
UIDLUtils.traverseElements(node, generateStylesForElementNode)
|
|
310
|
+
for (const prop of Object.values(propDefinitions)) {
|
|
311
|
+
if (prop.type === 'element' && prop.defaultValue) {
|
|
312
|
+
UIDLUtils.traverseElements(
|
|
313
|
+
prop.defaultValue as UIDLElementNode,
|
|
314
|
+
generateStylesForElementNode
|
|
315
|
+
)
|
|
316
|
+
}
|
|
317
|
+
}
|
|
283
318
|
|
|
284
319
|
/* Generating component scoped styles */
|
|
285
320
|
if (Object.keys(componentStyleSheet).length > 0) {
|
|
@@ -287,7 +322,7 @@ export const createCSSModulesPlugin: ComponentPluginFactory<CSSModulesConfig> =
|
|
|
287
322
|
componentStyleSheet,
|
|
288
323
|
cssClasses,
|
|
289
324
|
mediaStylesMap,
|
|
290
|
-
(
|
|
325
|
+
(styleName: string) => StringUtils.camelCaseToDashCase(uidl.name + styleName)
|
|
291
326
|
)
|
|
292
327
|
}
|
|
293
328
|
|
package/src/style-sheet.ts
CHANGED
|
@@ -6,39 +6,83 @@ import {
|
|
|
6
6
|
FileType,
|
|
7
7
|
} from '@teleporthq/teleport-types'
|
|
8
8
|
import { StringUtils } from '@teleporthq/teleport-shared'
|
|
9
|
+
import { relative, join } from 'path'
|
|
10
|
+
|
|
9
11
|
interface StyleSheetPlugin {
|
|
10
12
|
fileName?: string
|
|
11
13
|
moduleExtension?: boolean
|
|
14
|
+
relativeFontPath?: boolean
|
|
12
15
|
}
|
|
13
16
|
|
|
14
17
|
const defaultConfig = {
|
|
15
18
|
fileName: 'style',
|
|
16
19
|
moduleExtension: false,
|
|
20
|
+
relativeFontPath: false,
|
|
17
21
|
}
|
|
18
22
|
|
|
19
23
|
export const createStyleSheetPlugin: ComponentPluginFactory<StyleSheetPlugin> = (config) => {
|
|
20
|
-
const { fileName, moduleExtension } = {
|
|
24
|
+
const { fileName, moduleExtension, relativeFontPath } = {
|
|
21
25
|
...defaultConfig,
|
|
22
26
|
...config,
|
|
23
27
|
}
|
|
24
28
|
|
|
25
29
|
const styleSheetPlugin: ComponentPlugin = async (structure) => {
|
|
26
|
-
const {
|
|
30
|
+
const {
|
|
31
|
+
uidl,
|
|
32
|
+
chunks,
|
|
33
|
+
options: { assets },
|
|
34
|
+
} = structure
|
|
27
35
|
const { styleSetDefinitions = {}, designLanguage: { tokens = {} } = {} } = uidl
|
|
36
|
+
const {
|
|
37
|
+
localFonts = [],
|
|
38
|
+
fontsFolder,
|
|
39
|
+
identifier: assetIdentifier,
|
|
40
|
+
} = assets || { localFonts: [] }
|
|
41
|
+
|
|
42
|
+
const canSkipThePlugin =
|
|
43
|
+
localFonts?.length === 0 &&
|
|
44
|
+
Object.keys(styleSetDefinitions).length === 0 &&
|
|
45
|
+
Object.keys(tokens).length === 0
|
|
28
46
|
|
|
29
|
-
if (
|
|
30
|
-
|
|
31
|
-
(Object.keys(styleSetDefinitions).length === 0 && Object.keys(tokens).length === 0)
|
|
32
|
-
) {
|
|
33
|
-
return
|
|
47
|
+
if (canSkipThePlugin) {
|
|
48
|
+
return structure
|
|
34
49
|
}
|
|
35
50
|
|
|
51
|
+
uidl.outputOptions = uidl.outputOptions || {}
|
|
52
|
+
uidl.outputOptions.styleFileName = moduleExtension ? `${fileName}.module` : fileName
|
|
53
|
+
|
|
36
54
|
const cssMap: string[] = []
|
|
37
55
|
const mediaStylesMap: Record<
|
|
38
56
|
string,
|
|
39
57
|
Array<{ [x: string]: Record<string, string | number> }>
|
|
40
58
|
> = {}
|
|
41
59
|
|
|
60
|
+
if (localFonts.length > 0) {
|
|
61
|
+
localFonts.forEach((font) => {
|
|
62
|
+
const properties = StyleUtils.getContentOfStyleObject(font.properties) as Record<
|
|
63
|
+
string,
|
|
64
|
+
string | number
|
|
65
|
+
>
|
|
66
|
+
const format = properties?.format ? `format('${properties.format}')` : ''
|
|
67
|
+
/* tslint:disable:no-string-literal */
|
|
68
|
+
delete properties['format']
|
|
69
|
+
|
|
70
|
+
const fontPath = relativeFontPath
|
|
71
|
+
? join(
|
|
72
|
+
relative(join(...(uidl.outputOptions?.folderPath || [])), './'),
|
|
73
|
+
join(fontsFolder || '', font.path)
|
|
74
|
+
)
|
|
75
|
+
: join('/', assetIdentifier || '', 'fonts', font.path)
|
|
76
|
+
|
|
77
|
+
cssMap.push(
|
|
78
|
+
StyleBuilders.createFontDecleration({
|
|
79
|
+
...properties,
|
|
80
|
+
src: `url("${fontPath}") ${format}`,
|
|
81
|
+
})
|
|
82
|
+
)
|
|
83
|
+
})
|
|
84
|
+
}
|
|
85
|
+
|
|
42
86
|
if (Object.keys(tokens).length > 0) {
|
|
43
87
|
cssMap.push(
|
|
44
88
|
StyleBuilders.createCSSClassWithSelector(
|
|
@@ -65,9 +109,6 @@ export const createStyleSheetPlugin: ComponentPluginFactory<StyleSheetPlugin> =
|
|
|
65
109
|
return structure
|
|
66
110
|
}
|
|
67
111
|
|
|
68
|
-
uidl.outputOptions = uidl.outputOptions || {}
|
|
69
|
-
uidl.outputOptions.styleFileName = moduleExtension ? `${fileName}.module` : fileName
|
|
70
|
-
|
|
71
112
|
chunks.push({
|
|
72
113
|
name: fileName,
|
|
73
114
|
type: ChunkType.STRING,
|