Skip to content

Commit 2010cde

Browse files
authoredNov 2, 2023
XCSS prop no js lint (#1547)
* feat: add no-js-xcss * chore: changeset * chore: fix * chore: resolve code review comments
1 parent 351dbc2 commit 2010cde

File tree

6 files changed

+85
-0
lines changed

6 files changed

+85
-0
lines changed
 

‎.changeset/wild-berries-add.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@compiled/eslint-plugin': patch
3+
---
4+
5+
Adds new supplementary lint rule for xcss prop `no-js-xcss`.

‎packages/eslint-plugin/src/configs/recommended.ts

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export const recommended = {
66
'@compiled/no-exported-css': 'error',
77
'@compiled/no-exported-keyframes': 'error',
88
'@compiled/no-invalid-css-map': 'error',
9+
'@compiled/no-js-xcss': 'error',
910
'@compiled/no-keyframes-tagged-template-expression': 'error',
1011
'@compiled/no-styled-tagged-template-expression': 'error',
1112
'@compiled/no-suppress-xcss': 'error',

‎packages/eslint-plugin/src/index.ts

+2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { noEmotionCssRule } from './rules/no-emotion-css';
66
import { noExportedCssRule } from './rules/no-exported-css';
77
import { noExportedKeyframesRule } from './rules/no-exported-keyframes';
88
import { noInvalidCssMapRule } from './rules/no-invalid-css-map';
9+
import { noJavaScriptXCSSRule } from './rules/no-js-xcss';
910
import { noKeyframesTaggedTemplateExpressionRule } from './rules/no-keyframes-tagged-template-expression';
1011
import { noStyledTaggedTemplateExpressionRule } from './rules/no-styled-tagged-template-expression';
1112
import { noSuppressXCSS } from './rules/no-suppress-xcss';
@@ -18,6 +19,7 @@ export const rules = {
1819
'no-exported-css': noExportedCssRule,
1920
'no-exported-keyframes': noExportedKeyframesRule,
2021
'no-invalid-css-map': noInvalidCssMapRule,
22+
'no-js-xcss': noJavaScriptXCSSRule,
2123
'no-keyframes-tagged-template-expression': noKeyframesTaggedTemplateExpressionRule,
2224
'no-styled-tagged-template-expression': noStyledTaggedTemplateExpressionRule,
2325
'no-suppress-xcss': noSuppressXCSS,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# `no-js-xcss`
2+
3+
Disallows using xcss prop inside JavaScript files.
4+
5+
Components that use xcss prop have explicitly declared what styles via the type system they should and should not accept, consumers must adhere to this API. Without TypeScript it's impossible to ensure this is met.
6+
7+
👎 Examples of **incorrect** code for this rule:
8+
9+
```js
10+
// my-component.jsx
11+
<Button xcss={{ fill: 'var(--ds-text)' }} />
12+
```
13+
14+
👍 Examples of **correct** code for this rule:
15+
16+
```js
17+
// my-component.tsx
18+
<Button xcss={{ color: 'var(--ds-text)' }} />
19+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { typeScriptTester as tester } from '../../../test-utils';
2+
import { noJavaScriptXCSSRule } from '../index';
3+
4+
tester.run('no-js-xcss', noJavaScriptXCSSRule, {
5+
valid: [
6+
{
7+
filename: 'my-component.tsx',
8+
code: `
9+
<Component xcss={{ fill: 'red' }} />
10+
`,
11+
},
12+
],
13+
invalid: [
14+
{
15+
filename: 'my-component.js',
16+
code: `
17+
<Component xcss={{ fill: 'red' }} />
18+
`,
19+
errors: [{ messageId: 'no-js-xcss' }],
20+
},
21+
{
22+
filename: 'my-component.jsx',
23+
code: `
24+
<Component xcss={{ fill: 'red' }} />
25+
`,
26+
errors: [{ messageId: 'no-js-xcss' }],
27+
},
28+
],
29+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import type { Rule } from 'eslint';
2+
3+
export const noJavaScriptXCSSRule: Rule.RuleModule = {
4+
meta: {
5+
docs: {
6+
recommended: true,
7+
description:
8+
'The xcss prop is predicated on adhering to the type contract. Using it without TypeScript breaks this contract and thus is not allowed.',
9+
url: 'https://github.com/atlassian-labs/compiled/tree/master/packages/eslint-plugin/src/rules/no-js-xcss',
10+
},
11+
messages: {
12+
'no-js-xcss':
13+
'Using xcss in JavaScript risks incidents and unintended behaviour when code changes — only use inside TypeScript files',
14+
},
15+
type: 'problem',
16+
},
17+
create(context) {
18+
return {
19+
'JSXAttribute[name.name=/[xX]css$/]': (node: Rule.Node) => {
20+
if (node.type === 'JSXAttribute' && !context.filename.endsWith('.tsx')) {
21+
context.report({
22+
node: node.name,
23+
messageId: 'no-js-xcss',
24+
});
25+
}
26+
},
27+
};
28+
},
29+
};

0 commit comments

Comments
 (0)
Please sign in to comment.