Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: atlassian-labs/compiled
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: @compiled/react@0.16.1
Choose a base ref
...
head repository: atlassian-labs/compiled
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: @compiled/react@0.16.2
Choose a head ref
  • 2 commits
  • 12 files changed
  • 3 contributors

Commits on Nov 7, 2023

  1. Extend jsx-pragma eslint rule: detect mixing Compiled with Emotion, a…

    …nd only run if importing Compiled (#1551)
    
    * Extend jsx-pragma to support onlyRunIfImportingCompiled and detectConflictWithOtherLibraries
    
    * Raise linting error when Compiled styled API is mixed with Emotion
    
    * Add changeset
    
    * Restore xcss tests
    dddlr authored Nov 7, 2023

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    be019f1 View commit details
  2. Version Packages (#1554)

    Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
    atlas-dst-bot and github-actions[bot] authored Nov 7, 2023

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    c23b5c1 View commit details
11 changes: 11 additions & 0 deletions packages/babel-plugin/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
# @compiled/babel-plugin

## 0.24.3

### Patch Changes

- be019f11: Add detectConflictWithOtherLibraries and onlyRunIfImportingCompiled config options to jsx-pragma ESLint rule. Both are set to true by default, hence the breaking change.

`detectConflictWithOtherLibraries` raises a linting error if `css` or `jsx` is imported from `@emotion/react` (or `@emotion/core`) in the same file
as a Compiled import. Set to true by default.

`onlyRunIfImportingCompiled` sets this rule to only suggest adding the JSX pragma if the `css` or `cssMap` functions are imported from `@compiled/react`, as opposed to whenever the `css` attribute is detected at all. Set to false by default.

## 0.24.2

### Patch Changes
2 changes: 1 addition & 1 deletion packages/babel-plugin/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@compiled/babel-plugin",
"version": "0.24.2",
"version": "0.24.3",
"description": "A familiar and performant compile time CSS-in-JS library for React.",
"homepage": "https://compiledcssinjs.com/docs/pkg-babel-plugin",
"bugs": "https://github.com/atlassian-labs/compiled/issues/new?assignees=&labels=bug&template=bug_report.md",
11 changes: 11 additions & 0 deletions packages/eslint-plugin/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
# @compiled/eslint-plugin

## 0.10.0

### Minor Changes

- be019f11: Add detectConflictWithOtherLibraries and onlyRunIfImportingCompiled config options to jsx-pragma ESLint rule. Both are set to true by default, hence the breaking change.

`detectConflictWithOtherLibraries` raises a linting error if `css` or `jsx` is imported from `@emotion/react` (or `@emotion/core`) in the same file
as a Compiled import. Set to true by default.

`onlyRunIfImportingCompiled` sets this rule to only suggest adding the JSX pragma if the `css` or `cssMap` functions are imported from `@compiled/react`, as opposed to whenever the `css` attribute is detected at all. Set to false by default.

## 0.9.4

### Patch Changes
2 changes: 1 addition & 1 deletion packages/eslint-plugin/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@compiled/eslint-plugin",
"version": "0.9.4",
"version": "0.10.0",
"description": "A familiar and performant compile time CSS-in-JS library for React.",
"homepage": "https://compiledcssinjs.com/docs/pkg-eslint-plugin",
"bugs": "https://github.com/atlassian-labs/compiled/issues/new?assignees=&labels=bug&template=bug_report.md",
73 changes: 72 additions & 1 deletion packages/eslint-plugin/src/rules/jsx-pragma/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,23 @@
# `jsx-pragma`

Enforce a jsx pragma is set when using the `css` prop.
Ensure that the Compiled JSX pragma is set when using the `css` or `xcss` prop.

A JSX pragma is a comment that declares where to import the JSX namespace from. It looks
like one of the following:

```js
/** @jsx jsx */
import { jsx } from '@compiled/react';
```

```js
/** @jsxImportSource @compiled/react */
import { jsx } from '@compiled/react';
```

For all Compiled usages, one of these should be used. See the
[Emotion documentation](https://emotion.sh/docs/css-prop#jsx-pragma) for more details
on how JSX pragmas work.

---

@@ -35,6 +52,26 @@ import '@compiled/react';
^^^ missing pragma
```

```js
// [{ "pragma": "jsxImportSource" }]

import { Box } from '@atlaskit/primitives';

<Box xcss={{ borderStyle: 'solid' }} />;
^^^ missing pragma
```

```js
// [{ "detectConflictWithOtherLibraries": true }]

/** @jsx jsx */
import { css } from '@compiled/react';
import { jsx } from '@emotion/react';

<div css={css({ display: 'block' })} />;
^^^ cannot mix Compiled and Emotion
```

👍 Examples of **correct** code for this rule:

```js
@@ -52,6 +89,19 @@ import { jsx } from '@compiled/react';
<div css={{ display: 'block' }} />
```

```js
// [{ "onlyRunIfImportingCompiled": true }]

import { css } from '@emotion/react';
<div css={css({ display: 'block' })} />;
```

```js
// [{ "onlyRunIfImportingCompiled": true }]

<div css={{ display: 'block' }} />
```

## Options

This rule supports the following options:
@@ -60,3 +110,24 @@ This rule supports the following options:

What [JSX runtime](https://reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html) to adhere to,
defaults to automatic.

### `detectConflictWithOtherLibraries: boolean`

Raises a linting error if `css` or `jsx` is imported from `@emotion/react` (or `@emotion/core`) in the same file
as a Compiled import.

This is important as Emotion can't be used with Compiled in the same file, and ignoring this linting error will
result in a confusing runtime error.

This defaults to `true`.

### `onlyRunIfImportingCompiled: boolean`

By default, the `jsx-pragma` rule suggests adding the Compiled JSX pragma whenever the `css` attribute is being
used. This may not be ideal if your codebase uses a mix of Compiled and other libraries (e.g. Emotion,
styled-components). Setting `onlyRunIfImportingCompiled` to true turns off this rule unless `css` or `cssMap`
are imported from `@compiled/react`.

Note that this option does not affect `xcss`.

This option defaults to `false`.
209 changes: 202 additions & 7 deletions packages/eslint-plugin/src/rules/jsx-pragma/__tests__/rule.test.ts
Original file line number Diff line number Diff line change
@@ -23,19 +23,70 @@ tester.run('jsx-pragma', jsxPragmaRule, {
`,
{
code: `
/** @jsxImportSource @compiled/react */
<div css={{ display: 'block' }} />
`,
/** @jsxImportSource @compiled/react */
<div css={{ display: 'block' }} />
`,
options: [{ runtime: 'automatic' }],
},
{
code: `
/** @jsx jsx */
import { jsx } from '@compiled/react';
<div css={{ display: 'block' }} />
`,
/** @jsx jsx */
import { jsx } from '@compiled/react';
<div css={{ display: 'block' }} />
`,
options: [{ runtime: 'classic' }],
},
{
name: "don't error when @jsxImportSource and Compiled css API are being used",
code: `
/** @jsxImportSource @compiled/react */
import { css } from '@compiled/react';
<div css={css({ display: 'block' })} />
`,
options: [{ runtime: 'automatic' }],
},
{
code: `
/** @jsx jsx */
import { css, jsx } from '@compiled/react';
<div css={css({ display: 'block' })} />
`,
options: [{ runtime: 'classic' }],
},
{
name: "when onlyRunIfImportingCompiled is true and Compiled is not imported, don't override with Compiled",
code: `<div css={{ display: 'block' }} />`,
options: [{ onlyRunIfImportingCompiled: true }],
},
{
name: "when onlyRunIfImportingCompiled is true and Emotion jsx is used, don't override with Compiled",
code: `
/** @jsx jsx */
import { jsx } from '@emotion/react';
<>
<div css={{ display: 'block' }} />
<div css={[ someStyles ]} />
</>
`,
options: [{ onlyRunIfImportingCompiled: true }],
},
{
name: "when onlyRunIfImportingCompiled is true and Emotion css is used, don't override with Compiled (with Emotion css function)",
code: `
import { css } from '@emotion/react';
<div css={css({ display: 'block' })} />
`,
options: [{ onlyRunIfImportingCompiled: true }],
},
{
name: "when onlyRunIfImportingCompiled is true and Emotion css is used, don't override with Compiled (with Emotion css and jsx)",
code: `
/** @jsx jsx */
import { css, jsx } from '@emotion/react';
<div css={css({ display: 'block' })} />
`,
options: [{ onlyRunIfImportingCompiled: true }],
},
],
invalid: [
{
@@ -340,5 +391,149 @@ import * as React from 'react';
},
],
},
{
name: 'should error if Emotion css and Compiled styled are used',
code: `
import { css } from '@emotion/react';
import { styled } from '@compiled/react';
<div css={css({ display: 'block' })} />
`,
errors: [
{
messageId: 'emotionAndCompiledConflict',
},
],
},
{
name: 'should error if Emotion css and Compiled styled are used (onlyRunIfImportingCompiled = true)',
code: `
import { css } from '@emotion/react';
import { styled } from '@compiled/react';
<div css={css({ display: 'block' })} />
`,
options: [{ onlyRunIfImportingCompiled: true }],
errors: [
{
messageId: 'emotionAndCompiledConflict',
},
],
},
{
name: 'should error when both Emotion and Compiled css APIs are being used',
code: `
/** @jsx jsx */
import * as React from 'react';
import { css, jsx } from '@emotion/react';
import { css as cssCompiled } from '@compiled/react';
<div css={css({ display: 'block' })} />
`,
options: [{ onlyRunIfImportingCompiled: true }],
errors: [
{
messageId: 'emotionAndCompiledConflict',
},
],
},
{
name: 'should error when both Emotion and Compiled css APIs are being used (alt)',
code: `
/** @jsx jsxEmotion */
import * as React from 'react';
import { css, jsx as jsxEmotion } from '@emotion/react';
import { css as cssCompiled } from '@compiled/react';
<div css={css({ display: 'block' })} />
`,
options: [{ onlyRunIfImportingCompiled: true }],
errors: [
{
messageId: 'emotionAndCompiledConflict',
},
],
},
{
name: 'should error when both Emotion jsx API and Compiled css API are being used',
code: `
import * as React from 'react';
import { jsx } from '@emotion/react';
import { css } from '@compiled/react';
<div css={css({ display: 'block' })} />
`,
options: [{ onlyRunIfImportingCompiled: true }],
errors: [
{
messageId: 'emotionAndCompiledConflict',
},
],
},
{
name: 'should error when both Emotion jsx API and Compiled css API are being used (with JSX pragma)',
code: `
/** @jsx jsx */
import * as React from 'react';
import { jsx } from '@emotion/react';
import { css } from '@compiled/react';
<div css={css({ display: 'block' })} />
`,
options: [{ onlyRunIfImportingCompiled: true }],
errors: [
{
messageId: 'emotionAndCompiledConflict',
},
],
},
{
name: 'should error when both Emotion css API and Compiled jsx API are being used (with JSX pragma)',
code: `
/** @jsx jsx */
import * as React from 'react';
import { jsx } from '@compiled/react';
import { css } from '@emotion/react';
<div css={css({ display: 'block' })} />
`,
options: [{ onlyRunIfImportingCompiled: true, runtime: 'classic' }],
errors: [
{
messageId: 'emotionAndCompiledConflict',
},
],
},
{
name: 'should error when both Emotion and Compiled css APIs are being used (with @emotion/core)',
code: `
/** @jsx jsxEmotion */
import * as React from 'react';
import { jsx } from '@emotion/core';
import { css as cssCompiled } from '@compiled/react';
<div css={{ display: 'block' }} />
`,
options: [{ onlyRunIfImportingCompiled: true }],
errors: [
{
messageId: 'emotionAndCompiledConflict',
},
],
},
{
name: 'should error when both Emotion and Compiled css APIs are being used (onlyRunIfImportingCompiled = true)',
code: `
import * as React from 'react';
import { css } from '@emotion/react';
import { css as cssCompiled } from '@compiled/react';
<div css={css({ display: 'block' })} />
`,
options: [{ onlyRunIfImportingCompiled: true }],
errors: [
{
messageId: 'emotionAndCompiledConflict',
},
],
},
],
});
Loading