@backstage/plugin-search-react 1.4.0-next.2 → 1.5.0-next.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +63 -0
- package/dist/index.d.ts +170 -132
- package/dist/index.esm.js +275 -168
- package/dist/index.esm.js.map +1 -1
- package/package.json +7 -7
package/dist/index.esm.js
CHANGED
|
@@ -1,20 +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,
|
|
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, ListItem, Box, Divider, List, Typography as Typography$1, ListSubheader, Menu, Button } 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
|
|
15
|
-
import ArrowForwardIosIcon from '@material-ui/icons/ArrowForwardIos';
|
|
14
|
+
import Typography from '@material-ui/core/Typography';
|
|
16
15
|
import qs from 'qs';
|
|
17
16
|
import AddIcon from '@material-ui/icons/Add';
|
|
17
|
+
import ArrowRightIcon from '@material-ui/icons/ArrowForwardIos';
|
|
18
|
+
import ArrowBackIosIcon from '@material-ui/icons/ArrowBackIos';
|
|
18
19
|
|
|
19
20
|
const searchApiRef = createApiRef({
|
|
20
21
|
id: "plugin.search.queryservice"
|
|
@@ -621,96 +622,6 @@ SearchFilter.Checkbox = (props) => /* @__PURE__ */ React.createElement(SearchFil
|
|
|
621
622
|
SearchFilter.Select = (props) => /* @__PURE__ */ React.createElement(SearchFilter, { ...props, component: SelectFilter });
|
|
622
623
|
SearchFilter.Autocomplete = (props) => /* @__PURE__ */ React.createElement(SearchFilter, { ...props, component: AutocompleteFilter });
|
|
623
624
|
|
|
624
|
-
const SearchResultContext = (props) => {
|
|
625
|
-
const { children } = props;
|
|
626
|
-
const context = useSearch();
|
|
627
|
-
const state = context.result;
|
|
628
|
-
return children(state);
|
|
629
|
-
};
|
|
630
|
-
const SearchResultApi = (props) => {
|
|
631
|
-
const { query, children } = props;
|
|
632
|
-
const searchApi = useApi(searchApiRef);
|
|
633
|
-
const state = useAsync(() => {
|
|
634
|
-
const { term = "", types = [], filters = {}, ...rest } = query;
|
|
635
|
-
return searchApi.query({ ...rest, term, types, filters });
|
|
636
|
-
}, [query]);
|
|
637
|
-
return children(state);
|
|
638
|
-
};
|
|
639
|
-
const SearchResultState = (props) => {
|
|
640
|
-
const { query, children } = props;
|
|
641
|
-
return query ? /* @__PURE__ */ React.createElement(SearchResultApi, { query }, children) : /* @__PURE__ */ React.createElement(SearchResultContext, null, children);
|
|
642
|
-
};
|
|
643
|
-
const SearchResultComponent = (props) => {
|
|
644
|
-
const {
|
|
645
|
-
query,
|
|
646
|
-
children,
|
|
647
|
-
noResultsComponent = /* @__PURE__ */ React.createElement(EmptyState, { missing: "data", title: "Sorry, no results were found" })
|
|
648
|
-
} = props;
|
|
649
|
-
return /* @__PURE__ */ React.createElement(SearchResultState, { query }, ({ loading, error, value }) => {
|
|
650
|
-
if (loading) {
|
|
651
|
-
return /* @__PURE__ */ React.createElement(Progress, null);
|
|
652
|
-
}
|
|
653
|
-
if (error) {
|
|
654
|
-
return /* @__PURE__ */ React.createElement(
|
|
655
|
-
ResponseErrorPanel,
|
|
656
|
-
{
|
|
657
|
-
title: "Error encountered while fetching search results",
|
|
658
|
-
error
|
|
659
|
-
}
|
|
660
|
-
);
|
|
661
|
-
}
|
|
662
|
-
if (!(value == null ? void 0 : value.results.length)) {
|
|
663
|
-
return noResultsComponent;
|
|
664
|
-
}
|
|
665
|
-
return children(value);
|
|
666
|
-
});
|
|
667
|
-
};
|
|
668
|
-
const SearchResult = (props) => /* @__PURE__ */ React.createElement(
|
|
669
|
-
AnalyticsContext,
|
|
670
|
-
{
|
|
671
|
-
attributes: {
|
|
672
|
-
pluginId: "search",
|
|
673
|
-
extension: "SearchResult"
|
|
674
|
-
}
|
|
675
|
-
},
|
|
676
|
-
/* @__PURE__ */ React.createElement(SearchResultComponent, { ...props })
|
|
677
|
-
);
|
|
678
|
-
|
|
679
|
-
const useStyles$1 = makeStyles((theme) => ({
|
|
680
|
-
root: {
|
|
681
|
-
display: "flex",
|
|
682
|
-
justifyContent: "space-between",
|
|
683
|
-
gap: theme.spacing(2),
|
|
684
|
-
margin: theme.spacing(2, 0)
|
|
685
|
-
}
|
|
686
|
-
}));
|
|
687
|
-
const SearchResultPager = () => {
|
|
688
|
-
const { fetchNextPage, fetchPreviousPage } = useSearch();
|
|
689
|
-
const classes = useStyles$1();
|
|
690
|
-
if (!fetchNextPage && !fetchPreviousPage) {
|
|
691
|
-
return /* @__PURE__ */ React.createElement(React.Fragment, null);
|
|
692
|
-
}
|
|
693
|
-
return /* @__PURE__ */ React.createElement("nav", { "aria-label": "pagination navigation", className: classes.root }, /* @__PURE__ */ React.createElement(
|
|
694
|
-
Button,
|
|
695
|
-
{
|
|
696
|
-
"aria-label": "previous page",
|
|
697
|
-
disabled: !fetchPreviousPage,
|
|
698
|
-
onClick: fetchPreviousPage,
|
|
699
|
-
startIcon: /* @__PURE__ */ React.createElement(ArrowBackIosIcon, null)
|
|
700
|
-
},
|
|
701
|
-
"Previous"
|
|
702
|
-
), /* @__PURE__ */ React.createElement(
|
|
703
|
-
Button,
|
|
704
|
-
{
|
|
705
|
-
"aria-label": "next page",
|
|
706
|
-
disabled: !fetchNextPage,
|
|
707
|
-
onClick: fetchNextPage,
|
|
708
|
-
endIcon: /* @__PURE__ */ React.createElement(ArrowForwardIosIcon, null)
|
|
709
|
-
},
|
|
710
|
-
"Next"
|
|
711
|
-
));
|
|
712
|
-
};
|
|
713
|
-
|
|
714
625
|
const encodePageCursor = (pageCursor) => {
|
|
715
626
|
return Buffer.from(pageCursor.toString(), "utf-8").toString("base64");
|
|
716
627
|
};
|
|
@@ -775,26 +686,79 @@ const SearchPagination = (props) => {
|
|
|
775
686
|
);
|
|
776
687
|
};
|
|
777
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
|
+
|
|
778
748
|
const DefaultResultListItemComponent = ({
|
|
779
749
|
result,
|
|
780
750
|
highlight,
|
|
781
|
-
rank,
|
|
782
751
|
icon,
|
|
783
752
|
secondaryAction,
|
|
784
753
|
lineClamp = 5
|
|
785
754
|
}) => {
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
analytics.captureEvent("discover", result.title, {
|
|
789
|
-
attributes: { to: result.location },
|
|
790
|
-
value: rank
|
|
791
|
-
});
|
|
792
|
-
};
|
|
755
|
+
if (!result)
|
|
756
|
+
return null;
|
|
793
757
|
return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(ListItem, { alignItems: "center" }, icon && /* @__PURE__ */ React.createElement(ListItemIcon, null, icon), /* @__PURE__ */ React.createElement(
|
|
794
758
|
ListItemText,
|
|
795
759
|
{
|
|
796
760
|
primaryTypographyProps: { variant: "h6" },
|
|
797
|
-
primary: /* @__PURE__ */ React.createElement(Link, { noTrack: true, to: result.location
|
|
761
|
+
primary: /* @__PURE__ */ React.createElement(Link, { noTrack: true, to: result.location }, (highlight == null ? void 0 : highlight.fields.title) ? /* @__PURE__ */ React.createElement(
|
|
798
762
|
HighlightedSearchResultText,
|
|
799
763
|
{
|
|
800
764
|
text: (highlight == null ? void 0 : highlight.fields.title) || "",
|
|
@@ -803,8 +767,9 @@ const DefaultResultListItemComponent = ({
|
|
|
803
767
|
}
|
|
804
768
|
) : result.title),
|
|
805
769
|
secondary: /* @__PURE__ */ React.createElement(
|
|
806
|
-
|
|
770
|
+
Typography,
|
|
807
771
|
{
|
|
772
|
+
component: "span",
|
|
808
773
|
style: {
|
|
809
774
|
display: "-webkit-box",
|
|
810
775
|
WebkitBoxOrient: "vertical",
|
|
@@ -839,8 +804,8 @@ const HigherOrderDefaultResultListItem = (props) => {
|
|
|
839
804
|
|
|
840
805
|
const SearchResultListLayout = (props) => {
|
|
841
806
|
const {
|
|
842
|
-
loading,
|
|
843
807
|
error,
|
|
808
|
+
loading,
|
|
844
809
|
resultItems,
|
|
845
810
|
renderResultItem = (resultItem) => /* @__PURE__ */ React.createElement(
|
|
846
811
|
HigherOrderDefaultResultListItem,
|
|
@@ -849,19 +814,30 @@ const SearchResultListLayout = (props) => {
|
|
|
849
814
|
result: resultItem.document
|
|
850
815
|
}
|
|
851
816
|
),
|
|
852
|
-
|
|
817
|
+
disableRenderingWithNoResults,
|
|
818
|
+
noResultsComponent = disableRenderingWithNoResults ? null : /* @__PURE__ */ React.createElement(EmptyState, { missing: "data", title: "Sorry, no results were found" }),
|
|
853
819
|
...rest
|
|
854
820
|
} = props;
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
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));
|
|
862
837
|
};
|
|
863
838
|
const SearchResultList = (props) => {
|
|
864
|
-
const { query,
|
|
839
|
+
const { query, renderResultItem, children, ...rest } = props;
|
|
840
|
+
const defaultRenderResultItem = useSearchResultListItemExtensions(children);
|
|
865
841
|
return /* @__PURE__ */ React.createElement(
|
|
866
842
|
AnalyticsContext,
|
|
867
843
|
{
|
|
@@ -870,25 +846,20 @@ const SearchResultList = (props) => {
|
|
|
870
846
|
extension: "SearchResultList"
|
|
871
847
|
}
|
|
872
848
|
},
|
|
873
|
-
/* @__PURE__ */ React.createElement(SearchResultState, { query }, ({ loading, error, value }) =>
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
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
|
|
877
857
|
}
|
|
878
|
-
|
|
879
|
-
SearchResultListLayout,
|
|
880
|
-
{
|
|
881
|
-
...rest,
|
|
882
|
-
loading,
|
|
883
|
-
error,
|
|
884
|
-
resultItems: value == null ? void 0 : value.results
|
|
885
|
-
}
|
|
886
|
-
);
|
|
887
|
-
})
|
|
858
|
+
))
|
|
888
859
|
);
|
|
889
860
|
};
|
|
890
861
|
|
|
891
|
-
const useStyles = makeStyles((theme) => ({
|
|
862
|
+
const useStyles$1 = makeStyles((theme) => ({
|
|
892
863
|
listSubheader: {
|
|
893
864
|
display: "flex",
|
|
894
865
|
alignItems: "center"
|
|
@@ -917,7 +888,7 @@ const useStyles = makeStyles((theme) => ({
|
|
|
917
888
|
}
|
|
918
889
|
}));
|
|
919
890
|
const SearchResultGroupFilterFieldLayout = (props) => {
|
|
920
|
-
const classes = useStyles();
|
|
891
|
+
const classes = useStyles$1();
|
|
921
892
|
const { label, children, ...rest } = props;
|
|
922
893
|
return /* @__PURE__ */ React.createElement(
|
|
923
894
|
Chip,
|
|
@@ -956,7 +927,7 @@ const SearchResultGroupTextFilterField = (props) => {
|
|
|
956
927
|
[onChange]
|
|
957
928
|
);
|
|
958
929
|
return /* @__PURE__ */ React.createElement(SearchResultGroupFilterFieldLayout, { label, onDelete }, /* @__PURE__ */ React.createElement(
|
|
959
|
-
Typography,
|
|
930
|
+
Typography$1,
|
|
960
931
|
{
|
|
961
932
|
role: "textbox",
|
|
962
933
|
component: "span",
|
|
@@ -1009,15 +980,15 @@ const SearchResultGroupSelectFilterField = (props) => {
|
|
|
1009
980
|
));
|
|
1010
981
|
};
|
|
1011
982
|
function SearchResultGroupLayout(props) {
|
|
1012
|
-
const classes = useStyles();
|
|
983
|
+
const classes = useStyles$1();
|
|
1013
984
|
const [anchorEl, setAnchorEl] = useState(null);
|
|
1014
985
|
const {
|
|
1015
|
-
loading,
|
|
1016
986
|
error,
|
|
987
|
+
loading,
|
|
1017
988
|
icon,
|
|
1018
989
|
title,
|
|
1019
990
|
titleProps = {},
|
|
1020
|
-
link = /* @__PURE__ */ React.createElement(React.Fragment, null, "See all", /* @__PURE__ */ React.createElement(
|
|
991
|
+
link = /* @__PURE__ */ React.createElement(React.Fragment, null, "See all", /* @__PURE__ */ React.createElement(ArrowRightIcon, { className: classes.listSubheaderLinkIcon })),
|
|
1021
992
|
linkProps = {},
|
|
1022
993
|
filterOptions,
|
|
1023
994
|
renderFilterOption = (filterOption) => /* @__PURE__ */ React.createElement(MenuItem, { key: String(filterOption), value: String(filterOption) }, filterOption),
|
|
@@ -1031,7 +1002,8 @@ function SearchResultGroupLayout(props) {
|
|
|
1031
1002
|
result: resultItem.document
|
|
1032
1003
|
}
|
|
1033
1004
|
),
|
|
1034
|
-
|
|
1005
|
+
disableRenderingWithNoResults,
|
|
1006
|
+
noResultsComponent = disableRenderingWithNoResults ? null : /* @__PURE__ */ React.createElement(EmptyState, { missing: "data", title: "Sorry, no results were found" }),
|
|
1035
1007
|
...rest
|
|
1036
1008
|
} = props;
|
|
1037
1009
|
const handleClick = useCallback((e) => {
|
|
@@ -1040,8 +1012,23 @@ function SearchResultGroupLayout(props) {
|
|
|
1040
1012
|
const handleClose = useCallback(() => {
|
|
1041
1013
|
setAnchorEl(null);
|
|
1042
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
|
+
}
|
|
1043
1030
|
return /* @__PURE__ */ React.createElement(List, { ...rest }, /* @__PURE__ */ React.createElement(ListSubheader, { className: classes.listSubheader }, icon, /* @__PURE__ */ React.createElement(
|
|
1044
|
-
Typography,
|
|
1031
|
+
Typography$1,
|
|
1045
1032
|
{
|
|
1046
1033
|
className: classes.listSubheaderName,
|
|
1047
1034
|
component: "strong",
|
|
@@ -1076,30 +1063,11 @@ function SearchResultGroupLayout(props) {
|
|
|
1076
1063
|
var _a;
|
|
1077
1064
|
return (_a = renderFilterField == null ? void 0 : renderFilterField(filterField)) != null ? _a : null;
|
|
1078
1065
|
}
|
|
1079
|
-
), /* @__PURE__ */ React.createElement(Link, { className: classes.listSubheaderLink, to: "/search", ...linkProps }, link)),
|
|
1080
|
-
ResponseErrorPanel,
|
|
1081
|
-
{
|
|
1082
|
-
title: "Error encountered while fetching search results",
|
|
1083
|
-
error
|
|
1084
|
-
}
|
|
1085
|
-
) : 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));
|
|
1086
1067
|
}
|
|
1087
1068
|
function SearchResultGroup(props) {
|
|
1088
|
-
const {
|
|
1089
|
-
|
|
1090
|
-
linkProps = {},
|
|
1091
|
-
disableRenderingWithNoResults,
|
|
1092
|
-
...rest
|
|
1093
|
-
} = props;
|
|
1094
|
-
const to = `/search?${qs.stringify(
|
|
1095
|
-
{
|
|
1096
|
-
query: query.term,
|
|
1097
|
-
types: query.types,
|
|
1098
|
-
filters: query.filters,
|
|
1099
|
-
pageCursor: query.pageCursor
|
|
1100
|
-
},
|
|
1101
|
-
{ arrayFormat: "brackets" }
|
|
1102
|
-
)}`;
|
|
1069
|
+
const { query, children, renderResultItem, linkProps = {}, ...rest } = props;
|
|
1070
|
+
const defaultRenderResultItem = useSearchResultListItemExtensions(children);
|
|
1103
1071
|
return /* @__PURE__ */ React.createElement(
|
|
1104
1072
|
AnalyticsContext,
|
|
1105
1073
|
{
|
|
@@ -1108,25 +1076,164 @@ function SearchResultGroup(props) {
|
|
|
1108
1076
|
extension: "SearchResultGroup"
|
|
1109
1077
|
}
|
|
1110
1078
|
},
|
|
1111
|
-
/* @__PURE__ */ React.createElement(SearchResultState, { query }, ({ loading, error, value }) => {
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
}
|
|
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
|
+
)}`;
|
|
1116
1084
|
return /* @__PURE__ */ React.createElement(
|
|
1117
1085
|
SearchResultGroupLayout,
|
|
1118
1086
|
{
|
|
1119
1087
|
...rest,
|
|
1120
|
-
loading,
|
|
1121
1088
|
error,
|
|
1089
|
+
loading,
|
|
1122
1090
|
linkProps: { to, ...linkProps },
|
|
1091
|
+
filterFields: Object.keys(filters),
|
|
1123
1092
|
resultItems: value == null ? void 0 : value.results,
|
|
1124
|
-
|
|
1093
|
+
renderResultItem: renderResultItem != null ? renderResultItem : defaultRenderResultItem
|
|
1125
1094
|
}
|
|
1126
1095
|
);
|
|
1127
1096
|
})
|
|
1128
1097
|
);
|
|
1129
1098
|
}
|
|
1130
1099
|
|
|
1131
|
-
|
|
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 = ({
|
|
1157
|
+
rank,
|
|
1158
|
+
result,
|
|
1159
|
+
noTrack,
|
|
1160
|
+
children
|
|
1161
|
+
}) => {
|
|
1162
|
+
const analytics = useAnalytics();
|
|
1163
|
+
const handleClickCapture = useCallback(() => {
|
|
1164
|
+
if (noTrack)
|
|
1165
|
+
return;
|
|
1166
|
+
if (!result)
|
|
1167
|
+
return;
|
|
1168
|
+
analytics.captureEvent("discover", result.title, {
|
|
1169
|
+
attributes: { to: result.location },
|
|
1170
|
+
value: rank
|
|
1171
|
+
});
|
|
1172
|
+
}, [rank, result, noTrack, analytics]);
|
|
1173
|
+
return /* @__PURE__ */ React.createElement(Box, { role: "button", tabIndex: 0, onClickCapture: handleClickCapture }, children);
|
|
1174
|
+
};
|
|
1175
|
+
const createSearchResultListItemExtension = (options) => {
|
|
1176
|
+
const { name, component, predicate = () => true } = options;
|
|
1177
|
+
return createReactExtension({
|
|
1178
|
+
name,
|
|
1179
|
+
component: {
|
|
1180
|
+
lazy: () => component().then(
|
|
1181
|
+
(type) => (props) => /* @__PURE__ */ React.createElement(
|
|
1182
|
+
SearchResultListItemExtension,
|
|
1183
|
+
{
|
|
1184
|
+
rank: props.rank,
|
|
1185
|
+
result: props.result,
|
|
1186
|
+
noTrack: props.noTrack
|
|
1187
|
+
},
|
|
1188
|
+
createElement(type, props)
|
|
1189
|
+
)
|
|
1190
|
+
)
|
|
1191
|
+
},
|
|
1192
|
+
data: {
|
|
1193
|
+
[SEARCH_RESULT_LIST_ITEM_EXTENSION]: predicate
|
|
1194
|
+
}
|
|
1195
|
+
});
|
|
1196
|
+
};
|
|
1197
|
+
const useSearchResultListItemExtensions = (children) => {
|
|
1198
|
+
const elements = useElementFilter(
|
|
1199
|
+
children,
|
|
1200
|
+
(collection) => {
|
|
1201
|
+
return collection.selectByComponentData({
|
|
1202
|
+
key: SEARCH_RESULT_LIST_ITEM_EXTENSION
|
|
1203
|
+
}).getElements();
|
|
1204
|
+
},
|
|
1205
|
+
[children]
|
|
1206
|
+
);
|
|
1207
|
+
return useCallback(
|
|
1208
|
+
(result, key) => {
|
|
1209
|
+
const element = findSearchResultListItemExtensionElement(
|
|
1210
|
+
elements,
|
|
1211
|
+
result
|
|
1212
|
+
);
|
|
1213
|
+
return /* @__PURE__ */ React.createElement(Fragment, { key }, element != null ? element : /* @__PURE__ */ React.createElement(
|
|
1214
|
+
SearchResultListItemExtension,
|
|
1215
|
+
{
|
|
1216
|
+
rank: result.rank,
|
|
1217
|
+
result: result.document
|
|
1218
|
+
},
|
|
1219
|
+
/* @__PURE__ */ React.createElement(
|
|
1220
|
+
HigherOrderDefaultResultListItem,
|
|
1221
|
+
{
|
|
1222
|
+
rank: result.rank,
|
|
1223
|
+
highlight: result.highlight,
|
|
1224
|
+
result: result.document
|
|
1225
|
+
}
|
|
1226
|
+
)
|
|
1227
|
+
));
|
|
1228
|
+
},
|
|
1229
|
+
[elements]
|
|
1230
|
+
);
|
|
1231
|
+
};
|
|
1232
|
+
const SearchResultListItemExtensions = (props) => {
|
|
1233
|
+
const { results, children, ...rest } = props;
|
|
1234
|
+
const render = useSearchResultListItemExtensions(children);
|
|
1235
|
+
return /* @__PURE__ */ React.createElement(List, { ...rest }, results.map(render));
|
|
1236
|
+
};
|
|
1237
|
+
|
|
1238
|
+
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 };
|
|
1132
1239
|
//# sourceMappingURL=index.esm.js.map
|