Improve react-instantsearch Refinements

This commit is contained in:
Gordon
2018-12-06 16:08:48 -06:00
parent 6f6aaa4dee
commit 83f02a128b
3 changed files with 67 additions and 10 deletions
+14 -8
View File
@@ -129,17 +129,20 @@ export function connectAutoComplete(Composed: React.ComponentType<any>): React.C
export function connectBreadcrumb(Composed: React.ComponentType<any>): React.ComponentClass<any>;
export function connectConfigure(Composed: React.ComponentType<any>): React.ComponentClass<any>;
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<any>): 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<Hit<{ count: number, isRefined: boolean, label: string, value: string }>>;
/**
* The list of items the RefinementList can display.
* If isFromSearch is false, the hit properties like _highlightResult are undefined
*/
items: Array<Hit<{ count: number, isRefined: boolean, label: string, value: string[] }>>;
/** 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. */
@@ -9,7 +9,9 @@ import {
connectSearchBox,
connectRefinementList,
CurrentRefinementsProvided,
connectCurrentRefinements
connectCurrentRefinements,
RefinementListProvided,
Refinement
} from 'react-instantsearch-core';
() => {
@@ -168,3 +170,52 @@ import {
<ConnectedCurrentRefinements clearsQuery={true} transformItems={(item) => item} />;
};
() => {
function renderRefinement(
label: string,
value: Refinement['value'],
refine: CurrentRefinementsProvided['refine'],
) {
return <button className="badge badge-secondary" onClick={() => refine(value)}>
{label}
</button>;
}
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) => (
<button onClick={() => refine(item.value)}>
{item.label}
</button>
))}
</>;
const ConnectedRefinementList = connectRefinementList(MyRefinementList);
<ConnectedRefinementList attribute={'test'} searchable={true} operator={'and'}
showMore={true} limit={8} showMoreLimit={99} />;
};
@@ -348,7 +348,7 @@ import { createInstantSearch } from "react-instantsearch-core";
: item.label;
return (
<li key={item.value}>
<li key={item.label}>
<span onClick={() => props.refine(item.value)}>
{label} {item.isRefined ? '- selected' : ''}
</span>