diff --git a/packages/react-instantsearch/src/core/Index.js b/packages/react-instantsearch/src/core/Index.js index 86390963b8..5f72f83717 100644 --- a/packages/react-instantsearch/src/core/Index.js +++ b/packages/react-instantsearch/src/core/Index.js @@ -9,6 +9,7 @@ import React, { Component, Children } from 'react'; * @kind widget * @name * @propType {string} indexName - index in which to search. + * @propType {{ Root: string|function, props: object }} [root] - Use this to customize the root element. Default value: `{ Root: 'div' }` * @example * import {InstantSearch, Index, SearchBox, Hits, Configure} from 'react-instantsearch/dom'; * diff --git a/packages/react-instantsearch/src/core/__snapshots__/createIndex.test.js.snap b/packages/react-instantsearch/src/core/__snapshots__/createIndex.test.js.snap index d1a3e3cd47..4bab98847e 100644 --- a/packages/react-instantsearch/src/core/__snapshots__/createIndex.test.js.snap +++ b/packages/react-instantsearch/src/core/__snapshots__/createIndex.test.js.snap @@ -1,11 +1,28 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`createIndex expect to create Index with a custom root props 1`] = ` + +`; + exports[`createIndex wraps Index 1`] = ` -Object { - "children": undefined, - "indexName": "name", - "root": Object { - "Root": "div", - }, -} + `; diff --git a/packages/react-instantsearch/src/core/__snapshots__/createInstantSearch.test.js.snap b/packages/react-instantsearch/src/core/__snapshots__/createInstantSearch.test.js.snap index b43abba244..4337635c83 100644 --- a/packages/react-instantsearch/src/core/__snapshots__/createInstantSearch.test.js.snap +++ b/packages/react-instantsearch/src/core/__snapshots__/createInstantSearch.test.js.snap @@ -1,5 +1,28 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`createInstantSearch expect to create InstantSearch with a custom root props 1`] = ` +Object { + "children": undefined, + "createURL": undefined, + "indexName": "name", + "onSearchParameters": undefined, + "onSearchStateChange": undefined, + "refresh": false, + "resultsState": undefined, + "root": Object { + "Root": "span", + "props": Object { + "style": Object { + "flex": 1, + }, + }, + }, + "searchParameters": undefined, + "searchState": undefined, + "stalledSearchDelay": 200, +} +`; + exports[`createInstantSearch wraps InstantSearch 1`] = ` Object { "children": undefined, diff --git a/packages/react-instantsearch/src/core/createIndex.js b/packages/react-instantsearch/src/core/createIndex.js index abb816ca94..5a559d7e81 100644 --- a/packages/react-instantsearch/src/core/createIndex.js +++ b/packages/react-instantsearch/src/core/createIndex.js @@ -1,29 +1,34 @@ +import React from 'react'; import PropTypes from 'prop-types'; -import React, { Component } from 'react'; import Index from './Index'; /** * Creates a specialized root Index component. It accepts * a specification of the root Element. - * @param {object} root - the defininition of the root of an Index sub tree. - * @returns {object} a Index root + * @param {object} defaultRoot - the defininition of the root of an Index sub tree. + * @return {object} a Index root */ -export default function createIndex(root) { - return class CreateIndex extends Component { - static propTypes = { - children: PropTypes.oneOfType([ - PropTypes.arrayOf(PropTypes.node), - PropTypes.node, - ]), - indexName: PropTypes.string.isRequired, - }; +const createIndex = defaultRoot => { + const CreateIndex = ({ indexName, root, children }) => ( + + {children} + + ); - render() { - return ( - - {this.props.children} - - ); - } + CreateIndex.propTypes = { + indexName: PropTypes.string.isRequired, + root: PropTypes.shape({ + Root: PropTypes.oneOfType([PropTypes.string, PropTypes.func]).isRequired, + props: PropTypes.object, + }), + children: PropTypes.node, }; -} + + CreateIndex.defaultProps = { + root: defaultRoot, + }; + + return CreateIndex; +}; + +export default createIndex; diff --git a/packages/react-instantsearch/src/core/createIndex.test.js b/packages/react-instantsearch/src/core/createIndex.test.js index f15ae9523c..40dccd7cd4 100644 --- a/packages/react-instantsearch/src/core/createIndex.test.js +++ b/packages/react-instantsearch/src/core/createIndex.test.js @@ -1,19 +1,34 @@ -/* eslint-env jest, jasmine */ -/* eslint-disable no-console */ import React from 'react'; import Enzyme, { shallow } from 'enzyme'; import Adapter from 'enzyme-adapter-react-16'; -Enzyme.configure({ adapter: new Adapter() }); - import createIndex from './createIndex'; import Index from './Index'; +Enzyme.configure({ adapter: new Adapter() }); + describe('createIndex', () => { const CustomIndex = createIndex({ Root: 'div' }); it('wraps Index', () => { const wrapper = shallow(); expect(wrapper.is(Index)).toBe(true); - expect(wrapper.props()).toMatchSnapshot(); + expect(wrapper).toMatchSnapshot(); + }); + + it('expect to create Index with a custom root props', () => { + const root = { + Root: 'span', + props: { + style: { + flex: 1, + }, + }, + }; + + const wrapper = shallow(); + + expect(wrapper.is(Index)).toBe(true); + expect(wrapper.props().root).toEqual(root); + expect(wrapper).toMatchSnapshot(); }); }); diff --git a/packages/react-instantsearch/src/core/createInstantSearch.test.js b/packages/react-instantsearch/src/core/createInstantSearch.test.js index b75a98f63e..cf27b14353 100644 --- a/packages/react-instantsearch/src/core/createInstantSearch.test.js +++ b/packages/react-instantsearch/src/core/createInstantSearch.test.js @@ -10,11 +10,9 @@ Enzyme.configure({ adapter: new Adapter() }); describe('createInstantSearch', () => { const algoliaClient = { addAlgoliaAgent: jest.fn() }; const algoliaClientFactory = jest.fn(() => algoliaClient); - const createCustomInstantSearch = root => - createInstantSearch(algoliaClientFactory, { - Root: 'div', - ...root, - }); + const CustomInstantSearch = createInstantSearch(algoliaClientFactory, { + Root: 'div', + }); beforeEach(() => { algoliaClient.addAlgoliaAgent.mockClear(); @@ -22,8 +20,6 @@ describe('createInstantSearch', () => { }); it('wraps InstantSearch', () => { - const CustomInstantSearch = createCustomInstantSearch(); - const wrapper = shallow( ); @@ -37,8 +33,6 @@ describe('createInstantSearch', () => { }); it('creates an algolia client using the provided factory', () => { - const CustomInstantSearch = createCustomInstantSearch(); - shallow(); expect(algoliaClientFactory).toHaveBeenCalledTimes(1); @@ -50,8 +44,6 @@ describe('createInstantSearch', () => { }); it('updates the algoliaClient when appId or apiKey changes', () => { - const CustomInstantSearch = createCustomInstantSearch(); - const wrapper = shallow( ); @@ -65,8 +57,6 @@ describe('createInstantSearch', () => { }); it('uses the provided algoliaClient', () => { - const CustomInstantSearch = createCustomInstantSearch(); - const wrapper = shallow( ); @@ -77,7 +67,6 @@ describe('createInstantSearch', () => { }); it('updates the algoliaClient when provided algoliaClient is passed down', () => { - const CustomInstantSearch = createCustomInstantSearch(); const newAlgoliaClient = { addAlgoliaAgent: jest.fn(), }; @@ -97,28 +86,23 @@ describe('createInstantSearch', () => { }); it('expect to create InstantSearch with a custom root props', () => { - const CustomInstantSearch = createCustomInstantSearch({ + const root = { Root: 'span', props: { style: { flex: 1, }, }, - }); + }; const wrapper = shallow( - + ); - expect(algoliaClient.addAlgoliaAgent).toHaveBeenCalledTimes(1); + // eslint-disable-next-line no-shadow, no-unused-vars + const { algoliaClient, ...propsWithoutClient } = wrapper.props(); - expect(wrapper.props().root).toEqual({ - Root: 'span', - props: { - style: { - flex: 1, - }, - }, - }); + expect(wrapper.props().root).toEqual(root); + expect(propsWithoutClient).toMatchSnapshot(); }); }); diff --git a/stories/MultiIndex.stories.js b/stories/MultiIndex.stories.js index e7a79d0554..9c05c6d18a 100644 --- a/stories/MultiIndex.stories.js +++ b/stories/MultiIndex.stories.js @@ -16,6 +16,7 @@ import { connectStateResults, } from '../packages/react-instantsearch/connectors'; import Autosuggest from 'react-autosuggest'; +import { displayName, filterProps } from './util'; const stories = storiesOf('', module); @@ -166,7 +167,36 @@ stories - )); + )) + .addWithJSX( + 'with custom root', + () => ( + + + + + + + ), + { + displayName, + filterProps, + } + ); const AutoComplete = connectAutoComplete( ({ hits, currentRefinement, refine }) => (