Skip to content

Commit de04934

Browse files
committed
[Fix] add properties onToggle, fill, as and pointer events
1 parent 91ea5d5 commit de04934

File tree

2 files changed

+34
-4
lines changed

2 files changed

+34
-4
lines changed

lib/rules/no-unknown-property.js

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,16 @@ const ATTRIBUTE_TAGS_MAP = {
3030
checked: ['input'],
3131
// image is required for SVG support, all other tags are HTML.
3232
crossOrigin: ['script', 'img', 'video', 'audio', 'link', 'image'],
33-
fill: ['svg'],
33+
fill: [ // https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/fill
34+
// Fill color
35+
'altGlyph', 'circle', 'ellipse', 'path', 'polygon', 'polyline', 'rect', 'text', 'textPath', 'tref',
36+
'tspan', 'svg',
37+
// Animation final state
38+
'animate', 'animateColor', 'animateMotion', 'animateTransform', 'set',
39+
],
3440
property: ['meta'],
3541
viewBox: ['svg'],
42+
as: ['link'],
3643
};
3744

3845
const SVGDOM_ATTRIBUTE_NAMES = {
@@ -127,7 +134,7 @@ const DOM_PROPERTY_NAMES_ONE_WORD = [
127134
// Element specific attributes
128135
// See https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes (includes global attributes too)
129136
// To be considered if these should be added also to ATTRIBUTE_TAGS_MAP
130-
'accept', 'action', 'allow', 'alt', 'async', 'buffered', 'capture', 'challenge', 'cite', 'code', 'cols',
137+
'accept', 'action', 'allow', 'alt', 'as', 'async', 'buffered', 'capture', 'challenge', 'cite', 'code', 'cols',
131138
'content', 'coords', 'csp', 'data', 'decoding', 'default', 'defer', 'disabled', 'form',
132139
'headers', 'height', 'high', 'href', 'icon', 'importance', 'integrity', 'kind', 'label',
133140
'language', 'loading', 'list', 'loop', 'low', 'max', 'media', 'method', 'min', 'multiple', 'muted',
@@ -168,7 +175,7 @@ const DOM_PROPERTY_NAMES_TWO_WORDS = [
168175
'onCompositionUpdate', 'onCut', 'onDoubleClick', 'onDrag', 'onDragEnd', 'onDragEnter', 'onDragExit', 'onDragLeave',
169176
'onError', 'onFocus', 'onInput', 'onKeyDown', 'onKeyPress', 'onKeyUp', 'onLoad', 'onWheel', 'onDragOver',
170177
'onDragStart', 'onDrop', 'onMouseDown', 'onMouseEnter', 'onMouseLeave', 'onMouseMove', 'onMouseOut', 'onMouseOver',
171-
'onMouseUp', 'onPaste', 'onScroll', 'onSelect', 'onSubmit', 'onTransitionEnd', 'radioGroup', 'readOnly', 'referrerPolicy',
178+
'onMouseUp', 'onPaste', 'onScroll', 'onSelect', 'onSubmit', 'onToggle', 'onTransitionEnd', 'radioGroup', 'readOnly', 'referrerPolicy',
172179
'rowSpan', 'srcDoc', 'srcLang', 'srcSet', 'useMap',
173180
// SVG attributes
174181
// See https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute
@@ -230,7 +237,12 @@ function getDOMPropertyNames(context) {
230237
const ALL_DOM_PROPERTY_NAMES = DOM_PROPERTY_NAMES_TWO_WORDS.concat(DOM_PROPERTY_NAMES_ONE_WORD);
231238
// this was removed in React v16.1+, see https://github.com/facebook/react/pull/10823
232239
if (!testReactVersion(context, '>= 16.1.0')) {
233-
return ['allowTransparency'].concat(ALL_DOM_PROPERTY_NAMES);
240+
return ALL_DOM_PROPERTY_NAMES.concat(['allowTransparency']);
241+
}
242+
// these were added in React v16.4.0, see https://reactjs.org/blog/2018/05/23/react-v-16-4.html and https://github.com/facebook/react/pull/12507
243+
if (testReactVersion(context, '>= 16.4.0')) {
244+
return ALL_DOM_PROPERTY_NAMES.concat(['onPointerDown', 'onPointerMove', 'onPointerUp', 'onPointerCancel', 'onGotPointerCapture', 'onLostPointerCapture',
245+
'onPointerEnter', 'onPointerLeave', 'onPointerOver', 'onPointerOut']);
234246
}
235247
return ALL_DOM_PROPERTY_NAMES;
236248
}

tests/lib/rules/no-unknown-property.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ ruleTester.run('no-unknown-property', rule, {
5353
{ 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>' },
5454
{ code: '<meta property="og:type" content="website" />' },
5555
{ code: '<input type="checkbox" checked={checked} disabled={disabled} id={id} onChange={onChange} />' },
56+
// React related attributes
57+
{ code: '<div onPointerDown={this.onDown} onPointerUp={this.onUp} />' },
5658
// Case ignored attributes, for `charset` discussion see https://github.com/jsx-eslint/eslint-plugin-react/pull/1863
5759
{ code: '<meta charset="utf-8" />;' },
5860
{ code: '<meta charSet="utf-8" />;' },
@@ -82,6 +84,9 @@ ruleTester.run('no-unknown-property', rule, {
8284
{ code: '<script crossOrigin />' },
8385
{ code: '<audio crossOrigin />' },
8486
{ code: '<svg><image crossOrigin /></svg>' },
87+
{ code: '<details onToggle={this.onToggle}>Some details</details>' },
88+
{ code: '<path fill="pink" d="M 10,30 A 20,20 0,0,1 50,30 A 20,20 0,0,1 90,30 Q 90,60 50,90 Q 10,60 10,30 z"></path>' },
89+
{ code: '<link as="audio">Audio content</link>' },
8590
]),
8691
invalid: parsers.all([
8792
{
@@ -298,5 +303,18 @@ ruleTester.run('no-unknown-property', rule, {
298303
},
299304
],
300305
},
306+
{
307+
code: '<div as="audio" />',
308+
errors: [
309+
{
310+
messageId: 'invalidPropOnTag',
311+
data: {
312+
name: 'as',
313+
tagName: 'div',
314+
allowedTags: 'link',
315+
},
316+
},
317+
],
318+
},
301319
]),
302320
});

0 commit comments

Comments
 (0)