From 83f02a128bbc3fb2752af6861233fdfc93fb10fb Mon Sep 17 00:00:00 2001 From: Gordon Date: Thu, 6 Dec 2018 16:07:45 -0600 Subject: [PATCH] Improve react-instantsearch Refinements --- types/react-instantsearch-core/index.d.ts | 22 +++++--- .../react-instantsearch-core-tests.tsx | 53 ++++++++++++++++++- .../react-instantsearch-tests.tsx | 2 +- 3 files changed, 67 insertions(+), 10 deletions(-) diff --git a/types/react-instantsearch-core/index.d.ts b/types/react-instantsearch-core/index.d.ts index af86139fde..bceb91ca85 100644 --- a/types/react-instantsearch-core/index.d.ts +++ b/types/react-instantsearch-core/index.d.ts @@ -129,17 +129,20 @@ export function connectAutoComplete(Composed: React.ComponentType): React.C export function connectBreadcrumb(Composed: React.ComponentType): React.ComponentClass; export function connectConfigure(Composed: React.ComponentType): React.ComponentClass; -export interface Refinement { +export type Refinement = { label: string; attribute: string; - currentRefinement: string | object; - items?: Array<{ label: string, value: RefinementValue }>; index: string; id: string; value: RefinementValue; -} +} & ({ + currentRefinement: string; +} | { + items: Array<{ label: string, value: RefinementValue }>; + currentRefinement: string[]; +}); -type RefinementValue = (searchState: SearchState) => SearchState; +export type RefinementValue = (searchState: SearchState) => SearchState; export interface CurrentRefinementsExposed { /** @@ -305,13 +308,16 @@ export function connectRange(Composed: React.ComponentType): React.Componen export interface RefinementListProvided { /** a function to toggle a refinement */ - refine: (...args: any[]) => any; + refine: (value: string[]) => any; /** a function to generate a URL for the corresponding search state */ createURL: (...args: any[]) => any; /** the refinement currently applied */ currentRefinement: string[]; - /** the list of items the RefinementList can display. */ - items: Array>; + /** + * The list of items the RefinementList can display. + * If isFromSearch is false, the hit properties like _highlightResult are undefined + */ + items: Array>; /** a function to toggle a search inside items values */ searchForItems: (...args: any[]) => any; /** a boolean that says if the items props contains facet values from the global search or from the search inside items. */ diff --git a/types/react-instantsearch-core/react-instantsearch-core-tests.tsx b/types/react-instantsearch-core/react-instantsearch-core-tests.tsx index 1ced5dee69..e39a9f53e6 100644 --- a/types/react-instantsearch-core/react-instantsearch-core-tests.tsx +++ b/types/react-instantsearch-core/react-instantsearch-core-tests.tsx @@ -9,7 +9,9 @@ import { connectSearchBox, connectRefinementList, CurrentRefinementsProvided, - connectCurrentRefinements + connectCurrentRefinements, + RefinementListProvided, + Refinement } from 'react-instantsearch-core'; () => { @@ -168,3 +170,52 @@ import { item} />; }; + +() => { + function renderRefinement( + label: string, + value: Refinement['value'], + refine: CurrentRefinementsProvided['refine'], + ) { + return ; + } + + const MyCurrentRefinements = connectCurrentRefinements(({refine, items, query}: CurrentRefinementsProvided) => { + return <> + {items.map((refinement) => { + let str: string = refinement.currentRefinement; // $ExpectError + /* + * When existing several refinements for the same atribute name, then you get a + * nested items object that contains a label and a value function to use to remove a single filter. + * https://community.algolia.com/react-instantsearch/connectors/connectCurrentRefinements.html + */ + if ('items' in refinement) { + str = refinement.currentRefinement; // $ExpectError + return <> + {refinement.items.map((i) => renderRefinement(i.label, i.value, refine))} + ; + } + + console.log(refinement.items); // $ExpectError + return renderRefinement(refinement.currentRefinement, refinement.value, refine); + })} + ; + }); +}; + +() => { + const MyRefinementList = ({items, refine}: RefinementListProvided) => + <> + {items.map((item) => ( + + ))} + ; + const ConnectedRefinementList = connectRefinementList(MyRefinementList); + + ; +}; diff --git a/types/react-instantsearch/react-instantsearch-tests.tsx b/types/react-instantsearch/react-instantsearch-tests.tsx index 82672b7a60..9abf91c0ef 100644 --- a/types/react-instantsearch/react-instantsearch-tests.tsx +++ b/types/react-instantsearch/react-instantsearch-tests.tsx @@ -348,7 +348,7 @@ import { createInstantSearch } from "react-instantsearch-core"; : item.label; return ( -
  • +
  • props.refine(item.value)}> {label} {item.isRefined ? '- selected' : ''}