Skip to content

Commit

Permalink
Add rule no-conditional-css-prop
Browse files Browse the repository at this point in the history
  • Loading branch information
joephela committed Jan 10, 2025
1 parent bd529a2 commit c6f92f4
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .changeset/ninety-flowers-promise.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'eslint-config-widen-react': minor
---

Add a new rule that detects conditional statements used on a css prop.
2 changes: 2 additions & 0 deletions packages/eslint-config-widen-react/src/react.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import jsxA11y from 'eslint-plugin-jsx-a11y'
import react from 'eslint-plugin-react'
import reactHooks from 'eslint-plugin-react-hooks'
import noConditionalCssProp from './rules/no-conditional-css-prop.js'
import sharedGlobals from './sharedGlobals.js'

const languageOptions = {
Expand Down Expand Up @@ -71,6 +72,7 @@ export default [
files: ['*.tsx', '*.{spec,test}.{js,jsx}'],
languageOptions,
rules: {
'custom/no-conditional-css-prop': noConditionalCssProp,
'jsx-a11y/click-events-have-key-events': 'warn',
'jsx-a11y/label-has-associated-control': [
'error',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { Rule } from 'eslint'

export default {
create(context) {
return {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
JSXAttribute(node: any) {
if (
node.name.name === 'css' &&
node.value &&
node.value.type === 'JSXExpressionContainer' &&
(node.value.expression.type === 'ConditionalExpression' ||
(node.value.expression.type === 'LogicalExpression' &&
(node.value.expression.operator === '&&' ||
node.value.expression.operator === '||')))
) {
context.report({
message:
'Avoid using conditionals within the css prop, move them to style.',
node,
})
}
},
}
},
meta: {
docs: {
category: 'Best Practices',
description: 'Disallow conditionals within the css prop in components',
recommended: false,
},
schema: [],
type: 'suggestion',
},
} as Rule.RuleModule
1 change: 1 addition & 0 deletions packages/eslint-config-widen-react/src/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ declare module 'eslint-plugin-jsx-a11y'
declare module 'eslint-plugin-react'
declare module 'eslint-plugin-react-hooks'
declare module 'globals'
declare module 'no-conditional-css-prop'
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { RuleTester } from 'eslint'
import rule from '../src/rules/no-conditional-css-prop'
import sharedGlobals from '../src/sharedGlobals'

const ruleTester = new RuleTester({
languageOptions: {
globals: sharedGlobals,
parserOptions: {
ecmaFeatures: {
jsx: true,
},
},
},
})

ruleTester.run('no-conditional-css-prop', rule, {
invalid: [
{
code: '<div css={condition ? { color: "red" } : { color: "blue" }} />',
errors: [
{
message:
'Avoid using conditionals within the css prop, move them to style.',
},
],
},
{
code: '<div css={condition && { color: "red" }} />',
errors: [
{
message:
'Avoid using conditionals within the css prop, move them to style.',
},
],
},
{
code: '<div css={condition || { color: "blue" }} />',
errors: [
{
message:
'Avoid using conditionals within the css prop, move them to style.',
},
],
},
],
valid: [
{
code: '<div css={{ color: "red" }} />',
},
{
code: '<div css={someVariable} />',
},
{
code: '<div css={`color: ${someVariable}`} />',
},
],
})

0 comments on commit c6f92f4

Please sign in to comment.