From 7e7809c247f5298482172a15b9e40d95e1397833 Mon Sep 17 00:00:00 2001 From: Vaillant Samuel Date: Thu, 29 Aug 2019 09:29:13 +0200 Subject: [PATCH 01/10] chore(eslint): allow instant_search --- .eslintrc.js | 4 ++++ stories/instantsearch.stories.js | 1 - 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.eslintrc.js b/.eslintrc.js index b49e1e84e6..aa38d7fea3 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -10,6 +10,10 @@ module.exports = { 'error', { argsIgnorePattern: '^_', ignoreRestSiblings: true }, ], + '@typescript-eslint/camelcase': [ + 'error', + { allow: ['instant_search', 'instant_search_movies'] }, + ], }, overrides: [ { diff --git a/stories/instantsearch.stories.js b/stories/instantsearch.stories.js index f9250c046c..2d83b388af 100644 --- a/stories/instantsearch.stories.js +++ b/stories/instantsearch.stories.js @@ -20,7 +20,6 @@ storiesOf('InstantSearch', module) 'with initialUiState', withHits(() => {}, { initialUiState: { - // eslint-disable-next-line @typescript-eslint/camelcase instant_search: { refinementList: { brand: ['Apple'], From f221c220efa3b3ecf52d35c2610216c1a15f402f Mon Sep 17 00:00:00 2001 From: Vaillant Samuel Date: Wed, 28 Aug 2019 17:28:53 +0200 Subject: [PATCH 02/10] feat: drop support for searchParameters --- src/lib/InstantSearch.ts | 12 ----- src/lib/__tests__/InstantSearch-test.js | 65 ++--------------------- src/widgets/index/__tests__/index-test.ts | 51 ------------------ src/widgets/index/index.ts | 8 +-- test/mock/createInstantSearch.ts | 1 - 5 files changed, 6 insertions(+), 131 deletions(-) diff --git a/src/lib/InstantSearch.ts b/src/lib/InstantSearch.ts index 0a9afacdea..aa08c65fa4 100644 --- a/src/lib/InstantSearch.ts +++ b/src/lib/InstantSearch.ts @@ -95,12 +95,6 @@ export type InstantSearchOptions = { */ searchFunction?: (helper: AlgoliaSearchHelper) => void; - /** - * Additional parameters to unconditionally pass to the Algolia API. See also - * the `configure` widget for dynamically passing search parameters. - */ - searchParameters?: PlainSearchParameters; - /** * Injects a `uiState` to the `instantsearch` instance. You can use this option * to provide an initial state to a widget. Note that the state is only used @@ -144,7 +138,6 @@ class InstantSearch extends EventEmitter { public _stalledSearchDelay: number; public _searchStalledTimer: any; public _isSearchStalled: boolean; - public _searchParameters: PlainSearchParameters; public _initialUiState: UiState; public _searchFunction?: InstantSearchOptions['searchFunction']; public _createURL?: (params: SearchParameters) => string; @@ -158,7 +151,6 @@ class InstantSearch extends EventEmitter { const { indexName = null, numberLocale, - searchParameters = {}, initialUiState = {}, routing = null, searchFunction, @@ -226,10 +218,6 @@ See: https://www.algolia.com/doc/guides/building-search-ui/going-further/backend this._searchStalledTimer = null; this._isSearchStalled = false; this._initialUiState = initialUiState; - this._searchParameters = { - ...searchParameters, - index: indexName, - }; if (searchFunction) { this._searchFunction = searchFunction; diff --git a/src/lib/__tests__/InstantSearch-test.js b/src/lib/__tests__/InstantSearch-test.js index 0532ede34c..1cc14c60f3 100644 --- a/src/lib/__tests__/InstantSearch-test.js +++ b/src/lib/__tests__/InstantSearch-test.js @@ -235,37 +235,6 @@ describe('InstantSearch', () => { expect(search.insightsClient).toBe(insightsClient); }); - - // https://github.com/algolia/instantsearch.js/pull/1148 - it('does not mutate the provided `searchParameters`', () => { - const disjunctiveFacetsRefinements = { fruits: ['apple'] }; - const facetsRefinements = disjunctiveFacetsRefinements; - - const search = new InstantSearch({ - indexName: 'indexName', - searchClient: createSearchClient(), - searchParameters: { - disjunctiveFacetsRefinements, - facetsRefinements, - }, - }); - - search.addWidget( - createWidget({ - getConfiguration: () => ({ - disjunctiveFacetsRefinements: { - fruits: ['orange'], - }, - }), - }) - ); - - search.start(); - - expect(search.mainIndex.getHelper().state.facetsRefinements).toEqual({ - fruits: ['apple'], - }); - }); }); describe('addWidget(s)', () => { @@ -392,12 +361,11 @@ describe('start', () => { indexName: 'indexName', searchClient, searchFunction(helper) { - helper.addDisjunctiveFacetRefinement('brand', 'Apple'); - helper.search(); - }, - searchParameters: { - disjunctiveFacetsRefinements: { brand: ['Apple'] }, - disjunctiveFacets: ['brand'], + const nextState = helper.state + .addDisjunctiveFacet('brand') + .addDisjunctiveFacetRefinement('brand', 'Apple'); + + helper.setState(nextState).search(); }, }); @@ -406,29 +374,6 @@ describe('start', () => { }).not.toThrow(); }); - it('forwards the `searchParameters` to the main index', () => { - const search = new InstantSearch({ - indexName: 'indexName', - searchClient: createSearchClient(), - searchParameters: { - hitsPerPage: 5, - disjunctiveFacetsRefinements: { brand: ['Apple'] }, - disjunctiveFacets: ['brand'], - }, - }); - - search.start(); - - expect(search.mainIndex.getHelper().state).toEqual( - algoliasearchHelper.SearchParameters.make({ - index: 'indexName', - hitsPerPage: 5, - disjunctiveFacetsRefinements: { brand: ['Apple'] }, - disjunctiveFacets: ['brand'], - }) - ); - }); - it('forwards the `initialUiState` to the main index', () => { const search = new InstantSearch({ indexName: 'indexName', diff --git a/src/widgets/index/__tests__/index-test.ts b/src/widgets/index/__tests__/index-test.ts index fef7d38a54..30d0f533ad 100644 --- a/src/widgets/index/__tests__/index-test.ts +++ b/src/widgets/index/__tests__/index-test.ts @@ -595,57 +595,6 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/index/js/" ); }); - it('uses `searchParameters` for the top level index', () => { - const instance = index({ indexName: 'indexName' }); - const instantSearchInstance = createInstantSearch({ - _searchParameters: { - hitsPerPage: 5, - disjunctiveFacetsRefinements: { brand: ['Apple'] }, - disjunctiveFacets: ['brand'], - }, - }); - - instance.init( - createInitOptions({ - instantSearchInstance, - }) - ); - - expect(instance.getHelper()!.state).toEqual( - new SearchParameters({ - index: 'indexName', - hitsPerPage: 5, - disjunctiveFacetsRefinements: { brand: ['Apple'] }, - disjunctiveFacets: ['brand'], - }) - ); - }); - - it('does not use `searchParameters` for sub level indices ', () => { - const topLevelInstance = index({ indexName: 'topLevelIndexName' }); - const subLevelInstance = index({ indexName: 'subLevelIndexName' }); - const instantSearchInstance = createInstantSearch({ - _searchParameters: { - hitsPerPage: 5, - disjunctiveFacetsRefinements: { brand: ['Apple'] }, - disjunctiveFacets: ['brand'], - }, - }); - - subLevelInstance.init( - createInitOptions({ - instantSearchInstance, - parent: topLevelInstance, - }) - ); - - expect(subLevelInstance.getHelper()!.state).toEqual( - new SearchParameters({ - index: 'subLevelIndexName', - }) - ); - }); - it('uses the internal state for the queries', () => { const instance = index({ indexName: 'indexName' }); const searchClient = createSearchClient(); diff --git a/src/widgets/index/index.ts b/src/widgets/index/index.ts index 0f0b31536e..3da0da9721 100644 --- a/src/widgets/index/index.ts +++ b/src/widgets/index/index.ts @@ -287,12 +287,6 @@ const index = (props: IndexProps): Index => { // step. const mainHelper = instantSearchInstance.mainHelper!; - const initialSearchParameters = new algoliasearchHelper.SearchParameters( - // Uses the `searchParameters` for the top level index only, it allows - // us to have the exact same behaviour than before for the mono-index. - parent === null ? instantSearchInstance._searchParameters : {} - ); - // This Helper is only used for state management we do not care about the // `searchClient`. Only the "main" Helper created at the `InstantSearch` // level is aware of the client. @@ -301,7 +295,7 @@ const index = (props: IndexProps): Index => { indexName, getLocalWidgetsSearchParameters(localWidgets, { uiState: localUiState, - initialSearchParameters, + initialSearchParameters: new algoliasearchHelper.SearchParameters(), }) ); diff --git a/test/mock/createInstantSearch.ts b/test/mock/createInstantSearch.ts index d8a97e2e5f..4651f1adc0 100644 --- a/test/mock/createInstantSearch.ts +++ b/test/mock/createInstantSearch.ts @@ -36,7 +36,6 @@ export const createInstantSearch = ( _isSearchStalled: true, _stalledSearchDelay: 200, _searchStalledTimer: null, - _searchParameters: {}, _initialUiState: {}, _createURL: jest.fn(() => '#'), _createAbsoluteURL: jest.fn(() => '#'), From 7131e6b72e7b4a19b4f0c2c3cef50876463c7d2f Mon Sep 17 00:00:00 2001 From: Vaillant Samuel Date: Wed, 28 Aug 2019 17:53:07 +0200 Subject: [PATCH 03/10] refactor(stories): use configure vs searchParameters --- .storybook/decorators/withHits.ts | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/.storybook/decorators/withHits.ts b/.storybook/decorators/withHits.ts index f0d1dc4c41..eae7884b75 100644 --- a/.storybook/decorators/withHits.ts +++ b/.storybook/decorators/withHits.ts @@ -19,7 +19,6 @@ export const withHits = ( appId = 'latency', apiKey = '6be0576ff61c053d5f9a3225e2a90f76', indexName = 'instant_search', - searchParameters = {}, playground = defaultPlayground, ...instantsearchOptions } = searchOptions || {}; @@ -28,12 +27,6 @@ export const withHits = ( const search = instantsearch({ indexName, searchClient: algoliasearch(appId, apiKey), - searchParameters: { - hitsPerPage: 4, - attributesToSnippet: ['description:15'], - snippetEllipsisText: '[…]', - ...searchParameters, - }, routing: { router: { write: (routeState: object) => { @@ -67,6 +60,14 @@ export const withHits = ( rightPanelPlaygroundElement.classList.add('panel-right'); playgroundElement.appendChild(rightPanelPlaygroundElement); + search.addWidget( + instantsearch.widgets.configure({ + hitsPerPage: 4, + attributesToSnippet: ['description:15'], + snippetEllipsisText: '[…]', + }) + ); + playground({ search, leftPanel: leftPanelPlaygroundElement, From 74a5278d1e7eebc58c43b6e2e247fabff0bed660 Mon Sep 17 00:00:00 2001 From: Vaillant Samuel Date: Wed, 28 Aug 2019 17:54:50 +0200 Subject: [PATCH 04/10] refactor(stories): use initialUiState vs searchParameters in breadcrumb --- stories/breadcrumb.stories.js | 160 ++++++++++++++++++++-------------- 1 file changed, 96 insertions(+), 64 deletions(-) diff --git a/stories/breadcrumb.stories.js b/stories/breadcrumb.stories.js index ad02ea5568..473a579fa3 100644 --- a/stories/breadcrumb.stories.js +++ b/stories/breadcrumb.stories.js @@ -1,5 +1,17 @@ import { storiesOf } from '@storybook/html'; import { withHits, withLifecycle } from '../.storybook/decorators'; +import { connectHierarchicalMenu } from '../src/connectors'; +import { noop } from '../src/lib/utils'; + +const virtualHierarchicalMenu = (args = {}) => + connectHierarchicalMenu(noop, noop)({ + attributes: [ + 'hierarchicalCategories.lvl0', + 'hierarchicalCategories.lvl1', + 'hierarchicalCategories.lvl2', + ], + ...args, + }); storiesOf('Breadcrumb', module) .add( @@ -9,7 +21,9 @@ storiesOf('Breadcrumb', module) const breadcrumb = document.createElement('div'); container.appendChild(breadcrumb); - search.addWidget( + search.addWidgets([ + virtualHierarchicalMenu(), + instantsearch.widgets.breadcrumb({ container: breadcrumb, attributes: [ @@ -17,15 +31,17 @@ storiesOf('Breadcrumb', module) 'hierarchicalCategories.lvl1', 'hierarchicalCategories.lvl2', ], - }) - ); + }), + ]); }, { - searchParameters: { - hierarchicalFacetsRefinements: { - 'hierarchicalCategories.lvl0': [ - 'Cameras & Camcorders > Digital Cameras', - ], + initialUiState: { + instant_search: { + hierarchicalMenu: { + 'hierarchicalCategories.lvl0': [ + 'Cameras & Camcorders > Digital Cameras', + ], + }, }, }, } @@ -38,26 +54,30 @@ storiesOf('Breadcrumb', module) const breadcrumb = document.createElement('div'); container.appendChild(breadcrumb); - search.addWidget( + search.addWidgets([ + virtualHierarchicalMenu(), + instantsearch.widgets.breadcrumb({ container: breadcrumb, - templates: { - separator: ' + ', - }, attributes: [ 'hierarchicalCategories.lvl0', 'hierarchicalCategories.lvl1', 'hierarchicalCategories.lvl2', ], - }) - ); + templates: { + separator: ' + ', + }, + }), + ]); }, { - searchParameters: { - hierarchicalFacetsRefinements: { - 'hierarchicalCategories.lvl0': [ - 'Cameras & Camcorders > Digital Cameras', - ], + initialUiState: { + instant_search: { + hierarchicalMenu: { + 'hierarchicalCategories.lvl0': [ + 'Cameras & Camcorders > Digital Cameras', + ], + }, }, }, } @@ -70,7 +90,9 @@ storiesOf('Breadcrumb', module) const breadcrumb = document.createElement('div'); container.appendChild(breadcrumb); - search.addWidget( + search.addWidgets([ + virtualHierarchicalMenu(), + instantsearch.widgets.breadcrumb({ container: breadcrumb, attributes: [ @@ -81,15 +103,17 @@ storiesOf('Breadcrumb', module) templates: { home: 'Home Page', }, - }) - ); + }), + ]); }, { - searchParameters: { - hierarchicalFacetsRefinements: { - 'hierarchicalCategories.lvl0': [ - 'Cameras & Camcorders > Digital Cameras', - ], + initialUiState: { + instant_search: { + hierarchicalMenu: { + 'hierarchicalCategories.lvl0': [ + 'Cameras & Camcorders > Digital Cameras', + ], + }, }, }, } @@ -100,11 +124,12 @@ storiesOf('Breadcrumb', module) withHits( ({ search, container, instantsearch }) => { const breadcrumb = document.createElement('div'); - container.appendChild(breadcrumb); const hierarchicalMenu = document.createElement('div'); + + container.appendChild(breadcrumb); container.appendChild(hierarchicalMenu); - search.addWidget( + search.addWidgets([ instantsearch.widgets.breadcrumb({ container: breadcrumb, attributes: [ @@ -113,12 +138,9 @@ storiesOf('Breadcrumb', module) 'hierarchicalCategories.lvl2', ], rootPath: 'Cameras & Camcorders', - }) - ); + }), - search.addWidget( instantsearch.widgets.hierarchicalMenu({ - showParentLevel: false, container: hierarchicalMenu, attributes: [ 'hierarchicalCategories.lvl0', @@ -126,15 +148,17 @@ storiesOf('Breadcrumb', module) 'hierarchicalCategories.lvl2', ], rootPath: 'Cameras & Camcorders', - }) - ); + }), + ]); }, { - searchParameters: { - hierarchicalFacetsRefinements: { - 'hierarchicalCategories.lvl0': [ - 'Cameras & Camcorders > Digital Cameras', - ], + initialUiState: { + instant_search: { + hierarchicalMenu: { + 'hierarchicalCategories.lvl0': [ + 'Cameras & Camcorders > Digital Cameras', + ], + }, }, }, } @@ -149,7 +173,7 @@ storiesOf('Breadcrumb', module) const hierarchicalMenu = document.createElement('div'); container.appendChild(hierarchicalMenu); - search.addWidget( + search.addWidgets([ instantsearch.widgets.breadcrumb({ container: breadcrumb, attributes: [ @@ -157,10 +181,8 @@ storiesOf('Breadcrumb', module) 'hierarchicalCategories.lvl1', 'hierarchicalCategories.lvl2', ], - }) - ); + }), - search.addWidget( instantsearch.widgets.hierarchicalMenu({ container: hierarchicalMenu, attributes: [ @@ -168,15 +190,17 @@ storiesOf('Breadcrumb', module) 'hierarchicalCategories.lvl1', 'hierarchicalCategories.lvl2', ], - }) - ); + }), + ]); }, { - searchParameters: { - hierarchicalFacetsRefinements: { - 'hierarchicalCategories.lvl0': [ - 'Cameras & Camcorders > Digital Cameras', - ], + initialUiState: { + instant_search: { + hierarchicalMenu: { + 'hierarchicalCategories.lvl0': [ + 'Cameras & Camcorders > Digital Cameras', + ], + }, }, }, } @@ -189,7 +213,9 @@ storiesOf('Breadcrumb', module) const breadcrumb = document.createElement('div'); container.appendChild(breadcrumb); - search.addWidget( + search.addWidgets([ + virtualHierarchicalMenu(), + instantsearch.widgets.breadcrumb({ container: breadcrumb, attributes: [ @@ -202,15 +228,17 @@ storiesOf('Breadcrumb', module) ...item, label: `${item.label} (transformed)`, })), - }) - ); + }), + ]); }, { - searchParameters: { - hierarchicalFacetsRefinements: { - 'hierarchicalCategories.lvl0': [ - 'Cameras & Camcorders > Digital Cameras', - ], + initialUiState: { + instant_search: { + hierarchicalMenu: { + 'hierarchicalCategories.lvl0': [ + 'Cameras & Camcorders > Digital Cameras', + ], + }, }, }, } @@ -220,6 +248,8 @@ storiesOf('Breadcrumb', module) 'with add/remove', withHits( ({ search, container, instantsearch }) => { + search.addWidgets([virtualHierarchicalMenu()]); + withLifecycle(search, container, node => instantsearch.widgets.breadcrumb({ container: node, @@ -232,11 +262,13 @@ storiesOf('Breadcrumb', module) ); }, { - searchParameters: { - hierarchicalFacetsRefinements: { - 'hierarchicalCategories.lvl0': [ - 'Cameras & Camcorders > Digital Cameras', - ], + initialUiState: { + instant_search: { + hierarchicalMenu: { + 'hierarchicalCategories.lvl0': [ + 'Cameras & Camcorders > Digital Cameras', + ], + }, }, }, } From 04842b78a738504c579a4c8620e4b226cd790577 Mon Sep 17 00:00:00 2001 From: Vaillant Samuel Date: Wed, 28 Aug 2019 18:07:09 +0200 Subject: [PATCH 05/10] refactor(stories): use initialUiState vs searchParameters in clearRefinements --- stories/clear-refinements.stories.js | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/stories/clear-refinements.stories.js b/stories/clear-refinements.stories.js index f71a983e04..ae4b0e26ed 100644 --- a/stories/clear-refinements.stories.js +++ b/stories/clear-refinements.stories.js @@ -13,9 +13,12 @@ storiesOf('ClearRefinements', module) ); }, { - searchParameters: { - disjunctiveFacetsRefinements: { brand: ['Apple'] }, - disjunctiveFacets: ['brand'], + initialUiState: { + instant_search: { + refinementList: { + brand: ['Apple'], + }, + }, }, } ) @@ -49,9 +52,12 @@ storiesOf('ClearRefinements', module) ); }, { - searchParameters: { - disjunctiveFacetsRefinements: { brand: ['Apple'] }, - disjunctiveFacets: ['brand'], + initialUiState: { + instant_search: { + refinementList: { + brand: ['Apple'], + }, + }, }, } ) @@ -73,9 +79,12 @@ storiesOf('ClearRefinements', module) ); }, { - searchParameters: { - disjunctiveFacetsRefinements: { brand: ['Apple'] }, - disjunctiveFacets: ['brand'], + initialUiState: { + instant_search: { + refinementList: { + brand: ['Apple'], + }, + }, }, } ) From f827d129215e7b372daf86ec5df58b312edc9d0b Mon Sep 17 00:00:00 2001 From: Vaillant Samuel Date: Wed, 28 Aug 2019 18:29:32 +0200 Subject: [PATCH 06/10] refactor(stories): use initialUiState vs searchParameters in currentRefinements --- stories/current-refinements.stories.js | 457 ++++++++++++++----------- 1 file changed, 252 insertions(+), 205 deletions(-) diff --git a/stories/current-refinements.stories.js b/stories/current-refinements.stories.js index dec6914bc9..ead3ce847b 100644 --- a/stories/current-refinements.stories.js +++ b/stories/current-refinements.stories.js @@ -4,113 +4,127 @@ import { withHits } from '../.storybook/decorators'; storiesOf('CurrentRefinements', module) .add( 'default', - withHits(({ search, container, instantsearch }) => { - const currentRefinementsContainer = document.createElement('div'); - container.appendChild(currentRefinementsContainer); + withHits( + ({ search, container, instantsearch }) => { + const currentRefinementsContainer = document.createElement('div'); + container.appendChild(currentRefinementsContainer); - search.addWidget( - instantsearch.widgets.configure({ - disjunctiveFacetsRefinements: { brand: ['Apple', 'Samsung'] }, - disjunctiveFacets: ['brand'], - numericRefinements: { price: { '>=': [100] } }, - }) - ); - - search.addWidget( - instantsearch.widgets.currentRefinements({ - container: currentRefinementsContainer, - }) - ); - }) + search.addWidget( + instantsearch.widgets.currentRefinements({ + container: currentRefinementsContainer, + }) + ); + }, + { + initialUiState: { + instant_search: { + refinementList: { + brand: ['Apple', 'Samsung'], + }, + numericMenu: { + price: '100:', + }, + }, + }, + } + ) ) .add( 'with refinementList', - withHits(({ search, container, instantsearch }) => { - const currentRefinementsContainer = document.createElement('div'); - container.appendChild(currentRefinementsContainer); + withHits( + ({ search, container, instantsearch }) => { + const currentRefinementsContainer = document.createElement('div'); + container.appendChild(currentRefinementsContainer); - search.addWidget( - instantsearch.widgets.configure({ - disjunctiveFacetsRefinements: { - brand: ['Google', 'Apple', 'Samsung'], + search.addWidget( + instantsearch.widgets.currentRefinements({ + container: currentRefinementsContainer, + }) + ); + }, + { + initialUiState: { + instant_search: { + refinementList: { + brand: ['Google', 'Apple', 'Samsung'], + }, }, - disjunctiveFacets: ['brand'], - }) - ); - - search.addWidget( - instantsearch.widgets.currentRefinements({ - container: currentRefinementsContainer, - }) - ); - }) + }, + } + ) ) .add( 'with menu', - withHits(({ search, container, instantsearch }) => { - const currentRefinementsContainer = document.createElement('div'); - currentRefinementsContainer.style.marginBottom = '10px'; - container.appendChild(currentRefinementsContainer); - const menuContainer = document.createElement('div'); - container.appendChild(menuContainer); - - search.addWidget( - instantsearch.widgets.configure({ - hierarchicalFacetsRefinements: { - categories: ['Audio'], - }, - }) - ); + withHits( + ({ search, container, instantsearch }) => { + const currentRefinementsContainer = document.createElement('div'); + currentRefinementsContainer.style.marginBottom = '10px'; + container.appendChild(currentRefinementsContainer); + const menuContainer = document.createElement('div'); + container.appendChild(menuContainer); - search.addWidget( - instantsearch.widgets.menu({ - container: menuContainer, - attribute: 'categories', - }) - ); + search.addWidget( + instantsearch.widgets.menu({ + container: menuContainer, + attribute: 'categories', + }) + ); - search.addWidget( - instantsearch.widgets.currentRefinements({ - container: currentRefinementsContainer, - }) - ); - }) + search.addWidget( + instantsearch.widgets.currentRefinements({ + container: currentRefinementsContainer, + }) + ); + }, + { + initialUiState: { + instant_search: { + menu: { + categories: 'Audio', + }, + }, + }, + } + ) ) .add( 'with hierarchicalMenu', - withHits(({ search, container, instantsearch }) => { - const currentRefinementsContainer = document.createElement('div'); - currentRefinementsContainer.style.marginBottom = '10px'; - container.appendChild(currentRefinementsContainer); - const hierarchicalMenuContainer = document.createElement('div'); - container.appendChild(hierarchicalMenuContainer); + withHits( + ({ search, container, instantsearch }) => { + const currentRefinementsContainer = document.createElement('div'); + currentRefinementsContainer.style.marginBottom = '10px'; + container.appendChild(currentRefinementsContainer); + const hierarchicalMenuContainer = document.createElement('div'); + container.appendChild(hierarchicalMenuContainer); - search.addWidget( - instantsearch.widgets.configure({ - hierarchicalFacetsRefinements: { - 'hierarchicalCategories.lvl0': [ - 'Cameras & Camcorders > Digital Cameras', + search.addWidget( + instantsearch.widgets.hierarchicalMenu({ + container: hierarchicalMenuContainer, + attributes: [ + 'hierarchicalCategories.lvl0', + 'hierarchicalCategories.lvl1', ], - }, - }) - ); - - search.addWidget( - instantsearch.widgets.hierarchicalMenu({ - container: hierarchicalMenuContainer, - attributes: [ - 'hierarchicalCategories.lvl0', - 'hierarchicalCategories.lvl1', - ], - }) - ); + }) + ); - search.addWidget( - instantsearch.widgets.currentRefinements({ - container: currentRefinementsContainer, - }) - ); - }) + search.addWidget( + instantsearch.widgets.currentRefinements({ + container: currentRefinementsContainer, + }) + ); + }, + { + initialUiState: { + instant_search: { + hierarchicalMenu: { + 'hierarchicalCategories.lvl0': [ + 'Cameras & Camcorders > Digital Cameras', + ], + }, + }, + }, + } + ) ) .add( 'with toggleRefinement', @@ -140,144 +154,177 @@ storiesOf('CurrentRefinements', module) ) .add( 'with numericMenu', - withHits(({ search, container, instantsearch }) => { - const currentRefinementsContainer = document.createElement('div'); - container.appendChild(currentRefinementsContainer); - - search.addWidget( - instantsearch.widgets.configure({ - numericRefinements: { price: { '<=': [10] } }, - }) - ); + withHits( + ({ search, container, instantsearch }) => { + const currentRefinementsContainer = document.createElement('div'); + container.appendChild(currentRefinementsContainer); - search.addWidget( - instantsearch.widgets.currentRefinements({ - container: currentRefinementsContainer, - }) - ); - }) + search.addWidget( + instantsearch.widgets.currentRefinements({ + container: currentRefinementsContainer, + }) + ); + }, + { + initialUiState: { + instant_search: { + numericMenu: { + price: ':10', + }, + }, + }, + } + ) ) .add( 'with rangeInput', - withHits(({ search, container, instantsearch }) => { - const currentRefinementsContainer = document.createElement('div'); - currentRefinementsContainer.style.marginBottom = '10px'; - container.appendChild(currentRefinementsContainer); - const rangeInputContainer = document.createElement('div'); - container.appendChild(rangeInputContainer); - - search.addWidget( - instantsearch.widgets.configure({ - numericRefinements: { price: { '>=': [100], '<=': [500] } }, - }) - ); + withHits( + ({ search, container, instantsearch }) => { + const currentRefinementsContainer = document.createElement('div'); + currentRefinementsContainer.style.marginBottom = '10px'; + container.appendChild(currentRefinementsContainer); + const rangeInputContainer = document.createElement('div'); + container.appendChild(rangeInputContainer); - search.addWidget( - instantsearch.widgets.rangeInput({ - container: rangeInputContainer, - attribute: 'price', - }) - ); + search.addWidget( + instantsearch.widgets.rangeInput({ + container: rangeInputContainer, + attribute: 'price', + }) + ); - search.addWidget( - instantsearch.widgets.currentRefinements({ - container: currentRefinementsContainer, - }) - ); - }) + search.addWidget( + instantsearch.widgets.currentRefinements({ + container: currentRefinementsContainer, + }) + ); + }, + { + initialUiState: { + instant_search: { + range: { + price: '100:500', + }, + }, + }, + } + ) ) .add( 'with only price included', - withHits(({ search, container, instantsearch }) => { - const currentRefinementsContainer = document.createElement('div'); - container.appendChild(currentRefinementsContainer); + withHits( + ({ search, container, instantsearch }) => { + const currentRefinementsContainer = document.createElement('div'); + container.appendChild(currentRefinementsContainer); - search.addWidget( - instantsearch.widgets.configure({ - numericRefinements: { price: { '<=': [10] } }, - }) - ); - - search.addWidget( - instantsearch.widgets.currentRefinements({ - container: currentRefinementsContainer, - includedAttributes: ['price'], - }) - ); - }) + search.addWidget( + instantsearch.widgets.currentRefinements({ + container: currentRefinementsContainer, + includedAttributes: ['price'], + }) + ); + }, + { + initialUiState: { + instant_search: { + numericMenu: { + price: ':10', + }, + }, + }, + } + ) ) .add( 'with price and query excluded', - withHits(({ search, container, instantsearch }) => { - const currentRefinementsContainer = document.createElement('div'); - container.appendChild(currentRefinementsContainer); + withHits( + ({ search, container, instantsearch }) => { + const currentRefinementsContainer = document.createElement('div'); + container.appendChild(currentRefinementsContainer); - search.addWidget( - instantsearch.widgets.configure({ - disjunctiveFacetsRefinements: { brand: ['Apple', 'Samsung'] }, - disjunctiveFacets: ['brand'], - numericRefinements: { price: { '>=': [100] } }, - }) - ); - - search.addWidget( - instantsearch.widgets.currentRefinements({ - container: currentRefinementsContainer, - excludedAttributes: ['query', 'price'], - }) - ); - }) + search.addWidget( + instantsearch.widgets.currentRefinements({ + container: currentRefinementsContainer, + excludedAttributes: ['query', 'price'], + }) + ); + }, + { + initialUiState: { + instant_search: { + refinementList: { + brand: ['Apple', 'Samsung'], + }, + numericMenu: { + price: '100:', + }, + }, + }, + } + ) ) .add( 'with query', - withHits(({ search, container, instantsearch }) => { - const currentRefinementsContainer = document.createElement('div'); - container.appendChild(currentRefinementsContainer); - - search.addWidget( - instantsearch.widgets.configure({ - disjunctiveFacetsRefinements: { brand: ['Apple', 'Samsung'] }, - disjunctiveFacets: ['brand'], - numericRefinements: { price: { '>=': [100] } }, - }) - ); + withHits( + ({ search, container, instantsearch }) => { + const currentRefinementsContainer = document.createElement('div'); + container.appendChild(currentRefinementsContainer); - search.addWidget( - instantsearch.widgets.currentRefinements({ - container: currentRefinementsContainer, - excludedAttributes: [], - }) - ); - }) + search.addWidget( + instantsearch.widgets.currentRefinements({ + container: currentRefinementsContainer, + excludedAttributes: [], + }) + ); + }, + { + initialUiState: { + instant_search: { + refinementList: { + brand: ['Apple', 'Samsung'], + }, + numericMenu: { + price: '100:', + }, + }, + }, + } + ) ) .add( 'with transformed items', - withHits(({ search, container, instantsearch }) => { - const currentRefinementsContainer = document.createElement('div'); - container.appendChild(currentRefinementsContainer); - - search.addWidget( - instantsearch.widgets.configure({ - disjunctiveFacetsRefinements: { brand: ['Apple', 'Samsung'] }, - disjunctiveFacets: ['brand'], - numericRefinements: { price: { '>=': [100] } }, - }) - ); + withHits( + ({ search, container, instantsearch }) => { + const currentRefinementsContainer = document.createElement('div'); + container.appendChild(currentRefinementsContainer); - search.addWidget( - instantsearch.widgets.currentRefinements({ - container: currentRefinementsContainer, - transformItems: items => - items.map(refinementItem => ({ - ...refinementItem, - refinements: refinementItem.refinements.map(item => ({ - ...item, - label: item.label.toUpperCase(), + search.addWidget( + instantsearch.widgets.currentRefinements({ + container: currentRefinementsContainer, + transformItems: items => + items.map(refinementItem => ({ + ...refinementItem, + refinements: refinementItem.refinements.map(item => ({ + ...item, + label: item.label.toUpperCase(), + })), })), - })), - }) - ); - }) + }) + ); + }, + { + initialUiState: { + instant_search: { + refinementList: { + brand: ['Apple', 'Samsung'], + }, + numericMenu: { + price: '100:', + }, + }, + }, + } + ) ) .add( 'with multi indices', From 1ce8e3f819a1895a2a288fec1981a1b9ac75ddf8 Mon Sep 17 00:00:00 2001 From: Vaillant Samuel Date: Wed, 28 Aug 2019 18:48:50 +0200 Subject: [PATCH 07/10] refactor(stories): use initialUiState vs searchParameters in hierachicalMenu --- stories/hierarchical-menu.stories.js | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/stories/hierarchical-menu.stories.js b/stories/hierarchical-menu.stories.js index c6cc4a328c..28fa26080d 100644 --- a/stories/hierarchical-menu.stories.js +++ b/stories/hierarchical-menu.stories.js @@ -49,11 +49,13 @@ storiesOf('HierarchicalMenu', module) ); }, { - searchParameters: { - hierarchicalFacetsRefinements: { - 'hierarchicalCategories.lvl0': [ - 'Cameras & Camcorders > Digital Cameras', - ], + initialUiState: { + instant_search: { + hierarchicalMenu: { + 'hierarchicalCategories.lvl0': [ + 'Cameras & Camcorders > Digital Cameras', + ], + }, }, }, } From a48898a9f68ac1baf9aaeabe7d82659306e3f354 Mon Sep 17 00:00:00 2001 From: Vaillant Samuel Date: Thu, 29 Aug 2019 09:30:39 +0200 Subject: [PATCH 08/10] refactor(stories): use initialUiState vs MemoryRouter in infiniteHits --- stories/infinite-hits.stories.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/stories/infinite-hits.stories.js b/stories/infinite-hits.stories.js index 67b219bd17..023631d861 100644 --- a/stories/infinite-hits.stories.js +++ b/stories/infinite-hits.stories.js @@ -1,7 +1,6 @@ import { storiesOf } from '@storybook/html'; import { action } from '@storybook/addon-actions'; import { withHits } from '../.storybook/decorators'; -import { MemoryRouter } from '../.storybook/MemoryRouter'; import insights from '../src/helpers/insights'; storiesOf('InfiniteHits', module) @@ -120,8 +119,10 @@ storiesOf('InfiniteHits', module) ); }, { - routing: { - router: new MemoryRouter({ page: 3 }), + initialUiState: { + instant_search: { + page: 3, + }, }, } ) From 71012e158373a012592367e90b8947b9badba983 Mon Sep 17 00:00:00 2001 From: Vaillant Samuel Date: Thu, 29 Aug 2019 10:18:35 +0200 Subject: [PATCH 09/10] refactor(stories): use configure vs searchParameters in geoSearch --- stories/geo-search.stories.js | 222 +++++++++------------------------- 1 file changed, 57 insertions(+), 165 deletions(-) diff --git a/stories/geo-search.stories.js b/stories/geo-search.stories.js index 00047e4bea..ec260e7ffb 100644 --- a/stories/geo-search.stories.js +++ b/stories/geo-search.stories.js @@ -7,14 +7,25 @@ import injectScript from 'scriptjs'; const API_KEY = 'AIzaSyBawL8VbstJDdU5397SUX7pEt9DslAwWgQ'; -const wrapWithHitsAndConfiguration = (story, searchParameters) => - withHits(story, { - indexName: 'airbnb', - searchParameters: { - hitsPerPage: 20, - ...searchParameters, +const withHitsAndConfigure = (fn, options) => + withHits( + args => { + const { search, instantsearch } = args; + + search.addWidgets([ + instantsearch.widgets.configure({ + aroundLatLngViaIP: true, + hitsPerPage: 20, + }), + ]); + + fn(args); }, - }); + { + ...options, + indexName: 'airbnb', + } + ); const injectGoogleMaps = fn => { injectScript( @@ -32,14 +43,8 @@ const initialPosition = { stories.add( 'default', - wrapWithHitsAndConfiguration(({ search, container, instantsearch }) => + withHitsAndConfigure(({ search, container, instantsearch }) => injectGoogleMaps(() => { - search.addWidget( - instantsearch.widgets.configure({ - aroundLatLngViaIP: true, - }) - ); - search.addWidget( instantsearch.widgets.geoSearch({ googleReference: window.google, @@ -54,14 +59,8 @@ stories.add( stories .add( 'with IP', - wrapWithHitsAndConfiguration(({ search, container, instantsearch }) => + withHitsAndConfigure(({ search, container, instantsearch }) => injectGoogleMaps(() => { - search.addWidget( - instantsearch.widgets.configure({ - aroundLatLngViaIP: true, - }) - ); - search.addWidget( instantsearch.widgets.geoSearch({ googleReference: window.google, @@ -75,21 +74,20 @@ stories ) .add( 'with position', - wrapWithHitsAndConfiguration(({ search, container, instantsearch }) => + withHitsAndConfigure(({ search, container, instantsearch }) => injectGoogleMaps(() => { - search.addWidget( + search.addWidgets([ instantsearch.widgets.configure({ + aroundLatLngViaIP: false, aroundLatLng: '37.7793, -122.419', - }) - ); + }), - search.addWidget( instantsearch.widgets.geoSearch({ googleReference: window.google, container, initialZoom, - }) - ); + }), + ]); }) ) ); @@ -97,7 +95,7 @@ stories // With Places stories.add( 'with position from Places', - wrapWithHitsAndConfiguration(({ search, container, instantsearch }) => + withHitsAndConfigure(({ search, container, instantsearch }) => injectGoogleMaps(() => { const placesElement = document.createElement('input'); const mapElement = document.createElement('div'); @@ -106,27 +104,23 @@ stories.add( container.appendChild(placesElement); container.appendChild(mapElement); - search.addWidget( + search.addWidgets([ instantsearch.widgets.configure({ aroundRadius: 20000, - }) - ); + }), - search.addWidget( instantsearchPlacesWidget({ container: placesElement, defaultPosition: ['37.7793', '-122.419'], - }) - ); + }), - search.addWidget( instantsearch.widgets.geoSearch({ googleReference: window.google, container: mapElement, enableClearMapRefinement: false, initialZoom, - }) - ); + }), + ]); }) ) ); @@ -135,14 +129,8 @@ stories.add( stories .add( 'with refine disabled', - wrapWithHitsAndConfiguration(({ search, container, instantsearch }) => + withHitsAndConfigure(({ search, container, instantsearch }) => injectGoogleMaps(() => { - search.addWidget( - instantsearch.widgets.configure({ - aroundLatLngViaIP: true, - }) - ); - search.addWidget( instantsearch.widgets.geoSearch({ googleReference: window.google, @@ -157,14 +145,8 @@ stories ) .add( 'with control & refine on map move', - wrapWithHitsAndConfiguration(({ search, container, instantsearch }) => + withHitsAndConfigure(({ search, container, instantsearch }) => injectGoogleMaps(() => { - search.addWidget( - instantsearch.widgets.configure({ - aroundLatLngViaIP: true, - }) - ); - search.addWidget( instantsearch.widgets.geoSearch({ googleReference: window.google, @@ -180,14 +162,8 @@ stories ) .add( 'with control & disable refine on map move', - wrapWithHitsAndConfiguration(({ search, container, instantsearch }) => + withHitsAndConfigure(({ search, container, instantsearch }) => injectGoogleMaps(() => { - search.addWidget( - instantsearch.widgets.configure({ - aroundLatLngViaIP: true, - }) - ); - search.addWidget( instantsearch.widgets.geoSearch({ googleReference: window.google, @@ -203,14 +179,8 @@ stories ) .add( 'without control & refine on map move', - wrapWithHitsAndConfiguration(({ search, container, instantsearch }) => + withHitsAndConfigure(({ search, container, instantsearch }) => injectGoogleMaps(() => { - search.addWidget( - instantsearch.widgets.configure({ - aroundLatLngViaIP: true, - }) - ); - search.addWidget( instantsearch.widgets.geoSearch({ googleReference: window.google, @@ -226,14 +196,8 @@ stories ) .add( 'without control & disable refine on map move', - wrapWithHitsAndConfiguration(({ search, container, instantsearch }) => + withHitsAndConfigure(({ search, container, instantsearch }) => injectGoogleMaps(() => { - search.addWidget( - instantsearch.widgets.configure({ - aroundLatLngViaIP: true, - }) - ); - search.addWidget( instantsearch.widgets.geoSearch({ googleReference: window.google, @@ -249,14 +213,8 @@ stories ) .add( 'with custom templates for controls', - wrapWithHitsAndConfiguration(({ search, container, instantsearch }) => + withHitsAndConfigure(({ search, container, instantsearch }) => injectGoogleMaps(() => { - search.addWidget( - instantsearch.widgets.configure({ - aroundLatLngViaIP: true, - }) - ); - search.addWidget( instantsearch.widgets.geoSearch({ googleReference: window.google, @@ -275,14 +233,8 @@ stories ) .add( 'with custom map options', - wrapWithHitsAndConfiguration(({ search, container, instantsearch }) => + withHitsAndConfigure(({ search, container, instantsearch }) => injectGoogleMaps(() => { - search.addWidget( - instantsearch.widgets.configure({ - aroundLatLngViaIP: true, - }) - ); - search.addWidget( instantsearch.widgets.geoSearch({ googleReference: window.google, @@ -299,16 +251,10 @@ stories ) .add( 'with built-in marker options', - wrapWithHitsAndConfiguration(({ search, container, instantsearch }) => + withHitsAndConfigure(({ search, container, instantsearch }) => injectGoogleMaps(() => { const logger = action('[GeoSearch] click: builtInMarker'); - search.addWidget( - instantsearch.widgets.configure({ - aroundLatLngViaIP: true, - }) - ); - search.addWidget( instantsearch.widgets.geoSearch({ googleReference: window.google, @@ -333,16 +279,10 @@ stories ) .add( 'with built-in marker & InfoWindow', - wrapWithHitsAndConfiguration(({ search, container, instantsearch }) => + withHitsAndConfigure(({ search, container, instantsearch }) => injectGoogleMaps(() => { const InfoWindow = new window.google.maps.InfoWindow(); - search.addWidget( - instantsearch.widgets.configure({ - aroundLatLngViaIP: true, - }) - ); - search.addWidget( instantsearch.widgets.geoSearch({ googleReference: window.google, @@ -369,7 +309,7 @@ stories ) .add( 'with built-in marker & InfoBox', - wrapWithHitsAndConfiguration(({ search, container, instantsearch }) => + withHitsAndConfigure(({ search, container, instantsearch }) => injectGoogleMaps(() => { const InfoBox = createInfoBox(window.google); const InfoBoxInstance = new InfoBox(); @@ -385,12 +325,6 @@ stories }); }); - search.addWidget( - instantsearch.widgets.configure({ - aroundLatLngViaIP: true, - }) - ); - search.addWidget( instantsearch.widgets.geoSearch({ googleReference: window.google, @@ -421,16 +355,10 @@ stories ) .add( 'with HTML marker options', - wrapWithHitsAndConfiguration(({ search, container, instantsearch }) => + withHitsAndConfigure(({ search, container, instantsearch }) => injectGoogleMaps(() => { const logger = action('[GeoSearch] click: HTMLMarker'); - search.addWidget( - instantsearch.widgets.configure({ - aroundLatLngViaIP: true, - }) - ); - search.addWidget( instantsearch.widgets.geoSearch({ googleReference: window.google, @@ -464,18 +392,12 @@ stories ) .add( 'with HTML marker & InfoWindow', - wrapWithHitsAndConfiguration(({ search, container, instantsearch }) => + withHitsAndConfigure(({ search, container, instantsearch }) => injectGoogleMaps(() => { const InfoWindow = new window.google.maps.InfoWindow({ pixelOffset: new window.google.maps.Size(0, -30), }); - search.addWidget( - instantsearch.widgets.configure({ - aroundLatLngViaIP: true, - }) - ); - search.addWidget( instantsearch.widgets.geoSearch({ googleReference: window.google, @@ -515,7 +437,7 @@ stories ) .add( 'with HTML marker & InfoBox', - wrapWithHitsAndConfiguration(({ search, container, instantsearch }) => + withHitsAndConfigure(({ search, container, instantsearch }) => injectGoogleMaps(() => { const InfoBox = createInfoBox(window.google); const InfoBoxInstance = new InfoBox(); @@ -531,12 +453,6 @@ stories }); }); - search.addWidget( - instantsearch.widgets.configure({ - aroundLatLngViaIP: true, - }) - ); - search.addWidget( instantsearch.widgets.geoSearch({ googleReference: window.google, @@ -580,7 +496,7 @@ stories ) .add( 'with Hits communication (custom)', - wrapWithHitsAndConfiguration(({ search, container, instantsearch }) => + withHitsAndConfigure(({ search, container, instantsearch }) => injectGoogleMaps(() => { const containerElement = document.querySelector( '#results-hits-container' @@ -618,12 +534,6 @@ stories removeActiveMarkerClassNames(); }); - search.addWidget( - instantsearch.widgets.configure({ - aroundLatLngViaIP: true, - }) - ); - search.addWidget( instantsearch.widgets.geoSearch({ googleReference: window.google, @@ -666,15 +576,9 @@ stories ) .add( 'with routing (simulate)', - wrapWithHitsAndConfiguration( + withHitsAndConfigure( ({ search, container, instantsearch }) => injectGoogleMaps(() => { - search.addWidget( - instantsearch.widgets.configure({ - aroundLatLngViaIP: true, - }) - ); - search.addWidget( instantsearch.widgets.geoSearch({ googleReference: window.google, @@ -685,27 +589,21 @@ stories ); }), { - insideBoundingBox: [ - [ - 48.84174222399724, - 2.367719162523599, - 48.81614630305218, - 2.284205902635904, - ], - ], + initialUiState: { + airbnb: { + geoSearch: { + boundingBox: + '48.84174222399724, 2.367719162523599, 48.81614630305218, 2.284205902635904', + }, + }, + }, } ) ) .add( 'with transformed items', - wrapWithHitsAndConfiguration(({ search, container, instantsearch }) => + withHitsAndConfigure(({ search, container, instantsearch }) => injectGoogleMaps(() => { - search.addWidget( - instantsearch.widgets.configure({ - aroundLatLngViaIP: true, - }) - ); - search.addWidget( instantsearch.widgets.geoSearch({ googleReference: window.google, @@ -727,14 +625,8 @@ stories ) .add( 'with add/remove', - wrapWithHitsAndConfiguration(({ search, container, instantsearch }) => + withHitsAndConfigure(({ search, container, instantsearch }) => injectGoogleMaps(() => { - search.addWidget( - instantsearch.widgets.configure({ - aroundLatLngViaIP: true, - }) - ); - withLifecycle(search, container, node => instantsearch.widgets.geoSearch({ googleReference: window.google, From 9ffaffc5a2d1322598dd7f927bacebbfe186eb71 Mon Sep 17 00:00:00 2001 From: Vaillant Samuel Date: Thu, 29 Aug 2019 11:09:22 +0200 Subject: [PATCH 10/10] refactor(stories): use initialUiState vs configure in queryRuleContext --- stories/query-rule-context.stories.ts | 81 ++++++++++++++------------- 1 file changed, 42 insertions(+), 39 deletions(-) diff --git a/stories/query-rule-context.stories.ts b/stories/query-rule-context.stories.ts index 285c0262f4..7aa81927dc 100644 --- a/stories/query-rule-context.stories.ts +++ b/stories/query-rule-context.stories.ts @@ -1,7 +1,6 @@ import { storiesOf } from '@storybook/html'; import { withHits } from '../.storybook/decorators'; import moviesPlayground from '../.storybook/playgrounds/movies'; -import configure from '../src/widgets/configure/configure'; import queryRuleCustomData from '../src/widgets/query-rule-custom-data/query-rule-custom-data'; import queryRuleContext from '../src/widgets/query-rule-context/query-rule-context'; @@ -71,47 +70,40 @@ storiesOf('QueryRuleContext', module) ) .add( 'with initial filter', - withHits(({ search, container }) => { - const widgetContainer = document.createElement('div'); - const description = document.createElement('ul'); - description.innerHTML = ` + withHits( + ({ search, container }) => { + const widgetContainer = document.createElement('div'); + const description = document.createElement('ul'); + description.innerHTML = `
  • Select the "Drama" category and The Shawshank Redemption appears
  • Select the "Thriller" category and Pulp Fiction appears
  • Type music and a banner will appear.
  • `; - container.appendChild(description); - container.appendChild(widgetContainer); + container.appendChild(description); + container.appendChild(widgetContainer); - search.addWidget( - configure({ - disjunctiveFacetsRefinements: { - genre: ['Drama'], - }, - }) - ); + search.addWidget( + queryRuleContext({ + trackedFilters: { + genre: () => ['Thriller', 'Drama'], + }, + }) + ); - search.addWidget( - queryRuleContext({ - trackedFilters: { - genre: () => ['Thriller', 'Drama'], - }, - }) - ); + search.addWidget( + queryRuleCustomData({ + container: widgetContainer, + transformItems(items: CustomDataItem[]) { + return items.filter(item => typeof item.banner !== 'undefined'); + }, + templates: { + default: ({ items }: { items: CustomDataItem[] }) => + items + .map(item => { + const { title, banner, link } = item; - search.addWidget( - queryRuleCustomData({ - container: widgetContainer, - transformItems(items: CustomDataItem[]) { - return items.filter(item => typeof item.banner !== 'undefined'); - }, - templates: { - default: ({ items }: { items: CustomDataItem[] }) => - items - .map(item => { - const { title, banner, link } = item; - - return ` + return `

    ${title}

    @@ -120,10 +112,21 @@ storiesOf('QueryRuleContext', module)
    `; - }) - .join(''), + }) + .join(''), + }, + }) + ); + }, + { + ...searchOptions, + initialUiState: { + instant_search_movies: { + refinementList: { + genre: ['Drama'], + }, }, - }) - ); - }, searchOptions) + }, + } + ) );