1
0
Files
nex/frontend/eslint-rules/rules/no-hardcoded-color-in-style.js

108 lines
2.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { ESLintUtils } from '@typescript-eslint/utils'
const RE_HEX3 = /^#[0-9a-fA-F]{3}$/
const RE_HEX6 = /^#[0-9a-fA-F]{6}$/
const RE_HEX8 = /^#[0-9a-fA-F]{8}$/
const RE_RGB = /^rgb\s*\(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*\)$/
const RE_RGBA = /^rgba\s*\(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*,\s*[\d.]+\s*\)$/
const RE_HSL = /^hsl\s*\(\s*\d+\s*,\s*[\d.]+%?\s*,\s*[\d.]+%?\s*\)$/
const ALLOWED_KEYWORDS = new Set([
'inherit',
'transparent',
'currentColor',
'none',
'unset',
'initial',
'auto',
'contain',
'cover',
])
function isHardcodedColor(value) {
if (typeof value !== 'string') return false
const trimmed = value.trim()
if (ALLOWED_KEYWORDS.has(trimmed.toLowerCase())) return false
if (trimmed.startsWith('var(')) return false
if (/^\d+(\.\d+)?px?$/.test(trimmed)) return false
if (/^\d+(\.\d+)?\%$/.test(trimmed)) return false
return (
RE_HEX3.test(trimmed) ||
RE_HEX6.test(trimmed) ||
RE_HEX8.test(trimmed) ||
RE_RGB.test(trimmed) ||
RE_RGBA.test(trimmed) ||
RE_HSL.test(trimmed)
)
}
function extractStyleProperties(expression) {
const properties = []
if (expression.type === 'ObjectExpression' && expression.properties) {
for (const styleProp of expression.properties) {
if (
styleProp.type === 'Property' &&
styleProp.key?.type === 'Identifier' &&
styleProp.value?.type === 'Literal' &&
typeof styleProp.value.value === 'string'
) {
properties.push({
key: styleProp.key.name,
value: styleProp.value.value,
loc: styleProp.value.loc,
})
}
}
}
return properties
}
export const RULE_NAME = 'no-hardcoded-color-in-style'
export default ESLintUtils.RuleCreator((name) => {
return `https://eslint.dev/rules/#${name}`
})({
name: 'no-hardcoded-color-in-style',
meta: {
type: 'problem',
docs: {
description: 'Disallow hardcoded color values in JSX style properties',
recommended: false,
},
messages: {
hardcodedColor:
'硬编码的颜色值 "{{value}}" 不允许使用。请使用 TDesign CSS Token如 var(--td-text-color-placeholder))代替。',
},
schema: [],
},
create(context) {
return {
JSXAttribute(node) {
if (
node.name?.type === 'JSXIdentifier' &&
node.name.name === 'style' &&
node.value?.type === 'JSXExpressionContainer' &&
node.value.expression
) {
const styleProps = extractStyleProperties(node.value.expression)
for (const prop of styleProps) {
if (isHardcodedColor(prop.value)) {
context.report({
node: context.sourceCode.getLastToken(node),
messageId: 'hardcodedColor',
data: { value: prop.value },
})
}
}
}
},
}
},
})