@@ -27,8 +27,8 @@ const ruleTester = new RuleTester();
2727
2828const expectedError = {
2929 message : 'Elements with onClick handlers must be focusable. ' +
30- 'Either set the tabIndex property (usually 0), or use an element type which ' +
31- 'is inherently focusable such as `button`.' ,
30+ 'Either set the tabIndex property to a valid value (usually 0), ' +
31+ 'or use an element type which is inherently focusable such as `button`.' ,
3232 type : 'JSXOpeningElement'
3333} ;
3434
@@ -46,20 +46,23 @@ ruleTester.run('onclick-has-focus', rule, {
4646 { code : '<div aria-hidden={2 >= 1} onClick={() => void 0} />' , parserOptions } ,
4747 { code : '<input type="text" onClick={() => void 0} />' , parserOptions } ,
4848 { code : '<input type="hidden" onClick={() => void 0} tabIndex="-1" />' , parserOptions } ,
49+ { code : '<input type="hidden" onClick={() => void 0} tabIndex={-1} />' , parserOptions } ,
4950 { code : '<input onClick={() => void 0} />' , parserOptions } ,
5051 { code : '<button onClick={() => void 0} className="foo" />' , parserOptions } ,
5152 { code : '<option onClick={() => void 0} className="foo" />' , parserOptions } ,
5253 { code : '<select onClick={() => void 0} className="foo" />' , parserOptions } ,
5354 { code : '<area href="#" onClick={() => void 0} className="foo" />' , parserOptions } ,
5455 { code : '<textarea onClick={() => void 0} className="foo" />' , parserOptions } ,
5556 { code : '<a tabIndex="0" onClick={() => void 0} />' , parserOptions } ,
57+ { code : '<a tabIndex={0} onClick={() => void 0} />' , parserOptions } ,
5658 { code : '<a role="button" href="#" onClick={() => void 0} />' , parserOptions } ,
5759 { code : '<a onClick={() => void 0} href="http://x.y.z" />' , parserOptions } ,
5860 { code : '<a onClick={() => void 0} href="http://x.y.z" tabIndex="0" />' , parserOptions } ,
61+ { code : '<a onClick={() => void 0} href="http://x.y.z" tabIndex={0} />' , parserOptions } ,
5962 { code : '<TestComponent onClick={doFoo} />' , parserOptions } ,
6063 { code : '<input onClick={() => void 0} type="hidden" />;' , parserOptions } ,
6164 { code : '<span onClick="doSomething();" tabIndex="0">Click me!</span>' , parserOptions } ,
62- { code : '<span onClick="doSomething();" tabIndex="0" >Click me!</span>' , parserOptions } ,
65+ { code : '<span onClick="doSomething();" tabIndex={0} >Click me!</span>' , parserOptions } ,
6366 { code : '<span onClick="doSomething();" tabIndex="-1">Click me too!</span>' , parserOptions } ,
6467 { code : '<a href="javascript:void(0);" onClick="doSomething();">Click ALL the things!</a>' , parserOptions } ,
6568 { code : '<Foo.Bar onClick={() => void 0} aria-hidden={false} />;' , parserOptions } ,
@@ -69,17 +72,22 @@ ruleTester.run('onclick-has-focus', rule, {
6972 invalid : [
7073 { code : '<span onClick="submitForm();">Submit</span>' , errors : [ expectedError ] , parserOptions } ,
7174 { code : '<span onClick="submitForm();" tabIndex={undefined}>Submit</span>' , errors : [ expectedError ] , parserOptions } ,
75+ { code : '<span onClick="submitForm();" tabIndex="bad">Submit</span>' , errors : [ expectedError ] , parserOptions } ,
7276 { code : '<a onClick="showNextPage();">Next page</a>' , errors : [ expectedError ] , parserOptions } ,
77+ { code : '<a onClick="showNextPage();" tabIndex={undefined}>Next page</a>' , errors : [ expectedError ] , parserOptions } ,
78+ { code : '<a onClick="showNextPage();" tabIndex="bad">Next page</a>' , errors : [ expectedError ] , parserOptions } ,
79+ { code : '<a onClick={() => void 0} />' , errors : [ expectedError ] , parserOptions } ,
7380 { code : '<area onClick={() => void 0} className="foo" />' , errors : [ expectedError ] , parserOptions } ,
7481 { code : '<div onClick={() => void 0} />;' , errors : [ expectedError ] , parserOptions } ,
82+ { code : '<div onClick={() => void 0} tabIndex={undefined} />;' , errors : [ expectedError ] , parserOptions } ,
83+ { code : '<div onClick={() => void 0} tabIndex="bad" />;' , errors : [ expectedError ] , parserOptions } ,
7584 { code : '<div onClick={() => void 0} role={undefined} />;' , errors : [ expectedError ] , parserOptions } ,
85+ { code : '<div onClick={() => void 0} aria-hidden={false} />;' , errors : [ expectedError ] , parserOptions } ,
7686 { code : '<div onClick={() => void 0} {...props} />;' , errors : [ expectedError ] , parserOptions } ,
7787 { code : '<section onClick={() => void 0} />;' , errors : [ expectedError ] , parserOptions } ,
7888 { code : '<main onClick={() => void 0} />;' , errors : [ expectedError ] , parserOptions } ,
7989 { code : '<article onClick={() => void 0} />;' , errors : [ expectedError ] , parserOptions } ,
8090 { code : '<header onClick={() => void 0} />;' , errors : [ expectedError ] , parserOptions } ,
81- { code : '<footer onClick={() => void 0} />;' , errors : [ expectedError ] , parserOptions } ,
82- { code : '<div onClick={() => void 0} aria-hidden={false} />;' , errors : [ expectedError ] , parserOptions } ,
83- { code : '<a onClick={() => void 0} />' , errors : [ expectedError ] , parserOptions }
91+ { code : '<footer onClick={() => void 0} />;' , errors : [ expectedError ] , parserOptions }
8492 ]
8593} ) ;
0 commit comments