@docsearch/react 4.6.3 → 5.0.0-beta.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 (79) hide show
  1. package/README.md +0 -2
  2. package/dist/esm/AskAiScreenState-D0IZsCMJ.d.ts +106 -0
  3. package/dist/esm/DocSearch-Dq5Utfyb.d.ts +295 -0
  4. package/dist/esm/DocSearchAskAiModal-BwbMrrHv.d.ts +48 -0
  5. package/dist/esm/DocSearchAskAiModal-CCrk6YLb.js +954 -0
  6. package/dist/esm/DocSearchAskAiModal-CCrk6YLb.js.map +1 -0
  7. package/dist/esm/DocSearchButton-CRlNPf5k.d.ts +18 -0
  8. package/dist/esm/DocSearchButton-CaxxOzQU.js +71 -0
  9. package/dist/esm/DocSearchButton-CaxxOzQU.js.map +1 -0
  10. package/dist/esm/DocSearchModal-CpvDjo1O.js +250 -0
  11. package/dist/esm/DocSearchModal-CpvDjo1O.js.map +1 -0
  12. package/dist/esm/DocSearchTheme-DvL4mf0D.d.ts +5 -0
  13. package/dist/esm/askaiModal.d.ts +2 -0
  14. package/dist/esm/askaiModal.js +3 -0
  15. package/dist/esm/button.d.ts +2 -0
  16. package/dist/esm/button.js +3 -0
  17. package/dist/esm/docsearchAi.d.ts +220 -0
  18. package/dist/esm/docsearchAi.js +34 -0
  19. package/dist/esm/docsearchAi.js.map +1 -0
  20. package/dist/esm/index-Dl8FMlR5.d.ts +223 -0
  21. package/dist/esm/index.d.ts +9 -655
  22. package/dist/esm/index.js +35 -3
  23. package/dist/esm/index.js.map +1 -0
  24. package/dist/esm/keyboard-BkSdCzTU.js +9 -0
  25. package/dist/esm/keyboard-BkSdCzTU.js.map +1 -0
  26. package/dist/esm/keyboardShortcuts-C-lx6Xt7.js +25 -0
  27. package/dist/esm/keyboardShortcuts-C-lx6Xt7.js.map +1 -0
  28. package/dist/esm/modal.d.ts +2 -0
  29. package/dist/esm/modal.js +3 -0
  30. package/dist/esm/normalizeDocSearchIndexes-DAzlMybx.js +1240 -0
  31. package/dist/esm/normalizeDocSearchIndexes-DAzlMybx.js.map +1 -0
  32. package/dist/esm/objectSpread2-BNmiQYyW.js +67 -0
  33. package/dist/esm/objectWithoutProperties-phqYxDS0.js +53 -0
  34. package/dist/esm/objectWithoutProperties-phqYxDS0.js.map +1 -0
  35. package/dist/esm/sidepanel.d.ts +395 -0
  36. package/dist/esm/sidepanel.js +773 -0
  37. package/dist/esm/sidepanel.js.map +1 -0
  38. package/dist/esm/useDocSearchKeyboardEvents-68G8dw6c.d.ts +43 -0
  39. package/dist/esm/useDocSearchKeyboardEvents.d.ts +2 -41
  40. package/dist/esm/useDocSearchKeyboardEvents.js +43 -1
  41. package/dist/esm/useDocSearchKeyboardEvents.js.map +1 -0
  42. package/dist/esm/useSearchClient-mIHVB6ga.js +433 -0
  43. package/dist/esm/useSearchClient-mIHVB6ga.js.map +1 -0
  44. package/dist/esm/useSuggestedQuestions-D2TGVPsI.js +1112 -0
  45. package/dist/esm/useSuggestedQuestions-D2TGVPsI.js.map +1 -0
  46. package/dist/esm/useTheme.d.ts +7 -6
  47. package/dist/esm/useTheme.js +21 -1
  48. package/dist/esm/useTheme.js.map +1 -0
  49. package/dist/esm/version.d.ts +4 -2
  50. package/dist/esm/version.js +6 -1
  51. package/dist/esm/version.js.map +1 -0
  52. package/dist/umd/index.js +175 -5
  53. package/dist/umd/index.js.map +1 -1
  54. package/package.json +31 -34
  55. package/style/askai.js +1 -0
  56. package/button.js +0 -1
  57. package/dist/esm/DocSearchButton.d.ts +0 -18
  58. package/dist/esm/DocSearchButton.js +0 -1
  59. package/dist/esm/DocSearchModal.d.ts +0 -444
  60. package/dist/esm/DocSearchModal.js +0 -3
  61. package/dist/esm/Sidepanel.d.ts +0 -371
  62. package/dist/esm/Sidepanel.js +0 -3
  63. package/dist/umd/DocSearchModal.js +0 -5
  64. package/dist/umd/DocSearchModal.js.map +0 -1
  65. package/dist/umd/DocsearchButton.js +0 -3
  66. package/dist/umd/DocsearchButton.js.map +0 -1
  67. package/dist/umd/Sidepanel.js +0 -5
  68. package/dist/umd/Sidepanel.js.map +0 -1
  69. package/dist/umd/useDocSearchKeyboardEvents.js +0 -3
  70. package/dist/umd/useDocSearchKeyboardEvents.js.map +0 -1
  71. package/dist/umd/useTheme.js +0 -3
  72. package/dist/umd/useTheme.js.map +0 -1
  73. package/dist/umd/version.js +0 -3
  74. package/dist/umd/version.js.map +0 -1
  75. package/modal.js +0 -1
  76. package/sidepanel.js +0 -1
  77. package/useDocSearchKeyboardEvents.js +0 -1
  78. package/useTheme.js +0 -1
  79. package/version.js +0 -1
@@ -0,0 +1,1240 @@
1
+ import { t as _objectSpread2 } from "./objectSpread2-BNmiQYyW.js";
2
+ import { n as SearchIcon, t as _objectWithoutProperties } from "./objectWithoutProperties-phqYxDS0.js";
3
+ import { a as AlgoliaLogo, c as SourceIcon, d as _objectDestructuringEmpty, f as RecentIcon, i as manageLocalStorageQuota, l as CloseIcon, m as LoadingIcon, p as SparklesIcon, r as createStoredSearches, u as _extends } from "./useSearchClient-mIHVB6ga.js";
4
+ import React, { createElement, useMemo, useState } from "react";
5
+ import { useTheme } from "@docsearch/core/useTheme";
6
+ import { Menu } from "@base-ui/react/menu";
7
+
8
+ //#region src/utils/capitalize.ts
9
+ function capitalize(text) {
10
+ return `${text.charAt(0).toLocaleUpperCase()}${text.substring(1)}`;
11
+ }
12
+
13
+ //#endregion
14
+ //#region src/utils/collections.ts
15
+ const SOURCE_IDS = {
16
+ askAI: "askAI",
17
+ favoriteSearches: "favoriteSearches",
18
+ recentConversations: "recentConversations",
19
+ recentSearches: "recentSearches"
20
+ };
21
+ function getCollection(state, sourceId) {
22
+ return state.collections.find((collection) => (collection === null || collection === void 0 ? void 0 : collection.source.sourceId) === sourceId);
23
+ }
24
+
25
+ //#endregion
26
+ //#region src/utils/decodeHtmlEntities.ts
27
+ function decodeHtmlEntities(text) {
28
+ return text.replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&quot;/g, "\"").replace(/&#039;/g, "'").replace(/&amp;/g, "&");
29
+ }
30
+
31
+ //#endregion
32
+ //#region src/utils/getHitItemBreadcrumbs.ts
33
+ const LEVELS = [
34
+ "lvl0",
35
+ "lvl1",
36
+ "lvl2",
37
+ "lvl3",
38
+ "lvl4",
39
+ "lvl5",
40
+ "lvl6"
41
+ ];
42
+ function getHitItemBreadcrumbs(item) {
43
+ const currentIndex = item.type === "content" || item.type === "askAI" ? LEVELS.length : LEVELS.indexOf(item.type);
44
+ return LEVELS.slice(0, currentIndex).map((lvl) => item.hierarchy[lvl] ? decodeHtmlEntities(item.hierarchy[lvl]) : null).filter(Boolean).join(" > ");
45
+ }
46
+
47
+ //#endregion
48
+ //#region src/utils/getNestedValue.ts
49
+ const segmentsCache = /* @__PURE__ */ new Map();
50
+ function parseKey(key) {
51
+ const cachedKey = segmentsCache.get(key);
52
+ if (cachedKey) return cachedKey;
53
+ const segments = key.replace(/\[(\w+)\]/g, ".$1").replace(/^\/./, "").split(".");
54
+ segmentsCache.set(key, segments);
55
+ return segments;
56
+ }
57
+ function getNestedValue(obj, key) {
58
+ return parseKey(key).reduce((acc, curr) => {
59
+ if (acc && typeof acc === "object" && Object.prototype.hasOwnProperty.call(acc, curr)) return acc[curr];
60
+ }, obj);
61
+ }
62
+
63
+ //#endregion
64
+ //#region src/utils/groupBy.ts
65
+ function groupBy(values, predicate, maxResultsPerGroup) {
66
+ return values.reduce((acc, item) => {
67
+ const key = predicate(item);
68
+ if (!acc.hasOwnProperty(key)) acc[key] = [];
69
+ if (acc[key].length < (maxResultsPerGroup || 5)) acc[key].push(item);
70
+ return acc;
71
+ }, {});
72
+ }
73
+
74
+ //#endregion
75
+ //#region src/utils/identity.ts
76
+ function identity(x) {
77
+ return x;
78
+ }
79
+
80
+ //#endregion
81
+ //#region src/utils/isModifierEvent.ts
82
+ /**
83
+ * Detect when an event is modified with a special key to let the browser
84
+ * trigger its default behavior.
85
+ */
86
+ function isModifierEvent(event) {
87
+ return event.button === 1 || event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;
88
+ }
89
+
90
+ //#endregion
91
+ //#region src/utils/noop.ts
92
+ function noop(..._args) {}
93
+
94
+ //#endregion
95
+ //#region src/utils/removeHighlightTags.ts
96
+ const regexHighlightTags = /(<mark>|<\/mark>)/g;
97
+ const regexHasHighlightTags = RegExp(regexHighlightTags.source);
98
+ function removeHighlightTags(hit) {
99
+ var _internalDocSearchHit, _hit$_highlightResult;
100
+ const internalDocSearchHit = hit;
101
+ if (!internalDocSearchHit.__docsearch_parent && !hit._highlightResult) return hit.hierarchy.lvl0;
102
+ const lvl0 = internalDocSearchHit.__docsearch_parent ? (_internalDocSearchHit = internalDocSearchHit.__docsearch_parent) === null || _internalDocSearchHit === void 0 || (_internalDocSearchHit = _internalDocSearchHit._highlightResult) === null || _internalDocSearchHit === void 0 || (_internalDocSearchHit = _internalDocSearchHit.hierarchy) === null || _internalDocSearchHit === void 0 ? void 0 : _internalDocSearchHit.lvl0 : (_hit$_highlightResult = hit._highlightResult) === null || _hit$_highlightResult === void 0 || (_hit$_highlightResult = _hit$_highlightResult.hierarchy) === null || _hit$_highlightResult === void 0 ? void 0 : _hit$_highlightResult.lvl0;
103
+ if (!lvl0) return hit.hierarchy.lvl0;
104
+ return lvl0.value && regexHasHighlightTags.test(lvl0.value) ? lvl0.value.replace(regexHighlightTags, "") : lvl0.value;
105
+ }
106
+
107
+ //#endregion
108
+ //#region src/utils/scrollTo.ts
109
+ function scrollTo(el) {
110
+ if (typeof el.scrollTo === "function") el.scrollTo({
111
+ top: 0,
112
+ behavior: "smooth"
113
+ });
114
+ else el.scrollTop = 0;
115
+ }
116
+
117
+ //#endregion
118
+ //#region src/icons/SelectIcon.tsx
119
+ function SelectIcon() {
120
+ return /* @__PURE__ */ React.createElement("svg", {
121
+ className: "DocSearch-Hit-Select-Icon",
122
+ width: "20",
123
+ height: "20",
124
+ viewBox: "0 0 20 20"
125
+ }, /* @__PURE__ */ React.createElement("g", {
126
+ stroke: "currentColor",
127
+ fill: "none",
128
+ fillRule: "evenodd",
129
+ strokeLinecap: "round",
130
+ strokeLinejoin: "round"
131
+ }, /* @__PURE__ */ React.createElement("path", { d: "M18 3v4c0 2-2 4-4 4H2" }), /* @__PURE__ */ React.createElement("path", { d: "M8 17l-6-6 6-6" })));
132
+ }
133
+
134
+ //#endregion
135
+ //#region src/icons/ErrorIcon.tsx
136
+ function ErrorIcon() {
137
+ return /* @__PURE__ */ React.createElement("svg", {
138
+ width: "40",
139
+ height: "40",
140
+ viewBox: "0 0 20 20",
141
+ fill: "none",
142
+ fillRule: "evenodd",
143
+ stroke: "currentColor",
144
+ strokeLinecap: "round",
145
+ strokeLinejoin: "round"
146
+ }, /* @__PURE__ */ React.createElement("path", { d: "M19 4.8a16 16 0 00-2-1.2m-3.3-1.2A16 16 0 001.1 4.7M16.7 8a12 12 0 00-2.8-1.4M10 6a12 12 0 00-6.7 2M12.3 14.7a4 4 0 00-4.5 0M14.5 11.4A8 8 0 0010 10M3 16L18 2M10 18h0" }));
147
+ }
148
+
149
+ //#endregion
150
+ //#region src/icons/NoResultsIcon.tsx
151
+ function NoResultsIcon() {
152
+ return /* @__PURE__ */ React.createElement("svg", {
153
+ xmlns: "http://www.w3.org/2000/svg",
154
+ width: "64",
155
+ height: "64",
156
+ viewBox: "0 0 24 24",
157
+ fill: "none",
158
+ stroke: "#5a5e9a",
159
+ strokeWidth: "1.5",
160
+ strokeLinecap: "round",
161
+ strokeLinejoin: "round"
162
+ }, /* @__PURE__ */ React.createElement("path", { d: "m13.5 8.5-5 5" }), /* @__PURE__ */ React.createElement("path", { d: "m8.5 8.5 5 5" }), /* @__PURE__ */ React.createElement("circle", {
163
+ cx: "11",
164
+ cy: "11",
165
+ r: "8"
166
+ }), /* @__PURE__ */ React.createElement("path", { d: "m21 21-4.3-4.3" }));
167
+ }
168
+
169
+ //#endregion
170
+ //#region src/icons/PinIcon.tsx
171
+ function PinIcon() {
172
+ return /* @__PURE__ */ React.createElement("svg", {
173
+ xmlns: "http://www.w3.org/2000/svg",
174
+ width: "24",
175
+ height: "24",
176
+ viewBox: "0 0 24 24",
177
+ fill: "none",
178
+ stroke: "currentColor",
179
+ strokeWidth: "2",
180
+ strokeLinecap: "round",
181
+ strokeLinejoin: "round"
182
+ }, /* @__PURE__ */ React.createElement("path", { d: "M12 17v5" }), /* @__PURE__ */ React.createElement("path", { d: "M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2 2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z" }));
183
+ }
184
+
185
+ //#endregion
186
+ //#region src/icons/ChevronIcon.tsx
187
+ function ChevronIcon() {
188
+ return /* @__PURE__ */ React.createElement("svg", {
189
+ xmlns: "http://www.w3.org/2000/svg",
190
+ width: "24",
191
+ height: "24",
192
+ viewBox: "0 0 24 24",
193
+ fill: "none",
194
+ stroke: "currentColor",
195
+ strokeLinecap: "round",
196
+ strokeLinejoin: "round",
197
+ "aria-hidden": "true"
198
+ }, /* @__PURE__ */ React.createElement("polyline", { points: "6 9 12 15 18 9" }));
199
+ }
200
+
201
+ //#endregion
202
+ //#region src/icons/CheckIcon.tsx
203
+ function CheckIcon() {
204
+ return /* @__PURE__ */ React.createElement("svg", {
205
+ xmlns: "http://www.w3.org/2000/svg",
206
+ width: "24",
207
+ height: "24",
208
+ viewBox: "0 0 24 24",
209
+ fill: "none",
210
+ stroke: "currentColor",
211
+ strokeWidth: "2",
212
+ strokeLinecap: "round",
213
+ strokeLinejoin: "round",
214
+ "aria-hidden": "true"
215
+ }, /* @__PURE__ */ React.createElement("polyline", { points: "20 6 9 17 4 12" }));
216
+ }
217
+
218
+ //#endregion
219
+ //#region src/utils/facets.ts
220
+ const MAX_FACETS = 5;
221
+ function normalizeFacets(facets = []) {
222
+ const facetsMap = /* @__PURE__ */ new Map();
223
+ for (const facet of facets) {
224
+ const key = facet.key.trim().toLowerCase();
225
+ if (key.length === 0 || facetsMap.has(key)) continue;
226
+ if (facetsMap.size >= 5) break;
227
+ facetsMap.set(key, facet);
228
+ }
229
+ return Array.from(facetsMap.values());
230
+ }
231
+ function getFacetLabel(facet) {
232
+ if (facet.label) return facet.label;
233
+ return facet.key.replace(/[._-]+/g, " ").replace(/\b\w/g, (letter) => letter.toUpperCase());
234
+ }
235
+
236
+ //#endregion
237
+ //#region src/components/ui/Chip.tsx
238
+ const _excluded$6 = ["className", "type"];
239
+ function Chip({ children }) {
240
+ return /* @__PURE__ */ React.createElement("div", { className: "DocSearch-Chip" }, children);
241
+ }
242
+ function ChipDismiss(_ref) {
243
+ let { className, type = "button" } = _ref, props = _objectWithoutProperties(_ref, _excluded$6);
244
+ const cn = `DocSearch-Chip-Dismiss${className ? ` ${className}` : ""}`;
245
+ return /* @__PURE__ */ React.createElement("button", _objectSpread2({
246
+ type,
247
+ className: cn,
248
+ tabIndex: 0
249
+ }, props), /* @__PURE__ */ React.createElement(CloseIcon, { "aria-hidden": "true" }));
250
+ }
251
+ Chip.Dismiss = ChipDismiss;
252
+
253
+ //#endregion
254
+ //#region src/components/ui/Menu.tsx
255
+ const _excluded$5 = ["className"];
256
+ const _excluded2 = [
257
+ "align",
258
+ "alignOffset",
259
+ "side",
260
+ "sideOffset",
261
+ "collisionBoundary",
262
+ "container"
263
+ ];
264
+ const _excluded3 = ["className", "children"];
265
+ const _excluded4 = ["className"];
266
+ function Menu$1(_ref) {
267
+ let props = _extends({}, (_objectDestructuringEmpty(_ref), _ref));
268
+ return /* @__PURE__ */ React.createElement(Menu.Root, props);
269
+ }
270
+ function MenuTrigger(_ref2) {
271
+ let { className } = _ref2, props = _objectWithoutProperties(_ref2, _excluded$5);
272
+ const cn = `DocSearch-Menu-Trigger${className ? ` ${className}` : ""}`;
273
+ return /* @__PURE__ */ React.createElement(Menu.Trigger, _objectSpread2({ className: cn }, props));
274
+ }
275
+ Menu$1.Trigger = MenuTrigger;
276
+ function MenuPopup(_ref3) {
277
+ let { align = "start", alignOffset = 0, side = "bottom", sideOffset = 4, collisionBoundary = "clipping-ancestors", container } = _ref3, props = _objectWithoutProperties(_ref3, _excluded2);
278
+ return /* @__PURE__ */ React.createElement(Menu.Portal, { container }, /* @__PURE__ */ React.createElement(Menu.Positioner, {
279
+ className: "DocSearch-Menu-Positioner",
280
+ align,
281
+ alignOffset,
282
+ side,
283
+ sideOffset,
284
+ collisionBoundary
285
+ }, /* @__PURE__ */ React.createElement(Menu.Popup, _objectSpread2({ className: "DocSearch-Menu-Popup" }, props))));
286
+ }
287
+ Menu$1.Popup = MenuPopup;
288
+ function MenuRadioGroup(_ref4) {
289
+ let props = _extends({}, (_objectDestructuringEmpty(_ref4), _ref4));
290
+ return /* @__PURE__ */ React.createElement(Menu.RadioGroup, props);
291
+ }
292
+ Menu$1.RadioGroup = MenuRadioGroup;
293
+ function MenuRadioItem(_ref5) {
294
+ let { className, children } = _ref5, props = _objectWithoutProperties(_ref5, _excluded3);
295
+ const cn = `DocSearch-Menu-Item DocSearch-Menu-RadioItem${className ? ` ${className}` : ""}`;
296
+ return /* @__PURE__ */ React.createElement(Menu.RadioItem, _objectSpread2({
297
+ className: cn,
298
+ closeOnClick: true
299
+ }, props), /* @__PURE__ */ React.createElement("span", { className: "DocSearch-Menu-RadioItem-Indicator" }, /* @__PURE__ */ React.createElement(Menu.RadioItemIndicator, null, /* @__PURE__ */ React.createElement(CheckIcon, null))), children);
300
+ }
301
+ Menu$1.RadioItem = MenuRadioItem;
302
+ function MenuGroupLabel(_ref6) {
303
+ let { className } = _ref6, props = _objectWithoutProperties(_ref6, _excluded4);
304
+ const cn = `DocSearch-Menu-GroupLabel${className ? ` ${className}` : ""}`;
305
+ return /* @__PURE__ */ React.createElement(Menu.GroupLabel, _objectSpread2({ className: cn }, props));
306
+ }
307
+ Menu$1.GroupLabel = MenuGroupLabel;
308
+
309
+ //#endregion
310
+ //#region src/components/FacetBar.tsx
311
+ const FacetMenu = React.memo(function FacetMenu({ facet, selectedValue, defaultValueLabel, onSelectionChange, registerTrigger, menuTriggerSelectedAriaLabel }) {
312
+ const label = getFacetLabel(facet);
313
+ const handleValueChange = React.useCallback((value) => {
314
+ onSelectionChange(facet.key, value);
315
+ }, [facet.key, onSelectionChange]);
316
+ const triggerRef = React.useCallback((el) => {
317
+ registerTrigger(facet.key, el);
318
+ }, [facet.key, registerTrigger]);
319
+ return /* @__PURE__ */ React.createElement(Menu$1, null, /* @__PURE__ */ React.createElement(Menu$1.Trigger, {
320
+ ref: triggerRef,
321
+ "data-has-selection": Boolean(selectedValue),
322
+ "aria-label": selectedValue ? `${label}, ${selectedValue} ${menuTriggerSelectedAriaLabel}` : label
323
+ }, /* @__PURE__ */ React.createElement("span", null, capitalize(label)), /* @__PURE__ */ React.createElement(ChevronIcon, null)), /* @__PURE__ */ React.createElement(Menu$1.Popup, null, /* @__PURE__ */ React.createElement(Menu$1.RadioGroup, {
324
+ value: selectedValue,
325
+ onValueChange: handleValueChange
326
+ }, /* @__PURE__ */ React.createElement(Menu$1.RadioItem, {
327
+ value: "",
328
+ label: `${defaultValueLabel} ${label}`
329
+ }, defaultValueLabel), facet.values.map((value) => /* @__PURE__ */ React.createElement(Menu$1.RadioItem, {
330
+ key: value,
331
+ value,
332
+ label: value
333
+ }, capitalize(value))))));
334
+ });
335
+ const SelectedFacetChip = React.memo(function SelectedFacetChip({ facetKey, facetLabel, value, dismissAriaLabel, onDismiss }) {
336
+ const handleDismissFacet = React.useCallback((e) => {
337
+ onDismiss(facetKey, e);
338
+ }, [facetKey, onDismiss]);
339
+ return /* @__PURE__ */ React.createElement(Chip, null, capitalize(value), /* @__PURE__ */ React.createElement(Chip.Dismiss, {
340
+ "aria-label": `${dismissAriaLabel} ${capitalize(value)} (${facetLabel})`,
341
+ onClick: handleDismissFacet
342
+ }));
343
+ });
344
+ const FacetBar = React.memo(function FacetBar({ facets, selections, onSelectionChange, clearSelections, translations = {} }) {
345
+ const { defaultValueLabel = "All", facetMenuTriggerAriaLabel = "selected", clearAllLabel = "Clear all", facetsAriaLabel = "Search filters", selectedFacetsAriaLabel = "Selected search filters", clearFacetAriaLabel = "Clear filter:" } = translations;
346
+ const selectionsToDisplay = React.useMemo(() => {
347
+ return Object.entries(selections).filter(([_, value]) => Boolean(value));
348
+ }, [selections]);
349
+ const triggerRefs = React.useRef(/* @__PURE__ */ new Map());
350
+ const registerTrigger = React.useCallback((facetKey, el) => {
351
+ if (el) triggerRefs.current.set(facetKey, el);
352
+ else triggerRefs.current.delete(facetKey);
353
+ }, []);
354
+ const handleDismissFacet = React.useCallback((facetKey, ev) => {
355
+ const dismissButton = ev.currentTarget;
356
+ const selectionBar = dismissButton.closest(".DocSearch-FacetSelectionBar");
357
+ if (selectionBar) {
358
+ var _ref, _dismissButtons;
359
+ const dismissButtons = Array.from(selectionBar.querySelectorAll(".DocSearch-Chip-Dismiss"));
360
+ const index = dismissButtons.indexOf(dismissButton);
361
+ const target = (_ref = (_dismissButtons = dismissButtons[index + 1]) !== null && _dismissButtons !== void 0 ? _dismissButtons : dismissButtons[index - 1]) !== null && _ref !== void 0 ? _ref : triggerRefs.current.get(facetKey);
362
+ target === null || target === void 0 || target.focus();
363
+ }
364
+ onSelectionChange(facetKey, "");
365
+ }, [onSelectionChange]);
366
+ const handleClearAll = React.useCallback(() => {
367
+ var _triggerRefs$current$;
368
+ (_triggerRefs$current$ = triggerRefs.current.values().next().value) === null || _triggerRefs$current$ === void 0 || _triggerRefs$current$.focus();
369
+ clearSelections();
370
+ }, [clearSelections]);
371
+ const facetLabels = React.useMemo(() => new Map(facets.map((f) => [f.key, getFacetLabel(f)])), [facets]);
372
+ if (facets.length === 0) return null;
373
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("div", {
374
+ className: "DocSearch-FacetBar",
375
+ role: "group",
376
+ "aria-label": facetsAriaLabel
377
+ }, facets.map((facet) => {
378
+ var _selections$facet$key;
379
+ const selectedValue = (_selections$facet$key = selections[facet.key]) !== null && _selections$facet$key !== void 0 ? _selections$facet$key : "";
380
+ return /* @__PURE__ */ React.createElement(FacetMenu, {
381
+ key: facet.key,
382
+ facet,
383
+ selectedValue,
384
+ defaultValueLabel,
385
+ registerTrigger,
386
+ menuTriggerSelectedAriaLabel: facetMenuTriggerAriaLabel,
387
+ onSelectionChange
388
+ });
389
+ })), selectionsToDisplay.length > 0 && /* @__PURE__ */ React.createElement("div", {
390
+ className: "DocSearch-FacetSelectionBar",
391
+ role: "group",
392
+ "aria-label": selectedFacetsAriaLabel
393
+ }, selectionsToDisplay.map(([key, value]) => {
394
+ var _facetLabels$get;
395
+ return /* @__PURE__ */ React.createElement(SelectedFacetChip, {
396
+ key,
397
+ facetKey: key,
398
+ facetLabel: (_facetLabels$get = facetLabels.get(key)) !== null && _facetLabels$get !== void 0 ? _facetLabels$get : key,
399
+ value,
400
+ dismissAriaLabel: clearFacetAriaLabel,
401
+ onDismiss: handleDismissFacet
402
+ });
403
+ }), /* @__PURE__ */ React.createElement("button", {
404
+ type: "button",
405
+ className: "DocSearch-FacetSelectionBar-Action",
406
+ onClick: handleClearAll
407
+ }, clearAllLabel)));
408
+ });
409
+
410
+ //#endregion
411
+ //#region src/components/ui/SearchBoxForm.tsx
412
+ const _excluded$4 = [
413
+ "actionsBeforeClose",
414
+ "autoFocus",
415
+ "clearButtonAriaLabel",
416
+ "clearButtonTitle",
417
+ "closeButtonAriaLabel",
418
+ "closeButtonText",
419
+ "hideInput",
420
+ "inputOverlay",
421
+ "inputProps",
422
+ "inputRef",
423
+ "isFromSelection",
424
+ "leadingElement",
425
+ "onClose",
426
+ "placeholder",
427
+ "searchInputLabel",
428
+ "state"
429
+ ];
430
+ function SearchBoxForm(_ref) {
431
+ let { actionsBeforeClose, autoFocus, clearButtonAriaLabel, clearButtonTitle, closeButtonAriaLabel, closeButtonText, hideInput, inputOverlay, inputProps, inputRef, isFromSelection, leadingElement, onClose, placeholder, searchInputLabel, state } = _ref, autocomplete = _objectWithoutProperties(_ref, _excluded$4);
432
+ const { onReset } = autocomplete.getFormProps({ inputElement: inputRef.current });
433
+ React.useEffect(() => {
434
+ if (autoFocus && inputRef.current) inputRef.current.focus();
435
+ }, [autoFocus, inputRef]);
436
+ React.useEffect(() => {
437
+ if (isFromSelection && inputRef.current) inputRef.current.select();
438
+ }, [isFromSelection, inputRef]);
439
+ const baseInputProps = autocomplete.getInputProps({
440
+ inputElement: inputRef.current,
441
+ autoFocus,
442
+ maxLength: 512
443
+ });
444
+ const isKeywordSearchLoading = state.status === "stalled";
445
+ return /* @__PURE__ */ React.createElement("form", {
446
+ className: "DocSearch-Form",
447
+ onSubmit: (event) => {
448
+ event.preventDefault();
449
+ },
450
+ onReset
451
+ }, leadingElement || (isKeywordSearchLoading ? /* @__PURE__ */ React.createElement("div", { className: "DocSearch-LoadingIndicator" }, /* @__PURE__ */ React.createElement(LoadingIcon, null)) : /* @__PURE__ */ React.createElement("label", _objectSpread2({ className: "DocSearch-MagnifierLabel" }, autocomplete.getLabelProps()), /* @__PURE__ */ React.createElement(SearchIcon, null), /* @__PURE__ */ React.createElement("span", { className: "DocSearch-VisuallyHiddenForAccessibility" }, searchInputLabel))), inputOverlay, /* @__PURE__ */ React.createElement("input", _objectSpread2(_objectSpread2(_objectSpread2({
452
+ className: "DocSearch-Input",
453
+ ref: inputRef
454
+ }, baseInputProps), inputProps), {}, {
455
+ placeholder,
456
+ hidden: hideInput
457
+ })), /* @__PURE__ */ React.createElement("div", { className: "DocSearch-Actions" }, actionsBeforeClose, /* @__PURE__ */ React.createElement("button", {
458
+ type: "button",
459
+ title: closeButtonText,
460
+ className: "DocSearch-Action DocSearch-Close",
461
+ "aria-label": closeButtonAriaLabel,
462
+ onClick: onClose
463
+ }, /* @__PURE__ */ React.createElement(CloseIcon, null))));
464
+ }
465
+
466
+ //#endregion
467
+ //#region src/components/ui/ModalShell.tsx
468
+ function ModalShell({ state, containerRef, modalRef, formElementRef, dropdownRef, getRootProps, onClose, showDropdown, searchBox, filterBar, screenState, footer }) {
469
+ return /* @__PURE__ */ React.createElement("div", _objectSpread2(_objectSpread2({ ref: containerRef }, getRootProps({ "aria-expanded": true })), {}, {
470
+ className: [
471
+ "DocSearch",
472
+ "DocSearch-Container",
473
+ state.status === "stalled" && "DocSearch-Container--Stalled",
474
+ state.status === "error" && "DocSearch-Container--Errored"
475
+ ].filter(Boolean).join(" "),
476
+ role: "button",
477
+ tabIndex: 0,
478
+ onMouseDown: (event) => {
479
+ if (event.target === event.currentTarget) onClose();
480
+ }
481
+ }), /* @__PURE__ */ React.createElement("div", {
482
+ className: "DocSearch-Modal",
483
+ ref: modalRef
484
+ }, /* @__PURE__ */ React.createElement("header", {
485
+ className: "DocSearch-SearchBar",
486
+ ref: formElementRef
487
+ }, searchBox), filterBar, showDropdown && /* @__PURE__ */ React.createElement("div", {
488
+ className: "DocSearch-Dropdown",
489
+ ref: dropdownRef
490
+ }, screenState), /* @__PURE__ */ React.createElement("footer", { className: "DocSearch-Footer" }, footer)));
491
+ }
492
+
493
+ //#endregion
494
+ //#region src/Footer.tsx
495
+ function CommandIcon(props) {
496
+ return /* @__PURE__ */ React.createElement("svg", {
497
+ width: "20",
498
+ height: "20",
499
+ "aria-label": props.ariaLabel,
500
+ viewBox: "0 0 24 24",
501
+ role: "img"
502
+ }, /* @__PURE__ */ React.createElement("g", {
503
+ fill: "none",
504
+ stroke: "currentColor",
505
+ strokeLinecap: "round",
506
+ strokeLinejoin: "round",
507
+ strokeWidth: "1.4"
508
+ }, props.children));
509
+ }
510
+ function Footer({ translations = {}, isAskAiActive = false }) {
511
+ const { selectText = "Select", selectKeyAriaLabel = "Enter key", submitQuestionText = "Submit question", navigateText = "Navigate", navigateUpKeyAriaLabel = "Arrow up", navigateDownKeyAriaLabel = "Arrow down", closeText = "Close", backToSearchText = "Back to search", closeKeyAriaLabel = "Escape key", poweredByText = "Powered by" } = translations;
512
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("div", { className: "DocSearch-Logo" }, /* @__PURE__ */ React.createElement(AlgoliaLogo, { translations: { poweredByText } })), /* @__PURE__ */ React.createElement("ul", { className: "DocSearch-Commands" }, /* @__PURE__ */ React.createElement("li", null, /* @__PURE__ */ React.createElement("kbd", { className: "DocSearch-Commands-Key" }, /* @__PURE__ */ React.createElement(CommandIcon, { ariaLabel: navigateDownKeyAriaLabel }, /* @__PURE__ */ React.createElement("path", { d: "M12 5v14" }), /* @__PURE__ */ React.createElement("path", { d: "m19 12-7 7-7-7" }))), /* @__PURE__ */ React.createElement("kbd", { className: "DocSearch-Commands-Key" }, /* @__PURE__ */ React.createElement(CommandIcon, { ariaLabel: navigateUpKeyAriaLabel }, /* @__PURE__ */ React.createElement("path", { d: "m5 12 7-7 7 7" }), /* @__PURE__ */ React.createElement("path", { d: "M12 19V5" }))), /* @__PURE__ */ React.createElement("span", { className: "DocSearch-Label" }, navigateText)), /* @__PURE__ */ React.createElement("li", null, /* @__PURE__ */ React.createElement("kbd", { className: "DocSearch-Commands-Key" }, /* @__PURE__ */ React.createElement(CommandIcon, { ariaLabel: selectKeyAriaLabel }, /* @__PURE__ */ React.createElement("polyline", { points: "9 10 4 15 9 20" }), /* @__PURE__ */ React.createElement("path", { d: "M20 4v7a4 4 0 0 1-4 4H4" }))), /* @__PURE__ */ React.createElement("span", { className: "DocSearch-Label" }, isAskAiActive ? submitQuestionText : selectText)), /* @__PURE__ */ React.createElement("li", null, /* @__PURE__ */ React.createElement("kbd", { className: "DocSearch-Commands-Key" }, /* @__PURE__ */ React.createElement("span", { className: "DocSearch-Escape-Key" }, "ESC")), /* @__PURE__ */ React.createElement("span", {
513
+ className: "DocSearch-Label",
514
+ "aria-label": closeKeyAriaLabel
515
+ }, isAskAiActive ? backToSearchText : closeText))));
516
+ }
517
+
518
+ //#endregion
519
+ //#region src/Hit.tsx
520
+ function Hit({ hit, children }) {
521
+ return /* @__PURE__ */ React.createElement("a", { href: hit.url }, children);
522
+ }
523
+
524
+ //#endregion
525
+ //#region src/useFacetValues.ts
526
+ function useFacetValues({ facets, indexes, searchClient }) {
527
+ const [facetValues, setFacetValues] = React.useState({});
528
+ const stableFacetKeys = facets.map((facet) => facet.key).join(",");
529
+ const stableIndexes = JSON.stringify(indexes.map((index) => {
530
+ var _index$searchParamete;
531
+ return [index.name, (_index$searchParamete = index.searchParameters) !== null && _index$searchParamete !== void 0 ? _index$searchParamete : null];
532
+ }));
533
+ React.useEffect(() => {
534
+ let isMounted = true;
535
+ const facetKeys = stableFacetKeys ? stableFacetKeys.split(",") : [];
536
+ if (facetKeys.length === 0 || indexes.length === 0) {
537
+ setFacetValues({});
538
+ return () => {
539
+ isMounted = false;
540
+ };
541
+ }
542
+ searchClient.search({ requests: indexes.map((index) => {
543
+ var _index$searchParamete2;
544
+ return _objectSpread2(_objectSpread2({}, (_index$searchParamete2 = index.searchParameters) !== null && _index$searchParamete2 !== void 0 ? _index$searchParamete2 : {}), {}, {
545
+ indexName: index.name,
546
+ query: "",
547
+ hitsPerPage: 0,
548
+ facets: facetKeys
549
+ });
550
+ }) }).then(({ results }) => {
551
+ if (!isMounted) return;
552
+ const valuesByFacet = facetKeys.reduce((acc, facet) => {
553
+ acc[facet] = [];
554
+ return acc;
555
+ }, {});
556
+ results.forEach((res) => {
557
+ var _result$facets;
558
+ Object.entries((_result$facets = res.facets) !== null && _result$facets !== void 0 ? _result$facets : {}).forEach(([facet, values]) => {
559
+ if (!valuesByFacet[facet]) return;
560
+ valuesByFacet[facet] = Array.from(/* @__PURE__ */ new Set([...valuesByFacet[facet], ...Object.keys(values)])).sort();
561
+ });
562
+ });
563
+ setFacetValues(valuesByFacet);
564
+ }).catch(() => {
565
+ if (isMounted) setFacetValues({});
566
+ });
567
+ return () => {
568
+ isMounted = false;
569
+ };
570
+ }, [
571
+ stableFacetKeys,
572
+ stableIndexes,
573
+ searchClient
574
+ ]);
575
+ return facetValues;
576
+ }
577
+
578
+ //#endregion
579
+ //#region src/hooks/useDocSearchFacets.ts
580
+ function useDocSearchFacets({ facets, indexes, searchClient, onSelectionsChange }) {
581
+ const normalizedFacets = React.useMemo(() => normalizeFacets(facets), [facets]);
582
+ const facetValues = useFacetValues({
583
+ facets: normalizedFacets,
584
+ indexes,
585
+ searchClient
586
+ });
587
+ const [facetSelections, setFacetSelections] = React.useState({});
588
+ const facetSelectionsRef = React.useRef(facetSelections);
589
+ const onSelectionsChangeRef = React.useRef(onSelectionsChange);
590
+ onSelectionsChangeRef.current = onSelectionsChange;
591
+ const visibleFacets = React.useMemo(() => normalizedFacets.map((facet) => {
592
+ var _facetValues$facet$ke;
593
+ return _objectSpread2(_objectSpread2({}, facet), {}, { values: (_facetValues$facet$ke = facetValues[facet.key]) !== null && _facetValues$facet$ke !== void 0 ? _facetValues$facet$ke : [] });
594
+ }).filter((facet) => facet.values.length > 0), [facetValues, normalizedFacets]);
595
+ const applySelections = React.useCallback((next) => {
596
+ var _onSelectionsChangeRe;
597
+ facetSelectionsRef.current = next;
598
+ setFacetSelections(next);
599
+ (_onSelectionsChangeRe = onSelectionsChangeRef.current) === null || _onSelectionsChangeRe === void 0 || _onSelectionsChangeRe.call(onSelectionsChangeRef);
600
+ }, []);
601
+ return {
602
+ visibleFacets,
603
+ facetSelections,
604
+ facetSelectionsRef,
605
+ handleFacetSelectionChange: React.useCallback((facet, value) => {
606
+ if (facetSelectionsRef.current[facet] === value) return;
607
+ const next = _objectSpread2({}, facetSelectionsRef.current);
608
+ if (value === "") delete next[facet];
609
+ else next[facet] = value;
610
+ applySelections(next);
611
+ }, [applySelections]),
612
+ clearFacetSelections: React.useCallback(() => {
613
+ if (Object.keys(facetSelectionsRef.current).length === 0) return;
614
+ applySelections({});
615
+ }, [applySelections])
616
+ };
617
+ }
618
+
619
+ //#endregion
620
+ //#region src/hooks/useDocSearchInsights.ts
621
+ function useSendItemClickEvent(state) {
622
+ return React.useCallback((item) => {
623
+ if (!state.context.algoliaInsightsPlugin || !item.__autocomplete_id) return;
624
+ const insightsItem = item;
625
+ state.context.algoliaInsightsPlugin.insights.clickedObjectIDsAfterSearch({
626
+ eventName: "Item Selected",
627
+ index: insightsItem.__autocomplete_indexName,
628
+ items: [insightsItem],
629
+ positions: [item.__autocomplete_id],
630
+ queryID: insightsItem.__autocomplete_queryID
631
+ });
632
+ }, [state.context.algoliaInsightsPlugin]);
633
+ }
634
+
635
+ //#endregion
636
+ //#region src/hooks/useInitialModalQuery.ts
637
+ function useInitialModalQuery(initialQueryFromProp) {
638
+ const initialQueryFromSelection = React.useRef(typeof window !== "undefined" ? window.getSelection().toString().slice(0, 512) : "").current;
639
+ return {
640
+ initialQuery: React.useRef(initialQueryFromProp || initialQueryFromSelection).current,
641
+ initialQueryFromSelection
642
+ };
643
+ }
644
+
645
+ //#endregion
646
+ //#region src/useTouchEvents.ts
647
+ function useTouchEvents({ getEnvironmentProps, panelElement, formElement, inputElement }) {
648
+ React.useEffect(() => {
649
+ if (!(panelElement && formElement && inputElement)) return;
650
+ const { onTouchStart, onTouchMove } = getEnvironmentProps({
651
+ panelElement,
652
+ formElement,
653
+ inputElement
654
+ });
655
+ window.addEventListener("touchstart", onTouchStart);
656
+ window.addEventListener("touchmove", onTouchMove);
657
+ return () => {
658
+ window.removeEventListener("touchstart", onTouchStart);
659
+ window.removeEventListener("touchmove", onTouchMove);
660
+ };
661
+ }, [
662
+ getEnvironmentProps,
663
+ panelElement,
664
+ formElement,
665
+ inputElement
666
+ ]);
667
+ }
668
+
669
+ //#endregion
670
+ //#region src/useTrapFocus.ts
671
+ function useTrapFocus({ container }) {
672
+ React.useEffect(() => {
673
+ if (!container) return;
674
+ const focusableElements = container.querySelectorAll("a[href]:not([disabled]), button:not([disabled]), input:not([disabled])");
675
+ const firstElement = focusableElements[0];
676
+ const lastElement = focusableElements[focusableElements.length - 1];
677
+ function trapFocus(event) {
678
+ if (event.key !== "Tab") return;
679
+ if (event.shiftKey) {
680
+ if (document.activeElement === firstElement) {
681
+ event.preventDefault();
682
+ lastElement.focus();
683
+ }
684
+ } else if (document.activeElement === lastElement) {
685
+ event.preventDefault();
686
+ firstElement.focus();
687
+ }
688
+ }
689
+ container.addEventListener("keydown", trapFocus);
690
+ return () => {
691
+ container.removeEventListener("keydown", trapFocus);
692
+ };
693
+ }, [container]);
694
+ }
695
+
696
+ //#endregion
697
+ //#region src/hooks/useDocSearchModalEffects.ts
698
+ function useDocSearchModalEffects({ initialScrollY, modalRef, snippetLength, theme }) {
699
+ useTheme({ theme });
700
+ React.useEffect(() => {
701
+ document.body.classList.add("DocSearch--active");
702
+ return () => {
703
+ var _window$scrollTo, _window;
704
+ document.body.classList.remove("DocSearch--active");
705
+ (_window$scrollTo = (_window = window).scrollTo) === null || _window$scrollTo === void 0 || _window$scrollTo.call(_window, 0, initialScrollY);
706
+ };
707
+ }, [initialScrollY]);
708
+ React.useEffect(() => {
709
+ manageLocalStorageQuota();
710
+ }, []);
711
+ React.useLayoutEffect(() => {
712
+ const scrollBarWidth = window.innerWidth - document.body.clientWidth;
713
+ document.body.style.marginInlineEnd = `${scrollBarWidth}px`;
714
+ return () => {
715
+ document.body.style.marginInlineEnd = "0px";
716
+ };
717
+ }, []);
718
+ React.useEffect(() => {
719
+ if (window.matchMedia("(max-width: 768px)").matches) snippetLength.current = 5;
720
+ }, [snippetLength]);
721
+ React.useEffect(() => {
722
+ function setFullViewportHeight() {
723
+ if (modalRef.current) {
724
+ const vh = window.innerHeight * .01;
725
+ modalRef.current.style.setProperty("--docsearch-vh", `${vh}px`);
726
+ }
727
+ }
728
+ setFullViewportHeight();
729
+ window.addEventListener("resize", setFullViewportHeight);
730
+ return () => {
731
+ window.removeEventListener("resize", setFullViewportHeight);
732
+ };
733
+ }, [modalRef]);
734
+ }
735
+
736
+ //#endregion
737
+ //#region src/hooks/useModalEnvironment.ts
738
+ function useModalEnvironment({ getEnvironmentProps, containerRef, dropdownRef, formElementRef, inputRef, initialScrollY, modalRef, snippetLength, theme }) {
739
+ useTouchEvents({
740
+ getEnvironmentProps,
741
+ panelElement: dropdownRef.current,
742
+ formElement: formElementRef.current,
743
+ inputElement: inputRef.current
744
+ });
745
+ useTrapFocus({ container: containerRef.current });
746
+ useDocSearchModalEffects({
747
+ initialScrollY,
748
+ modalRef,
749
+ snippetLength,
750
+ theme
751
+ });
752
+ }
753
+
754
+ //#endregion
755
+ //#region src/hooks/useModalRefs.ts
756
+ function useModalRefs() {
757
+ return {
758
+ containerRef: React.useRef(null),
759
+ modalRef: React.useRef(null),
760
+ formElementRef: React.useRef(null),
761
+ dropdownRef: React.useRef(null),
762
+ inputRef: React.useRef(null),
763
+ snippetLength: React.useRef(15)
764
+ };
765
+ }
766
+
767
+ //#endregion
768
+ //#region src/hooks/useRefreshOnInitialQuery.ts
769
+ function useRefreshOnInitialQuery({ initialQuery, inputRef, refresh }) {
770
+ React.useEffect(() => {
771
+ if (initialQuery.length > 0) {
772
+ refresh();
773
+ if (inputRef.current) inputRef.current.focus();
774
+ }
775
+ }, [
776
+ initialQuery,
777
+ inputRef,
778
+ refresh
779
+ ]);
780
+ }
781
+
782
+ //#endregion
783
+ //#region src/hooks/useSaveRecentSearch.ts
784
+ function createSyntheticParent(item) {
785
+ const hierarchy = item.hierarchy;
786
+ const deepestLevel = [
787
+ "lvl6",
788
+ "lvl5",
789
+ "lvl4",
790
+ "lvl3",
791
+ "lvl2",
792
+ "lvl1",
793
+ "lvl0"
794
+ ].find((level) => hierarchy[level]);
795
+ return _objectSpread2(_objectSpread2({}, item), {}, {
796
+ type: deepestLevel || "lvl0",
797
+ content: null
798
+ });
799
+ }
800
+ function useSaveRecentSearch({ favoriteSearches, recentSearches, disableUserPersonalization }) {
801
+ return React.useCallback(function saveRecentSearch(item) {
802
+ if (disableUserPersonalization) return;
803
+ const search = item.type === "content" ? item.__docsearch_parent || createSyntheticParent(item) : item;
804
+ if (search && favoriteSearches.getAll().findIndex((x) => x.objectID === search.objectID) === -1) recentSearches.add(search);
805
+ }, [
806
+ favoriteSearches,
807
+ recentSearches,
808
+ disableUserPersonalization
809
+ ]);
810
+ }
811
+
812
+ //#endregion
813
+ //#region src/hooks/useStoredDocSearches.ts
814
+ function useStoredDocSearches({ defaultIndexName, recentSearchesLimit, recentSearchesWithFavoritesLimit }) {
815
+ const favoriteSearches = React.useRef(createStoredSearches({
816
+ key: `__DOCSEARCH_FAVORITE_SEARCHES__${defaultIndexName}`,
817
+ limit: 10
818
+ })).current;
819
+ return {
820
+ favoriteSearches,
821
+ recentSearches: React.useRef(createStoredSearches({
822
+ key: `__DOCSEARCH_RECENT_SEARCHES__${defaultIndexName}`,
823
+ limit: favoriteSearches.getAll().length === 0 ? recentSearchesLimit : recentSearchesWithFavoritesLimit
824
+ })).current
825
+ };
826
+ }
827
+
828
+ //#endregion
829
+ //#region src/components/ui/HitContent.tsx
830
+ function HitContent({ title, subText }) {
831
+ return /* @__PURE__ */ React.createElement("div", { className: "DocSearch-Hit-content-wrapper" }, /* @__PURE__ */ React.createElement("span", { className: "DocSearch-Hit-title" }, title), /* @__PURE__ */ React.createElement("span", { className: "DocSearch-Hit-path" }, subText));
832
+ }
833
+
834
+ //#endregion
835
+ //#region src/hooks/useRelativeFormattedDate.ts
836
+ const MS_IN_SECOND = 1e3;
837
+ const MS_IN_MINUTE = MS_IN_SECOND * 60;
838
+ const MS_IN_HOUR = MS_IN_MINUTE * 60;
839
+ const UNITS = [
840
+ [MS_IN_HOUR * 24, "day"],
841
+ [MS_IN_HOUR, "hour"],
842
+ [MS_IN_MINUTE, "minute"],
843
+ [MS_IN_SECOND, "second"]
844
+ ];
845
+ function useRelativeFormattedDate(start, end = Date.now()) {
846
+ const [diff] = useState(() => {
847
+ var _UNITS$find;
848
+ const elapsed = Math.abs(Number(end) - Number(start));
849
+ const [ms, unit] = (_UNITS$find = UNITS.find(([threshold]) => elapsed >= threshold)) !== null && _UNITS$find !== void 0 ? _UNITS$find : UNITS[UNITS.length - 1];
850
+ return [Math.floor(elapsed / ms), unit];
851
+ });
852
+ const formattedDate = useMemo(() => {
853
+ const locale = typeof navigator !== "undefined" ? navigator.language : void 0;
854
+ const [elapsedTime, elapsedUnit] = diff;
855
+ return new Intl.RelativeTimeFormat(locale, { style: "long" }).format(elapsedTime * -1, elapsedUnit);
856
+ }, [diff]);
857
+ return start ? formattedDate : null;
858
+ }
859
+
860
+ //#endregion
861
+ //#region src/Snippet.tsx
862
+ const _excluded$3 = [
863
+ "hit",
864
+ "attribute",
865
+ "tagName"
866
+ ];
867
+ function getPropertyByPath(object, path) {
868
+ return path.split(".").reduce((prev, current) => {
869
+ if (prev === null || prev === void 0 ? void 0 : prev[current]) return prev[current];
870
+ return null;
871
+ }, object);
872
+ }
873
+ function Snippet(_ref) {
874
+ let { hit, attribute, tagName = "span" } = _ref;
875
+ return createElement(tagName, _objectSpread2(_objectSpread2({}, _objectWithoutProperties(_ref, _excluded$3)), {}, { dangerouslySetInnerHTML: { __html: getPropertyByPath(hit, `_snippetResult.${attribute}.value`) || getPropertyByPath(hit, attribute) } }));
876
+ }
877
+
878
+ //#endregion
879
+ //#region src/Results.tsx
880
+ function Results(props) {
881
+ var _props$sourceIcon;
882
+ const { askAiResultsTitle = "Ask AI Assistant" } = props.translations || {};
883
+ const askAiResultsId = React.useId();
884
+ const decodedTitle = React.useMemo(() => {
885
+ if (!props.title) return null;
886
+ return decodeHtmlEntities(props.title);
887
+ }, [props.title]);
888
+ if (!props.collection || props.collection.items.length === 0) return null;
889
+ if (props.collection.source.sourceId === SOURCE_IDS.askAI) return /* @__PURE__ */ React.createElement("section", { className: "DocSearch-Hits" }, /* @__PURE__ */ React.createElement("h2", {
890
+ id: askAiResultsId,
891
+ className: "DocSearch-Hit-source"
892
+ }, askAiResultsTitle), /* @__PURE__ */ React.createElement("ul", _objectSpread2(_objectSpread2({ className: "DocSearch-Hits-padded" }, props.getListProps({ source: props.collection.source })), {}, { "aria-labelledby": askAiResultsId }), props.collection.items.map((item) => /* @__PURE__ */ React.createElement(AskAiButton, _objectSpread2({
893
+ key: item.objectID,
894
+ item,
895
+ translations: props.translations
896
+ }, props)))));
897
+ if (props.collection.source.sourceId === SOURCE_IDS.recentConversations) return /* @__PURE__ */ React.createElement("section", { className: "DocSearch-Hits" }, /* @__PURE__ */ React.createElement("div", { className: "DocSearch-Hit-source" }, /* @__PURE__ */ React.createElement(SparklesIcon, null), decodedTitle), /* @__PURE__ */ React.createElement("ul", _objectSpread2({ className: "DocSearch-Hits-padded" }, props.getListProps({ source: props.collection.source })), props.collection.items.map((item, index) => {
898
+ return /* @__PURE__ */ React.createElement(Result, _objectSpread2({
899
+ key: [props.title, item.objectID].join(":"),
900
+ item,
901
+ index
902
+ }, props));
903
+ })));
904
+ return /* @__PURE__ */ React.createElement("section", { className: "DocSearch-Hits" }, /* @__PURE__ */ React.createElement("div", { className: "DocSearch-Hit-source" }, (_props$sourceIcon = props.sourceIcon) !== null && _props$sourceIcon !== void 0 ? _props$sourceIcon : null, decodedTitle), /* @__PURE__ */ React.createElement("ul", _objectSpread2({ className: "DocSearch-Hits-padded" }, props.getListProps({ source: props.collection.source })), props.collection.items.map((item, index) => {
905
+ return /* @__PURE__ */ React.createElement(Result, _objectSpread2({
906
+ key: [props.title, item.objectID].join(":"),
907
+ item,
908
+ index
909
+ }, props));
910
+ })));
911
+ }
912
+ function Result({ item, index, renderIcon, renderAction, getItemProps, onItemClick, collection, hitComponent, translations = {}, renderResultBadge }) {
913
+ const Hit = hitComponent;
914
+ const { recentConversationTimestampFallback = "A while ago" } = translations;
915
+ const titleAttribute = item.type === "content" ? "content" : `hierarchy.${item.type}`;
916
+ const breadcrumbs = getHitItemBreadcrumbs(item);
917
+ return /* @__PURE__ */ React.createElement("li", _objectSpread2({ className: ["DocSearch-Hit", item.__docsearch_parent && "DocSearch-Hit--Child"].filter(Boolean).join(" ") }, getItemProps({
918
+ item,
919
+ source: collection.source,
920
+ onClick(event) {
921
+ onItemClick(item, event);
922
+ }
923
+ })), /* @__PURE__ */ React.createElement(Hit, { hit: item }, /* @__PURE__ */ React.createElement("div", { className: "DocSearch-Hit-Container" }, renderIcon({
924
+ item,
925
+ index
926
+ }), item.type === "lvl0" && /* @__PURE__ */ React.createElement(HitContent, {
927
+ title: /* @__PURE__ */ React.createElement(Snippet, {
928
+ hit: item,
929
+ attribute: "hierarchy.lvl0"
930
+ }),
931
+ subText: /* @__PURE__ */ React.createElement(Snippet, {
932
+ hit: item,
933
+ attribute: "content"
934
+ })
935
+ }), item.type === "askAI" ? /* @__PURE__ */ React.createElement(AskAIResultContent, {
936
+ item,
937
+ relativeDateFallbackText: recentConversationTimestampFallback
938
+ }) : /* @__PURE__ */ React.createElement(HitContent, {
939
+ title: /* @__PURE__ */ React.createElement(Snippet, {
940
+ hit: item,
941
+ attribute: titleAttribute
942
+ }),
943
+ subText: breadcrumbs
944
+ }), renderResultBadge === null || renderResultBadge === void 0 ? void 0 : renderResultBadge({ item }), renderAction({ item }))));
945
+ }
946
+ function AskAIResultContent({ item, relativeDateFallbackText }) {
947
+ const relativeDate = useRelativeFormattedDate(item.hierarchy.lvl2 ? new Date(item.hierarchy.lvl2) : null);
948
+ return /* @__PURE__ */ React.createElement(HitContent, {
949
+ title: decodeHtmlEntities(item.hierarchy.lvl1 || ""),
950
+ subText: relativeDate || relativeDateFallbackText
951
+ });
952
+ }
953
+ function AskAiButton({ item, getItemProps, onItemClick, collection }) {
954
+ if (!item.query) return null;
955
+ return /* @__PURE__ */ React.createElement("li", _objectSpread2({ className: "DocSearch-Hit" }, getItemProps({
956
+ item,
957
+ source: collection.source,
958
+ onClick(event) {
959
+ onItemClick(item, event);
960
+ }
961
+ })), /* @__PURE__ */ React.createElement("div", { className: "DocSearch-Hit--AskAI" }, /* @__PURE__ */ React.createElement("div", { className: "DocSearch-Hit-AskAIButton DocSearch-Hit-Container" }, /* @__PURE__ */ React.createElement("div", { className: " DocSearch-Hit-AskAIButton-icon DocSearch-Hit-icon" }, /* @__PURE__ */ React.createElement(SparklesIcon, null)), /* @__PURE__ */ React.createElement("div", { className: "DocSearch-Hit-AskAIButton-title" }, /* @__PURE__ */ React.createElement("span", { className: "DocSearch-Hit-AskAIButton-title-query" }, item.query)))));
962
+ }
963
+
964
+ //#endregion
965
+ //#region src/components/ui/StoredSearchesSections.tsx
966
+ const _excluded$2 = ["translations"];
967
+ function StoredSearchesSections(_ref) {
968
+ let { translations = {} } = _ref, props = _objectWithoutProperties(_ref, _excluded$2);
969
+ const { recentSearchesTitle = "Recently viewed docs", saveRecentSearchButtonTitle = "Pin this search", removeRecentSearchButtonTitle = "Remove this search from history", favoriteSearchesTitle = "Pinned", removeFavoriteSearchButtonTitle = "Remove this saved search" } = translations;
970
+ const favoriteSearches = getCollection(props.state, "favoriteSearches");
971
+ const recentSearchesCollection = getCollection(props.state, "recentSearches");
972
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, favoriteSearches && /* @__PURE__ */ React.createElement(Results, _objectSpread2(_objectSpread2({}, props), {}, {
973
+ title: favoriteSearchesTitle,
974
+ collection: favoriteSearches,
975
+ sourceIcon: /* @__PURE__ */ React.createElement(PinIcon, null),
976
+ renderIcon: ({ item }) => /* @__PURE__ */ React.createElement("div", { className: "DocSearch-Hit-icon" }, /* @__PURE__ */ React.createElement(SourceIcon, { type: item.type })),
977
+ renderAction: ({ item }) => /* @__PURE__ */ React.createElement("div", { className: "DocSearch-Hit-action" }, /* @__PURE__ */ React.createElement("button", {
978
+ className: "DocSearch-Hit-action-button",
979
+ title: removeFavoriteSearchButtonTitle,
980
+ type: "submit",
981
+ onClick: (event) => {
982
+ event.preventDefault();
983
+ event.stopPropagation();
984
+ props.favoriteSearches.remove(item);
985
+ props.refresh();
986
+ }
987
+ }, /* @__PURE__ */ React.createElement(CloseIcon, null)))
988
+ })), recentSearchesCollection && /* @__PURE__ */ React.createElement(Results, _objectSpread2(_objectSpread2({}, props), {}, {
989
+ title: recentSearchesTitle,
990
+ collection: recentSearchesCollection,
991
+ sourceIcon: /* @__PURE__ */ React.createElement(RecentIcon, null),
992
+ renderIcon: ({ item }) => /* @__PURE__ */ React.createElement("div", { className: "DocSearch-Hit-icon" }, /* @__PURE__ */ React.createElement(SourceIcon, { type: item.type })),
993
+ renderAction: ({ item }) => /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("div", { className: "DocSearch-Hit-action" }, /* @__PURE__ */ React.createElement("button", {
994
+ className: "DocSearch-Hit-action-button DocSearch-Hit-action-button--pin",
995
+ title: saveRecentSearchButtonTitle,
996
+ type: "submit",
997
+ onClick: (event) => {
998
+ event.preventDefault();
999
+ event.stopPropagation();
1000
+ props.favoriteSearches.add(item);
1001
+ props.recentSearches.remove(item);
1002
+ props.refresh();
1003
+ }
1004
+ }, /* @__PURE__ */ React.createElement(PinIcon, null))), /* @__PURE__ */ React.createElement("div", { className: "DocSearch-Hit-action" }, /* @__PURE__ */ React.createElement("button", {
1005
+ className: "DocSearch-Hit-action-button",
1006
+ title: removeRecentSearchButtonTitle,
1007
+ type: "submit",
1008
+ onClick: (event) => {
1009
+ event.preventDefault();
1010
+ event.stopPropagation();
1011
+ props.recentSearches.remove(item);
1012
+ props.refresh();
1013
+ }
1014
+ }, /* @__PURE__ */ React.createElement(CloseIcon, null))))
1015
+ })));
1016
+ }
1017
+
1018
+ //#endregion
1019
+ //#region src/ErrorScreen.tsx
1020
+ function ErrorScreen({ translations = {} }) {
1021
+ const { titleText = "Unable to fetch results", helpText = "You might want to check your network connection." } = translations;
1022
+ return /* @__PURE__ */ React.createElement("div", { className: "DocSearch-ErrorScreen" }, /* @__PURE__ */ React.createElement("div", { className: "DocSearch-Screen-Icon" }, /* @__PURE__ */ React.createElement(ErrorIcon, null)), /* @__PURE__ */ React.createElement("p", { className: "DocSearch-Title" }, titleText), /* @__PURE__ */ React.createElement("p", { className: "DocSearch-Help" }, helpText));
1023
+ }
1024
+
1025
+ //#endregion
1026
+ //#region src/NoResultsScreen.tsx
1027
+ const _excluded$1 = ["translations"];
1028
+ function NoResultsScreen(_ref) {
1029
+ let { translations = {} } = _ref, props = _objectWithoutProperties(_ref, _excluded$1);
1030
+ const { noResultsText = "No results found for", suggestedQueryText = "Try searching for", reportMissingResultsText = "Believe this query should return results?", reportMissingResultsLinkText = "Let us know." } = translations;
1031
+ const searchSuggestions = props.state.context.searchSuggestions;
1032
+ return /* @__PURE__ */ React.createElement("div", { className: `DocSearch-NoResults ${props.canHandleAskAi ? "DocSearch-NoResults--withAskAi" : ""}` }, /* @__PURE__ */ React.createElement("div", { className: "DocSearch-Screen-Icon" }, /* @__PURE__ */ React.createElement(NoResultsIcon, null)), /* @__PURE__ */ React.createElement("p", { className: "DocSearch-Title" }, noResultsText, " \"", /* @__PURE__ */ React.createElement("strong", null, props.state.query), "\""), searchSuggestions && searchSuggestions.length > 0 && /* @__PURE__ */ React.createElement("div", { className: "DocSearch-NoResults-Prefill-List" }, /* @__PURE__ */ React.createElement("p", { className: "DocSearch-Help" }, suggestedQueryText, ":"), /* @__PURE__ */ React.createElement("div", { className: "DocSearch-NoResults-Prefill-List-Items" }, searchSuggestions.slice(0, 3).reduce((acc, search) => [...acc, /* @__PURE__ */ React.createElement("p", { key: search }, /* @__PURE__ */ React.createElement(SearchIcon, { size: 16 }), /* @__PURE__ */ React.createElement("button", {
1033
+ className: "DocSearch-Prefill",
1034
+ key: search,
1035
+ type: "button",
1036
+ onClick: () => {
1037
+ props.setQuery(search.toLowerCase() + " ");
1038
+ props.refresh();
1039
+ props.inputRef.current.focus();
1040
+ }
1041
+ }, search))], []))), props.getMissingResultsUrl && /* @__PURE__ */ React.createElement("p", { className: "DocSearch-Help" }, `${reportMissingResultsText} `, /* @__PURE__ */ React.createElement("a", {
1042
+ href: props.getMissingResultsUrl({ query: props.state.query }),
1043
+ target: "_blank",
1044
+ rel: "noopener noreferrer"
1045
+ }, reportMissingResultsLinkText)));
1046
+ }
1047
+
1048
+ //#endregion
1049
+ //#region src/components/HitResultBadge.tsx
1050
+ function isRenderablePrimitive(v) {
1051
+ return typeof v === "string" || typeof v === "number" || typeof v === "boolean";
1052
+ }
1053
+ function HitResultBadge({ item, resultBadgeKey, translations = {} }) {
1054
+ if (!resultBadgeKey) return null;
1055
+ const parsedValue = getNestedValue(item, resultBadgeKey);
1056
+ if (parsedValue === null || typeof parsedValue === "undefined") return null;
1057
+ const { resultBadgeLabelText = "Category" } = translations;
1058
+ let badgeValue = null;
1059
+ if (isRenderablePrimitive(parsedValue)) badgeValue = String(parsedValue).trim();
1060
+ else if (Array.isArray(parsedValue)) {
1061
+ const parts = parsedValue.filter(isRenderablePrimitive).map((v) => String(v).trim());
1062
+ badgeValue = parts.length > 0 ? parts.join(", ") : null;
1063
+ }
1064
+ if (badgeValue === null || badgeValue.length === 0) return null;
1065
+ return /* @__PURE__ */ React.createElement("div", { className: "DocSearch-Hit-badge" }, /* @__PURE__ */ React.createElement("span", { className: "DocSearch-VisuallyHiddenForAccessibility" }, `${resultBadgeLabelText}: ${badgeValue}`), /* @__PURE__ */ React.createElement("span", { "aria-hidden": "true" }, badgeValue));
1066
+ }
1067
+
1068
+ //#endregion
1069
+ //#region src/ResultsScreen.tsx
1070
+ const _excluded = ["translations", "resultBadgeKey"];
1071
+ function ResultsScreen(_ref) {
1072
+ let { translations = {}, resultBadgeKey } = _ref, props = _objectWithoutProperties(_ref, _excluded);
1073
+ const { resultsSectionTitle = "Results" } = translations;
1074
+ const renderIcon = React.useCallback(({ item }) => {
1075
+ return /* @__PURE__ */ React.createElement("div", { className: "DocSearch-Hit-icon" }, /* @__PURE__ */ React.createElement(SourceIcon, { type: item.type }));
1076
+ }, []);
1077
+ const renderAction = React.useCallback(() => {
1078
+ return /* @__PURE__ */ React.createElement("div", { className: "DocSearch-Hit-action" }, /* @__PURE__ */ React.createElement(SelectIcon, null));
1079
+ }, []);
1080
+ const renderResultBadge = React.useCallback(({ item }) => {
1081
+ return /* @__PURE__ */ React.createElement(HitResultBadge, {
1082
+ item,
1083
+ resultBadgeKey,
1084
+ translations: { resultBadgeLabelText: translations.resultBadgeLabelText }
1085
+ });
1086
+ }, [resultBadgeKey, translations.resultBadgeLabelText]);
1087
+ return /* @__PURE__ */ React.createElement("div", { className: "DocSearch-Dropdown-Container" }, props.state.collections.map((collection) => {
1088
+ if (collection.items.length === 0) return null;
1089
+ return /* @__PURE__ */ React.createElement(Results, _objectSpread2(_objectSpread2({}, props), {}, {
1090
+ key: collection.source.sourceId,
1091
+ translations,
1092
+ title: resultsSectionTitle,
1093
+ collection,
1094
+ renderIcon,
1095
+ renderAction,
1096
+ renderResultBadge
1097
+ }));
1098
+ }), props.resultsFooterComponent && /* @__PURE__ */ React.createElement("section", { className: "DocSearch-HitsFooter" }, /* @__PURE__ */ React.createElement(props.resultsFooterComponent, { state: props.state })));
1099
+ }
1100
+
1101
+ //#endregion
1102
+ //#region src/utils/createDocSearchSources.ts
1103
+ function createFacetFilters(searchParametersFacetFilters, facetSelections) {
1104
+ const dynamicFacetFilters = Object.entries(facetSelections).filter(([, value]) => value).map(([facet, value]) => `${facet}:${value}`);
1105
+ if (dynamicFacetFilters.length === 0) return searchParametersFacetFilters;
1106
+ if (!searchParametersFacetFilters) return dynamicFacetFilters;
1107
+ return [...searchParametersFacetFilters, ...dynamicFacetFilters];
1108
+ }
1109
+ function buildNoQuerySources({ recentSearches, favoriteSearches, saveRecentSearch, onClose, disableUserPersonalization }) {
1110
+ if (disableUserPersonalization) return [];
1111
+ return [{
1112
+ sourceId: SOURCE_IDS.favoriteSearches,
1113
+ onSelect({ item, event }) {
1114
+ saveRecentSearch(item);
1115
+ if (!isModifierEvent(event)) onClose();
1116
+ },
1117
+ getItemUrl({ item }) {
1118
+ return item.url;
1119
+ },
1120
+ getItems() {
1121
+ return favoriteSearches.getAll();
1122
+ }
1123
+ }, {
1124
+ sourceId: SOURCE_IDS.recentSearches,
1125
+ onSelect({ item, event }) {
1126
+ saveRecentSearch(item);
1127
+ if (!isModifierEvent(event)) onClose();
1128
+ },
1129
+ getItemUrl({ item }) {
1130
+ return item.url;
1131
+ },
1132
+ getItems() {
1133
+ return recentSearches.getAll();
1134
+ }
1135
+ }];
1136
+ }
1137
+ async function buildQuerySources({ query, state: sourcesState, setContext, setStatus, searchClient, indexes, snippetLength, insights, appId, apiKey, maxResultsPerGroup, transformItems = identity, saveRecentSearch, onClose, facetSelections }) {
1138
+ const insightsActive = insights;
1139
+ try {
1140
+ const { results } = await searchClient.search({ requests: indexes.map((index) => {
1141
+ var _searchParams$attribu, _searchParams$attribu2, _searchParams$snippet, _searchParams$highlig, _searchParams$highlig2, _searchParams$hitsPer, _searchParams$clickAn;
1142
+ const indexName = index.name;
1143
+ const searchParams = index.searchParameters;
1144
+ const facetFilters = createFacetFilters(searchParams === null || searchParams === void 0 ? void 0 : searchParams.facetFilters, facetSelections.current);
1145
+ return _objectSpread2(_objectSpread2({
1146
+ query,
1147
+ indexName,
1148
+ attributesToRetrieve: (_searchParams$attribu = searchParams === null || searchParams === void 0 ? void 0 : searchParams.attributesToRetrieve) !== null && _searchParams$attribu !== void 0 ? _searchParams$attribu : [
1149
+ "hierarchy.lvl0",
1150
+ "hierarchy.lvl1",
1151
+ "hierarchy.lvl2",
1152
+ "hierarchy.lvl3",
1153
+ "hierarchy.lvl4",
1154
+ "hierarchy.lvl5",
1155
+ "hierarchy.lvl6",
1156
+ "content",
1157
+ "type",
1158
+ "url"
1159
+ ],
1160
+ attributesToSnippet: (_searchParams$attribu2 = searchParams === null || searchParams === void 0 ? void 0 : searchParams.attributesToSnippet) !== null && _searchParams$attribu2 !== void 0 ? _searchParams$attribu2 : [
1161
+ `hierarchy.lvl1:${snippetLength.current}`,
1162
+ `hierarchy.lvl2:${snippetLength.current}`,
1163
+ `hierarchy.lvl3:${snippetLength.current}`,
1164
+ `hierarchy.lvl4:${snippetLength.current}`,
1165
+ `hierarchy.lvl5:${snippetLength.current}`,
1166
+ `hierarchy.lvl6:${snippetLength.current}`,
1167
+ `content:${snippetLength.current}`
1168
+ ],
1169
+ snippetEllipsisText: (_searchParams$snippet = searchParams === null || searchParams === void 0 ? void 0 : searchParams.snippetEllipsisText) !== null && _searchParams$snippet !== void 0 ? _searchParams$snippet : "…",
1170
+ highlightPreTag: (_searchParams$highlig = searchParams === null || searchParams === void 0 ? void 0 : searchParams.highlightPreTag) !== null && _searchParams$highlig !== void 0 ? _searchParams$highlig : "<mark>",
1171
+ highlightPostTag: (_searchParams$highlig2 = searchParams === null || searchParams === void 0 ? void 0 : searchParams.highlightPostTag) !== null && _searchParams$highlig2 !== void 0 ? _searchParams$highlig2 : "</mark>",
1172
+ hitsPerPage: (_searchParams$hitsPer = searchParams === null || searchParams === void 0 ? void 0 : searchParams.hitsPerPage) !== null && _searchParams$hitsPer !== void 0 ? _searchParams$hitsPer : 20,
1173
+ clickAnalytics: (_searchParams$clickAn = searchParams === null || searchParams === void 0 ? void 0 : searchParams.clickAnalytics) !== null && _searchParams$clickAn !== void 0 ? _searchParams$clickAn : insightsActive
1174
+ }, searchParams !== null && searchParams !== void 0 ? searchParams : {}), facetFilters ? { facetFilters } : {});
1175
+ }) });
1176
+ return results.flatMap((res) => {
1177
+ const result = res;
1178
+ const { hits, nbHits } = result;
1179
+ const sources = groupBy(transformItems(hits), (hit) => removeHighlightTags(hit), maxResultsPerGroup);
1180
+ if (sourcesState.context.searchSuggestions.length < Object.keys(sources).length) {
1181
+ var _sourcesState$context;
1182
+ setContext({ searchSuggestions: _objectSpread2(_objectSpread2({}, (_sourcesState$context = sourcesState.context.searchSuggestions) !== null && _sourcesState$context !== void 0 ? _sourcesState$context : []), Object.keys(sources)) });
1183
+ }
1184
+ if (nbHits) {
1185
+ const currentNbHits = sourcesState.context.nbHits;
1186
+ setContext({ nbHits: (currentNbHits !== null && currentNbHits !== void 0 ? currentNbHits : 0) + nbHits });
1187
+ }
1188
+ let insightsParams = {};
1189
+ if (insightsActive) insightsParams = {
1190
+ __autocomplete_indexName: result.index,
1191
+ __autocomplete_queryID: result.queryID,
1192
+ __autocomplete_algoliaCredentials: {
1193
+ appId,
1194
+ apiKey
1195
+ }
1196
+ };
1197
+ const items = Object.values(sources).flat();
1198
+ return {
1199
+ sourceId: `hits_${result.index}`,
1200
+ onSelect({ item, event }) {
1201
+ saveRecentSearch(item);
1202
+ if (!isModifierEvent(event)) onClose();
1203
+ },
1204
+ getItemUrl({ item }) {
1205
+ return item.url;
1206
+ },
1207
+ getItems() {
1208
+ return Object.values(groupBy(items, (item) => item.hierarchy.lvl1, maxResultsPerGroup)).map((groupedHits) => groupedHits.map((item) => {
1209
+ let parent = null;
1210
+ const potentialParent = groupedHits.find((siblingItem) => siblingItem.type === "lvl1" && siblingItem.hierarchy.lvl1 === item.hierarchy.lvl1);
1211
+ if (item.type !== "lvl1" && potentialParent) parent = potentialParent;
1212
+ return _objectSpread2(_objectSpread2({}, item), {}, { __docsearch_parent: parent }, insightsParams);
1213
+ }).flat()).flat();
1214
+ }
1215
+ };
1216
+ });
1217
+ } catch (error) {
1218
+ if (error.name === "RetryError") setStatus("error");
1219
+ throw error;
1220
+ }
1221
+ }
1222
+
1223
+ //#endregion
1224
+ //#region src/utils/normalizeDocSearchIndexes.ts
1225
+ function normalizeDocSearchIndexes({ indexName, indices = [], searchParameters }) {
1226
+ const indexes = [];
1227
+ if (indexName && indexName !== "") indexes.push({
1228
+ name: indexName,
1229
+ searchParameters
1230
+ });
1231
+ if (indices.length > 0) indices.forEach((index) => {
1232
+ indexes.push(typeof index === "string" ? { name: index } : index);
1233
+ });
1234
+ if (indexes.length < 1) throw new Error("Must supply either `indexName` or `indices` for DocSearch to work");
1235
+ return indexes;
1236
+ }
1237
+
1238
+ //#endregion
1239
+ export { noop as C, getCollection as D, SOURCE_IDS as E, scrollTo as S, identity as T, Hit as _, NoResultsScreen as a, SearchBoxForm as b, Results as c, useRefreshOnInitialQuery as d, useModalRefs as f, useDocSearchFacets as g, useSendItemClickEvent as h, ResultsScreen as i, useStoredDocSearches as l, useInitialModalQuery as m, buildNoQuerySources as n, ErrorScreen as o, useModalEnvironment as p, buildQuerySources as r, StoredSearchesSections as s, normalizeDocSearchIndexes as t, useSaveRecentSearch as u, Footer as v, isModifierEvent as w, FacetBar as x, ModalShell as y };
1240
+ //# sourceMappingURL=normalizeDocSearchIndexes-DAzlMybx.js.map