Skip to content

Commit

Permalink
Update docs
Browse files Browse the repository at this point in the history
  • Loading branch information
jackyho112 committed Aug 12, 2017
1 parent 0f0e292 commit 82fe18e
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 36 deletions.
60 changes: 51 additions & 9 deletions docs/rules/jsx-curly-brace-presence.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,12 @@ or alternatively

### Valid options for <string>

They are `always`, `never` and `ignore` for checking on JSX props and children.
They are `always`, `always,single`, `always,double`, `always,orignal`, `never` and `ignore` for checking on JSX props and children.

* `always`: always enforce curly braces inside JSX props or/and children
* `always`: always enforce curly braces inside JSX props or/and children and fix with double quotes inside the generated JSX expressions
* `always,single`: always enforce curly braces and fix with single quotes
* `always,double`: always enforce curly braces and fix with double quotes
* `always,original`: always enforce curly braces and fix with original quotes(default to double quotes for JSX children)
* `never`: never allow unnecessary curly braces inside JSX props or/and children
* `ignore`: ignore the rule for JSX props or/and children

Expand All @@ -45,21 +48,23 @@ When `{ props: "always", children: "always" }` is set, the following patterns wi
<App prop='Hello world'>{'Hello world'}</App>;
```

The following patterns won't.
They can be fixed to:

```jsx
<App>{'Hello world'}</App>;
<App prop={'Hello world'}>{'Hello world'}</App>;
<App>{"Hello world"}</App>;
<App prop={"Hello world"}>{"Hello world"}</App>;
```

They will fixed with single, double or original quotes based on the option you passed in. The default is double.

When `{ props: "never", children: "never" }` is set, the following patterns will be given warnings.

```jsx
<App>{'Hello world'}</App>;
<App prop={'Hello world'} />;
```

If passed in the option to fix, they will be corrected to
They can be fixed to:

```jsx
<App>Hello world</App>;
Expand All @@ -68,9 +73,9 @@ If passed in the option to fix, they will be corrected to

### Alternative syntax

The options are also `always`, `ignore` and `ignore` for the same meanings.
The options are also `always`, `always,single`, `always,double`, `always,orignal`, `never` and `ignore` for the same meanings.

If only a string is provided, the default will be set to that option for checking on both JSX props and children.
In this syntax, only a string is provided and the default will be set to that option for checking on both JSX props and children.

For examples:

Expand All @@ -81,13 +86,50 @@ When `'always'` is set, the following patterns will be given warnings.
<App prop='Hello world'>Hello world</App>;
```

And the following will pass.
They can be fixed to:
```jsx
<App>{"Hello world"}</App>;
<App prop={"Hello world"}>{"Hello world"}</App>;
```

If `'always,single'` is passed, they can be fixed to:

```jsx
<App>{'Hello world'}</App>;
<App prop={'Hello world'}>{'Hello world'}</App>;
```

## Edge cases

The fix also deals with template literals, strings with quotes and strings with escapes characters.

* If the rule is set to get rid of unnecessary curly braces and the template literal inside a JSX expression has no expression, it will throw a warning and be fixed with double quotes. For example:

```jsx
<App prop={`Hello world`}>Hello world</App>;
```

will warned and fixed to:

```jsx
<App prop="Hello world">Hello world</App>;
```

* If the rule is set to enforce curly braces and the strings have quotes, it will be fixed with original quotes for JSX attributes and double for JSX children. For example:


```jsx
<App prop='Hello "foo" world'>Hello 'foo' "bar" world</App>;
```

will warned and fixed to:

```jsx
<App prop={'Hello "foo" world'}>{"Hello 'foo' \"bar\" world"}</App>;
```

* If the rule is set to get rid of unnecessary curly braces and the strings will have escaped characters, it will not warn or fix for JSX children because JSX expressions are necessary in this case.

## When Not To Use It

You should turn this rule off if you are not concerned about maintaining consistency regarding the use of curly braces in JSX props and/or children as well as the use of unnecessary JSX expressions.
30 changes: 14 additions & 16 deletions lib/rules/jsx-curly-brace-presence.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,23 @@ const OPTION_NEVER = 'never';
const OPTION_IGNORE = 'ignore';
const OPTION_SINGLE_QUOTE = 'single';
const OPTION_DOUBLE_QUOTE = 'double';
const DEAULT_QUOTE_OPTION = OPTION_DOUBLE_QUOTE;
const OPTION_ORIGINAL_QUOTE = 'original';
const optionValues = [

const OPTION_VALUES = [
OPTION_ALWAYS,
`${OPTION_ALWAYS},${OPTION_SINGLE_QUOTE}`,
`${OPTION_ALWAYS},${OPTION_DOUBLE_QUOTE}`,
`${OPTION_ALWAYS},${OPTION_ORIGINAL_QUOTE}`,
OPTION_NEVER,
OPTION_IGNORE
];
const quoteOptionsValues = [OPTION_SINGLE_QUOTE, OPTION_DOUBLE_QUOTE];
const quoteOptionValueStore = {
const QUOTE_OPTON_VALUE_STORE = {
[OPTION_SINGLE_QUOTE]: '\'',
[OPTION_DOUBLE_QUOTE]: '"'
[OPTION_DOUBLE_QUOTE]: '"',
[OPTION_ORIGINAL_QUOTE]: '"' // Defaults to double if no orignal quote
};
const defaultConfig = {props: OPTION_NEVER, children: OPTION_NEVER};
const DEFAULT_CONFIG = {props: OPTION_NEVER, children: OPTION_NEVER};

module.exports = {
meta: {
Expand All @@ -46,18 +48,15 @@ module.exports = {
{
type: 'object',
properties: {
props: {enum: optionValues, default: OPTION_NEVER},
children: {enum: optionValues, default: OPTION_NEVER}
props: {enum: OPTION_VALUES, default: OPTION_NEVER},
children: {enum: OPTION_VALUES, default: OPTION_NEVER}
},
additionalProperties: false
},
{
enum: optionValues
}
]
},
{
enum: quoteOptionsValues
}
]
},
Expand All @@ -66,7 +65,7 @@ module.exports = {
const ruleOptions = context.options[0];
const userConfig = typeof ruleOptions === 'string' ?
{props: ruleOptions, children: ruleOptions} :
Object.assign({}, defaultConfig, ruleOptions);
Object.assign({}, DEFAULT_CONFIG, ruleOptions);

function containsBackslashForEscaping(rawStringValue) {
return rawStringValue.includes('\\');
Expand Down Expand Up @@ -107,7 +106,6 @@ module.exports = {
}

function wrapLiteralNodeInJSXExpression(fixer, literalNode) {
const defaultQuoteOption = context.options[1] || OPTION_DOUBLE_QUOTE;
const {parent: {type: parentType}} = literalNode;
const {raw, value} = literalNode;
const valueContainsQuote = containsQuote(value);
Expand All @@ -122,8 +120,8 @@ module.exports = {
}

if (
userSetQuoteOption === OPTION_ORIGINAL_QUOTE ||
(parentType === 'JSXAttribute' && valueContainsQuote)
parentType === 'JSXAttribute' &&
(userSetQuoteOption === OPTION_ORIGINAL_QUOTE || valueContainsQuote)
) {
return fixer.replaceText(literalNode, `{${raw}}`);
}
Expand All @@ -132,8 +130,8 @@ module.exports = {
return fixer.replaceText(literalNode, `{${JSON.stringify(value)}}`);
}

const quoteStyle = quoteOptionValueStore[
userSetQuoteOption || defaultQuoteOption
const quoteStyle = QUOTE_OPTON_VALUE_STORE[
userSetQuoteOption || DEAULT_QUOTE_OPTION
];
return fixer.replaceText(
literalNode,
Expand Down
34 changes: 23 additions & 11 deletions tests/lib/rules/jsx-curly-brace-presence.js
Original file line number Diff line number Diff line change
Expand Up @@ -268,15 +268,15 @@ ruleTester.run('jsx-curly-brace-presence', rule, {
{
code: '<MyComponent prop=\'bar\'>foo</MyComponent>',
output: '<MyComponent prop={\'bar\'}>{\'foo\'}</MyComponent>',
options: ['always', 'single'],
options: ['always,single'],
errors: [
{message: missingCurlyMessage}, {message: missingCurlyMessage}
]
},
{
code: '<MyComponent prop=\'bar\'>foo</MyComponent>',
output: '<MyComponent prop={\"bar\"}>{\"foo\"}</MyComponent>',
options: ['always', 'double'],
options: ['always,double'],
errors: [
{message: missingCurlyMessage}, {message: missingCurlyMessage}
]
Expand All @@ -300,39 +300,39 @@ ruleTester.run('jsx-curly-brace-presence', rule, {
{
code: '<MyComponent prop=\"bar\">foo</MyComponent>',
output: '<MyComponent prop={\'bar\'}>{\"foo\"}</MyComponent>',
options: [{props: 'always', children: 'always,double'}, 'single'],
options: [{props: 'always,single', children: 'always,double'}],
errors: [
{message: missingCurlyMessage}, {message: missingCurlyMessage}
]
},
{
code: '<MyComponent prop=\"bar\">foo</MyComponent>',
output: '<MyComponent prop={\'bar\'}>{\'foo\'}</MyComponent>',
options: [{props: 'always', children: 'always'}, 'single'],
options: [{props: 'always,single', children: 'always,single'}],
errors: [
{message: missingCurlyMessage}, {message: missingCurlyMessage}
]
},
{
code: '<MyComponent prop=\'bar\'>foo</MyComponent>',
output: '<MyComponent prop={\"bar\"}>{\"foo\"}</MyComponent>',
options: [{props: 'always,double', children: 'always,double'}, 'single'],
options: [{props: 'always,double', children: 'always,double'}],
errors: [
{message: missingCurlyMessage}, {message: missingCurlyMessage}
]
},
{
code: '<MyComponent prop=\'bar\'>foo<App/></MyComponent>',
output: '<MyComponent prop={\"bar\"}>{\"foo\"}<App/></MyComponent>',
options: ['always', 'double'],
options: ['always,double'],
errors: [
{message: missingCurlyMessage}, {message: missingCurlyMessage}
]
},
{
code: '<MyComponent prop=\'bar\'><App/>foo</MyComponent>',
output: '<MyComponent prop={\"bar\"}><App/>{\"foo\"}</MyComponent>',
options: ['always', 'double'],
options: ['always,double'],
errors: [
{message: missingCurlyMessage}, {message: missingCurlyMessage}
]
Expand Down Expand Up @@ -361,34 +361,46 @@ ruleTester.run('jsx-curly-brace-presence', rule, {
options: [{props: 'always,original'}],
errors: [{message: missingCurlyMessage}]
},
{
code: '<MyComponent prop=\'bar \\n bar \"hello\" foo \'>foo</MyComponent>',
output: '<MyComponent prop={\'bar \\n bar \"hello\" foo \'}>{"foo"}</MyComponent>',
options: ['always,original'],
errors: [{message: missingCurlyMessage}, {message: missingCurlyMessage}]
},
{
code: '<MyComponent prop=\'foo\'>foo \\n \'bar\' "foo"</MyComponent>',
output: '<MyComponent prop={\'foo\'}>{"foo \\\\n \'bar\' \\"foo\\""}</MyComponent>',
options: ['always,original'],
errors: [{message: missingCurlyMessage}, {message: missingCurlyMessage}]
},
{
code: '<MyComponent prop=\'bar\"bar\"foo\'>foo"bar"</MyComponent>',
output: '<MyComponent prop={\'bar\"bar\"foo\'}>{\"foo\\"bar\\"\"}</MyComponent>',
options: ['always', 'single'],
options: ['always,single'],
errors: [
{message: missingCurlyMessage}, {message: missingCurlyMessage}
]
},
{
code: '<MyComponent prop=\'bar\"bar\"foo\'>foo"bar"</MyComponent>',
output: '<MyComponent prop={\'bar\"bar\"foo\'}>{\"foo\\"bar\\"\"}</MyComponent>',
options: ['always', 'double'],
options: ['always,double'],
errors: [
{message: missingCurlyMessage}, {message: missingCurlyMessage}
]
},
{
code: '<MyComponent prop="bar\'bar\'foo">foo\'bar\'</MyComponent>',
output: '<MyComponent prop={"bar\'bar\'foo"}>{"foo\'bar\'"}</MyComponent>',
options: ['always', 'single'],
options: ['always,single'],
errors: [
{message: missingCurlyMessage}, {message: missingCurlyMessage}
]
},
{
code: '<MyComponent prop="bar\'bar\'foo">foo\'bar\'</MyComponent>',
output: '<MyComponent prop={"bar\'bar\'foo"}>{"foo\'bar\'"}</MyComponent>',
options: ['always', 'double'],
options: ['always,double'],
errors: [
{message: missingCurlyMessage}, {message: missingCurlyMessage}
]
Expand Down

0 comments on commit 82fe18e

Please sign in to comment.