instantsearch.js 4.68.1 → 4.69.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 (56) hide show
  1. package/cjs/connectors/frequently-bought-together/connectFrequentlyBoughtTogether.js +93 -0
  2. package/cjs/connectors/index.js +28 -0
  3. package/cjs/connectors/looking-similar/connectLookingSimilar.js +94 -0
  4. package/cjs/connectors/related-products/connectRelatedProducts.js +94 -0
  5. package/cjs/connectors/trending-items/connectTrendingItems.js +90 -0
  6. package/cjs/lib/InstantSearch.js +9 -1
  7. package/cjs/lib/utils/addWidgetId.js +13 -0
  8. package/cjs/lib/utils/render-args.js +3 -3
  9. package/cjs/lib/version.js +1 -1
  10. package/cjs/widgets/frequently-bought-together/frequently-bought-together.js +120 -0
  11. package/cjs/widgets/index/index.js +81 -19
  12. package/cjs/widgets/index.js +28 -0
  13. package/cjs/widgets/looking-similar/looking-similar.js +122 -0
  14. package/cjs/widgets/related-products/related-products.js +122 -0
  15. package/cjs/widgets/trending-items/trending-items.js +126 -0
  16. package/dist/instantsearch.development.d.ts +403 -10
  17. package/dist/instantsearch.development.js +1678 -273
  18. package/dist/instantsearch.development.js.map +1 -1
  19. package/dist/instantsearch.production.d.ts +403 -10
  20. package/dist/instantsearch.production.min.d.ts +403 -10
  21. package/dist/instantsearch.production.min.js +2 -2
  22. package/dist/instantsearch.production.min.js.map +1 -1
  23. package/es/connectors/frequently-bought-together/connectFrequentlyBoughtTogether.d.ts +45 -0
  24. package/es/connectors/frequently-bought-together/connectFrequentlyBoughtTogether.js +86 -0
  25. package/es/connectors/index.d.ts +4 -0
  26. package/es/connectors/index.js +5 -1
  27. package/es/connectors/looking-similar/connectLookingSimilar.d.ts +49 -0
  28. package/es/connectors/looking-similar/connectLookingSimilar.js +87 -0
  29. package/es/connectors/related-products/connectRelatedProducts.d.ts +49 -0
  30. package/es/connectors/related-products/connectRelatedProducts.js +87 -0
  31. package/es/connectors/trending-items/connectTrendingItems.d.ts +57 -0
  32. package/es/connectors/trending-items/connectTrendingItems.js +83 -0
  33. package/es/lib/InstantSearch.d.ts +2 -0
  34. package/es/lib/InstantSearch.js +9 -1
  35. package/es/lib/templating/renderTemplate.d.ts +1 -1
  36. package/es/lib/utils/addWidgetId.d.ts +2 -0
  37. package/es/lib/utils/addWidgetId.js +7 -0
  38. package/es/lib/utils/render-args.d.ts +3 -3
  39. package/es/lib/utils/render-args.js +3 -3
  40. package/es/lib/version.d.ts +1 -1
  41. package/es/lib/version.js +1 -1
  42. package/es/types/templates.d.ts +1 -1
  43. package/es/types/widget.d.ts +16 -9
  44. package/es/widgets/frequently-bought-together/frequently-bought-together.d.ts +41 -0
  45. package/es/widgets/frequently-bought-together/frequently-bought-together.js +112 -0
  46. package/es/widgets/index/index.d.ts +2 -1
  47. package/es/widgets/index/index.js +81 -19
  48. package/es/widgets/index.d.ts +4 -0
  49. package/es/widgets/index.js +5 -1
  50. package/es/widgets/looking-similar/looking-similar.d.ts +41 -0
  51. package/es/widgets/looking-similar/looking-similar.js +114 -0
  52. package/es/widgets/related-products/related-products.d.ts +41 -0
  53. package/es/widgets/related-products/related-products.js +114 -0
  54. package/es/widgets/trending-items/trending-items.d.ts +41 -0
  55. package/es/widgets/trending-items/trending-items.js +118 -0
  56. package/package.json +7 -7
@@ -1,4 +1,4 @@
1
- import type { InstantSearch, UiState } from '../../types';
1
+ import type { InstantSearch, UiState, Widget } from '../../types';
2
2
  import type { IndexWidget } from '../../widgets/index/index';
3
3
  export declare function createInitArgs(instantSearchInstance: InstantSearch, parent: IndexWidget, uiState: UiState): {
4
4
  uiState: UiState;
@@ -126,11 +126,11 @@ export declare function createInitArgs(instantSearchInstance: InstantSearch, par
126
126
  status: import("../InstantSearch").InstantSearchStatus;
127
127
  error: Error | undefined;
128
128
  };
129
- export declare function createRenderArgs(instantSearchInstance: InstantSearch, parent: IndexWidget): {
129
+ export declare function createRenderArgs(instantSearchInstance: InstantSearch, parent: IndexWidget, widget: IndexWidget | Widget): {
130
130
  helper: import("algoliasearch-helper").AlgoliaSearchHelper;
131
131
  parent: IndexWidget;
132
132
  instantSearchInstance: InstantSearch<UiState, UiState>;
133
- results: import("algoliasearch-helper").SearchResults<any>;
133
+ results: import("algoliasearch-helper").SearchResults<any> | import("algoliasearch-helper").RecommendResultItem;
134
134
  scopedResults: import("../../types").ScopedResult[];
135
135
  state: import("algoliasearch-helper").SearchParameters;
136
136
  renderState: import("../../types").RenderState;
@@ -17,8 +17,8 @@ export function createInitArgs(instantSearchInstance, parent, uiState) {
17
17
  error: instantSearchInstance.error
18
18
  };
19
19
  }
20
- export function createRenderArgs(instantSearchInstance, parent) {
21
- var results = parent.getResults();
20
+ export function createRenderArgs(instantSearchInstance, parent, widget) {
21
+ var results = parent.getResultsForWidget(widget);
22
22
  var helper = parent.getHelper();
23
23
  return {
24
24
  helper: helper,
@@ -26,7 +26,7 @@ export function createRenderArgs(instantSearchInstance, parent) {
26
26
  instantSearchInstance: instantSearchInstance,
27
27
  results: results,
28
28
  scopedResults: parent.getScopedResults(),
29
- state: results ? results._state : helper.state,
29
+ state: results && '_state' in results ? results._state : helper.state,
30
30
  renderState: instantSearchInstance.renderState,
31
31
  templatesConfig: instantSearchInstance.templatesConfig,
32
32
  createURL: parent.createURL,
@@ -1,2 +1,2 @@
1
- declare const _default: "4.68.1";
1
+ declare const _default: "4.69.0";
2
2
  export default _default;
package/es/lib/version.js CHANGED
@@ -1 +1 @@
1
- export default '4.68.1';
1
+ export default '4.69.0';
@@ -2,7 +2,7 @@ import type { Highlight, ReverseHighlight, ReverseSnippet, Snippet } from '../he
2
2
  import type { BuiltInBindEventForHits, CustomBindEventForHits, SendEventForHits } from '../lib/utils';
3
3
  import type { html } from 'htm/preact';
4
4
  import type { VNode } from 'preact';
5
- export type Template<TTemplateData = void> = string | ((data: TTemplateData, params: TemplateParams) => VNode | VNode[] | string);
5
+ export type Template<TTemplateData = void> = string | ((data: TTemplateData, params: TemplateParams) => VNode | VNode[] | string | null);
6
6
  export type TemplateParams = {
7
7
  html: typeof html;
8
8
  components: {
@@ -3,7 +3,7 @@ import type { InstantSearch } from './instantsearch';
3
3
  import type { IndexRenderState, WidgetRenderState } from './render-state';
4
4
  import type { IndexUiState, UiState } from './ui-state';
5
5
  import type { Expand, RequiredKeys } from './utils';
6
- import type { AlgoliaSearchHelper as Helper, SearchParameters, SearchResults, RecommendParameters } from 'algoliasearch-helper';
6
+ import type { AlgoliaSearchHelper as Helper, SearchParameters, SearchResults, RecommendParameters, RecommendResultItem } from 'algoliasearch-helper';
7
7
  export type ScopedResult = {
8
8
  indexId: string;
9
9
  results: SearchResults;
@@ -39,10 +39,11 @@ export type RenderOptions = SharedRenderOptions & {
39
39
  export type DisposeOptions = {
40
40
  helper: Helper;
41
41
  state: SearchParameters;
42
+ recommendState: RecommendParameters;
42
43
  parent: IndexWidget;
43
44
  };
44
- export type BuiltinTypes = 'ais.analytics' | 'ais.answers' | 'ais.autocomplete' | 'ais.breadcrumb' | 'ais.clearRefinements' | 'ais.configure' | 'ais.configureRelatedItems' | 'ais.currentRefinements' | 'ais.dynamicWidgets' | 'ais.geoSearch' | 'ais.hierarchicalMenu' | 'ais.hits' | 'ais.hitsPerPage' | 'ais.index' | 'ais.infiniteHits' | 'ais.menu' | 'ais.numericMenu' | 'ais.pagination' | 'ais.places' | 'ais.poweredBy' | 'ais.queryRules' | 'ais.range' | 'ais.rangeSlider' | 'ais.rangeInput' | 'ais.ratingMenu' | 'ais.refinementList' | 'ais.searchBox' | 'ais.relevantSort' | 'ais.sortBy' | 'ais.stats' | 'ais.toggleRefinement' | 'ais.voiceSearch';
45
- export type BuiltinWidgetTypes = 'ais.analytics' | 'ais.answers' | 'ais.autocomplete' | 'ais.breadcrumb' | 'ais.clearRefinements' | 'ais.configure' | 'ais.configureRelatedItems' | 'ais.currentRefinements' | 'ais.dynamicWidgets' | 'ais.geoSearch' | 'ais.hierarchicalMenu' | 'ais.hits' | 'ais.hitsPerPage' | 'ais.index' | 'ais.infiniteHits' | 'ais.menu' | 'ais.menuSelect' | 'ais.numericMenu' | 'ais.pagination' | 'ais.places' | 'ais.poweredBy' | 'ais.queryRuleCustomData' | 'ais.queryRuleContext' | 'ais.rangeInput' | 'ais.rangeSlider' | 'ais.ratingMenu' | 'ais.refinementList' | 'ais.searchBox' | 'ais.relevantSort' | 'ais.sortBy' | 'ais.stats' | 'ais.toggleRefinement' | 'ais.voiceSearch';
45
+ export type BuiltinTypes = 'ais.analytics' | 'ais.answers' | 'ais.autocomplete' | 'ais.breadcrumb' | 'ais.clearRefinements' | 'ais.configure' | 'ais.configureRelatedItems' | 'ais.currentRefinements' | 'ais.dynamicWidgets' | 'ais.frequentlyBoughtTogether' | 'ais.geoSearch' | 'ais.hierarchicalMenu' | 'ais.hits' | 'ais.hitsPerPage' | 'ais.index' | 'ais.infiniteHits' | 'ais.lookingSimilar' | 'ais.menu' | 'ais.numericMenu' | 'ais.pagination' | 'ais.places' | 'ais.poweredBy' | 'ais.queryRules' | 'ais.range' | 'ais.rangeSlider' | 'ais.rangeInput' | 'ais.ratingMenu' | 'ais.refinementList' | 'ais.relatedProducts' | 'ais.searchBox' | 'ais.relevantSort' | 'ais.sortBy' | 'ais.stats' | 'ais.toggleRefinement' | 'ais.trendingItems' | 'ais.voiceSearch';
46
+ export type BuiltinWidgetTypes = 'ais.analytics' | 'ais.answers' | 'ais.autocomplete' | 'ais.breadcrumb' | 'ais.clearRefinements' | 'ais.configure' | 'ais.configureRelatedItems' | 'ais.currentRefinements' | 'ais.dynamicWidgets' | 'ais.frequentlyBoughtTogether' | 'ais.geoSearch' | 'ais.hierarchicalMenu' | 'ais.hits' | 'ais.hitsPerPage' | 'ais.index' | 'ais.infiniteHits' | 'ais.lookingSimilar' | 'ais.menu' | 'ais.menuSelect' | 'ais.numericMenu' | 'ais.pagination' | 'ais.places' | 'ais.poweredBy' | 'ais.queryRuleCustomData' | 'ais.queryRuleContext' | 'ais.rangeInput' | 'ais.rangeSlider' | 'ais.ratingMenu' | 'ais.refinementList' | 'ais.relatedProducts' | 'ais.searchBox' | 'ais.relevantSort' | 'ais.sortBy' | 'ais.stats' | 'ais.toggleRefinement' | 'ais.trendingItems' | 'ais.voiceSearch';
46
47
  export type UnknownWidgetParams = NonNullable<object>;
47
48
  export type WidgetParams = {
48
49
  widgetParams?: UnknownWidgetParams;
@@ -54,17 +55,23 @@ export type WidgetDescription = {
54
55
  indexRenderState?: Record<string, unknown>;
55
56
  indexUiState?: Record<string, unknown>;
56
57
  };
57
- type SearchWidgetLifeCycle<TWidgetDescription extends WidgetDescription> = {
58
+ type SearchWidget<TWidgetDescription extends WidgetDescription> = {
58
59
  dependsOn?: 'search';
59
60
  getWidgetParameters?: (state: SearchParameters, widgetParametersOptions: {
60
61
  uiState: Expand<Partial<TWidgetDescription['indexUiState'] & IndexUiState>>;
61
62
  }) => SearchParameters;
62
63
  };
63
- type RecommendWidgetLifeCycle<TWidgetDescription extends WidgetDescription> = {
64
- dependsOn?: 'recommend';
64
+ type RecommendRenderOptions = SharedRenderOptions & {
65
+ results: RecommendResultItem;
66
+ };
67
+ type RecommendWidget<TWidgetDescription extends WidgetDescription & WidgetParams> = {
68
+ dependsOn: 'recommend';
69
+ $$id?: number;
65
70
  getWidgetParameters: (state: RecommendParameters, widgetParametersOptions: {
66
71
  uiState: Expand<Partial<TWidgetDescription['indexUiState'] & IndexUiState>>;
67
72
  }) => RecommendParameters;
73
+ getRenderState: (renderState: Expand<IndexRenderState & Partial<TWidgetDescription['indexRenderState']>>, renderOptions: InitOptions | RecommendRenderOptions) => IndexRenderState & TWidgetDescription['indexRenderState'];
74
+ getWidgetRenderState: (renderOptions: InitOptions | RecommendRenderOptions) => Expand<WidgetRenderState<TWidgetDescription['renderState'], TWidgetDescription['widgetParams']>>;
68
75
  };
69
76
  type RequiredWidgetLifeCycle<TWidgetDescription extends WidgetDescription> = {
70
77
  /**
@@ -87,7 +94,7 @@ type RequiredWidgetLifeCycle<TWidgetDescription extends WidgetDescription> = {
87
94
  * Called when this widget is unmounted. Used to remove refinements set by
88
95
  * during this widget's initialization and life time.
89
96
  */
90
- dispose?: (options: DisposeOptions) => SearchParameters | void;
97
+ dispose?: (options: DisposeOptions) => SearchParameters | RecommendParameters | void;
91
98
  };
92
99
  type RequiredWidgetType<TWidgetDescription extends WidgetDescription> = {
93
100
  /**
@@ -135,7 +142,7 @@ type RequiredUiStateLifeCycle<TWidgetDescription extends WidgetDescription> = {
135
142
  getWidgetSearchParameters: (state: SearchParameters, widgetSearchParametersOptions: {
136
143
  uiState: Expand<Partial<TWidgetDescription['indexUiState'] & IndexUiState>>;
137
144
  }) => SearchParameters;
138
- } & (SearchWidgetLifeCycle<TWidgetDescription> | RecommendWidgetLifeCycle<TWidgetDescription>);
145
+ };
139
146
  type UiStateLifeCycle<TWidgetDescription extends WidgetDescription> = TWidgetDescription extends RequiredKeys<WidgetDescription, 'indexUiState'> ? RequiredUiStateLifeCycle<TWidgetDescription> : Partial<RequiredUiStateLifeCycle<TWidgetDescription>>;
140
147
  type RequiredRenderStateLifeCycle<TWidgetDescription extends WidgetDescription & WidgetParams> = {
141
148
  /**
@@ -151,7 +158,7 @@ type RequiredRenderStateLifeCycle<TWidgetDescription extends WidgetDescription &
151
158
  type RenderStateLifeCycle<TWidgetDescription extends WidgetDescription & WidgetParams> = TWidgetDescription extends RequiredKeys<WidgetDescription, 'renderState' | 'indexRenderState'> & WidgetParams ? RequiredRenderStateLifeCycle<TWidgetDescription> : Partial<RequiredRenderStateLifeCycle<TWidgetDescription>>;
152
159
  export type Widget<TWidgetDescription extends WidgetDescription & WidgetParams = {
153
160
  $$type: string;
154
- }> = Expand<RequiredWidgetLifeCycle<TWidgetDescription> & WidgetType<TWidgetDescription> & UiStateLifeCycle<TWidgetDescription> & RenderStateLifeCycle<TWidgetDescription>>;
161
+ }> = Expand<RequiredWidgetLifeCycle<TWidgetDescription> & WidgetType<TWidgetDescription> & UiStateLifeCycle<TWidgetDescription> & RenderStateLifeCycle<TWidgetDescription>> & (SearchWidget<TWidgetDescription> | RecommendWidget<TWidgetDescription>);
155
162
  export type TransformItemsMetadata = {
156
163
  results?: SearchResults;
157
164
  };
@@ -0,0 +1,41 @@
1
+
2
+ import type { FrequentlyBoughtTogetherWidgetDescription, FrequentlyBoughtTogetherConnectorParams } from '../../connectors/frequently-bought-together/connectFrequentlyBoughtTogether';
3
+ import type { Template, WidgetFactory, Hit } from '../../types';
4
+ import type { RecommendResultItem } from 'algoliasearch-helper';
5
+ import type { RecommendClassNames, FrequentlyBoughtTogetherProps as FrequentlyBoughtTogetherUiProps } from 'instantsearch-ui-components';
6
+ export type FrequentlyBoughtTogetherCSSClasses = Partial<RecommendClassNames>;
7
+ export type FrequentlyBoughtTogetherTemplates = Partial<{
8
+ /**
9
+ * Template to use when there are no results.
10
+ */
11
+ empty: Template<RecommendResultItem>;
12
+ /**
13
+ * Template to use for the header of the widget.
14
+ */
15
+ header: Template<Pick<Parameters<NonNullable<FrequentlyBoughtTogetherUiProps<Hit>['headerComponent']>>[0], 'items'> & {
16
+ cssClasses: RecommendClassNames;
17
+ }>;
18
+ /**
19
+ * Template to use for each result. This template will receive an object containing a single record.
20
+ */
21
+ item: Template<Hit>;
22
+ }>;
23
+ type FrequentlyBoughtTogetherWidgetParams = {
24
+ /**
25
+ * CSS Selector or HTMLElement to insert the widget.
26
+ */
27
+ container: string | HTMLElement;
28
+ /**
29
+ * Templates to use for the widget.
30
+ */
31
+ templates?: FrequentlyBoughtTogetherTemplates;
32
+ /**
33
+ * CSS classes to add.
34
+ */
35
+ cssClasses?: FrequentlyBoughtTogetherCSSClasses;
36
+ };
37
+ export type FrequentlyBoughtTogetherWidget = WidgetFactory<FrequentlyBoughtTogetherWidgetDescription & {
38
+ $$widgetType: 'ais.frequentlyBoughtTogether';
39
+ }, FrequentlyBoughtTogetherConnectorParams, FrequentlyBoughtTogetherWidgetParams>;
40
+ declare const frequentlyBoughtTogether: FrequentlyBoughtTogetherWidget;
41
+ export default frequentlyBoughtTogether;
@@ -0,0 +1,112 @@
1
+ function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
2
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
3
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
4
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
5
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); }
6
+ function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
7
+ function _extends() { _extends = Object.assign ? Object.assign.bind() : 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); }
8
+ import { createFrequentlyBoughtTogetherComponent } from 'instantsearch-ui-components';
9
+ import { Fragment, h, render } from 'preact';
10
+ import TemplateComponent from "../../components/Template/Template.js";
11
+ import connectFrequentlyBoughtTogether from "../../connectors/frequently-bought-together/connectFrequentlyBoughtTogether.js";
12
+ import { prepareTemplateProps } from "../../lib/templating/index.js";
13
+ import { getContainerNode, createDocumentationMessageGenerator } from "../../lib/utils/index.js";
14
+ var withUsage = createDocumentationMessageGenerator({
15
+ name: 'frequently-bought-together'
16
+ });
17
+ var FrequentlyBoughtTogether = createFrequentlyBoughtTogetherComponent({
18
+ createElement: h,
19
+ Fragment: Fragment
20
+ });
21
+ var renderer = function renderer(_ref) {
22
+ var renderState = _ref.renderState,
23
+ cssClasses = _ref.cssClasses,
24
+ containerNode = _ref.containerNode,
25
+ templates = _ref.templates;
26
+ return function (_ref2, isFirstRendering) {
27
+ var items = _ref2.items,
28
+ results = _ref2.results,
29
+ instantSearchInstance = _ref2.instantSearchInstance;
30
+ if (isFirstRendering) {
31
+ renderState.templateProps = prepareTemplateProps({
32
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
33
+ defaultTemplates: {},
34
+ templatesConfig: instantSearchInstance.templatesConfig,
35
+ templates: templates
36
+ });
37
+ return;
38
+ }
39
+ var headerComponent = templates.header ? function (data) {
40
+ return h(TemplateComponent, _extends({}, renderState.templateProps, {
41
+ templateKey: "header",
42
+ rootTagName: "fragment",
43
+ data: {
44
+ cssClasses: data.classNames,
45
+ items: data.items
46
+ }
47
+ }));
48
+ } : undefined;
49
+ var itemComponent = templates.item ? function (_ref3) {
50
+ var item = _ref3.item;
51
+ return h(TemplateComponent, _extends({}, renderState.templateProps, {
52
+ templateKey: "item",
53
+ rootTagName: "fragment",
54
+ data: item
55
+ }));
56
+ } : undefined;
57
+ var emptyComponent = templates.empty ? function () {
58
+ return h(TemplateComponent, _extends({}, renderState.templateProps, {
59
+ templateKey: "empty",
60
+ rootTagName: "fragment",
61
+ data: results
62
+ }));
63
+ } : undefined;
64
+ render(h(FrequentlyBoughtTogether, {
65
+ items: items,
66
+ headerComponent: headerComponent,
67
+ itemComponent: itemComponent,
68
+ sendEvent: function sendEvent() {},
69
+ classNames: cssClasses,
70
+ emptyComponent: emptyComponent,
71
+ status: instantSearchInstance.status
72
+ }), containerNode);
73
+ };
74
+ };
75
+ var frequentlyBoughtTogether = function frequentlyBoughtTogether(widgetParams) {
76
+ var _ref4 = widgetParams || {},
77
+ container = _ref4.container,
78
+ objectIDs = _ref4.objectIDs,
79
+ limit = _ref4.limit,
80
+ queryParameters = _ref4.queryParameters,
81
+ threshold = _ref4.threshold,
82
+ escapeHTML = _ref4.escapeHTML,
83
+ transformItems = _ref4.transformItems,
84
+ _ref4$templates = _ref4.templates,
85
+ templates = _ref4$templates === void 0 ? {} : _ref4$templates,
86
+ _ref4$cssClasses = _ref4.cssClasses,
87
+ cssClasses = _ref4$cssClasses === void 0 ? {} : _ref4$cssClasses;
88
+ if (!container) {
89
+ throw new Error(withUsage('The `container` option is required.'));
90
+ }
91
+ var containerNode = getContainerNode(container);
92
+ var specializedRenderer = renderer({
93
+ containerNode: containerNode,
94
+ cssClasses: cssClasses,
95
+ renderState: {},
96
+ templates: templates
97
+ });
98
+ var makeWidget = connectFrequentlyBoughtTogether(specializedRenderer, function () {
99
+ return render(null, containerNode);
100
+ });
101
+ return _objectSpread(_objectSpread({}, makeWidget({
102
+ objectIDs: objectIDs,
103
+ limit: limit,
104
+ queryParameters: queryParameters,
105
+ threshold: threshold,
106
+ escapeHTML: escapeHTML,
107
+ transformItems: transformItems
108
+ })), {}, {
109
+ $$widgetType: 'ais.frequentlyBoughtTogether'
110
+ });
111
+ };
112
+ export default frequentlyBoughtTogether;
@@ -1,5 +1,5 @@
1
1
  import type { InstantSearch, UiState, IndexUiState, Widget, ScopedResult } from '../../types';
2
- import type { AlgoliaSearchHelper as Helper, SearchParameters, SearchResults } from 'algoliasearch-helper';
2
+ import type { AlgoliaSearchHelper as Helper, SearchParameters, SearchResults, RecommendResultItem } from 'algoliasearch-helper';
3
3
  export type IndexWidgetParams = {
4
4
  indexName: string;
5
5
  indexId?: string;
@@ -23,6 +23,7 @@ export type IndexWidget<TUiState extends UiState = UiState> = Omit<Widget<IndexW
23
23
  getIndexId: () => string;
24
24
  getHelper: () => Helper | null;
25
25
  getResults: () => SearchResults | null;
26
+ getResultsForWidget: (widget: IndexWidget | Widget) => SearchResults | RecommendResultItem | null;
26
27
  getPreviousState: () => SearchParameters | null;
27
28
  getScopedResults: () => ScopedResult[];
28
29
  getParent: () => IndexWidget | null;
@@ -16,6 +16,7 @@ function _objectWithoutProperties(source, excluded) { if (source == null) return
16
16
  function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
17
17
  import algoliasearchHelper from 'algoliasearch-helper';
18
18
  import { checkIndexUiState, createDocumentationMessageGenerator, resolveSearchParameters, mergeSearchParameters, warning, isIndexWidget, createInitArgs, createRenderArgs } from "../../lib/utils/index.js";
19
+ import { addWidgetId } from "../../lib/utils/addWidgetId.js";
19
20
  var withUsage = createDocumentationMessageGenerator({
20
21
  name: 'index-widget'
21
22
  });
@@ -123,6 +124,8 @@ var index = function index(widgetParams) {
123
124
  var helper = null;
124
125
  var derivedHelper = null;
125
126
  var lastValidSearchParameters = null;
127
+ var hasRecommendWidget = false;
128
+ var hasSearchWidget = false;
126
129
  return {
127
130
  $$type: 'ais.index',
128
131
  $$widgetType: 'ais.index',
@@ -147,6 +150,16 @@ var index = function index(widgetParams) {
147
150
  derivedHelper.lastResults._state = helper.state;
148
151
  return derivedHelper.lastResults;
149
152
  },
153
+ getResultsForWidget: function getResultsForWidget(widget) {
154
+ var _helper;
155
+ if (widget.dependsOn !== 'recommend' || isIndexWidget(widget) || widget.$$id === undefined) {
156
+ return this.getResults();
157
+ }
158
+ if (!((_helper = helper) !== null && _helper !== void 0 && _helper.lastRecommendResults)) {
159
+ return null;
160
+ }
161
+ return helper.lastRecommendResults[widget.$$id];
162
+ },
150
163
  getPreviousState: function getPreviousState() {
151
164
  return lastValidSearchParameters;
152
165
  },
@@ -191,6 +204,21 @@ var index = function index(widgetParams) {
191
204
  })) {
192
205
  throw new Error(withUsage('The widget definition expects a `render` and/or an `init` method.'));
193
206
  }
207
+ widgets.forEach(function (widget) {
208
+ if (isIndexWidget(widget)) {
209
+ return;
210
+ }
211
+ if (localInstantSearchInstance && widget.dependsOn === 'recommend') {
212
+ localInstantSearchInstance._hasRecommendWidget = true;
213
+ } else if (localInstantSearchInstance) {
214
+ localInstantSearchInstance._hasSearchWidget = true;
215
+ } else if (widget.dependsOn === 'recommend') {
216
+ hasRecommendWidget = true;
217
+ } else {
218
+ hasSearchWidget = true;
219
+ }
220
+ addWidgetId(widget);
221
+ });
194
222
  localWidgets = localWidgets.concat(widgets);
195
223
  if (localInstantSearchInstance && Boolean(widgets.length)) {
196
224
  privateHelperSetState(helper, {
@@ -240,16 +268,41 @@ var index = function index(widgetParams) {
240
268
  localWidgets = localWidgets.filter(function (widget) {
241
269
  return widgets.indexOf(widget) === -1;
242
270
  });
271
+ localWidgets.forEach(function (widget) {
272
+ if (isIndexWidget(widget)) {
273
+ return;
274
+ }
275
+ if (localInstantSearchInstance && widget.dependsOn === 'recommend') {
276
+ localInstantSearchInstance._hasRecommendWidget = true;
277
+ } else if (localInstantSearchInstance) {
278
+ localInstantSearchInstance._hasSearchWidget = true;
279
+ } else if (widget.dependsOn === 'recommend') {
280
+ hasRecommendWidget = true;
281
+ } else {
282
+ hasSearchWidget = true;
283
+ }
284
+ });
243
285
  if (localInstantSearchInstance && Boolean(widgets.length)) {
244
- var cleanedState = widgets.reduce(function (state, widget) {
245
- // the `dispose` method exists at this point we already assert it
246
- var next = widget.dispose({
247
- helper: helper,
248
- state: state,
249
- parent: _this2
250
- });
251
- return next || state;
252
- }, helper.state);
286
+ var _widgets$reduce = widgets.reduce(function (states, widget) {
287
+ // the `dispose` method exists at this point we already assert it
288
+ var next = widget.dispose({
289
+ helper: helper,
290
+ state: states.cleanedSearchState,
291
+ recommendState: states.cleanedRecommendState,
292
+ parent: _this2
293
+ });
294
+ if (next instanceof algoliasearchHelper.RecommendParameters) {
295
+ states.cleanedRecommendState = next;
296
+ } else if (next) {
297
+ states.cleanedSearchState = next;
298
+ }
299
+ return states;
300
+ }, {
301
+ cleanedSearchState: helper.state,
302
+ cleanedRecommendState: helper.recommendState
303
+ }),
304
+ cleanedSearchState = _widgets$reduce.cleanedSearchState,
305
+ cleanedRecommendState = _widgets$reduce.cleanedRecommendState;
253
306
  var newState = localInstantSearchInstance.future.preserveSharedStateOnUnmount ? getLocalWidgetsSearchParameters(localWidgets, {
254
307
  uiState: localUiState,
255
308
  initialSearchParameters: new algoliasearchHelper.SearchParameters({
@@ -257,16 +310,17 @@ var index = function index(widgetParams) {
257
310
  })
258
311
  }) : getLocalWidgetsSearchParameters(localWidgets, {
259
312
  uiState: getLocalWidgetsUiState(localWidgets, {
260
- searchParameters: cleanedState,
313
+ searchParameters: cleanedSearchState,
261
314
  helper: helper
262
315
  }),
263
- initialSearchParameters: cleanedState
316
+ initialSearchParameters: cleanedSearchState
264
317
  });
265
318
  localUiState = getLocalWidgetsUiState(localWidgets, {
266
319
  searchParameters: newState,
267
320
  helper: helper
268
321
  });
269
322
  helper.setState(newState);
323
+ helper.recommendState = cleanedRecommendState;
270
324
  if (localWidgets.length) {
271
325
  localInstantSearchInstance.scheduleSearch();
272
326
  }
@@ -452,9 +506,16 @@ var index = function index(widgetParams) {
452
506
  // schedule a render that will render the results injected on the helper.
453
507
  instantSearchInstance.scheduleRender();
454
508
  }
509
+ if (hasRecommendWidget) {
510
+ instantSearchInstance._hasRecommendWidget = true;
511
+ }
512
+ if (hasSearchWidget) {
513
+ instantSearchInstance._hasSearchWidget = true;
514
+ }
455
515
  },
456
516
  render: function render(_ref6) {
457
- var _this4 = this;
517
+ var _derivedHelper2,
518
+ _this4 = this;
458
519
  var instantSearchInstance = _ref6.instantSearchInstance;
459
520
  // we can't attach a listener to the error event of search, as the error
460
521
  // then would no longer be thrown for global handlers.
@@ -464,7 +525,7 @@ var index = function index(widgetParams) {
464
525
 
465
526
  // We only render index widgets if there are no results.
466
527
  // This makes sure `render` is never called with `results` being `null`.
467
- var widgetsToRender = this.getResults() ? localWidgets : localWidgets.filter(isIndexWidget);
528
+ var widgetsToRender = this.getResults() || (_derivedHelper2 = derivedHelper) !== null && _derivedHelper2 !== void 0 && _derivedHelper2.lastRecommendResults ? localWidgets : localWidgets.filter(isIndexWidget);
468
529
  widgetsToRender = widgetsToRender.filter(function (widget) {
469
530
  if (!widget.shouldRender) {
470
531
  return true;
@@ -475,7 +536,7 @@ var index = function index(widgetParams) {
475
536
  });
476
537
  widgetsToRender.forEach(function (widget) {
477
538
  if (widget.getRenderState) {
478
- var renderState = widget.getRenderState(instantSearchInstance.renderState[_this4.getIndexId()] || {}, createRenderArgs(instantSearchInstance, _this4));
539
+ var renderState = widget.getRenderState(instantSearchInstance.renderState[_this4.getIndexId()] || {}, createRenderArgs(instantSearchInstance, _this4, widget));
479
540
  storeRenderState({
480
541
  renderState: renderState,
481
542
  instantSearchInstance: instantSearchInstance,
@@ -492,14 +553,14 @@ var index = function index(widgetParams) {
492
553
  // not have results yet.
493
554
 
494
555
  if (widget.render) {
495
- widget.render(createRenderArgs(instantSearchInstance, _this4));
556
+ widget.render(createRenderArgs(instantSearchInstance, _this4, widget));
496
557
  }
497
558
  });
498
559
  },
499
560
  dispose: function dispose() {
500
561
  var _this5 = this,
501
- _helper,
502
- _derivedHelper2;
562
+ _helper2,
563
+ _derivedHelper3;
503
564
  localWidgets.forEach(function (widget) {
504
565
  if (widget.dispose && helper) {
505
566
  // The dispose function is always called once the instance is started
@@ -511,15 +572,16 @@ var index = function index(widgetParams) {
511
572
  widget.dispose({
512
573
  helper: helper,
513
574
  state: helper.state,
575
+ recommendState: helper.recommendState,
514
576
  parent: _this5
515
577
  });
516
578
  }
517
579
  });
518
580
  localInstantSearchInstance = null;
519
581
  localParent = null;
520
- (_helper = helper) === null || _helper === void 0 ? void 0 : _helper.removeAllListeners();
582
+ (_helper2 = helper) === null || _helper2 === void 0 ? void 0 : _helper2.removeAllListeners();
521
583
  helper = null;
522
- (_derivedHelper2 = derivedHelper) === null || _derivedHelper2 === void 0 ? void 0 : _derivedHelper2.detach();
584
+ (_derivedHelper3 = derivedHelper) === null || _derivedHelper3 === void 0 ? void 0 : _derivedHelper3.detach();
523
585
  derivedHelper = null;
524
586
  },
525
587
  getWidgetUiState: function getWidgetUiState(uiState) {
@@ -25,6 +25,7 @@ export { default as places } from './places/places';
25
25
  export { default as poweredBy } from './powered-by/powered-by';
26
26
  export { default as queryRuleContext } from './query-rule-context/query-rule-context';
27
27
  export { default as queryRuleCustomData } from './query-rule-custom-data/query-rule-custom-data';
28
+ export { default as relatedProducts } from './related-products/related-products';
28
29
  export { default as rangeInput } from './range-input/range-input';
29
30
  export { default as rangeSlider } from './range-slider/range-slider';
30
31
  export { default as ratingMenu } from './rating-menu/rating-menu';
@@ -34,4 +35,7 @@ export { default as searchBox } from './search-box/search-box';
34
35
  export { default as sortBy } from './sort-by/sort-by';
35
36
  export { default as stats } from './stats/stats';
36
37
  export { default as toggleRefinement } from './toggle-refinement/toggle-refinement';
38
+ export { default as trendingItems } from './trending-items/trending-items';
37
39
  export { default as voiceSearch } from './voice-search/voice-search';
40
+ export { default as frequentlyBoughtTogether } from './frequently-bought-together/frequently-bought-together';
41
+ export { default as lookingSimilar } from './looking-similar/looking-similar';
@@ -29,6 +29,7 @@ export { default as places } from "./places/places.js";
29
29
  export { default as poweredBy } from "./powered-by/powered-by.js";
30
30
  export { default as queryRuleContext } from "./query-rule-context/query-rule-context.js";
31
31
  export { default as queryRuleCustomData } from "./query-rule-custom-data/query-rule-custom-data.js";
32
+ export { default as relatedProducts } from "./related-products/related-products.js";
32
33
  export { default as rangeInput } from "./range-input/range-input.js";
33
34
  export { default as rangeSlider } from "./range-slider/range-slider.js";
34
35
  export { default as ratingMenu } from "./rating-menu/rating-menu.js";
@@ -38,4 +39,7 @@ export { default as searchBox } from "./search-box/search-box.js";
38
39
  export { default as sortBy } from "./sort-by/sort-by.js";
39
40
  export { default as stats } from "./stats/stats.js";
40
41
  export { default as toggleRefinement } from "./toggle-refinement/toggle-refinement.js";
41
- export { default as voiceSearch } from "./voice-search/voice-search.js";
42
+ export { default as trendingItems } from "./trending-items/trending-items.js";
43
+ export { default as voiceSearch } from "./voice-search/voice-search.js";
44
+ export { default as frequentlyBoughtTogether } from "./frequently-bought-together/frequently-bought-together.js";
45
+ export { default as lookingSimilar } from "./looking-similar/looking-similar.js";
@@ -0,0 +1,41 @@
1
+
2
+ import type { LookingSimilarWidgetDescription, LookingSimilarConnectorParams } from '../../connectors/looking-similar/connectLookingSimilar';
3
+ import type { Template, WidgetFactory, Hit } from '../../types';
4
+ import type { RecommendResultItem } from 'algoliasearch-helper';
5
+ import type { RecommendClassNames, LookingSimilarProps as LookingSimilarUiProps } from 'instantsearch-ui-components';
6
+ export type LookingSimilarCSSClasses = Partial<RecommendClassNames>;
7
+ export type LookingSimilarTemplates = Partial<{
8
+ /**
9
+ * Template to use when there are no results.
10
+ */
11
+ empty: Template<RecommendResultItem>;
12
+ /**
13
+ * Template to use for the header of the widget.
14
+ */
15
+ header: Template<Pick<Parameters<NonNullable<LookingSimilarUiProps<Hit>['headerComponent']>>[0], 'items'> & {
16
+ cssClasses: RecommendClassNames;
17
+ }>;
18
+ /**
19
+ * Template to use for each result. This template will receive an object containing a single record.
20
+ */
21
+ item: Template<Hit>;
22
+ }>;
23
+ type LookingSimilarWidgetParams = {
24
+ /**
25
+ * CSS Selector or HTMLElement to insert the widget.
26
+ */
27
+ container: string | HTMLElement;
28
+ /**
29
+ * Templates to use for the widget.
30
+ */
31
+ templates?: LookingSimilarTemplates;
32
+ /**
33
+ * CSS classes to add.
34
+ */
35
+ cssClasses?: LookingSimilarCSSClasses;
36
+ };
37
+ export type LookingSimilarWidget = WidgetFactory<LookingSimilarWidgetDescription & {
38
+ $$widgetType: 'ais.lookingSimilar';
39
+ }, LookingSimilarConnectorParams, LookingSimilarWidgetParams>;
40
+ declare const lookingSimilar: LookingSimilarWidget;
41
+ export default lookingSimilar;