instantsearch.js 4.82.0 → 4.84.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.
@@ -3,7 +3,7 @@ import { Chat } from '../../lib/chat';
3
3
  import type { AbstractChat, ChatInit as ChatInitAi, UIMessage } from '../../lib/chat';
4
4
  import type { SendEventForHits } from '../../lib/utils';
5
5
  import type { Connector, Renderer, Unmounter, UnknownWidgetParams, IndexUiState, IndexWidget } from '../../types';
6
- import type { UserClientSideTool } from 'instantsearch-ui-components';
6
+ import type { UserClientSideTool, ClientSideTools } from 'instantsearch-ui-components';
7
7
  export type ChatRenderState<TUiMessage extends UIMessage = UIMessage> = {
8
8
  indexUiState: IndexUiState;
9
9
  input: string;
@@ -34,9 +34,9 @@ export type ChatRenderState<TUiMessage extends UIMessage = UIMessage> = {
34
34
  */
35
35
  onClearTransitionEnd: () => void;
36
36
  /**
37
- * Tools configuration passed to the connector.
37
+ * Tools configuration with addToolResult bound, ready to be used by the UI.
38
38
  */
39
- tools: Record<string, Omit<UserClientSideTool, 'layoutComponent'>>;
39
+ tools: ClientSideTools;
40
40
  } & Pick<AbstractChat<TUiMessage>, 'addToolResult' | 'clearError' | 'error' | 'id' | 'messages' | 'regenerate' | 'resumeStream' | 'sendMessage' | 'status' | 'stop'>;
41
41
  export type ChatInitWithoutTransport<TUiMessage extends UIMessage> = Omit<ChatInitAi<TUiMessage>, 'transport'>;
42
42
  export type ChatTransport = {
@@ -389,7 +389,7 @@ declare const _default: <TWidgetParams extends UnknownWidgetParams>(renderFn: Re
389
389
  isClearing: boolean;
390
390
  clearMessages: () => void;
391
391
  onClearTransitionEnd: () => void;
392
- tools: Record<string, Omit<UserClientSideTool, "layoutComponent">>;
392
+ tools: ClientSideTools;
393
393
  widgetParams: TWidgetParams & ChatConnectorParams<TUiMessage>;
394
394
  addToolResult: <TOOL extends keyof (TUiMessage extends UIMessage<unknown, import("ai").UIDataTypes, infer TOOLS extends import("ai").UITools> ? TOOLS : import("ai").UITools)>({ tool, toolCallId, output, }: {
395
395
  tool: TOOL;
@@ -174,6 +174,16 @@ export default (function connectChat(renderFn) {
174
174
  widgetType: this.$$type
175
175
  });
176
176
  }
177
+ var toolsWithAddToolResult = {};
178
+ Object.entries(tools).forEach(function (_ref4) {
179
+ var _ref5 = _slicedToArray(_ref4, 2),
180
+ key = _ref5[0],
181
+ tool = _ref5[1];
182
+ var toolWithAddToolResult = _objectSpread(_objectSpread({}, tool), {}, {
183
+ addToolResult: _chatInstance.addToolResult
184
+ });
185
+ toolsWithAddToolResult[key] = toolWithAddToolResult;
186
+ });
177
187
  return {
178
188
  indexUiState: instantSearchInstance.getUiState()[parent.getIndexId()],
179
189
  input: input,
@@ -186,7 +196,7 @@ export default (function connectChat(renderFn) {
186
196
  isClearing: isClearing,
187
197
  clearMessages: clearMessages,
188
198
  onClearTransitionEnd: onClearTransitionEnd,
189
- tools: tools,
199
+ tools: toolsWithAddToolResult,
190
200
  widgetParams: widgetParams,
191
201
  // Chat instance render state
192
202
  addToolResult: _chatInstance.addToolResult,
@@ -1,2 +1,2 @@
1
- declare const _default: "4.82.0";
1
+ declare const _default: "4.84.0";
2
2
  export default _default;
package/es/lib/version.js CHANGED
@@ -1 +1 @@
1
- export default '4.82.0';
1
+ export default '4.84.0';
@@ -1,9 +1,19 @@
1
1
 
2
- import type { AutocompleteConnectorParams, AutocompleteWidgetDescription } from '../../connectors/autocomplete/connectAutocomplete';
2
+ import type { AutocompleteConnectorParams, AutocompleteRenderState, AutocompleteWidgetDescription } from '../../connectors/autocomplete/connectAutocomplete';
3
3
  import type { BaseHit, IndexUiState, IndexWidget, Template, WidgetFactory } from '../../types';
4
+ import type { PlainSearchParameters } from 'algoliasearch-helper';
4
5
  import type { AutocompleteClassNames, AutocompleteIndexClassNames, AutocompleteIndexConfig } from 'instantsearch-ui-components';
5
6
  export type AutocompleteCSSClasses = Partial<AutocompleteClassNames>;
6
- export type AutocompleteTemplates<TItem extends BaseHit> = Partial<Record<string, TItem>>;
7
+ export type AutocompleteSearchParameters = Omit<PlainSearchParameters, 'index'>;
8
+ export type AutocompleteTemplates = {
9
+ /**
10
+ * Template to use for the panel.
11
+ */
12
+ panel?: Template<{
13
+ elements: PanelElements;
14
+ indices: AutocompleteRenderState['indices'];
15
+ }>;
16
+ };
7
17
  type IndexConfig<TItem extends BaseHit> = AutocompleteIndexConfig<TItem> & {
8
18
  templates?: Partial<{
9
19
  /**
@@ -20,8 +30,13 @@ type IndexConfig<TItem extends BaseHit> = AutocompleteIndexConfig<TItem> & {
20
30
  onSelect: () => void;
21
31
  }>;
22
32
  }>;
33
+ /**
34
+ * Search parameters to apply to this index.
35
+ */
36
+ searchParameters?: AutocompleteSearchParameters;
23
37
  cssClasses?: Partial<AutocompleteIndexClassNames>;
24
38
  };
39
+ type PanelElements = Partial<Record<'recent' | 'suggestions' | (string & {}), preact.JSX.Element>>;
25
40
  type AutocompleteWidgetParams<TItem extends BaseHit> = {
26
41
  /**
27
42
  * CSS Selector or HTMLElement to insert the widget.
@@ -37,12 +52,34 @@ type AutocompleteWidgetParams<TItem extends BaseHit> = {
37
52
  showSuggestions?: Partial<Pick<IndexConfig<{
38
53
  query: string;
39
54
  }>, 'indexName' | 'getURL' | 'templates' | 'cssClasses'>>;
55
+ showRecent?: boolean | {
56
+ /**
57
+ * Storage key to use in the local storage.
58
+ */
59
+ storageKey?: string;
60
+ templates?: Partial<{
61
+ /**
62
+ * Template to use for each result. This template will receive an object containing a single record.
63
+ */
64
+ item: Template<{
65
+ item: {
66
+ query: string;
67
+ };
68
+ onSelect: () => void;
69
+ onRemoveRecentSearch: () => void;
70
+ }>;
71
+ }>;
72
+ };
73
+ /**
74
+ * Search parameters to apply to the autocomplete indices.
75
+ */
76
+ searchParameters?: AutocompleteSearchParameters;
40
77
  getSearchPageURL?: (nextUiState: IndexUiState) => string;
41
78
  onSelect?: AutocompleteIndexConfig<TItem>['onSelect'];
42
79
  /**
43
80
  * Templates to use for the widget.
44
81
  */
45
- templates?: AutocompleteTemplates<TItem>;
82
+ templates?: AutocompleteTemplates;
46
83
  /**
47
84
  * CSS classes to add.
48
85
  */
@@ -1,4 +1,3 @@
1
- function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
2
1
  var _excluded = ["instanceId", "containerNode"];
3
2
  function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }
4
3
  function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
@@ -6,6 +5,7 @@ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r)
6
5
  function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
7
6
  function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); }
8
7
  function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
8
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
9
9
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
10
10
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
11
11
  function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
@@ -14,11 +14,12 @@ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e
14
14
  function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
15
15
  function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
16
16
  function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
17
- import { createAutocompleteComponent, createAutocompleteIndexComponent, createAutocompletePanelComponent, createAutocompletePropGetters, createAutocompleteSearchComponent, createAutocompleteSuggestionComponent, cx } from 'instantsearch-ui-components';
17
+ import { createAutocompleteComponent, createAutocompleteIndexComponent, createAutocompletePanelComponent, createAutocompletePropGetters, createAutocompleteRecentSearchComponent, createAutocompleteSearchComponent, createAutocompleteStorage, createAutocompleteSuggestionComponent, cx } from 'instantsearch-ui-components';
18
18
  import { Fragment, h, render } from 'preact';
19
19
  import { useEffect, useId, useMemo, useRef, useState } from 'preact/hooks';
20
20
  import TemplateComponent from "../../components/Template/Template.js";
21
21
  import { connectAutocomplete, connectSearchBox } from "../../connectors/index.umd.js";
22
+ import { ReverseHighlight } from "../../helpers/components/index.js";
22
23
  import { component } from "../../lib/suit.js";
23
24
  import { prepareTemplateProps } from "../../lib/templating/index.js";
24
25
  import { createDocumentationMessageGenerator, getContainerNode, walkIndex } from "../../lib/utils/index.js";
@@ -49,6 +50,10 @@ var AutocompleteSearchBox = createAutocompleteSearchComponent({
49
50
  createElement: h,
50
51
  Fragment: Fragment
51
52
  });
53
+ var AutocompleteRecentSearch = createAutocompleteRecentSearchComponent({
54
+ createElement: h,
55
+ Fragment: Fragment
56
+ });
52
57
  var usePropGetters = createAutocompletePropGetters({
53
58
  useEffect: useEffect,
54
59
  useId: useId,
@@ -56,12 +61,18 @@ var usePropGetters = createAutocompletePropGetters({
56
61
  useRef: useRef,
57
62
  useState: useState
58
63
  });
64
+ var useStorage = createAutocompleteStorage({
65
+ useEffect: useEffect,
66
+ useState: useState,
67
+ useMemo: useMemo
68
+ });
59
69
  var createRenderer = function createRenderer(params) {
60
70
  var instanceId = params.instanceId,
61
71
  containerNode = params.containerNode,
62
72
  rendererParams = _objectWithoutProperties(params, _excluded);
63
73
  return function (connectorParams, isFirstRendering) {
64
74
  if (isFirstRendering) {
75
+ var _targetIndex$getHelpe, _targetIndex$getHelpe2;
65
76
  var isolatedIndex = connectorParams.instantSearchInstance.mainIndex;
66
77
  var targetIndex = connectorParams.instantSearchInstance.mainIndex;
67
78
  walkIndex(targetIndex, function (childIndex) {
@@ -73,15 +84,21 @@ var createRenderer = function createRenderer(params) {
73
84
  rendererParams.renderState = {
74
85
  indexTemplateProps: [],
75
86
  isolatedIndex: isolatedIndex,
76
- targetIndex: targetIndex
87
+ targetIndex: targetIndex,
88
+ templateProps: prepareTemplateProps({
89
+ defaultTemplates: {},
90
+ templatesConfig: connectorParams.instantSearchInstance.templatesConfig,
91
+ templates: rendererParams.templates
92
+ })
77
93
  };
94
+ connectorParams.refine((_targetIndex$getHelpe = (_targetIndex$getHelpe2 = targetIndex.getHelper()) === null || _targetIndex$getHelpe2 === void 0 ? void 0 : _targetIndex$getHelpe2.state.query) !== null && _targetIndex$getHelpe !== void 0 ? _targetIndex$getHelpe : '');
78
95
  return;
79
96
  }
80
97
  render(h(AutocompleteWrapper, _extends({}, rendererParams, connectorParams)), containerNode);
81
98
  };
82
99
  };
83
100
  function AutocompleteWrapper(_ref) {
84
- var _targetIndex$getWidge, _isolatedIndex$getHel;
101
+ var _isolatedIndex$getHel, _targetIndex$getWidge, _showRecent$templates;
85
102
  var indicesConfig = _ref.indicesConfig,
86
103
  indices = _ref.indices,
87
104
  getSearchPageURL = _ref.getSearchPageURL,
@@ -89,9 +106,23 @@ function AutocompleteWrapper(_ref) {
89
106
  refine = _ref.refine,
90
107
  cssClasses = _ref.cssClasses,
91
108
  renderState = _ref.renderState,
92
- instantSearchInstance = _ref.instantSearchInstance;
109
+ instantSearchInstance = _ref.instantSearchInstance,
110
+ showRecent = _ref.showRecent,
111
+ showSuggestions = _ref.showSuggestions,
112
+ templates = _ref.templates;
93
113
  var isolatedIndex = renderState.isolatedIndex,
94
114
  targetIndex = renderState.targetIndex;
115
+ var searchboxQuery = isolatedIndex === null || isolatedIndex === void 0 ? void 0 : (_isolatedIndex$getHel = isolatedIndex.getHelper()) === null || _isolatedIndex$getHel === void 0 ? void 0 : _isolatedIndex$getHel.state.query;
116
+ var _useStorage = useStorage({
117
+ query: searchboxQuery,
118
+ showRecent: showRecent,
119
+ indices: indices,
120
+ indicesConfig: indicesConfig
121
+ }),
122
+ storage = _useStorage.storage,
123
+ storageHits = _useStorage.storageHits,
124
+ indicesConfigForPropGetters = _useStorage.indicesConfigForPropGetters,
125
+ indicesForPropGetters = _useStorage.indicesForPropGetters;
95
126
  var isSearchPage = (_targetIndex$getWidge = targetIndex === null || targetIndex === void 0 ? void 0 : targetIndex.getWidgets().some(function (_ref2) {
96
127
  var $$type = _ref2.$$type;
97
128
  return ['ais.hits', 'ais.infiniteHits'].includes($$type);
@@ -105,10 +136,11 @@ function AutocompleteWrapper(_ref) {
105
136
  query: query
106
137
  }), _objectSpread2));
107
138
  });
139
+ query.length > 0 && storage.onAdd(query);
108
140
  };
109
141
  var _usePropGetters = usePropGetters({
110
- indices: indices,
111
- indicesConfig: indicesConfig,
142
+ indices: indicesForPropGetters,
143
+ indicesConfig: indicesConfigForPropGetters,
112
144
  onRefine: onRefine,
113
145
  onSelect: userOnSelect !== null && userOnSelect !== void 0 ? userOnSelect : function (_ref3) {
114
146
  var query = _ref3.query,
@@ -132,25 +164,69 @@ function AutocompleteWrapper(_ref) {
132
164
  getItemProps = _usePropGetters.getItemProps,
133
165
  getPanelProps = _usePropGetters.getPanelProps,
134
166
  getRootProps = _usePropGetters.getRootProps;
135
- var query = isolatedIndex === null || isolatedIndex === void 0 ? void 0 : (_isolatedIndex$getHel = isolatedIndex.getHelper()) === null || _isolatedIndex$getHel === void 0 ? void 0 : _isolatedIndex$getHel.state.query;
136
- return h(Autocomplete, _extends({}, getRootProps(), {
137
- classNames: cssClasses
138
- }), h(AutocompleteSearchBox, {
139
- query: query || '',
140
- inputProps: _objectSpread(_objectSpread({}, getInputProps()), {}, {
141
- // @ts-ignore - This clashes with some ambient React JSX declarations.
142
- onInput: function onInput(evt) {
143
- return refine(evt.currentTarget.value);
144
- }
145
- }),
146
- onClear: function onClear() {
147
- return onRefine('');
148
- },
149
- isSearchStalled: instantSearchInstance.status === 'stalled'
150
- }), h(AutocompletePanel, getPanelProps(), indices.map(function (_ref4, i) {
167
+ var AutocompleteRecentSearchComponent = function AutocompleteRecentSearchComponent(_ref4) {
168
+ var item = _ref4.item,
169
+ onSelect = _ref4.onSelect,
170
+ onRemoveRecentSearch = _ref4.onRemoveRecentSearch;
171
+ return h(AutocompleteRecentSearch, {
172
+ item: item,
173
+ onSelect: onSelect,
174
+ onRemoveRecentSearch: onRemoveRecentSearch
175
+ }, h(ConditionalReverseHighlight, {
176
+ item: item
177
+ }));
178
+ };
179
+ if (_typeof(showRecent) === 'object' && (_showRecent$templates = showRecent.templates) !== null && _showRecent$templates !== void 0 && _showRecent$templates.item) {
180
+ var props = prepareTemplateProps({
181
+ defaultTemplates: {},
182
+ templatesConfig: instantSearchInstance.templatesConfig,
183
+ templates: showRecent.templates
184
+ });
185
+ AutocompleteRecentSearchComponent = function AutocompleteRecentSearchComponent(_ref5) {
186
+ var item = _ref5.item,
187
+ onSelect = _ref5.onSelect,
188
+ onRemoveRecentSearch = _ref5.onRemoveRecentSearch;
189
+ return h(TemplateComponent, _extends({}, props, {
190
+ templateKey: "item",
191
+ rootTagName: "fragment",
192
+ data: {
193
+ item: item,
194
+ onSelect: onSelect,
195
+ onRemoveRecentSearch: onRemoveRecentSearch
196
+ }
197
+ }));
198
+ };
199
+ }
200
+ var elements = {};
201
+ if (showRecent) {
202
+ elements.recent = h(AutocompleteIndex
203
+ // @ts-ignore - there seems to be problems with React.ComponentType and this, but it's actually correct
204
+ , {
205
+ ItemComponent: function ItemComponent(_ref6) {
206
+ var item = _ref6.item,
207
+ onSelect = _ref6.onSelect;
208
+ return h(AutocompleteRecentSearchComponent, {
209
+ item: item,
210
+ onSelect: onSelect,
211
+ onRemoveRecentSearch: function onRemoveRecentSearch() {
212
+ return storage.onRemove(item.query);
213
+ }
214
+ });
215
+ },
216
+ classNames: {
217
+ root: 'ais-AutocompleteRecentSearches',
218
+ list: 'ais-AutocompleteRecentSearchesList',
219
+ item: 'ais-AutocompleteRecentSearchesItem'
220
+ },
221
+ items: storageHits,
222
+ getItemProps: getItemProps
223
+ });
224
+ }
225
+ indices.forEach(function (_ref7, i) {
151
226
  var _indicesConfig$i$temp;
152
- var indexId = _ref4.indexId,
153
- hits = _ref4.hits;
227
+ var indexId = _ref7.indexId,
228
+ indexName = _ref7.indexName,
229
+ hits = _ref7.hits;
154
230
  if (!renderState.indexTemplateProps[i]) {
155
231
  renderState.indexTemplateProps[i] = prepareTemplateProps({
156
232
  defaultTemplates: {},
@@ -158,8 +234,8 @@ function AutocompleteWrapper(_ref) {
158
234
  templates: indicesConfig[i].templates
159
235
  });
160
236
  }
161
- var headerComponent = (_indicesConfig$i$temp = indicesConfig[i].templates) !== null && _indicesConfig$i$temp !== void 0 && _indicesConfig$i$temp.header ? function (_ref5) {
162
- var items = _ref5.items;
237
+ var headerComponent = (_indicesConfig$i$temp = indicesConfig[i].templates) !== null && _indicesConfig$i$temp !== void 0 && _indicesConfig$i$temp.header ? function (_ref8) {
238
+ var items = _ref8.items;
163
239
  return h(TemplateComponent, _extends({}, renderState.indexTemplateProps[i], {
164
240
  templateKey: "header",
165
241
  rootTagName: "fragment",
@@ -168,9 +244,9 @@ function AutocompleteWrapper(_ref) {
168
244
  }
169
245
  }));
170
246
  } : undefined;
171
- var itemComponent = function itemComponent(_ref6) {
172
- var item = _ref6.item,
173
- onSelect = _ref6.onSelect;
247
+ var itemComponent = function itemComponent(_ref9) {
248
+ var item = _ref9.item,
249
+ onSelect = _ref9.onSelect;
174
250
  return h(TemplateComponent, _extends({}, renderState.indexTemplateProps[i], {
175
251
  templateKey: "item",
176
252
  rootTagName: "fragment",
@@ -180,7 +256,8 @@ function AutocompleteWrapper(_ref) {
180
256
  }
181
257
  }));
182
258
  };
183
- return h(AutocompleteIndex, {
259
+ var elementId = indexName === (showSuggestions === null || showSuggestions === void 0 ? void 0 : showSuggestions.indexName) ? 'suggestions' : indexName;
260
+ elements[elementId] = h(AutocompleteIndex, {
184
261
  key: indexId,
185
262
  HeaderComponent: headerComponent,
186
263
  ItemComponent: itemComponent,
@@ -192,25 +269,54 @@ function AutocompleteWrapper(_ref) {
192
269
  getItemProps: getItemProps,
193
270
  classNames: indicesConfig[i].cssClasses
194
271
  });
272
+ });
273
+ return h(Autocomplete, _extends({}, getRootProps(), {
274
+ classNames: cssClasses
275
+ }), h(AutocompleteSearchBox, {
276
+ query: searchboxQuery || '',
277
+ inputProps: _objectSpread(_objectSpread({}, getInputProps()), {}, {
278
+ // @ts-ignore - This clashes with some ambient React JSX declarations.
279
+ onInput: function onInput(evt) {
280
+ return refine(evt.currentTarget.value);
281
+ }
282
+ }),
283
+ onClear: function onClear() {
284
+ return onRefine('');
285
+ },
286
+ isSearchStalled: instantSearchInstance.status === 'stalled'
287
+ }), h(AutocompletePanel, getPanelProps(), templates.panel ? h(TemplateComponent, _extends({}, renderState.templateProps, {
288
+ templateKey: "panel",
289
+ rootTagName: "fragment",
290
+ data: {
291
+ elements: elements,
292
+ indices: indices
293
+ }
294
+ })) : Object.keys(elements).map(function (elementId) {
295
+ return elements[elementId];
195
296
  })));
196
297
  }
197
298
  export function EXPERIMENTAL_autocomplete(widgetParams) {
198
- var _ref7 = widgetParams || {},
199
- container = _ref7.container,
200
- escapeHTML = _ref7.escapeHTML,
201
- _ref7$indices = _ref7.indices,
202
- indices = _ref7$indices === void 0 ? [] : _ref7$indices,
203
- showSuggestions = _ref7.showSuggestions,
204
- getSearchPageURL = _ref7.getSearchPageURL,
205
- onSelect = _ref7.onSelect,
206
- _ref7$templates = _ref7.templates,
207
- templates = _ref7$templates === void 0 ? {} : _ref7$templates,
208
- _ref7$cssClasses = _ref7.cssClasses,
209
- userCssClasses = _ref7$cssClasses === void 0 ? {} : _ref7$cssClasses;
299
+ var _ref0 = widgetParams || {},
300
+ container = _ref0.container,
301
+ escapeHTML = _ref0.escapeHTML,
302
+ _ref0$indices = _ref0.indices,
303
+ indices = _ref0$indices === void 0 ? [] : _ref0$indices,
304
+ showSuggestions = _ref0.showSuggestions,
305
+ showRecent = _ref0.showRecent,
306
+ userSearchParameters = _ref0.searchParameters,
307
+ getSearchPageURL = _ref0.getSearchPageURL,
308
+ onSelect = _ref0.onSelect,
309
+ _ref0$templates = _ref0.templates,
310
+ templates = _ref0$templates === void 0 ? {} : _ref0$templates,
311
+ _ref0$cssClasses = _ref0.cssClasses,
312
+ userCssClasses = _ref0$cssClasses === void 0 ? {} : _ref0$cssClasses;
210
313
  if (!container) {
211
314
  throw new Error(withUsage('The `container` option is required.'));
212
315
  }
213
316
  var containerNode = getContainerNode(container);
317
+ var searchParameters = _objectSpread({
318
+ hitsPerPage: 5
319
+ }, userSearchParameters);
214
320
  var cssClasses = {
215
321
  root: cx(suit(), userCssClasses.root)
216
322
  };
@@ -221,7 +327,16 @@ export function EXPERIMENTAL_autocomplete(widgetParams) {
221
327
  indexName: showSuggestions.indexName,
222
328
  templates: _objectSpread({
223
329
  // @ts-expect-error
224
- item: AutocompleteSuggestion
330
+ item: function item(_ref1) {
331
+ var _item = _ref1.item,
332
+ onSelectItem = _ref1.onSelect;
333
+ return h(AutocompleteSuggestion, {
334
+ item: _item,
335
+ onSelect: onSelectItem
336
+ }, h(ConditionalReverseHighlight, {
337
+ item: _item
338
+ }));
339
+ }
225
340
  }, showSuggestions.templates),
226
341
  cssClasses: {
227
342
  root: cx('ais-AutocompleteSuggestions', (_showSuggestions$cssC = showSuggestions.cssClasses) === null || _showSuggestions$cssC === void 0 ? void 0 : _showSuggestions$cssC.root),
@@ -243,10 +358,13 @@ export function EXPERIMENTAL_autocomplete(widgetParams) {
243
358
  getSearchPageURL: getSearchPageURL,
244
359
  onSelect: onSelect,
245
360
  cssClasses: cssClasses,
361
+ showRecent: showRecent,
362
+ showSuggestions: showSuggestions,
246
363
  renderState: {
247
364
  indexTemplateProps: [],
248
365
  isolatedIndex: undefined,
249
- targetIndex: undefined
366
+ targetIndex: undefined,
367
+ templateProps: undefined
250
368
  },
251
369
  templates: templates
252
370
  });
@@ -258,17 +376,29 @@ export function EXPERIMENTAL_autocomplete(widgetParams) {
258
376
  })({}), index({
259
377
  indexId: "ais-autocomplete-".concat(instanceId),
260
378
  EXPERIMENTAL_isolated: true
261
- }).addWidgets([configure({
262
- hitsPerPage: 5
263
- })].concat(_toConsumableArray(indicesConfig.map(function (_ref8) {
264
- var indexName = _ref8.indexName;
379
+ }).addWidgets([configure(searchParameters)].concat(_toConsumableArray(indicesConfig.map(function (_ref10) {
380
+ var indexName = _ref10.indexName,
381
+ indexSearchParameters = _ref10.searchParameters;
265
382
  return index({
266
383
  indexName: indexName,
267
384
  indexId: indexName
268
- }).addWidgets([configure({})]);
385
+ }).addWidgets([configure(indexSearchParameters || {})]);
269
386
  })), [_objectSpread(_objectSpread({}, makeWidget({
270
387
  escapeHTML: escapeHTML
271
388
  })), {}, {
272
389
  $$widgetType: 'ais.autocomplete'
273
390
  })]))];
391
+ }
392
+ function ConditionalReverseHighlight(_ref11) {
393
+ var _item$_highlightResul;
394
+ var item = _ref11.item;
395
+ if (!((_item$_highlightResul = item._highlightResult) !== null && _item$_highlightResul !== void 0 && _item$_highlightResul.query) ||
396
+ // @ts-expect-error - we should not have matchLevel as arrays here
397
+ item._highlightResult.query.matchLevel === 'none') {
398
+ return item.query;
399
+ }
400
+ return h(ReverseHighlight, {
401
+ attribute: "query",
402
+ hit: item
403
+ });
274
404
  }
@@ -2,7 +2,7 @@
2
2
  import { SearchIndexToolType, RecommendToolType } from '../../lib/chat';
3
3
  import type { ChatConnectorParams, ChatWidgetDescription } from '../../connectors/chat/connectChat';
4
4
  import type { WidgetFactory, Hit, TemplateWithBindEvent, BaseHit, Template, IndexUiState } from '../../types';
5
- import type { ChatClassNames, ChatHeaderProps, ChatMessageActionProps, ChatMessageBase, ChatMessageErrorProps, ChatMessageLoaderProps, ChatPromptProps, ChatToggleButtonProps, ClientSideToolComponentProps, RecordWithObjectID, UserClientSideTool } from 'instantsearch-ui-components';
5
+ import type { ChatClassNames, ChatHeaderProps, ChatMessageActionProps, ChatMessageBase, ChatMessageErrorProps, ChatMessageLoaderProps, ChatPromptProps, ChatToggleButtonProps, ClientSideToolComponentProps, ClientSideTools, RecordWithObjectID, UserClientSideTool } from 'instantsearch-ui-components';
6
6
  export { SearchIndexToolType, RecommendToolType };
7
7
  export type UserClientSideToolTemplates = Partial<{
8
8
  layout: TemplateWithBindEvent<ClientSideToolComponentProps>;
@@ -95,6 +95,45 @@ export type ChatTemplates<THit extends NonNullable<object> = BaseHit> = Partial<
95
95
  */
96
96
  regenerateLabelText?: string;
97
97
  }>;
98
+ /**
99
+ * Templates to use for each message.
100
+ */
101
+ message: Partial<{
102
+ /**
103
+ * Label for the message actions
104
+ */
105
+ actionsLabelText?: string;
106
+ /**
107
+ * Label for the message container
108
+ */
109
+ messageLabelText?: string;
110
+ }>;
111
+ /**
112
+ * Templates to use for the assistant message.
113
+ */
114
+ assistantMessage: Partial<{
115
+ /**
116
+ * Template to use for the assistant message leading content.
117
+ */
118
+ leading: Template;
119
+ /**
120
+ * Template to use for the assistant message footer content.
121
+ */
122
+ footer: Template;
123
+ }>;
124
+ /**
125
+ * Templates to use for the user message.
126
+ */
127
+ userMessage: Partial<{
128
+ /**
129
+ * Template to use for the user message leading content.
130
+ */
131
+ leading: Template;
132
+ /**
133
+ * Template to use for the user message footer content.
134
+ */
135
+ footer: Template;
136
+ }>;
98
137
  /**
99
138
  * Templates to use for the prompt.
100
139
  */
@@ -515,7 +554,7 @@ declare const _default: <THit extends RecordWithObjectID = RecordWithObjectID>(w
515
554
  isClearing: boolean;
516
555
  clearMessages: () => void;
517
556
  onClearTransitionEnd: () => void;
518
- tools: Record<string, Omit<UserClientSideTool, "layoutComponent">>;
557
+ tools: ClientSideTools;
519
558
  widgetParams: Partial<ChatWidgetParams<RecordWithObjectID>> & ChatConnectorParams<import("ai").UIMessage<unknown, import("ai").UIDataTypes, import("ai").UITools>>;
520
559
  addToolResult: <TOOL extends string>({ tool, toolCallId, output, }: {
521
560
  tool: TOOL;