Skip to content

Commit aaf50b1

Browse files
authored
Merge pull request temando#79 from brendo/no-bind-jsx
Fix `react/jsx-no-bind` violations, simplify Example
2 parents 7a8bce8 + 40d838c commit aaf50b1

File tree

25 files changed

+402
-291
lines changed

25 files changed

+402
-291
lines changed

.eslintrc.json

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,5 @@
88
"browser": true,
99
"node": true,
1010
"jest": true
11-
},
12-
"rules": {
13-
// Temporary, components need to be rewritten to take advantage of this
14-
"react/jsx-no-bind": 0
1511
}
1612
}

jest.config.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@ module.exports = {
77
'node_modules'
88
],
99
moduleNameMapper: {
10+
'balloon-css': '<rootDir>/src/__mocks__/styleMock.js',
1011
'\\.(css|scss)$': '<rootDir>/src/__mocks__/styleMock.js',
11-
'\\.(jpg|jpeg|png|gif|svg)$': '<rootDir>/src/__mocks__/styleMock.js'
12+
'\\.(jpg|jpeg|png|gif|svg)$': '<rootDir>/src/__mocks__/fileMock.js'
1213
},
1314
moduleFileExtensions: [
1415
'js',
@@ -17,4 +18,4 @@ module.exports = {
1718
],
1819
testEnvironment: 'node',
1920
verbose: true
20-
};
21+
}

package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,9 @@
2424
"prop-types": "^15.5.8",
2525
"react": "^15.5.4",
2626
"react-addons-create-fragment": "^15.5.4",
27-
"react-addons-css-transition-group": "^15.5.2",
2827
"react-document-title": "^2.0.2",
2928
"react-dom": "^15.5.4",
30-
"react-json-view": "^1.7.5",
29+
"react-json-view": "^1.8.2",
3130
"react-redux": "^5.0.3",
3231
"react-router": "3.0.0",
3332
"react-router-redux": "^4.0.8",

src/components/BodyContent/BodyContent.js

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,22 +13,22 @@ export default class BodyContent extends Component {
1313

1414
this.renderTabs = this.renderTabs.bind(this)
1515
this.renderSchema = this.renderSchema.bind(this)
16-
this.renderExample = this.renderExample.bind(this)
16+
this.renderExamples = this.renderExamples.bind(this)
1717

1818
this.state = {
1919
tab: 'schema'
2020
}
2121
}
2222

2323
render () {
24-
const { schema, example, examples } = this.props
24+
const { schema, examples } = this.props
2525

2626
const { tab } = this.state
2727
return (
2828
<div className='body-content'>
29-
{schema && this.renderTabs(schema, example || examples)}
29+
{schema && this.renderTabs(schema, examples)}
3030
{tab === 'schema' && this.renderSchema(schema)}
31-
{tab === 'example' && this.renderExample(example, examples)}
31+
{tab === 'example' && this.renderExamples(examples)}
3232
</div>
3333
)
3434
}
@@ -38,7 +38,7 @@ export default class BodyContent extends Component {
3838
return (
3939
<div className='body-content-tabs'>
4040
{includeSchema && this.renderSchemaTab(currentTab)}
41-
{includeExample && this.renderExampleTab(currentTab)}
41+
{includeExample && this.renderExamplesTab(currentTab)}
4242
</div>
4343
)
4444
}
@@ -57,7 +57,7 @@ export default class BodyContent extends Component {
5757
)
5858
}
5959

60-
renderExampleTab (currentTab) {
60+
renderExamplesTab (currentTab) {
6161
return (
6262
<div
6363
role='button'
@@ -72,23 +72,23 @@ export default class BodyContent extends Component {
7272
}
7373

7474
renderSchema (schema) {
75-
if (schema) {
76-
return (
77-
<BodySchema properties={schema} styleVariation='odd' />
78-
)
75+
if (!schema) {
76+
return null
7977
}
80-
return null
78+
79+
return (
80+
<BodySchema properties={schema} styleVariation='odd' />
81+
)
8182
}
8283

83-
renderExample (example, examples) {
84+
renderExamples (examples) {
8485
return (
85-
<Example example={example} examples={examples} />
86+
<Example examples={examples} />
8687
)
8788
}
8889
}
8990

9091
BodyContent.propTypes = {
9192
schema: PropTypes.array,
92-
example: PropTypes.string,
9393
examples: PropTypes.array
9494
}

src/components/BodySchema/BodySchema.js

Lines changed: 37 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import React, { Component } from 'react'
22
import createFragment from 'react-addons-create-fragment'
3-
import ReactCSSTransitionGroup from 'react-addons-css-transition-group'
43
import classNames from 'classnames'
54
import PropTypes from 'prop-types'
65

@@ -14,6 +13,7 @@ export default class BodySchema extends Component {
1413

1514
this.renderPropertyRow = this.renderPropertyRow.bind(this)
1615
this.renderSubsetProperties = this.renderSubsetProperties.bind(this)
16+
this.onClick = this.onClick.bind(this)
1717

1818
this.state = {
1919
expandedProp: []
@@ -28,41 +28,37 @@ export default class BodySchema extends Component {
2828
}
2929

3030
const { expandedProp } = this.state
31-
let iterator = 0
31+
3232
return (
3333
<table className={classNames('body-schema', `body-schema--${styleVariation}`)}>
3434
<tbody>
35-
{properties.map((property) => {
36-
iterator = iterator + 1
37-
let isLast = false
38-
if (properties.length === iterator) {
39-
isLast = true
40-
}
35+
{properties.map((property, i) => {
36+
const isLast = (properties.length === i + 1)
4137

42-
if (property.type.includes('array') && expandedProp.includes(property.name) && property.properties !== undefined) {
43-
return createFragment({
44-
property: this.renderPropertyRow(property, isLast, true),
45-
subset: this.renderSubsetProperties(property, true)
46-
})
47-
} else if (property.type.includes('array') && property.properties !== undefined) {
48-
return this.renderPropertyRow(property, isLast, false)
49-
} else if (property.type.includes('object') && expandedProp.includes(property.name) && property.properties !== undefined) {
50-
return createFragment({
51-
property: this.renderPropertyRow(property, isLast, true),
52-
subset: this.renderSubsetProperties(property)
53-
})
54-
} else if (property.type.includes('object') && property.properties !== undefined) {
55-
return this.renderPropertyRow(property, isLast, false)
56-
} else {
38+
if (property.properties === undefined) {
5739
return this.renderPropertyRow(property, isLast)
5840
}
41+
42+
const isPropertyArray = property.type.includes('array')
43+
const isPropertyObject = property.type.includes('object')
44+
45+
if (isPropertyArray || isPropertyObject) {
46+
if (expandedProp.includes(property.name)) {
47+
return createFragment({
48+
property: this.renderPropertyRow(property, isLast, true, true),
49+
subset: this.renderSubsetProperties(property, isPropertyArray)
50+
})
51+
}
52+
53+
return this.renderPropertyRow(property, isLast, false, true)
54+
}
5955
})}
6056
</tbody>
6157
</table>
6258
)
6359
}
6460

65-
renderPropertyRow (property, isLast, isOpen) {
61+
renderPropertyRow (property, isLast, isOpen = false, hasSubset = false) {
6662
return (
6763
<Property
6864
key={property.name}
@@ -73,7 +69,7 @@ export default class BodySchema extends Component {
7369
enumValues={property.enum}
7470
defaultValue={property.defaultValue}
7571
constraints={property.constraints}
76-
onClick={this.onClick.bind(this, property.name)}
72+
onClick={hasSubset ? this.onClick : undefined}
7773
isRequired={property.required}
7874
isOpen={isOpen}
7975
isLast={isLast}
@@ -83,35 +79,32 @@ export default class BodySchema extends Component {
8379

8480
renderSubsetProperties (property, isArray = false) {
8581
const { styleVariation } = this.props
86-
let nextStyleVariation = 'even'
87-
if (styleVariation === 'even') {
88-
nextStyleVariation = 'odd'
89-
}
82+
const nextStyleVariation = (styleVariation === 'even') ? 'odd' : 'even'
83+
9084
return (
9185
<tr className='body-schema-subset'>
9286
<td colSpan='100'>
93-
<ReactCSSTransitionGroup
94-
transitionName='schema-slide-toggle'
95-
transitionEnterTimeout={500}
96-
transitionLeaveTimeout={500}
97-
transitionAppear
98-
transitionAppearTimeout={500}
99-
>
100-
{isArray && <div>Array [</div>}
101-
<BodySchema
102-
key={`${property.name}-properties`}
103-
properties={property.properties}
104-
styleVariation={nextStyleVariation}
105-
/>
106-
{isArray && <div>]</div>}
107-
</ReactCSSTransitionGroup>
87+
{isArray && <div>Array [</div>}
88+
<BodySchema
89+
key={`${property.name}-properties`}
90+
properties={property.properties}
91+
styleVariation={nextStyleVariation}
92+
/>
93+
{isArray && <div>]</div>}
10894
</td>
10995
</tr>
11096
)
11197
}
11298

99+
/**
100+
* Responsible for updating the state of all properties that
101+
* have been expanded by the user.
102+
*
103+
* @param {string} propertyName
104+
*/
113105
onClick (propertyName) {
114106
const { expandedProp } = this.state
107+
115108
if (expandedProp.includes(propertyName)) {
116109
const newExpanded = expandedProp.filter((prop) => prop !== propertyName)
117110
this.setState({ expandedProp: newExpanded })

src/components/Example/Example.js

Lines changed: 27 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -13,79 +13,61 @@ export default class Example extends Component {
1313
super(props)
1414

1515
this.onCopyClick = this.onCopyClick.bind(this)
16-
this.updateState = this.updateState.bind(this)
17-
this.renderString = this.renderString.bind(this)
18-
this.renderJson = this.renderJson.bind(this)
19-
20-
const { example, examples } = this.props
21-
let exampleToShow = example
22-
23-
if (!exampleToShow && examples && examples.length > 0) {
24-
exampleToShow = examples[0]
25-
}
2616

2717
this.state = {
2818
hovered: false,
29-
collapseAll: false,
30-
example: exampleToShow
19+
collapseAll: false
3120
}
3221
}
3322

3423
render () {
35-
const example = this.state.example
24+
const { examples } = this.props
25+
let example
3626

37-
if (example) {
38-
if (typeof example === 'string') {
39-
return this.renderString(example)
40-
} else {
41-
return this.renderJson(example)
42-
}
27+
// TODO: Handle multiple examples
28+
if (examples && examples.length) {
29+
example = examples[0]
4330
}
4431

45-
return null
46-
}
32+
const isSimple = typeof example === 'string'
4733

48-
renderString (example) {
49-
return (
50-
<div className='body-content-example'>{example}</div>
51-
)
52-
}
34+
if (!example) {
35+
return null
36+
}
5337

54-
renderJson (example) {
5538
return (
5639
<div className='body-content-example'
57-
onMouseEnter={() => this.updateState({ hovered: true })}
58-
onMouseLeave={() => this.updateState({ hovered: false })}
40+
onMouseEnter={() => this.setState({ hovered: true })}
41+
onMouseLeave={() => this.setState({ hovered: false })}
5942
>
6043
<div className={classNames('action-buttons', {
6144
hovered: this.state.hovered
6245
})}>
6346
<CopyButton onCopyClick={this.onCopyClick} tooltip='Copy to Clipboard' />
64-
<span onClick={() => this.updateState({ collapseAll: false })}>Expand All</span>
65-
<span onClick={() => this.updateState({ collapseAll: true })}>Collapse All</span>
47+
{!isSimple &&
48+
<span onClick={() => this.setState({ collapseAll: false })}>Expand All</span>}
49+
{!isSimple &&
50+
<span onClick={() => this.setState({ collapseAll: true })}>Collapse All</span>}
6651
</div>
67-
<ReactJson src={example} theme='chalk' displayDataTypes={false} displayObjectSize={false}
68-
collapsed={this.state.collapseAll}
69-
enableClipboard={false} />
52+
{isSimple
53+
? {example}
54+
: <ReactJson
55+
src={example}
56+
theme='chalk'
57+
displayDataTypes={false}
58+
displayObjectSize={false}
59+
collapsed={this.state.collapseAll}
60+
enableClipboard={false}
61+
/>}
7062
</div>
7163
)
7264
}
7365

74-
/**
75-
* Update internal state
76-
*
77-
* @param {Object} changedState
78-
*/
79-
updateState (changedState) {
80-
this.setState(Object.assign({}, this.state, changedState))
81-
}
82-
8366
onCopyClick () {
84-
copy(JSON.stringify(this.state.example, null, 2))
67+
copy(JSON.stringify(this.props.examples[0], null, 2))
8568
}
8669
}
8770

8871
Example.propTypes = {
89-
example: PropTypes.string,
9072
examples: PropTypes.array
9173
}

src/components/Indicator/Indicator.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@ export default class Indicator extends Component {
1111
const { status, className } = this.props
1212

1313
return (
14-
<div className={classNames('indicator', className, {
14+
<span className={classNames('indicator', className, {
1515
[`indicator--${status}`]: status
1616
})}>
17-
<img src={arrow} title='arrow' />
18-
</div>
17+
<img src={arrow} alt='' title='arrow' />
18+
</span>
1919
)
2020
}
2121
}

0 commit comments

Comments
 (0)