Repository: jsx-eslint/eslint-plugin-react
Pull request #3381 (2022-09-02 23:57:25)

[Fix] no-unknown-property: No unknown property doesn't recognize svg properties
fixes https://github.com/jsx-eslint/eslint-plugin-react/issues/3380

I don't know if the added attributes are exhaustive or not. I sure hope MDN covered all possible attributes.


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 27ae3e4a..c92d5255 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,11 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange
 
 ## Unreleased
 
+### Fixed
+* [`no-unknown-property`]: add SVG and meta properties ([#3381][] @AhmadMayo)
+
+[#3381]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3381
+
 ## [7.31.2] - 2022.09.02
 
 ### Fixed
diff --git a/lib/rules/no-unknown-property.js b/lib/rules/no-unknown-property.js
index d8f7f1e3..a39bfde1 100644
--- a/lib/rules/no-unknown-property.js
+++ b/lib/rules/no-unknown-property.js
@@ -29,6 +29,9 @@ const DOM_ATTRIBUTE_NAMES = {
 const ATTRIBUTE_TAGS_MAP = {
   // image is required for SVG support, all other tags are HTML.
   crossOrigin: ['script', 'img', 'video', 'audio', 'link', 'image'],
+  fill: ['svg'],
+  property: ['meta'],
+  viewBox: ['svg'],
 };
 
 const SVGDOM_ATTRIBUTE_NAMES = {
@@ -130,8 +133,22 @@ const DOM_PROPERTY_NAMES_ONE_WORD = [
   'name', 'open', 'optimum', 'pattern', 'ping', 'placeholder', 'poster', 'preload', 'profile',
   'rel', 'required', 'reversed', 'role', 'rows', 'sandbox', 'scope', 'selected', 'shape', 'size', 'sizes',
   'span', 'src', 'start', 'step', 'target', 'type', 'value', 'width', 'wrap',
+  // SVG attributes
+  // See https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute
+  'accumulate', 'additive', 'alphabetic', 'amplitude', 'ascent', 'azimuth', 'bbox', 'begin',
+  'bias', 'by', 'clip', 'color', 'cursor', 'cx', 'cy', 'd', 'decelerate', 'descent', 'direction',
+  'display', 'divisor', 'dur', 'dx', 'dy', 'elevation', 'end', 'exponent', 'fill', 'filter',
+  'format', 'from', 'fr', 'fx', 'fy', 'g1', 'g2', 'hanging', 'height', 'hreflang', 'ideographic',
+  'in', 'in2', 'intercept', 'k', 'k1', 'k2', 'k3', 'k4', 'kerning', 'local', 'mask', 'mode',
+  'offset', 'opacity', 'operator', 'order', 'orient', 'orientation', 'origin', 'overflow', 'path',
+  'ping', 'points', 'r', 'radius', 'rel', 'restart', 'result', 'rotate', 'rx', 'ry', 'scale',
+  'seed', 'slope', 'spacing', 'speed', 'stemh', 'stemv', 'string', 'stroke', 'to', 'transform',
+  'u1', 'u2', 'unicode', 'values', 'version', 'visibility', 'widths', 'x', 'x1', 'x2', 'xmlns',
+  'y', 'y1', 'y2', 'z',
+  // OpenGraph meta tag attributes
+  'property',
   // React specific attributes
-  'ref',
+  'ref', 'key',
 ];
 
 const DOM_PROPERTY_NAMES_TWO_WORDS = [
@@ -152,6 +169,36 @@ const DOM_PROPERTY_NAMES_TWO_WORDS = [
   'onDragStart', 'onDrop', 'onMouseDown', 'onMouseEnter', 'onMouseLeave', 'onMouseMove', 'onMouseOut', 'onMouseOver',
   'onMouseUp', 'onPaste', 'onScroll', 'onSelect', 'onSubmit', 'onTransitionEnd', 'radioGroup', 'readOnly', 'referrerPolicy',
   'rowSpan', 'srcDoc', 'srcLang', 'srcSet', 'useMap',
+  // SVG attributes
+  // See https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute
+  'crossOrigin', 'accentHeight', 'alignmentBaseline', 'arabicForm', 'attributeName',
+  'attributeType', 'baseFrequency', 'baselineShift', 'baseProfile', 'calcMode', 'capHeight',
+  'clipPathUnits', 'clipPath', 'clipRule', 'colorInterpolation', 'colorInterpolationFilters',
+  'colorProfile', 'colorRendering', 'contentScriptType', 'contentStyleType', 'diffuseConstant',
+  'dominantBaseline', 'edgeMode', 'enableBackground', 'fillOpacity', 'fillRule', 'filterRes',
+  'filterUnits', 'floodColor', 'floodOpacity', 'fontFamily', 'fontSize', 'fontSizeAdjust',
+  'fontStretch', 'fontStyle', 'fontVariant', 'fontWeight', 'glyphName',
+  'glyphOrientationHorizontal', 'glyphOrientationVertical', 'glyphRef', 'gradientTransform',
+  'gradientUnits', 'horizAdvX', 'horizOriginX', 'imageRendering', 'kernelMatrix',
+  'kernelUnitLength', 'keyPoints', 'keySplines', 'keyTimes', 'lengthAdjust', 'letterSpacing',
+  'lightingColor', 'limitingConeAngle', 'markerEnd', 'markerMid', 'markerStart', 'markerHeight',
+  'markerUnits', 'markerWidth', 'maskContentUnits', 'maskUnits', 'mathematical', 'numOctaves',
+  'overlinePosition', 'overlineThickness', 'panose1', 'paintOrder', 'pathLength',
+  'patternContentUnits', 'patternTransform', 'patternUnits', 'pointerEvents', 'pointsAtX',
+  'pointsAtY', 'pointsAtZ', 'preserveAlpha', 'preserveAspectRatio', 'primitiveUnits',
+  'referrerPolicy', 'refX', 'refY', 'rendering-intent', 'repeatCount', 'repeatDur',
+  'requiredExtensions', 'requiredFeatures', 'shapeRendering', 'specularConstant',
+  'specularExponent', 'spreadMethod', 'startOffset', 'stdDeviation', 'stitchTiles', 'stopColor',
+  'stopOpacity', 'strikethroughPosition', 'strikethroughThickness', 'strokeDasharray',
+  'strokeDashoffset', 'strokeLinecap', 'strokeLinejoin', 'strokeMiterlimit', 'strokeOpacity',
+  'strokeWidth', 'surfaceScale', 'systemLanguage', 'tableValues', 'targetX', 'targetY',
+  'textAnchor', 'textDecoration', 'textRendering', 'textLength', 'transformOrigin',
+  'underlinePosition', 'underlineThickness', 'unicodeBidi', 'unicodeRange', 'unitsPerEm',
+  'vAlphabetic', 'vHanging', 'vIdeographic', 'vMathematical', 'vectorEffect', 'vertAdvY',
+  'vertOriginX', 'vertOriginY', 'viewBox', 'viewTarget', 'wordSpacing', 'writingMode', 'xHeight',
+  'xChannelSelector', 'xlinkActuate', 'xlinkArcrole', 'xlinkHref', 'xlinkRole', 'xlinkShow',
+  'xlinkTitle', 'xlinkType', 'xmlBase', 'xmlLang', 'xmlnsXlink', 'xmlSpace', 'yChannelSelector',
+  'zoomAndPan',
   // Safari/Apple specific, no listing available
   'autoCorrect', // https://stackoverflow.com/questions/47985384/html-autocorrect-for-text-input-is-not-working
   'autoSave', // https://stackoverflow.com/questions/25456396/what-is-autosave-attribute-supposed-to-do-how-do-i-use-it


Test patch:
diff --git a/tests/lib/rules/no-unknown-property.js b/tests/lib/rules/no-unknown-property.js
index 0db6f3bc..b6b8173e 100644
--- a/tests/lib/rules/no-unknown-property.js
+++ b/tests/lib/rules/no-unknown-property.js
@@ -48,7 +48,10 @@ ruleTester.run('no-unknown-property', rule, {
     { code: '<img src="cat_keyboard.jpeg" alt="A cat sleeping on a keyboard" />' },
     { code: '<input type="password" required />' },
     { code: '<input ref={this.input} type="radio" />' },
+    { code: '<input key="bar" type="radio" />' },
     { code: '<button disabled>You cannot click me</button>;' },
+    { code: '<svg key="lock" viewBox="box" fill={10} d="d" stroke={1} strokeWidth={2} strokeLinecap={3} strokeLinejoin={4} transform="something" clipRule="else" x1={5} x2="6" y1="7" y2="8"></svg>' },
+    { code: '<meta property="og:type" content="website" />' },
     // Case ignored attributes, for `charset` discussion see https://github.com/jsx-eslint/eslint-plugin-react/pull/1863
     { code: '<meta charset="utf-8" />;' },
     { code: '<meta charSet="utf-8" />;' },