@backstage/plugin-search-react 1.4.0 → 1.5.0-next.1

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/index.esm.js CHANGED
@@ -1,21 +1,21 @@
1
- import { createApiRef, AnalyticsContext, useApi, useAnalytics, configApiRef } from '@backstage/core-plugin-api';
2
- import React, { useMemo, useContext, useState, useCallback, useEffect, forwardRef, useRef } from 'react';
3
- import { makeStyles, InputBase, InputAdornment, IconButton, CircularProgress, ListItemIcon, ListItemText, TextField, Chip, FormControl, FormLabel, FormControlLabel, Checkbox, InputLabel, Select, MenuItem, Button, TablePagination, ListItem, Box, Divider, List, Typography as Typography$1, ListSubheader, Menu } from '@material-ui/core';
1
+ import { createApiRef, AnalyticsContext, useApi, useAnalytics, configApiRef, createReactExtension, useElementFilter, getComponentData } from '@backstage/core-plugin-api';
2
+ import React, { useMemo, useContext, useState, useCallback, useEffect, forwardRef, useRef, createElement, Fragment, isValidElement, cloneElement } from 'react';
3
+ import { makeStyles, InputBase, InputAdornment, IconButton, CircularProgress, ListItemIcon, ListItemText, TextField, Chip, FormControl, FormLabel, FormControlLabel, Checkbox, InputLabel, Select, MenuItem, TablePagination, Box, List, Typography as Typography$1, ListSubheader, Menu, Button, ListItem } from '@material-ui/core';
4
4
  import useDebounce from 'react-use/lib/useDebounce';
5
5
  import SearchIcon from '@material-ui/icons/Search';
6
6
  import ClearButton from '@material-ui/icons/Clear';
7
- import { isEqual } from 'lodash';
7
+ import { isEqual, isFunction } from 'lodash';
8
8
  import useAsync from 'react-use/lib/useAsync';
9
9
  import usePrevious from 'react-use/lib/usePrevious';
10
10
  import { createVersionedContext, createVersionedValueMap } from '@backstage/version-bridge';
11
11
  import { Autocomplete } from '@material-ui/lab';
12
12
  import useAsyncFn from 'react-use/lib/useAsyncFn';
13
13
  import { Progress, ResponseErrorPanel, EmptyState, Link } from '@backstage/core-components';
14
- import ArrowBackIosIcon from '@material-ui/icons/ArrowBackIos';
15
- import ArrowForwardIosIcon from '@material-ui/icons/ArrowForwardIos';
16
14
  import Typography from '@material-ui/core/Typography';
17
15
  import qs from 'qs';
18
16
  import AddIcon from '@material-ui/icons/Add';
17
+ import ArrowRightIcon from '@material-ui/icons/ArrowForwardIos';
18
+ import ArrowBackIosIcon from '@material-ui/icons/ArrowBackIos';
19
19
 
20
20
  const searchApiRef = createApiRef({
21
21
  id: "plugin.search.queryservice"
@@ -622,96 +622,6 @@ SearchFilter.Checkbox = (props) => /* @__PURE__ */ React.createElement(SearchFil
622
622
  SearchFilter.Select = (props) => /* @__PURE__ */ React.createElement(SearchFilter, { ...props, component: SelectFilter });
623
623
  SearchFilter.Autocomplete = (props) => /* @__PURE__ */ React.createElement(SearchFilter, { ...props, component: AutocompleteFilter });
624
624
 
625
- const SearchResultContext = (props) => {
626
- const { children } = props;
627
- const context = useSearch();
628
- const state = context.result;
629
- return children(state);
630
- };
631
- const SearchResultApi = (props) => {
632
- const { query, children } = props;
633
- const searchApi = useApi(searchApiRef);
634
- const state = useAsync(() => {
635
- const { term = "", types = [], filters = {}, ...rest } = query;
636
- return searchApi.query({ ...rest, term, types, filters });
637
- }, [query]);
638
- return children(state);
639
- };
640
- const SearchResultState = (props) => {
641
- const { query, children } = props;
642
- return query ? /* @__PURE__ */ React.createElement(SearchResultApi, { query }, children) : /* @__PURE__ */ React.createElement(SearchResultContext, null, children);
643
- };
644
- const SearchResultComponent = (props) => {
645
- const {
646
- query,
647
- children,
648
- noResultsComponent = /* @__PURE__ */ React.createElement(EmptyState, { missing: "data", title: "Sorry, no results were found" })
649
- } = props;
650
- return /* @__PURE__ */ React.createElement(SearchResultState, { query }, ({ loading, error, value }) => {
651
- if (loading) {
652
- return /* @__PURE__ */ React.createElement(Progress, null);
653
- }
654
- if (error) {
655
- return /* @__PURE__ */ React.createElement(
656
- ResponseErrorPanel,
657
- {
658
- title: "Error encountered while fetching search results",
659
- error
660
- }
661
- );
662
- }
663
- if (!(value == null ? void 0 : value.results.length)) {
664
- return noResultsComponent;
665
- }
666
- return children(value);
667
- });
668
- };
669
- const SearchResult = (props) => /* @__PURE__ */ React.createElement(
670
- AnalyticsContext,
671
- {
672
- attributes: {
673
- pluginId: "search",
674
- extension: "SearchResult"
675
- }
676
- },
677
- /* @__PURE__ */ React.createElement(SearchResultComponent, { ...props })
678
- );
679
-
680
- const useStyles$1 = makeStyles((theme) => ({
681
- root: {
682
- display: "flex",
683
- justifyContent: "space-between",
684
- gap: theme.spacing(2),
685
- margin: theme.spacing(2, 0)
686
- }
687
- }));
688
- const SearchResultPager = () => {
689
- const { fetchNextPage, fetchPreviousPage } = useSearch();
690
- const classes = useStyles$1();
691
- if (!fetchNextPage && !fetchPreviousPage) {
692
- return /* @__PURE__ */ React.createElement(React.Fragment, null);
693
- }
694
- return /* @__PURE__ */ React.createElement("nav", { "aria-label": "pagination navigation", className: classes.root }, /* @__PURE__ */ React.createElement(
695
- Button,
696
- {
697
- "aria-label": "previous page",
698
- disabled: !fetchPreviousPage,
699
- onClick: fetchPreviousPage,
700
- startIcon: /* @__PURE__ */ React.createElement(ArrowBackIosIcon, null)
701
- },
702
- "Previous"
703
- ), /* @__PURE__ */ React.createElement(
704
- Button,
705
- {
706
- "aria-label": "next page",
707
- disabled: !fetchNextPage,
708
- onClick: fetchNextPage,
709
- endIcon: /* @__PURE__ */ React.createElement(ArrowForwardIosIcon, null)
710
- },
711
- "Next"
712
- ));
713
- };
714
-
715
625
  const encodePageCursor = (pageCursor) => {
716
626
  return Buffer.from(pageCursor.toString(), "utf-8").toString("base64");
717
627
  };
@@ -776,26 +686,79 @@ const SearchPagination = (props) => {
776
686
  );
777
687
  };
778
688
 
689
+ const SearchResultContext = (props) => {
690
+ const { children } = props;
691
+ const context = useSearch();
692
+ const { result: state, ...query } = context;
693
+ return children(state, query);
694
+ };
695
+ const SearchResultApi = (props) => {
696
+ const { query, children } = props;
697
+ const searchApi = useApi(searchApiRef);
698
+ const state = useAsync(() => {
699
+ const { term = "", types = [], filters = {}, ...rest } = query;
700
+ return searchApi.query({ ...rest, term, types, filters });
701
+ }, [query]);
702
+ return children(state, query);
703
+ };
704
+ const SearchResultState = (props) => {
705
+ const { query, children } = props;
706
+ return query ? /* @__PURE__ */ React.createElement(SearchResultApi, { query }, children) : /* @__PURE__ */ React.createElement(SearchResultContext, null, children);
707
+ };
708
+ const SearchResultComponent = (props) => {
709
+ const {
710
+ query,
711
+ children,
712
+ noResultsComponent = /* @__PURE__ */ React.createElement(EmptyState, { missing: "data", title: "Sorry, no results were found" }),
713
+ ...rest
714
+ } = props;
715
+ return /* @__PURE__ */ React.createElement(SearchResultState, { query }, ({ loading, error, value }) => {
716
+ if (loading) {
717
+ return /* @__PURE__ */ React.createElement(Progress, null);
718
+ }
719
+ if (error) {
720
+ return /* @__PURE__ */ React.createElement(
721
+ ResponseErrorPanel,
722
+ {
723
+ title: "Error encountered while fetching search results",
724
+ error
725
+ }
726
+ );
727
+ }
728
+ if (!(value == null ? void 0 : value.results.length)) {
729
+ return noResultsComponent;
730
+ }
731
+ if (isFunction(children)) {
732
+ return children(value);
733
+ }
734
+ return /* @__PURE__ */ React.createElement(SearchResultListItemExtensions, { ...rest, results: value.results }, children);
735
+ });
736
+ };
737
+ const SearchResult = (props) => /* @__PURE__ */ React.createElement(
738
+ AnalyticsContext,
739
+ {
740
+ attributes: {
741
+ pluginId: "search",
742
+ extension: "SearchResult"
743
+ }
744
+ },
745
+ /* @__PURE__ */ React.createElement(SearchResultComponent, { ...props })
746
+ );
747
+
779
748
  const DefaultResultListItemComponent = ({
780
749
  result,
781
750
  highlight,
782
- rank,
783
751
  icon,
784
752
  secondaryAction,
785
753
  lineClamp = 5
786
754
  }) => {
787
- const analytics = useAnalytics();
788
- const handleClick = () => {
789
- analytics.captureEvent("discover", result.title, {
790
- attributes: { to: result.location },
791
- value: rank
792
- });
793
- };
794
- return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(ListItem, { alignItems: "center" }, icon && /* @__PURE__ */ React.createElement(ListItemIcon, null, icon), /* @__PURE__ */ React.createElement(
755
+ if (!result)
756
+ return null;
757
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, icon && /* @__PURE__ */ React.createElement(ListItemIcon, null, icon), /* @__PURE__ */ React.createElement(
795
758
  ListItemText,
796
759
  {
797
760
  primaryTypographyProps: { variant: "h6" },
798
- primary: /* @__PURE__ */ React.createElement(Link, { noTrack: true, to: result.location, onClick: handleClick }, (highlight == null ? void 0 : highlight.fields.title) ? /* @__PURE__ */ React.createElement(
761
+ primary: /* @__PURE__ */ React.createElement(Link, { noTrack: true, to: result.location }, (highlight == null ? void 0 : highlight.fields.title) ? /* @__PURE__ */ React.createElement(
799
762
  HighlightedSearchResultText,
800
763
  {
801
764
  text: (highlight == null ? void 0 : highlight.fields.title) || "",
@@ -824,7 +787,7 @@ const DefaultResultListItemComponent = ({
824
787
  ) : result.text
825
788
  )
826
789
  }
827
- ), secondaryAction && /* @__PURE__ */ React.createElement(Box, { alignItems: "flex-end" }, secondaryAction)), /* @__PURE__ */ React.createElement(Divider, null));
790
+ ), secondaryAction && /* @__PURE__ */ React.createElement(Box, { alignItems: "flex-end" }, secondaryAction));
828
791
  };
829
792
  const HigherOrderDefaultResultListItem = (props) => {
830
793
  return /* @__PURE__ */ React.createElement(
@@ -841,8 +804,8 @@ const HigherOrderDefaultResultListItem = (props) => {
841
804
 
842
805
  const SearchResultListLayout = (props) => {
843
806
  const {
844
- loading,
845
807
  error,
808
+ loading,
846
809
  resultItems,
847
810
  renderResultItem = (resultItem) => /* @__PURE__ */ React.createElement(
848
811
  HigherOrderDefaultResultListItem,
@@ -851,19 +814,30 @@ const SearchResultListLayout = (props) => {
851
814
  result: resultItem.document
852
815
  }
853
816
  ),
854
- noResultsComponent = /* @__PURE__ */ React.createElement(EmptyState, { missing: "data", title: "Sorry, no results were found" }),
817
+ disableRenderingWithNoResults,
818
+ noResultsComponent = disableRenderingWithNoResults ? null : /* @__PURE__ */ React.createElement(EmptyState, { missing: "data", title: "Sorry, no results were found" }),
855
819
  ...rest
856
820
  } = props;
857
- return /* @__PURE__ */ React.createElement(List, { ...rest }, loading ? /* @__PURE__ */ React.createElement(Progress, null) : null, !loading && error ? /* @__PURE__ */ React.createElement(
858
- ResponseErrorPanel,
859
- {
860
- title: "Error encountered while fetching search results",
861
- error
862
- }
863
- ) : null, !loading && !error && (resultItems == null ? void 0 : resultItems.length) ? resultItems.map(renderResultItem) : null, !loading && !error && !(resultItems == null ? void 0 : resultItems.length) ? /* @__PURE__ */ React.createElement(ListItem, null, noResultsComponent) : null);
821
+ if (loading) {
822
+ return /* @__PURE__ */ React.createElement(Progress, null);
823
+ }
824
+ if (error) {
825
+ return /* @__PURE__ */ React.createElement(
826
+ ResponseErrorPanel,
827
+ {
828
+ title: "Error encountered while fetching search results",
829
+ error
830
+ }
831
+ );
832
+ }
833
+ if (!(resultItems == null ? void 0 : resultItems.length)) {
834
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, noResultsComponent);
835
+ }
836
+ return /* @__PURE__ */ React.createElement(List, { ...rest }, resultItems.map(renderResultItem));
864
837
  };
865
838
  const SearchResultList = (props) => {
866
- const { query, disableRenderingWithNoResults, ...rest } = props;
839
+ const { query, renderResultItem, children, ...rest } = props;
840
+ const defaultRenderResultItem = useSearchResultListItemExtensions(children);
867
841
  return /* @__PURE__ */ React.createElement(
868
842
  AnalyticsContext,
869
843
  {
@@ -872,25 +846,20 @@ const SearchResultList = (props) => {
872
846
  extension: "SearchResultList"
873
847
  }
874
848
  },
875
- /* @__PURE__ */ React.createElement(SearchResultState, { query }, ({ loading, error, value }) => {
876
- var _a;
877
- if (!((_a = value == null ? void 0 : value.results) == null ? void 0 : _a.length) && disableRenderingWithNoResults) {
878
- return null;
849
+ /* @__PURE__ */ React.createElement(SearchResultState, { query }, ({ loading, error, value }) => /* @__PURE__ */ React.createElement(
850
+ SearchResultListLayout,
851
+ {
852
+ ...rest,
853
+ error,
854
+ loading,
855
+ resultItems: value == null ? void 0 : value.results,
856
+ renderResultItem: renderResultItem != null ? renderResultItem : defaultRenderResultItem
879
857
  }
880
- return /* @__PURE__ */ React.createElement(
881
- SearchResultListLayout,
882
- {
883
- ...rest,
884
- loading,
885
- error,
886
- resultItems: value == null ? void 0 : value.results
887
- }
888
- );
889
- })
858
+ ))
890
859
  );
891
860
  };
892
861
 
893
- const useStyles = makeStyles((theme) => ({
862
+ const useStyles$1 = makeStyles((theme) => ({
894
863
  listSubheader: {
895
864
  display: "flex",
896
865
  alignItems: "center"
@@ -919,7 +888,7 @@ const useStyles = makeStyles((theme) => ({
919
888
  }
920
889
  }));
921
890
  const SearchResultGroupFilterFieldLayout = (props) => {
922
- const classes = useStyles();
891
+ const classes = useStyles$1();
923
892
  const { label, children, ...rest } = props;
924
893
  return /* @__PURE__ */ React.createElement(
925
894
  Chip,
@@ -1011,15 +980,15 @@ const SearchResultGroupSelectFilterField = (props) => {
1011
980
  ));
1012
981
  };
1013
982
  function SearchResultGroupLayout(props) {
1014
- const classes = useStyles();
983
+ const classes = useStyles$1();
1015
984
  const [anchorEl, setAnchorEl] = useState(null);
1016
985
  const {
1017
- loading,
1018
986
  error,
987
+ loading,
1019
988
  icon,
1020
989
  title,
1021
990
  titleProps = {},
1022
- link = /* @__PURE__ */ React.createElement(React.Fragment, null, "See all", /* @__PURE__ */ React.createElement(ArrowForwardIosIcon, { className: classes.listSubheaderLinkIcon })),
991
+ link = /* @__PURE__ */ React.createElement(React.Fragment, null, "See all", /* @__PURE__ */ React.createElement(ArrowRightIcon, { className: classes.listSubheaderLinkIcon })),
1023
992
  linkProps = {},
1024
993
  filterOptions,
1025
994
  renderFilterOption = (filterOption) => /* @__PURE__ */ React.createElement(MenuItem, { key: String(filterOption), value: String(filterOption) }, filterOption),
@@ -1033,7 +1002,8 @@ function SearchResultGroupLayout(props) {
1033
1002
  result: resultItem.document
1034
1003
  }
1035
1004
  ),
1036
- noResultsComponent = /* @__PURE__ */ React.createElement(EmptyState, { missing: "data", title: "Sorry, no results were found" }),
1005
+ disableRenderingWithNoResults,
1006
+ noResultsComponent = disableRenderingWithNoResults ? null : /* @__PURE__ */ React.createElement(EmptyState, { missing: "data", title: "Sorry, no results were found" }),
1037
1007
  ...rest
1038
1008
  } = props;
1039
1009
  const handleClick = useCallback((e) => {
@@ -1042,6 +1012,21 @@ function SearchResultGroupLayout(props) {
1042
1012
  const handleClose = useCallback(() => {
1043
1013
  setAnchorEl(null);
1044
1014
  }, []);
1015
+ if (loading) {
1016
+ return /* @__PURE__ */ React.createElement(Progress, null);
1017
+ }
1018
+ if (error) {
1019
+ return /* @__PURE__ */ React.createElement(
1020
+ ResponseErrorPanel,
1021
+ {
1022
+ title: "Error encountered while fetching search results",
1023
+ error
1024
+ }
1025
+ );
1026
+ }
1027
+ if (!(resultItems == null ? void 0 : resultItems.length)) {
1028
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, noResultsComponent);
1029
+ }
1045
1030
  return /* @__PURE__ */ React.createElement(List, { ...rest }, /* @__PURE__ */ React.createElement(ListSubheader, { className: classes.listSubheader }, icon, /* @__PURE__ */ React.createElement(
1046
1031
  Typography$1,
1047
1032
  {
@@ -1078,30 +1063,11 @@ function SearchResultGroupLayout(props) {
1078
1063
  var _a;
1079
1064
  return (_a = renderFilterField == null ? void 0 : renderFilterField(filterField)) != null ? _a : null;
1080
1065
  }
1081
- ), /* @__PURE__ */ React.createElement(Link, { className: classes.listSubheaderLink, to: "/search", ...linkProps }, link)), loading ? /* @__PURE__ */ React.createElement(Progress, null) : null, !loading && error ? /* @__PURE__ */ React.createElement(
1082
- ResponseErrorPanel,
1083
- {
1084
- title: "Error encountered while fetching search results",
1085
- error
1086
- }
1087
- ) : null, !loading && !error && (resultItems == null ? void 0 : resultItems.length) ? resultItems.map(renderResultItem) : null, !loading && !error && !(resultItems == null ? void 0 : resultItems.length) ? /* @__PURE__ */ React.createElement(ListItem, null, noResultsComponent) : null);
1066
+ ), /* @__PURE__ */ React.createElement(Link, { className: classes.listSubheaderLink, to: "/search", ...linkProps }, link)), resultItems.map(renderResultItem));
1088
1067
  }
1089
1068
  function SearchResultGroup(props) {
1090
- const {
1091
- query,
1092
- linkProps = {},
1093
- disableRenderingWithNoResults,
1094
- ...rest
1095
- } = props;
1096
- const to = `/search?${qs.stringify(
1097
- {
1098
- query: query.term,
1099
- types: query.types,
1100
- filters: query.filters,
1101
- pageCursor: query.pageCursor
1102
- },
1103
- { arrayFormat: "brackets" }
1104
- )}`;
1069
+ const { query, children, renderResultItem, linkProps = {}, ...rest } = props;
1070
+ const defaultRenderResultItem = useSearchResultListItemExtensions(children);
1105
1071
  return /* @__PURE__ */ React.createElement(
1106
1072
  AnalyticsContext,
1107
1073
  {
@@ -1110,25 +1076,176 @@ function SearchResultGroup(props) {
1110
1076
  extension: "SearchResultGroup"
1111
1077
  }
1112
1078
  },
1113
- /* @__PURE__ */ React.createElement(SearchResultState, { query }, ({ loading, error, value }) => {
1114
- var _a, _b;
1115
- if (!((_a = value == null ? void 0 : value.results) == null ? void 0 : _a.length) && disableRenderingWithNoResults) {
1116
- return null;
1117
- }
1079
+ /* @__PURE__ */ React.createElement(SearchResultState, { query }, ({ loading, error, value }, { term, types, pageCursor, filters = {} }) => {
1080
+ const to = `/search?${qs.stringify(
1081
+ { term, types, filters, pageCursor, query: term },
1082
+ { arrayFormat: "brackets" }
1083
+ )}`;
1118
1084
  return /* @__PURE__ */ React.createElement(
1119
1085
  SearchResultGroupLayout,
1120
1086
  {
1121
1087
  ...rest,
1122
- loading,
1123
1088
  error,
1089
+ loading,
1124
1090
  linkProps: { to, ...linkProps },
1091
+ filterFields: Object.keys(filters),
1125
1092
  resultItems: value == null ? void 0 : value.results,
1126
- filterFields: Object.keys((_b = query.filters) != null ? _b : {})
1093
+ renderResultItem: renderResultItem != null ? renderResultItem : defaultRenderResultItem
1127
1094
  }
1128
1095
  );
1129
1096
  })
1130
1097
  );
1131
1098
  }
1132
1099
 
1133
- export { AutocompleteFilter, CheckboxFilter, HigherOrderDefaultResultListItem as DefaultResultListItem, HighlightedSearchResultText, MockSearchApi, SearchAutocomplete, SearchAutocompleteDefaultOption, SearchBar, SearchBarBase, SearchContextProvider, SearchFilter, SearchPagination, SearchPaginationBase, SearchResult, SearchResultApi, SearchResultComponent, SearchResultContext, SearchResultGroup, SearchResultGroupFilterFieldLayout, SearchResultGroupLayout, SearchResultGroupSelectFilterField, SearchResultGroupTextFilterField, SearchResultList, SearchResultListLayout, SearchResultPager, SearchResultState, SelectFilter, searchApiRef, useSearch, useSearchContextCheck };
1100
+ const useStyles = makeStyles((theme) => ({
1101
+ root: {
1102
+ display: "flex",
1103
+ justifyContent: "space-between",
1104
+ gap: theme.spacing(2),
1105
+ margin: theme.spacing(2, 0)
1106
+ }
1107
+ }));
1108
+ const SearchResultPager = () => {
1109
+ const { fetchNextPage, fetchPreviousPage } = useSearch();
1110
+ const classes = useStyles();
1111
+ if (!fetchNextPage && !fetchPreviousPage) {
1112
+ return /* @__PURE__ */ React.createElement(React.Fragment, null);
1113
+ }
1114
+ return /* @__PURE__ */ React.createElement("nav", { "aria-label": "pagination navigation", className: classes.root }, /* @__PURE__ */ React.createElement(
1115
+ Button,
1116
+ {
1117
+ "aria-label": "previous page",
1118
+ disabled: !fetchPreviousPage,
1119
+ onClick: fetchPreviousPage,
1120
+ startIcon: /* @__PURE__ */ React.createElement(ArrowBackIosIcon, null)
1121
+ },
1122
+ "Previous"
1123
+ ), /* @__PURE__ */ React.createElement(
1124
+ Button,
1125
+ {
1126
+ "aria-label": "next page",
1127
+ disabled: !fetchNextPage,
1128
+ onClick: fetchNextPage,
1129
+ endIcon: /* @__PURE__ */ React.createElement(ArrowRightIcon, null)
1130
+ },
1131
+ "Next"
1132
+ ));
1133
+ };
1134
+
1135
+ const SEARCH_RESULT_LIST_ITEM_EXTENSION = "search.results.list.items.extensions.v1";
1136
+ const findSearchResultListItemExtensionElement = (elements, result) => {
1137
+ for (const element of elements) {
1138
+ if (!isValidElement(element))
1139
+ continue;
1140
+ const predicate = getComponentData(
1141
+ element,
1142
+ SEARCH_RESULT_LIST_ITEM_EXTENSION
1143
+ );
1144
+ if (!(predicate == null ? void 0 : predicate(result)))
1145
+ continue;
1146
+ return cloneElement(element, {
1147
+ rank: result.rank,
1148
+ highlight: result.highlight,
1149
+ result: result.document,
1150
+ // Use props in situations where a consumer is manually rendering the extension
1151
+ ...element.props
1152
+ });
1153
+ }
1154
+ return null;
1155
+ };
1156
+ const SearchResultListItemExtension = (props) => {
1157
+ const {
1158
+ rank,
1159
+ result,
1160
+ noTrack,
1161
+ children,
1162
+ alignItems = "flex-start",
1163
+ ...rest
1164
+ } = props;
1165
+ const analytics = useAnalytics();
1166
+ const handleClickCapture = useCallback(() => {
1167
+ if (noTrack)
1168
+ return;
1169
+ if (!result)
1170
+ return;
1171
+ analytics.captureEvent("discover", result.title, {
1172
+ attributes: { to: result.location },
1173
+ value: rank
1174
+ });
1175
+ }, [rank, result, noTrack, analytics]);
1176
+ return /* @__PURE__ */ React.createElement(
1177
+ ListItem,
1178
+ {
1179
+ divider: true,
1180
+ alignItems,
1181
+ onClickCapture: handleClickCapture,
1182
+ ...rest
1183
+ },
1184
+ children
1185
+ );
1186
+ };
1187
+ const createSearchResultListItemExtension = (options) => {
1188
+ const { name, component, predicate = () => true } = options;
1189
+ return createReactExtension({
1190
+ name,
1191
+ component: {
1192
+ lazy: () => component().then(
1193
+ (type) => (props) => /* @__PURE__ */ React.createElement(
1194
+ SearchResultListItemExtension,
1195
+ {
1196
+ rank: props.rank,
1197
+ result: props.result,
1198
+ noTrack: props.noTrack
1199
+ },
1200
+ createElement(type, props)
1201
+ )
1202
+ )
1203
+ },
1204
+ data: {
1205
+ [SEARCH_RESULT_LIST_ITEM_EXTENSION]: predicate
1206
+ }
1207
+ });
1208
+ };
1209
+ const useSearchResultListItemExtensions = (children) => {
1210
+ const elements = useElementFilter(
1211
+ children,
1212
+ (collection) => {
1213
+ return collection.selectByComponentData({
1214
+ key: SEARCH_RESULT_LIST_ITEM_EXTENSION
1215
+ }).getElements();
1216
+ },
1217
+ [children]
1218
+ );
1219
+ return useCallback(
1220
+ (result, key) => {
1221
+ const element = findSearchResultListItemExtensionElement(
1222
+ elements,
1223
+ result
1224
+ );
1225
+ return /* @__PURE__ */ React.createElement(Fragment, { key }, element != null ? element : /* @__PURE__ */ React.createElement(
1226
+ SearchResultListItemExtension,
1227
+ {
1228
+ rank: result.rank,
1229
+ result: result.document
1230
+ },
1231
+ /* @__PURE__ */ React.createElement(
1232
+ HigherOrderDefaultResultListItem,
1233
+ {
1234
+ rank: result.rank,
1235
+ highlight: result.highlight,
1236
+ result: result.document
1237
+ }
1238
+ )
1239
+ ));
1240
+ },
1241
+ [elements]
1242
+ );
1243
+ };
1244
+ const SearchResultListItemExtensions = (props) => {
1245
+ const { results, children, ...rest } = props;
1246
+ const render = useSearchResultListItemExtensions(children);
1247
+ return /* @__PURE__ */ React.createElement(List, { ...rest }, results.map(render));
1248
+ };
1249
+
1250
+ export { AutocompleteFilter, CheckboxFilter, HigherOrderDefaultResultListItem as DefaultResultListItem, HighlightedSearchResultText, MockSearchApi, SearchAutocomplete, SearchAutocompleteDefaultOption, SearchBar, SearchBarBase, SearchContextProvider, SearchFilter, SearchPagination, SearchPaginationBase, SearchResult, SearchResultApi, SearchResultComponent, SearchResultContext, SearchResultGroup, SearchResultGroupFilterFieldLayout, SearchResultGroupLayout, SearchResultGroupSelectFilterField, SearchResultGroupTextFilterField, SearchResultList, SearchResultListItemExtensions, SearchResultListLayout, SearchResultPager, SearchResultState, SelectFilter, createSearchResultListItemExtension, searchApiRef, useSearch, useSearchContextCheck, useSearchResultListItemExtensions };
1134
1251
  //# sourceMappingURL=index.esm.js.map