Skip to content

Commit c6f92f4

Browse files
committed
Add rule no-conditional-css-prop
1 parent bd529a2 commit c6f92f4

File tree

5 files changed

+100
-0
lines changed

5 files changed

+100
-0
lines changed

.changeset/ninety-flowers-promise.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'eslint-config-widen-react': minor
3+
---
4+
5+
Add a new rule that detects conditional statements used on a css prop.

packages/eslint-config-widen-react/src/react.ts

+2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import jsxA11y from 'eslint-plugin-jsx-a11y'
22
import react from 'eslint-plugin-react'
33
import reactHooks from 'eslint-plugin-react-hooks'
4+
import noConditionalCssProp from './rules/no-conditional-css-prop.js'
45
import sharedGlobals from './sharedGlobals.js'
56

67
const languageOptions = {
@@ -71,6 +72,7 @@ export default [
7172
files: ['*.tsx', '*.{spec,test}.{js,jsx}'],
7273
languageOptions,
7374
rules: {
75+
'custom/no-conditional-css-prop': noConditionalCssProp,
7476
'jsx-a11y/click-events-have-key-events': 'warn',
7577
'jsx-a11y/label-has-associated-control': [
7678
'error',
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { Rule } from 'eslint'
2+
3+
export default {
4+
create(context) {
5+
return {
6+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
7+
JSXAttribute(node: any) {
8+
if (
9+
node.name.name === 'css' &&
10+
node.value &&
11+
node.value.type === 'JSXExpressionContainer' &&
12+
(node.value.expression.type === 'ConditionalExpression' ||
13+
(node.value.expression.type === 'LogicalExpression' &&
14+
(node.value.expression.operator === '&&' ||
15+
node.value.expression.operator === '||')))
16+
) {
17+
context.report({
18+
message:
19+
'Avoid using conditionals within the css prop, move them to style.',
20+
node,
21+
})
22+
}
23+
},
24+
}
25+
},
26+
meta: {
27+
docs: {
28+
category: 'Best Practices',
29+
description: 'Disallow conditionals within the css prop in components',
30+
recommended: false,
31+
},
32+
schema: [],
33+
type: 'suggestion',
34+
},
35+
} as Rule.RuleModule

packages/eslint-config-widen-react/src/types.d.ts

+1
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ declare module 'eslint-plugin-jsx-a11y'
22
declare module 'eslint-plugin-react'
33
declare module 'eslint-plugin-react-hooks'
44
declare module 'globals'
5+
declare module 'no-conditional-css-prop'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import { RuleTester } from 'eslint'
2+
import rule from '../src/rules/no-conditional-css-prop'
3+
import sharedGlobals from '../src/sharedGlobals'
4+
5+
const ruleTester = new RuleTester({
6+
languageOptions: {
7+
globals: sharedGlobals,
8+
parserOptions: {
9+
ecmaFeatures: {
10+
jsx: true,
11+
},
12+
},
13+
},
14+
})
15+
16+
ruleTester.run('no-conditional-css-prop', rule, {
17+
invalid: [
18+
{
19+
code: '<div css={condition ? { color: "red" } : { color: "blue" }} />',
20+
errors: [
21+
{
22+
message:
23+
'Avoid using conditionals within the css prop, move them to style.',
24+
},
25+
],
26+
},
27+
{
28+
code: '<div css={condition && { color: "red" }} />',
29+
errors: [
30+
{
31+
message:
32+
'Avoid using conditionals within the css prop, move them to style.',
33+
},
34+
],
35+
},
36+
{
37+
code: '<div css={condition || { color: "blue" }} />',
38+
errors: [
39+
{
40+
message:
41+
'Avoid using conditionals within the css prop, move them to style.',
42+
},
43+
],
44+
},
45+
],
46+
valid: [
47+
{
48+
code: '<div css={{ color: "red" }} />',
49+
},
50+
{
51+
code: '<div css={someVariable} />',
52+
},
53+
{
54+
code: '<div css={`color: ${someVariable}`} />',
55+
},
56+
],
57+
})

0 commit comments

Comments
 (0)