@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/CHANGELOG.md +33 -0
- package/dist/index.d.ts +181 -133
- package/dist/index.esm.js +284 -167
- package/dist/index.esm.js.map +1 -1
- package/package.json +5 -5
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,
|
|
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
|
-
|
|
788
|
-
|
|
789
|
-
|
|
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
|
|
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))
|
|
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
|
-
|
|
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
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
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,
|
|
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
|
-
|
|
877
|
-
|
|
878
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
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)),
|
|
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
|
-
|
|
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
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
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
|
-
|
|
1093
|
+
renderResultItem: renderResultItem != null ? renderResultItem : defaultRenderResultItem
|
|
1127
1094
|
}
|
|
1128
1095
|
);
|
|
1129
1096
|
})
|
|
1130
1097
|
);
|
|
1131
1098
|
}
|
|
1132
1099
|
|
|
1133
|
-
|
|
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
|