@docsearch/js 5.0.0-beta.1 → 5.0.0-beta.3

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.
package/dist/esm/index.js CHANGED
@@ -1,4 +1,4 @@
1
- /*! @docsearch/js 5.0.0-beta.1 (UNRELEASED cc75f9a) | MIT License | © Algolia, Inc. and contributors | https://docsearch.algolia.com */
1
+ /*! @docsearch/js 5.0.0-beta.3 (UNRELEASED b044250) | MIT License | © Algolia, Inc. and contributors | https://docsearch.algolia.com */
2
2
  //#region \0rolldown/runtime.js
3
3
  var __create = Object.create;
4
4
  var __defProp$1 = Object.defineProperty;
@@ -1188,7 +1188,7 @@ function DocSearchButtonKey({ reactsToKey, children }) {
1188
1188
 
1189
1189
  //#endregion
1190
1190
  //#region ../docsearch-react/dist/esm/version.js
1191
- const version$2 = "5.0.0-beta.0";
1191
+ const version$2 = "5.0.0-beta.3";
1192
1192
 
1193
1193
  //#endregion
1194
1194
  //#region \0@oxc-project+runtime@0.139.0/helpers/esm/OverloadYield.js
@@ -12295,7 +12295,7 @@ const BOUNDARY_OFFSET = 2;
12295
12295
  *
12296
12296
  * Documentation: [Base UI Menu](https://base-ui.com/react/components/menu)
12297
12297
  */
12298
- const MenuTrigger$2 = fastComponentRef(function MenuTrigger(componentProps, forwardedRef) {
12298
+ const MenuTrigger$1 = fastComponentRef(function MenuTrigger(componentProps, forwardedRef) {
12299
12299
  var _handle$store;
12300
12300
  const { render, className, style, disabled: disabledProp = false, nativeButton = true, id: idProp, openOnHover: openOnHoverProp, delay = 100, closeDelay = 0, handle, payload } = componentProps, elementProps = _objectWithoutProperties$5(componentProps, _excluded$23);
12301
12301
  const rootContext = useMenuRootContext(true);
@@ -12496,7 +12496,7 @@ function useMenuParent() {
12496
12496
  }
12497
12497
 
12498
12498
  //#endregion
12499
- //#region ../docsearch-react/dist/esm/normalizeDocSearchIndexes-DAzlMybx.js
12499
+ //#region ../docsearch-react/dist/esm/normalizeDocSearchIndexes-ChnVvoVt.js
12500
12500
  init_compat();
12501
12501
  function capitalize(text) {
12502
12502
  return `${text.charAt(0).toLocaleUpperCase()}${text.substring(1)}`;
@@ -12557,6 +12557,10 @@ function identity(x) {
12557
12557
  function isModifierEvent(event) {
12558
12558
  return event.button === 1 || event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;
12559
12559
  }
12560
+ function isQueryEmpty(query) {
12561
+ if (!query || query.trim().length === 0) return true;
12562
+ return false;
12563
+ }
12560
12564
  function noop$2(..._args) {}
12561
12565
  const regexHighlightTags = /(<mark>|<\/mark>)/g;
12562
12566
  const regexHasHighlightTags = RegExp(regexHighlightTags.source);
@@ -12672,12 +12676,28 @@ function getFacetLabel(facet) {
12672
12676
  if (facet.label) return facet.label;
12673
12677
  return facet.key.replace(/[._-]+/g, " ").replace(/\b\w/g, (letter) => letter.toUpperCase());
12674
12678
  }
12675
- const _excluded$6$12 = ["className", "type"];
12679
+ function deriveDefaultSelectedFacetsFromIndex(indices) {
12680
+ const defaultFacets = {};
12681
+ for (const index of indices) {
12682
+ var _index$searchParamete;
12683
+ const facetFilters = (_index$searchParamete = index.searchParameters) === null || _index$searchParamete === void 0 ? void 0 : _index$searchParamete.facetFilters;
12684
+ for (const facetFilter of Array.isArray(facetFilters) ? facetFilters : [facetFilters]) {
12685
+ if (typeof facetFilter !== "string") continue;
12686
+ const separatorIndex = facetFilter.indexOf(":");
12687
+ if (separatorIndex <= 0) continue;
12688
+ const key = facetFilter.slice(0, separatorIndex);
12689
+ const value = facetFilter.slice(separatorIndex + 1);
12690
+ if (key && value) defaultFacets[key] = value;
12691
+ }
12692
+ }
12693
+ return defaultFacets;
12694
+ }
12695
+ const _excluded$6$11 = ["className", "type"];
12676
12696
  function Chip({ children }) {
12677
12697
  return /* @__PURE__ */ En.createElement("div", { className: "DocSearch-Chip" }, children);
12678
12698
  }
12679
12699
  function ChipDismiss(_ref) {
12680
- let { className, type = "button" } = _ref, props = _objectWithoutProperties$6(_ref, _excluded$6$12);
12700
+ let { className, type = "button" } = _ref, props = _objectWithoutProperties$6(_ref, _excluded$6$11);
12681
12701
  const cn = `DocSearch-Chip-Dismiss${className ? ` ${className}` : ""}`;
12682
12702
  return /* @__PURE__ */ En.createElement("button", _objectSpread2$2({
12683
12703
  type,
@@ -12701,12 +12721,14 @@ function Menu$1(_ref) {
12701
12721
  let props = _extends({}, (_objectDestructuringEmpty(_ref), _ref));
12702
12722
  return /* @__PURE__ */ En.createElement(MenuRoot, props);
12703
12723
  }
12704
- function MenuTrigger$1(_ref2) {
12724
+ Menu$1.Trigger = En.forwardRef((_ref2, ref) => {
12705
12725
  let { className } = _ref2, props = _objectWithoutProperties$6(_ref2, _excluded$5$13);
12706
12726
  const cn = `DocSearch-Menu-Trigger${className ? ` ${className}` : ""}`;
12707
- return /* @__PURE__ */ En.createElement(MenuTrigger$2, _objectSpread2$2({ className: cn }, props));
12708
- }
12709
- Menu$1.Trigger = MenuTrigger$1;
12727
+ return /* @__PURE__ */ En.createElement(MenuTrigger$1, _objectSpread2$2({
12728
+ className: cn,
12729
+ ref
12730
+ }, props));
12731
+ });
12710
12732
  function MenuPopup(_ref3) {
12711
12733
  let { align = "start", alignOffset = 0, side = "bottom", sideOffset = 4, collisionBoundary = "clipping-ancestors", container } = _ref3, props = _objectWithoutProperties$6(_ref3, _excluded2$5);
12712
12734
  return /* @__PURE__ */ En.createElement(MenuPortal, { container }, /* @__PURE__ */ En.createElement(MenuPositioner, {
@@ -12774,9 +12796,10 @@ const SelectedFacetChip = En.memo(function SelectedFacetChip({ facetKey, facetLa
12774
12796
  });
12775
12797
  const FacetBar = En.memo(function FacetBar({ facets, selections, onSelectionChange, clearSelections, translations = {} }) {
12776
12798
  const { defaultValueLabel = "All", facetMenuTriggerAriaLabel = "selected", clearAllLabel = "Clear all", facetsAriaLabel = "Search filters", selectedFacetsAriaLabel = "Selected search filters", clearFacetAriaLabel = "Clear filter:" } = translations;
12799
+ const visibleFacetKeys = En.useMemo(() => new Set(facets.map((f) => f.key)), [facets]);
12777
12800
  const selectionsToDisplay = En.useMemo(() => {
12778
- return Object.entries(selections).filter(([_, value]) => Boolean(value));
12779
- }, [selections]);
12801
+ return Object.entries(selections).filter(([key, value]) => Boolean(value) && visibleFacetKeys.has(key));
12802
+ }, [selections, visibleFacetKeys]);
12780
12803
  const triggerRefs = En.useRef(/* @__PURE__ */ new Map());
12781
12804
  const registerTrigger = En.useCallback((facetKey, el) => {
12782
12805
  if (el) triggerRefs.current.set(facetKey, el);
@@ -12837,7 +12860,7 @@ const FacetBar = En.memo(function FacetBar({ facets, selections, onSelectionChan
12837
12860
  onClick: handleClearAll
12838
12861
  }, clearAllLabel)));
12839
12862
  });
12840
- const _excluded$4$18 = [
12863
+ const _excluded$4$19 = [
12841
12864
  "actionsBeforeClose",
12842
12865
  "autoFocus",
12843
12866
  "clearButtonAriaLabel",
@@ -12856,7 +12879,7 @@ const _excluded$4$18 = [
12856
12879
  "state"
12857
12880
  ];
12858
12881
  function SearchBoxForm(_ref) {
12859
- let { actionsBeforeClose, autoFocus, clearButtonAriaLabel, clearButtonTitle, closeButtonAriaLabel, closeButtonText, hideInput, inputOverlay, inputProps, inputRef, isFromSelection, leadingElement, onClose, placeholder, searchInputLabel, state } = _ref, autocomplete = _objectWithoutProperties$6(_ref, _excluded$4$18);
12882
+ let { actionsBeforeClose, autoFocus, clearButtonAriaLabel, clearButtonTitle, closeButtonAriaLabel, closeButtonText, hideInput, inputOverlay, inputProps, inputRef, isFromSelection, leadingElement, onClose, placeholder, searchInputLabel, state } = _ref, autocomplete = _objectWithoutProperties$6(_ref, _excluded$4$19);
12860
12883
  const { onReset } = autocomplete.getFormProps({ inputElement: inputRef.current });
12861
12884
  En.useEffect(() => {
12862
12885
  if (autoFocus && inputRef.current) inputRef.current.focus();
@@ -12929,12 +12952,13 @@ function CommandIcon(props) {
12929
12952
  strokeWidth: "1.4"
12930
12953
  }, props.children));
12931
12954
  }
12932
- function Footer({ translations = {}, isAskAiActive = false }) {
12955
+ function Footer({ translations = {}, isAskAiActive = false, footerAction }) {
12933
12956
  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;
12934
- return /* @__PURE__ */ En.createElement(En.Fragment, null, /* @__PURE__ */ En.createElement("div", { className: "DocSearch-Logo" }, /* @__PURE__ */ En.createElement(AlgoliaLogo, { translations: { poweredByText } })), /* @__PURE__ */ En.createElement("ul", { className: "DocSearch-Commands" }, /* @__PURE__ */ En.createElement("li", null, /* @__PURE__ */ En.createElement("kbd", { className: "DocSearch-Commands-Key" }, /* @__PURE__ */ En.createElement(CommandIcon, { ariaLabel: navigateDownKeyAriaLabel }, /* @__PURE__ */ En.createElement("path", { d: "M12 5v14" }), /* @__PURE__ */ En.createElement("path", { d: "m19 12-7 7-7-7" }))), /* @__PURE__ */ En.createElement("kbd", { className: "DocSearch-Commands-Key" }, /* @__PURE__ */ En.createElement(CommandIcon, { ariaLabel: navigateUpKeyAriaLabel }, /* @__PURE__ */ En.createElement("path", { d: "m5 12 7-7 7 7" }), /* @__PURE__ */ En.createElement("path", { d: "M12 19V5" }))), /* @__PURE__ */ En.createElement("span", { className: "DocSearch-Label" }, navigateText)), /* @__PURE__ */ En.createElement("li", null, /* @__PURE__ */ En.createElement("kbd", { className: "DocSearch-Commands-Key" }, /* @__PURE__ */ En.createElement(CommandIcon, { ariaLabel: selectKeyAriaLabel }, /* @__PURE__ */ En.createElement("polyline", { points: "9 10 4 15 9 20" }), /* @__PURE__ */ En.createElement("path", { d: "M20 4v7a4 4 0 0 1-4 4H4" }))), /* @__PURE__ */ En.createElement("span", { className: "DocSearch-Label" }, isAskAiActive ? submitQuestionText : selectText)), /* @__PURE__ */ En.createElement("li", null, /* @__PURE__ */ En.createElement("kbd", { className: "DocSearch-Commands-Key" }, /* @__PURE__ */ En.createElement("span", { className: "DocSearch-Escape-Key" }, "ESC")), /* @__PURE__ */ En.createElement("span", {
12957
+ const hasFooterAction = footerAction !== null && footerAction !== void 0 && typeof footerAction !== "boolean";
12958
+ return /* @__PURE__ */ En.createElement(En.Fragment, null, /* @__PURE__ */ En.createElement("ul", { className: "DocSearch-Commands" }, /* @__PURE__ */ En.createElement("li", null, /* @__PURE__ */ En.createElement("kbd", { className: "DocSearch-Commands-Key" }, /* @__PURE__ */ En.createElement(CommandIcon, { ariaLabel: navigateDownKeyAriaLabel }, /* @__PURE__ */ En.createElement("path", { d: "M12 5v14" }), /* @__PURE__ */ En.createElement("path", { d: "m19 12-7 7-7-7" }))), /* @__PURE__ */ En.createElement("kbd", { className: "DocSearch-Commands-Key" }, /* @__PURE__ */ En.createElement(CommandIcon, { ariaLabel: navigateUpKeyAriaLabel }, /* @__PURE__ */ En.createElement("path", { d: "m5 12 7-7 7 7" }), /* @__PURE__ */ En.createElement("path", { d: "M12 19V5" }))), /* @__PURE__ */ En.createElement("span", { className: "DocSearch-Label" }, navigateText)), /* @__PURE__ */ En.createElement("li", null, /* @__PURE__ */ En.createElement("kbd", { className: "DocSearch-Commands-Key" }, /* @__PURE__ */ En.createElement(CommandIcon, { ariaLabel: selectKeyAriaLabel }, /* @__PURE__ */ En.createElement("polyline", { points: "9 10 4 15 9 20" }), /* @__PURE__ */ En.createElement("path", { d: "M20 4v7a4 4 0 0 1-4 4H4" }))), /* @__PURE__ */ En.createElement("span", { className: "DocSearch-Label" }, isAskAiActive ? submitQuestionText : selectText)), /* @__PURE__ */ En.createElement("li", null, /* @__PURE__ */ En.createElement("kbd", { className: "DocSearch-Commands-Key" }, /* @__PURE__ */ En.createElement("span", { className: "DocSearch-Escape-Key" }, "ESC")), /* @__PURE__ */ En.createElement("span", {
12935
12959
  className: "DocSearch-Label",
12936
12960
  "aria-label": closeKeyAriaLabel
12937
- }, isAskAiActive ? backToSearchText : closeText))));
12961
+ }, isAskAiActive ? backToSearchText : closeText))), /* @__PURE__ */ En.createElement("div", { className: "DocSearch-Footer-Actions" }, hasFooterAction && /* @__PURE__ */ En.createElement("div", { className: "DocSearch-Footer-Action" }, footerAction), /* @__PURE__ */ En.createElement("div", { className: "DocSearch-Logo" }, /* @__PURE__ */ En.createElement(AlgoliaLogo, { translations: { poweredByText } }))));
12938
12962
  }
12939
12963
  function Hit({ hit, children }) {
12940
12964
  return /* @__PURE__ */ En.createElement("a", { href: hit.url }, children);
@@ -12949,21 +12973,15 @@ function useFacetValues({ facets, indexes, searchClient }) {
12949
12973
  En.useEffect(() => {
12950
12974
  let isMounted = true;
12951
12975
  const facetKeys = stableFacetKeys ? stableFacetKeys.split(",") : [];
12952
- if (facetKeys.length === 0 || indexes.length === 0) {
12953
- setFacetValues({});
12954
- return () => {
12955
- isMounted = false;
12956
- };
12957
- }
12958
- searchClient.search({ requests: indexes.map((index) => {
12959
- var _index$searchParamete2;
12960
- return _objectSpread2$2(_objectSpread2$2({}, (_index$searchParamete2 = index.searchParameters) !== null && _index$searchParamete2 !== void 0 ? _index$searchParamete2 : {}), {}, {
12961
- indexName: index.name,
12962
- query: "",
12963
- hitsPerPage: 0,
12964
- facets: facetKeys
12965
- });
12966
- }) }).then(({ results }) => {
12976
+ if (facetKeys.length === 0 || indexes.length === 0) return () => {
12977
+ isMounted = false;
12978
+ };
12979
+ searchClient.search({ requests: indexes.map((index) => ({
12980
+ indexName: index.name,
12981
+ query: "",
12982
+ hitsPerPage: 0,
12983
+ facets: facetKeys
12984
+ })) }).then(({ results }) => {
12967
12985
  if (!isMounted) return;
12968
12986
  const valuesByFacet = facetKeys.reduce((acc, facet) => {
12969
12987
  acc[facet] = [];
@@ -12992,19 +13010,23 @@ function useFacetValues({ facets, indexes, searchClient }) {
12992
13010
  }
12993
13011
  function useDocSearchFacets({ facets, indexes, searchClient, onSelectionsChange }) {
12994
13012
  const normalizedFacets = En.useMemo(() => normalizeFacets(facets), [facets]);
13013
+ const normalizedFacetsRef = En.useRef(normalizedFacets);
12995
13014
  const facetValues = useFacetValues({
12996
13015
  facets: normalizedFacets,
12997
13016
  indexes,
12998
13017
  searchClient
12999
13018
  });
13000
- const [facetSelections, setFacetSelections] = En.useState({});
13019
+ const [facetSelections, setFacetSelections] = En.useState(() => deriveDefaultSelectedFacetsFromIndex(indexes));
13001
13020
  const facetSelectionsRef = En.useRef(facetSelections);
13002
13021
  const onSelectionsChangeRef = En.useRef(onSelectionsChange);
13003
- onSelectionsChangeRef.current = onSelectionsChange;
13004
13022
  const visibleFacets = En.useMemo(() => normalizedFacets.map((facet) => {
13005
13023
  var _facetValues$facet$ke;
13006
13024
  return _objectSpread2$2(_objectSpread2$2({}, facet), {}, { values: (_facetValues$facet$ke = facetValues[facet.key]) !== null && _facetValues$facet$ke !== void 0 ? _facetValues$facet$ke : [] });
13007
13025
  }).filter((facet) => facet.values.length > 0), [facetValues, normalizedFacets]);
13026
+ En.useLayoutEffect(() => {
13027
+ normalizedFacetsRef.current = normalizedFacets;
13028
+ onSelectionsChangeRef.current = onSelectionsChange;
13029
+ });
13008
13030
  const applySelections = En.useCallback((next) => {
13009
13031
  var _onSelectionsChangeRe;
13010
13032
  facetSelectionsRef.current = next;
@@ -13018,13 +13040,14 @@ function useDocSearchFacets({ facets, indexes, searchClient, onSelectionsChange
13018
13040
  handleFacetSelectionChange: En.useCallback((facet, value) => {
13019
13041
  if (facetSelectionsRef.current[facet] === value) return;
13020
13042
  const next = _objectSpread2$2({}, facetSelectionsRef.current);
13021
- if (value === "") delete next[facet];
13022
- else next[facet] = value;
13043
+ next[facet] = value;
13023
13044
  applySelections(next);
13024
13045
  }, [applySelections]),
13025
13046
  clearFacetSelections: En.useCallback(() => {
13026
13047
  if (Object.keys(facetSelectionsRef.current).length === 0) return;
13027
- applySelections({});
13048
+ const next = {};
13049
+ for (const facet of normalizedFacetsRef.current) if (facetSelectionsRef.current[facet.key]) next[facet.key] = "";
13050
+ applySelections(next);
13028
13051
  }, [applySelections])
13029
13052
  };
13030
13053
  }
@@ -13093,7 +13116,7 @@ function useTrapFocus({ container }) {
13093
13116
  };
13094
13117
  }, [container]);
13095
13118
  }
13096
- function useDocSearchModalEffects({ initialScrollY, modalRef, snippetLength, theme }) {
13119
+ function useDocSearchModalEffects({ initialScrollY, modalRef, theme }) {
13097
13120
  useTheme({ theme });
13098
13121
  En.useEffect(() => {
13099
13122
  document.body.classList.add("DocSearch--active");
@@ -13113,9 +13136,6 @@ function useDocSearchModalEffects({ initialScrollY, modalRef, snippetLength, the
13113
13136
  document.body.style.marginInlineEnd = "0px";
13114
13137
  };
13115
13138
  }, []);
13116
- En.useEffect(() => {
13117
- if (window.matchMedia("(max-width: 768px)").matches) snippetLength.current = 5;
13118
- }, [snippetLength]);
13119
13139
  En.useEffect(() => {
13120
13140
  function setFullViewportHeight() {
13121
13141
  if (modalRef.current) {
@@ -13130,7 +13150,7 @@ function useDocSearchModalEffects({ initialScrollY, modalRef, snippetLength, the
13130
13150
  };
13131
13151
  }, [modalRef]);
13132
13152
  }
13133
- function useModalEnvironment({ getEnvironmentProps, containerRef, dropdownRef, formElementRef, inputRef, initialScrollY, modalRef, snippetLength, theme }) {
13153
+ function useModalEnvironment({ getEnvironmentProps, containerRef, dropdownRef, formElementRef, inputRef, initialScrollY, modalRef, theme }) {
13134
13154
  useTouchEvents({
13135
13155
  getEnvironmentProps,
13136
13156
  panelElement: dropdownRef.current,
@@ -13141,7 +13161,6 @@ function useModalEnvironment({ getEnvironmentProps, containerRef, dropdownRef, f
13141
13161
  useDocSearchModalEffects({
13142
13162
  initialScrollY,
13143
13163
  modalRef,
13144
- snippetLength,
13145
13164
  theme
13146
13165
  });
13147
13166
  }
@@ -13151,8 +13170,7 @@ function useModalRefs() {
13151
13170
  modalRef: En.useRef(null),
13152
13171
  formElementRef: En.useRef(null),
13153
13172
  dropdownRef: En.useRef(null),
13154
- inputRef: En.useRef(null),
13155
- snippetLength: En.useRef(15)
13173
+ inputRef: En.useRef(null)
13156
13174
  };
13157
13175
  }
13158
13176
  function useRefreshOnInitialQuery({ initialQuery, inputRef, refresh }) {
@@ -13233,7 +13251,7 @@ function useRelativeFormattedDate(start, end = Date.now()) {
13233
13251
  }, [diff]);
13234
13252
  return start ? formattedDate : null;
13235
13253
  }
13236
- const _excluded$3$19 = [
13254
+ const _excluded$3$20 = [
13237
13255
  "hit",
13238
13256
  "attribute",
13239
13257
  "tagName"
@@ -13246,7 +13264,7 @@ function getPropertyByPath(object, path) {
13246
13264
  }
13247
13265
  function Snippet(_ref) {
13248
13266
  let { hit, attribute, tagName = "span" } = _ref;
13249
- return _$2(tagName, _objectSpread2$2(_objectSpread2$2({}, _objectWithoutProperties$6(_ref, _excluded$3$19)), {}, { dangerouslySetInnerHTML: { __html: getPropertyByPath(hit, `_snippetResult.${attribute}.value`) || getPropertyByPath(hit, attribute) } }));
13267
+ return _$2(tagName, _objectSpread2$2(_objectSpread2$2({}, _objectWithoutProperties$6(_ref, _excluded$3$20)), {}, { dangerouslySetInnerHTML: { __html: getPropertyByPath(hit, `_snippetResult.${attribute}.value`) || getPropertyByPath(hit, attribute) } }));
13250
13268
  }
13251
13269
  function Results(props) {
13252
13270
  var _props$sourceIcon;
@@ -13331,9 +13349,9 @@ function AskAiButton({ item, getItemProps, onItemClick, collection }) {
13331
13349
  }
13332
13350
  })), /* @__PURE__ */ En.createElement("div", { className: "DocSearch-Hit--AskAI" }, /* @__PURE__ */ En.createElement("div", { className: "DocSearch-Hit-AskAIButton DocSearch-Hit-Container" }, /* @__PURE__ */ En.createElement("div", { className: " DocSearch-Hit-AskAIButton-icon DocSearch-Hit-icon" }, /* @__PURE__ */ En.createElement(SparklesIcon, null)), /* @__PURE__ */ En.createElement("div", { className: "DocSearch-Hit-AskAIButton-title" }, /* @__PURE__ */ En.createElement("span", { className: "DocSearch-Hit-AskAIButton-title-query" }, item.query)))));
13333
13351
  }
13334
- const _excluded$2$21 = ["translations"];
13352
+ const _excluded$2$22 = ["translations"];
13335
13353
  function StoredSearchesSections(_ref) {
13336
- let { translations = {} } = _ref, props = _objectWithoutProperties$6(_ref, _excluded$2$21);
13354
+ let { translations = {} } = _ref, props = _objectWithoutProperties$6(_ref, _excluded$2$22);
13337
13355
  const { recentSearchesTitle = "Recently viewed docs", saveRecentSearchButtonTitle = "Pin this search", removeRecentSearchButtonTitle = "Remove this search from history", favoriteSearchesTitle = "Pinned", removeFavoriteSearchButtonTitle = "Remove this saved search" } = translations;
13338
13356
  const favoriteSearches = getCollection(props.state, "favoriteSearches");
13339
13357
  const recentSearchesCollection = getCollection(props.state, "recentSearches");
@@ -13386,9 +13404,9 @@ function ErrorScreen({ translations = {} }) {
13386
13404
  const { titleText = "Unable to fetch results", helpText = "You might want to check your network connection." } = translations;
13387
13405
  return /* @__PURE__ */ En.createElement("div", { className: "DocSearch-ErrorScreen" }, /* @__PURE__ */ En.createElement("div", { className: "DocSearch-Screen-Icon" }, /* @__PURE__ */ En.createElement(ErrorIcon, null)), /* @__PURE__ */ En.createElement("p", { className: "DocSearch-Title" }, titleText), /* @__PURE__ */ En.createElement("p", { className: "DocSearch-Help" }, helpText));
13388
13406
  }
13389
- const _excluded$1$22 = ["translations"];
13407
+ const _excluded$1$20 = ["translations"];
13390
13408
  function NoResultsScreen(_ref) {
13391
- let { translations = {} } = _ref, props = _objectWithoutProperties$6(_ref, _excluded$1$22);
13409
+ let { translations = {} } = _ref, props = _objectWithoutProperties$6(_ref, _excluded$1$20);
13392
13410
  const { noResultsText = "No results found for", suggestedQueryText = "Try searching for", reportMissingResultsText = "Believe this query should return results?", reportMissingResultsLinkText = "Let us know." } = translations;
13393
13411
  const searchSuggestions = props.state.context.searchSuggestions;
13394
13412
  return /* @__PURE__ */ En.createElement("div", { className: `DocSearch-NoResults ${props.canHandleAskAi ? "DocSearch-NoResults--withAskAi" : ""}` }, /* @__PURE__ */ En.createElement("div", { className: "DocSearch-Screen-Icon" }, /* @__PURE__ */ En.createElement(NoResultsIcon, null)), /* @__PURE__ */ En.createElement("p", { className: "DocSearch-Title" }, noResultsText, " \"", /* @__PURE__ */ En.createElement("strong", null, props.state.query), "\""), searchSuggestions && searchSuggestions.length > 0 && /* @__PURE__ */ En.createElement("div", { className: "DocSearch-NoResults-Prefill-List" }, /* @__PURE__ */ En.createElement("p", { className: "DocSearch-Help" }, suggestedQueryText, ":"), /* @__PURE__ */ En.createElement("div", { className: "DocSearch-NoResults-Prefill-List-Items" }, searchSuggestions.slice(0, 3).reduce((acc, search) => [...acc, /* @__PURE__ */ En.createElement("p", { key: search }, /* @__PURE__ */ En.createElement(SearchIcon, { size: 16 }), /* @__PURE__ */ En.createElement("button", {
@@ -13426,10 +13444,6 @@ function HitResultBadge({ item, resultBadgeKey, translations = {} }) {
13426
13444
  const _excluded$22 = ["translations", "resultBadgeKey"];
13427
13445
  function ResultsScreen(_ref) {
13428
13446
  let { translations = {}, resultBadgeKey } = _ref, props = _objectWithoutProperties$6(_ref, _excluded$22);
13429
- const { resultsSectionTitle = "Results" } = translations;
13430
- const renderIcon = En.useCallback(({ item }) => {
13431
- return /* @__PURE__ */ En.createElement("div", { className: "DocSearch-Hit-icon" }, /* @__PURE__ */ En.createElement(SourceIcon, { type: item.type }));
13432
- }, []);
13433
13447
  const renderAction = En.useCallback(() => {
13434
13448
  return /* @__PURE__ */ En.createElement("div", { className: "DocSearch-Hit-action" }, /* @__PURE__ */ En.createElement(SelectIcon, null));
13435
13449
  }, []);
@@ -13442,22 +13456,45 @@ function ResultsScreen(_ref) {
13442
13456
  }, [resultBadgeKey, translations.resultBadgeLabelText]);
13443
13457
  return /* @__PURE__ */ En.createElement("div", { className: "DocSearch-Dropdown-Container" }, props.state.collections.map((collection) => {
13444
13458
  if (collection.items.length === 0) return null;
13459
+ const title = removeHighlightTags(collection.items[0]);
13445
13460
  return /* @__PURE__ */ En.createElement(Results, _objectSpread2$2(_objectSpread2$2({}, props), {}, {
13446
13461
  key: collection.source.sourceId,
13447
13462
  translations,
13448
- title: resultsSectionTitle,
13463
+ title,
13449
13464
  collection,
13450
- renderIcon,
13465
+ renderIcon: ({ item, index }) => {
13466
+ var _collection$items;
13467
+ return /* @__PURE__ */ En.createElement(En.Fragment, null, item.__docsearch_parent && /* @__PURE__ */ En.createElement("svg", {
13468
+ className: "DocSearch-Hit-Tree",
13469
+ viewBox: "0 0 24 54"
13470
+ }, /* @__PURE__ */ En.createElement("g", {
13471
+ stroke: "currentColor",
13472
+ fill: "none",
13473
+ fillRule: "evenodd",
13474
+ strokeLinecap: "round",
13475
+ strokeLinejoin: "round"
13476
+ }, item.__docsearch_parent !== ((_collection$items = collection.items[index + 1]) === null || _collection$items === void 0 ? void 0 : _collection$items.__docsearch_parent) ? /* @__PURE__ */ En.createElement("path", { d: "M8 6v21M20 27H8.3" }) : /* @__PURE__ */ En.createElement("path", { d: "M8 6v42M20 27H8.3" }))), /* @__PURE__ */ En.createElement("div", { className: "DocSearch-Hit-icon" }, /* @__PURE__ */ En.createElement(SourceIcon, { type: item.type })));
13477
+ },
13451
13478
  renderAction,
13452
13479
  renderResultBadge
13453
13480
  }));
13454
13481
  }), props.resultsFooterComponent && /* @__PURE__ */ En.createElement("section", { className: "DocSearch-HitsFooter" }, /* @__PURE__ */ En.createElement(props.resultsFooterComponent, { state: props.state })));
13455
13482
  }
13456
13483
  function createFacetFilters(searchParametersFacetFilters, facetSelections) {
13457
- const dynamicFacetFilters = Object.entries(facetSelections).filter(([, value]) => value).map(([facet, value]) => `${facet}:${value}`);
13458
- if (dynamicFacetFilters.length === 0) return searchParametersFacetFilters;
13459
- if (!searchParametersFacetFilters) return dynamicFacetFilters;
13460
- return [...searchParametersFacetFilters, ...dynamicFacetFilters];
13484
+ const selections = Object.entries(facetSelections);
13485
+ const selectedFacets = new Set(selections.map(([facet]) => facet));
13486
+ const dynamicFacetFilters = [];
13487
+ for (const [facet, selection] of selections) if (selection !== "") dynamicFacetFilters.push(`${facet}:${selection}`);
13488
+ if (selectedFacets.size === 0) return searchParametersFacetFilters;
13489
+ let configuredFacetFilters = [];
13490
+ if (searchParametersFacetFilters && Array.isArray(searchParametersFacetFilters)) configuredFacetFilters = searchParametersFacetFilters;
13491
+ else if (searchParametersFacetFilters) configuredFacetFilters = [searchParametersFacetFilters];
13492
+ return [...configuredFacetFilters.filter((facetFilter) => {
13493
+ if (typeof facetFilter !== "string") return true;
13494
+ const separatorIndex = facetFilter.indexOf(":");
13495
+ const facet = facetFilter.slice(0, separatorIndex);
13496
+ return separatorIndex <= 0 || !selectedFacets.has(facet);
13497
+ }), ...dynamicFacetFilters];
13461
13498
  }
13462
13499
  function buildNoQuerySources({ recentSearches, favoriteSearches, saveRecentSearch, onClose, disableUserPersonalization }) {
13463
13500
  if (disableUserPersonalization) return [];
@@ -13487,7 +13524,7 @@ function buildNoQuerySources({ recentSearches, favoriteSearches, saveRecentSearc
13487
13524
  }
13488
13525
  }];
13489
13526
  }
13490
- async function buildQuerySources({ query, state: sourcesState, setContext, setStatus, searchClient, indexes, snippetLength, insights, appId, apiKey, maxResultsPerGroup, transformItems = identity, saveRecentSearch, onClose, facetSelections }) {
13527
+ async function buildQuerySources({ query, state: sourcesState, setContext, setStatus, searchClient, indexes, insights, appId, apiKey, maxResultsPerGroup, transformItems = identity, saveRecentSearch, onClose, facetSelections }) {
13491
13528
  const insightsActive = insights;
13492
13529
  try {
13493
13530
  const { results } = await searchClient.search({ requests: indexes.map((index) => {
@@ -13511,20 +13548,20 @@ async function buildQuerySources({ query, state: sourcesState, setContext, setSt
13511
13548
  "url"
13512
13549
  ],
13513
13550
  attributesToSnippet: (_searchParams$attribu2 = searchParams === null || searchParams === void 0 ? void 0 : searchParams.attributesToSnippet) !== null && _searchParams$attribu2 !== void 0 ? _searchParams$attribu2 : [
13514
- `hierarchy.lvl1:${snippetLength.current}`,
13515
- `hierarchy.lvl2:${snippetLength.current}`,
13516
- `hierarchy.lvl3:${snippetLength.current}`,
13517
- `hierarchy.lvl4:${snippetLength.current}`,
13518
- `hierarchy.lvl5:${snippetLength.current}`,
13519
- `hierarchy.lvl6:${snippetLength.current}`,
13520
- `content:${snippetLength.current}`
13551
+ `hierarchy.lvl1:15`,
13552
+ `hierarchy.lvl2:15`,
13553
+ `hierarchy.lvl3:15`,
13554
+ `hierarchy.lvl4:15`,
13555
+ `hierarchy.lvl5:15`,
13556
+ `hierarchy.lvl6:15`,
13557
+ `content:15`
13521
13558
  ],
13522
13559
  snippetEllipsisText: (_searchParams$snippet = searchParams === null || searchParams === void 0 ? void 0 : searchParams.snippetEllipsisText) !== null && _searchParams$snippet !== void 0 ? _searchParams$snippet : "…",
13523
13560
  highlightPreTag: (_searchParams$highlig = searchParams === null || searchParams === void 0 ? void 0 : searchParams.highlightPreTag) !== null && _searchParams$highlig !== void 0 ? _searchParams$highlig : "<mark>",
13524
13561
  highlightPostTag: (_searchParams$highlig2 = searchParams === null || searchParams === void 0 ? void 0 : searchParams.highlightPostTag) !== null && _searchParams$highlig2 !== void 0 ? _searchParams$highlig2 : "</mark>",
13525
13562
  hitsPerPage: (_searchParams$hitsPer = searchParams === null || searchParams === void 0 ? void 0 : searchParams.hitsPerPage) !== null && _searchParams$hitsPer !== void 0 ? _searchParams$hitsPer : 20,
13526
13563
  clickAnalytics: (_searchParams$clickAn = searchParams === null || searchParams === void 0 ? void 0 : searchParams.clickAnalytics) !== null && _searchParams$clickAn !== void 0 ? _searchParams$clickAn : insightsActive
13527
- }, searchParams !== null && searchParams !== void 0 ? searchParams : {}), facetFilters ? { facetFilters } : {});
13564
+ }, searchParams), facetFilters ? { facetFilters } : {});
13528
13565
  }) });
13529
13566
  return results.flatMap((res) => {
13530
13567
  const result = res;
@@ -13547,9 +13584,8 @@ async function buildQuerySources({ query, state: sourcesState, setContext, setSt
13547
13584
  apiKey
13548
13585
  }
13549
13586
  };
13550
- const items = Object.values(sources).flat();
13551
- return {
13552
- sourceId: `hits_${result.index}`,
13587
+ return Object.values(sources).map((items, index) => ({
13588
+ sourceId: `hits_${result.index}_${index}`,
13553
13589
  onSelect({ item, event }) {
13554
13590
  saveRecentSearch(item);
13555
13591
  if (!isModifierEvent(event)) onClose();
@@ -13563,26 +13599,18 @@ async function buildQuerySources({ query, state: sourcesState, setContext, setSt
13563
13599
  const potentialParent = groupedHits.find((siblingItem) => siblingItem.type === "lvl1" && siblingItem.hierarchy.lvl1 === item.hierarchy.lvl1);
13564
13600
  if (item.type !== "lvl1" && potentialParent) parent = potentialParent;
13565
13601
  return _objectSpread2$2(_objectSpread2$2({}, item), {}, { __docsearch_parent: parent }, insightsParams);
13566
- }).flat()).flat();
13602
+ })).flat();
13567
13603
  }
13568
- };
13604
+ }));
13569
13605
  });
13570
13606
  } catch (error) {
13571
13607
  if (error.name === "RetryError") setStatus("error");
13572
13608
  throw error;
13573
13609
  }
13574
13610
  }
13575
- function normalizeDocSearchIndexes({ indexName, indices = [], searchParameters }) {
13576
- const indexes = [];
13577
- if (indexName && indexName !== "") indexes.push({
13578
- name: indexName,
13579
- searchParameters
13580
- });
13581
- if (indices.length > 0) indices.forEach((index) => {
13582
- indexes.push(typeof index === "string" ? { name: index } : index);
13583
- });
13584
- if (indexes.length < 1) throw new Error("Must supply either `indexName` or `indices` for DocSearch to work");
13585
- return indexes;
13611
+ function normalizeDocSearchIndexes({ indices }) {
13612
+ if (!Array.isArray(indices) || indices.length < 1) throw new Error("Must supply at least one `indices` entry for DocSearch");
13613
+ return indices.map((index) => typeof index === "string" ? { name: index } : index);
13586
13614
  }
13587
13615
 
13588
13616
  //#endregion
@@ -13789,7 +13817,7 @@ const _excluded$21 = [
13789
13817
  "closeDelay",
13790
13818
  "id"
13791
13819
  ];
13792
- const PopoverTrigger$1 = /*#__PURE__*/ M$1(function PopoverTrigger(componentProps, forwardedRef) {
13820
+ const PopoverTrigger = /*#__PURE__*/ M$1(function PopoverTrigger(componentProps, forwardedRef) {
13793
13821
  var _handle$store;
13794
13822
  const { render, className, style, disabled = false, nativeButton = true, handle, payload, openOnHover = false, delay = 300, closeDelay = 0, id: idProp } = componentProps, elementProps = _objectWithoutProperties$5(componentProps, _excluded$21);
13795
13823
  const rootContext = usePopoverRootContext(true);
@@ -27212,7 +27240,7 @@ var require_throttleit = /* @__PURE__ */ __commonJSMin(((exports, module) => {
27212
27240
  //#region ../../node_modules/.bun/@ai-sdk+react@2.0.215+38ec045d21336c81/node_modules/@ai-sdk/react/dist/index.mjs
27213
27241
  init_compat();
27214
27242
  var import_throttleit = /* @__PURE__ */ __toESM(require_throttleit(), 1);
27215
- const _excluded$13 = ["messages"];
27243
+ const _excluded$12 = ["messages"];
27216
27244
  const _excluded2$4 = ["experimental_throttle", "resume"];
27217
27245
  var __accessCheck = (obj, member, msg) => {
27218
27246
  if (!member.has(obj)) throw TypeError("Cannot " + msg);
@@ -27331,7 +27359,7 @@ _callErrorCallbacks = /* @__PURE__ */ new WeakMap();
27331
27359
  var _state;
27332
27360
  var Chat = class extends AbstractChat {
27333
27361
  constructor(_ref) {
27334
- let { messages } = _ref, init = _objectWithoutProperties$5(_ref, _excluded$13);
27362
+ let { messages } = _ref, init = _objectWithoutProperties$5(_ref, _excluded$12);
27335
27363
  const state = new ReactChatState(messages);
27336
27364
  super(_objectSpread2$1(_objectSpread2$1({}, init), {}, { state }));
27337
27365
  __privateAdd(this, _state, void 0);
@@ -27376,7 +27404,7 @@ function useChat(_ref2 = {}) {
27376
27404
  }
27377
27405
 
27378
27406
  //#endregion
27379
- //#region ../docsearch-react/dist/esm/useSuggestedQuestions-CG2H3qm4.js
27407
+ //#region ../docsearch-react/dist/esm/useSuggestedQuestions-DwcUPOf_.js
27380
27408
  init_compat();
27381
27409
  function AlertIcon(props) {
27382
27410
  return /* @__PURE__ */ En.createElement("svg", _objectSpread2$2({
@@ -27602,7 +27630,7 @@ function FeedbackActions({ id, showActions, latestAssistantMessageContent, trans
27602
27630
  translations,
27603
27631
  onClick: () => navigator.clipboard.writeText(latestAssistantMessageContent)
27604
27632
  });
27605
- return /* @__PURE__ */ En.createElement("div", { className: "DocSearch-AskAiScreen-Actions" }, /* @__PURE__ */ En.createElement("div", { className: "DocSearch-AskAiScreen-Actions-Controls" }, isSidepanel ? copyButton : null, view === "thanks" ? /* @__PURE__ */ En.createElement("p", { className: "DocSearch-AskAiScreen-FeedbackText DocSearch-AskAiScreen-FeedbackText--visible" }, thanksForFeedbackText) : /* @__PURE__ */ En.createElement(En.Fragment, null, saving && view === "actions" ? /* @__PURE__ */ En.createElement(LoadingIcon, { className: "DocSearch-AskAiScreen-SmallerLoadingIcon" }) : /* @__PURE__ */ En.createElement(En.Fragment, null, /* @__PURE__ */ En.createElement(LikeButton, {
27633
+ return /* @__PURE__ */ En.createElement(En.Fragment, null, /* @__PURE__ */ En.createElement("div", { className: "DocSearch-AskAiScreen-Actions-Controls" }, isSidepanel ? copyButton : null, view === "thanks" ? /* @__PURE__ */ En.createElement("p", { className: "DocSearch-AskAiScreen-FeedbackText DocSearch-AskAiScreen-FeedbackText--visible" }, thanksForFeedbackText) : /* @__PURE__ */ En.createElement(En.Fragment, null, saving && view === "actions" ? /* @__PURE__ */ En.createElement(LoadingIcon, { className: "DocSearch-AskAiScreen-SmallerLoadingIcon" }) : /* @__PURE__ */ En.createElement(En.Fragment, null, /* @__PURE__ */ En.createElement(LikeButton, {
27606
27634
  title: likeButtonTitle,
27607
27635
  onClick: handleLike
27608
27636
  }), /* @__PURE__ */ En.createElement(DislikeButton, {
@@ -27621,18 +27649,22 @@ function FeedbackActions({ id, showActions, latestAssistantMessageContent, trans
27621
27649
  }) : null);
27622
27650
  }
27623
27651
  function NegativeFeedbackPanel({ translations, tags, notes, saving, savingError, onToggleTag, onNotesChange, onSubmit, onClose }) {
27652
+ const feedbackTitleId = En.useId();
27624
27653
  const { feedbackPanelTitle = "What went wrong? (optional)", feedbackDetailsPlaceholder = "Share some details...", feedbackSubmitButtonText = "Submit", feedbackCancelButtonText = "Cancel" } = translations;
27625
27654
  return /* @__PURE__ */ En.createElement("div", {
27626
27655
  className: "DocSearch-Feedback-Panel",
27627
27656
  role: "group",
27628
- "aria-label": feedbackPanelTitle
27629
- }, /* @__PURE__ */ En.createElement("div", { className: "DocSearch-Feedback-Panel-Header" }, /* @__PURE__ */ En.createElement("p", { className: "DocSearch-Feedback-Panel-Title" }, feedbackPanelTitle)), /* @__PURE__ */ En.createElement("div", { className: "DocSearch-Feedback-Panel-Reasons" }, FEEDBACK_REASONS.map((reason) => {
27657
+ "aria-labelledby": feedbackTitleId
27658
+ }, /* @__PURE__ */ En.createElement("div", { className: "DocSearch-Feedback-Panel-Header" }, /* @__PURE__ */ En.createElement("p", {
27659
+ className: "DocSearch-Feedback-Panel-Title",
27660
+ id: feedbackTitleId
27661
+ }, feedbackPanelTitle)), /* @__PURE__ */ En.createElement("div", { className: "DocSearch-Feedback-Panel-Reasons" }, FEEDBACK_REASONS.map((reason) => {
27630
27662
  var _translations$reason$;
27631
27663
  const isSelected = tags.includes(reason.value);
27632
27664
  return /* @__PURE__ */ En.createElement("button", {
27633
27665
  key: reason.value,
27634
27666
  type: "button",
27635
- className: `DocSearch-Feedback-Panel-Reason${isSelected ? " DocSearch-Feedback-Panel-Reason--selected" : ""}`,
27667
+ className: "DocSearch-Feedback-Panel-Reason",
27636
27668
  "aria-pressed": isSelected,
27637
27669
  onClick: () => onToggleTag(reason.value)
27638
27670
  }, /* @__PURE__ */ En.createElement("span", null, (_translations$reason$ = translations[reason.translationKey]) !== null && _translations$reason$ !== void 0 ? _translations$reason$ : reason.defaultLabel));
@@ -27757,12 +27789,14 @@ function Popover$1(_ref) {
27757
27789
  let props = _extends({}, (_objectDestructuringEmpty(_ref), _ref));
27758
27790
  return /* @__PURE__ */ En.createElement(PopoverRoot, props);
27759
27791
  }
27760
- function PopoverTrigger(_ref2) {
27792
+ Popover$1.Trigger = En.forwardRef((_ref2, ref) => {
27761
27793
  let { className } = _ref2, props = _objectWithoutProperties$6(_ref2, _excluded$2$12);
27762
27794
  const cn = `DocSearch-Popover-Trigger${className ? ` ${className}` : ""}`;
27763
- return /* @__PURE__ */ En.createElement(PopoverTrigger$1, _objectSpread2$2({ className: cn }, props));
27764
- }
27765
- Popover$1.Trigger = PopoverTrigger;
27795
+ return /* @__PURE__ */ En.createElement(PopoverTrigger, _objectSpread2$2({
27796
+ className: cn,
27797
+ ref
27798
+ }, props));
27799
+ });
27766
27800
  function PopoverPopup(_ref3) {
27767
27801
  let { align = "center", alignOffset = 0, side = "bottom", sideOffset = 4, collisionBoundary = "clipping-ancestors", container, children } = _ref3, props = _objectWithoutProperties$6(_ref3, _excluded2$3);
27768
27802
  return /* @__PURE__ */ En.createElement(PopoverPortal, { container }, /* @__PURE__ */ En.createElement(PopoverPositioner, {
@@ -27780,10 +27814,11 @@ function PopoverTitle(_ref4) {
27780
27814
  return /* @__PURE__ */ En.createElement(PopoverTitle$1, _objectSpread2$2({ className: "DocSearch-Popover-Title" }, props));
27781
27815
  }
27782
27816
  Popover$1.Title = PopoverTitle;
27783
- function SourcesPanel({ links, titleText = "Sources" }) {
27817
+ function SourcesPanel({ links, titleText = "Source", pluralTitleText = "Sources" }) {
27784
27818
  const [open, setOpen] = En.useState(false);
27785
27819
  const triggerRef = En.useRef(null);
27786
27820
  const [boundary, setBoundary] = En.useState(null);
27821
+ const sourcesTitle = links.length > 1 ? pluralTitleText : titleText;
27787
27822
  _$1(() => {
27788
27823
  var _ref, _trigger$closest;
27789
27824
  if (!open) return;
@@ -27810,13 +27845,13 @@ function SourcesPanel({ links, titleText = "Sources" }) {
27810
27845
  }, /* @__PURE__ */ En.createElement(Popover$1.Trigger, {
27811
27846
  ref: triggerRef,
27812
27847
  className: "DocSearch-AskAiScreen-Sources-Action"
27813
- }, /* @__PURE__ */ En.createElement("span", { className: "DocSearch-AskAiScreen-Sources-Action-icon" }, /* @__PURE__ */ En.createElement(ContentIcon, null)), /* @__PURE__ */ En.createElement("span", { className: "DocSearch-AskAiScreen-Sources-Action-text" }, links.length, " sources")), /* @__PURE__ */ En.createElement(Popover$1.Popup, {
27848
+ }, /* @__PURE__ */ En.createElement("span", { className: "DocSearch-AskAiScreen-Sources-Action-icon" }, /* @__PURE__ */ En.createElement(ContentIcon, null)), /* @__PURE__ */ En.createElement("span", { className: "DocSearch-AskAiScreen-Sources-Action-text" }, links.length, " ", sourcesTitle)), /* @__PURE__ */ En.createElement(Popover$1.Popup, {
27814
27849
  container: boundary,
27815
27850
  sideOffset: 10,
27816
27851
  align: "start",
27817
27852
  alignOffset: -16,
27818
27853
  collisionBoundary: boundary !== null && boundary !== void 0 ? boundary : "clipping-ancestors"
27819
- }, /* @__PURE__ */ En.createElement(Popover$1.Title, null, titleText), /* @__PURE__ */ En.createElement("ul", { className: "DocSearch-AskAiScreen-Sources" }, links.map((l) => /* @__PURE__ */ En.createElement("li", {
27854
+ }, /* @__PURE__ */ En.createElement(Popover$1.Title, null, sourcesTitle), /* @__PURE__ */ En.createElement("ul", { className: "DocSearch-AskAiScreen-Sources" }, links.map((l) => /* @__PURE__ */ En.createElement("li", {
27820
27855
  key: l.url,
27821
27856
  className: "DocSearch-AskAiScreen-Sources-source"
27822
27857
  }, /* @__PURE__ */ En.createElement("a", {
@@ -27825,19 +27860,52 @@ function SourcesPanel({ links, titleText = "Sources" }) {
27825
27860
  rel: "noopener noreferrer"
27826
27861
  }, /* @__PURE__ */ En.createElement(ContentIcon, null), /* @__PURE__ */ En.createElement("span", { className: "DocSearch-AskAiScreen-Sources-source-title" }, l.title || l.url)))))));
27827
27862
  }
27828
- /**
27829
- * Escapes HTML special characters to prevent XSS attacks. This should be used
27830
- * for any user-provided content that will be displayed.
27831
- */
27832
- function escapeHtml$1(unsafe) {
27863
+ /** Escapes HTML special characters for safe interpolation into HTML strings. */
27864
+ function escapeHtml(unsafe) {
27833
27865
  return unsafe.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#039;");
27834
27866
  }
27867
+ /** Strips HTML tags and escapes the remainder for plain-text React children. */
27868
+ function sanitizeUserInput(input) {
27869
+ return escapeHtml(input.replace(/<[^>]*>/g, ""));
27870
+ }
27871
+ function decodeUrlForSchemeCheck(value) {
27872
+ let current = value;
27873
+ for (let i = 0; i < 3; i += 1) try {
27874
+ const decoded = decodeURIComponent(current);
27875
+ if (decoded === current) break;
27876
+ current = decoded;
27877
+ } catch (_unused) {
27878
+ break;
27879
+ }
27880
+ return current;
27881
+ }
27882
+ function stripControlsAndWhitespace(value) {
27883
+ let result = "";
27884
+ for (let i = 0; i < value.length; i += 1) {
27885
+ const code = value.charCodeAt(i);
27886
+ if (code > 32 && code !== 127) result += value[i];
27887
+ }
27888
+ return result;
27889
+ }
27835
27890
  /**
27836
- * Sanitizes user input to prevent XSS attacks. Removes any HTML tags and
27837
- * escapes special characters.
27891
+ * Returns a URL safe for href/src, or '' if unsafe. Does not HTML-escape
27892
+ * callers building HTML strings must escape separately.
27838
27893
  */
27839
- function sanitizeUserInput(input) {
27840
- return escapeHtml$1(input.replace(/<[^>]*>/g, ""));
27894
+ function sanitizeUrl(url) {
27895
+ if (!url) return "";
27896
+ const trimmed = url.trim();
27897
+ if (!trimmed) return "";
27898
+ const normalized = stripControlsAndWhitespace(decodeUrlForSchemeCheck(trimmed));
27899
+ if (!normalized) return "";
27900
+ if (normalized.startsWith("//")) return "";
27901
+ if (!/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(normalized)) return trimmed;
27902
+ try {
27903
+ const parsed = new URL(normalized);
27904
+ if (parsed.protocol === "http:" || parsed.protocol === "https:" || parsed.protocol === "mailto:") return normalized;
27905
+ } catch (_unused2) {
27906
+ return "";
27907
+ }
27908
+ return "";
27841
27909
  }
27842
27910
  function extractLinksFromMessage(message) {
27843
27911
  const links = [];
@@ -27852,8 +27920,8 @@ function extractLinksFromMessage(message) {
27852
27920
  const markdownMatches = cleanText.matchAll(markdownLinkRegex);
27853
27921
  for (const match of markdownMatches) {
27854
27922
  const title = match[1].trim();
27855
- const url = match[2];
27856
- if (!seen.has(url)) {
27923
+ const url = sanitizeUrl(match[2]);
27924
+ if (url && !seen.has(url)) {
27857
27925
  seen.add(url);
27858
27926
  links.push({
27859
27927
  url,
@@ -27863,8 +27931,8 @@ function extractLinksFromMessage(message) {
27863
27931
  }
27864
27932
  const plainUrls = cleanText.matchAll(plainLinkRegex);
27865
27933
  for (const match of plainUrls) {
27866
- const cleanUrl = match[0].replace(/[.,;:!?]+$/, "");
27867
- if (!seen.has(cleanUrl)) {
27934
+ const cleanUrl = sanitizeUrl(match[0].replace(/[.,;:!?]+$/, ""));
27935
+ if (cleanUrl && !seen.has(cleanUrl)) {
27868
27936
  seen.add(cleanUrl);
27869
27937
  links.push({ url: cleanUrl });
27870
27938
  }
@@ -27896,12 +27964,15 @@ const buildDummyAskAiHit = (query, messages, chatId) => {
27896
27964
  url_without_anchor: ""
27897
27965
  };
27898
27966
  };
27899
- const getMessageContent = (message) => message === null || message === void 0 ? void 0 : message.parts.find((part) => part.type === "text");
27900
- /** Helper function to check if error is a thread depth error (AI-217). */
27967
+ const getMessageContent = (message) => {
27968
+ var _message$parts;
27969
+ return ((_message$parts = message === null || message === void 0 ? void 0 : message.parts) !== null && _message$parts !== void 0 ? _message$parts : []).filter((part) => part.type === "text").map((part) => part.text).join("\n\n");
27970
+ };
27971
+ /** Helper function to check if an error reports the conversation depth limit. */
27901
27972
  function isThreadDepthError(error) {
27902
27973
  var _error$message;
27903
27974
  if (!error) return false;
27904
- return ((_error$message = error.message) === null || _error$message === void 0 ? void 0 : _error$message.includes("AI-217")) || false;
27975
+ return /(?:ai-217|conversation\s+depth)/i.test((_error$message = error.message) !== null && _error$message !== void 0 ? _error$message : "");
27905
27976
  }
27906
27977
  const EMPTY_TOOLS = Object.freeze({});
27907
27978
  function isAIToolPart(part) {
@@ -28049,12 +28120,10 @@ function ToolCall({ part, translations, tools, onSearchQueryClick, memoryEnabled
28049
28120
  });
28050
28121
  return null;
28051
28122
  }
28052
- function escapeHtml(html) {
28053
- return html.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
28054
- }
28055
28123
  const renderer = new k.Renderer();
28056
28124
  renderer.code = ({ text, lang = "", escaped }) => {
28057
- const languageClass = lang ? `language-${lang}` : "";
28125
+ const safeLang = /^[a-zA-Z0-9_-]+$/.test(lang) ? lang : "";
28126
+ const languageClass = safeLang ? `language-${safeLang}` : "";
28058
28127
  const safeCode = escaped ? text : escapeHtml(text);
28059
28128
  return `
28060
28129
  <div class="DocSearch-CodeSnippet">
@@ -28064,15 +28133,28 @@ renderer.code = ({ text, lang = "", escaped }) => {
28064
28133
  `;
28065
28134
  };
28066
28135
  renderer.link = ({ href, title, text }) => {
28136
+ const safeHref = escapeHtml(sanitizeUrl(href));
28137
+ const textEscaped = escapeHtml(text);
28138
+ if (!safeHref) return textEscaped;
28139
+ return `<a href="${safeHref}"${title ? ` title="${escapeHtml(title)}"` : ""} target="_blank" rel="noopener noreferrer">${textEscaped}</a>`;
28140
+ };
28141
+ renderer.image = ({ href, title, text }) => {
28142
+ const safeHref = escapeHtml(sanitizeUrl(href));
28143
+ if (!safeHref) return escapeHtml(text);
28067
28144
  const titleAttr = title ? ` title="${escapeHtml(title)}"` : "";
28068
- return `<a href="${href ? escapeHtml(href) : ""}"${titleAttr} target="_blank" rel="noopener noreferrer">${escapeHtml(text)}</a>`;
28145
+ return `<img src="${safeHref}" alt="${escapeHtml(text)}"${titleAttr} />`;
28069
28146
  };
28070
- const MemoizedMarkdown = D$1(({ content, copyButtonText, copyButtonCopiedText, isStreaming }) => {
28071
- const html = q$2(() => k.parse(content, {
28147
+ renderer.html = ({ text }) => escapeHtml(text);
28148
+ /** Parses markdown into HTML safe for `dangerouslySetInnerHTML`. */
28149
+ function parseMarkdownToSafeHtml(content) {
28150
+ return k.parse(content, {
28072
28151
  gfm: true,
28073
28152
  breaks: true,
28074
28153
  renderer
28075
- }), [content]);
28154
+ });
28155
+ }
28156
+ const MemoizedMarkdown = D$1(({ content, copyButtonText, copyButtonCopiedText, isStreaming }) => {
28157
+ const html = q$2(() => parseMarkdownToSafeHtml(content), [content]);
28076
28158
  const containerRef = F$2(null);
28077
28159
  _$1(() => {
28078
28160
  const container = containerRef.current;
@@ -28147,7 +28229,7 @@ function groupConsecutiveToolResults(parts) {
28147
28229
  }
28148
28230
  return aggregatedParts;
28149
28231
  }
28150
- const _excluded$1$11 = [
28232
+ const _excluded$1$10 = [
28151
28233
  "children",
28152
28234
  "className",
28153
28235
  "onClick"
@@ -28197,7 +28279,7 @@ function MenuContent({ children }) {
28197
28279
  }
28198
28280
  Menu.Content = MenuContent;
28199
28281
  function MenuItem(_ref) {
28200
- let { children, className = "", onClick } = _ref, props = _objectWithoutProperties$6(_ref, _excluded$1$11);
28282
+ let { children, className = "", onClick } = _ref, props = _objectWithoutProperties$6(_ref, _excluded$1$10);
28201
28283
  const { setOpen } = En.useContext(MenuContext);
28202
28284
  const handleClick = (e) => {
28203
28285
  if (onClick) {
@@ -28244,24 +28326,24 @@ const postAgentStudioFeedback = ({ agentId, vote, messageId, appId, apiKey, abor
28244
28326
  signal: abortSignal
28245
28327
  });
28246
28328
  };
28247
- const _excluded$12 = [
28329
+ const _excluded$13 = [
28248
28330
  "id",
28249
28331
  "messages",
28250
28332
  "body"
28251
28333
  ];
28252
- const getAgentStudioTransport = ({ appId, apiKey, assistantId, searchParameters, userToken, indices }) => {
28334
+ const getAgentStudioTransport = ({ appId, apiKey, agentId, searchParameters, userToken, indices }) => {
28253
28335
  const algoliaParams = {};
28254
28336
  if (searchParameters) algoliaParams.searchParameters = searchParameters;
28255
28337
  if (indices && indices.length > 0) algoliaParams.indices = indices;
28256
28338
  return new DefaultChatTransport({
28257
- api: `${agentStudioBaseUrl(appId)}/agents/${assistantId}/completions?stream=true&compatibilityMode=ai-sdk-5`,
28339
+ api: `${agentStudioBaseUrl(appId)}/agents/${agentId}/completions?stream=true&compatibilityMode=ai-sdk-5`,
28258
28340
  headers: _objectSpread2$2({
28259
28341
  "x-algolia-application-id": appId,
28260
28342
  "x-algolia-api-key": apiKey
28261
28343
  }, userToken ? { "x-algolia-secure-user-token": userToken } : {}),
28262
28344
  body: { algolia: algoliaParams },
28263
28345
  prepareSendMessagesRequest(_ref) {
28264
- let { id, messages, body } = _ref, rest = _objectWithoutProperties$6(_ref, _excluded$12);
28346
+ let { id, messages, body } = _ref, rest = _objectWithoutProperties$6(_ref, _excluded$13);
28265
28347
  const sanitizedMessages = sanitizeMessagesForRequest(messages);
28266
28348
  return _objectSpread2$2(_objectSpread2$2({}, rest), {}, { body: _objectSpread2$2({
28267
28349
  id,
@@ -28270,19 +28352,19 @@ const getAgentStudioTransport = ({ appId, apiKey, assistantId, searchParameters,
28270
28352
  }
28271
28353
  });
28272
28354
  };
28273
- const useAskAi = ({ assistantId, apiKey, appId, indexName, tools = EMPTY_TOOLS, searchParameters, memory, indices }) => {
28355
+ const useAskAi = ({ agentId, apiKey, appId, tools = EMPTY_TOOLS, searchParameters, memory, indices }) => {
28274
28356
  const abortControllerRef = F$2(new AbortController());
28275
28357
  const askAiTransport = q$2(() => getAgentStudioTransport({
28276
28358
  apiKey,
28277
28359
  appId,
28278
- assistantId,
28360
+ agentId,
28279
28361
  searchParameters,
28280
28362
  userToken: memory === null || memory === void 0 ? void 0 : memory.userToken,
28281
28363
  indices
28282
28364
  }), [
28283
28365
  apiKey,
28284
28366
  appId,
28285
- assistantId,
28367
+ agentId,
28286
28368
  searchParameters,
28287
28369
  memory === null || memory === void 0 ? void 0 : memory.userToken,
28288
28370
  indices
@@ -28319,14 +28401,14 @@ const useAskAi = ({ assistantId, apiKey, appId, indexName, tools = EMPTY_TOOLS,
28319
28401
  addToolOutputRef.current = addToolOutput;
28320
28402
  }, [addToolOutput]);
28321
28403
  const conversations = F$2(createStoredConversations({
28322
- key: `__DOCSEARCH_ASKAI_CONVERSATIONS__${indexName}`,
28404
+ key: `__DOCSEARCH_ASKAI_CONVERSATIONS__${appId}`,
28323
28405
  limit: 10
28324
28406
  })).current;
28325
28407
  const sendFeedback = b$1(async (messageId, { thumbs, tags, notes }) => {
28326
28408
  var _conversations$addFee;
28327
- if (!assistantId) return;
28409
+ if (!agentId) return;
28328
28410
  if ((await postAgentStudioFeedback({
28329
- agentId: assistantId,
28411
+ agentId,
28330
28412
  vote: thumbs,
28331
28413
  messageId,
28332
28414
  appId,
@@ -28340,7 +28422,7 @@ const useAskAi = ({ assistantId, apiKey, appId, indexName, tools = EMPTY_TOOLS,
28340
28422
  notes
28341
28423
  });
28342
28424
  }, [
28343
- assistantId,
28425
+ agentId,
28344
28426
  appId,
28345
28427
  apiKey,
28346
28428
  conversations
@@ -28397,22 +28479,22 @@ const useAskAi = ({ assistantId, apiKey, appId, indexName, tools = EMPTY_TOOLS,
28397
28479
  restoreConversation
28398
28480
  };
28399
28481
  };
28400
- const useSuggestedQuestions = ({ assistantId, searchClient, suggestedQuestionsEnabled = false }) => {
28482
+ const useSuggestedQuestions = ({ agentId, searchClient, suggestedQuestionsEnabled = false }) => {
28401
28483
  const [suggestedQuestions, setSuggestedQuestions] = h([]);
28402
28484
  _$1(() => {
28403
28485
  const getSuggestedQuestions = async () => {
28404
28486
  const { results } = await searchClient.search({ requests: [{
28405
28487
  indexName: SUGGESTED_QUETIONS_INDEX_NAME,
28406
- filters: `state:published AND assistantId:${assistantId}`,
28488
+ filters: `state:published AND assistantId:${agentId}`,
28407
28489
  hitsPerPage: 3
28408
28490
  }] });
28409
28491
  const result = results[0];
28410
28492
  setSuggestedQuestions(result.hits);
28411
28493
  };
28412
- if (suggestedQuestionsEnabled && assistantId && assistantId !== "") getSuggestedQuestions();
28494
+ if (suggestedQuestionsEnabled && agentId && agentId !== "") getSuggestedQuestions();
28413
28495
  }, [
28414
28496
  suggestedQuestionsEnabled,
28415
- assistantId,
28497
+ agentId,
28416
28498
  searchClient
28417
28499
  ]);
28418
28500
  return suggestedQuestions;
@@ -31226,7 +31308,7 @@ function createAutocomplete(options) {
31226
31308
  }
31227
31309
 
31228
31310
  //#endregion
31229
- //#region ../docsearch-react/dist/esm/DocSearchAskAiModal-KaA6fBV4.js
31311
+ //#region ../docsearch-react/dist/esm/DocSearchAskAiModal-C_sH1j8Y.js
31230
31312
  init_compat();
31231
31313
  function MessageIcon() {
31232
31314
  return /* @__PURE__ */ En.createElement("svg", {
@@ -31284,9 +31366,9 @@ function AskAiScreenDisclaimer({ disclaimerText }) {
31284
31366
  return /* @__PURE__ */ En.createElement("p", { className: "DocSearch-AskAiScreen-Disclaimer" }, /* @__PURE__ */ En.createElement(SparklesIcon, null), " ", disclaimerText);
31285
31367
  }
31286
31368
  function AskAiExchangeCard({ exchange, askAiError, isLastExchange, loadingStatus, onSearchQueryClick, translations, tools, conversations, onFeedback, memoryEnabled, onSelectPromptSuggestion }) {
31287
- var _userMessage$metadata, _assistantMessage$met, _userContent$text;
31369
+ var _userMessage$metadata, _assistantMessage$met;
31288
31370
  const { userMessage, assistantMessage } = exchange;
31289
- const { stoppedStreamingText = "You stopped this response", errorTitleText = "Chat error", relatedSourcesText, suggestedPromptsTitleText = "Suggested prompts" } = translations;
31371
+ const { stoppedStreamingText = "You stopped this response", errorTitleText = "Chat error", relatedSourcesText, relatedSourcesTextPlural, suggestedPromptsTitleText = "Suggested prompts" } = translations;
31290
31372
  const toolCallTranslations = q$2(() => toToolCallTranslations(translations), [translations]);
31291
31373
  const isThreadDepth = isThreadDepthError(askAiError);
31292
31374
  const assistantContent = q$2(() => getMessageContent(assistantMessage), [assistantMessage]);
@@ -31303,7 +31385,7 @@ function AskAiExchangeCard({ exchange, askAiError, isLastExchange, loadingStatus
31303
31385
  const showActions = !wasStopped && (!isLastExchange || isLastExchange && loadingStatus === "ready" && Boolean(assistantMessage));
31304
31386
  const isThinking = ["submitted", "streaming"].includes(loadingStatus) && isLastExchange && !displayParts.some((part) => part.type !== "step-start");
31305
31387
  const messageId = (assistantMessage === null || assistantMessage === void 0 ? void 0 : assistantMessage.id) || exchange.id;
31306
- return /* @__PURE__ */ En.createElement("div", { className: "DocSearch-AskAiScreen-Response-Container" }, /* @__PURE__ */ En.createElement("div", { className: "DocSearch-AskAiScreen-Response" }, /* @__PURE__ */ En.createElement("div", { className: "DocSearch-AskAiScreen-Message DocSearch-AskAiScreen-Message--user" }, /* @__PURE__ */ En.createElement("p", { className: "DocSearch-AskAiScreen-Query" }, (_userContent$text = userContent === null || userContent === void 0 ? void 0 : userContent.text) !== null && _userContent$text !== void 0 ? _userContent$text : "")), /* @__PURE__ */ En.createElement("div", { className: "DocSearch-AskAiScreen-Message DocSearch-AskAiScreen-Message--assistant" }, /* @__PURE__ */ En.createElement("div", { className: "DocSearch-AskAiScreen-MessageContent" }, loadingStatus === "error" && askAiError && isLastExchange && !isThreadDepth && /* @__PURE__ */ En.createElement("div", {
31388
+ return /* @__PURE__ */ En.createElement("div", { className: "DocSearch-AskAiScreen-Response-Container" }, /* @__PURE__ */ En.createElement("div", { className: "DocSearch-AskAiScreen-Response" }, /* @__PURE__ */ En.createElement("div", { className: "DocSearch-AskAiScreen-Message DocSearch-AskAiScreen-Message--user" }, /* @__PURE__ */ En.createElement("p", { className: "DocSearch-AskAiScreen-Query" }, userContent !== null && userContent !== void 0 ? userContent : "")), /* @__PURE__ */ En.createElement("div", { className: "DocSearch-AskAiScreen-Message DocSearch-AskAiScreen-Message--assistant" }, /* @__PURE__ */ En.createElement("div", { className: "DocSearch-AskAiScreen-MessageContent" }, loadingStatus === "error" && askAiError && isLastExchange && !isThreadDepth && /* @__PURE__ */ En.createElement("div", {
31307
31389
  className: "DocSearch-AskAiScreen-Error",
31308
31390
  role: "alert"
31309
31391
  }, /* @__PURE__ */ En.createElement(AlertIcon, { "aria-hidden": "true" }), /* @__PURE__ */ En.createElement("div", { className: "DocSearch-AskAiScreen-Error-Content" }, /* @__PURE__ */ En.createElement("h4", { className: "DocSearch-AskAiScreen-Error-Title" }, errorTitleText), /* @__PURE__ */ En.createElement(MemoizedMarkdown, {
@@ -31351,11 +31433,12 @@ function AskAiExchangeCard({ exchange, askAiError, isLastExchange, loadingStatus
31351
31433
  return null;
31352
31434
  })), wasStopped && /* @__PURE__ */ En.createElement("p", { className: "DocSearch-AskAiScreen-MessageContent-Stopped" }, stoppedStreamingText)), /* @__PURE__ */ En.createElement("div", { className: "DocSearch-AskAiScreen-Answer-Footer" }, /* @__PURE__ */ En.createElement(SourcesPanel, {
31353
31435
  links: urlsToDisplay,
31354
- titleText: relatedSourcesText
31436
+ titleText: relatedSourcesText,
31437
+ pluralTitleText: relatedSourcesTextPlural
31355
31438
  }), /* @__PURE__ */ En.createElement(FeedbackActions, {
31356
31439
  id: messageId,
31357
31440
  showActions,
31358
- latestAssistantMessageContent: (assistantContent === null || assistantContent === void 0 ? void 0 : assistantContent.text) || null,
31441
+ latestAssistantMessageContent: assistantContent || null,
31359
31442
  translations,
31360
31443
  conversations,
31361
31444
  onFeedback
@@ -31423,7 +31506,7 @@ function RecentConversationsResults(_ref) {
31423
31506
  return /* @__PURE__ */ En.createElement(Results, _objectSpread2$2(_objectSpread2$2({}, props), {}, {
31424
31507
  title: recentConversationsTitle,
31425
31508
  collection: recentConversations,
31426
- renderIcon: () => /* @__PURE__ */ En.createElement("div", { className: "DocSearch-Hit-icon DocSearch-Hit-icon--small" }, /* @__PURE__ */ En.createElement(MessageIcon, null)),
31509
+ renderIcon: () => /* @__PURE__ */ En.createElement("div", { className: "DocSearch-Hit-icon DocSearch-Hit-icon--start" }, /* @__PURE__ */ En.createElement(MessageIcon, null)),
31427
31510
  renderAction: ({ item }) => /* @__PURE__ */ En.createElement("div", { className: "DocSearch-Hit-action" }, /* @__PURE__ */ En.createElement("button", {
31428
31511
  className: "DocSearch-Hit-action-button",
31429
31512
  title: removeRecentConversationButtonTitle,
@@ -31477,10 +31560,10 @@ function NewConversationScreen({ translations = {}, suggestedQuestions = [], sel
31477
31560
  onClick: () => selectSuggestedQuestion(question)
31478
31561
  }, question.question))));
31479
31562
  }
31480
- const _excluded$2 = ["translations", "selectAskAiQuestion"];
31563
+ const _excluded$2$1 = ["translations", "selectAskAiQuestion"];
31481
31564
  const AskAiScreenState = En.memo((_ref) => {
31482
31565
  var _props$state;
31483
- let { translations = {}, selectAskAiQuestion } = _ref, props = _objectWithoutProperties$6(_ref, _excluded$2);
31566
+ let { translations = {}, selectAskAiQuestion } = _ref, props = _objectWithoutProperties$6(_ref, _excluded$2$1);
31484
31567
  const handleSelectPromptSuggestion = En.useCallback((prompt) => {
31485
31568
  selectAskAiQuestion(true, prompt);
31486
31569
  }, [selectAskAiQuestion]);
@@ -31501,15 +31584,18 @@ const AskAiScreenState = En.memo((_ref) => {
31501
31584
  onSelectPromptSuggestion: handleSelectPromptSuggestion
31502
31585
  }));
31503
31586
  if (((_props$state = props.state) === null || _props$state === void 0 ? void 0 : _props$state.status) === "error") return /* @__PURE__ */ En.createElement(ErrorScreen, { translations: translations === null || translations === void 0 ? void 0 : translations.errorScreen });
31504
- if (!props.state.query) return /* @__PURE__ */ En.createElement(AskAiStartScreen, _objectSpread2$2(_objectSpread2$2({}, props), {}, {
31587
+ if (isQueryEmpty(props.state.query)) return /* @__PURE__ */ En.createElement(AskAiStartScreen, _objectSpread2$2(_objectSpread2$2({}, props), {}, {
31505
31588
  hasCollections: props.hasCollections,
31506
31589
  translations: translations === null || translations === void 0 ? void 0 : translations.startScreen,
31507
31590
  selectAskAiQuestion
31508
31591
  }));
31509
31592
  if (!props.hasCollections && !props.canHandleAskAi) return /* @__PURE__ */ En.createElement(NoResultsScreen, _objectSpread2$2(_objectSpread2$2({}, props), {}, { translations: translations === null || translations === void 0 ? void 0 : translations.noResultsScreen }));
31510
31593
  return /* @__PURE__ */ En.createElement(En.Fragment, null, /* @__PURE__ */ En.createElement(ResultsScreen, _objectSpread2$2(_objectSpread2$2({}, props), {}, { translations: translations === null || translations === void 0 ? void 0 : translations.resultsScreen })), props.canHandleAskAi && !props.hasCollections && /* @__PURE__ */ En.createElement(NoResultsScreen, _objectSpread2$2(_objectSpread2$2({}, props), {}, { translations: translations === null || translations === void 0 ? void 0 : translations.noResultsScreen })));
31511
- }, function areEqual(_prevProps, nextProps) {
31512
- return nextProps.state.status === "loading" || nextProps.state.status === "stalled";
31594
+ }, function areEqual(prevProps, nextProps) {
31595
+ if (prevProps.isAskAiActive !== nextProps.isAskAiActive || prevProps.askAiState !== nextProps.askAiState || prevProps.canHandleAskAi !== nextProps.canHandleAskAi) return false;
31596
+ const isLoading = nextProps.state.status === "loading" || nextProps.state.status === "stalled";
31597
+ const isWaitingForCollections = nextProps.state.status === "idle" && !isQueryEmpty(nextProps.state.query) && prevProps.state.query !== nextProps.state.query && prevProps.state.collections === nextProps.state.collections;
31598
+ return isLoading || isWaitingForCollections;
31513
31599
  });
31514
31600
  function ModalHeading({ heading, shimmer = false }) {
31515
31601
  return /* @__PURE__ */ En.createElement("span", { className: `DocSearch-Modal-heading${shimmer ? " DocSearch-shimmer" : ""}` }, heading);
@@ -31564,7 +31650,7 @@ function AskAiSearchBox(_ref) {
31564
31650
  onKeyDown: (e) => {
31565
31651
  let askAiHandled = false;
31566
31652
  if (props.isAskAiActive && blockedKeys.has(e.key)) {
31567
- if (e.key === "Enter" && !isAskAiStreaming && props.state.query) props.onAskAgain(props.state.query);
31653
+ if (e.key === "Enter" && !isAskAiStreaming && !isQueryEmpty(props.state.query)) props.onAskAgain(props.state.query);
31568
31654
  askAiHandled = true;
31569
31655
  }
31570
31656
  if (askAiHandled) {
@@ -31766,10 +31852,9 @@ const _excluded$7 = [
31766
31852
  "recentSearchesLimit",
31767
31853
  "recentSearchesWithFavoritesLimit",
31768
31854
  "indices",
31769
- "indexName",
31770
- "searchParameters",
31771
31855
  "facets",
31772
- "isHybridModeSupported"
31856
+ "isHybridModeSupported",
31857
+ "footerAction"
31773
31858
  ];
31774
31859
  const _excluded2 = [
31775
31860
  "footer",
@@ -31778,7 +31863,7 @@ const _excluded2 = [
31778
31863
  ];
31779
31864
  function DocSearchAskAiModal(_ref) {
31780
31865
  var _translations$searchB, _askAiConfig$memory$e, _askAiConfig$memory, _askAiConfig$tools;
31781
- let { appId, apiKey, askAi, maxResultsPerGroup, theme, onClose = noop$2, transformItems = identity, hitComponent = Hit, resultsFooterComponent = () => null, navigator, initialScrollY = 0, transformSearchClient = identity, disableUserPersonalization = false, initialQuery: initialQueryFromProp = "", translations = {}, getMissingResultsUrl, insights = false, onAskAiToggle, interceptAskAiEvent, isAskAiActive = false, recentSearchesLimit = 7, recentSearchesWithFavoritesLimit = 4, indices = [], indexName, searchParameters, facets, isHybridModeSupported = false } = _ref, props = _objectWithoutProperties$6(_ref, _excluded$7);
31866
+ let { appId, apiKey, askAi, maxResultsPerGroup, theme, onClose = noop$2, transformItems = identity, hitComponent = Hit, resultsFooterComponent = () => null, navigator, initialScrollY = 0, transformSearchClient = identity, disableUserPersonalization = false, initialQuery: initialQueryFromProp = "", translations = {}, getMissingResultsUrl, insights = false, onAskAiToggle, interceptAskAiEvent, isAskAiActive = false, recentSearchesLimit = 7, recentSearchesWithFavoritesLimit = 4, indices, facets, isHybridModeSupported = false, footerAction } = _ref, props = _objectWithoutProperties$6(_ref, _excluded$7);
31782
31867
  const { footer: footerTranslations, searchBox: searchBoxTranslations, facets: facetBarTranslations } = translations, screenStateTranslations = _objectWithoutProperties$6(translations, _excluded2);
31783
31868
  const [state, setState] = En.useState({
31784
31869
  query: "",
@@ -31799,29 +31884,21 @@ function DocSearchAskAiModal(_ref) {
31799
31884
  var _translations$searchB3;
31800
31885
  placeholder = (translations === null || translations === void 0 || (_translations$searchB3 = translations.searchBox) === null || _translations$searchB3 === void 0 ? void 0 : _translations$searchB3.placeholderTextAskAi) || "Ask another question...";
31801
31886
  }
31802
- const { containerRef, modalRef, formElementRef, dropdownRef, inputRef, snippetLength } = useModalRefs();
31887
+ const { containerRef, modalRef, formElementRef, dropdownRef, inputRef } = useModalRefs();
31803
31888
  const { initialQuery, initialQueryFromSelection } = useInitialModalQuery(initialQueryFromProp);
31804
31889
  const searchClient = useSearchClient(appId, apiKey, transformSearchClient);
31805
31890
  const askAiConfig = typeof askAi === "object" ? askAi : null;
31806
- const askAiConfigurationId = askAiConfig ? askAiConfig.assistantId : askAi;
31891
+ const askAiConfigurationId = askAiConfig ? askAiConfig.agentId : askAi;
31807
31892
  const askAiSearchParameters = askAiConfig === null || askAiConfig === void 0 ? void 0 : askAiConfig.searchParameters;
31808
31893
  const [askAiState, setAskAiState] = En.useState("initial");
31809
31894
  const suggestedQuestions = useSuggestedQuestions({
31810
- assistantId: askAiConfigurationId,
31895
+ agentId: askAiConfigurationId,
31811
31896
  searchClient,
31812
31897
  suggestedQuestionsEnabled: askAiConfig === null || askAiConfig === void 0 ? void 0 : askAiConfig.suggestedQuestions
31813
31898
  });
31814
31899
  const memoryEnabled = (_askAiConfig$memory$e = askAiConfig === null || askAiConfig === void 0 || (_askAiConfig$memory = askAiConfig.memory) === null || _askAiConfig$memory === void 0 ? void 0 : _askAiConfig$memory.enabled) !== null && _askAiConfig$memory$e !== void 0 ? _askAiConfig$memory$e : false;
31815
31900
  const tools = (_askAiConfig$tools = askAiConfig === null || askAiConfig === void 0 ? void 0 : askAiConfig.tools) !== null && _askAiConfig$tools !== void 0 ? _askAiConfig$tools : EMPTY_TOOLS;
31816
- const indexes = En.useMemo(() => normalizeDocSearchIndexes({
31817
- indexName,
31818
- indices,
31819
- searchParameters
31820
- }), [
31821
- indexName,
31822
- indices,
31823
- searchParameters
31824
- ]);
31901
+ const indexes = En.useMemo(() => normalizeDocSearchIndexes({ indices }), [indices]);
31825
31902
  const defaultIndexName = indexes[0].name;
31826
31903
  const autocompleteRef = En.useRef(void 0);
31827
31904
  const { visibleFacets, facetSelections, facetSelectionsRef, handleFacetSelectionChange, clearFacetSelections } = useDocSearchFacets({
@@ -31840,10 +31917,9 @@ function DocSearchAskAiModal(_ref) {
31840
31917
  });
31841
31918
  const [stoppedStream, setStoppedStream] = En.useState(false);
31842
31919
  const { chatId, messages, status, setMessages, sendMessage, stopAskAiStreaming, askAiError, sendFeedback, conversations, startNewConversation, restoreConversation } = useAskAi({
31843
- assistantId: askAiConfigurationId,
31920
+ agentId: askAiConfigurationId,
31844
31921
  apiKey: (askAiConfig === null || askAiConfig === void 0 ? void 0 : askAiConfig.apiKey) || apiKey,
31845
31922
  appId: (askAiConfig === null || askAiConfig === void 0 ? void 0 : askAiConfig.appId) || appId,
31846
- indexName: (askAiConfig === null || askAiConfig === void 0 ? void 0 : askAiConfig.indexName) || defaultIndexName,
31847
31923
  searchParameters: askAiSearchParameters,
31848
31924
  tools,
31849
31925
  memory: askAiConfig === null || askAiConfig === void 0 ? void 0 : askAiConfig.memory,
@@ -31940,7 +32016,7 @@ function DocSearchAskAiModal(_ref) {
31940
32016
  setState(changes.state);
31941
32017
  },
31942
32018
  async getSources({ query, state: sourcesState, setContext, setStatus }) {
31943
- if (!query) {
32019
+ if (isQueryEmpty(query)) {
31944
32020
  const noQuerySources = buildNoQuerySources({
31945
32021
  recentSearches,
31946
32022
  favoriteSearches,
@@ -31962,7 +32038,6 @@ function DocSearchAskAiModal(_ref) {
31962
32038
  setStatus,
31963
32039
  searchClient,
31964
32040
  indexes,
31965
- snippetLength,
31966
32041
  insights: Boolean(insights),
31967
32042
  appId,
31968
32043
  apiKey,
@@ -31992,7 +32067,6 @@ function DocSearchAskAiModal(_ref) {
31992
32067
  inputRef,
31993
32068
  initialScrollY,
31994
32069
  modalRef,
31995
- snippetLength,
31996
32070
  theme
31997
32071
  });
31998
32072
  En.useEffect(() => {
@@ -32038,7 +32112,7 @@ function DocSearchAskAiModal(_ref) {
32038
32112
  };
32039
32113
  let showDocsearchDropdown = true;
32040
32114
  const hasCollections = state.collections.some((collection) => collection.source.sourceId !== SOURCE_IDS.askAI && collection.items.length > 0);
32041
- if (state.status === "idle" && hasCollections === false && state.query.length === 0 && !isAskAiActive) showDocsearchDropdown = false;
32115
+ if (state.status === "idle" && hasCollections === false && isQueryEmpty(state.query) && !isAskAiActive) showDocsearchDropdown = false;
32042
32116
  return /* @__PURE__ */ En.createElement(ModalShell, {
32043
32117
  state,
32044
32118
  containerRef,
@@ -32050,7 +32124,7 @@ function DocSearchAskAiModal(_ref) {
32050
32124
  searchBox: /* @__PURE__ */ En.createElement(AskAiSearchBox, _objectSpread2$2(_objectSpread2$2({}, autocomplete), {}, {
32051
32125
  state,
32052
32126
  placeholder: placeholder || "Search docs",
32053
- autoFocus: initialQuery.length === 0,
32127
+ autoFocus: isQueryEmpty(initialQuery),
32054
32128
  inputRef,
32055
32129
  isFromSelection: Boolean(initialQuery) && initialQuery === initialQueryFromSelection,
32056
32130
  translations: searchBoxTranslations,
@@ -32069,7 +32143,7 @@ function DocSearchAskAiModal(_ref) {
32069
32143
  onNewConversation: handleNewConversation,
32070
32144
  onViewConversationHistory: handleViewConversationHistory
32071
32145
  })),
32072
- filterBar: !isAskAiActive && state.query !== "" ? /* @__PURE__ */ En.createElement(FacetBar, {
32146
+ filterBar: !isAskAiActive && !isQueryEmpty(state.query) ? /* @__PURE__ */ En.createElement(FacetBar, {
32073
32147
  facets: visibleFacets,
32074
32148
  selections: facetSelections,
32075
32149
  translations: facetBarTranslations,
@@ -32131,7 +32205,8 @@ function DocSearchAskAiModal(_ref) {
32131
32205
  })),
32132
32206
  footer: /* @__PURE__ */ En.createElement(Footer, {
32133
32207
  translations: footerTranslations,
32134
- isAskAiActive
32208
+ isAskAiActive,
32209
+ footerAction
32135
32210
  }),
32136
32211
  onClose
32137
32212
  });
@@ -32216,7 +32291,7 @@ init_compat();
32216
32291
  function isEditingContent(event) {
32217
32292
  const element = event.composedPath()[0];
32218
32293
  const tagName = element.tagName;
32219
- return element.isContentEditable || tagName === "INPUT" || tagName === "SELECT" || tagName === "TEXTAREA";
32294
+ return element.isContentEditable || tagName === "INPUT" || tagName === "SELECT" || tagName === "TEXTAREA" || tagName === "BUTTON";
32220
32295
  }
32221
32296
  function useDocSearchKeyboardEvents({ isOpen, isAskAiActive, onAskAiToggle, onClose, onOpen, keyboardShortcuts = DEFAULT_KEYBOARD_SHORTCUTS }) {
32222
32297
  En.useEffect(() => {
@@ -32284,8 +32359,10 @@ function _objectWithoutProperties(e, t) {
32284
32359
  }
32285
32360
  return i;
32286
32361
  }
32287
- const _excluded$1 = [
32362
+ const _excluded$2 = [
32288
32363
  "children",
32364
+ "appId",
32365
+ "apiKey",
32289
32366
  "theme",
32290
32367
  "onReady",
32291
32368
  "onOpen",
@@ -32296,7 +32373,7 @@ const _excluded$1 = [
32296
32373
  const Context = En.createContext(void 0);
32297
32374
  Context.displayName = "DocSearchContext";
32298
32375
  function DocSearchInner(_ref, ref) {
32299
- let { children, theme, onReady, onOpen, onClose, onSidepanelOpen, onSidepanelClose } = _ref, props = _objectWithoutProperties(_ref, _excluded$1);
32376
+ let { children, appId, apiKey, theme, onReady, onOpen, onClose, onSidepanelOpen, onSidepanelClose } = _ref, props = _objectWithoutProperties(_ref, _excluded$2);
32300
32377
  const [docsearchState, setDocsearchState] = En.useState("ready");
32301
32378
  const [initialQuery, setInitialQuery] = En.useState(props.initialQuery || "");
32302
32379
  const searchButtonRef = En.useRef(null);
@@ -32403,6 +32480,8 @@ function DocSearchInner(_ref, ref) {
32403
32480
  keyboardShortcuts
32404
32481
  });
32405
32482
  const value = En.useMemo(() => ({
32483
+ appId,
32484
+ apiKey,
32406
32485
  docsearchState,
32407
32486
  setDocsearchState,
32408
32487
  searchButtonRef,
@@ -32417,6 +32496,8 @@ function DocSearchInner(_ref, ref) {
32417
32496
  registerView,
32418
32497
  isHybridModeSupported
32419
32498
  }), [
32499
+ appId,
32500
+ apiKey,
32420
32501
  docsearchState,
32421
32502
  searchButtonRef,
32422
32503
  initialQuery,
@@ -32443,19 +32524,28 @@ function useDocSearch() {
32443
32524
  //#endregion
32444
32525
  //#region ../docsearch-react/dist/esm/docsearchAi.js
32445
32526
  init_compat();
32446
- function DocSearchAIComponent(props, ref) {
32447
- return /* @__PURE__ */ En.createElement(DocSearch, _objectSpread2$2(_objectSpread2$2({}, props), {}, { ref }), /* @__PURE__ */ En.createElement(DocSearchAIInner, props));
32527
+ const _excluded$1 = ["appId", "apiKey"];
32528
+ function DocSearchAIComponent(_ref, ref) {
32529
+ let { appId, apiKey } = _ref, props = _objectWithoutProperties$6(_ref, _excluded$1);
32530
+ return /* @__PURE__ */ En.createElement(DocSearch, _objectSpread2$2(_objectSpread2$2({}, props), {}, {
32531
+ appId,
32532
+ apiKey,
32533
+ ref
32534
+ }), /* @__PURE__ */ En.createElement(DocSearchAIInner, props));
32448
32535
  }
32449
32536
  const DocSearchAI = En.forwardRef(DocSearchAIComponent);
32450
32537
  function DocSearchAIInner(props) {
32451
32538
  var _props$translations, _props$translations2, _props$portalContaine;
32452
- const { searchButtonRef, keyboardShortcuts, isModalActive, isAskAiActive, initialQuery, onAskAiToggle, openModal, closeModal, isHybridModeSupported } = useDocSearch();
32539
+ const { searchButtonRef, keyboardShortcuts, isModalActive, isAskAiActive, initialQuery, onAskAiToggle, openModal, closeModal, isHybridModeSupported, appId, apiKey } = useDocSearch();
32540
+ if (!appId || !apiKey) throw new Error("`DocSearchAI` requires `appId` and `apiKey` props.");
32453
32541
  return /* @__PURE__ */ En.createElement(En.Fragment, null, /* @__PURE__ */ En.createElement(DocSearchButton, {
32454
32542
  keyboardShortcuts,
32455
32543
  ref: searchButtonRef,
32456
32544
  translations: (_props$translations = props.translations) === null || _props$translations === void 0 ? void 0 : _props$translations.button,
32457
32545
  onClick: openModal
32458
32546
  }), isModalActive && H(/* @__PURE__ */ En.createElement(DocSearchAskAiModal, _objectSpread2$2(_objectSpread2$2({}, props), {}, {
32547
+ appId,
32548
+ apiKey,
32459
32549
  initialScrollY: window.scrollY,
32460
32550
  initialQuery,
32461
32551
  translations: props === null || props === void 0 || (_props$translations2 = props.translations) === null || _props$translations2 === void 0 ? void 0 : _props$translations2.modal,
@@ -32499,7 +32589,8 @@ const _excluded = [
32499
32589
  "environment",
32500
32590
  "transformSearchClient",
32501
32591
  "hitComponent",
32502
- "resultsFooterComponent"
32592
+ "resultsFooterComponent",
32593
+ "footerAction"
32503
32594
  ];
32504
32595
  function getHTMLElement(value, env) {
32505
32596
  if (typeof value !== "string") return value;
@@ -32522,14 +32613,16 @@ function createTemplateFunction(original) {
32522
32613
  function createDocSearch(Component, version) {
32523
32614
  return (allProps) => {
32524
32615
  const input = allProps;
32525
- const { container, environment, transformSearchClient, hitComponent, resultsFooterComponent } = input, rest = _objectWithoutProperties$5(input, _excluded);
32616
+ const { container, environment, transformSearchClient, hitComponent, resultsFooterComponent, footerAction } = input, rest = _objectWithoutProperties$5(input, _excluded);
32526
32617
  const containerElement = getHTMLElement(container, environment || (typeof window !== "undefined" ? window : void 0));
32527
32618
  const ref = b$2();
32528
32619
  let isReady = false;
32620
+ const FooterAction = createTemplateFunction(footerAction);
32529
32621
  J$1(_$2(Component, _objectSpread2$1(_objectSpread2$1({}, rest), {}, {
32530
32622
  ref,
32531
32623
  hitComponent: createTemplateFunction(hitComponent),
32532
32624
  resultsFooterComponent: createTemplateFunction(resultsFooterComponent),
32625
+ footerAction: FooterAction ? _$2(FooterAction, null) : void 0,
32533
32626
  transformSearchClient: (searchClient) => {
32534
32627
  if (typeof searchClient === "object" && searchClient !== null && "addAlgoliaAgent" in searchClient && typeof searchClient.addAlgoliaAgent === "function") searchClient.addAlgoliaAgent("docsearch.js", version);
32535
32628
  return typeof transformSearchClient === "function" ? transformSearchClient(searchClient) : searchClient;