@atlaskit/css 0.6.0 → 0.6.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/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # @atlaskit/css
2
2
 
3
+ ## 0.6.2
4
+
5
+ ### Patch Changes
6
+
7
+ - [#165531](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/165531)
8
+ [`57f451bda8919`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/57f451bda8919) -
9
+ Adds side-effect config to support Compiled css extraction in third-party apps
10
+
11
+ ## 0.6.1
12
+
13
+ ### Patch Changes
14
+
15
+ - [#160054](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/160054)
16
+ [`a85c8b06aad62`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/a85c8b06aad62) -
17
+ Updates to the 0.5.2-primitives-emotion-to-compiled codemod to group imports from
18
+ @atlaskit/primitives.
19
+
3
20
  ## 0.6.0
4
21
 
5
22
  ### Minor Changes
@@ -50,8 +50,6 @@ const styleMaps = {
50
50
  export default function transformer(fileInfo: FileInfo, { jscodeshift: j }: API, options: Options) {
51
51
  const base = j(fileInfo.source);
52
52
 
53
- addJsxPragma(j, base);
54
-
55
53
  // replace xcss with cssMap
56
54
  const xcssSpecifier = getImportSpecifier(j, base, 'xcss');
57
55
  if (!xcssSpecifier) {
@@ -62,6 +60,8 @@ export default function transformer(fileInfo: FileInfo, { jscodeshift: j }: API,
62
60
 
63
61
  updateImports(j, base);
64
62
 
63
+ addJsxPragma(j, base);
64
+
65
65
  return base.toSource();
66
66
  }
67
67
 
@@ -221,20 +221,34 @@ function ensureSelectorAmpersand(j: core.JSCodeshift, objectExpression: core.Obj
221
221
  }
222
222
 
223
223
  function updateImports(j: core.JSCodeshift, source: ReturnType<typeof j>) {
224
- // remove xcss import
224
+ // remove xcss import and collect primitives to import
225
+ const primitivesToImport = new Set<string>();
225
226
  source
226
227
  .find(j.ImportDeclaration)
227
- .filter((path: ASTPath<ImportDeclaration>) => path.node.source.value === '@atlaskit/primitives')
228
+ .filter((path: ASTPath<ImportDeclaration>) => {
229
+ const importSource = path.node.source.value as string;
230
+ return (
231
+ importSource === '@atlaskit/primitives' || importSource.startsWith('@atlaskit/primitives/')
232
+ );
233
+ })
228
234
  .forEach((path) => {
229
235
  if (path.node.specifiers) {
230
- path.node.specifiers = path.node.specifiers.filter(
231
- (specifier) => specifier.local?.name !== 'xcss',
232
- );
233
- if (path.node.specifiers.length === 0) {
234
- // if no specifiers remain, remove the import
235
- j(path).remove();
236
- }
236
+ path.node.specifiers.forEach((specifier) => {
237
+ if (specifier.type === 'ImportSpecifier' && specifier.imported) {
238
+ const importedName = specifier.imported.name;
239
+ if (importedName !== 'xcss') {
240
+ primitivesToImport.add(importedName);
241
+ }
242
+ } else if (specifier.type === 'ImportDefaultSpecifier') {
243
+ // handle deep imports like `import Anchor from '@atlaskit/primitives/anchor'`
244
+ if (specifier.local) {
245
+ primitivesToImport.add(specifier.local.name);
246
+ }
247
+ }
248
+ });
237
249
  }
250
+ // remove the import declaration
251
+ j(path).remove();
238
252
  });
239
253
 
240
254
  const importsNeeded = {
@@ -245,18 +259,17 @@ function updateImports(j: core.JSCodeshift, source: ReturnType<typeof j>) {
245
259
 
246
260
  // check existing imports
247
261
  source.find(j.ImportDeclaration).forEach((path) => {
248
- switch (path.node.source.value) {
262
+ const importSource = path.node.source.value as string;
263
+ switch (importSource) {
249
264
  case '@atlaskit/css':
250
- if (path.node.specifiers) {
251
- path.node.specifiers.forEach((specifier) => {
252
- if (specifier.local?.name === 'cssMap') {
253
- importsNeeded.cssMap = true;
254
- }
255
- if (specifier.local?.name === 'jsx') {
256
- importsNeeded.jsx = true;
257
- }
258
- });
259
- }
265
+ path.node.specifiers?.forEach((specifier) => {
266
+ if (specifier.local?.name === 'cssMap') {
267
+ importsNeeded.cssMap = true;
268
+ }
269
+ if (specifier.local?.name === 'jsx') {
270
+ importsNeeded.jsx = true;
271
+ }
272
+ });
260
273
  break;
261
274
  case '@atlaskit/tokens':
262
275
  importsNeeded.token = true;
@@ -264,7 +277,17 @@ function updateImports(j: core.JSCodeshift, source: ReturnType<typeof j>) {
264
277
  case '@emotion/react':
265
278
  // remove the jsx import from @emotion/react
266
279
  path.node.specifiers = path.node.specifiers?.filter(
267
- (specifier) => j.ImportSpecifier.check(specifier) && specifier.imported.name !== 'jsx',
280
+ (specifier) => !(j.ImportSpecifier.check(specifier) && specifier.imported.name === 'jsx'),
281
+ );
282
+ if (path.node.specifiers?.length === 0) {
283
+ j(path).remove();
284
+ }
285
+ break;
286
+ case 'react':
287
+ // remove default import React from 'react' if not needed
288
+ path.node.specifiers = path.node.specifiers?.filter(
289
+ (specifier) =>
290
+ !(specifier.type === 'ImportDefaultSpecifier' && specifier.local?.name === 'React'),
268
291
  );
269
292
  if (path.node.specifiers?.length === 0) {
270
293
  j(path).remove();
@@ -275,15 +298,47 @@ function updateImports(j: core.JSCodeshift, source: ReturnType<typeof j>) {
275
298
 
276
299
  const newImports: ImportDeclaration[] = [];
277
300
 
278
- if (!importsNeeded.cssMap || !importsNeeded.jsx) {
279
- // add cssMap and jsx together if either is missing
280
- const cssMapImport = j.importDeclaration(
281
- [j.importSpecifier(j.identifier('cssMap')), j.importSpecifier(j.identifier('jsx'))],
282
- j.literal('@atlaskit/css'),
301
+ // add grouped import for primitives
302
+ // e.g. import { Anchor, Box } from '@atlaskit/primitives/compiled';
303
+ if (primitivesToImport.size > 0) {
304
+ const primitivesImport = j.importDeclaration(
305
+ Array.from(primitivesToImport)
306
+ .sort()
307
+ .map((name) => j.importSpecifier(j.identifier(name))),
308
+ j.literal('@atlaskit/primitives/compiled'),
283
309
  );
284
- newImports.push(cssMapImport);
310
+ newImports.push(primitivesImport);
311
+ }
312
+
313
+ // add cssMap and jsx import if needed
314
+ if (!importsNeeded.cssMap || !importsNeeded.jsx) {
315
+ const existingCssImports = source
316
+ .find(j.ImportDeclaration)
317
+ .filter((path) => path.node.source.value === '@atlaskit/css');
318
+
319
+ const newSpecifiers: core.ImportSpecifier[] = [];
320
+
321
+ if (!importsNeeded.cssMap) {
322
+ newSpecifiers.push(j.importSpecifier(j.identifier('cssMap')));
323
+ }
324
+ if (!importsNeeded.jsx) {
325
+ newSpecifiers.push(j.importSpecifier(j.identifier('jsx')));
326
+ }
327
+
328
+ if (existingCssImports.size() > 0) {
329
+ // existing import from '@atlaskit/css'
330
+ const existingCssImport = existingCssImports.at(0).get();
331
+
332
+ if (existingCssImport && existingCssImport.node.specifiers) {
333
+ existingCssImport.node.specifiers.push(...newSpecifiers);
334
+ }
335
+ } else {
336
+ const cssMapImport = j.importDeclaration(newSpecifiers, j.literal('@atlaskit/css'));
337
+ newImports.push(cssMapImport);
338
+ }
285
339
  }
286
340
 
341
+ // add token import
287
342
  if (!importsNeeded.token) {
288
343
  const tokenImport = j.importDeclaration(
289
344
  [j.importSpecifier(j.identifier('token'))],
@@ -292,26 +347,7 @@ function updateImports(j: core.JSCodeshift, source: ReturnType<typeof j>) {
292
347
  newImports.push(tokenImport);
293
348
  }
294
349
 
295
- // remove default import React from 'react' if not needed
296
- source.find(j.ImportDeclaration, { source: { value: 'react' } }).forEach((path) => {
297
- path.node.specifiers = path.node.specifiers?.filter(
298
- (specifier) =>
299
- !(specifier.type === 'ImportDefaultSpecifier' && specifier.local?.name === 'React'),
300
- );
301
- if (path.node.specifiers?.length === 0) {
302
- j(path).remove();
303
- }
304
- });
305
-
306
- // update @atlaskit/primitives imports to @atlaskit/primitives/compiled
307
- source
308
- .find(j.ImportDeclaration)
309
- .filter((path: ASTPath<ImportDeclaration>) => path.node.source.value === '@atlaskit/primitives')
310
- .forEach((path) => {
311
- path.node.source.value = '@atlaskit/primitives/compiled';
312
- });
313
-
314
- // add new imports after any existing comments to ensure they're below the jsx pragma
350
+ // add new imports after any existing comments
315
351
  const rootNode = source.get().node;
316
352
  const firstNonCommentIndex = rootNode.program.body.findIndex(
317
353
  (node: core.Node) =>
@@ -846,14 +846,15 @@ export type Fill = keyof typeof fillMap;
846
846
 
847
847
  /**
848
848
  * THIS SECTION WAS CREATED VIA CODEGEN DO NOT MODIFY {@see http://go/af-codegen}
849
- * @codegen <<SignedSource::dbfb4c7de16d0ae4a53d66f9663aca91>>
849
+ * @codegen <<SignedSource::042cbfe8041c09e3817ae74154994f32>>
850
850
  * @codegenId misc
851
851
  * @codegenCommand yarn workspace @atlaskit/primitives codegen-styles
852
852
  * @codegenParams ["layer"]
853
853
  * @codegenDependency ../../../primitives/scripts/codegen-file-templates/dimensions.tsx <<SignedSource::cc9b3f12104c6ede803da6a42daac0b0>>
854
- * @codegenDependency ../../../primitives/scripts/codegen-file-templates/layer.tsx <<SignedSource::6f10945ad9139d0119003738c65ae40a>>
854
+ * @codegenDependency ../../../primitives/scripts/codegen-file-templates/layer.tsx <<SignedSource::92793ca02dbfdad66e53ffbe9f0baa0a>>
855
855
  */
856
856
  export const layerMap = {
857
+ '1': 1,
857
858
  card: 100,
858
859
  navigation: 200,
859
860
  dialog: 300,
@@ -906,12 +907,12 @@ export type BorderRadius = keyof typeof borderRadiusMap;
906
907
 
907
908
  /**
908
909
  * THIS SECTION WAS CREATED VIA CODEGEN DO NOT MODIFY {@see http://go/af-codegen}
909
- * @codegen <<SignedSource::97e5ae47f252660a5ef7569a3880c26c>>
910
+ * @codegen <<SignedSource::96d9a841cb440c2bd770d0af5c670f10>>
910
911
  * @codegenId typography
911
912
  * @codegenCommand yarn workspace @atlaskit/primitives codegen-styles
912
913
  * @codegenParams ["fontSize", "fontWeight", "fontFamily", "lineHeight", "body", "ui"]
913
914
  * @codegenDependency ../../../primitives/scripts/codegen-file-templates/dimensions.tsx <<SignedSource::cc9b3f12104c6ede803da6a42daac0b0>>
914
- * @codegenDependency ../../../primitives/scripts/codegen-file-templates/layer.tsx <<SignedSource::6f10945ad9139d0119003738c65ae40a>>
915
+ * @codegenDependency ../../../primitives/scripts/codegen-file-templates/layer.tsx <<SignedSource::92793ca02dbfdad66e53ffbe9f0baa0a>>
915
916
  */
916
917
  export const fontMap = {
917
918
  'font.body': token(
@@ -1006,11 +1007,11 @@ export type FontFamily = keyof typeof fontFamilyMap;
1006
1007
 
1007
1008
  /**
1008
1009
  * THIS SECTION WAS CREATED VIA CODEGEN DO NOT MODIFY {@see http://go/af-codegen}
1009
- * @codegen <<SignedSource::7dc7abf82a13bc780c338b9602508ae6>>
1010
+ * @codegen <<SignedSource::ae96213e36b930556f9ad18382088ff8>>
1010
1011
  * @codegenId text
1011
1012
  * @codegenCommand yarn workspace @atlaskit/primitives codegen-styles
1012
1013
  * @codegenDependency ../../../primitives/scripts/codegen-file-templates/dimensions.tsx <<SignedSource::cc9b3f12104c6ede803da6a42daac0b0>>
1013
- * @codegenDependency ../../../primitives/scripts/codegen-file-templates/layer.tsx <<SignedSource::6f10945ad9139d0119003738c65ae40a>>
1014
+ * @codegenDependency ../../../primitives/scripts/codegen-file-templates/layer.tsx <<SignedSource::92793ca02dbfdad66e53ffbe9f0baa0a>>
1014
1015
  */
1015
1016
  export const textSizeMap = {
1016
1017
  medium: token(
@@ -2,21 +2,24 @@
2
2
  order: 1
3
3
  ---
4
4
 
5
+ import SectionMessage from '@atlaskit/section-message';
6
+
5
7
  ## Migration to `@atlaskit/css`
6
8
 
7
- `@atlaskit/css` is the replacement for `@atlaskit/primitives/xcss` which will only work with the
8
- Compiled variants of packages, eg. `@atlaskit/primitives/compiled` (note that not all packages will
9
- be migrated to Compiled by the end of 2024).
9
+ <SectionMessage title="Migration from Emotion to Compiled" appearance="discovery">
10
+ <p>
11
+ The Atlassian Design System is migrating from Emotion to Compiled CSS-in-JS. This transition
12
+ aims to improve performance and align with modern React features.{' '}
13
+ <a href="https://community.developer.atlassian.com/t/rfc-73-migrating-our-components-to-compiled-css-in-js/85953">
14
+ Read our RFC to learn more.
15
+ </a>
16
+ </p>
17
+ </SectionMessage>
10
18
 
11
- Typically, this migration means moving from the `const styles = xcss({ padding: 'space.100' })` API
12
- to a `const styles = cssMap({ root: { padding: token('space.100') } })` API, and we have a codemod
13
- to assist with a majority of this migration for you. Some things are not available in the Compiled
14
- API such as dynamic styles or imports, please use the
19
+ We have a codemod available to support this migration, but there are some breaking changes between
20
+ Emotion and Compiled, such as dynamic styles or imports. Please use the
15
21
  [UI Styling Standard ESLint Plugin](/components/eslint-plugin-ui-styling-standard/) to guide you.
16
22
 
17
- Refer to [Configuration required](/components/css/examples#configuration-required) for details on
18
- how to configure your project to use `@atlaskit/css`
19
-
20
23
  ## Codemod
21
24
 
22
25
  We have a codemod to assist in migrations from `xcss()` to `@atlaskit/css`.
@@ -53,6 +56,10 @@ The codemod should migrate something like this:
53
56
  +export const MyComponent = () => <Box xcss={styles.root} />;
54
57
  ```
55
58
 
59
+ The codemod will migrate most usecases, but there is a known issue that it's unable to handle any
60
+ logical operators in the `xcss` property. If you have any logical operators in your `xcss` property,
61
+ you will need to manually update them.
62
+
56
63
  Please note there may be very minute differences in this migration if you do not have theming
57
64
  enabled as `@atlaskit/primitives` and the Compiled variant of `@atlaskit/primitives/compiled` have
58
65
  different fallback colors. They are unchanged with theming applied, this will only happen if you're
@@ -0,0 +1,276 @@
1
+ ---
2
+ order: 0
3
+ ---
4
+
5
+ import SectionMessage from '@atlaskit/section-message';
6
+
7
+ <SectionMessage title="Migration from Emotion to Compiled" appearance="discovery">
8
+ <p>
9
+ The Atlassian Design System is migrating from Emotion to Compiled CSS-in-JS. This transition
10
+ aims to improve performance and align with modern React features.{' '}
11
+ <a href="https://community.developer.atlassian.com/t/rfc-73-migrating-our-components-to-compiled-css-in-js/85953">
12
+ Read our RFC to learn more.
13
+ </a>
14
+ </p>
15
+ </SectionMessage>
16
+
17
+ `@atlaskit/css` is the replacement for `@atlaskit/primitives.xcss`. It serves as a bounded styling
18
+ library for use with native HTML elements and the Atlassian Design System, including
19
+ [primitive components](/components/primitives).
20
+
21
+ Built on [Compiled CSS-in-JS](https://compiledcssinjs.com/), it provides a performant, static
22
+ styling solution with some syntax changes. Notably, dynamic styles and certain imports/exports may
23
+ not work as before.
24
+
25
+ For configuration details, see our
26
+ [Get Started](/get-started/develop#set-up-your-bundling-environment) guide.
27
+
28
+ ## Usage
29
+
30
+ `@atlaskit/css` closely resembles the behavior of `@compiled/react` and other CSS-in-JS libraries'
31
+ `css()` functions. However, we encourage using `cssMap` to create style maps, as the common practice
32
+ at Atlassian.
33
+
34
+ This is a strictly bounded variant designed to align the use of
35
+ [Design System tokens](<(/components/tokens/all-tokens)>) and properties. You cannot use arbitrary
36
+ values, such as `color: 'rgba(123, 45, 67)'` nor `padding: 8`. Typically, only tokenized values are
37
+ allowed. Additionally, there are some restrictions, such as `zIndex`, which only supports a limited
38
+ set of numeric values.
39
+
40
+ ### cssMap
41
+
42
+ We recommend using `cssMap` to create style maps. These maps can be applied and reused on both
43
+ native elements and React components using `props.css` and `props.xcss`.
44
+
45
+ ```tsx
46
+ /**
47
+ * @jsxRuntime classic
48
+ * @jsx jsx
49
+ */
50
+ import { cssMap } from '@atlaskit/css';
51
+ const styles = cssMap({
52
+ root: { display: 'inline-block' },
53
+ primary: {
54
+ backgroundColor: token('color.background.brand.bold'),
55
+ color: token('color.text.inverse'),
56
+ },
57
+ discovery: {
58
+ backgroundColor: token('color.background.discovery.bold'),
59
+ color: token('color.text.inverse'),
60
+ },
61
+ success: {
62
+ backgroundColor: token('color.background.success.bold'),
63
+ color: token('color.text.inverse'),
64
+ },
65
+ disabled: { opacity: 0.7, cursor: 'not-allowed' },
66
+ });
67
+ export default ({
68
+ appearance = 'primary',
69
+ isDisabled,
70
+ }: {
71
+ appearance?: 'primary' | 'discovery' | 'success';
72
+ isDisabled?: boolean;
73
+ }) => <div css={(styles.root, styles[appearance], isDisabled && styles.disabled)} />;
74
+ ```
75
+
76
+ ### cx
77
+
78
+ Use the `cx` function when combining styles in an `xcss` prop to maintain correct typing. This is
79
+ not required for native elements, but still works with or without.
80
+
81
+ ```tsx
82
+ <div css={[styles.root, styles.bordered]} />
83
+ <div css={cx(styles.root, styles.bordered)} />
84
+ <Box xcss={cx(styles.root, styles.bordered)} />
85
+ ```
86
+
87
+ ### JSX pragma
88
+
89
+ You must have a JSX pragma in scope in order to use this, depending on your setup this may be
90
+ automatic, require `React` imported, or require `jsx` imported.
91
+
92
+ ```tsx
93
+ /**
94
+ * @jsxRuntime classic
95
+ * @jsx jsx
96
+ */
97
+ import { cssMap, cx, jsx } from '@atlaskit/css';
98
+ import { Box } from '@atlaskit/primitives/compiled';
99
+ import { token } from '@atlaskit/tokens';
100
+
101
+ const styles = cssMap({
102
+ root: {
103
+ padding: token('space.100'),
104
+ color: token('color.text'),
105
+ backgroundColor: token('elevation.surface'),
106
+ },
107
+ compact: { padding: token('space.50') },
108
+ transparent: { backgroundColor: 'transparent' },
109
+ });
110
+
111
+ export default ({
112
+ spacing = 'default',
113
+ noBackground,
114
+ }: {
115
+ spacing: 'compact' | 'default';
116
+ noBackground?: boolean;
117
+ }) => {
118
+ return (
119
+ <Box
120
+ xcss={cx(
121
+ styles.root,
122
+ spacing === 'compact' && styles.compact,
123
+ noBackground && styles.transparent,
124
+ )}
125
+ >
126
+ <p css={[styles.compact, styles.transparent]}>Hello world!</p>
127
+ </Box>
128
+ );
129
+ };
130
+ ```
131
+
132
+ ## Building reusable components
133
+
134
+ With the introduction of `@atlaskit/css`, and leveraging the underlying `createStrictAPI` from
135
+ Compiled, we've established a strictly bounded API for our components. This approach ensures
136
+ consistency and alignment with our Design System, and it might be an API pattern you find beneficial
137
+ to adopt in your own projects.
138
+
139
+ For instance, if you want to create a component that allows you to extend and pass-through styles,
140
+ you can do so:
141
+
142
+ ```tsx
143
+ /**
144
+ * @jsxRuntime classic
145
+ * @jsx jsx
146
+ */
147
+ import { cssMap, cx, jsx, type StrictXCSSProp } from '@atlaskit/css';
148
+ import { token } from '@atlaskit/tokens';
149
+
150
+ const styles = cssMap({
151
+ button: { padding: token('space.100'), borderRadius: token('border.radius.100') },
152
+ dense: { padding: token('space.050'), borderRadius: token('border.radius.050') },
153
+ });
154
+
155
+ export function Card({
156
+ children,
157
+ xcss,
158
+ isDense,
159
+ }: {
160
+ children: React.ReactNode;
161
+ isDense?: boolean;
162
+ xcss?: StrictXCSSProp<
163
+ 'padding' | 'borderRadius' | 'backgroundColor' | 'color',
164
+ '&:hover' | '&:focus'
165
+ >;
166
+ }) {
167
+ return (
168
+ <div css={cx(styles.button, isDense && styles.dense)} className={xcss}>
169
+ {children}
170
+ </div>
171
+ );
172
+ }
173
+ ```
174
+
175
+ You can then build a component using this Card component and override its properties as needed:
176
+
177
+ ```tsx
178
+ /**
179
+ * @jsxRuntime classic
180
+ * @jsx jsx
181
+ */
182
+ import { cssMap, cx, jsx, type StrictXCSSProp } from '@atlaskit/css';
183
+ import { token } from '@atlaskit/tokens';
184
+ import { Card } from './Card';
185
+
186
+ const styles = cssMap({
187
+ root: { padding: token('space.200'), borderRadius: token('border.radius.200') },
188
+ inverse: {
189
+ backgroundColor: token('color.background.discovery'),
190
+ color: token('color.text.inverse'),
191
+ },
192
+ });
193
+
194
+ export const LargeCard = ({
195
+ children,
196
+ isInverse,
197
+ }: {
198
+ children: React.ReactNode;
199
+ isInverse?: boolean;
200
+ }) => {
201
+ return <Card xcss={cx(styles.root, isInverse && styles.inverse)}>{children}</Card>;
202
+ };
203
+ ```
204
+
205
+ However, if you're extending a component that uses `props.xcss` under the hood, for example a
206
+ Primitive, the first `Card` component would look a bit different, brief example:
207
+
208
+ ```tsx
209
+ /**
210
+ * @jsxRuntime classic
211
+ * @jsx jsx
212
+ */
213
+ import { cssMap, cx, jsx, type StrictXCSSProp } from '@atlaskit/css';
214
+ import { Box } from '@atlaskit/primitives/compiled';
215
+ import { token } from '@atlaskit/tokens';
216
+
217
+ const styles = cssMap({
218
+ button: { padding: token('space.100'), borderRadius: token('border.radius.100') },
219
+ });
220
+
221
+ export function Card({
222
+ children,
223
+ xcss,
224
+ }: {
225
+ children: React.ReactNode;
226
+ xcss?: StrictXCSSProp<'padding' | 'borderRadius'>;
227
+ }) {
228
+ return <Box xcss={cx(styles.button, xcss)}>{children}</Box>;
229
+ }
230
+ ```
231
+
232
+ ### Unbounded styles
233
+
234
+ If you need to apply styles that aren't tokenized, or styles that aren't within the `@atlaskit/css`
235
+ API, you can use the `cssMap()` function from `@compiled/react` directly on native HTML elements.
236
+ Note that this won't work on primitive components. While it's best to stick to the Design System
237
+ guidelines, this option can be useful for handling specific edge cases. Please note this isn't
238
+ recommended for general use.
239
+
240
+ ```tsx
241
+ /**
242
+ * @jsxRuntime classic
243
+ * @jsx jsx
244
+ */
245
+ import { cssMap } from '@compiled/react';
246
+
247
+ import { jsx } from '@atlaskit/css';
248
+ import { token } from '@atlaskit/tokens';
249
+
250
+ const unboundedStyles = cssMap({
251
+ container: {
252
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-selectors
253
+ '&:first-child': {
254
+ paddingBlockEnd: token('space.150'),
255
+ },
256
+ '@media (min-width: 48rem)': {
257
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-selectors
258
+ '&:first-child': {
259
+ paddingBlockStart: token('space.400'),
260
+ },
261
+ },
262
+ },
263
+ });
264
+
265
+ const Container = ({ children, testId }: ContainerProps) => (
266
+ <div css={unboundedStyles.container} data-testid={testId}>
267
+ {children}
268
+ </div>
269
+ );
270
+ ```
271
+
272
+ ## Configuration required
273
+
274
+ In order to use any Atlassian Design System packages that distribute Compiled CSS-in-JS, you
275
+ **must** configure your project, please refer to our
276
+ [Get started](/get-started/develop#set-up-your-bundling-environment) guide.
package/dist/cjs/index.js CHANGED
@@ -1,4 +1,4 @@
1
- /* index.tsx generated by @compiled/babel-plugin v0.32.1 */
1
+ /* index.tsx generated by @compiled/babel-plugin v0.32.2 */
2
2
  "use strict";
3
3
 
4
4
  var _typeof = require("@babel/runtime/helpers/typeof");
@@ -1,4 +1,4 @@
1
- /* index.tsx generated by @compiled/babel-plugin v0.32.1 */
1
+ /* index.tsx generated by @compiled/babel-plugin v0.32.2 */
2
2
  import * as React from 'react';
3
3
  import { ax, ix } from "@compiled/react/runtime";
4
4
  import { createStrictAPI } from '@compiled/react';
package/dist/esm/index.js CHANGED
@@ -1,4 +1,4 @@
1
- /* index.tsx generated by @compiled/babel-plugin v0.32.1 */
1
+ /* index.tsx generated by @compiled/babel-plugin v0.32.2 */
2
2
  import * as React from 'react';
3
3
  import { ax, ix } from "@compiled/react/runtime";
4
4
  import { createStrictAPI } from '@compiled/react';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/css",
3
- "version": "0.6.0",
3
+ "version": "0.6.2",
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",
@@ -15,7 +15,14 @@
15
15
  "category": "Libraries",
16
16
  "ignorePropTypes": true,
17
17
  "status": {
18
- "type": "alpha"
18
+ "type": "beta",
19
+ "description": "The Atlassian Design System is migrating from Emotion to Compiled CSS-in-JS. This transition aims to improve performance and align with modern React features.",
20
+ "actions": [
21
+ {
22
+ "text": "View RFC",
23
+ "href": "https://community.developer.atlassian.com/t/rfc-73-migrating-our-components-to-compiled-css-in-js/85953"
24
+ }
25
+ ]
19
26
  }
20
27
  }
21
28
  },
@@ -32,13 +39,15 @@
32
39
  ]
33
40
  }
34
41
  },
35
- "sideEffects": false,
42
+ "sideEffects": [
43
+ "**/*.compiled.css"
44
+ ],
36
45
  "atlaskit:src": "src/index.tsx",
37
46
  "af:exports": {
38
47
  ".": "./src/index.tsx"
39
48
  },
40
49
  "dependencies": {
41
- "@atlaskit/tokens": "^2.0.0",
50
+ "@atlaskit/tokens": "^2.2.0",
42
51
  "@babel/runtime": "^7.0.0",
43
52
  "@compiled/react": "^0.18.1"
44
53
  },
@@ -48,7 +57,7 @@
48
57
  "devDependencies": {
49
58
  "@af/integration-testing": "*",
50
59
  "@af/visual-regression": "*",
51
- "@atlaskit/ds-lib": "^3.1.0",
60
+ "@atlaskit/ds-lib": "^3.2.0",
52
61
  "@atlaskit/ssr": "*",
53
62
  "@atlaskit/visual-regression": "*",
54
63
  "@emotion/react": "^11.7.1",
@@ -1,366 +0,0 @@
1
- ---
2
- order: 0
3
- ---
4
-
5
- import SectionMessage from '@atlaskit/section-message';
6
-
7
- <SectionMessage title="Migration from Emotion to Compiled" appearance="discovery">
8
- <p>
9
- The Atlassian Design System is under the process of migrating from Emotion to Compiled for our
10
- CSS-in-JS. Further details to come.
11
- </p>
12
- </SectionMessage>
13
-
14
- `@atlaskit/css` is the replacement for `@atlaskit/primitives.xcss`, refer to
15
- [Migration](/components/css/migration) for details migrating.
16
-
17
- This is a bounded styling library to be used both with native styles (`<div>`) and the Atlassian
18
- Design System, such as our [primitive components](/components/primitives).
19
-
20
- This is built on top of [Compiled CSS-in-JS](https://compiledcssinjs.com/) which is a much more
21
- performant, static styling solution with the same syntax and a few breaking changes—the primary ones
22
- being dynamic styles as well as deep imports or exports for reuse of styles may not work.
23
-
24
- This will require major configuration, noted below.
25
-
26
- ## Usage
27
-
28
- For the most part, `@atlaskit/css` should behave like `@compiled/react` or other CSS-in-JS
29
- libraries' `css()` syntaxes, however we promote `cssMap` as a way to create maps of styles as that's
30
- the common use-case at Atlassian.
31
-
32
- Please note that `@atlaskit/css` is a strictly bounded variant to help promote and align the usage
33
- of Design System tokens and properties, so you you cannot use arbitrary values such as
34
- `color: 'rgba(123, 45, 67)', padding: 8`, and typically we only allow our
35
- [tokenized values](/components/tokens/all-tokens), but a few other property restrictions or
36
- limitations exist, such as `zIndex` only having a few allowed literal numeric values.
37
-
38
- ### cssMap
39
-
40
- `cssMap` is the default function we suggest to use, it can be reused across native elements through
41
- `props.css` and React components through `props.xcss` and is flexible to style maps that are known
42
- ahead-of-time.
43
-
44
- These can be reused across multiple components, even across native and non-native.
45
-
46
- ```tsx
47
- import { cssMap } from '@atlaskit/css';
48
- const styles = cssMap({
49
- root: { display: 'inline-block' },
50
- primary: {
51
- backgroundColor: token('color.background.brand.bold'),
52
- color: token('color.text.inverse'),
53
- },
54
- discovery: {
55
- backgroundColor: token('color.background.discovery.bold'),
56
- color: token('color.text.inverse'),
57
- },
58
- success: {
59
- backgroundColor: token('color.background.success.bold'),
60
- color: token('color.text.inverse'),
61
- },
62
- disabled: { opacity: 0.7, cursor: 'not-allowed' },
63
- });
64
- export default ({
65
- appearance = 'primary',
66
- isDisabled,
67
- }: {
68
- appearance?: 'primary' | 'discovery' | 'success';
69
- isDisabled?: boolean;
70
- }) => <div css={(styles.root, styles[appearance], isDisabled && styles.disabled)} />;
71
- ```
72
-
73
- ### cx
74
-
75
- The `cx` function is required when combining styles inside of an `xcss` prop, but can be used
76
- anywhere. This is only required because `xcss={[styles.root, styles.bordered]}` results in incorrect
77
- typing while with a function it is preserved.
78
-
79
- ```tsx
80
- <div css={[styles.root, styles.bordered]} />
81
- <div css={cx(styles.root, styles.bordered)} />
82
- <Box xcss={cx(styles.root, styles.bordered)} />
83
- ```
84
-
85
- ### Typical example
86
-
87
- You must have a JSX pragma in scope in order to use this, depending on your setup this may be
88
- automatic, require `React` imported, or require `jsx` imported.
89
-
90
- ```tsx
91
- /**
92
- * @jsxRuntime classic
93
- * @jsx jsx
94
- */
95
- import { cssMap, cx, jsx } from '@atlaskit/css';
96
- import { Box } from '@atlaskit/primitives/compiled';
97
- import { token } from '@atlaskit/tokens';
98
-
99
- const styles = cssMap({
100
- root: {
101
- padding: token('space.100'),
102
- color: token('color.text'),
103
- backgroundColor: token('elevation.surface'),
104
- },
105
- compact: { padding: token('space.50') },
106
- transparent: { backgroundColor: 'transparent' },
107
- });
108
-
109
- export default ({
110
- spacing = 'default',
111
- noBackground,
112
- }: {
113
- spacing: 'compact' | 'default';
114
- noBackground?: boolean;
115
- }) => {
116
- return (
117
- <Box
118
- xcss={cx(
119
- styles.root,
120
- spacing === 'compact' && styles.compact,
121
- noBackground && styles.transparent,
122
- )}
123
- >
124
- <p css={[styles.compact, styles.transparent]}>Hello world!</p>
125
- </Box>
126
- );
127
- };
128
- ```
129
-
130
- ### Building a reusable component with pass-through styles
131
-
132
- With the introduction of `@atlaskit/css` (and the underlying `createStrictAPI` from Compiled), we're
133
- now able to define a strictly bounded API for our components. This may be an API pattern that you
134
- want to copy as well.
135
-
136
- For example, if you want to create your own component that allows you to extend and pass-through
137
- styles, you can do so:
138
-
139
- ```tsx
140
- /**
141
- * @jsxRuntime classic
142
- * @jsx jsx
143
- */
144
- import { cssMap, cx, jsx, type StrictXCSSProp } from '@atlaskit/css';
145
- import { token } from '@atlaskit/tokens';
146
-
147
- const styles = cssMap({
148
- button: { padding: token('space.100'), borderRadius: token('border.radius.100') },
149
- dense: { padding: token('space.050'), borderRadius: token('border.radius.050') },
150
- });
151
-
152
- export function Card({
153
- children,
154
- xcss,
155
- dense,
156
- }: {
157
- children: React.ReactNode;
158
- dense?: boolean;
159
- /** Only `padding`, `borderRadius`, `backgroundColor`, and `color` properties and `hover` and `focus` pseudos are allowed */
160
- xcss?: StrictXCSSProp<
161
- 'padding' | 'borderRadius' | 'backgroundColor' | 'color',
162
- '&:hover' | '&:focus'
163
- >;
164
- }) {
165
- return (
166
- <div css={cx(styles.button, isDense && styles.dense)} className={xcss}>
167
- {children}
168
- </div>
169
- );
170
- }
171
- ```
172
-
173
- I'm then allowed to build a component that uses this `Card` component and overrides these properties
174
- as I see fit:
175
-
176
- ```tsx
177
- /**
178
- * @jsxRuntime classic
179
- * @jsx jsx
180
- */
181
- import { cssMap, cx, jsx, type StrictXCSSProp } from '@atlaskit/css';
182
- import { token } from '@atlaskit/tokens';
183
- import { Card } from './Card';
184
-
185
- const styles = cssMap({
186
- root: { padding: token('space.200'), borderRadius: token('border.radius.200') },
187
- inverse: {
188
- backgroundColor: token('color.background.discovery'),
189
- color: token('color.text.inverse'),
190
- },
191
- });
192
-
193
- export const LargeCard = ({
194
- children,
195
- isInverse,
196
- }: {
197
- children: React.ReactNode;
198
- isInverse?: boolean;
199
- }) => {
200
- return <Card xcss={cx(styles.root, isInverse && styles.inverse)}>{children}</Card>;
201
- };
202
- ```
203
-
204
- However, if you're extending a component that uses `props.xcss` under the hood, for example a
205
- Primitive, the first `Card` component would look a bit different, brief example:
206
-
207
- ```tsx
208
- /**
209
- * @jsxRuntime classic
210
- * @jsx jsx
211
- */
212
- import { cssMap, cx, jsx, type StrictXCSSProp } from '@atlaskit/css';
213
- import { Box } from '@atlaskit/primitives/compiled';
214
- import { token } from '@atlaskit/tokens';
215
-
216
- const styles = cssMap({
217
- button: { padding: token('space.100'), borderRadius: token('border.radius.100') },
218
- });
219
-
220
- export function Card({
221
- children,
222
- xcss,
223
- }: {
224
- children: React.ReactNode;
225
- xcss?: StrictXCSSProp<'padding' | 'borderRadius'>;
226
- }) {
227
- return <Box xcss={cx(styles.button, xcss)}>{children}</Box>;
228
- }
229
- ```
230
-
231
- ## Configuration required
232
-
233
- <SectionMessage title="More details coming soon!" appearance="warning">
234
- <p>This section is under development, more details will come soon.</p>
235
- </SectionMessage>
236
-
237
- In order to use any Atlassian Design System packages that distribute Compiled CSS-in-JS, you
238
- **must** configure your project via Babel as well your bundler with Webpack and/or Parcel and using
239
- the latest version of these plugins:
240
-
241
- - `@atlaskit/tokens/babel-plugin`
242
- - `@compiled/babel-plugin` configured with `sortShorthand: true` (or configured through
243
- `@compiled/webpack-loader` or `@compiled/parcel-config` or similar)
244
- - **SUGGESTED:** You should turn on
245
- [@atlaskit/eslint-plugin-ui-styling-standard](/components/eslint-plugin-ui-styling-standard) to
246
- guide you
247
-
248
- Refer to https://compiledcssinjs.com/docs/installation
249
-
250
- ### Setup your Babel plugins
251
-
252
- Most products will use Babel across the dev lifecycle, so this is typically a baseline
253
- configuration.
254
-
255
- ```sh
256
- yarn install @atlaskit/tokens
257
- yarn install --dev @compiled/babel-plugin
258
- yarn install --dev @compiled/babel-plugin-strip-runtime # optional, for extracting styles
259
- ```
260
-
261
- Plugin order matters, your `@atlaskit/tokens/babel-plugin` must come before your
262
- `@compiled/babel-plugin`, otherwise you may experience errors.
263
-
264
- ```js
265
- // babel.config.js
266
- module.exports = {
267
- plugins: [
268
- // This will handle all `token()` calls, eg. if used in a non-Compiled CSS-in-JS library:
269
- '@atlaskit/tokens/babel-plugin',
270
- // ↓↓ Compiled should run last ↓↓
271
- ['@compiled/babel-plugin', { transformerBabelPlugins: ['@atlaskit/tokens/babel-plugin'] }],
272
- // OPTIONAL: If you are distributing packages with Compiled styles, you should also include the following.
273
- // Your `dest` may vary depending on how you distribute, eg. if you have multiple `cjs` and `esm` distributions
274
- // those will each need a separate `dest` through Babel's environment-specific configuration.
275
- [
276
- '@compiled/babel-plugin-strip-runtime',
277
- {
278
- sortShorthand: true,
279
- extractStylesToDirectory: { source: 'src', dest: 'dist' }
280
- },
281
- ],
282
- ],
283
- };
284
- ```
285
-
286
- For full documentation, refer to https://compiledcssinjs.com/docs/installation#babel
287
-
288
- ### Bundling with Webpack
289
-
290
- This configuration may vary, this is the default production-like configuration expected where the
291
- primary suggestion is to use extracted styles for performance and consistency reasons. Development
292
- configuration may vary.
293
-
294
- ```sh
295
- yarn install @atlaskit/tokens
296
- yarn install --dev @compiled/webpack-loader mini-css-extract-plugin
297
- ```
298
-
299
- ```js
300
- const { CompiledExtractPlugin } = require('@compiled/webpack-loader');
301
- const MiniCssExtractPlugin = require('mini-css-extract-plugin');
302
-
303
- module.exports = {
304
- module: {
305
- rules: [
306
- {
307
- test: /\.(js|jsx|ts|tsx)$/,
308
- use: [
309
- { loader: 'babel-loader' },
310
- {
311
- // ↓↓ Compiled should run last ↓↓
312
- loader: '@compiled/webpack-loader',
313
- options: {
314
- transformerBabelPlugins: ['@atlaskit/tokens/babel-plugin'],
315
- extract: true,
316
- inlineCss: true,
317
- },
318
- },
319
- ],
320
- },
321
- {
322
- test: /compiled-css\.css$/i,
323
- use: [MiniCssExtractPlugin.loader, 'css-loader'],
324
- },
325
- {
326
- test: /(?<!compiled-css)(?<!\.compiled)\.css$/,
327
- use: ['style-loader', 'css-loader'],
328
- },
329
- ],
330
- },
331
- plugins: [
332
- new MiniCssExtractPlugin(),
333
- new CompiledExtractPlugin({ sortShorthand: true }),
334
- ],
335
- };
336
- ```
337
-
338
- For full documentation, refer to https://compiledcssinjs.com/docs/installation#webpack
339
-
340
- ### Bundling with Parcel
341
-
342
- ```sh
343
- yarn install @atlaskit/tokens
344
- yarn install --dev @compiled/parcel-config
345
- ```
346
-
347
- Setup your `.compiledcssrc`:
348
-
349
- ```json
350
- {
351
- "transformerBabelPlugins": [["@atlaskit/tokens/babel-plugin"]],
352
- "extract": true,
353
- "inlineCss": true,
354
- "sortShorthand": true
355
- }
356
- ```
357
-
358
- Setup your `.parcelrc`:
359
-
360
- ```json
361
- {
362
- "extends": ["@parcel/config-default", "@compiled/parcel-config"]
363
- }
364
- ```
365
-
366
- For full documentation, refer to https://compiledcssinjs.com/docs/installation#(recommended)-parcel