@atlaskit/css 0.10.3 → 0.10.5
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/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# @atlaskit/css
|
|
2
2
|
|
|
3
|
+
## 0.10.5
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#135712](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/135712)
|
|
8
|
+
[`fa9caa5adb7a3`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/fa9caa5adb7a3) -
|
|
9
|
+
Improvements to `xcss()` -> `cssMap()` codemod.
|
|
10
|
+
- Updated dependencies
|
|
11
|
+
|
|
12
|
+
## 0.10.4
|
|
13
|
+
|
|
14
|
+
### Patch Changes
|
|
15
|
+
|
|
16
|
+
- [#133515](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/133515)
|
|
17
|
+
[`3e092526fea27`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/3e092526fea27) -
|
|
18
|
+
Fix codemod config.
|
|
19
|
+
|
|
3
20
|
## 0.10.3
|
|
4
21
|
|
|
5
22
|
### Patch Changes
|
|
@@ -92,6 +92,10 @@ function replaceXcssWithCssMap(
|
|
|
92
92
|
specifier: string,
|
|
93
93
|
) {
|
|
94
94
|
const cssMapProperties: core.ObjectProperty[] = [];
|
|
95
|
+
let firstXcssPath: ASTPath<core.CallExpression> | null = null;
|
|
96
|
+
let firstUsagePath: ASTPath<core.Node> | null = null;
|
|
97
|
+
const styleVariables = new Set<string>();
|
|
98
|
+
const variableDependencies = new Map<string, Set<string>>();
|
|
95
99
|
|
|
96
100
|
source
|
|
97
101
|
.find(j.CallExpression, {
|
|
@@ -114,15 +118,85 @@ function replaceXcssWithCssMap(
|
|
|
114
118
|
|
|
115
119
|
if (variableDeclarator && variableDeclarator.type === 'VariableDeclarator') {
|
|
116
120
|
const variableName = variableDeclarator.id.name; // e.g. buttonStyles
|
|
117
|
-
|
|
121
|
+
styleVariables.add(variableName);
|
|
122
|
+
|
|
123
|
+
// find dependencies in the xcss object
|
|
124
|
+
const dependencies = new Set<string>();
|
|
125
|
+
if (args[0].type === 'ObjectExpression') {
|
|
126
|
+
args[0].properties.forEach((prop) => {
|
|
127
|
+
if (prop.type === 'ObjectProperty' && prop.value.type === 'TemplateLiteral') {
|
|
128
|
+
prop.value.expressions.forEach((expr) => {
|
|
129
|
+
if (expr.type === 'Identifier') {
|
|
130
|
+
dependencies.add(expr.name);
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
if (dependencies.size > 0) {
|
|
137
|
+
variableDependencies.set(variableName, dependencies);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
});
|
|
118
143
|
|
|
144
|
+
// find the first usage of any style variable
|
|
145
|
+
source.find(j.Identifier).forEach((path) => {
|
|
146
|
+
if (
|
|
147
|
+
styleVariables.has(path.node.name) &&
|
|
148
|
+
(!firstUsagePath ||
|
|
149
|
+
(path.node.loc?.start &&
|
|
150
|
+
firstUsagePath.node.loc?.start &&
|
|
151
|
+
(path.node.loc.start.line < firstUsagePath.node.loc.start.line ||
|
|
152
|
+
(path.node.loc.start.line === firstUsagePath.node.loc.start.line &&
|
|
153
|
+
path.node.loc.start.column < firstUsagePath.node.loc.start.column))))
|
|
154
|
+
) {
|
|
155
|
+
firstUsagePath = path;
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
// find all xcss function calls
|
|
160
|
+
source
|
|
161
|
+
.find(j.CallExpression, {
|
|
162
|
+
callee: {
|
|
163
|
+
type: 'Identifier',
|
|
164
|
+
name: specifier,
|
|
165
|
+
},
|
|
166
|
+
})
|
|
167
|
+
.forEach((path) => {
|
|
168
|
+
const args = path.node.arguments;
|
|
169
|
+
// only process xcss calls that have a single object argument
|
|
170
|
+
if (args.length === 1 && args[0].type === 'ObjectExpression') {
|
|
171
|
+
// get the parent variable declaration that contains this xcss call
|
|
172
|
+
// e.g. const buttonStyles = xcss({...})
|
|
173
|
+
const parentVariableDeclaration = path.parentPath?.parentPath?.parentPath?.node;
|
|
174
|
+
if (parentVariableDeclaration && parentVariableDeclaration.type === 'VariableDeclaration') {
|
|
175
|
+
// find the variable declarator that initialises with this xcss call
|
|
176
|
+
// e.g. const buttonStyles = xcss({ color: 'red' });
|
|
177
|
+
const variableDeclarator = parentVariableDeclaration.declarations.find(
|
|
178
|
+
(declaration: core.VariableDeclarator) => declaration.init === path.node,
|
|
179
|
+
);
|
|
180
|
+
|
|
181
|
+
if (variableDeclarator && variableDeclarator.type === 'VariableDeclarator') {
|
|
182
|
+
// convert the variable name to a cssMap key (e.g. myStyles -> root)
|
|
183
|
+
const variableName = variableDeclarator.id.name;
|
|
184
|
+
const key = getCssMapKey(variableName);
|
|
185
|
+
|
|
186
|
+
// create a new cssMap property with the key and the processed styles
|
|
119
187
|
const cssMapObject = j.objectProperty(
|
|
120
188
|
j.identifier(key),
|
|
121
189
|
ensureSelectorAmpersand(j, args[0]),
|
|
122
190
|
);
|
|
123
191
|
cssMapProperties.push(cssMapObject);
|
|
124
192
|
|
|
125
|
-
|
|
193
|
+
// track the first xcss call
|
|
194
|
+
if (!firstXcssPath) {
|
|
195
|
+
firstXcssPath = path;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// remove the original xcss variable declaration since we'll replace it with cssMap
|
|
199
|
+
j(path.parentPath.parentPath.parentPath).remove();
|
|
126
200
|
}
|
|
127
201
|
}
|
|
128
202
|
}
|
|
@@ -138,11 +212,167 @@ function replaceXcssWithCssMap(
|
|
|
138
212
|
),
|
|
139
213
|
]);
|
|
140
214
|
|
|
141
|
-
// insert the cssMap
|
|
142
|
-
|
|
143
|
-
|
|
215
|
+
// insert the cssMap declaration before its first usage
|
|
216
|
+
if (firstUsagePath) {
|
|
217
|
+
const programBody = source.get().node.program.body;
|
|
218
|
+
let insertIndex = 0;
|
|
219
|
+
|
|
220
|
+
// find the last variable declaration that any style depends on
|
|
221
|
+
let lastDependencyIndex = -1;
|
|
222
|
+
for (let i = 0; i < programBody.length; i++) {
|
|
223
|
+
const node = programBody[i];
|
|
224
|
+
if (node.type === 'VariableDeclaration') {
|
|
225
|
+
const varName = node.declarations[0]?.id.name;
|
|
226
|
+
if (varName) {
|
|
227
|
+
// check if this variable is a dependency of any style
|
|
228
|
+
for (const [, deps] of variableDependencies.entries()) {
|
|
229
|
+
if (deps.has(varName)) {
|
|
230
|
+
lastDependencyIndex = i;
|
|
231
|
+
break;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// insert after the last dependency
|
|
239
|
+
if (lastDependencyIndex !== -1) {
|
|
240
|
+
insertIndex = lastDependencyIndex + 1;
|
|
241
|
+
} else {
|
|
242
|
+
// if no dependencies, find the first non-import/type declaration
|
|
243
|
+
insertIndex = programBody.findIndex(
|
|
244
|
+
(node: { type: string }) =>
|
|
245
|
+
node.type !== 'ImportDeclaration' &&
|
|
246
|
+
node.type !== 'TypeAlias' &&
|
|
247
|
+
node.type !== 'InterfaceDeclaration',
|
|
248
|
+
);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
programBody.splice(insertIndex, 0, cssMapVariableDeclaration);
|
|
252
|
+
}
|
|
144
253
|
}
|
|
145
254
|
|
|
255
|
+
// First handle backgroundColor transformation for Box components
|
|
256
|
+
source
|
|
257
|
+
.find(j.JSXAttribute, {
|
|
258
|
+
name: {
|
|
259
|
+
type: 'JSXIdentifier',
|
|
260
|
+
name: 'xcss',
|
|
261
|
+
},
|
|
262
|
+
})
|
|
263
|
+
.forEach((path) => {
|
|
264
|
+
const value = path.node.value;
|
|
265
|
+
if (value && value.type === 'JSXExpressionContainer') {
|
|
266
|
+
const expression = value.expression;
|
|
267
|
+
const parentElement = path.parentPath?.node;
|
|
268
|
+
const isBoxComponent = parentElement?.name?.name === 'Box';
|
|
269
|
+
|
|
270
|
+
if (isBoxComponent) {
|
|
271
|
+
if (expression.type === 'Identifier') {
|
|
272
|
+
const styleKey = getCssMapKey(expression.name);
|
|
273
|
+
const styleObject = cssMapProperties.find(
|
|
274
|
+
(prop) => prop.key.type === 'Identifier' && prop.key.name === styleKey,
|
|
275
|
+
)?.value;
|
|
276
|
+
if (styleObject?.type === 'ObjectExpression') {
|
|
277
|
+
const backgroundColorProp = styleObject.properties.find(
|
|
278
|
+
(prop) =>
|
|
279
|
+
prop.type === 'ObjectProperty' &&
|
|
280
|
+
prop.key.type === 'Identifier' &&
|
|
281
|
+
prop.key.name === 'backgroundColor',
|
|
282
|
+
);
|
|
283
|
+
if (
|
|
284
|
+
backgroundColorProp?.type === 'ObjectProperty' &&
|
|
285
|
+
backgroundColorProp.value.type === 'StringLiteral'
|
|
286
|
+
) {
|
|
287
|
+
// add backgroundColor prop to Box component
|
|
288
|
+
parentElement.attributes.push(
|
|
289
|
+
j.jsxAttribute(
|
|
290
|
+
j.jsxIdentifier('backgroundColor'),
|
|
291
|
+
j.stringLiteral(backgroundColorProp.value.value),
|
|
292
|
+
),
|
|
293
|
+
);
|
|
294
|
+
// remove backgroundColor from cssMap
|
|
295
|
+
styleObject.properties = styleObject.properties.filter(
|
|
296
|
+
(prop) =>
|
|
297
|
+
!(
|
|
298
|
+
prop.type === 'ObjectProperty' &&
|
|
299
|
+
prop.key.type === 'Identifier' &&
|
|
300
|
+
prop.key.name === 'backgroundColor'
|
|
301
|
+
),
|
|
302
|
+
);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
} else if (expression.type === 'ArrayExpression') {
|
|
306
|
+
// handle array of styles
|
|
307
|
+
const backgroundColorValues: string[] = [];
|
|
308
|
+
expression.elements.forEach((element) => {
|
|
309
|
+
if (element?.type === 'Identifier') {
|
|
310
|
+
const styleKey = getCssMapKey(element.name);
|
|
311
|
+
const styleObject = cssMapProperties.find(
|
|
312
|
+
(prop) => prop.key.type === 'Identifier' && prop.key.name === styleKey,
|
|
313
|
+
)?.value;
|
|
314
|
+
if (styleObject?.type === 'ObjectExpression') {
|
|
315
|
+
const backgroundColorProp = styleObject.properties.find(
|
|
316
|
+
(prop) =>
|
|
317
|
+
prop.type === 'ObjectProperty' &&
|
|
318
|
+
prop.key.type === 'Identifier' &&
|
|
319
|
+
prop.key.name === 'backgroundColor',
|
|
320
|
+
);
|
|
321
|
+
if (
|
|
322
|
+
backgroundColorProp?.type === 'ObjectProperty' &&
|
|
323
|
+
backgroundColorProp.value.type === 'StringLiteral'
|
|
324
|
+
) {
|
|
325
|
+
backgroundColorValues.push(backgroundColorProp.value.value);
|
|
326
|
+
// remove backgroundColor from cssMap
|
|
327
|
+
styleObject.properties = styleObject.properties.filter(
|
|
328
|
+
(prop) =>
|
|
329
|
+
!(
|
|
330
|
+
prop.type === 'ObjectProperty' &&
|
|
331
|
+
prop.key.type === 'Identifier' &&
|
|
332
|
+
prop.key.name === 'backgroundColor'
|
|
333
|
+
),
|
|
334
|
+
);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
});
|
|
339
|
+
|
|
340
|
+
// if we found backgroundColor values, add to Box component
|
|
341
|
+
if (backgroundColorValues.length > 0) {
|
|
342
|
+
if (backgroundColorValues.length === 1) {
|
|
343
|
+
// single backgroundColor value
|
|
344
|
+
parentElement.attributes.push(
|
|
345
|
+
j.jsxAttribute(
|
|
346
|
+
j.jsxIdentifier('backgroundColor'),
|
|
347
|
+
j.stringLiteral(backgroundColorValues[0]),
|
|
348
|
+
),
|
|
349
|
+
);
|
|
350
|
+
} else {
|
|
351
|
+
// multiple backgroundColor values - use ternary for conditional
|
|
352
|
+
const conditions = expression.elements
|
|
353
|
+
.map((element, index) => {
|
|
354
|
+
if (
|
|
355
|
+
element?.type === 'LogicalExpression' &&
|
|
356
|
+
element.left.type === 'Identifier'
|
|
357
|
+
) {
|
|
358
|
+
return `${element.left.name} ? "${backgroundColorValues[index]}" :`;
|
|
359
|
+
}
|
|
360
|
+
return `"${backgroundColorValues[index]}"`;
|
|
361
|
+
})
|
|
362
|
+
.join(' ');
|
|
363
|
+
parentElement.attributes.push(
|
|
364
|
+
j.jsxAttribute(
|
|
365
|
+
j.jsxIdentifier('backgroundColor'),
|
|
366
|
+
j.jsxExpressionContainer(j.identifier(conditions)),
|
|
367
|
+
),
|
|
368
|
+
);
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
});
|
|
375
|
+
|
|
146
376
|
// update the xcss prop references to use the new cssMap object
|
|
147
377
|
source
|
|
148
378
|
.find(j.JSXAttribute, {
|
|
@@ -160,7 +390,7 @@ function replaceXcssWithCssMap(
|
|
|
160
390
|
// <Box xcss={buttonStyles} /> -> <Box xcss={styles.button} />
|
|
161
391
|
expression.name = `styles.${getCssMapKey(expression.name)}`;
|
|
162
392
|
} else if (expression.type === 'ArrayExpression') {
|
|
163
|
-
// <Box xcss={[baseStyles, otherStyles]} /> -> <Box xcss={[styles.base, styles.
|
|
393
|
+
// <Box xcss={[baseStyles, otherStyles]} /> -> <Box xcss={[styles.base, styles.other]} />
|
|
164
394
|
expression.elements.forEach((element) => {
|
|
165
395
|
if (element?.type === 'Identifier') {
|
|
166
396
|
element.name = `styles.${getCssMapKey(element.name)}`;
|
|
@@ -25,7 +25,7 @@ Emotion and Compiled, such as dynamic styles or imports. Please use the
|
|
|
25
25
|
We have a codemod to assist in migrations from `xcss()` to `@atlaskit/css`.
|
|
26
26
|
|
|
27
27
|
```sh
|
|
28
|
-
npx @hypermod/cli --packages @atlaskit/css
|
|
28
|
+
npx @hypermod/cli --packages @atlaskit/css#primitives-emotion-to-compiled ./path/to/folder
|
|
29
29
|
```
|
|
30
30
|
|
|
31
31
|
The codemod should migrate something like this:
|
|
@@ -18,7 +18,7 @@ import UnboundedExample from '../../examples/constellation/unbounded';
|
|
|
18
18
|
|
|
19
19
|
`@atlaskit/css` is the replacement for `@atlaskit/primitives.xcss`. It serves as a bounded styling
|
|
20
20
|
library for use with native HTML elements and the Atlassian Design System, including
|
|
21
|
-
[primitive components](/components/primitives).
|
|
21
|
+
[primitive components](/components/primitives/overview).
|
|
22
22
|
|
|
23
23
|
Built on [Compiled CSS-in-JS](https://compiledcssinjs.com/), it provides a performant, static
|
|
24
24
|
styling solution with some syntax changes. Notably, dynamic styles and certain imports/exports may
|
|
@@ -39,7 +39,7 @@ values, such as `color: 'rgba(123, 45, 67)'` nor `padding: 8`. Typically, only t
|
|
|
39
39
|
allowed. Additionally, there are some restrictions, such as `zIndex`, which only supports a limited
|
|
40
40
|
set of numeric values.
|
|
41
41
|
|
|
42
|
-
### cssMap
|
|
42
|
+
### cssMap()
|
|
43
43
|
|
|
44
44
|
We recommend using `cssMap` to create style maps. These maps can be applied and reused on both
|
|
45
45
|
native elements and React components using `props.css` and `props.xcss` respectively.
|
|
@@ -48,6 +48,22 @@ Make sure to define the styles before using them in your components, i.e. at the
|
|
|
48
48
|
|
|
49
49
|
<Example Component={CssMapExample} packageName="@atlaskit/css" />
|
|
50
50
|
|
|
51
|
+
### css()
|
|
52
|
+
|
|
53
|
+
The `css()` function is a lower-level API that creates a single style object. Unlike `cssMap()`,
|
|
54
|
+
it's best suited for one-off styles. Use it with elements that accept a `css` prop. While `css()` is
|
|
55
|
+
simpler to use, we recommend `cssMap()` for most cases because it provides better reusability and
|
|
56
|
+
type safety.
|
|
57
|
+
|
|
58
|
+
```tsx
|
|
59
|
+
const styles = css({
|
|
60
|
+
padding: token('space.100'),
|
|
61
|
+
color: token('color.text'),
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
<div css={styles}>Hello world!</div>;
|
|
65
|
+
```
|
|
66
|
+
|
|
51
67
|
### Primitives
|
|
52
68
|
|
|
53
69
|
When using `@atlaskit/css`, it's important to note that it's not compatible with the Emotion variant
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/css",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.5",
|
|
4
4
|
"description": "Style components backed by Atlassian Design System design tokens powered by Compiled CSS-in-JS.",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"./test-utils": "./src/test-utils/index.tsx"
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
|
-
"@atlaskit/tokens": "^4.
|
|
51
|
+
"@atlaskit/tokens": "^4.6.0",
|
|
52
52
|
"@babel/runtime": "^7.0.0",
|
|
53
53
|
"@compiled/react": "^0.18.3"
|
|
54
54
|
},
|
|
@@ -57,13 +57,13 @@
|
|
|
57
57
|
},
|
|
58
58
|
"devDependencies": {
|
|
59
59
|
"@af/visual-regression": "^1.3.0",
|
|
60
|
-
"@atlaskit/button": "^
|
|
60
|
+
"@atlaskit/button": "^23.0.0",
|
|
61
61
|
"@atlaskit/ds-lib": "^4.0.0",
|
|
62
|
-
"@atlaskit/primitives": "^14.
|
|
62
|
+
"@atlaskit/primitives": "^14.3.0",
|
|
63
63
|
"@emotion/react": "^11.7.1",
|
|
64
64
|
"@testing-library/react": "^13.4.0",
|
|
65
65
|
"@types/jscodeshift": "^0.11.0",
|
|
66
|
-
"jscodeshift": "^0.
|
|
66
|
+
"jscodeshift": "^17.0.0",
|
|
67
67
|
"react-dom": "^18.2.0",
|
|
68
68
|
"typescript": "~5.4.2"
|
|
69
69
|
},
|