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: [