Skip to content

Commit 0e8530e

Browse files
committed
Add jsx-no-typeless-button rule
1 parent f36b0fa commit 0e8530e

File tree

4 files changed

+108
-0
lines changed

4 files changed

+108
-0
lines changed

docs/rules/jsx-no-typeless-button.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Prevent usage of `button` elements without an explicit `type` attribute (react/jsx-no-typeless-button)
2+
3+
The default value of `type` attribute for `button` HTML element is `"submit"` which is often not the desired behavior and may lead to unexpected page reloads.
4+
This rules enforces an explicit `type` attribute for all the `button` elements.
5+
6+
## Rule Details
7+
8+
The following patterns are considered errors:
9+
10+
```jsx
11+
var Hello = <button>Hello</button>
12+
```
13+
14+
The following patterns are **not** considered errors:
15+
16+
```jsx
17+
var Hello = <span>Hello</span>
18+
var Hello = <button type="button">Hello</button>
19+
var Hello = <button type="submit">Hello</button>
20+
var Hello = <button type="reset">Hello</button>
21+
```
22+
23+
## When Not To Use It
24+
25+
If you use only `"submit"` buttons, you can disable this rule

index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ const allRules = {
2929
'jsx-no-duplicate-props': require('./lib/rules/jsx-no-duplicate-props'),
3030
'jsx-no-literals': require('./lib/rules/jsx-no-literals'),
3131
'jsx-no-target-blank': require('./lib/rules/jsx-no-target-blank'),
32+
'jsx-no-typeless-button': require('./lib/rules/jsx-no-typeless-button'),
3233
'jsx-no-undef': require('./lib/rules/jsx-no-undef'),
3334
'jsx-curly-brace-presence': require('./lib/rules/jsx-curly-brace-presence'),
3435
'jsx-pascal-case': require('./lib/rules/jsx-pascal-case'),

lib/rules/jsx-no-typeless-button.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/**
2+
* @fileoverview Forbid "button" element without an explicit "type" attribute
3+
* @author Filipp Riabchun
4+
*/
5+
'use strict';
6+
7+
const hasProp = require('jsx-ast-utils/hasProp');
8+
9+
// ------------------------------------------------------------------------------
10+
// Rule Definition
11+
// ------------------------------------------------------------------------------
12+
13+
module.exports = {
14+
meta: {
15+
docs: {
16+
description: 'Forbid "button" element without an explicit "type" attribute',
17+
category: 'Possible Errors',
18+
recommended: false
19+
},
20+
schema: []
21+
},
22+
23+
create: function(context) {
24+
return {
25+
JSXElement: function(node) {
26+
if (node.openingElement.name.name !== 'button') {
27+
return;
28+
}
29+
30+
if (hasProp(node.openingElement.attributes, 'type')) {
31+
return;
32+
}
33+
34+
context.report({
35+
node: node,
36+
message: 'Missing an explicit "type" attribute for button'
37+
});
38+
}
39+
};
40+
}
41+
};
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/**
2+
* @fileoverview Forbid "button" element without an explicit "type" attribute
3+
* @author Filipp Riabchun
4+
*/
5+
'use strict';
6+
7+
// ------------------------------------------------------------------------------
8+
// Requirements
9+
// ------------------------------------------------------------------------------
10+
11+
const rule = require('../../../lib/rules/jsx-no-typeless-button');
12+
const RuleTester = require('eslint').RuleTester;
13+
14+
const parserOptions = {
15+
ecmaVersion: 8,
16+
sourceType: 'module',
17+
ecmaFeatures: {
18+
experimentalObjectRestSpread: true,
19+
jsx: true
20+
}
21+
};
22+
23+
// ------------------------------------------------------------------------------
24+
// Tests
25+
// ------------------------------------------------------------------------------
26+
27+
const ruleTester = new RuleTester({parserOptions});
28+
ruleTester.run('jsx-no-typeless-button', rule, {
29+
valid: [
30+
{code: '<span/>'},
31+
{code: '<button type="button"/>'},
32+
{code: '<button type="submit"/>'},
33+
{code: '<button type="reset"/>'}
34+
],
35+
invalid: [{
36+
code: '<button/>',
37+
errors: [{
38+
message: 'Missing an explicit "type" attribute for button'
39+
}]
40+
}]
41+
});

0 commit comments

Comments
 (0)