instantsearch.js 4.44.1 → 4.46.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/cjs/components/Hits/Hits.js +3 -1
  3. package/cjs/components/InfiniteHits/InfiniteHits.js +3 -1
  4. package/cjs/components/Template/Template.js +13 -3
  5. package/cjs/connectors/hits-per-page/connectHitsPerPage.js +3 -1
  6. package/cjs/connectors/numeric-menu/connectNumericMenu.js +27 -2
  7. package/cjs/connectors/rating-menu/connectRatingMenu.js +10 -4
  8. package/cjs/connectors/sort-by/connectSortBy.js +3 -1
  9. package/cjs/lib/createHelpers.js +3 -1
  10. package/cjs/lib/formatNumber.js +10 -0
  11. package/cjs/lib/utils/cx.js +10 -0
  12. package/cjs/lib/utils/index.js +10 -1
  13. package/cjs/lib/utils/renderTemplate.js +17 -2
  14. package/cjs/lib/version.js +1 -1
  15. package/cjs/widgets/answers/defaultTemplates.js +6 -2
  16. package/cjs/widgets/breadcrumb/defaultTemplates.js +6 -2
  17. package/cjs/widgets/clear-refinements/clear-refinements.js +2 -2
  18. package/cjs/widgets/clear-refinements/defaultTemplates.js +3 -1
  19. package/cjs/widgets/geo-search/createHTMLMarker.js +10 -4
  20. package/cjs/widgets/geo-search/defaultTemplates.js +18 -4
  21. package/cjs/widgets/hierarchical-menu/defaultTemplates.js +26 -2
  22. package/cjs/widgets/hits/defaultTemplates.js +3 -1
  23. package/cjs/widgets/infinite-hits/defaultTemplates.js +9 -3
  24. package/cjs/widgets/menu/defaultTemplates.js +26 -2
  25. package/cjs/widgets/menu-select/defaultTemplates.js +11 -2
  26. package/cjs/widgets/numeric-menu/defaultTemplates.js +20 -1
  27. package/cjs/widgets/range-input/range-input.js +6 -2
  28. package/cjs/widgets/rating-menu/defaultTemplates.js +57 -1
  29. package/cjs/widgets/refinement-list/defaultTemplates.js +38 -3
  30. package/cjs/widgets/relevant-sort/defaultTemplates.js +3 -1
  31. package/cjs/widgets/search-box/defaultTemplates.js +62 -3
  32. package/cjs/widgets/stats/stats.js +70 -22
  33. package/cjs/widgets/toggle-refinement/defaultTemplates.js +4 -1
  34. package/cjs/widgets/voice-search/defaultTemplates.js +81 -9
  35. package/dist/instantsearch.development.d.ts +171 -29
  36. package/dist/instantsearch.development.js +1430 -671
  37. package/dist/instantsearch.development.js.map +1 -1
  38. package/dist/instantsearch.production.d.ts +171 -29
  39. package/dist/instantsearch.production.min.d.ts +171 -29
  40. package/dist/instantsearch.production.min.js +2 -2
  41. package/dist/instantsearch.production.min.js.map +1 -1
  42. package/es/components/Answers/Answers.d.ts +2 -2
  43. package/es/components/Hits/Hits.d.ts +3 -3
  44. package/es/components/Hits/Hits.js +3 -1
  45. package/es/components/InfiniteHits/InfiniteHits.d.ts +3 -3
  46. package/es/components/InfiniteHits/InfiniteHits.js +3 -1
  47. package/es/components/Template/Template.d.ts +4 -2
  48. package/es/components/Template/Template.js +14 -4
  49. package/es/connectors/answers/connectAnswers.d.ts +2 -2
  50. package/es/connectors/autocomplete/connectAutocomplete.d.ts +2 -2
  51. package/es/connectors/hits-per-page/connectHitsPerPage.d.ts +5 -0
  52. package/es/connectors/hits-per-page/connectHitsPerPage.js +3 -1
  53. package/es/connectors/numeric-menu/connectNumericMenu.d.ts +8 -0
  54. package/es/connectors/numeric-menu/connectNumericMenu.js +27 -2
  55. package/es/connectors/rating-menu/connectRatingMenu.d.ts +2 -0
  56. package/es/connectors/rating-menu/connectRatingMenu.js +10 -4
  57. package/es/connectors/sort-by/connectSortBy.d.ts +5 -0
  58. package/es/connectors/sort-by/connectSortBy.js +3 -1
  59. package/es/lib/createHelpers.js +2 -1
  60. package/es/lib/formatNumber.d.ts +1 -0
  61. package/es/lib/formatNumber.js +3 -0
  62. package/es/lib/insights/client.d.ts +2 -2
  63. package/es/lib/utils/createSendEventForHits.d.ts +3 -3
  64. package/es/lib/utils/cx.d.ts +1 -0
  65. package/es/lib/utils/cx.js +3 -0
  66. package/es/lib/utils/index.d.ts +1 -0
  67. package/es/lib/utils/index.js +2 -1
  68. package/es/lib/utils/renderTemplate.d.ts +4 -3
  69. package/es/lib/utils/renderTemplate.js +15 -2
  70. package/es/lib/version.d.ts +1 -1
  71. package/es/lib/version.js +1 -1
  72. package/es/types/connector.d.ts +2 -2
  73. package/es/types/templates.d.ts +16 -3
  74. package/es/widgets/answers/defaultTemplates.js +6 -2
  75. package/es/widgets/breadcrumb/defaultTemplates.js +6 -2
  76. package/es/widgets/clear-refinements/clear-refinements.d.ts +3 -1
  77. package/es/widgets/clear-refinements/clear-refinements.js +2 -2
  78. package/es/widgets/clear-refinements/defaultTemplates.js +3 -1
  79. package/es/widgets/geo-search/createHTMLMarker.d.ts +2 -1
  80. package/es/widgets/geo-search/createHTMLMarker.js +8 -1
  81. package/es/widgets/geo-search/defaultTemplates.d.ts +1 -0
  82. package/es/widgets/geo-search/defaultTemplates.js +17 -4
  83. package/es/widgets/hierarchical-menu/defaultTemplates.js +22 -2
  84. package/es/widgets/hierarchical-menu/hierarchical-menu.d.ts +2 -0
  85. package/es/widgets/hits/defaultTemplates.js +3 -1
  86. package/es/widgets/hits/hits.d.ts +2 -1
  87. package/es/widgets/infinite-hits/defaultTemplates.js +9 -3
  88. package/es/widgets/infinite-hits/infinite-hits.d.ts +1 -3
  89. package/es/widgets/menu/defaultTemplates.js +22 -2
  90. package/es/widgets/menu-select/defaultTemplates.js +9 -2
  91. package/es/widgets/numeric-menu/defaultTemplates.js +18 -1
  92. package/es/widgets/range-input/range-input.js +6 -2
  93. package/es/widgets/rating-menu/defaultTemplates.js +54 -1
  94. package/es/widgets/rating-menu/rating-menu.d.ts +6 -0
  95. package/es/widgets/refinement-list/defaultTemplates.js +34 -3
  96. package/es/widgets/refinement-list/refinement-list.d.ts +7 -1
  97. package/es/widgets/relevant-sort/defaultTemplates.js +3 -1
  98. package/es/widgets/search-box/defaultTemplates.js +61 -3
  99. package/es/widgets/search-box/search-box.d.ts +10 -3
  100. package/es/widgets/stats/stats.d.ts +10 -6
  101. package/es/widgets/stats/stats.js +69 -22
  102. package/es/widgets/toggle-refinement/defaultTemplates.js +4 -1
  103. package/es/widgets/toggle-refinement/toggle-refinement.d.ts +3 -1
  104. package/es/widgets/voice-search/defaultTemplates.js +81 -9
  105. package/package.json +7 -5
@@ -1,11 +1,11 @@
1
1
  /** @jsx h */
2
2
  import { h } from 'preact';
3
3
  import type { AnswersCSSClasses, AnswersTemplates } from '../../widgets/answers/answers';
4
- import type { ComponentCSSClasses, Hits } from '../../types';
4
+ import type { ComponentCSSClasses, Hit } from '../../types';
5
5
  export declare type AnswersComponentCSSClasses = ComponentCSSClasses<AnswersCSSClasses>;
6
6
  export declare type AnswersComponentTemplates = Required<AnswersTemplates>;
7
7
  export declare type AnswersProps = {
8
- hits: Hits;
8
+ hits: Hit[];
9
9
  isLoading: boolean;
10
10
  cssClasses: AnswersComponentCSSClasses;
11
11
  templateProps: {
@@ -2,18 +2,18 @@
2
2
  import { h } from 'preact';
3
3
  import type { SearchResults } from 'algoliasearch-helper';
4
4
  import type { BindEventForHits, SendEventForHits } from '../../lib/utils';
5
- import type { ComponentCSSClasses, Hits as HitsArray } from '../../types';
5
+ import type { ComponentCSSClasses, Hit } from '../../types';
6
6
  import type { HitsCSSClasses, HitsTemplates } from '../../widgets/hits/hits';
7
7
  import type { PreparedTemplateProps } from '../../lib/utils/prepareTemplateProps';
8
8
  export declare type HitsComponentCSSClasses = ComponentCSSClasses<HitsCSSClasses>;
9
9
  export declare type HitsComponentTemplates = Required<HitsTemplates>;
10
10
  export declare type HitsProps = {
11
11
  results: SearchResults;
12
- hits: HitsArray;
12
+ hits: Hit[];
13
13
  sendEvent?: SendEventForHits;
14
14
  bindEvent?: BindEventForHits;
15
15
  cssClasses: HitsComponentCSSClasses;
16
16
  templateProps: PreparedTemplateProps<HitsComponentTemplates>;
17
17
  };
18
- declare const Hits: ({ results, hits, bindEvent, cssClasses, templateProps, }: HitsProps) => h.JSX.Element;
18
+ declare const Hits: ({ results, hits, bindEvent, sendEvent, cssClasses, templateProps, }: HitsProps) => h.JSX.Element;
19
19
  export default Hits;
@@ -15,6 +15,7 @@ var Hits = function Hits(_ref) {
15
15
  var results = _ref.results,
16
16
  hits = _ref.hits,
17
17
  bindEvent = _ref.bindEvent,
18
+ sendEvent = _ref.sendEvent,
18
19
  cssClasses = _ref.cssClasses,
19
20
  templateProps = _ref.templateProps;
20
21
 
@@ -43,7 +44,8 @@ var Hits = function Hits(_ref) {
43
44
  data: _objectSpread(_objectSpread({}, hit), {}, {
44
45
  __hitIndex: index
45
46
  }),
46
- bindEvent: bindEvent
47
+ bindEvent: bindEvent,
48
+ sendEvent: sendEvent
47
49
  }));
48
50
  })));
49
51
  };
@@ -1,14 +1,14 @@
1
1
  /** @jsx h */
2
2
  import { h } from 'preact';
3
3
  import type { SearchResults } from 'algoliasearch-helper';
4
- import type { ComponentCSSClasses, Hits } from '../../types';
4
+ import type { ComponentCSSClasses, Hit } from '../../types';
5
5
  import type { InfiniteHitsCSSClasses, InfiniteHitsTemplates } from '../../widgets/infinite-hits/infinite-hits';
6
6
  import type { SendEventForHits, BindEventForHits } from '../../lib/utils';
7
7
  export declare type InfiniteHitsComponentCSSClasses = ComponentCSSClasses<InfiniteHitsCSSClasses>;
8
8
  export declare type InfiniteHitsComponentTemplates = Required<InfiniteHitsTemplates>;
9
9
  export declare type InfiniteHitsProps = {
10
10
  cssClasses: InfiniteHitsComponentCSSClasses;
11
- hits: Hits;
11
+ hits: Hit[];
12
12
  results: SearchResults;
13
13
  hasShowPrevious: boolean;
14
14
  showPrevious: () => void;
@@ -22,5 +22,5 @@ export declare type InfiniteHitsProps = {
22
22
  sendEvent: SendEventForHits;
23
23
  bindEvent: BindEventForHits;
24
24
  };
25
- declare const InfiniteHits: ({ results, hits, bindEvent, hasShowPrevious, showPrevious, showMore, isFirstPage, isLastPage, cssClasses, templateProps, }: InfiniteHitsProps) => h.JSX.Element;
25
+ declare const InfiniteHits: ({ results, hits, bindEvent, sendEvent, hasShowPrevious, showPrevious, showMore, isFirstPage, isLastPage, cssClasses, templateProps, }: InfiniteHitsProps) => h.JSX.Element;
26
26
  export default InfiniteHits;
@@ -15,6 +15,7 @@ var InfiniteHits = function InfiniteHits(_ref) {
15
15
  var results = _ref.results,
16
16
  hits = _ref.hits,
17
17
  bindEvent = _ref.bindEvent,
18
+ sendEvent = _ref.sendEvent,
18
19
  hasShowPrevious = _ref.hasShowPrevious,
19
20
  showPrevious = _ref.showPrevious,
20
21
  showMore = _ref.showMore,
@@ -56,7 +57,8 @@ var InfiniteHits = function InfiniteHits(_ref) {
56
57
  data: _objectSpread(_objectSpread({}, hit), {}, {
57
58
  __hitIndex: position
58
59
  }),
59
- bindEvent: bindEvent
60
+ bindEvent: bindEvent,
61
+ sendEvent: sendEvent
60
62
  }));
61
63
  })), h(Template, _extends({}, templateProps, {
62
64
  templateKey: "showMoreText",
@@ -1,6 +1,7 @@
1
1
  /** @jsx h */
2
2
  import type { JSX } from 'preact';
3
3
  import { Component } from 'preact';
4
+ import type { BindEventForHits, SendEventForHits } from '../../lib/utils';
4
5
  import type { PreparedTemplateProps } from '../../lib/utils/prepareTemplateProps';
5
6
  import type { Templates } from '../../types';
6
7
  declare const defaultProps: {
@@ -10,12 +11,13 @@ declare const defaultProps: {
10
11
  templates: {};
11
12
  templatesConfig: {};
12
13
  };
13
- declare type TemplateProps = {
14
+ export declare type TemplateProps = {
14
15
  data?: Record<string, any>;
15
16
  rootProps?: Record<string, any>;
16
17
  rootTagName?: keyof JSX.IntrinsicElements;
17
18
  templateKey: string;
18
- bindEvent?: (...args: any[]) => string;
19
+ bindEvent?: BindEventForHits;
20
+ sendEvent?: SendEventForHits;
19
21
  } & PreparedTemplateProps<Templates> & Readonly<typeof defaultProps>;
20
22
  declare class Template extends Component<TemplateProps> {
21
23
  static readonly defaultProps: {
@@ -1,7 +1,7 @@
1
- function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
2
-
3
1
  function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
4
2
 
3
+ function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
4
+
5
5
  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
6
6
 
7
7
  function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
@@ -26,7 +26,7 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
26
26
 
27
27
  /** @jsx h */
28
28
  import { h, Component } from 'preact';
29
- import { renderTemplate, isEqual } from "../../lib/utils/index.js";
29
+ import { warning, renderTemplate, isEqual } from "../../lib/utils/index.js";
30
30
  var defaultProps = {
31
31
  data: {},
32
32
  rootTagName: 'div',
@@ -55,6 +55,11 @@ var Template = /*#__PURE__*/function (_Component) {
55
55
  }, {
56
56
  key: "render",
57
57
  value: function render() {
58
+ var _this = this;
59
+
60
+ process.env.NODE_ENV === 'development' ? warning(Object.keys(this.props.templates).every(function (key) {
61
+ return typeof _this.props.templates[key] === 'function';
62
+ }), "Hogan.js and string-based templates are deprecated and will not be supported in InstantSearch.js 5.x.\n\nYou can replace them with function-form templates and use either the provided `html` function or JSX templates.\n\nSee: https://www.algolia.com/doc/guides/building-search-ui/upgrade-guides/js/#upgrade-templates") : void 0;
58
63
  var RootTagName = this.props.rootTagName;
59
64
  var useCustomCompileOptions = this.props.useCustomCompileOptions[this.props.templateKey];
60
65
  var compileOptions = useCustomCompileOptions ? this.props.templatesConfig.compileOptions : {};
@@ -64,7 +69,8 @@ var Template = /*#__PURE__*/function (_Component) {
64
69
  compileOptions: compileOptions,
65
70
  helpers: this.props.templatesConfig.helpers,
66
71
  data: this.props.data,
67
- bindEvent: this.props.bindEvent
72
+ bindEvent: this.props.bindEvent,
73
+ sendEvent: this.props.sendEvent
68
74
  });
69
75
 
70
76
  if (content === null) {
@@ -73,6 +79,10 @@ var Template = /*#__PURE__*/function (_Component) {
73
79
  return null;
74
80
  }
75
81
 
82
+ if (_typeof(content) === 'object') {
83
+ return h(RootTagName, this.props.rootProps, content);
84
+ }
85
+
76
86
  return h(RootTagName, _extends({}, this.props.rootProps, {
77
87
  dangerouslySetInnerHTML: {
78
88
  __html: content
@@ -1,9 +1,9 @@
1
- import type { Connector, Hits, FindAnswersOptions, WidgetRenderState } from '../../types';
1
+ import type { Connector, Hit, FindAnswersOptions, WidgetRenderState } from '../../types';
2
2
  export declare type AnswersRenderState = {
3
3
  /**
4
4
  * The matched hits from Algolia API.
5
5
  */
6
- hits: Hits;
6
+ hits: Hit[];
7
7
  /**
8
8
  * Whether it's still loading the results from the Answers API.
9
9
  */
@@ -1,6 +1,6 @@
1
1
  import type { SearchResults } from 'algoliasearch-helper';
2
2
  import type { SendEventForHits } from '../../lib/utils';
3
- import type { Hits, Connector, WidgetRenderState } from '../../types';
3
+ import type { Hit, Connector, WidgetRenderState } from '../../types';
4
4
  export declare type AutocompleteConnectorParams = {
5
5
  /**
6
6
  * Escapes HTML entities from hits string values.
@@ -25,7 +25,7 @@ export declare type AutocompleteRenderState = {
25
25
  /**
26
26
  * The resolved hits from the index matching the query.
27
27
  */
28
- hits: Hits;
28
+ hits: Hit[];
29
29
  /**
30
30
  * The full results object from the Algolia API.
31
31
  */
@@ -50,8 +50,13 @@ export declare type HitsPerPageRenderState = {
50
50
  refine: (value: number) => void;
51
51
  /**
52
52
  * Indicates whether or not the search has results.
53
+ * @deprecated Use `canRefine` instead.
53
54
  */
54
55
  hasNoResults: boolean;
56
+ /**
57
+ * Indicates if search state can be refined.
58
+ */
59
+ canRefine: boolean;
55
60
  };
56
61
  export declare type HitsPerPageWidgetDescription = {
57
62
  $$type: 'ais.hitsPerPage';
@@ -119,6 +119,7 @@ var connectHitsPerPage = function connectHitsPerPage(renderFn) {
119
119
  results = _ref5.results,
120
120
  createURL = _ref5.createURL,
121
121
  helper = _ref5.helper;
122
+ var canRefine = results ? results.nbHits > 0 : false;
122
123
  return {
123
124
  items: transformItems(normalizeItems(state), {
124
125
  results: results
@@ -128,7 +129,8 @@ var connectHitsPerPage = function connectHitsPerPage(renderFn) {
128
129
  state: state,
129
130
  createURL: createURL
130
131
  }),
131
- hasNoResults: results ? results.nbHits === 0 : true,
132
+ hasNoResults: !canRefine,
133
+ canRefine: canRefine,
132
134
  widgetParams: widgetParams
133
135
  };
134
136
  },
@@ -56,8 +56,16 @@ export declare type NumericMenuRenderState = {
56
56
  createURL: CreateURL<NumericMenuRenderStateItem['value']>;
57
57
  /**
58
58
  * `true` if the last search contains no result
59
+ * @deprecated Use `canRefine` instead.
59
60
  */
60
61
  hasNoResults: boolean;
62
+ /**
63
+ * Indicates if search state can be refined.
64
+ *
65
+ * This is `true` if the last search contains no result and
66
+ * "All" range is selected
67
+ */
68
+ canRefine: boolean;
61
69
  /**
62
70
  * Sets the selected value and trigger a new search
63
71
  */
@@ -1,3 +1,5 @@
1
+ function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e2) { throw _e2; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e3) { didErr = true; err = _e3; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
2
+
1
3
  function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
2
4
 
3
5
  function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
@@ -177,12 +179,35 @@ var connectNumericMenu = function connectNumericMenu(renderFn) {
177
179
  });
178
180
  }
179
181
 
182
+ var hasNoResults = results ? results.nbHits === 0 : true;
183
+ var preparedItems = prepareItems(state);
184
+ var allIsSelected = true;
185
+
186
+ var _iterator = _createForOfIteratorHelper(preparedItems),
187
+ _step;
188
+
189
+ try {
190
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
191
+ var item = _step.value;
192
+
193
+ if (item.isRefined && decodeURI(item.value) !== '{}') {
194
+ allIsSelected = false;
195
+ break;
196
+ }
197
+ }
198
+ } catch (err) {
199
+ _iterator.e(err);
200
+ } finally {
201
+ _iterator.f();
202
+ }
203
+
180
204
  return {
181
205
  createURL: connectorState.createURL(state),
182
- items: transformItems(prepareItems(state), {
206
+ items: transformItems(preparedItems, {
183
207
  results: results
184
208
  }),
185
- hasNoResults: results ? results.nbHits === 0 : true,
209
+ hasNoResults: hasNoResults,
210
+ canRefine: !(hasNoResults && allIsSelected),
186
211
  refine: connectorState.refine,
187
212
  sendEvent: connectorState.sendEvent,
188
213
  widgetParams: widgetParams
@@ -56,6 +56,8 @@ export declare type RatingMenuRenderState = {
56
56
  refine: (value: string) => void;
57
57
  /**
58
58
  * `true` if the last search contains no result.
59
+ *
60
+ * @deprecated Use `canRefine` instead.
59
61
  */
60
62
  hasNoResults: boolean;
61
63
  /**
@@ -210,8 +210,11 @@ var connectRatingMenu = function connectRatingMenu(renderFn) {
210
210
  });
211
211
  }
212
212
 
213
- if (results) {
214
- var facetResults = results.getFacetValues(attribute, {});
213
+ var refinementIsApplied = false;
214
+ var totalCount = 0;
215
+ var facetResults = results === null || results === void 0 ? void 0 : results.getFacetValues(attribute, {});
216
+
217
+ if (results && facetResults) {
215
218
  var maxValuesPerFacet = facetResults.length;
216
219
  var maxDecimalPlaces = getFacetsMaxDecimalPlaces(facetResults);
217
220
  var maxFacets = Math.pow(10, maxDecimalPlaces) * max;
@@ -225,6 +228,7 @@ var connectRatingMenu = function connectRatingMenu(renderFn) {
225
228
 
226
229
  var _loop = function _loop(star) {
227
230
  var isRefined = refinedStar === star;
231
+ refinementIsApplied = refinementIsApplied || isRefined;
228
232
  var count = facetResults.filter(function (f) {
229
233
  return Number(f.name) >= star && Number(f.name) <= max;
230
234
  }).map(function (f) {
@@ -232,6 +236,7 @@ var connectRatingMenu = function connectRatingMenu(renderFn) {
232
236
  }).reduce(function (sum, current) {
233
237
  return sum + current;
234
238
  }, 0);
239
+ totalCount += count;
235
240
 
236
241
  if (refinedStar && !isRefined && count === 0) {
237
242
  // skip count==0 when at least 1 refinement is enabled
@@ -261,10 +266,11 @@ var connectRatingMenu = function connectRatingMenu(renderFn) {
261
266
  }
262
267
 
263
268
  facetValues = facetValues.reverse();
269
+ var hasNoResults = results ? results.nbHits === 0 : true;
264
270
  return {
265
271
  items: facetValues,
266
- hasNoResults: results ? results.nbHits === 0 : true,
267
- canRefine: facetValues.length > 0,
272
+ hasNoResults: hasNoResults,
273
+ canRefine: (!hasNoResults || refinementIsApplied) && totalCount > 0,
268
274
  refine: connectorState.toggleRefinementFactory(helper),
269
275
  sendEvent: sendEvent,
270
276
  createURL: connectorState.createURLFactory({
@@ -43,8 +43,13 @@ export declare type SortByRenderState = {
43
43
  refine: (value: string) => void;
44
44
  /**
45
45
  * `true` if the last search contains no result.
46
+ * @deprecated Use `canRefine` instead.
46
47
  */
47
48
  hasNoResults: boolean;
49
+ /**
50
+ * `true` if we can refine.
51
+ */
52
+ canRefine: boolean;
48
53
  };
49
54
  export declare type SortByWidgetDescription = {
50
55
  $$type: 'ais.sortBy';
@@ -77,13 +77,15 @@ var connectSortBy = function connectSortBy(renderFn) {
77
77
  };
78
78
  }
79
79
 
80
+ var hasNoResults = results ? results.nbHits === 0 : true;
80
81
  return {
81
82
  currentRefinement: state.index,
82
83
  options: transformItems(items, {
83
84
  results: results
84
85
  }),
85
86
  refine: connectorState.setIndex,
86
- hasNoResults: results ? results.nbHits === 0 : true,
87
+ hasNoResults: hasNoResults,
88
+ canRefine: !hasNoResults && items.length > 0,
87
89
  widgetParams: widgetParams
88
90
  };
89
91
  },
@@ -5,11 +5,12 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
5
5
  function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
6
6
 
7
7
  import { highlight as _highlight, reverseHighlight as _reverseHighlight, snippet as _snippet, reverseSnippet as _reverseSnippet, insights as _insights } from "../helpers/index.js";
8
+ import { formatNumber as _formatNumber } from "./formatNumber.js";
8
9
  export default function hoganHelpers(_ref) {
9
10
  var numberLocale = _ref.numberLocale;
10
11
  return {
11
12
  formatNumber: function formatNumber(value, render) {
12
- return Number(render(value)).toLocaleString(numberLocale);
13
+ return _formatNumber(Number(render(value)), numberLocale);
13
14
  },
14
15
  highlight: function highlight(options, render) {
15
16
  try {
@@ -0,0 +1 @@
1
+ export declare function formatNumber(value: number, numberLocale?: string): string;
@@ -0,0 +1,3 @@
1
+ export function formatNumber(value, numberLocale) {
2
+ return value.toLocaleString(numberLocale);
3
+ }
@@ -1,9 +1,9 @@
1
1
  import type { SearchResults } from 'algoliasearch-helper';
2
- import type { Hits, InsightsClientMethod, InsightsClientPayload, Connector } from '../../types';
2
+ import type { Hit, InsightsClientMethod, InsightsClientPayload, Connector } from '../../types';
3
3
  export declare const inferPayload: ({ method, results, hits, objectIDs, }: {
4
4
  method: InsightsClientMethod;
5
5
  results: SearchResults;
6
- hits: Hits;
6
+ hits: Hit[];
7
7
  objectIDs: string[];
8
8
  }) => Omit<InsightsClientPayload, 'eventName'>;
9
9
  /**
@@ -1,11 +1,11 @@
1
1
  /**
2
2
  * @jest-environment jsdom
3
3
  */
4
- import type { InstantSearch, Hit, Hits } from '../../types';
5
- declare type BuiltInSendEventForHits = (eventType: string, hits: Hit | Hits, eventName?: string) => void;
4
+ import type { InstantSearch, Hit } from '../../types';
5
+ declare type BuiltInSendEventForHits = (eventType: string, hits: Hit | Hit[], eventName?: string) => void;
6
6
  declare type CustomSendEventForHits = (customPayload: any) => void;
7
7
  export declare type SendEventForHits = BuiltInSendEventForHits & CustomSendEventForHits;
8
- declare type BuiltInBindEventForHits = (eventType: string, hits: Hit | Hits, eventName?: string) => string;
8
+ declare type BuiltInBindEventForHits = (eventType: string, hits: Hit | Hit[], eventName?: string) => string;
9
9
  declare type CustomBindEventForHits = (customPayload: any) => string;
10
10
  export declare type BindEventForHits = BuiltInBindEventForHits & CustomBindEventForHits;
11
11
  export declare function createSendEventForHits({ instantSearchInstance, index, widgetType, }: {
@@ -0,0 +1 @@
1
+ export declare function cx(cssClasses?: string | string[] | undefined): string;
@@ -0,0 +1,3 @@
1
+ export function cx(cssClasses) {
2
+ return Array.isArray(cssClasses) ? cssClasses.filter(Boolean).join(' ') : cssClasses || '';
3
+ }
@@ -45,3 +45,4 @@ export { debounce } from './debounce';
45
45
  export { serializePayload, deserializePayload } from './serializer';
46
46
  export { getWidgetAttribute } from './getWidgetAttribute';
47
47
  export { safelyRunOnBrowser } from './safelyRunOnBrowser';
48
+ export { cx } from './cx';
@@ -44,4 +44,5 @@ export { createConcurrentSafePromise } from "./createConcurrentSafePromise.js";
44
44
  export { debounce } from "./debounce.js";
45
45
  export { serializePayload, deserializePayload } from "./serializer.js";
46
46
  export { getWidgetAttribute } from "./getWidgetAttribute.js";
47
- export { safelyRunOnBrowser } from "./safelyRunOnBrowser.js";
47
+ export { safelyRunOnBrowser } from "./safelyRunOnBrowser.js";
48
+ export { cx } from "./cx.js";
@@ -1,12 +1,13 @@
1
1
  import type { HoganOptions } from 'hogan.js';
2
2
  import type { Templates, HoganHelpers } from '../../types';
3
- import type { BindEventForHits } from './createSendEventForHits';
4
- declare function renderTemplate({ templates, templateKey, compileOptions, helpers, data, bindEvent, }: {
3
+ import type { BindEventForHits, SendEventForHits } from './createSendEventForHits';
4
+ declare function renderTemplate({ templates, templateKey, compileOptions, helpers, data, bindEvent, sendEvent, }: {
5
5
  templates: Templates;
6
6
  templateKey: string;
7
7
  compileOptions?: HoganOptions;
8
8
  helpers?: HoganHelpers;
9
9
  data?: Record<string, any>;
10
10
  bindEvent?: BindEventForHits;
11
- }): string;
11
+ sendEvent?: SendEventForHits;
12
+ }): string | import("preact").VNode<{}> | import("preact").VNode<{}>[];
12
13
  export default renderTemplate;
@@ -7,6 +7,8 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
7
7
  function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
8
8
 
9
9
  import hogan from 'hogan.js';
10
+ import { Highlight, ReverseHighlight, ReverseSnippet, Snippet } from "../../helpers/components/index.js";
11
+ import { html } from 'htm/preact';
10
12
 
11
13
  // We add all our template helper methods to the template as lambdas. Note
12
14
  // that lambdas in Mustache are supposed to accept a second argument of
@@ -37,7 +39,8 @@ function renderTemplate(_ref) {
37
39
  compileOptions = _ref.compileOptions,
38
40
  helpers = _ref.helpers,
39
41
  data = _ref.data,
40
- bindEvent = _ref.bindEvent;
42
+ bindEvent = _ref.bindEvent,
43
+ sendEvent = _ref.sendEvent;
41
44
  var template = templates[templateKey];
42
45
 
43
46
  if (typeof template !== 'string' && typeof template !== 'function') {
@@ -45,7 +48,17 @@ function renderTemplate(_ref) {
45
48
  }
46
49
 
47
50
  if (typeof template === 'function') {
48
- return template(data, bindEvent);
51
+ // @MAJOR no longer pass bindEvent when string templates are removed
52
+ var params = bindEvent || {};
53
+ params.html = html;
54
+ params.sendEvent = sendEvent;
55
+ params.components = {
56
+ Highlight: Highlight,
57
+ ReverseHighlight: ReverseHighlight,
58
+ Snippet: Snippet,
59
+ ReverseSnippet: ReverseSnippet
60
+ };
61
+ return template(data, params);
49
62
  }
50
63
 
51
64
  var transformedHelpers = transformHelpersToHogan(helpers, compileOptions, data);
@@ -1,2 +1,2 @@
1
- declare const _default: "4.44.1";
1
+ declare const _default: "4.46.0";
2
2
  export default _default;
package/es/lib/version.js CHANGED
@@ -1 +1 @@
1
- export default '4.44.1';
1
+ export default '4.46.0';
@@ -1,7 +1,7 @@
1
1
  import type { SearchResults } from 'algoliasearch-helper';
2
2
  import type { InstantSearch } from './instantsearch';
3
3
  import type { InsightsClient } from './insights';
4
- import type { Hits } from './results';
4
+ import type { Hit } from './results';
5
5
  import type { UnknownWidgetParams, Widget, WidgetDescription } from './widget';
6
6
  /**
7
7
  * The base renderer options. All render functions receive
@@ -25,7 +25,7 @@ export declare type RendererOptions<TWidgetParams> = {
25
25
  * The mutable list of hits. The may change depending
26
26
  * of the given transform items function.
27
27
  */
28
- hits?: Hits;
28
+ hits?: Hit[];
29
29
  /**
30
30
  * The current insights client, if any.
31
31
  */
@@ -1,6 +1,19 @@
1
- import type { BindEventForHits } from '../lib/utils';
2
- export declare type Template<TTemplateData = void> = string | ((data: TTemplateData) => string);
3
- export declare type TemplateWithBindEvent<TTemplateData = void> = string | ((data: TTemplateData, bindEvent: BindEventForHits) => string);
1
+ import type { VNode } from 'preact';
2
+ import type { Highlight, ReverseHighlight, ReverseSnippet, Snippet } from '../helpers/components';
3
+ import type { html } from 'htm/preact';
4
+ import type { BindEventForHits, SendEventForHits } from '../lib/utils';
5
+ export declare type Template<TTemplateData = void> = string | ((data: TTemplateData, params: TemplateParams) => VNode | VNode[] | string);
6
+ export declare type TemplateParams = BindEventForHits & {
7
+ html: typeof html;
8
+ components: {
9
+ Highlight: typeof Highlight;
10
+ ReverseHighlight: typeof ReverseHighlight;
11
+ Snippet: typeof Snippet;
12
+ ReverseSnippet: typeof ReverseSnippet;
13
+ };
14
+ sendEvent?: SendEventForHits;
15
+ };
16
+ export declare type TemplateWithBindEvent<TTemplateData = void> = string | ((data: TTemplateData, params: TemplateParams) => VNode | VNode[] | string);
4
17
  export declare type Templates = {
5
18
  [key: string]: Template<any> | TemplateWithBindEvent<any> | undefined;
6
19
  };
@@ -1,6 +1,10 @@
1
1
  var defaultTemplates = {
2
- header: '',
3
- loader: '',
2
+ header: function header() {
3
+ return '';
4
+ },
5
+ loader: function loader() {
6
+ return '';
7
+ },
4
8
  item: function item(_item) {
5
9
  return JSON.stringify(_item);
6
10
  }
@@ -1,5 +1,9 @@
1
1
  var defaultTemplates = {
2
- home: 'Home',
3
- separator: '>'
2
+ home: function home() {
3
+ return 'Home';
4
+ },
5
+ separator: function separator() {
6
+ return '>';
7
+ }
4
8
  };
5
9
  export default defaultTemplates;
@@ -19,7 +19,9 @@ export declare type ClearRefinementsTemplates = Partial<{
19
19
  /**
20
20
  * Template for the content of the button
21
21
  */
22
- resetLabel: Template;
22
+ resetLabel: Template<{
23
+ hasRefinements: boolean;
24
+ }>;
23
25
  }>;
24
26
  export declare type ClearRefinementsWidgetParams = {
25
27
  /**
@@ -24,7 +24,7 @@ var renderer = function renderer(_ref) {
24
24
  templates = _ref.templates;
25
25
  return function (_ref2, isFirstRendering) {
26
26
  var refine = _ref2.refine,
27
- hasRefinements = _ref2.hasRefinements,
27
+ canRefine = _ref2.canRefine,
28
28
  instantSearchInstance = _ref2.instantSearchInstance;
29
29
 
30
30
  if (isFirstRendering) {
@@ -39,7 +39,7 @@ var renderer = function renderer(_ref) {
39
39
  render(h(ClearRefinements, {
40
40
  refine: refine,
41
41
  cssClasses: cssClasses,
42
- hasRefinements: hasRefinements,
42
+ hasRefinements: canRefine,
43
43
  templateProps: renderState.templateProps
44
44
  }), containerNode);
45
45
  };
@@ -1,4 +1,6 @@
1
1
  var defaultTemplates = {
2
- resetLabel: 'Clear refinements'
2
+ resetLabel: function resetLabel() {
3
+ return 'Clear refinements';
4
+ }
3
5
  };
4
6
  export default defaultTemplates;