From 98d3167a987f963fd91103174e98765144678491 Mon Sep 17 00:00:00 2001 From: Herman Bilous Date: Fri, 20 Oct 2023 11:28:59 +0300 Subject: [PATCH] [New] add allowDataUpperCase option to no-unknown-property rule Fixes #3643 --- docs/rules/no-unknown-property.md | 3 ++- lib/rules/no-unknown-property.js | 23 +++++++++++++++++++---- tests/lib/rules/no-unknown-property.js | 16 ++++++++++++++++ 3 files changed, 37 insertions(+), 5 deletions(-) diff --git a/docs/rules/no-unknown-property.md b/docs/rules/no-unknown-property.md index ac47ccac9d..ae8b93a678 100644 --- a/docs/rules/no-unknown-property.md +++ b/docs/rules/no-unknown-property.md @@ -51,12 +51,13 @@ var AtomPanel = ; ```js ... -"react/no-unknown-property": [, { ignore: }] +"react/no-unknown-property": [, { ignore: , allowDataUpperCase: }] ... ``` - `enabled`: for enabling the rule. 0=off, 1=warn, 2=error. Defaults to 0. - `ignore`: optional array of property and attribute names to ignore during validation. +- `allowDataUpperCase`: optional (default: `true`), allow for data-\* attributes to contain upper-case letters. React will issue a warning when data-\* attributes contain upper-case letters. In order to catch such attributes, set `allowDataUpperCase` option to `false`. If you are using a library that passes something as a prop to JSX elements, it is recommended to add those props to the ignored properties. diff --git a/lib/rules/no-unknown-property.js b/lib/rules/no-unknown-property.js index fc57336695..7ffa831ae8 100644 --- a/lib/rules/no-unknown-property.js +++ b/lib/rules/no-unknown-property.js @@ -16,6 +16,7 @@ const report = require('../util/report'); const DEFAULTS = { ignore: [], + allowDataUpperCase: true, }; const DOM_ATTRIBUTE_NAMES = { @@ -418,15 +419,19 @@ function normalizeAttributeCase(name) { /** * Checks if an attribute name is a valid `data-*` attribute: - * if the name starts with "data-" and has alphanumeric words (browsers require lowercase, but React and TS lowercase them), + * if the name starts with "data-" and has alphanumeric words, * not start with any casing of "xml", and separated by hyphens (-) (which is also called "kebab case" or "dash case"), * then the attribute is a valid data attribute. * + * Accepts option to allow upper-case letters (react will lowercase them, but will throw a warning) + * * @param {String} name - Attribute name to be tested + * @param {Boolean} allowUpperCase - Allow "data-*" to contain upper-case letters * @returns {boolean} Result */ -function isValidDataAttribute(name) { - return /^data(-[^:]*)*$/.test(name) && !/^data-xml/i.test(name); +function isValidDataAttribute(name, allowUpperCase) { + const basicAttributeRegexp = allowUpperCase ? /^data(-[^:]*)*$/ : /^data(-[a-z1-9]*)*$/; + return basicAttributeRegexp.test(name) && !/^data-xml/i.test(name); } /** @@ -516,6 +521,10 @@ module.exports = { type: 'string', }, }, + allowDataUpperCase: { + type: 'boolean', + default: true, + }, }, additionalProperties: false, }], @@ -526,6 +535,12 @@ module.exports = { return (context.options[0] && context.options[0].ignore) || DEFAULTS.ignore; } + function getAllowDataUpperCase() { + return (context.options[0] && typeof context.options[0].allowDataUpperCase !== 'undefined') + ? context.options[0].allowDataUpperCase + : DEFAULTS.allowDataUpperCase; + } + return { JSXAttribute(node) { const ignoreNames = getIgnoreConfig(); @@ -540,7 +555,7 @@ module.exports = { return; } - if (isValidDataAttribute(name)) { return; } + if (isValidDataAttribute(name, getAllowDataUpperCase())) { return; } if (isValidAriaAttribute(name)) { return; } diff --git a/tests/lib/rules/no-unknown-property.js b/tests/lib/rules/no-unknown-property.js index 0fc510e3b5..d2e9923148 100644 --- a/tests/lib/rules/no-unknown-property.js +++ b/tests/lib/rules/no-unknown-property.js @@ -99,6 +99,10 @@ ruleTester.run('no-unknown-property', rule, { { code: '
;' }, { code: '
;' }, { code: '
;' }, + { + code: '
;', + options: [{ allowDataUpperCase: true }], + }, // Ignoring should work { code: '
;', @@ -573,6 +577,18 @@ ruleTester.run('no-unknown-property', rule, { }, ], }, + { + code: '
', + errors: [ + { + messageId: 'unknownProp', + data: { + name: 'data-UPPERCASE', + }, + }, + ], + options: [{ allowDataUpperCase: false }], + }, { code: '
', errors: [