@backstage/plugin-search 0.9.1-next.2 → 1.0.1-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 CHANGED
@@ -1,5 +1,57 @@
1
1
  # @backstage/plugin-search
2
2
 
3
+ ## 1.0.1-next.0
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies
8
+ - @backstage/core-plugin-api@1.0.5-next.0
9
+ - @backstage/plugin-catalog-react@1.1.3-next.0
10
+ - @backstage/core-components@0.10.1-next.0
11
+ - @backstage/plugin-search-react@1.0.1-next.0
12
+
13
+ ## 1.0.0
14
+
15
+ ### Major Changes
16
+
17
+ - 7bd7d336b2: This package has been promoted to 1.0. Read more about what it means in [New release: Backstage Search 1.0 blog](https://backstage.io/blog/2022/07/19/releasing-backstage-search-1.0)
18
+
19
+ ### Patch Changes
20
+
21
+ - a70869e775: Updated dependency `msw` to `^0.43.0`.
22
+ - 8006d0f9bf: Updated dependency `msw` to `^0.44.0`.
23
+ - 509c4092f0: To allow people to use a global search context in the search modal, the code for the search modal has been changed to only create a local search context if there is no parent context already defined.
24
+
25
+ If you want to continue using a local context even if you define a global one, you will have to wrap the modal in a new local context manually:
26
+
27
+ ```tsx
28
+ <SearchContextProvider>
29
+ <SearchModal toggleModal={toggleModal} />
30
+ </SearchContextProvider>
31
+ ```
32
+
33
+ - Updated dependencies
34
+ - @backstage/core-components@0.10.0
35
+ - @backstage/catalog-model@1.1.0
36
+ - @backstage/plugin-search-react@1.0.0
37
+ - @backstage/plugin-search-common@1.0.0
38
+ - @backstage/core-plugin-api@1.0.4
39
+ - @backstage/plugin-catalog-react@1.1.2
40
+ - @backstage/theme@0.2.16
41
+ - @backstage/errors@1.1.0
42
+
43
+ ## 0.9.1-next.3
44
+
45
+ ### Patch Changes
46
+
47
+ - a70869e775: Updated dependency `msw` to `^0.43.0`.
48
+ - Updated dependencies
49
+ - @backstage/core-plugin-api@1.0.4-next.0
50
+ - @backstage/core-components@0.10.0-next.3
51
+ - @backstage/catalog-model@1.1.0-next.3
52
+ - @backstage/plugin-catalog-react@1.1.2-next.3
53
+ - @backstage/plugin-search-react@0.2.2-next.3
54
+
3
55
  ## 0.9.1-next.2
4
56
 
5
57
  ### Patch Changes
@@ -1,28 +1,17 @@
1
1
  import React from 'react';
2
2
  import SearchIcon from '@material-ui/icons/Search';
3
3
  import { SidebarItem } from '@backstage/core-components';
4
- import { a as SearchModalProvider, u as useSearchModal, b as SearchModal } from './index-5187be91.esm.js';
5
- import '@material-ui/icons/FilterList';
4
+ import { a as SearchModalProvider, u as useSearchModal, b as SearchModal } from './index-7063ba2d.esm.js';
6
5
  import '@material-ui/core';
7
- import '@backstage/plugin-search-react';
8
6
  import '@material-ui/icons/Launch';
9
7
  import '@material-ui/core/styles';
8
+ import '@backstage/plugin-search-react';
10
9
  import '@backstage/core-plugin-api';
11
10
  import '@backstage/errors';
12
11
  import 'qs';
13
12
  import '@backstage/version-bridge';
14
13
  import 'react-use/lib/usePrevious';
15
14
  import 'react-router';
16
- import 'react-use/lib/useDebounce';
17
- import '@material-ui/core/InputBase';
18
- import '@material-ui/core/IconButton';
19
- import '@material-ui/icons/Clear';
20
- import '@material-ui/lab';
21
- import 'react-use/lib/useAsync';
22
- import '@backstage/plugin-catalog-react';
23
- import '@backstage/catalog-model';
24
- import '@material-ui/icons/ArrowBackIos';
25
- import '@material-ui/icons/ArrowForwardIos';
26
15
  import 'react-use/lib/useEffectOnce';
27
16
  import '@material-ui/icons/ExpandMore';
28
17
  import '@material-ui/icons/FontDownload';
@@ -49,4 +38,4 @@ const SidebarSearchModal = (props) => {
49
38
  };
50
39
 
51
40
  export { SidebarSearchModal };
52
- //# sourceMappingURL=index-30f1f9c5.esm.js.map
41
+ //# sourceMappingURL=index-2cf5b862.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index-30f1f9c5.esm.js","sources":["../../src/components/SidebarSearchModal/SidebarSearchModal.tsx"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport React from 'react';\nimport SearchIcon from '@material-ui/icons/Search';\nimport { SidebarItem } from '@backstage/core-components';\nimport { IconComponent } from '@backstage/core-plugin-api';\nimport {\n SearchModal,\n SearchModalChildrenProps,\n SearchModalProvider,\n useSearchModal,\n} from '../SearchModal';\n\n/**\n * Props for {@link SidebarSearchModal}.\n *\n * @public\n */\nexport type SidebarSearchModalProps = {\n icon?: IconComponent;\n children?: (props: SearchModalChildrenProps) => JSX.Element;\n};\n\nconst SidebarSearchModalContent = (props: SidebarSearchModalProps) => {\n const { state, toggleModal } = useSearchModal();\n const Icon = props.icon ? props.icon : SearchIcon;\n\n return (\n <>\n <SidebarItem\n className=\"search-icon\"\n icon={Icon}\n text=\"Search\"\n onClick={toggleModal}\n />\n <SearchModal\n {...state}\n toggleModal={toggleModal}\n children={props.children}\n />\n </>\n );\n};\n\nexport const SidebarSearchModal = (props: SidebarSearchModalProps) => {\n return (\n <SearchModalProvider>\n <SidebarSearchModalContent {...props} />\n </SearchModalProvider>\n );\n};\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAQA,MAAM,yBAAyB,GAAG,CAAC,KAAK,KAAK;AAC7C,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,GAAG,cAAc,EAAE,CAAC;AAClD,EAAE,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI,GAAG,UAAU,CAAC;AACpD,EAAE,uBAAuB,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,QAAQ,EAAE,IAAI,kBAAkB,KAAK,CAAC,aAAa,CAAC,WAAW,EAAE;AACpH,IAAI,SAAS,EAAE,aAAa;AAC5B,IAAI,IAAI,EAAE,IAAI;AACd,IAAI,IAAI,EAAE,QAAQ;AAClB,IAAI,OAAO,EAAE,WAAW;AACxB,GAAG,CAAC,kBAAkB,KAAK,CAAC,aAAa,CAAC,WAAW,EAAE;AACvD,IAAI,GAAG,KAAK;AACZ,IAAI,WAAW;AACf,IAAI,QAAQ,EAAE,KAAK,CAAC,QAAQ;AAC5B,GAAG,CAAC,CAAC,CAAC;AACN,CAAC,CAAC;AACU,MAAC,kBAAkB,GAAG,CAAC,KAAK,KAAK;AAC7C,EAAE,uBAAuB,KAAK,CAAC,aAAa,CAAC,mBAAmB,EAAE,IAAI,kBAAkB,KAAK,CAAC,aAAa,CAAC,yBAAyB,EAAE;AACvI,IAAI,GAAG,KAAK;AACZ,GAAG,CAAC,CAAC,CAAC;AACN;;;;"}
1
+ {"version":3,"file":"index-2cf5b862.esm.js","sources":["../../src/components/SidebarSearchModal/SidebarSearchModal.tsx"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport React from 'react';\nimport SearchIcon from '@material-ui/icons/Search';\nimport { SidebarItem } from '@backstage/core-components';\nimport { IconComponent } from '@backstage/core-plugin-api';\nimport {\n SearchModal,\n SearchModalChildrenProps,\n SearchModalProvider,\n useSearchModal,\n} from '../SearchModal';\n\n/**\n * Props for {@link SidebarSearchModal}.\n *\n * @public\n */\nexport type SidebarSearchModalProps = {\n icon?: IconComponent;\n children?: (props: SearchModalChildrenProps) => JSX.Element;\n};\n\nconst SidebarSearchModalContent = (props: SidebarSearchModalProps) => {\n const { state, toggleModal } = useSearchModal();\n const Icon = props.icon ? props.icon : SearchIcon;\n\n return (\n <>\n <SidebarItem\n className=\"search-icon\"\n icon={Icon}\n text=\"Search\"\n onClick={toggleModal}\n />\n <SearchModal\n {...state}\n toggleModal={toggleModal}\n children={props.children}\n />\n </>\n );\n};\n\nexport const SidebarSearchModal = (props: SidebarSearchModalProps) => {\n return (\n <SearchModalProvider>\n <SidebarSearchModalContent {...props} />\n </SearchModalProvider>\n );\n};\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;AAQA,MAAM,yBAAyB,GAAG,CAAC,KAAK,KAAK;AAC7C,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,GAAG,cAAc,EAAE,CAAC;AAClD,EAAE,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI,GAAG,UAAU,CAAC;AACpD,EAAE,uBAAuB,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,QAAQ,EAAE,IAAI,kBAAkB,KAAK,CAAC,aAAa,CAAC,WAAW,EAAE;AACpH,IAAI,SAAS,EAAE,aAAa;AAC5B,IAAI,IAAI,EAAE,IAAI;AACd,IAAI,IAAI,EAAE,QAAQ;AAClB,IAAI,OAAO,EAAE,WAAW;AACxB,GAAG,CAAC,kBAAkB,KAAK,CAAC,aAAa,CAAC,WAAW,EAAE;AACvD,IAAI,GAAG,KAAK;AACZ,IAAI,WAAW;AACf,IAAI,QAAQ,EAAE,KAAK,CAAC,QAAQ;AAC5B,GAAG,CAAC,CAAC,CAAC;AACN,CAAC,CAAC;AACU,MAAC,kBAAkB,GAAG,CAAC,KAAK,KAAK;AAC7C,EAAE,uBAAuB,KAAK,CAAC,aAAa,CAAC,mBAAmB,EAAE,IAAI,kBAAkB,KAAK,CAAC,aAAa,CAAC,yBAAyB,EAAE;AACvI,IAAI,GAAG,KAAK;AACZ,GAAG,CAAC,CAAC,CAAC;AACN;;;;"}
@@ -0,0 +1,18 @@
1
+ export { S as SearchPage } from './index-7063ba2d.esm.js';
2
+ import 'react';
3
+ import '@material-ui/core';
4
+ import '@material-ui/icons/Launch';
5
+ import '@material-ui/core/styles';
6
+ import '@backstage/plugin-search-react';
7
+ import '@backstage/core-plugin-api';
8
+ import '@backstage/core-components';
9
+ import '@backstage/errors';
10
+ import 'qs';
11
+ import '@backstage/version-bridge';
12
+ import 'react-use/lib/usePrevious';
13
+ import 'react-router';
14
+ import 'react-use/lib/useEffectOnce';
15
+ import '@material-ui/icons/ExpandMore';
16
+ import '@material-ui/icons/FontDownload';
17
+ import 'react-router-dom';
18
+ //# sourceMappingURL=index-64e4c3d4.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-64e4c3d4.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;"}
@@ -0,0 +1,509 @@
1
+ import React, { useContext, useState, useCallback, useEffect, Fragment, cloneElement } from 'react';
2
+ import { Dialog, useTheme, DialogTitle, Paper, DialogContent, Grid, Divider, List, DialogActions, makeStyles as makeStyles$1, Card, CardHeader, CardContent, Accordion, AccordionSummary, AccordionDetails, ListItem, ListItemIcon, ListItemText, Tabs, Tab, FormControl, InputLabel, Select, Chip, MenuItem, Checkbox } from '@material-ui/core';
3
+ import LaunchIcon from '@material-ui/icons/Launch';
4
+ import { makeStyles } from '@material-ui/core/styles';
5
+ import { searchApiRef, useSearch, SearchBar, SearchResult, DefaultResultListItem, SearchResultPager, useSearchContextCheck, SearchContextProvider } from '@backstage/plugin-search-react';
6
+ import { createRouteRef, createPlugin, createApiFactory, discoveryApiRef, identityApiRef, createRoutableExtension, createComponentExtension, useRouteRef } from '@backstage/core-plugin-api';
7
+ import { useContent, Link, SidebarSearchField } from '@backstage/core-components';
8
+ import { ResponseError } from '@backstage/errors';
9
+ import qs from 'qs';
10
+ import { createVersionedContext, createVersionedValueMap } from '@backstage/version-bridge';
11
+ import usePrevious from 'react-use/lib/usePrevious';
12
+ import { useOutlet, useLocation } from 'react-router';
13
+ import useEffectOnce from 'react-use/lib/useEffectOnce';
14
+ import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
15
+ import AllIcon from '@material-ui/icons/FontDownload';
16
+ import { useNavigate } from 'react-router-dom';
17
+
18
+ class SearchClient {
19
+ constructor(options) {
20
+ this.discoveryApi = options.discoveryApi;
21
+ this.identityApi = options.identityApi;
22
+ }
23
+ async query(query) {
24
+ const { token } = await this.identityApi.getCredentials();
25
+ const queryString = qs.stringify(query);
26
+ const url = `${await this.discoveryApi.getBaseUrl(
27
+ "search/query"
28
+ )}?${queryString}`;
29
+ const response = await fetch(url, {
30
+ headers: token ? { Authorization: `Bearer ${token}` } : {}
31
+ });
32
+ if (!response.ok) {
33
+ throw await ResponseError.fromResponse(response);
34
+ }
35
+ return response.json();
36
+ }
37
+ }
38
+
39
+ const rootRouteRef = createRouteRef({
40
+ id: "search"
41
+ });
42
+ const searchPlugin = createPlugin({
43
+ id: "search",
44
+ apis: [
45
+ createApiFactory({
46
+ api: searchApiRef,
47
+ deps: { discoveryApi: discoveryApiRef, identityApi: identityApiRef },
48
+ factory: ({ discoveryApi, identityApi }) => {
49
+ return new SearchClient({ discoveryApi, identityApi });
50
+ }
51
+ })
52
+ ],
53
+ routes: {
54
+ root: rootRouteRef
55
+ }
56
+ });
57
+ const SearchPage$1 = searchPlugin.provide(
58
+ createRoutableExtension({
59
+ name: "SearchPage",
60
+ component: () => import('./index-64e4c3d4.esm.js').then((m) => m.SearchPage),
61
+ mountPoint: rootRouteRef
62
+ })
63
+ );
64
+ const SidebarSearchModal = searchPlugin.provide(
65
+ createComponentExtension({
66
+ name: "SidebarSearchModal",
67
+ component: {
68
+ lazy: () => import('./index-2cf5b862.esm.js').then(
69
+ (m) => m.SidebarSearchModal
70
+ )
71
+ }
72
+ })
73
+ );
74
+ const HomePageSearchBar = searchPlugin.provide(
75
+ createComponentExtension({
76
+ name: "HomePageSearchBar",
77
+ component: {
78
+ lazy: () => import('./index-b2b7c8ed.esm.js').then((m) => m.HomePageSearchBar)
79
+ }
80
+ })
81
+ );
82
+
83
+ const useStyles$3 = makeStyles((theme) => ({
84
+ container: {
85
+ borderRadius: 30,
86
+ display: "flex",
87
+ height: "2.4em"
88
+ },
89
+ input: {
90
+ flex: 1
91
+ },
92
+ paperFullWidth: { height: "calc(100% - 128px)" },
93
+ dialogActionsContainer: { padding: theme.spacing(1, 3) },
94
+ viewResultsLink: { verticalAlign: "0.5em" }
95
+ }));
96
+ const Modal = ({ toggleModal }) => {
97
+ const getSearchLink = useRouteRef(rootRouteRef);
98
+ const classes = useStyles$3();
99
+ const { term } = useSearch();
100
+ const { focusContent } = useContent();
101
+ const { transitions } = useTheme();
102
+ const handleResultClick = () => {
103
+ toggleModal();
104
+ setTimeout(focusContent, transitions.duration.leavingScreen);
105
+ };
106
+ const handleKeyPress = () => {
107
+ handleResultClick();
108
+ };
109
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(DialogTitle, null, /* @__PURE__ */ React.createElement(Paper, {
110
+ className: classes.container
111
+ }, /* @__PURE__ */ React.createElement(SearchBar, {
112
+ className: classes.input
113
+ }))), /* @__PURE__ */ React.createElement(DialogContent, null, /* @__PURE__ */ React.createElement(Grid, {
114
+ container: true,
115
+ direction: "row-reverse",
116
+ justifyContent: "flex-start",
117
+ alignItems: "center"
118
+ }, /* @__PURE__ */ React.createElement(Grid, {
119
+ item: true
120
+ }, /* @__PURE__ */ React.createElement(Link, {
121
+ onClick: () => {
122
+ toggleModal();
123
+ setTimeout(focusContent, transitions.duration.leavingScreen);
124
+ },
125
+ to: `${getSearchLink()}?query=${term}`
126
+ }, /* @__PURE__ */ React.createElement("span", {
127
+ className: classes.viewResultsLink
128
+ }, "View Full Results"), /* @__PURE__ */ React.createElement(LaunchIcon, {
129
+ color: "primary"
130
+ })))), /* @__PURE__ */ React.createElement(Divider, null), /* @__PURE__ */ React.createElement(SearchResult, null, ({ results }) => /* @__PURE__ */ React.createElement(List, null, results.map(({ document, highlight }) => /* @__PURE__ */ React.createElement("div", {
131
+ role: "button",
132
+ tabIndex: 0,
133
+ key: `${document.location}-btn`,
134
+ onClick: handleResultClick,
135
+ onKeyPress: handleKeyPress
136
+ }, /* @__PURE__ */ React.createElement(DefaultResultListItem, {
137
+ key: document.location,
138
+ result: document,
139
+ highlight
140
+ })))))), /* @__PURE__ */ React.createElement(DialogActions, {
141
+ className: classes.dialogActionsContainer
142
+ }, /* @__PURE__ */ React.createElement(Grid, {
143
+ container: true,
144
+ direction: "row"
145
+ }, /* @__PURE__ */ React.createElement(Grid, {
146
+ item: true,
147
+ xs: 12
148
+ }, /* @__PURE__ */ React.createElement(SearchResultPager, null)))));
149
+ };
150
+ const Context = ({ children }) => {
151
+ const hasParentContext = useSearchContextCheck();
152
+ if (hasParentContext) {
153
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, children);
154
+ }
155
+ return /* @__PURE__ */ React.createElement(SearchContextProvider, null, children);
156
+ };
157
+ const SearchModal = ({
158
+ open = true,
159
+ hidden,
160
+ toggleModal,
161
+ children
162
+ }) => {
163
+ var _a;
164
+ const classes = useStyles$3();
165
+ return /* @__PURE__ */ React.createElement(Dialog, {
166
+ classes: {
167
+ paperFullWidth: classes.paperFullWidth
168
+ },
169
+ onClose: toggleModal,
170
+ "aria-labelledby": "search-modal-title",
171
+ fullWidth: true,
172
+ maxWidth: "lg",
173
+ open,
174
+ hidden
175
+ }, open && /* @__PURE__ */ React.createElement(Context, null, (_a = children && children({ toggleModal })) != null ? _a : /* @__PURE__ */ React.createElement(Modal, {
176
+ toggleModal
177
+ })));
178
+ };
179
+
180
+ const SearchModalContext = createVersionedContext("search-modal-context");
181
+ const SearchModalProvider = ({
182
+ children,
183
+ showInitially
184
+ }) => {
185
+ const value = useSearchModal(showInitially);
186
+ const versionedValue = createVersionedValueMap({ 1: value });
187
+ return /* @__PURE__ */ React.createElement(SearchModalContext.Provider, {
188
+ value: versionedValue
189
+ }, children);
190
+ };
191
+ function useSearchModal(initialState = false) {
192
+ const parentContext = useContext(SearchModalContext);
193
+ const parentContextValue = parentContext == null ? void 0 : parentContext.atVersion(1);
194
+ const [state, setState] = useState({
195
+ hidden: !initialState,
196
+ open: initialState
197
+ });
198
+ const toggleModal = useCallback(
199
+ () => setState((prevState) => ({
200
+ open: true,
201
+ hidden: !prevState.hidden
202
+ })),
203
+ []
204
+ );
205
+ const setOpen = useCallback(
206
+ (open) => setState((prevState) => ({
207
+ open: prevState.open || open,
208
+ hidden: !open
209
+ })),
210
+ []
211
+ );
212
+ return (parentContextValue == null ? void 0 : parentContextValue.state) ? parentContextValue : { state, toggleModal, setOpen };
213
+ }
214
+
215
+ const UrlUpdater = () => {
216
+ const location = useLocation();
217
+ const {
218
+ term,
219
+ setTerm,
220
+ types,
221
+ setTypes,
222
+ pageCursor,
223
+ setPageCursor,
224
+ filters,
225
+ setFilters
226
+ } = useSearch();
227
+ const prevQueryParams = usePrevious(location.search);
228
+ useEffect(() => {
229
+ if (location.search === prevQueryParams) {
230
+ return;
231
+ }
232
+ const query = qs.parse(location.search.substring(1), { arrayLimit: 0 }) || {};
233
+ if (query.filters) {
234
+ setFilters(query.filters);
235
+ }
236
+ if (query.query) {
237
+ setTerm(query.query);
238
+ }
239
+ if (query.pageCursor) {
240
+ setPageCursor(query.pageCursor);
241
+ }
242
+ if (query.types) {
243
+ setTypes(query.types);
244
+ }
245
+ }, [prevQueryParams, location, setTerm, setTypes, setPageCursor, setFilters]);
246
+ useEffect(() => {
247
+ const newParams = qs.stringify(
248
+ {
249
+ query: term,
250
+ types,
251
+ pageCursor,
252
+ filters
253
+ },
254
+ { arrayFormat: "brackets" }
255
+ );
256
+ const newUrl = `${window.location.pathname}?${newParams}`;
257
+ window.history.replaceState(null, document.title, newUrl);
258
+ }, [term, types, pageCursor, filters]);
259
+ return null;
260
+ };
261
+ const SearchPage = () => {
262
+ const outlet = useOutlet();
263
+ return /* @__PURE__ */ React.createElement(SearchContextProvider, null, /* @__PURE__ */ React.createElement(UrlUpdater, null), outlet);
264
+ };
265
+
266
+ const useStyles$2 = makeStyles$1((theme) => ({
267
+ card: {
268
+ backgroundColor: "rgba(0, 0, 0, .11)"
269
+ },
270
+ cardContent: {
271
+ paddingTop: theme.spacing(1)
272
+ },
273
+ icon: {
274
+ color: theme.palette.common.black
275
+ },
276
+ list: {
277
+ width: "100%"
278
+ },
279
+ listItemIcon: {
280
+ width: "24px",
281
+ height: "24px"
282
+ },
283
+ accordion: {
284
+ backgroundColor: theme.palette.background.paper
285
+ },
286
+ accordionSummary: {
287
+ minHeight: "auto",
288
+ "&.Mui-expanded": {
289
+ minHeight: "auto"
290
+ }
291
+ },
292
+ accordionSummaryContent: {
293
+ margin: theme.spacing(2, 0),
294
+ "&.Mui-expanded": {
295
+ margin: theme.spacing(2, 0)
296
+ }
297
+ },
298
+ accordionDetails: {
299
+ padding: theme.spacing(0, 0, 1)
300
+ }
301
+ }));
302
+ const SearchTypeAccordion = (props) => {
303
+ const classes = useStyles$2();
304
+ const { setPageCursor, setTypes, types } = useSearch();
305
+ const [expanded, setExpanded] = useState(true);
306
+ const { defaultValue, name, types: givenTypes } = props;
307
+ const toggleExpanded = () => setExpanded((prevState) => !prevState);
308
+ const handleClick = (type) => {
309
+ return () => {
310
+ setTypes(type !== "" ? [type] : []);
311
+ setPageCursor(void 0);
312
+ setExpanded(false);
313
+ };
314
+ };
315
+ useEffect(() => {
316
+ if (defaultValue) {
317
+ setTypes([defaultValue]);
318
+ }
319
+ }, []);
320
+ const definedTypes = [
321
+ {
322
+ value: "",
323
+ name: "All",
324
+ icon: /* @__PURE__ */ React.createElement(AllIcon, null)
325
+ },
326
+ ...givenTypes
327
+ ];
328
+ const selected = types[0] || "";
329
+ return /* @__PURE__ */ React.createElement(Card, {
330
+ className: classes.card
331
+ }, /* @__PURE__ */ React.createElement(CardHeader, {
332
+ title: name,
333
+ titleTypographyProps: { variant: "overline" }
334
+ }), /* @__PURE__ */ React.createElement(CardContent, {
335
+ className: classes.cardContent
336
+ }, /* @__PURE__ */ React.createElement(Accordion, {
337
+ className: classes.accordion,
338
+ expanded,
339
+ onChange: toggleExpanded
340
+ }, /* @__PURE__ */ React.createElement(AccordionSummary, {
341
+ classes: {
342
+ root: classes.accordionSummary,
343
+ content: classes.accordionSummaryContent
344
+ },
345
+ expandIcon: /* @__PURE__ */ React.createElement(ExpandMoreIcon, {
346
+ className: classes.icon
347
+ }),
348
+ IconButtonProps: { size: "small" }
349
+ }, expanded ? "Collapse" : definedTypes.filter((t) => t.value === selected)[0].name), /* @__PURE__ */ React.createElement(AccordionDetails, {
350
+ classes: { root: classes.accordionDetails }
351
+ }, /* @__PURE__ */ React.createElement(List, {
352
+ className: classes.list,
353
+ component: "nav",
354
+ "aria-label": "filter by type",
355
+ disablePadding: true,
356
+ dense: true
357
+ }, definedTypes.map((type) => /* @__PURE__ */ React.createElement(Fragment, {
358
+ key: type.value
359
+ }, /* @__PURE__ */ React.createElement(Divider, null), /* @__PURE__ */ React.createElement(ListItem, {
360
+ selected: types[0] === type.value || types.length === 0 && type.value === "",
361
+ onClick: handleClick(type.value),
362
+ button: true
363
+ }, /* @__PURE__ */ React.createElement(ListItemIcon, null, cloneElement(type.icon, {
364
+ className: classes.listItemIcon
365
+ })), /* @__PURE__ */ React.createElement(ListItemText, {
366
+ primary: type.name
367
+ })))))))));
368
+ };
369
+
370
+ const useStyles$1 = makeStyles$1((theme) => ({
371
+ tabs: {
372
+ borderBottom: `1px solid ${theme.palette.textVerySubtle}`,
373
+ padding: theme.spacing(0, 4)
374
+ },
375
+ tab: {
376
+ height: "50px",
377
+ fontWeight: theme.typography.fontWeightBold,
378
+ fontSize: theme.typography.pxToRem(13),
379
+ color: theme.palette.textSubtle,
380
+ minWidth: "130px"
381
+ }
382
+ }));
383
+ const SearchTypeTabs = (props) => {
384
+ const classes = useStyles$1();
385
+ const { setPageCursor, setTypes, types } = useSearch();
386
+ const { defaultValue, types: givenTypes } = props;
387
+ const changeTab = (_, newType) => {
388
+ setTypes(newType !== "" ? [newType] : []);
389
+ setPageCursor(void 0);
390
+ };
391
+ useEffect(() => {
392
+ if (defaultValue) {
393
+ setTypes([defaultValue]);
394
+ }
395
+ }, []);
396
+ const definedTypes = [
397
+ {
398
+ value: "",
399
+ name: "All"
400
+ },
401
+ ...givenTypes
402
+ ];
403
+ return /* @__PURE__ */ React.createElement(Tabs, {
404
+ className: classes.tabs,
405
+ indicatorColor: "primary",
406
+ value: types.length === 0 ? "" : types[0],
407
+ onChange: changeTab
408
+ }, definedTypes.map((type, idx) => /* @__PURE__ */ React.createElement(Tab, {
409
+ key: idx,
410
+ className: classes.tab,
411
+ disableRipple: true,
412
+ label: type.name,
413
+ value: type.value
414
+ })));
415
+ };
416
+
417
+ const useStyles = makeStyles$1((theme) => ({
418
+ label: {
419
+ textTransform: "capitalize"
420
+ },
421
+ chips: {
422
+ display: "flex",
423
+ flexWrap: "wrap",
424
+ marginTop: theme.spacing(1)
425
+ },
426
+ chip: {
427
+ margin: 2
428
+ }
429
+ }));
430
+ const SearchType = (props) => {
431
+ const { className, defaultValue, name, values = [] } = props;
432
+ const classes = useStyles();
433
+ const { types, setTypes } = useSearch();
434
+ useEffectOnce(() => {
435
+ if (!types.length) {
436
+ if (defaultValue && Array.isArray(defaultValue)) {
437
+ setTypes(defaultValue);
438
+ } else if (defaultValue) {
439
+ setTypes([defaultValue]);
440
+ }
441
+ }
442
+ });
443
+ const handleChange = (e) => {
444
+ const value = e.target.value;
445
+ setTypes(value);
446
+ };
447
+ return /* @__PURE__ */ React.createElement(FormControl, {
448
+ className,
449
+ variant: "filled",
450
+ fullWidth: true,
451
+ "data-testid": "search-typefilter-next"
452
+ }, /* @__PURE__ */ React.createElement(InputLabel, {
453
+ className: classes.label,
454
+ margin: "dense"
455
+ }, name), /* @__PURE__ */ React.createElement(Select, {
456
+ multiple: true,
457
+ variant: "outlined",
458
+ value: types,
459
+ onChange: handleChange,
460
+ placeholder: "All Results",
461
+ renderValue: (selected) => /* @__PURE__ */ React.createElement("div", {
462
+ className: classes.chips
463
+ }, selected.map((value) => /* @__PURE__ */ React.createElement(Chip, {
464
+ key: value,
465
+ label: value,
466
+ className: classes.chip,
467
+ size: "small"
468
+ })))
469
+ }, values.map((value) => /* @__PURE__ */ React.createElement(MenuItem, {
470
+ key: value,
471
+ value
472
+ }, /* @__PURE__ */ React.createElement(Checkbox, {
473
+ checked: types.indexOf(value) > -1
474
+ }), /* @__PURE__ */ React.createElement(ListItemText, {
475
+ primary: value
476
+ })))));
477
+ };
478
+ SearchType.Accordion = (props) => {
479
+ return /* @__PURE__ */ React.createElement(SearchTypeAccordion, {
480
+ ...props
481
+ });
482
+ };
483
+ SearchType.Tabs = (props) => {
484
+ return /* @__PURE__ */ React.createElement(SearchTypeTabs, {
485
+ ...props
486
+ });
487
+ };
488
+
489
+ const SidebarSearch = (props) => {
490
+ const searchRoute = useRouteRef(rootRouteRef);
491
+ const { focusContent } = useContent();
492
+ const navigate = useNavigate();
493
+ const handleSearch = useCallback(
494
+ (query) => {
495
+ const queryString = qs.stringify({ query }, { addQueryPrefix: true });
496
+ focusContent();
497
+ navigate(`${searchRoute()}${queryString}`);
498
+ },
499
+ [focusContent, navigate, searchRoute]
500
+ );
501
+ return /* @__PURE__ */ React.createElement(SidebarSearchField, {
502
+ icon: props.icon,
503
+ onSearch: handleSearch,
504
+ to: "/search"
505
+ });
506
+ };
507
+
508
+ export { HomePageSearchBar as H, SearchPage as S, SearchModalProvider as a, SearchModal as b, SearchType as c, SidebarSearch as d, SearchPage$1 as e, SidebarSearchModal as f, rootRouteRef as r, searchPlugin as s, useSearchModal as u };
509
+ //# sourceMappingURL=index-7063ba2d.esm.js.map