Skip to content

Commit

Permalink
Add beforeClosing option to jsx-tag-spacing
Browse files Browse the repository at this point in the history
  • Loading branch information
CJ Skillingstad committed Jan 11, 2018
1 parent 07345b4 commit 73c86c9
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 5 deletions.
49 changes: 46 additions & 3 deletions docs/rules/jsx-tag-spacing.md
@@ -1,22 +1,23 @@
# Validate whitespace in and around the JSX opening and closing brackets (react/jsx-tag-spacing)

Enforce or forbid spaces after the opening bracket, before the closing bracket of self-closing elements, and between the angle bracket and slash of JSX closing or self-closing elements.
Enforce or forbid spaces after the opening bracket, before the closing bracket, before the closing bracket of self-closing elements, and between the angle bracket and slash of JSX closing or self-closing elements.

**Fixable:** This rule is automatically fixable using the `--fix` flag on the command line.

## Rule Details

This rule checks the whitespace inside and surrounding the JSX syntactic elements.

This rule takes one argument, an object with 3 possible keys: `closingSlash`, `beforeSelfClosing` and `afterOpening`. Each key can receive the value `"allow"` to disable that specific check.
This rule takes one argument, an object with 4 possible keys: `closingSlash`, `beforeSelfClosing`, `afterOpening`, and `beforeClosing`. Each key can receive the value `"allow"` to disable that specific check.

The default values are:

```json
{
"closingSlash": "never",
"beforeSelfClosing": "always",
"afterOpening": "never"
"afterOpening": "never",
"beforeClosing": "never"
}
```

Expand Down Expand Up @@ -176,6 +177,48 @@ The following patterns are **not** considered warnings when configured `"allow-m
/>
```

### `beforeClosing`

This check can be set to `"always"`, `"never"`, or `"allow"` (to disable it).

If it is `"always"` the check warns whenever whitespace is missing before the closing bracket of a JSX opening element or whenever a space is missing before the closing bracket closing element. If `"never"`, them it warns if a space is present before the closing bracket of either a JSX opening element or closing element. This rule will never warn for self closing JSX elements. The default value of this check is `"never"`.

The following patterns are considered warnings when configured `"always"`:

```jsx
<Hello></Hello>
<Hello></Hello >
<Hello ></Hello>
```

The following patterns are **not** considered warnings when configured `"always"`:

```jsx
<Hello ></Hello >
<Hello
firstName="John"
>
</Hello >
```

The following patterns are considered warnings when configured `"never"`:

```jsx
<Hello ></Hello>
<Hello></Hello >
<Hello ></Hello >
```

The following patterns are **not** considered warnings when configured `"never"`:

```jsx
<Hello></Hello>
<Hello
firstName="John"
>
</Hello>
```

## When Not To Use It

You can turn this rule off if you are not concerned with the consistency of spacing in or around JSX brackets.
61 changes: 59 additions & 2 deletions lib/rules/jsx-tag-spacing.js
Expand Up @@ -169,6 +169,52 @@ function validateAfterOpening(context, node, option) {
}
}

function validateBeforeClosing(context, node, option) {
// Don't enforce this rule for self closing tags
if (!node.selfClosing) {
const sourceCode = context.getSourceCode();

const NEVER_MESSAGE = 'A space is forbidden before closing bracket';
const ALWAYS_MESSAGE = 'Whitespace is required before closing bracket';

const lastTokens = sourceCode.getLastTokens(node, 2);
const closingToken = lastTokens[1];
const leftToken = lastTokens[0];

if (leftToken.loc.start.line !== closingToken.loc.start.line) {
return;
}

const adjacent = !sourceCode.isSpaceBetweenTokens(leftToken, closingToken);

if (option === 'never' && !adjacent) {
context.report({
node: node,
loc: {
start: leftToken.loc.end,
end: closingToken.loc.start
},
message: NEVER_MESSAGE,
fix: function(fixer) {
return fixer.removeRange([leftToken.range[1], closingToken.range[0]]);
}
});
} else if (option === 'always' && adjacent) {
context.report({
node: node,
loc: {
start: leftToken.loc.end,
end: closingToken.loc.start
},
message: ALWAYS_MESSAGE,
fix: function(fixer) {
return fixer.insertTextBefore(closingToken, ' ');
}
});
}
}
}

// ------------------------------------------------------------------------------
// Rule Definition
// ------------------------------------------------------------------------------
Expand All @@ -191,12 +237,16 @@ module.exports = {
},
afterOpening: {
enum: ['always', 'allow-multiline', 'never', 'allow']
},
beforeClosing: {
enum: ['always', 'never', 'allow']
}
},
default: {
closingSlash: 'never',
beforeSelfClosing: 'always',
afterOpening: 'never'
afterOpening: 'never',
beforeClosing: 'never'
},
additionalProperties: false
}
Expand All @@ -206,7 +256,8 @@ module.exports = {
const options = {
closingSlash: 'never',
beforeSelfClosing: 'always',
afterOpening: 'never'
afterOpening: 'never',
beforeClosing: 'never'
};
for (const key in options) {
if (has(options, key) && has(context.options[0] || {}, key)) {
Expand All @@ -225,6 +276,9 @@ module.exports = {
if (options.beforeSelfClosing !== 'allow' && node.selfClosing) {
validateBeforeSelfClosing(context, node, options.beforeSelfClosing);
}
if (options.beforeClosing !== 'allow') {
validateBeforeClosing(context, node, options.beforeClosing);
}
},
JSXClosingElement: function (node) {
if (options.afterOpening !== 'allow') {
Expand All @@ -233,6 +287,9 @@ module.exports = {
if (options.closingSlash !== 'allow') {
validateClosingSlash(context, node, options.closingSlash);
}
if (options.beforeClosing !== 'allow') {
validateBeforeClosing(context, node, options.beforeClosing);
}
}
};
}
Expand Down

0 comments on commit 73c86c9

Please sign in to comment.