diff --git a/.eslintrc.js b/.eslintrc.js
index 6c0194e..d0b2318 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -94,7 +94,7 @@ module.exports = {
'react/style-prop-object': 2,
'react/jsx-boolean-value': [2, 'always'],
- 'react/jsx-closing-bracket-location': [2, { 'selfClosing': 'after-props', 'nonEmpty': 'after-props' }],
+ 'react/jsx-closing-bracket-location': [2, 'tag-aligned'],
'react/jsx-curly-spacing': [2, 'never', { 'allowMultiline': true }],
'react/jsx-equals-spacing': [2, 'never'],
'react/jsx-filename-extension': [2, { 'extensions': ['.js'] }],
diff --git a/demo/src/components/App/components/Example0/Example0.js b/demo/src/components/App/components/Example0/Example0.js
index 851abf4..bbda170 100644
--- a/demo/src/components/App/components/Example0/Example0.js
+++ b/demo/src/components/App/components/Example0/Example0.js
@@ -31,7 +31,8 @@ function Example(props) {
id={exampleId}
items={[]}
inputProps={inputProps}
- theme={theme} />
+ theme={theme}
+ />
);
diff --git a/demo/src/components/App/components/Example1/Example1.js b/demo/src/components/App/components/Example1/Example1.js
index 08c0da5..2d3f4ce 100644
--- a/demo/src/components/App/components/Example1/Example1.js
+++ b/demo/src/components/App/components/Example1/Example1.js
@@ -50,7 +50,8 @@ function Example(props) {
items={items}
renderItem={renderItem}
inputProps={inputProps}
- theme={theme} />
+ theme={theme}
+ />
);
diff --git a/demo/src/components/App/components/Example10/Example10.js b/demo/src/components/App/components/Example10/Example10.js
index 7d96044..2854228 100644
--- a/demo/src/components/App/components/Example10/Example10.js
+++ b/demo/src/components/App/components/Example10/Example10.js
@@ -9,7 +9,7 @@ import SourceCodeLink from 'SourceCodeLink/SourceCodeLink';
const exampleId = '10';
const file = `demo/src/components/App/components/Example${exampleId}/Example${exampleId}.js`;
-function CustomInput(props) {
+const renderInputComponent = inputProps => {
const style = {
border: '0 solid green',
borderBottomWidth: '1px',
@@ -17,23 +17,19 @@ function CustomInput(props) {
};
return (
-
+
);
-}
+};
-function mapStateToProps(state) {
- return {
- value: state[exampleId].value
- };
-}
+const mapStateToProps = state => ({
+ value: state[exampleId].value
+});
-function mapDispatchToProps(dispatch) {
- return {
- onChange: event => dispatch(updateInputValue(exampleId, event.target.value))
- };
-}
+const mapDispatchToProps = dispatch => ({
+ onChange: event => dispatch(updateInputValue(exampleId, event.target.value))
+});
-function Example(props) {
+const Example = props => {
const { value, onChange } = props;
const inputProps = {
placeholder: 'Custom input',
@@ -45,14 +41,15 @@ function Example(props) {
);
-}
+};
Example.propTypes = {
value: PropTypes.string.isRequired,
diff --git a/demo/src/components/App/components/Example2/Example2.js b/demo/src/components/App/components/Example2/Example2.js
index 5dd58ea..6597b24 100644
--- a/demo/src/components/App/components/Example2/Example2.js
+++ b/demo/src/components/App/components/Example2/Example2.js
@@ -51,7 +51,8 @@ function Example(props) {
renderItem={renderItem}
inputProps={inputProps}
focusedItemIndex={2}
- theme={theme} />
+ theme={theme}
+ />
);
diff --git a/demo/src/components/App/components/Example3/Example3.js b/demo/src/components/App/components/Example3/Example3.js
index 67038ea..ea1399e 100644
--- a/demo/src/components/App/components/Example3/Example3.js
+++ b/demo/src/components/App/components/Example3/Example3.js
@@ -75,7 +75,8 @@ function Example(props) {
getSectionItems={getSectionItems}
renderItem={renderItem}
inputProps={inputProps}
- theme={theme} />
+ theme={theme}
+ />
);
diff --git a/demo/src/components/App/components/Example4/Example4.js b/demo/src/components/App/components/Example4/Example4.js
index 444982c..7de5de6 100644
--- a/demo/src/components/App/components/Example4/Example4.js
+++ b/demo/src/components/App/components/Example4/Example4.js
@@ -77,7 +77,8 @@ function Example(props) {
inputProps={inputProps}
focusedSectionIndex={0}
focusedItemIndex={1}
- theme={theme} />
+ theme={theme}
+ />
);
diff --git a/demo/src/components/App/components/Example5/Example5.js b/demo/src/components/App/components/Example5/Example5.js
index 1c9210a..592f7f7 100644
--- a/demo/src/components/App/components/Example5/Example5.js
+++ b/demo/src/components/App/components/Example5/Example5.js
@@ -68,7 +68,8 @@ function Example(props) {
itemProps={itemProps}
focusedSectionIndex={focusedSectionIndex}
focusedItemIndex={focusedItemIndex}
- theme={theme} />
+ theme={theme}
+ />
);
diff --git a/demo/src/components/App/components/Example6/Example6.js b/demo/src/components/App/components/Example6/Example6.js
index cfdd88b..847937a 100644
--- a/demo/src/components/App/components/Example6/Example6.js
+++ b/demo/src/components/App/components/Example6/Example6.js
@@ -63,7 +63,8 @@ function Example(props) {
inputProps={inputProps}
focusedSectionIndex={focusedSectionIndex}
focusedItemIndex={focusedItemIndex}
- theme={theme} />
+ theme={theme}
+ />
);
diff --git a/demo/src/components/App/components/Example7/Example7.js b/demo/src/components/App/components/Example7/Example7.js
index 64331a0..2e08b7e 100644
--- a/demo/src/components/App/components/Example7/Example7.js
+++ b/demo/src/components/App/components/Example7/Example7.js
@@ -87,7 +87,8 @@ function Example(props) {
inputProps={inputProps}
focusedSectionIndex={focusedSectionIndex}
focusedItemIndex={focusedItemIndex}
- theme={theme} />
+ theme={theme}
+ />
);
diff --git a/demo/src/components/App/components/Example8/Example8.js b/demo/src/components/App/components/Example8/Example8.js
index 3e3d4dd..0397b5c 100644
--- a/demo/src/components/App/components/Example8/Example8.js
+++ b/demo/src/components/App/components/Example8/Example8.js
@@ -96,7 +96,8 @@ function Example(props) {
inputProps={inputProps}
focusedSectionIndex={focusedSectionIndex}
focusedItemIndex={focusedItemIndex}
- theme={theme} />
+ theme={theme}
+ />
);
diff --git a/demo/src/components/App/components/Example9/Example9.js b/demo/src/components/App/components/Example9/Example9.js
index 6697308..2357e99 100644
--- a/demo/src/components/App/components/Example9/Example9.js
+++ b/demo/src/components/App/components/Example9/Example9.js
@@ -143,7 +143,8 @@ function Example(props) {
focusedSectionIndex={focusedSectionIndex}
focusedItemIndex={focusedItemIndex}
itemProps={itemProps}
- theme={theme} />
+ theme={theme}
+ />
);
diff --git a/demo/src/components/App/components/ForkMeOnGitHub/ForkMeOnGitHub.js b/demo/src/components/App/components/ForkMeOnGitHub/ForkMeOnGitHub.js
index ab54506..c29076a 100644
--- a/demo/src/components/App/components/ForkMeOnGitHub/ForkMeOnGitHub.js
+++ b/demo/src/components/App/components/ForkMeOnGitHub/ForkMeOnGitHub.js
@@ -11,7 +11,8 @@ export default function ForkMeOnGitHub(props) {
className={styles.image}
src="//camo.githubusercontent.com/a6677b08c955af8400f44c6298f40e7d19cc5b2d/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f677261795f3664366436642e706e67"
alt="Fork me on GitHub"
- data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_gray_6d6d6d.png" />
+ data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_gray_6d6d6d.png"
+ />
);
}
diff --git a/demo/src/components/App/components/SourceCodeLink/SourceCodeLink.js b/demo/src/components/App/components/SourceCodeLink/SourceCodeLink.js
index 4d98904..169bec9 100644
--- a/demo/src/components/App/components/SourceCodeLink/SourceCodeLink.js
+++ b/demo/src/components/App/components/SourceCodeLink/SourceCodeLink.js
@@ -10,7 +10,8 @@ export default function SourceCodeLink(props) {
className={styles.link}
href={`//github.com/moroshko/react-autowhatever/tree/master/${file}`}
target="_blank"
- rel="noopener noreferrer">
+ rel="noopener noreferrer"
+ >
Source code
);
diff --git a/demo/standalone/app.js b/demo/standalone/app.js
index 800e9b1..b52ee7a 100644
--- a/demo/standalone/app.js
+++ b/demo/standalone/app.js
@@ -42,7 +42,8 @@ class App extends React.Component { // eslint-disable-line no-undef
items={items}
renderItem={renderItem}
inputProps={inputProps}
- focusedItemIndex={2} />
+ focusedItemIndex={2}
+ />
);
}
}
diff --git a/demo/standalone/compiled.app.js b/demo/standalone/compiled.app.js
index c487ec9..91728f3 100644
--- a/demo/standalone/compiled.app.js
+++ b/demo/standalone/compiled.app.js
@@ -115,7 +115,8 @@
, { items: items,
renderItem: renderItem,
inputProps: inputProps,
- focusedItemIndex: 2 });
+ focusedItemIndex: 2
+ });
}
}]);
diff --git a/package.json b/package.json
index 5c753be..3ffdfeb 100644
--- a/package.json
+++ b/package.json
@@ -44,15 +44,15 @@
"babel-register": "^6.16.3",
"chai": "^3.5.0",
"css-loader": "^0.25.0",
- "eslint": "^3.7.1",
+ "eslint": "^3.8.1",
"eslint-plugin-react": "^6.4.1",
"extract-text-webpack-plugin": "^1.0.1",
- "jsdom": "^9.6.0",
+ "jsdom": "^9.8.0",
"less": "^2.7.1",
"less-loader": "^2.2.3",
"mocha": "^3.1.2",
"openurl": "^1.1.1",
- "postcss-loader": "^0.13.0",
+ "postcss-loader": "^1.0.0",
"react": "^15.3.2",
"react-addons-test-utils": "^15.3.2",
"react-dom": "^15.3.2",
diff --git a/src/Autowhatever.js b/src/Autowhatever.js
index 3fd1e7e..95dbf5a 100644
--- a/src/Autowhatever.js
+++ b/src/Autowhatever.js
@@ -6,6 +6,7 @@ import ItemsList from './ItemsList';
const alwaysTrue = () => true;
const emptyObject = {};
+const defaultRenderInputComponent = props => ;
const defaultRenderItemsContainer = props => ;
const defaultTheme = {
container: 'react-autowhatever__container',
@@ -23,6 +24,7 @@ export default class Autowhatever extends Component {
static propTypes = {
id: PropTypes.string, // Used in aria-* attributes. If multiple Autowhatever's are rendered on a page, they must have unique ids.
multiSection: PropTypes.bool, // Indicates whether a multi section layout should be rendered.
+ renderInputComponent: PropTypes.func, // Renders the input component.
items: PropTypes.array.isRequired, // Array of items or sections to render.
renderItemsContainer: PropTypes.func, // Renders the items container.
renderItem: PropTypes.func, // This function renders a single item.
@@ -47,6 +49,7 @@ export default class Autowhatever extends Component {
static defaultProps = {
id: '1',
multiSection: false,
+ renderInputComponent: defaultRenderInputComponent,
renderItemsContainer: defaultRenderItemsContainer,
shouldRenderSection: alwaysTrue,
renderItem: () => {
@@ -177,7 +180,8 @@ export default class Autowhatever extends Component {
section={section}
renderSectionTitle={renderSectionTitle}
theme={theme}
- sectionKeyPrefix={sectionKeyPrefix} />
+ sectionKeyPrefix={sectionKeyPrefix}
+ />
+ ref={this.storeItemsListReference}
+ />
);
/* eslint-enable react/jsx-key */
@@ -219,7 +224,8 @@ export default class Autowhatever extends Component {
onFocusedItemChange={this.onFocusedItemChange}
getItemId={this.getItemId}
theme={theme}
- keyPrefix={`react-autowhatever-${id}-`} />
+ keyPrefix={`react-autowhatever-${id}-`}
+ />
);
}
@@ -273,7 +279,7 @@ export default class Autowhatever extends Component {
render() {
const { theme } = this;
const {
- id, multiSection, renderItemsContainer,
+ id, multiSection, renderInputComponent, renderItemsContainer,
focusedSectionIndex, focusedItemIndex
} = this.props;
const renderedItems = multiSection ? this.renderSections() : this.renderItems();
@@ -285,7 +291,7 @@ export default class Autowhatever extends Component {
isOpen && 'containerOpen'
);
const itemsContainerId = `react-autowhatever-${id}`;
- const inputProps = {
+ const inputComponent = renderInputComponent({
type: 'text',
value: '',
autoComplete: 'off',
@@ -299,21 +305,17 @@ export default class Autowhatever extends Component {
...this.props.inputProps,
onKeyDown: this.props.inputProps.onKeyDown && this.onKeyDown,
ref: this.storeInputReference
- };
- const itemsContainerProps = {
+ });
+ const itemsContainer = renderItemsContainer({
id: itemsContainerId,
...theme(`react-autowhatever-${id}-items-container`, 'itemsContainer'),
- ref: this.storeItemsContainerReference
- };
- const InputComponent = this.props.inputComponent || 'input';
- const itemsContainer = renderItemsContainer({
- ...itemsContainerProps,
+ ref: this.storeItemsContainerReference,
children: renderedItems
});
return (
-
+ {inputComponent}
{itemsContainer}
);
diff --git a/src/ItemsList.js b/src/ItemsList.js
index 78d39c4..36760ae 100644
--- a/src/ItemsList.js
+++ b/src/ItemsList.js
@@ -71,7 +71,8 @@ export default class ItemsList extends Component {
itemIndex={itemIndex}
item={item}
renderItem={renderItem}
- renderItemData={renderItemData} />
+ renderItemData={renderItemData}
+ />
);
/* eslint-enable react/jsx-key */
})
diff --git a/test/input-component/Autowhatever.test.js b/test/input-component/Autowhatever.test.js
new file mode 100644
index 0000000..4811201
--- /dev/null
+++ b/test/input-component/Autowhatever.test.js
@@ -0,0 +1,15 @@
+import React from 'react';
+import TestUtils from 'react-addons-test-utils';
+import { expect } from 'chai';
+import { init, getStoredInput } from '../helpers';
+import AutowhateverApp from './AutowhateverApp';
+
+describe('Autowhatever with inputComponent', () => {
+ beforeEach(() => {
+ init(TestUtils.renderIntoDocument());
+ });
+
+ it('should store the input on the instance', () => {
+ expect(getStoredInput().getAttribute('id')).to.equal('my-custom-input');
+ });
+});
diff --git a/test/input-component/AutowhateverApp.js b/test/input-component/AutowhateverApp.js
new file mode 100644
index 0000000..89007dc
--- /dev/null
+++ b/test/input-component/AutowhateverApp.js
@@ -0,0 +1,61 @@
+import React, { Component } from 'react';
+import Autowhatever from '../../src/Autowhatever';
+import items from './items';
+
+export const renderItem = item => item.text;
+
+export const inputComponent = props => (
+
+
+
+);
+
+export default class AutowhateverApp extends Component {
+ constructor() {
+ super();
+
+ this.state = {
+ value: ''
+ };
+
+ this.storeAutowhateverReference = this.storeAutowhateverReference.bind(this);
+ this.onChange = this.onChange.bind(this);
+ }
+
+ storeAutowhateverReference(autowhatever) {
+ if (autowhatever !== null) {
+ this.autowhatever = autowhatever;
+ }
+ }
+
+ onChange(event) {
+ this.setState({
+ value: event.target.value
+ });
+ }
+
+ onClick(event, { itemIndex }) {
+ this.setState({
+ value: items[itemIndex].text
+ });
+ }
+
+ render() {
+ const { value } = this.state;
+ const inputProps = {
+ id: 'my-custom-input',
+ value,
+ onChange: this.onChange
+ };
+
+ return (
+
+ );
+ }
+}
diff --git a/test/input-component/items.js b/test/input-component/items.js
new file mode 100644
index 0000000..b74b3f7
--- /dev/null
+++ b/test/input-component/items.js
@@ -0,0 +1,17 @@
+export default [
+ {
+ text: 'Apple'
+ },
+ {
+ text: 'Banana'
+ },
+ {
+ text: 'Cherry'
+ },
+ {
+ text: 'Grapefruit'
+ },
+ {
+ text: 'Lemon'
+ }
+];
diff --git a/test/multi-section/AutowhateverApp.js b/test/multi-section/AutowhateverApp.js
index dcde974..d1f2a11 100644
--- a/test/multi-section/AutowhateverApp.js
+++ b/test/multi-section/AutowhateverApp.js
@@ -73,7 +73,8 @@ export default class AutowhateverApp extends Component {
inputProps={inputProps}
focusedSectionIndex={focusedSectionIndex}
focusedItemIndex={focusedItemIndex}
- ref={this.storeAutowhateverReference} />
+ ref={this.storeAutowhateverReference}
+ />
);
}
}
diff --git a/test/plain-list/AutowhateverApp.js b/test/plain-list/AutowhateverApp.js
index bfde38b..e1922b0 100644
--- a/test/plain-list/AutowhateverApp.js
+++ b/test/plain-list/AutowhateverApp.js
@@ -74,7 +74,8 @@ export default class AutowhateverApp extends Component {
inputProps={inputProps}
itemProps={itemProps}
focusedItemIndex={focusedItemIndex}
- ref={this.storeAutowhateverReference} />
+ ref={this.storeAutowhateverReference}
+ />
);
}
}