diff --git a/packages/kbn-eslint-config/.eslintrc.js b/packages/kbn-eslint-config/.eslintrc.js index 38c45d89af7fd..57a116a2b9b68 100644 --- a/packages/kbn-eslint-config/.eslintrc.js +++ b/packages/kbn-eslint-config/.eslintrc.js @@ -334,7 +334,6 @@ module.exports = { '@kbn/imports/no_group_crossing_manifests': 'error', '@kbn/imports/no_group_crossing_imports': 'error', '@kbn/css/no_css_color': 'warn', - '@kbn/css/prefer_css_attributes_for_eui_components': 'warn', 'no-new-func': 'error', 'no-implied-eval': 'error', 'no-prototype-builtins': 'error', diff --git a/packages/kbn-eslint-plugin-css/src/rules/no_css_color.test.ts b/packages/kbn-eslint-plugin-css/src/rules/no_css_color.test.ts index 47d6a2aa601b6..4cc81ed15887b 100644 --- a/packages/kbn-eslint-plugin-css/src/rules/no_css_color.test.ts +++ b/packages/kbn-eslint-plugin-css/src/rules/no_css_color.test.ts @@ -51,8 +51,36 @@ const invalid: RuleTester.InvalidTestCase[] = [ This is a test ) }`, + errors: [{ messageId: 'noCssColorSpecific' }], + }, + { + name: 'Raises an error when a CSS color is used in a JSX style attribute with template literals', + filename: '/x-pack/plugins/observability_solution/observability/public/test_component.tsx', + code: ` + import React from 'react'; + + function TestComponent() { + return ( + This is a test + ) + }`, errors: [{ messageId: 'noCssColor' }], }, + { + name: 'Raises an error when a CSS color is used for the background property in a JSX style attribute', + filename: '/x-pack/plugins/observability_solution/observability/public/test_component.tsx', + code: ` + import React from 'react'; + + function TestComponent() { + return ( + This is a test + ) + }`, + errors: [{ messageId: 'noCssColorSpecific' }], + }, { name: 'Raises an error when a CSS color for the color property is used in a JSX css attribute for EuiComponents', filename: '/x-pack/plugins/observability_solution/observability/public/test_component.tsx', @@ -64,7 +92,7 @@ const invalid: RuleTester.InvalidTestCase[] = [ This is a test ) }`, - errors: [{ messageId: 'noCssColor' }], + errors: [{ messageId: 'noCssColorSpecific' }], }, { name: 'Raises an error when a CSS color for the color property is used in a JSX css attribute for EuiComponents with the css template function', @@ -90,7 +118,7 @@ const invalid: RuleTester.InvalidTestCase[] = [ ({ color: '#dd4040' })}>This is a test ) }`, - errors: [{ messageId: 'noCssColor' }], + errors: [{ messageId: 'noCssColorSpecific' }], }, { name: 'Raises an error when a CSS color for the color property is used in a JSX css attribute for EuiComponents with a regular function', @@ -103,7 +131,7 @@ const invalid: RuleTester.InvalidTestCase[] = [ This is a test ) }`, - errors: [{ messageId: 'noCssColor' }], + errors: [{ messageId: 'noCssColorSpecific' }], }, ]; diff --git a/packages/kbn-eslint-plugin-css/src/rules/no_css_color.ts b/packages/kbn-eslint-plugin-css/src/rules/no_css_color.ts index 5fc7a9fc966d9..3547850dd1573 100644 --- a/packages/kbn-eslint-plugin-css/src/rules/no_css_color.ts +++ b/packages/kbn-eslint-plugin-css/src/rules/no_css_color.ts @@ -22,7 +22,8 @@ const cssColorRegex = /(#|rgb|hsl|hwb|lab|lch|oklab).*/; const propertiesSupportingCssColor = ['color', 'background', 'backgroundColor', 'border']; /** - * @description Builds off the existing color definition regex to match css declarations that can apply color to html elements and text nodes + * @description Builds off the existing color definition regex to match css declarations that can apply color to + * html elements and text nodes for string declarations */ const htmlElementColorDeclarationRegex = RegExp( String.raw`(${propertiesSupportingCssColor.join('|')})\:\s?(\'|\")?${cssColorRegex.source}` @@ -46,7 +47,11 @@ const raiseReportIfPropertyHasCssColor = ( ) { context.report({ loc: node.loc, - messageId: 'noCssColor', + messageId: 'noCssColorSpecific', + data: { + // @ts-expect-error the key name is always pretty else this code will not execute + property: node.key.name, + }, }); } @@ -63,7 +68,9 @@ export const NoCssColor: Rule.RuleModule = { url: 'https://eui.elastic.co/#/theming/colors/values', }, messages: { - noCssColor: 'Avoid using CSS colors', + noCssColorSpecific: + 'Avoid using a literal CSS color value for {{property}}, use an EUI theme color instead', + noCssColor: 'Avoid using a literal CSS color value, use an EUI theme color instead', }, schema: [], }, @@ -83,13 +90,17 @@ export const NoCssColor: Rule.RuleModule = { node.value.type === 'JSXExpressionContainer' && node.value.expression.type === 'TemplateLiteral' ) { - const declarationTemplateNode = node.value.expression.quasis[0]; + for (let i = 0; i < node.value.expression.quasis.length; i++) { + const declarationTemplateNode = node.value.expression.quasis[i]; - if (htmlElementColorDeclarationRegex.test(declarationTemplateNode.value.raw)) { - context.report({ - node: declarationTemplateNode, - messageId: 'noCssColor', - }); + if (htmlElementColorDeclarationRegex.test(declarationTemplateNode.value.raw)) { + context.report({ + loc: declarationTemplateNode.loc, + messageId: 'noCssColor', + }); + + break; + } } } @@ -126,13 +137,17 @@ export const NoCssColor: Rule.RuleModule = { node.value.type === 'JSXExpressionContainer' && node.value.expression.type === 'TemplateLiteral' ) { - const declarationTemplateNode = node.value.expression.quasis[0]; + for (let i = 0; i < node.value.expression.quasis.length; i++) { + const declarationTemplateNode = node.value.expression.quasis[i]; - if (htmlElementColorDeclarationRegex.test(declarationTemplateNode.value.raw)) { - context.report({ - node: declarationTemplateNode, - messageId: 'noCssColor', - }); + if (htmlElementColorDeclarationRegex.test(declarationTemplateNode.value.raw)) { + context.report({ + node: declarationTemplateNode, + messageId: 'noCssColor', + }); + + break; + } } } @@ -169,13 +184,17 @@ export const NoCssColor: Rule.RuleModule = { node.value.expression.tag.type === 'Identifier' && node.value.expression.tag.name === 'css' ) { - const declarationTemplateNode = node.value.expression.quasi.quasis[0]; + for (let i = 0; i < node.value.expression.quasi.quasis.length; i++) { + const declarationTemplateNode = node.value.expression.quasi.quasis[i]; - if (htmlElementColorDeclarationRegex.test(declarationTemplateNode.value.raw)) { - context.report({ - node: declarationTemplateNode, - messageId: 'noCssColor', - }); + if (htmlElementColorDeclarationRegex.test(declarationTemplateNode.value.raw)) { + context.report({ + loc: declarationTemplateNode.loc, + messageId: 'noCssColor', + }); + + break; + } } }