instantsearch-ui-components 0.17.1 → 0.19.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 (29) hide show
  1. package/dist/cjs/components/autocomplete/AutocompleteDetachedContainer.js +21 -0
  2. package/dist/cjs/components/autocomplete/AutocompleteDetachedFormContainer.js +28 -0
  3. package/dist/cjs/components/autocomplete/AutocompleteDetachedOverlay.js +20 -0
  4. package/dist/cjs/components/autocomplete/AutocompleteDetachedSearchButton.js +53 -0
  5. package/dist/cjs/components/autocomplete/createAutocompletePropGetters.js +21 -7
  6. package/dist/cjs/components/autocomplete/icons.js +11 -0
  7. package/dist/cjs/components/autocomplete/index.js +44 -0
  8. package/dist/cjs/components/chat/ChatMessage.js +10 -2
  9. package/dist/cjs/version.js +1 -1
  10. package/dist/es/components/autocomplete/Autocomplete.d.ts +36 -0
  11. package/dist/es/components/autocomplete/AutocompleteDetachedContainer.d.ts +8 -0
  12. package/dist/es/components/autocomplete/AutocompleteDetachedContainer.js +15 -0
  13. package/dist/es/components/autocomplete/AutocompleteDetachedFormContainer.d.ts +11 -0
  14. package/dist/es/components/autocomplete/AutocompleteDetachedFormContainer.js +22 -0
  15. package/dist/es/components/autocomplete/AutocompleteDetachedOverlay.d.ts +9 -0
  16. package/dist/es/components/autocomplete/AutocompleteDetachedOverlay.js +14 -0
  17. package/dist/es/components/autocomplete/AutocompleteDetachedSearchButton.d.ts +17 -0
  18. package/dist/es/components/autocomplete/AutocompleteDetachedSearchButton.js +47 -0
  19. package/dist/es/components/autocomplete/createAutocompletePropGetters.d.ts +25 -1
  20. package/dist/es/components/autocomplete/createAutocompletePropGetters.js +21 -7
  21. package/dist/es/components/autocomplete/icons.d.ts +1 -0
  22. package/dist/es/components/autocomplete/icons.js +10 -0
  23. package/dist/es/components/autocomplete/index.d.ts +4 -0
  24. package/dist/es/components/autocomplete/index.js +4 -0
  25. package/dist/es/components/chat/ChatMessage.js +10 -2
  26. package/dist/es/components/chat/types.d.ts +13 -1
  27. package/dist/es/version.d.ts +1 -1
  28. package/dist/es/version.js +1 -1
  29. package/package.json +2 -2
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.createAutocompleteDetachedContainerComponent = createAutocompleteDetachedContainerComponent;
7
+ var _cx = require("../../lib/cx");
8
+ function createAutocompleteDetachedContainerComponent(_ref) {
9
+ var createElement = _ref.createElement;
10
+ return function AutocompleteDetachedContainer(userProps) {
11
+ var children = userProps.children,
12
+ _userProps$classNames = userProps.classNames,
13
+ classNames = _userProps$classNames === void 0 ? {} : _userProps$classNames;
14
+ return createElement("div", {
15
+ className: (0, _cx.cx)('ais-AutocompleteDetachedContainer', classNames.detachedContainer),
16
+ onMouseDown: function onMouseDown(event) {
17
+ event.stopPropagation();
18
+ }
19
+ }, children);
20
+ };
21
+ }
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.createAutocompleteDetachedFormContainerComponent = createAutocompleteDetachedFormContainerComponent;
7
+ var _cx = require("../../lib/cx");
8
+ var _Button = require("../Button");
9
+ function createAutocompleteDetachedFormContainerComponent(_ref) {
10
+ var createElement = _ref.createElement;
11
+ var Button = (0, _Button.createButtonComponent)({
12
+ createElement: createElement
13
+ });
14
+ return function AutocompleteDetachedFormContainer(userProps) {
15
+ var children = userProps.children,
16
+ _userProps$classNames = userProps.classNames,
17
+ classNames = _userProps$classNames === void 0 ? {} : _userProps$classNames,
18
+ onCancel = userProps.onCancel,
19
+ translations = userProps.translations;
20
+ return createElement("div", {
21
+ className: (0, _cx.cx)('ais-AutocompleteDetachedFormContainer', classNames.detachedFormContainer)
22
+ }, children, createElement(Button, {
23
+ variant: "ghost",
24
+ className: (0, _cx.cx)('ais-AutocompleteDetachedCancelButton', classNames.detachedCancelButton),
25
+ onClick: onCancel
26
+ }, translations.detachedCancelButtonText));
27
+ };
28
+ }
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.createAutocompleteDetachedOverlayComponent = createAutocompleteDetachedOverlayComponent;
7
+ var _cx = require("../../lib/cx");
8
+ function createAutocompleteDetachedOverlayComponent(_ref) {
9
+ var createElement = _ref.createElement;
10
+ return function AutocompleteDetachedOverlay(userProps) {
11
+ var children = userProps.children,
12
+ _userProps$classNames = userProps.classNames,
13
+ classNames = _userProps$classNames === void 0 ? {} : _userProps$classNames,
14
+ onClose = userProps.onClose;
15
+ return createElement("div", {
16
+ className: (0, _cx.cx)('ais-AutocompleteDetachedOverlay', classNames.detachedOverlay),
17
+ onMouseDown: onClose
18
+ }, children);
19
+ };
20
+ }
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.createAutocompleteDetachedSearchButtonComponent = createAutocompleteDetachedSearchButtonComponent;
7
+ var _cx = require("../../lib/cx");
8
+ var _icons = require("./icons");
9
+ function createAutocompleteDetachedSearchButtonComponent(_ref) {
10
+ var createElement = _ref.createElement;
11
+ return function AutocompleteDetachedSearchButton(userProps) {
12
+ var query = userProps.query,
13
+ _userProps$placeholde = userProps.placeholder,
14
+ placeholder = _userProps$placeholde === void 0 ? 'Search' : _userProps$placeholde,
15
+ _userProps$classNames = userProps.classNames,
16
+ classNames = _userProps$classNames === void 0 ? {} : _userProps$classNames,
17
+ onClick = userProps.onClick,
18
+ onClear = userProps.onClear,
19
+ translations = userProps.translations;
20
+ return createElement("div", {
21
+ className: (0, _cx.cx)('ais-AutocompleteDetachedSearchButton', classNames.detachedSearchButton),
22
+ onClick: onClick,
23
+ onKeyDown: function onKeyDown(event) {
24
+ if (event.key === 'Enter' || event.key === ' ') {
25
+ event.preventDefault();
26
+ onClick();
27
+ }
28
+ },
29
+ role: "button",
30
+ tabIndex: 0,
31
+ title: translations.detachedSearchButtonTitle
32
+ }, createElement("div", {
33
+ className: (0, _cx.cx)('ais-AutocompleteDetachedSearchButtonIcon', classNames.detachedSearchButtonIcon)
34
+ }, createElement(_icons.SearchIcon, {
35
+ createElement: createElement
36
+ })), createElement("div", {
37
+ className: (0, _cx.cx)('ais-AutocompleteDetachedSearchButtonPlaceholder', classNames.detachedSearchButtonPlaceholder),
38
+ hidden: Boolean(query)
39
+ }, placeholder), createElement("div", {
40
+ className: (0, _cx.cx)('ais-AutocompleteDetachedSearchButtonQuery', classNames.detachedSearchButtonQuery)
41
+ }, query), query && onClear && createElement("button", {
42
+ type: "reset",
43
+ className: (0, _cx.cx)('ais-AutocompleteDetachedSearchButtonClear', classNames.detachedSearchButtonClear),
44
+ title: translations.detachedClearButtonTitle,
45
+ onClick: function onClick(event) {
46
+ event.stopPropagation();
47
+ onClear();
48
+ }
49
+ }, createElement(_icons.ClearIcon, {
50
+ createElement: createElement
51
+ })));
52
+ };
53
+ }
@@ -20,7 +20,10 @@ function createAutocompletePropGetters(_ref) {
20
20
  onRefine = _ref2.onRefine,
21
21
  globalOnSelect = _ref2.onSelect,
22
22
  _onApply = _ref2.onApply,
23
- placeholder = _ref2.placeholder;
23
+ onSubmit = _ref2.onSubmit,
24
+ placeholder = _ref2.placeholder,
25
+ _ref2$isDetached = _ref2.isDetached,
26
+ isDetached = _ref2$isDetached === void 0 ? false : _ref2$isDetached;
24
27
  var getElementId = createGetElementId(useId());
25
28
  var inputRef = useRef(null);
26
29
  var rootRef = useRef(null);
@@ -42,6 +45,11 @@ function createAutocompletePropGetters(_ref) {
42
45
  items = _useMemo.items,
43
46
  itemsIds = _useMemo.itemsIds;
44
47
  useEffect(function () {
48
+ // In detached mode, we don't close the panel on body click
49
+ // because the overlay handles closing
50
+ if (isDetached) {
51
+ return function () {};
52
+ }
45
53
  var onBodyClick = function onBodyClick(event) {
46
54
  var _unwrapRef;
47
55
  if ((_unwrapRef = unwrapRef(rootRef)) !== null && _unwrapRef !== void 0 && _unwrapRef.contains(event.target)) {
@@ -53,16 +61,14 @@ function createAutocompletePropGetters(_ref) {
53
61
  return function () {
54
62
  document.body.removeEventListener('click', onBodyClick);
55
63
  };
56
- }, [rootRef]);
64
+ }, [rootRef, isDetached]);
57
65
  var getNextActiveDescendant = function getNextActiveDescendant(key) {
58
66
  switch (key) {
59
- case 'ArrowLeft':
60
67
  case 'ArrowUp':
61
68
  {
62
69
  var prevIndex = itemsIds.indexOf(activeDescendant || '') - 1;
63
70
  return itemsIds[prevIndex] || itemsIds[itemsIds.length - 1];
64
71
  }
65
- case 'ArrowRight':
66
72
  case 'ArrowDown':
67
73
  {
68
74
  var nextIndex = itemsIds.indexOf(activeDescendant || '') + 1;
@@ -104,6 +110,7 @@ function createAutocompletePropGetters(_ref) {
104
110
  });
105
111
  setActiveDescendant(undefined);
106
112
  }
113
+ onSubmit === null || onSubmit === void 0 ? void 0 : onSubmit();
107
114
  };
108
115
  return {
109
116
  getInputProps: function getInputProps() {
@@ -132,9 +139,7 @@ function createAutocompletePropGetters(_ref) {
132
139
  }
133
140
  break;
134
141
  }
135
- case 'ArrowLeft':
136
142
  case 'ArrowUp':
137
- case 'ArrowRight':
138
143
  case 'ArrowDown':
139
144
  {
140
145
  var _document$getElementB;
@@ -153,7 +158,10 @@ function createAutocompletePropGetters(_ref) {
153
158
  break;
154
159
  }
155
160
  case 'Tab':
156
- setIsOpen(false);
161
+ // In detached mode, Tab doesn't close the panel
162
+ if (!isDetached) {
163
+ setIsOpen(false);
164
+ }
157
165
  break;
158
166
  default:
159
167
  setIsOpen(true);
@@ -209,6 +217,12 @@ function createAutocompletePropGetters(_ref) {
209
217
  return {
210
218
  ref: rootRef
211
219
  };
220
+ },
221
+ isOpen: isOpen,
222
+ setIsOpen: setIsOpen,
223
+ focusInput: function focusInput() {
224
+ var _inputRef$current2;
225
+ (_inputRef$current2 = inputRef.current) === null || _inputRef$current2 === void 0 ? void 0 : _inputRef$current2.focus();
212
226
  }
213
227
  };
214
228
  };
@@ -7,6 +7,7 @@ exports.ApplyIcon = ApplyIcon;
7
7
  exports.ClearIcon = ClearIcon;
8
8
  exports.ClockIcon = ClockIcon;
9
9
  exports.LoadingIcon = LoadingIcon;
10
+ exports.SearchIcon = SearchIcon;
10
11
  exports.SubmitIcon = SubmitIcon;
11
12
  exports.TrashIcon = TrashIcon;
12
13
  function SubmitIcon(_ref) {
@@ -77,4 +78,14 @@ function ApplyIcon(_ref6) {
77
78
  }, createElement("path", {
78
79
  d: "M8 17v-7.586l8.293 8.293c0.391 0.391 1.024 0.391 1.414 0s0.391-1.024 0-1.414l-8.293-8.293h7.586c0.552 0 1-0.448 1-1s-0.448-1-1-1h-10c-0.552 0-1 0.448-1 1v10c0 0.552 0.448 1 1 1s1-0.448 1-1z"
79
80
  }));
81
+ }
82
+ function SearchIcon(_ref7) {
83
+ var createElement = _ref7.createElement;
84
+ return createElement("svg", {
85
+ className: "ais-AutocompleteDetachedSearchIcon",
86
+ viewBox: "0 0 24 24",
87
+ fill: "currentColor"
88
+ }, createElement("path", {
89
+ d: "M16.041 15.856c-0.034 0.026-0.067 0.055-0.099 0.087s-0.060 0.064-0.087 0.099c-1.258 1.213-2.969 1.958-4.855 1.958-1.933 0-3.682-0.782-4.95-2.050s-2.050-3.017-2.050-4.95 0.782-3.682 2.050-4.95 3.017-2.050 4.95-2.050 3.682 0.782 4.95 2.050 2.050 3.017 2.050 4.95c0 1.886-0.745 3.597-1.959 4.856zM21.707 20.293l-3.675-3.675c1.231-1.54 1.968-3.493 1.968-5.618 0-2.485-1.008-4.736-2.636-6.364s-3.879-2.636-6.364-2.636-4.736 1.008-6.364 2.636-2.636 3.879-2.636 6.364 1.008 4.736 2.636 6.364 3.879 2.636 6.364 2.636c2.125 0 4.078-0.737 5.618-1.968l3.675 3.675c0.391 0.391 1.024 0.391 1.414 0s0.391-1.024 0-1.414z"
90
+ }));
80
91
  }
@@ -14,6 +14,50 @@ Object.keys(_Autocomplete).forEach(function (key) {
14
14
  }
15
15
  });
16
16
  });
17
+ var _AutocompleteDetachedContainer = require("./AutocompleteDetachedContainer");
18
+ Object.keys(_AutocompleteDetachedContainer).forEach(function (key) {
19
+ if (key === "default" || key === "__esModule") return;
20
+ if (key in exports && exports[key] === _AutocompleteDetachedContainer[key]) return;
21
+ Object.defineProperty(exports, key, {
22
+ enumerable: true,
23
+ get: function get() {
24
+ return _AutocompleteDetachedContainer[key];
25
+ }
26
+ });
27
+ });
28
+ var _AutocompleteDetachedFormContainer = require("./AutocompleteDetachedFormContainer");
29
+ Object.keys(_AutocompleteDetachedFormContainer).forEach(function (key) {
30
+ if (key === "default" || key === "__esModule") return;
31
+ if (key in exports && exports[key] === _AutocompleteDetachedFormContainer[key]) return;
32
+ Object.defineProperty(exports, key, {
33
+ enumerable: true,
34
+ get: function get() {
35
+ return _AutocompleteDetachedFormContainer[key];
36
+ }
37
+ });
38
+ });
39
+ var _AutocompleteDetachedOverlay = require("./AutocompleteDetachedOverlay");
40
+ Object.keys(_AutocompleteDetachedOverlay).forEach(function (key) {
41
+ if (key === "default" || key === "__esModule") return;
42
+ if (key in exports && exports[key] === _AutocompleteDetachedOverlay[key]) return;
43
+ Object.defineProperty(exports, key, {
44
+ enumerable: true,
45
+ get: function get() {
46
+ return _AutocompleteDetachedOverlay[key];
47
+ }
48
+ });
49
+ });
50
+ var _AutocompleteDetachedSearchButton = require("./AutocompleteDetachedSearchButton");
51
+ Object.keys(_AutocompleteDetachedSearchButton).forEach(function (key) {
52
+ if (key === "default" || key === "__esModule") return;
53
+ if (key in exports && exports[key] === _AutocompleteDetachedSearchButton[key]) return;
54
+ Object.defineProperty(exports, key, {
55
+ enumerable: true,
56
+ get: function get() {
57
+ return _AutocompleteDetachedSearchButton[key];
58
+ }
59
+ });
60
+ });
17
61
  var _AutocompleteIndex = require("./AutocompleteIndex");
18
62
  Object.keys(_AutocompleteIndex).forEach(function (key) {
19
63
  if (key === "default" || key === "__esModule") return;
@@ -15,6 +15,8 @@ var _icons = require("./icons");
15
15
  var _excluded = ["classNames", "message", "side", "variant", "actions", "autoHideActions", "leadingComponent", "actionsComponent", "footerComponent", "tools", "indexUiState", "setIndexUiState", "onClose", "translations", "suggestionsElement"];
16
16
  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; }
17
17
  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) { (0, _defineProperty2.default)(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; }
18
+ // Keep in sync with packages/instantsearch.js/src/lib/chat/index.ts
19
+ var SearchIndexToolType = 'algolia_search_index';
18
20
  function createChatMessageComponent(_ref) {
19
21
  var createElement = _ref.createElement;
20
22
  var Button = (0, _Button.createButtonComponent)({
@@ -74,12 +76,17 @@ function createChatMessageComponent(_ref) {
74
76
  if ((0, _lib.startsWith)(part.type, 'tool-')) {
75
77
  var toolName = part.type.replace('tool-', '');
76
78
  var tool = tools[toolName];
79
+
80
+ // Compatibility shim with Algolia MCP Server search tool
81
+ if (!tool && (0, _lib.startsWith)(toolName, "".concat(SearchIndexToolType, "_"))) {
82
+ tool = tools[SearchIndexToolType];
83
+ }
77
84
  if (tool) {
78
85
  var ToolLayoutComponent = tool.layoutComponent;
79
86
  var toolMessage = part;
80
87
  var boundAddToolResult = function boundAddToolResult(params) {
81
- var _tool$addToolResult;
82
- return (_tool$addToolResult = tool.addToolResult) === null || _tool$addToolResult === void 0 ? void 0 : _tool$addToolResult.call(tool, {
88
+ var _tool$addToolResult, _tool;
89
+ return (_tool$addToolResult = (_tool = tool).addToolResult) === null || _tool$addToolResult === void 0 ? void 0 : _tool$addToolResult.call(_tool, {
83
90
  output: params.output,
84
91
  tool: part.type,
85
92
  toolCallId: toolMessage.toolCallId
@@ -96,6 +103,7 @@ function createChatMessageComponent(_ref) {
96
103
  indexUiState: indexUiState,
97
104
  setIndexUiState: setIndexUiState,
98
105
  addToolResult: boundAddToolResult,
106
+ applyFilters: tool.applyFilters,
99
107
  onClose: onClose
100
108
  }));
101
109
  }
@@ -4,4 +4,4 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
- var _default = exports.default = '0.17.1';
7
+ var _default = exports.default = '0.19.0';
@@ -9,5 +9,41 @@ export type AutocompleteClassNames = {
9
9
  * Class names to apply to the root element
10
10
  */
11
11
  root: string | string[];
12
+ /**
13
+ * Class names to apply to the detached overlay backdrop
14
+ */
15
+ detachedOverlay: string | string[];
16
+ /**
17
+ * Class names to apply to the detached container
18
+ */
19
+ detachedContainer: string | string[];
20
+ /**
21
+ * Class names to apply to the detached form container
22
+ */
23
+ detachedFormContainer: string | string[];
24
+ /**
25
+ * Class names to apply to the detached search button
26
+ */
27
+ detachedSearchButton: string | string[];
28
+ /**
29
+ * Class names to apply to the detached search button icon
30
+ */
31
+ detachedSearchButtonIcon: string | string[];
32
+ /**
33
+ * Class names to apply to the detached search button placeholder
34
+ */
35
+ detachedSearchButtonPlaceholder: string | string[];
36
+ /**
37
+ * Class names to apply to the detached search button query
38
+ */
39
+ detachedSearchButtonQuery: string | string[];
40
+ /**
41
+ * Class names to apply to the detached search button clear button
42
+ */
43
+ detachedSearchButtonClear: string | string[];
44
+ /**
45
+ * Class names to apply to the detached cancel button
46
+ */
47
+ detachedCancelButton: string | string[];
12
48
  };
13
49
  export declare function createAutocompleteComponent({ createElement }: Renderer): (userProps: AutocompleteProps) => JSX.Element;
@@ -0,0 +1,8 @@
1
+ /** @jsx createElement */
2
+ import type { ComponentChildren, Renderer } from '../../types';
3
+ import type { AutocompleteClassNames } from './Autocomplete';
4
+ export type AutocompleteDetachedContainerProps = {
5
+ children?: ComponentChildren;
6
+ classNames?: Partial<AutocompleteClassNames>;
7
+ };
8
+ export declare function createAutocompleteDetachedContainerComponent({ createElement, }: Renderer): (userProps: AutocompleteDetachedContainerProps) => JSX.Element;
@@ -0,0 +1,15 @@
1
+ import { cx } from "../../lib/cx.js";
2
+ export function createAutocompleteDetachedContainerComponent(_ref) {
3
+ var createElement = _ref.createElement;
4
+ return function AutocompleteDetachedContainer(userProps) {
5
+ var children = userProps.children,
6
+ _userProps$classNames = userProps.classNames,
7
+ classNames = _userProps$classNames === void 0 ? {} : _userProps$classNames;
8
+ return createElement("div", {
9
+ className: cx('ais-AutocompleteDetachedContainer', classNames.detachedContainer),
10
+ onMouseDown: function onMouseDown(event) {
11
+ event.stopPropagation();
12
+ }
13
+ }, children);
14
+ };
15
+ }
@@ -0,0 +1,11 @@
1
+ /** @jsx createElement */
2
+ import type { ComponentChildren, Renderer } from '../../types';
3
+ import type { AutocompleteClassNames } from './Autocomplete';
4
+ import type { AutocompleteDetachedTranslations } from './AutocompleteDetachedSearchButton';
5
+ export type AutocompleteDetachedFormContainerProps = {
6
+ children?: ComponentChildren;
7
+ classNames?: Partial<AutocompleteClassNames>;
8
+ onCancel: () => void;
9
+ translations: AutocompleteDetachedTranslations;
10
+ };
11
+ export declare function createAutocompleteDetachedFormContainerComponent({ createElement, }: Renderer): (userProps: AutocompleteDetachedFormContainerProps) => JSX.Element;
@@ -0,0 +1,22 @@
1
+ import { cx } from "../../lib/cx.js";
2
+ import { createButtonComponent } from "../Button.js";
3
+ export function createAutocompleteDetachedFormContainerComponent(_ref) {
4
+ var createElement = _ref.createElement;
5
+ var Button = createButtonComponent({
6
+ createElement: createElement
7
+ });
8
+ return function AutocompleteDetachedFormContainer(userProps) {
9
+ var children = userProps.children,
10
+ _userProps$classNames = userProps.classNames,
11
+ classNames = _userProps$classNames === void 0 ? {} : _userProps$classNames,
12
+ onCancel = userProps.onCancel,
13
+ translations = userProps.translations;
14
+ return createElement("div", {
15
+ className: cx('ais-AutocompleteDetachedFormContainer', classNames.detachedFormContainer)
16
+ }, children, createElement(Button, {
17
+ variant: "ghost",
18
+ className: cx('ais-AutocompleteDetachedCancelButton', classNames.detachedCancelButton),
19
+ onClick: onCancel
20
+ }, translations.detachedCancelButtonText));
21
+ };
22
+ }
@@ -0,0 +1,9 @@
1
+ /** @jsx createElement */
2
+ import type { ComponentChildren, Renderer } from '../../types';
3
+ import type { AutocompleteClassNames } from './Autocomplete';
4
+ export type AutocompleteDetachedOverlayProps = {
5
+ children?: ComponentChildren;
6
+ classNames?: Partial<AutocompleteClassNames>;
7
+ onClose: () => void;
8
+ };
9
+ export declare function createAutocompleteDetachedOverlayComponent({ createElement, }: Renderer): (userProps: AutocompleteDetachedOverlayProps) => JSX.Element;
@@ -0,0 +1,14 @@
1
+ import { cx } from "../../lib/cx.js";
2
+ export function createAutocompleteDetachedOverlayComponent(_ref) {
3
+ var createElement = _ref.createElement;
4
+ return function AutocompleteDetachedOverlay(userProps) {
5
+ var children = userProps.children,
6
+ _userProps$classNames = userProps.classNames,
7
+ classNames = _userProps$classNames === void 0 ? {} : _userProps$classNames,
8
+ onClose = userProps.onClose;
9
+ return createElement("div", {
10
+ className: cx('ais-AutocompleteDetachedOverlay', classNames.detachedOverlay),
11
+ onMouseDown: onClose
12
+ }, children);
13
+ };
14
+ }
@@ -0,0 +1,17 @@
1
+ /** @jsx createElement */
2
+ import type { Renderer } from '../../types';
3
+ import type { AutocompleteClassNames } from './Autocomplete';
4
+ export type AutocompleteDetachedTranslations = {
5
+ detachedCancelButtonText: string;
6
+ detachedSearchButtonTitle: string;
7
+ detachedClearButtonTitle: string;
8
+ };
9
+ export type AutocompleteDetachedSearchButtonProps = {
10
+ query: string;
11
+ placeholder?: string;
12
+ classNames?: Partial<AutocompleteClassNames>;
13
+ onClick: () => void;
14
+ onClear?: () => void;
15
+ translations: AutocompleteDetachedTranslations;
16
+ };
17
+ export declare function createAutocompleteDetachedSearchButtonComponent({ createElement, }: Renderer): (userProps: AutocompleteDetachedSearchButtonProps) => JSX.Element;
@@ -0,0 +1,47 @@
1
+ import { cx } from "../../lib/cx.js";
2
+ import { ClearIcon, SearchIcon } from "./icons.js";
3
+ export function createAutocompleteDetachedSearchButtonComponent(_ref) {
4
+ var createElement = _ref.createElement;
5
+ return function AutocompleteDetachedSearchButton(userProps) {
6
+ var query = userProps.query,
7
+ _userProps$placeholde = userProps.placeholder,
8
+ placeholder = _userProps$placeholde === void 0 ? 'Search' : _userProps$placeholde,
9
+ _userProps$classNames = userProps.classNames,
10
+ classNames = _userProps$classNames === void 0 ? {} : _userProps$classNames,
11
+ onClick = userProps.onClick,
12
+ onClear = userProps.onClear,
13
+ translations = userProps.translations;
14
+ return createElement("div", {
15
+ className: cx('ais-AutocompleteDetachedSearchButton', classNames.detachedSearchButton),
16
+ onClick: onClick,
17
+ onKeyDown: function onKeyDown(event) {
18
+ if (event.key === 'Enter' || event.key === ' ') {
19
+ event.preventDefault();
20
+ onClick();
21
+ }
22
+ },
23
+ role: "button",
24
+ tabIndex: 0,
25
+ title: translations.detachedSearchButtonTitle
26
+ }, createElement("div", {
27
+ className: cx('ais-AutocompleteDetachedSearchButtonIcon', classNames.detachedSearchButtonIcon)
28
+ }, createElement(SearchIcon, {
29
+ createElement: createElement
30
+ })), createElement("div", {
31
+ className: cx('ais-AutocompleteDetachedSearchButtonPlaceholder', classNames.detachedSearchButtonPlaceholder),
32
+ hidden: Boolean(query)
33
+ }, placeholder), createElement("div", {
34
+ className: cx('ais-AutocompleteDetachedSearchButtonQuery', classNames.detachedSearchButtonQuery)
35
+ }, query), query && onClear && createElement("button", {
36
+ type: "reset",
37
+ className: cx('ais-AutocompleteDetachedSearchButtonClear', classNames.detachedSearchButtonClear),
38
+ title: translations.detachedClearButtonTitle,
39
+ onClick: function onClick(event) {
40
+ event.stopPropagation();
41
+ onClear();
42
+ }
43
+ }, createElement(ClearIcon, {
44
+ createElement: createElement
45
+ })));
46
+ };
47
+ }
@@ -53,12 +53,36 @@ export type UsePropGetters<TItem extends BaseHit> = (params: {
53
53
  onRefine: (query: string) => void;
54
54
  onSelect: NonNullable<AutocompleteIndexConfig<TItem>['onSelect']>;
55
55
  onApply: (query: string) => void;
56
+ /**
57
+ * Called when the form is submitted (Enter pressed).
58
+ * Useful for detached mode to close the modal.
59
+ */
60
+ onSubmit?: () => void;
56
61
  placeholder?: string;
62
+ /**
63
+ * Whether the autocomplete is in detached mode (mobile).
64
+ * In detached mode:
65
+ * - Panel stays open (doesn't close on body click)
66
+ * - Tab key doesn't close panel
67
+ */
68
+ isDetached?: boolean;
57
69
  }) => {
58
70
  getInputProps: GetInputProps;
59
71
  getItemProps: GetItemProps;
60
72
  getPanelProps: GetPanelProps;
61
73
  getRootProps: GetRootProps;
74
+ /**
75
+ * Whether the panel is open.
76
+ */
77
+ isOpen: boolean;
78
+ /**
79
+ * Function to set the panel open state. Useful for detached mode.
80
+ */
81
+ setIsOpen: (isOpen: boolean) => void;
82
+ /**
83
+ * Function to focus the input. Useful for detached mode to show the keyboard.
84
+ */
85
+ focusInput: () => void;
62
86
  };
63
- export declare function createAutocompletePropGetters({ useEffect, useId, useMemo, useRef, useState, }: CreateAutocompletePropGettersParams): <TItem extends BaseHit>({ indices, indicesConfig, onRefine, onSelect: globalOnSelect, onApply, placeholder, }: Parameters<UsePropGetters<TItem>>[0]) => ReturnType<UsePropGetters<TItem>>;
87
+ export declare function createAutocompletePropGetters({ useEffect, useId, useMemo, useRef, useState, }: CreateAutocompletePropGettersParams): <TItem extends BaseHit>({ indices, indicesConfig, onRefine, onSelect: globalOnSelect, onApply, onSubmit, placeholder, isDetached, }: Parameters<UsePropGetters<TItem>>[0]) => ReturnType<UsePropGetters<TItem>>;
64
88
  export {};
@@ -13,7 +13,10 @@ export function createAutocompletePropGetters(_ref) {
13
13
  onRefine = _ref2.onRefine,
14
14
  globalOnSelect = _ref2.onSelect,
15
15
  _onApply = _ref2.onApply,
16
- placeholder = _ref2.placeholder;
16
+ onSubmit = _ref2.onSubmit,
17
+ placeholder = _ref2.placeholder,
18
+ _ref2$isDetached = _ref2.isDetached,
19
+ isDetached = _ref2$isDetached === void 0 ? false : _ref2$isDetached;
17
20
  var getElementId = createGetElementId(useId());
18
21
  var inputRef = useRef(null);
19
22
  var rootRef = useRef(null);
@@ -35,6 +38,11 @@ export function createAutocompletePropGetters(_ref) {
35
38
  items = _useMemo.items,
36
39
  itemsIds = _useMemo.itemsIds;
37
40
  useEffect(function () {
41
+ // In detached mode, we don't close the panel on body click
42
+ // because the overlay handles closing
43
+ if (isDetached) {
44
+ return function () {};
45
+ }
38
46
  var onBodyClick = function onBodyClick(event) {
39
47
  var _unwrapRef;
40
48
  if ((_unwrapRef = unwrapRef(rootRef)) !== null && _unwrapRef !== void 0 && _unwrapRef.contains(event.target)) {
@@ -46,16 +54,14 @@ export function createAutocompletePropGetters(_ref) {
46
54
  return function () {
47
55
  document.body.removeEventListener('click', onBodyClick);
48
56
  };
49
- }, [rootRef]);
57
+ }, [rootRef, isDetached]);
50
58
  var getNextActiveDescendant = function getNextActiveDescendant(key) {
51
59
  switch (key) {
52
- case 'ArrowLeft':
53
60
  case 'ArrowUp':
54
61
  {
55
62
  var prevIndex = itemsIds.indexOf(activeDescendant || '') - 1;
56
63
  return itemsIds[prevIndex] || itemsIds[itemsIds.length - 1];
57
64
  }
58
- case 'ArrowRight':
59
65
  case 'ArrowDown':
60
66
  {
61
67
  var nextIndex = itemsIds.indexOf(activeDescendant || '') + 1;
@@ -97,6 +103,7 @@ export function createAutocompletePropGetters(_ref) {
97
103
  });
98
104
  setActiveDescendant(undefined);
99
105
  }
106
+ onSubmit === null || onSubmit === void 0 ? void 0 : onSubmit();
100
107
  };
101
108
  return {
102
109
  getInputProps: function getInputProps() {
@@ -125,9 +132,7 @@ export function createAutocompletePropGetters(_ref) {
125
132
  }
126
133
  break;
127
134
  }
128
- case 'ArrowLeft':
129
135
  case 'ArrowUp':
130
- case 'ArrowRight':
131
136
  case 'ArrowDown':
132
137
  {
133
138
  var _document$getElementB;
@@ -146,7 +151,10 @@ export function createAutocompletePropGetters(_ref) {
146
151
  break;
147
152
  }
148
153
  case 'Tab':
149
- setIsOpen(false);
154
+ // In detached mode, Tab doesn't close the panel
155
+ if (!isDetached) {
156
+ setIsOpen(false);
157
+ }
150
158
  break;
151
159
  default:
152
160
  setIsOpen(true);
@@ -202,6 +210,12 @@ export function createAutocompletePropGetters(_ref) {
202
210
  return {
203
211
  ref: rootRef
204
212
  };
213
+ },
214
+ isOpen: isOpen,
215
+ setIsOpen: setIsOpen,
216
+ focusInput: function focusInput() {
217
+ var _inputRef$current2;
218
+ (_inputRef$current2 = inputRef.current) === null || _inputRef$current2 === void 0 ? void 0 : _inputRef$current2.focus();
205
219
  }
206
220
  };
207
221
  };
@@ -7,4 +7,5 @@ export declare function ClearIcon({ createElement }: IconProps): JSX.Element;
7
7
  export declare function ClockIcon({ createElement }: IconProps): JSX.Element;
8
8
  export declare function TrashIcon({ createElement }: IconProps): JSX.Element;
9
9
  export declare function ApplyIcon({ createElement }: IconProps): JSX.Element;
10
+ export declare function SearchIcon({ createElement }: IconProps): JSX.Element;
10
11
  export {};
@@ -66,4 +66,14 @@ export function ApplyIcon(_ref6) {
66
66
  }, createElement("path", {
67
67
  d: "M8 17v-7.586l8.293 8.293c0.391 0.391 1.024 0.391 1.414 0s0.391-1.024 0-1.414l-8.293-8.293h7.586c0.552 0 1-0.448 1-1s-0.448-1-1-1h-10c-0.552 0-1 0.448-1 1v10c0 0.552 0.448 1 1 1s1-0.448 1-1z"
68
68
  }));
69
+ }
70
+ export function SearchIcon(_ref7) {
71
+ var createElement = _ref7.createElement;
72
+ return createElement("svg", {
73
+ className: "ais-AutocompleteDetachedSearchIcon",
74
+ viewBox: "0 0 24 24",
75
+ fill: "currentColor"
76
+ }, createElement("path", {
77
+ d: "M16.041 15.856c-0.034 0.026-0.067 0.055-0.099 0.087s-0.060 0.064-0.087 0.099c-1.258 1.213-2.969 1.958-4.855 1.958-1.933 0-3.682-0.782-4.95-2.050s-2.050-3.017-2.050-4.95 0.782-3.682 2.050-4.95 3.017-2.050 4.95-2.050 3.682 0.782 4.95 2.050 2.050 3.017 2.050 4.95c0 1.886-0.745 3.597-1.959 4.856zM21.707 20.293l-3.675-3.675c1.231-1.54 1.968-3.493 1.968-5.618 0-2.485-1.008-4.736-2.636-6.364s-3.879-2.636-6.364-2.636-4.736 1.008-6.364 2.636-2.636 3.879-2.636 6.364 1.008 4.736 2.636 6.364 3.879 2.636 6.364 2.636c2.125 0 4.078-0.737 5.618-1.968l3.675 3.675c0.391 0.391 1.024 0.391 1.414 0s0.391-1.024 0-1.414z"
78
+ }));
69
79
  }
@@ -1,4 +1,8 @@
1
1
  export * from './Autocomplete';
2
+ export * from './AutocompleteDetachedContainer';
3
+ export * from './AutocompleteDetachedFormContainer';
4
+ export * from './AutocompleteDetachedOverlay';
5
+ export * from './AutocompleteDetachedSearchButton';
2
6
  export * from './AutocompleteIndex';
3
7
  export * from './AutocompletePanel';
4
8
  export * from './AutocompleteRecentSearch';
@@ -1,4 +1,8 @@
1
1
  export * from "./Autocomplete.js";
2
+ export * from "./AutocompleteDetachedContainer.js";
3
+ export * from "./AutocompleteDetachedFormContainer.js";
4
+ export * from "./AutocompleteDetachedOverlay.js";
5
+ export * from "./AutocompleteDetachedSearchButton.js";
2
6
  export * from "./AutocompleteIndex.js";
3
7
  export * from "./AutocompletePanel.js";
4
8
  export * from "./AutocompleteRecentSearch.js";
@@ -8,6 +8,8 @@ import { compiler } from 'markdown-to-jsx';
8
8
  import { cx, startsWith } from "../../lib/index.js";
9
9
  import { createButtonComponent } from "../Button.js";
10
10
  import { MenuIcon } from "./icons.js";
11
+ // Keep in sync with packages/instantsearch.js/src/lib/chat/index.ts
12
+ var SearchIndexToolType = 'algolia_search_index';
11
13
  export function createChatMessageComponent(_ref) {
12
14
  var createElement = _ref.createElement;
13
15
  var Button = createButtonComponent({
@@ -67,12 +69,17 @@ export function createChatMessageComponent(_ref) {
67
69
  if (startsWith(part.type, 'tool-')) {
68
70
  var toolName = part.type.replace('tool-', '');
69
71
  var tool = tools[toolName];
72
+
73
+ // Compatibility shim with Algolia MCP Server search tool
74
+ if (!tool && startsWith(toolName, "".concat(SearchIndexToolType, "_"))) {
75
+ tool = tools[SearchIndexToolType];
76
+ }
70
77
  if (tool) {
71
78
  var ToolLayoutComponent = tool.layoutComponent;
72
79
  var toolMessage = part;
73
80
  var boundAddToolResult = function boundAddToolResult(params) {
74
- var _tool$addToolResult;
75
- return (_tool$addToolResult = tool.addToolResult) === null || _tool$addToolResult === void 0 ? void 0 : _tool$addToolResult.call(tool, {
81
+ var _tool$addToolResult, _tool;
82
+ return (_tool$addToolResult = (_tool = tool).addToolResult) === null || _tool$addToolResult === void 0 ? void 0 : _tool$addToolResult.call(_tool, {
76
83
  output: params.output,
77
84
  tool: part.type,
78
85
  toolCallId: toolMessage.toolCallId
@@ -89,6 +96,7 @@ export function createChatMessageComponent(_ref) {
89
96
  indexUiState: indexUiState,
90
97
  setIndexUiState: setIndexUiState,
91
98
  addToolResult: boundAddToolResult,
99
+ applyFilters: tool.applyFilters,
92
100
  onClose: onClose
93
101
  }));
94
102
  }
@@ -1,3 +1,4 @@
1
+ import type { SearchParameters } from 'algoliasearch-helper';
1
2
  export type ChatStatus = 'ready' | 'submitted' | 'streaming' | 'error';
2
3
  export type ChatRole = 'data' | 'user' | 'assistant' | 'system';
3
4
  /**
@@ -349,12 +350,22 @@ export interface AbstractChat<TUIMessage extends UIMessage> {
349
350
  }
350
351
  export type AddToolResult = AbstractChat<UIMessage>['addToolResult'];
351
352
  export type AddToolResultWithOutput = (params: Pick<Parameters<AddToolResult>[0], 'output'>) => ReturnType<AddToolResult>;
353
+ export type SearchToolInput = {
354
+ query: string;
355
+ number_of_results?: number;
356
+ facet_filters?: string[][];
357
+ };
358
+ export type ApplyFiltersParams = {
359
+ query?: string;
360
+ facetFilters?: string[][];
361
+ };
352
362
  export type ClientSideToolComponentProps = {
353
363
  message: ChatToolMessage;
354
364
  indexUiState: object;
355
365
  setIndexUiState: (state: object) => void;
356
366
  onClose: () => void;
357
367
  addToolResult: AddToolResultWithOutput;
368
+ applyFilters: (params: ApplyFiltersParams) => SearchParameters;
358
369
  };
359
370
  export type ClientSideToolComponent = (props: ClientSideToolComponentProps) => JSX.Element;
360
371
  export type ClientSideTool = {
@@ -363,8 +374,9 @@ export type ClientSideTool = {
363
374
  onToolCall?: (params: Parameters<NonNullable<ChatInit<UIMessage>['onToolCall']>>[0]['toolCall'] & {
364
375
  addToolResult: AddToolResultWithOutput;
365
376
  }) => void;
377
+ applyFilters: (params: ApplyFiltersParams) => SearchParameters;
366
378
  };
367
379
  export type ClientSideTools = Record<string, ClientSideTool>;
368
- export type UserClientSideTool = Omit<ClientSideTool, 'addToolResult'>;
380
+ export type UserClientSideTool = Omit<ClientSideTool, 'addToolResult' | 'applyFilters'>;
369
381
  export type UserClientSideTools = Record<string, UserClientSideTool>;
370
382
  export {};
@@ -1,2 +1,2 @@
1
- declare const _default: "0.17.1";
1
+ declare const _default: "0.19.0";
2
2
  export default _default;
@@ -1 +1 @@
1
- export default '0.17.1';
1
+ export default '0.19.0';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "instantsearch-ui-components",
3
- "version": "0.17.1",
3
+ "version": "0.19.0",
4
4
  "description": "Common UI components for InstantSearch.",
5
5
  "types": "dist/es/index.d.ts",
6
6
  "main": "dist/cjs/index.js",
@@ -52,5 +52,5 @@
52
52
  "zod": "^3.25.76 || ^4",
53
53
  "zod-to-json-schema": "3.24.6"
54
54
  },
55
- "gitHead": "d40d81bc9232c88f0dba1fdaada8471237f31847"
55
+ "gitHead": "b1d19a647b42add5bbf0a5b70bd2705d3b6ca92e"
56
56
  }