@backstage/plugin-search-react 1.0.2-next.1 → 1.1.0-next.2

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,75 @@
1
1
  # @backstage/plugin-search-react
2
2
 
3
+ ## 1.1.0-next.2
4
+
5
+ ### Minor Changes
6
+
7
+ - 18f60427f2: Provides search autocomplete functionality through a `SearchAutocomplete` component.
8
+ A `SearchAutocompleteDefaultOption` can also be used to render options with icons, primary texts, and secondary texts.
9
+ Example:
10
+
11
+ ```jsx
12
+ import React, { ChangeEvent, useState, useCallback } from 'react';
13
+ import useAsync from 'react-use/lib/useAsync';
14
+
15
+ import { Grid, Paper } from '@material-ui/core';
16
+
17
+ import { Page, Content } from '@backstage/core-components';
18
+ import { SearchAutocomplete, SearchAutocompleteDefaultOption} from '@backstage/plugin-search-react';
19
+
20
+ const OptionsIcon = () => <svg />
21
+
22
+ const SearchPage = () => {
23
+ const [inputValue, setInputValue] = useState('');
24
+
25
+ const options = useAsync(async () => {
26
+ // Gets and returns autocomplete options
27
+ }, [inputValue])
28
+
29
+ const useCallback((_event: ChangeEvent<{}>, newInputValue: string) => {
30
+ setInputValue(newInputValue);
31
+ }, [setInputValue])
32
+
33
+ return (
34
+ <Page themeId="home">
35
+ <Content>
36
+ <Grid container direction="row">
37
+ <Grid item xs={12}>
38
+ <Paper>
39
+ <SearchAutocomplete
40
+ options={options}
41
+ inputValue={inputValue}
42
+ inputDebounceTime={100}
43
+ onInputChange={handleInputChange}
44
+ getOptionLabel={option => option.title}
45
+ renderOption={option => (
46
+ <SearchAutocompleteDefaultOption
47
+ icon={<OptionIcon />}
48
+ primaryText={option.title}
49
+ secondaryText={option.text}
50
+ />
51
+ )}
52
+ />
53
+ </Paper>
54
+ </Grid>
55
+ </Grid>
56
+ {'/* Filters and results are omitted */'}
57
+ </Content>
58
+ </Page>
59
+ );
60
+ };
61
+ ```
62
+
63
+ - ca8d5a6eae: We noticed a repeated check for the existence of a parent context before creating a child search context in more the one component such as Search Modal and Search Bar and to remove code duplication we extract the conditional to the context provider, now you can use it passing an `inheritParentContextIfAvailable` prop to the `SearchContextProvider`.
64
+
65
+ Note: This added property does not create a local context if there is a parent context and in this case, you cannot use it together with `initialState`, it will result in a type error because the parent context is already initialized.
66
+
67
+ ### Patch Changes
68
+
69
+ - Updated dependencies
70
+ - @backstage/core-components@0.11.1-next.2
71
+ - @backstage/core-plugin-api@1.0.6-next.2
72
+
3
73
  ## 1.0.2-next.1
4
74
 
5
75
  ### Patch Changes
package/dist/index.d.ts CHANGED
@@ -1,8 +1,9 @@
1
1
  /// <reference types="react" />
2
2
  import * as _backstage_core_plugin_api from '@backstage/core-plugin-api';
3
3
  import { SearchQuery, SearchResultSet, SearchResult, SearchDocument, ResultHighlight } from '@backstage/plugin-search-common';
4
- import React, { ReactElement, ReactNode, PropsWithChildren } from 'react';
5
- import { InputBaseProps } from '@material-ui/core';
4
+ import React, { ForwardRefExoticComponent, ReactNode, ReactElement, PropsWithChildren } from 'react';
5
+ import { InputBaseProps, ListItemTextProps } from '@material-ui/core';
6
+ import { AutocompleteProps } from '@material-ui/lab';
6
7
  import { JsonObject } from '@backstage/types';
7
8
  import { AsyncState } from 'react-use/lib/useAsync';
8
9
 
@@ -42,6 +43,82 @@ declare type HighlightedSearchResultTextProps = {
42
43
  */
43
44
  declare const HighlightedSearchResultText: ({ text, preTag, postTag, }: HighlightedSearchResultTextProps) => JSX.Element;
44
45
 
46
+ /**
47
+ * Props for {@link SearchBarBase}.
48
+ *
49
+ * @public
50
+ */
51
+ declare type SearchBarBaseProps = Omit<InputBaseProps, 'onChange'> & {
52
+ debounceTime?: number;
53
+ clearButton?: boolean;
54
+ onClear?: () => void;
55
+ onSubmit?: () => void;
56
+ onChange: (value: string) => void;
57
+ };
58
+ /**
59
+ * All search boxes exported by the search plugin are based on the <SearchBarBase />,
60
+ * and this one is based on the <InputBase /> component from Material UI.
61
+ * Recommended if you don't use Search Provider or Search Context.
62
+ *
63
+ * @public
64
+ */
65
+ declare const SearchBarBase: ForwardRefExoticComponent<SearchBarBaseProps>;
66
+ /**
67
+ * Props for {@link SearchBar}.
68
+ *
69
+ * @public
70
+ */
71
+ declare type SearchBarProps = Partial<SearchBarBaseProps>;
72
+ /**
73
+ * Recommended search bar when you use the Search Provider or Search Context.
74
+ *
75
+ * @public
76
+ */
77
+ declare const SearchBar: ForwardRefExoticComponent<SearchBarProps>;
78
+
79
+ /**
80
+ * Props for {@link SearchAutocomplete}.
81
+ *
82
+ * @public
83
+ */
84
+ declare type SearchAutocompleteProps<Option> = Omit<AutocompleteProps<Option, undefined, undefined, boolean>, 'renderInput' | 'disableClearable' | 'multiple'> & {
85
+ 'data-testid'?: string;
86
+ inputPlaceholder?: SearchBarProps['placeholder'];
87
+ inputDebounceTime?: SearchBarProps['debounceTime'];
88
+ };
89
+ /**
90
+ * Type for {@link SearchAutocomplete}.
91
+ *
92
+ * @public
93
+ */
94
+ declare type SearchAutocompleteComponent = <Option>(props: SearchAutocompleteProps<Option>) => JSX.Element;
95
+ /**
96
+ * Recommended search autocomplete when you use the Search Provider or Search Context.
97
+ *
98
+ * @public
99
+ */
100
+ declare const SearchAutocomplete: SearchAutocompleteComponent;
101
+
102
+ /**
103
+ * Props for {@link SearchAutocompleteDefaultOption}.
104
+ *
105
+ * @public
106
+ */
107
+ declare type SearchAutocompleteDefaultOptionProps = {
108
+ icon?: ReactNode;
109
+ primaryText: ListItemTextProps['primary'];
110
+ primaryTextTypographyProps?: ListItemTextProps['primaryTypographyProps'];
111
+ secondaryText?: ListItemTextProps['secondary'];
112
+ secondaryTextTypographyProps?: ListItemTextProps['secondaryTypographyProps'];
113
+ disableTextTypography?: ListItemTextProps['disableTypography'];
114
+ };
115
+ /**
116
+ * A default search autocomplete option component.
117
+ *
118
+ * @public
119
+ */
120
+ declare const SearchAutocompleteDefaultOption: ({ icon, primaryText, primaryTextTypographyProps, secondaryText, secondaryTextTypographyProps, disableTextTypography, }: SearchAutocompleteDefaultOptionProps) => JSX.Element;
121
+
45
122
  /**
46
123
  * @public
47
124
  */
@@ -134,39 +211,6 @@ declare const HigherOrderSearchResult: (props: SearchResultProps) => JSX.Element
134
211
  */
135
212
  declare const SearchResultPager: () => JSX.Element;
136
213
 
137
- /**
138
- * Props for {@link SearchBarBase}.
139
- *
140
- * @public
141
- */
142
- declare type SearchBarBaseProps = Omit<InputBaseProps, 'onChange'> & {
143
- debounceTime?: number;
144
- clearButton?: boolean;
145
- onClear?: () => void;
146
- onSubmit?: () => void;
147
- onChange: (value: string) => void;
148
- };
149
- /**
150
- * All search boxes exported by the search plugin are based on the <SearchBarBase />,
151
- * and this one is based on the <InputBase /> component from Material UI.
152
- * Recommended if you don't use Search Provider or Search Context.
153
- *
154
- * @public
155
- */
156
- declare const SearchBarBase: ({ onChange, onKeyDown, onSubmit, debounceTime, clearButton, fullWidth, value: defaultValue, inputProps: defaultInputProps, endAdornment: defaultEndAdornment, ...props }: SearchBarBaseProps) => JSX.Element;
157
- /**
158
- * Props for {@link SearchBar}.
159
- *
160
- * @public
161
- */
162
- declare type SearchBarProps = Partial<SearchBarBaseProps>;
163
- /**
164
- * Recommended search bar when you use the Search Provider or Search Context.
165
- *
166
- * @public
167
- */
168
- declare const SearchBar: ({ onChange, ...props }: SearchBarProps) => JSX.Element;
169
-
170
214
  /**
171
215
  * Props for {@link DefaultResultListItem}
172
216
  *
@@ -226,13 +270,29 @@ declare const useSearchContextCheck: () => boolean;
226
270
  * @public
227
271
  */
228
272
  declare type SearchContextProviderProps = PropsWithChildren<{
273
+ /**
274
+ * State initialized by a local context.
275
+ */
229
276
  initialState?: SearchContextState;
277
+ /**
278
+ * Do not create an inheritance from the parent, as a new initial state must be defined in a local context.
279
+ */
280
+ inheritParentContextIfAvailable?: never;
281
+ }> | PropsWithChildren<{
282
+ /**
283
+ * Does not accept initial state since it is already initialized by parent context.
284
+ */
285
+ initialState?: never;
286
+ /**
287
+ * If true, don't create a child context if there is a parent one already defined.
288
+ * @remarks Defaults to false.
289
+ */
290
+ inheritParentContextIfAvailable?: boolean;
230
291
  }>;
231
292
  /**
232
293
  * @public
233
- *
234
294
  * Search context provider which gives you access to shared state between search components
235
295
  */
236
296
  declare const SearchContextProvider: (props: SearchContextProviderProps) => JSX.Element;
237
297
 
238
- export { AutocompleteFilter, CheckboxFilter, HigherOrderDefaultResultListItem as DefaultResultListItem, DefaultResultListItemProps, HighlightedSearchResultText, HighlightedSearchResultTextProps, MockSearchApi, SearchApi, SearchAutocompleteFilterProps, SearchBar, SearchBarBase, SearchBarBaseProps, SearchBarProps, SearchContextProvider, SearchContextProviderProps, SearchContextState, SearchContextValue, SearchFilter, SearchFilterComponentProps, SearchFilterWrapperProps, HigherOrderSearchResult as SearchResult, SearchResultComponent, SearchResultPager, SearchResultProps, SelectFilter, searchApiRef, useSearch, useSearchContextCheck };
298
+ export { AutocompleteFilter, CheckboxFilter, HigherOrderDefaultResultListItem as DefaultResultListItem, DefaultResultListItemProps, HighlightedSearchResultText, HighlightedSearchResultTextProps, MockSearchApi, SearchApi, SearchAutocomplete, SearchAutocompleteComponent, SearchAutocompleteDefaultOption, SearchAutocompleteDefaultOptionProps, SearchAutocompleteFilterProps, SearchAutocompleteProps, SearchBar, SearchBarBase, SearchBarBaseProps, SearchBarProps, SearchContextProvider, SearchContextProviderProps, SearchContextState, SearchContextValue, SearchFilter, SearchFilterComponentProps, SearchFilterWrapperProps, HigherOrderSearchResult as SearchResult, SearchResultComponent, SearchResultPager, SearchResultProps, SelectFilter, searchApiRef, useSearch, useSearchContextCheck };
package/dist/index.esm.js CHANGED
@@ -1,17 +1,17 @@
1
- import { createApiRef, useApi, AnalyticsContext, useAnalytics, configApiRef } from '@backstage/core-plugin-api';
2
- import React, { useMemo, useContext, useState, useCallback, useEffect, useRef } from 'react';
3
- import { makeStyles, TextField, Chip, FormControl, FormLabel, FormControlLabel, Checkbox, InputLabel, Select, MenuItem, Button, InputBase, InputAdornment, IconButton, ListItem, ListItemIcon, ListItemText, Box, Divider } from '@material-ui/core';
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, ListItem, Box, Divider } from '@material-ui/core';
4
+ import useDebounce from 'react-use/lib/useDebounce';
5
+ import SearchIcon from '@material-ui/icons/Search';
6
+ import ClearButton from '@material-ui/icons/Clear';
4
7
  import { createVersionedContext, createVersionedValueMap } from '@backstage/version-bridge';
5
8
  import useAsync from 'react-use/lib/useAsync';
6
9
  import usePrevious from 'react-use/lib/usePrevious';
7
10
  import { Autocomplete } from '@material-ui/lab';
8
11
  import useAsyncFn from 'react-use/lib/useAsyncFn';
9
- import useDebounce from 'react-use/lib/useDebounce';
10
12
  import { Progress, ResponseErrorPanel, EmptyState, Link } from '@backstage/core-components';
11
13
  import ArrowBackIosIcon from '@material-ui/icons/ArrowBackIos';
12
14
  import ArrowForwardIosIcon from '@material-ui/icons/ArrowForwardIos';
13
- import SearchIcon from '@material-ui/icons/Search';
14
- import ClearButton from '@material-ui/icons/Clear';
15
15
 
16
16
  const searchApiRef = createApiRef({
17
17
  id: "plugin.search.queryservice"
@@ -71,16 +71,15 @@ const searchInitialState = {
71
71
  filters: {},
72
72
  types: []
73
73
  };
74
- const SearchContextProvider = (props) => {
74
+ const useSearchContextValue = (initialValue = searchInitialState) => {
75
75
  var _a, _b, _c, _d;
76
- const { initialState = searchInitialState, children } = props;
77
76
  const searchApi = useApi(searchApiRef);
78
77
  const [pageCursor, setPageCursor] = useState(
79
- initialState.pageCursor
78
+ initialValue.pageCursor
80
79
  );
81
- const [filters, setFilters] = useState(initialState.filters);
82
- const [term, setTerm] = useState(initialState.term);
83
- const [types, setTypes] = useState(initialState.types);
80
+ const [filters, setFilters] = useState(initialValue.filters);
81
+ const [term, setTerm] = useState(initialValue.term);
82
+ const [types, setTypes] = useState(initialValue.types);
84
83
  const prevTerm = usePrevious(term);
85
84
  const result = useAsync(
86
85
  () => searchApi.query({
@@ -119,14 +118,248 @@ const SearchContextProvider = (props) => {
119
118
  fetchNextPage: hasNextPage ? fetchNextPage : void 0,
120
119
  fetchPreviousPage: hasPreviousPage ? fetchPreviousPage : void 0
121
120
  };
122
- const versionedValue = createVersionedValueMap({ 1: value });
121
+ return value;
122
+ };
123
+ const LocalSearchContext = (props) => {
124
+ const { initialState, children } = props;
125
+ const value = useSearchContextValue(initialState);
123
126
  return /* @__PURE__ */ React.createElement(AnalyticsContext, {
124
- attributes: { searchTypes: types.sort().join(",") }
127
+ attributes: { searchTypes: value.types.sort().join(",") }
125
128
  }, /* @__PURE__ */ React.createElement(SearchContext.Provider, {
126
- value: versionedValue,
127
- children
129
+ value: createVersionedValueMap({ 1: value })
130
+ }, children));
131
+ };
132
+ const SearchContextProvider = (props) => {
133
+ const { initialState, inheritParentContextIfAvailable, children } = props;
134
+ const hasParentContext = useSearchContextCheck();
135
+ return hasParentContext && inheritParentContextIfAvailable ? /* @__PURE__ */ React.createElement(React.Fragment, null, children) : /* @__PURE__ */ React.createElement(LocalSearchContext, {
136
+ initialState
137
+ }, children);
138
+ };
139
+
140
+ const TrackSearch = ({ children }) => {
141
+ const analytics = useAnalytics();
142
+ const { term } = useSearch();
143
+ useEffect(() => {
144
+ if (term) {
145
+ analytics.captureEvent("search", term);
146
+ }
147
+ }, [analytics, term]);
148
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, children);
149
+ };
150
+
151
+ function withContext$1(Component) {
152
+ return forwardRef((props, ref) => /* @__PURE__ */ React.createElement(SearchContextProvider, {
153
+ inheritParentContextIfAvailable: true
154
+ }, /* @__PURE__ */ React.createElement(Component, {
155
+ ...props,
156
+ ref
157
+ })));
158
+ }
159
+ const SearchBarBase = withContext$1(
160
+ forwardRef((props, ref) => {
161
+ const {
162
+ onChange,
163
+ onKeyDown = () => {
164
+ },
165
+ onClear = () => {
166
+ },
167
+ onSubmit = () => {
168
+ },
169
+ debounceTime = 200,
170
+ clearButton = true,
171
+ fullWidth = true,
172
+ value: defaultValue,
173
+ placeholder: defaultPlaceholder,
174
+ inputProps: defaultInputProps = {},
175
+ endAdornment: defaultEndAdornment,
176
+ ...rest
177
+ } = props;
178
+ const configApi = useApi(configApiRef);
179
+ const [value, setValue] = useState("");
180
+ useEffect(() => {
181
+ setValue(
182
+ (prevValue) => prevValue !== defaultValue ? String(defaultValue) : prevValue
183
+ );
184
+ }, [defaultValue]);
185
+ useDebounce(() => onChange(value), debounceTime, [value]);
186
+ const handleChange = useCallback(
187
+ (e) => {
188
+ setValue(e.target.value);
189
+ },
190
+ [setValue]
191
+ );
192
+ const handleKeyDown = useCallback(
193
+ (e) => {
194
+ if (onKeyDown)
195
+ onKeyDown(e);
196
+ if (onSubmit && e.key === "Enter") {
197
+ onSubmit();
198
+ }
199
+ },
200
+ [onKeyDown, onSubmit]
201
+ );
202
+ const handleClear = useCallback(() => {
203
+ onChange("");
204
+ if (onClear) {
205
+ onClear();
206
+ }
207
+ }, [onChange, onClear]);
208
+ const placeholder = defaultPlaceholder != null ? defaultPlaceholder : `Search in ${configApi.getOptionalString("app.title") || "Backstage"}`;
209
+ const startAdornment = /* @__PURE__ */ React.createElement(InputAdornment, {
210
+ position: "start"
211
+ }, /* @__PURE__ */ React.createElement(IconButton, {
212
+ "aria-label": "Query",
213
+ size: "small",
214
+ disabled: true
215
+ }, /* @__PURE__ */ React.createElement(SearchIcon, null)));
216
+ const endAdornment = /* @__PURE__ */ React.createElement(InputAdornment, {
217
+ position: "end"
218
+ }, /* @__PURE__ */ React.createElement(IconButton, {
219
+ "aria-label": "Clear",
220
+ size: "small",
221
+ onClick: handleClear
222
+ }, /* @__PURE__ */ React.createElement(ClearButton, null)));
223
+ return /* @__PURE__ */ React.createElement(TrackSearch, null, /* @__PURE__ */ React.createElement(InputBase, {
224
+ "data-testid": "search-bar-next",
225
+ ref,
226
+ value,
227
+ placeholder,
228
+ startAdornment,
229
+ endAdornment: clearButton ? endAdornment : defaultEndAdornment,
230
+ inputProps: { "aria-label": "Search", ...defaultInputProps },
231
+ fullWidth,
232
+ onChange: handleChange,
233
+ onKeyDown: handleKeyDown,
234
+ ...rest
235
+ }));
236
+ })
237
+ );
238
+ const SearchBar = withContext$1(
239
+ forwardRef((props, ref) => {
240
+ const { value: initialValue = "", onChange, ...rest } = props;
241
+ const { term, setTerm } = useSearch();
242
+ useEffect(() => {
243
+ if (initialValue) {
244
+ setTerm(String(initialValue));
245
+ }
246
+ }, [initialValue, setTerm]);
247
+ const handleChange = useCallback(
248
+ (newValue) => {
249
+ if (onChange) {
250
+ onChange(newValue);
251
+ } else {
252
+ setTerm(newValue);
253
+ }
254
+ },
255
+ [onChange, setTerm]
256
+ );
257
+ return /* @__PURE__ */ React.createElement(AnalyticsContext, {
258
+ attributes: { pluginId: "search", extension: "SearchBar" }
259
+ }, /* @__PURE__ */ React.createElement(SearchBarBase, {
260
+ ...rest,
261
+ ref,
262
+ value: term,
263
+ onChange: handleChange
264
+ }));
265
+ })
266
+ );
267
+
268
+ const withContext = (Component) => {
269
+ return (props) => /* @__PURE__ */ React.createElement(SearchContextProvider, {
270
+ inheritParentContextIfAvailable: true
271
+ }, /* @__PURE__ */ React.createElement(Component, {
272
+ ...props
128
273
  }));
129
274
  };
275
+ const SearchAutocomplete = withContext(
276
+ function SearchAutocompleteComponent(props) {
277
+ const {
278
+ loading,
279
+ value,
280
+ onChange = () => {
281
+ },
282
+ options = [],
283
+ getOptionLabel = (option) => String(option),
284
+ inputPlaceholder,
285
+ inputDebounceTime,
286
+ freeSolo = true,
287
+ fullWidth = true,
288
+ clearOnBlur = false,
289
+ "data-testid": dataTestId = "search-autocomplete",
290
+ ...rest
291
+ } = props;
292
+ const { setTerm } = useSearch();
293
+ const getInputValue = useCallback(
294
+ (option) => {
295
+ if (!option)
296
+ return "";
297
+ if (typeof option === "string")
298
+ return option;
299
+ return getOptionLabel(option);
300
+ },
301
+ [getOptionLabel]
302
+ );
303
+ const inputValue = useMemo(
304
+ () => getInputValue(value),
305
+ [value, getInputValue]
306
+ );
307
+ const handleChange = useCallback(
308
+ (event, option, reason, details) => {
309
+ setTerm(getInputValue(option));
310
+ onChange(event, option, reason, details);
311
+ },
312
+ [getInputValue, setTerm, onChange]
313
+ );
314
+ const renderInput = useCallback(
315
+ ({
316
+ InputProps: { ref, endAdornment },
317
+ InputLabelProps,
318
+ ...params
319
+ }) => /* @__PURE__ */ React.createElement(SearchBar, {
320
+ ...params,
321
+ ref,
322
+ clearButton: false,
323
+ value: inputValue,
324
+ placeholder: inputPlaceholder,
325
+ debounceTime: inputDebounceTime,
326
+ endAdornment: loading ? /* @__PURE__ */ React.createElement(CircularProgress, {
327
+ "data-testid": "search-autocomplete-progressbar",
328
+ color: "inherit",
329
+ size: 20
330
+ }) : endAdornment
331
+ }),
332
+ [loading, inputValue, inputPlaceholder, inputDebounceTime]
333
+ );
334
+ return /* @__PURE__ */ React.createElement(Autocomplete, {
335
+ ...rest,
336
+ "data-testid": dataTestId,
337
+ value,
338
+ onChange: handleChange,
339
+ options,
340
+ getOptionLabel,
341
+ renderInput,
342
+ freeSolo,
343
+ fullWidth,
344
+ clearOnBlur
345
+ });
346
+ }
347
+ );
348
+
349
+ const SearchAutocompleteDefaultOption = ({
350
+ icon,
351
+ primaryText,
352
+ primaryTextTypographyProps,
353
+ secondaryText,
354
+ secondaryTextTypographyProps,
355
+ disableTextTypography
356
+ }) => /* @__PURE__ */ React.createElement(React.Fragment, null, icon ? /* @__PURE__ */ React.createElement(ListItemIcon, null, icon) : null, /* @__PURE__ */ React.createElement(ListItemText, {
357
+ primary: primaryText,
358
+ primaryTypographyProps: primaryTextTypographyProps,
359
+ secondary: secondaryText,
360
+ secondaryTypographyProps: secondaryTextTypographyProps,
361
+ disableTypography: disableTextTypography
362
+ }));
130
363
 
131
364
  const useAsyncFilterValues = (fn, inputValue, defaultValues = [], debounce = 250) => {
132
365
  const valuesMemo = useRef({});
@@ -424,105 +657,6 @@ const SearchResultPager = () => {
424
657
  }, "Next"));
425
658
  };
426
659
 
427
- const TrackSearch = ({ children }) => {
428
- const analytics = useAnalytics();
429
- const { term } = useSearch();
430
- useEffect(() => {
431
- if (term) {
432
- analytics.captureEvent("search", term);
433
- }
434
- }, [analytics, term]);
435
- return /* @__PURE__ */ React.createElement(React.Fragment, null, children);
436
- };
437
-
438
- const SearchBarBase = ({
439
- onChange,
440
- onKeyDown,
441
- onSubmit,
442
- debounceTime = 200,
443
- clearButton = true,
444
- fullWidth = true,
445
- value: defaultValue,
446
- inputProps: defaultInputProps = {},
447
- endAdornment: defaultEndAdornment,
448
- ...props
449
- }) => {
450
- const configApi = useApi(configApiRef);
451
- const [value, setValue] = useState(defaultValue);
452
- const hasSearchContext = useSearchContextCheck();
453
- useEffect(() => {
454
- setValue(
455
- (prevValue) => prevValue !== defaultValue ? defaultValue : prevValue
456
- );
457
- }, [defaultValue]);
458
- useDebounce(() => onChange(value), debounceTime, [value]);
459
- const handleChange = useCallback(
460
- (e) => {
461
- setValue(e.target.value);
462
- },
463
- [setValue]
464
- );
465
- const handleKeyDown = useCallback(
466
- (e) => {
467
- if (onKeyDown)
468
- onKeyDown(e);
469
- if (onSubmit && e.key === "Enter") {
470
- onSubmit();
471
- }
472
- },
473
- [onKeyDown, onSubmit]
474
- );
475
- const handleClear = useCallback(() => {
476
- onChange("");
477
- }, [onChange]);
478
- const placeholder = `Search in ${configApi.getOptionalString("app.title") || "Backstage"}`;
479
- const startAdornment = /* @__PURE__ */ React.createElement(InputAdornment, {
480
- position: "start"
481
- }, /* @__PURE__ */ React.createElement(IconButton, {
482
- "aria-label": "Query",
483
- disabled: true
484
- }, /* @__PURE__ */ React.createElement(SearchIcon, null)));
485
- const endAdornment = /* @__PURE__ */ React.createElement(InputAdornment, {
486
- position: "end"
487
- }, /* @__PURE__ */ React.createElement(IconButton, {
488
- "aria-label": "Clear",
489
- onClick: handleClear
490
- }, /* @__PURE__ */ React.createElement(ClearButton, null)));
491
- const searchBar = /* @__PURE__ */ React.createElement(TrackSearch, null, /* @__PURE__ */ React.createElement(InputBase, {
492
- "data-testid": "search-bar-next",
493
- value,
494
- placeholder,
495
- startAdornment,
496
- endAdornment: clearButton ? endAdornment : defaultEndAdornment,
497
- inputProps: { "aria-label": "Search", ...defaultInputProps },
498
- fullWidth,
499
- onChange: handleChange,
500
- onKeyDown: handleKeyDown,
501
- ...props
502
- }));
503
- return hasSearchContext ? searchBar : /* @__PURE__ */ React.createElement(SearchContextProvider, null, searchBar);
504
- };
505
- const SearchBar = ({ onChange, ...props }) => {
506
- const { term, setTerm } = useSearch();
507
- const handleChange = useCallback(
508
- (newValue) => {
509
- if (onChange) {
510
- onChange(newValue);
511
- } else {
512
- setTerm(newValue);
513
- }
514
- },
515
- [onChange, setTerm]
516
- );
517
- return /* @__PURE__ */ React.createElement(AnalyticsContext, {
518
- attributes: { pluginId: "search", extension: "SearchBar" }
519
- }, /* @__PURE__ */ React.createElement(SearchBarBase, {
520
- value: term,
521
- onChange: handleChange,
522
- ...props
523
- }));
524
- };
525
-
526
660
  const DefaultResultListItemComponent = ({
527
661
  result,
528
662
  highlight,
@@ -578,5 +712,5 @@ const HigherOrderDefaultResultListItem = (props) => {
578
712
  }));
579
713
  };
580
714
 
581
- export { AutocompleteFilter, CheckboxFilter, HigherOrderDefaultResultListItem as DefaultResultListItem, HighlightedSearchResultText, MockSearchApi, SearchBar, SearchBarBase, SearchContextProvider, SearchFilter, HigherOrderSearchResult as SearchResult, SearchResultComponent, SearchResultPager, SelectFilter, searchApiRef, useSearch, useSearchContextCheck };
715
+ export { AutocompleteFilter, CheckboxFilter, HigherOrderDefaultResultListItem as DefaultResultListItem, HighlightedSearchResultText, MockSearchApi, SearchAutocomplete, SearchAutocompleteDefaultOption, SearchBar, SearchBarBase, SearchContextProvider, SearchFilter, HigherOrderSearchResult as SearchResult, SearchResultComponent, SearchResultPager, SelectFilter, searchApiRef, useSearch, useSearchContextCheck };
582
716
  //# sourceMappingURL=index.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.esm.js","sources":["../src/api.ts","../src/components/HighlightedSearchResultText/HighlightedSearchResultText.tsx","../src/context/SearchContext.tsx","../src/components/SearchFilter/hooks.ts","../src/components/SearchFilter/SearchFilter.Autocomplete.tsx","../src/components/SearchFilter/SearchFilter.tsx","../src/components/SearchResult/SearchResult.tsx","../src/components/SearchResultPager/SearchResultPager.tsx","../src/components/SearchTracker/SearchTracker.tsx","../src/components/SearchBar/SearchBar.tsx","../src/components/DefaultResultListItem/DefaultResultListItem.tsx"],"sourcesContent":["/*\n * Copyright 2022 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 */\n\nimport { SearchQuery, SearchResultSet } from '@backstage/plugin-search-common';\nimport { createApiRef } from '@backstage/core-plugin-api';\n\n/**\n * @public\n */\nexport const searchApiRef = createApiRef<SearchApi>({\n id: 'plugin.search.queryservice',\n});\n\n/**\n * @public\n */\nexport interface SearchApi {\n query(query: SearchQuery): Promise<SearchResultSet>;\n}\n\n/**\n * @public\n *\n * Search Api Mock that can be used in tests and storybooks\n */\nexport class MockSearchApi implements SearchApi {\n constructor(public mockedResults?: SearchResultSet) {}\n\n query(): Promise<SearchResultSet> {\n return Promise.resolve(this.mockedResults || { results: [] });\n }\n}\n","/*\n * Copyright 2022 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 */\n\nimport React, { useMemo } from 'react';\nimport { makeStyles } from '@material-ui/core';\n\nconst useStyles = makeStyles(\n () => ({\n highlight: {},\n }),\n { name: 'BackstageHighlightedSearchResultText' },\n);\n\n/**\n * Props for {@link HighlightedSearchResultText}.\n *\n * @public\n */\nexport type HighlightedSearchResultTextProps = {\n text: string;\n preTag: string;\n postTag: string;\n};\n\n/**\n * @public\n */\nexport const HighlightedSearchResultText = ({\n text,\n preTag,\n postTag,\n}: HighlightedSearchResultTextProps) => {\n const classes = useStyles();\n const terms = useMemo(\n () => text.split(new RegExp(`(${preTag}.+?${postTag})`)),\n [postTag, preTag, text],\n );\n return (\n <>\n {terms.map((t, idx) =>\n t.includes(preTag) ? (\n <mark className={classes.highlight} key={idx}>\n {t.replace(new RegExp(`${preTag}|${postTag}`, 'g'), '')}\n </mark>\n ) : (\n t\n ),\n )}\n </>\n );\n};\n","/*\n * Copyright 2022 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 */\n\nimport { JsonObject } from '@backstage/types';\nimport { useApi, AnalyticsContext } from '@backstage/core-plugin-api';\nimport { SearchResultSet } from '@backstage/plugin-search-common';\nimport {\n createVersionedContext,\n createVersionedValueMap,\n} from '@backstage/version-bridge';\nimport React, {\n PropsWithChildren,\n useCallback,\n useContext,\n useEffect,\n useState,\n} from 'react';\nimport useAsync, { AsyncState } from 'react-use/lib/useAsync';\nimport usePrevious from 'react-use/lib/usePrevious';\nimport { searchApiRef } from '../api';\n\n/**\n *\n * @public\n */\nexport type SearchContextValue = {\n result: AsyncState<SearchResultSet>;\n setTerm: React.Dispatch<React.SetStateAction<string>>;\n setTypes: React.Dispatch<React.SetStateAction<string[]>>;\n setFilters: React.Dispatch<React.SetStateAction<JsonObject>>;\n setPageCursor: React.Dispatch<React.SetStateAction<string | undefined>>;\n fetchNextPage?: React.DispatchWithoutAction;\n fetchPreviousPage?: React.DispatchWithoutAction;\n} & SearchContextState;\n\n/**\n *\n * @public\n */\nexport type SearchContextState = {\n term: string;\n types: string[];\n filters: JsonObject;\n pageCursor?: string;\n};\n\nconst SearchContext = createVersionedContext<{\n 1: SearchContextValue;\n}>('search-context');\n\n/**\n * @public\n *\n * React hook which provides the search context\n */\nexport const useSearch = () => {\n const context = useContext(SearchContext);\n if (!context) {\n throw new Error('useSearch must be used within a SearchContextProvider');\n }\n\n const value = context.atVersion(1);\n if (!value) {\n throw new Error('No SearchContext v1 found');\n }\n return value;\n};\n\n/**\n * @public\n *\n * React hook which checks for an existing search context\n */\nexport const useSearchContextCheck = () => {\n const context = useContext(SearchContext);\n return context !== undefined;\n};\n\n/**\n * The initial state of `SearchContextProvider`.\n *\n */\nconst searchInitialState: SearchContextState = {\n term: '',\n pageCursor: undefined,\n filters: {},\n types: [],\n};\n\n/**\n * Props for {@link SearchContextProvider}\n *\n * @public\n */\nexport type SearchContextProviderProps = PropsWithChildren<{\n initialState?: SearchContextState;\n}>;\n\n/**\n * @public\n *\n * Search context provider which gives you access to shared state between search components\n */\nexport const SearchContextProvider = (props: SearchContextProviderProps) => {\n const { initialState = searchInitialState, children } = props;\n const searchApi = useApi(searchApiRef);\n const [pageCursor, setPageCursor] = useState<string | undefined>(\n initialState.pageCursor,\n );\n const [filters, setFilters] = useState<JsonObject>(initialState.filters);\n const [term, setTerm] = useState<string>(initialState.term);\n const [types, setTypes] = useState<string[]>(initialState.types);\n\n const prevTerm = usePrevious(term);\n\n const result = useAsync(\n () =>\n searchApi.query({\n term,\n filters,\n pageCursor,\n types,\n }),\n [term, filters, types, pageCursor],\n );\n\n const hasNextPage =\n !result.loading && !result.error && result.value?.nextPageCursor;\n const hasPreviousPage =\n !result.loading && !result.error && result.value?.previousPageCursor;\n const fetchNextPage = useCallback(() => {\n setPageCursor(result.value?.nextPageCursor);\n }, [result.value?.nextPageCursor]);\n const fetchPreviousPage = useCallback(() => {\n setPageCursor(result.value?.previousPageCursor);\n }, [result.value?.previousPageCursor]);\n\n useEffect(() => {\n // Any time a term is reset, we want to start from page 0.\n // Only reset the term if it has been modified by the user at least once, the initial state must not reset the term.\n if (prevTerm !== undefined && term !== prevTerm) {\n setPageCursor(undefined);\n }\n }, [term, prevTerm, setPageCursor]);\n\n const value: SearchContextValue = {\n result,\n filters,\n setFilters,\n term,\n setTerm,\n types,\n setTypes,\n pageCursor,\n setPageCursor,\n fetchNextPage: hasNextPage ? fetchNextPage : undefined,\n fetchPreviousPage: hasPreviousPage ? fetchPreviousPage : undefined,\n };\n\n const versionedValue = createVersionedValueMap({ 1: value });\n\n return (\n <AnalyticsContext attributes={{ searchTypes: types.sort().join(',') }}>\n <SearchContext.Provider value={versionedValue} children={children} />\n </AnalyticsContext>\n );\n};\n","/*\n * Copyright 2022 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 */\n\nimport { useEffect, useRef } from 'react';\nimport useAsyncFn from 'react-use/lib/useAsyncFn';\nimport useDebounce from 'react-use/lib/useDebounce';\n\nimport { useSearch } from '../../context';\n\n/**\n * Utility hook for either asynchronously loading filter values from a given\n * function or synchronously providing a given list of default values.\n *\n * @public\n */\nexport const useAsyncFilterValues = (\n fn: ((partial: string) => Promise<string[]>) | undefined,\n inputValue: string,\n defaultValues: string[] = [],\n debounce: number = 250,\n) => {\n const valuesMemo = useRef<Record<string, string[] | Promise<string[]>>>({});\n const definiteFn = fn || (() => Promise.resolve([]));\n\n const [state, callback] = useAsyncFn(definiteFn, [inputValue], {\n loading: true,\n });\n\n // Do not invoke the given function more than necessary.\n useDebounce(\n () => {\n // Performance optimization: only invoke the callback once per inputValue\n // for the lifetime of the hook/component.\n if (valuesMemo.current[inputValue] === undefined) {\n valuesMemo.current[inputValue] = callback(inputValue).then(values => {\n // Override the value for future immediate returns.\n valuesMemo.current[inputValue] = values;\n return values;\n });\n }\n },\n debounce,\n [callback, inputValue],\n );\n\n // Immediately return the default values if they are provided.\n if (defaultValues.length) {\n return {\n loading: false,\n value: defaultValues,\n };\n }\n\n // Immediately return a memoized value if it is set (and not a promise).\n const possibleValue = valuesMemo.current[inputValue];\n if (Array.isArray(possibleValue)) {\n return {\n loading: false,\n value: possibleValue,\n };\n }\n\n return state;\n};\n\n/**\n * Utility hook for applying a given default value to the search context.\n *\n * @public\n */\nexport const useDefaultFilterValue = (\n name: string,\n defaultValue?: string | string[] | null,\n) => {\n const { setFilters } = useSearch();\n\n useEffect(() => {\n if (defaultValue && [defaultValue].flat().length > 0) {\n setFilters(prevFilters => ({\n ...prevFilters,\n [name]: defaultValue,\n }));\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n};\n","/*\n * Copyright 2022 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 */\n\nimport React, { ChangeEvent, useState } from 'react';\nimport { Chip, TextField } from '@material-ui/core';\nimport {\n Autocomplete,\n AutocompleteGetTagProps,\n AutocompleteRenderInputParams,\n} from '@material-ui/lab';\n\nimport { useSearch } from '../../context';\nimport { useAsyncFilterValues, useDefaultFilterValue } from './hooks';\nimport { SearchFilterComponentProps } from './SearchFilter';\n\n/**\n * @public\n */\nexport type SearchAutocompleteFilterProps = SearchFilterComponentProps & {\n filterSelectedOptions?: boolean;\n limitTags?: number;\n multiple?: boolean;\n};\n\n/**\n * @public\n */\nexport const AutocompleteFilter = (props: SearchAutocompleteFilterProps) => {\n const {\n className,\n defaultValue,\n name,\n values: givenValues,\n valuesDebounceMs,\n label,\n filterSelectedOptions,\n limitTags,\n multiple,\n } = props;\n const [inputValue, setInputValue] = useState<string>('');\n useDefaultFilterValue(name, defaultValue);\n const asyncValues =\n typeof givenValues === 'function' ? givenValues : undefined;\n const defaultValues =\n typeof givenValues === 'function' ? undefined : givenValues;\n const { value: values, loading } = useAsyncFilterValues(\n asyncValues,\n inputValue,\n defaultValues,\n valuesDebounceMs,\n );\n const { filters, setFilters } = useSearch();\n const filterValue =\n (filters[name] as string | string[] | undefined) || (multiple ? [] : null);\n\n // Set new filter values on input change.\n const handleChange = (\n _: ChangeEvent<{}>,\n newValue: string | string[] | null,\n ) => {\n setFilters(prevState => {\n const { [name]: filter, ...others } = prevState;\n\n if (newValue) {\n return { ...others, [name]: newValue };\n }\n return { ...others };\n });\n };\n\n // Provide the input field.\n const renderInput = (params: AutocompleteRenderInputParams) => (\n <TextField\n {...params}\n name=\"search\"\n variant=\"outlined\"\n label={label}\n fullWidth\n />\n );\n\n // Render tags as primary-colored chips.\n const renderTags = (\n tagValue: string[],\n getTagProps: AutocompleteGetTagProps,\n ) =>\n tagValue.map((option: string, index: number) => (\n <Chip label={option} color=\"primary\" {...getTagProps({ index })} />\n ));\n\n return (\n <Autocomplete\n filterSelectedOptions={filterSelectedOptions}\n limitTags={limitTags}\n multiple={multiple}\n className={className}\n id={`${multiple ? 'multi-' : ''}select-filter-${name}--select`}\n options={values || []}\n loading={loading}\n value={filterValue}\n onChange={handleChange}\n onInputChange={(_, newValue) => setInputValue(newValue)}\n renderInput={renderInput}\n renderTags={renderTags}\n />\n );\n};\n","/*\n * Copyright 2022 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 */\n\nimport React, { ReactElement, ChangeEvent } from 'react';\nimport {\n makeStyles,\n FormControl,\n FormControlLabel,\n InputLabel,\n Checkbox,\n Select,\n MenuItem,\n FormLabel,\n} from '@material-ui/core';\n\nimport { useSearch } from '../../context';\nimport {\n AutocompleteFilter,\n SearchAutocompleteFilterProps,\n} from './SearchFilter.Autocomplete';\nimport { useAsyncFilterValues, useDefaultFilterValue } from './hooks';\n\nconst useStyles = makeStyles({\n label: {\n textTransform: 'capitalize',\n },\n});\n\n/**\n * @public\n */\nexport type SearchFilterComponentProps = {\n className?: string;\n name: string;\n label?: string;\n /**\n * Either an array of values directly, or an async function to return a list\n * of values to be used in the filter. In the autocomplete filter, the last\n * input value is provided as an input to allow values to be filtered. This\n * function is debounced and values cached.\n */\n values?: string[] | ((partial: string) => Promise<string[]>);\n defaultValue?: string[] | string | null;\n /**\n * Debounce time in milliseconds, used when values is an async callback.\n * Defaults to 250ms.\n */\n valuesDebounceMs?: number;\n};\n\n/**\n * @public\n */\nexport type SearchFilterWrapperProps = SearchFilterComponentProps & {\n component: (props: SearchFilterComponentProps) => ReactElement;\n debug?: boolean;\n};\n\n/**\n * @public\n */\nexport const CheckboxFilter = (props: SearchFilterComponentProps) => {\n const {\n className,\n defaultValue,\n label,\n name,\n values: givenValues = [],\n valuesDebounceMs,\n } = props;\n const classes = useStyles();\n const { filters, setFilters } = useSearch();\n useDefaultFilterValue(name, defaultValue);\n const asyncValues =\n typeof givenValues === 'function' ? givenValues : undefined;\n const defaultValues =\n typeof givenValues === 'function' ? undefined : givenValues;\n const { value: values = [], loading } = useAsyncFilterValues(\n asyncValues,\n '',\n defaultValues,\n valuesDebounceMs,\n );\n\n const handleChange = (e: ChangeEvent<HTMLInputElement>) => {\n const {\n target: { value, checked },\n } = e;\n\n setFilters(prevFilters => {\n const { [name]: filter, ...others } = prevFilters;\n const rest = ((filter as string[]) || []).filter(i => i !== value);\n const items = checked ? [...rest, value] : rest;\n return items.length ? { ...others, [name]: items } : others;\n });\n };\n\n return (\n <FormControl\n className={className}\n disabled={loading}\n fullWidth\n data-testid=\"search-checkboxfilter-next\"\n >\n {label ? <FormLabel className={classes.label}>{label}</FormLabel> : null}\n {values.map((value: string) => (\n <FormControlLabel\n key={value}\n control={\n <Checkbox\n color=\"primary\"\n tabIndex={-1}\n inputProps={{ 'aria-labelledby': value }}\n value={value}\n name={value}\n onChange={handleChange}\n checked={((filters[name] as string[]) ?? []).includes(value)}\n />\n }\n label={value}\n />\n ))}\n </FormControl>\n );\n};\n\n/**\n * @public\n */\nexport const SelectFilter = (props: SearchFilterComponentProps) => {\n const {\n className,\n defaultValue,\n label,\n name,\n values: givenValues,\n valuesDebounceMs,\n } = props;\n const classes = useStyles();\n useDefaultFilterValue(name, defaultValue);\n const asyncValues =\n typeof givenValues === 'function' ? givenValues : undefined;\n const defaultValues =\n typeof givenValues === 'function' ? undefined : givenValues;\n const { value: values = [], loading } = useAsyncFilterValues(\n asyncValues,\n '',\n defaultValues,\n valuesDebounceMs,\n );\n const { filters, setFilters } = useSearch();\n\n const handleChange = (e: ChangeEvent<{ value: unknown }>) => {\n const {\n target: { value },\n } = e;\n\n setFilters(prevFilters => {\n const { [name]: filter, ...others } = prevFilters;\n return value ? { ...others, [name]: value as string } : others;\n });\n };\n\n return (\n <FormControl\n disabled={loading}\n className={className}\n variant=\"filled\"\n fullWidth\n data-testid=\"search-selectfilter-next\"\n >\n {label ? (\n <InputLabel className={classes.label} margin=\"dense\">\n {label}\n </InputLabel>\n ) : null}\n <Select\n variant=\"outlined\"\n value={filters[name] || ''}\n onChange={handleChange}\n >\n <MenuItem value=\"\">\n <em>All</em>\n </MenuItem>\n {values.map((value: string) => (\n <MenuItem key={value} value={value}>\n {value}\n </MenuItem>\n ))}\n </Select>\n </FormControl>\n );\n};\n\n/**\n * @public\n */\nconst SearchFilter = ({\n component: Element,\n ...props\n}: SearchFilterWrapperProps) => <Element {...props} />;\n\nSearchFilter.Checkbox = (\n props: Omit<SearchFilterWrapperProps, 'component'> &\n SearchFilterComponentProps,\n) => <SearchFilter {...props} component={CheckboxFilter} />;\n\nSearchFilter.Select = (\n props: Omit<SearchFilterWrapperProps, 'component'> &\n SearchFilterComponentProps,\n) => <SearchFilter {...props} component={SelectFilter} />;\n\n/**\n * A control surface for a given filter field name, rendered as an autocomplete\n * textfield. A hard-coded list of values may be provided, or an async function\n * which returns values may be provided instead.\n *\n * @public\n */\nSearchFilter.Autocomplete = (props: SearchAutocompleteFilterProps) => (\n <SearchFilter {...props} component={AutocompleteFilter} />\n);\n\nexport { SearchFilter };\n","/*\n * Copyright 2022 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 */\n\nimport React from 'react';\n\nimport {\n EmptyState,\n Progress,\n ResponseErrorPanel,\n} from '@backstage/core-components';\nimport { AnalyticsContext } from '@backstage/core-plugin-api';\nimport { SearchResult } from '@backstage/plugin-search-common';\n\nimport { useSearch } from '../../context';\n\n/**\n * Props for {@link SearchResultComponent}\n *\n * @public\n */\nexport type SearchResultProps = {\n children: (results: { results: SearchResult[] }) => JSX.Element;\n};\n\n/**\n * A component returning the search result.\n *\n * @public\n */\nexport const SearchResultComponent = ({ children }: SearchResultProps) => {\n const {\n result: { loading, error, value },\n } = useSearch();\n\n if (loading) {\n return <Progress />;\n }\n if (error) {\n return (\n <ResponseErrorPanel\n title=\"Error encountered while fetching search results\"\n error={error}\n />\n );\n }\n\n if (!value?.results.length) {\n return <EmptyState missing=\"data\" title=\"Sorry, no results were found\" />;\n }\n\n return <>{children({ results: value.results })}</>;\n};\n\n/**\n * @public\n */\nconst HigherOrderSearchResult = (props: SearchResultProps) => {\n return (\n <AnalyticsContext\n attributes={{\n pluginId: 'search',\n extension: 'SearchResult',\n }}\n >\n <SearchResultComponent {...props} />\n </AnalyticsContext>\n );\n};\n\nexport { HigherOrderSearchResult as SearchResult };\n","/*\n * Copyright 2022 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 */\n\nimport React from 'react';\n\nimport { Button, makeStyles } from '@material-ui/core';\nimport ArrowBackIosIcon from '@material-ui/icons/ArrowBackIos';\nimport ArrowForwardIosIcon from '@material-ui/icons/ArrowForwardIos';\n\nimport { useSearch } from '../../context';\n\nconst useStyles = makeStyles(theme => ({\n root: {\n display: 'flex',\n justifyContent: 'space-between',\n gap: theme.spacing(2),\n margin: theme.spacing(2, 0),\n },\n}));\n\n/**\n * @public\n */\nexport const SearchResultPager = () => {\n const { fetchNextPage, fetchPreviousPage } = useSearch();\n const classes = useStyles();\n\n if (!fetchNextPage && !fetchPreviousPage) {\n return <></>;\n }\n\n return (\n <nav arial-label=\"pagination navigation\" className={classes.root}>\n <Button\n aria-label=\"previous page\"\n disabled={!fetchPreviousPage}\n onClick={fetchPreviousPage}\n startIcon={<ArrowBackIosIcon />}\n >\n Previous\n </Button>\n\n <Button\n aria-label=\"next page\"\n disabled={!fetchNextPage}\n onClick={fetchNextPage}\n endIcon={<ArrowForwardIosIcon />}\n >\n Next\n </Button>\n </nav>\n );\n};\n","/*\n * Copyright 2022 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 */\n\nimport React, { useEffect } from 'react';\nimport { useAnalytics } from '@backstage/core-plugin-api';\nimport { useSearch } from '../../context';\n\n/**\n * Capture search event on term change.\n */\nexport const TrackSearch = ({ children }: { children: React.ReactChild }) => {\n const analytics = useAnalytics();\n const { term } = useSearch();\n\n useEffect(() => {\n if (term) {\n // Capture analytics search event with search term provided as value\n analytics.captureEvent('search', term);\n }\n }, [analytics, term]);\n\n return <>{children}</>;\n};\n","/*\n * Copyright 2022 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 */\n\nimport React, {\n ChangeEvent,\n KeyboardEvent,\n useState,\n useEffect,\n useCallback,\n} from 'react';\nimport useDebounce from 'react-use/lib/useDebounce';\nimport {\n InputBase,\n InputBaseProps,\n InputAdornment,\n IconButton,\n} from '@material-ui/core';\nimport SearchIcon from '@material-ui/icons/Search';\nimport ClearButton from '@material-ui/icons/Clear';\n\nimport {\n AnalyticsContext,\n configApiRef,\n useApi,\n} from '@backstage/core-plugin-api';\n\nimport {\n SearchContextProvider,\n useSearch,\n useSearchContextCheck,\n} from '../../context';\nimport { TrackSearch } from '../SearchTracker';\n\n/**\n * Props for {@link SearchBarBase}.\n *\n * @public\n */\nexport type SearchBarBaseProps = Omit<InputBaseProps, 'onChange'> & {\n debounceTime?: number;\n clearButton?: boolean;\n onClear?: () => void;\n onSubmit?: () => void;\n onChange: (value: string) => void;\n};\n\n/**\n * All search boxes exported by the search plugin are based on the <SearchBarBase />,\n * and this one is based on the <InputBase /> component from Material UI.\n * Recommended if you don't use Search Provider or Search Context.\n *\n * @public\n */\nexport const SearchBarBase = ({\n onChange,\n onKeyDown,\n onSubmit,\n debounceTime = 200,\n clearButton = true,\n fullWidth = true,\n value: defaultValue,\n inputProps: defaultInputProps = {},\n endAdornment: defaultEndAdornment,\n ...props\n}: SearchBarBaseProps) => {\n const configApi = useApi(configApiRef);\n const [value, setValue] = useState<string>(defaultValue as string);\n const hasSearchContext = useSearchContextCheck();\n\n useEffect(() => {\n setValue(prevValue =>\n prevValue !== defaultValue ? (defaultValue as string) : prevValue,\n );\n }, [defaultValue]);\n\n useDebounce(() => onChange(value), debounceTime, [value]);\n\n const handleChange = useCallback(\n (e: ChangeEvent<HTMLInputElement>) => {\n setValue(e.target.value);\n },\n [setValue],\n );\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent<HTMLInputElement>) => {\n if (onKeyDown) onKeyDown(e);\n if (onSubmit && e.key === 'Enter') {\n onSubmit();\n }\n },\n [onKeyDown, onSubmit],\n );\n\n const handleClear = useCallback(() => {\n onChange('');\n }, [onChange]);\n\n const placeholder = `Search in ${\n configApi.getOptionalString('app.title') || 'Backstage'\n }`;\n\n const startAdornment = (\n <InputAdornment position=\"start\">\n <IconButton aria-label=\"Query\" disabled>\n <SearchIcon />\n </IconButton>\n </InputAdornment>\n );\n\n const endAdornment = (\n <InputAdornment position=\"end\">\n <IconButton aria-label=\"Clear\" onClick={handleClear}>\n <ClearButton />\n </IconButton>\n </InputAdornment>\n );\n\n const searchBar = (\n <TrackSearch>\n <InputBase\n data-testid=\"search-bar-next\"\n value={value}\n placeholder={placeholder}\n startAdornment={startAdornment}\n endAdornment={clearButton ? endAdornment : defaultEndAdornment}\n inputProps={{ 'aria-label': 'Search', ...defaultInputProps }}\n fullWidth={fullWidth}\n onChange={handleChange}\n onKeyDown={handleKeyDown}\n {...props}\n />\n </TrackSearch>\n );\n\n return hasSearchContext ? (\n searchBar\n ) : (\n <SearchContextProvider>{searchBar}</SearchContextProvider>\n );\n};\n\n/**\n * Props for {@link SearchBar}.\n *\n * @public\n */\nexport type SearchBarProps = Partial<SearchBarBaseProps>;\n\n/**\n * Recommended search bar when you use the Search Provider or Search Context.\n *\n * @public\n */\nexport const SearchBar = ({ onChange, ...props }: SearchBarProps) => {\n const { term, setTerm } = useSearch();\n\n const handleChange = useCallback(\n (newValue: string) => {\n if (onChange) {\n onChange(newValue);\n } else {\n setTerm(newValue);\n }\n },\n [onChange, setTerm],\n );\n\n return (\n <AnalyticsContext\n attributes={{ pluginId: 'search', extension: 'SearchBar' }}\n >\n <SearchBarBase value={term} onChange={handleChange} {...props} />\n </AnalyticsContext>\n );\n};\n","/*\n * Copyright 2022 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 */\n\nimport React, { ReactNode } from 'react';\nimport { AnalyticsContext, useAnalytics } from '@backstage/core-plugin-api';\nimport {\n ResultHighlight,\n SearchDocument,\n} from '@backstage/plugin-search-common';\nimport { HighlightedSearchResultText } from '../HighlightedSearchResultText';\nimport {\n ListItem,\n ListItemIcon,\n ListItemText,\n Box,\n Divider,\n} from '@material-ui/core';\nimport { Link } from '@backstage/core-components';\n\n/**\n * Props for {@link DefaultResultListItem}\n *\n * @public\n */\nexport type DefaultResultListItemProps = {\n icon?: ReactNode;\n secondaryAction?: ReactNode;\n result: SearchDocument;\n highlight?: ResultHighlight;\n rank?: number;\n lineClamp?: number;\n};\n\n/**\n * A default result list item.\n *\n * @public\n */\nexport const DefaultResultListItemComponent = ({\n result,\n highlight,\n rank,\n icon,\n secondaryAction,\n lineClamp = 5,\n}: DefaultResultListItemProps) => {\n const analytics = useAnalytics();\n const handleClick = () => {\n analytics.captureEvent('discover', result.title, {\n attributes: { to: result.location },\n value: rank,\n });\n };\n\n return (\n <Link noTrack to={result.location} onClick={handleClick}>\n <ListItem alignItems=\"center\">\n {icon && <ListItemIcon>{icon}</ListItemIcon>}\n <ListItemText\n primaryTypographyProps={{ variant: 'h6' }}\n primary={\n highlight?.fields.title ? (\n <HighlightedSearchResultText\n text={highlight.fields.title}\n preTag={highlight.preTag}\n postTag={highlight.postTag}\n />\n ) : (\n result.title\n )\n }\n secondary={\n <span\n style={{\n display: '-webkit-box',\n WebkitBoxOrient: 'vertical',\n WebkitLineClamp: lineClamp,\n overflow: 'hidden',\n }}\n >\n {highlight?.fields.text ? (\n <HighlightedSearchResultText\n text={highlight.fields.text}\n preTag={highlight.preTag}\n postTag={highlight.postTag}\n />\n ) : (\n result.text\n )}\n </span>\n }\n />\n {secondaryAction && <Box alignItems=\"flex-end\">{secondaryAction}</Box>}\n </ListItem>\n <Divider />\n </Link>\n );\n};\n\n/**\n * @public\n */\nconst HigherOrderDefaultResultListItem = (\n props: DefaultResultListItemProps,\n) => {\n return (\n <AnalyticsContext\n attributes={{\n pluginId: 'search',\n extension: 'DefaultResultListItem',\n }}\n >\n <DefaultResultListItemComponent {...props} />\n </AnalyticsContext>\n );\n};\n\nexport { HigherOrderDefaultResultListItem as DefaultResultListItem };\n"],"names":["useStyles","_a"],"mappings":"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"}
1
+ {"version":3,"file":"index.esm.js","sources":["../src/api.ts","../src/components/HighlightedSearchResultText/HighlightedSearchResultText.tsx","../src/context/SearchContext.tsx","../src/components/SearchTracker/SearchTracker.tsx","../src/components/SearchBar/SearchBar.tsx","../src/components/SearchAutocomplete/SearchAutocomplete.tsx","../src/components/SearchAutocomplete/SearchAutocompleteDefaultOption.tsx","../src/components/SearchFilter/hooks.ts","../src/components/SearchFilter/SearchFilter.Autocomplete.tsx","../src/components/SearchFilter/SearchFilter.tsx","../src/components/SearchResult/SearchResult.tsx","../src/components/SearchResultPager/SearchResultPager.tsx","../src/components/DefaultResultListItem/DefaultResultListItem.tsx"],"sourcesContent":["/*\n * Copyright 2022 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 */\n\nimport { SearchQuery, SearchResultSet } from '@backstage/plugin-search-common';\nimport { createApiRef } from '@backstage/core-plugin-api';\n\n/**\n * @public\n */\nexport const searchApiRef = createApiRef<SearchApi>({\n id: 'plugin.search.queryservice',\n});\n\n/**\n * @public\n */\nexport interface SearchApi {\n query(query: SearchQuery): Promise<SearchResultSet>;\n}\n\n/**\n * @public\n *\n * Search Api Mock that can be used in tests and storybooks\n */\nexport class MockSearchApi implements SearchApi {\n constructor(public mockedResults?: SearchResultSet) {}\n\n query(): Promise<SearchResultSet> {\n return Promise.resolve(this.mockedResults || { results: [] });\n }\n}\n","/*\n * Copyright 2022 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 */\n\nimport React, { useMemo } from 'react';\nimport { makeStyles } from '@material-ui/core';\n\nconst useStyles = makeStyles(\n () => ({\n highlight: {},\n }),\n { name: 'BackstageHighlightedSearchResultText' },\n);\n\n/**\n * Props for {@link HighlightedSearchResultText}.\n *\n * @public\n */\nexport type HighlightedSearchResultTextProps = {\n text: string;\n preTag: string;\n postTag: string;\n};\n\n/**\n * @public\n */\nexport const HighlightedSearchResultText = ({\n text,\n preTag,\n postTag,\n}: HighlightedSearchResultTextProps) => {\n const classes = useStyles();\n const terms = useMemo(\n () => text.split(new RegExp(`(${preTag}.+?${postTag})`)),\n [postTag, preTag, text],\n );\n return (\n <>\n {terms.map((t, idx) =>\n t.includes(preTag) ? (\n <mark className={classes.highlight} key={idx}>\n {t.replace(new RegExp(`${preTag}|${postTag}`, 'g'), '')}\n </mark>\n ) : (\n t\n ),\n )}\n </>\n );\n};\n","/*\n * Copyright 2022 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 */\n\nimport { JsonObject } from '@backstage/types';\nimport { useApi, AnalyticsContext } from '@backstage/core-plugin-api';\nimport { SearchResultSet } from '@backstage/plugin-search-common';\nimport {\n createVersionedContext,\n createVersionedValueMap,\n} from '@backstage/version-bridge';\nimport React, {\n PropsWithChildren,\n useCallback,\n useContext,\n useEffect,\n useState,\n} from 'react';\nimport useAsync, { AsyncState } from 'react-use/lib/useAsync';\nimport usePrevious from 'react-use/lib/usePrevious';\nimport { searchApiRef } from '../api';\n\n/**\n *\n * @public\n */\nexport type SearchContextValue = {\n result: AsyncState<SearchResultSet>;\n setTerm: React.Dispatch<React.SetStateAction<string>>;\n setTypes: React.Dispatch<React.SetStateAction<string[]>>;\n setFilters: React.Dispatch<React.SetStateAction<JsonObject>>;\n setPageCursor: React.Dispatch<React.SetStateAction<string | undefined>>;\n fetchNextPage?: React.DispatchWithoutAction;\n fetchPreviousPage?: React.DispatchWithoutAction;\n} & SearchContextState;\n\n/**\n *\n * @public\n */\nexport type SearchContextState = {\n term: string;\n types: string[];\n filters: JsonObject;\n pageCursor?: string;\n};\n\nconst SearchContext = createVersionedContext<{\n 1: SearchContextValue;\n}>('search-context');\n\n/**\n * @public\n *\n * React hook which provides the search context\n */\nexport const useSearch = () => {\n const context = useContext(SearchContext);\n if (!context) {\n throw new Error('useSearch must be used within a SearchContextProvider');\n }\n\n const value = context.atVersion(1);\n if (!value) {\n throw new Error('No SearchContext v1 found');\n }\n return value;\n};\n\n/**\n * @public\n *\n * React hook which checks for an existing search context\n */\nexport const useSearchContextCheck = () => {\n const context = useContext(SearchContext);\n return context !== undefined;\n};\n\n/**\n * The initial state of `SearchContextProvider`.\n *\n */\nconst searchInitialState: SearchContextState = {\n term: '',\n pageCursor: undefined,\n filters: {},\n types: [],\n};\n\nconst useSearchContextValue = (\n initialValue: SearchContextState = searchInitialState,\n) => {\n const searchApi = useApi(searchApiRef);\n const [pageCursor, setPageCursor] = useState<string | undefined>(\n initialValue.pageCursor,\n );\n const [filters, setFilters] = useState<JsonObject>(initialValue.filters);\n const [term, setTerm] = useState<string>(initialValue.term);\n const [types, setTypes] = useState<string[]>(initialValue.types);\n\n const prevTerm = usePrevious(term);\n\n const result = useAsync(\n () =>\n searchApi.query({\n term,\n filters,\n pageCursor,\n types,\n }),\n [term, filters, types, pageCursor],\n );\n\n const hasNextPage =\n !result.loading && !result.error && result.value?.nextPageCursor;\n const hasPreviousPage =\n !result.loading && !result.error && result.value?.previousPageCursor;\n const fetchNextPage = useCallback(() => {\n setPageCursor(result.value?.nextPageCursor);\n }, [result.value?.nextPageCursor]);\n const fetchPreviousPage = useCallback(() => {\n setPageCursor(result.value?.previousPageCursor);\n }, [result.value?.previousPageCursor]);\n\n useEffect(() => {\n // Any time a term is reset, we want to start from page 0.\n // Only reset the term if it has been modified by the user at least once, the initial state must not reset the term.\n if (prevTerm !== undefined && term !== prevTerm) {\n setPageCursor(undefined);\n }\n }, [term, prevTerm, setPageCursor]);\n\n const value: SearchContextValue = {\n result,\n filters,\n setFilters,\n term,\n setTerm,\n types,\n setTypes,\n pageCursor,\n setPageCursor,\n fetchNextPage: hasNextPage ? fetchNextPage : undefined,\n fetchPreviousPage: hasPreviousPage ? fetchPreviousPage : undefined,\n };\n\n return value;\n};\n\nexport type LocalSearchContextProps = PropsWithChildren<{\n initialState?: SearchContextState;\n}>;\n\nconst LocalSearchContext = (props: SearchContextProviderProps) => {\n const { initialState, children } = props;\n const value = useSearchContextValue(initialState);\n\n return (\n <AnalyticsContext\n attributes={{ searchTypes: value.types.sort().join(',') }}\n >\n <SearchContext.Provider value={createVersionedValueMap({ 1: value })}>\n {children}\n </SearchContext.Provider>\n </AnalyticsContext>\n );\n};\n\n/**\n * Props for {@link SearchContextProvider}\n *\n * @public\n */\nexport type SearchContextProviderProps =\n | PropsWithChildren<{\n /**\n * State initialized by a local context.\n */\n initialState?: SearchContextState;\n /**\n * Do not create an inheritance from the parent, as a new initial state must be defined in a local context.\n */\n inheritParentContextIfAvailable?: never;\n }>\n | PropsWithChildren<{\n /**\n * Does not accept initial state since it is already initialized by parent context.\n */\n initialState?: never;\n /**\n * If true, don't create a child context if there is a parent one already defined.\n * @remarks Defaults to false.\n */\n inheritParentContextIfAvailable?: boolean;\n }>;\n\n/**\n * @public\n * Search context provider which gives you access to shared state between search components\n */\nexport const SearchContextProvider = (props: SearchContextProviderProps) => {\n const { initialState, inheritParentContextIfAvailable, children } = props;\n const hasParentContext = useSearchContextCheck();\n\n return hasParentContext && inheritParentContextIfAvailable ? (\n <>{children}</>\n ) : (\n <LocalSearchContext initialState={initialState}>\n {children}\n </LocalSearchContext>\n );\n};\n","/*\n * Copyright 2022 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 */\n\nimport React, { useEffect } from 'react';\nimport { useAnalytics } from '@backstage/core-plugin-api';\nimport { useSearch } from '../../context';\n\n/**\n * Capture search event on term change.\n */\nexport const TrackSearch = ({ children }: { children: React.ReactChild }) => {\n const analytics = useAnalytics();\n const { term } = useSearch();\n\n useEffect(() => {\n if (term) {\n // Capture analytics search event with search term provided as value\n analytics.captureEvent('search', term);\n }\n }, [analytics, term]);\n\n return <>{children}</>;\n};\n","/*\n * Copyright 2022 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 */\n\nimport React, {\n ChangeEvent,\n KeyboardEvent,\n useState,\n useEffect,\n useCallback,\n forwardRef,\n ComponentType,\n ForwardRefExoticComponent,\n} from 'react';\nimport useDebounce from 'react-use/lib/useDebounce';\n\nimport {\n InputBase,\n InputBaseProps,\n InputAdornment,\n IconButton,\n} from '@material-ui/core';\nimport SearchIcon from '@material-ui/icons/Search';\nimport ClearButton from '@material-ui/icons/Clear';\n\nimport {\n AnalyticsContext,\n configApiRef,\n useApi,\n} from '@backstage/core-plugin-api';\n\nimport { SearchContextProvider, useSearch } from '../../context';\nimport { TrackSearch } from '../SearchTracker';\n\nfunction withContext<T>(Component: ComponentType<T>) {\n return forwardRef<unknown, T>((props, ref) => (\n <SearchContextProvider inheritParentContextIfAvailable>\n <Component {...props} ref={ref} />\n </SearchContextProvider>\n ));\n}\n\n/**\n * Props for {@link SearchBarBase}.\n *\n * @public\n */\nexport type SearchBarBaseProps = Omit<InputBaseProps, 'onChange'> & {\n debounceTime?: number;\n clearButton?: boolean;\n onClear?: () => void;\n onSubmit?: () => void;\n onChange: (value: string) => void;\n};\n\n/**\n * All search boxes exported by the search plugin are based on the <SearchBarBase />,\n * and this one is based on the <InputBase /> component from Material UI.\n * Recommended if you don't use Search Provider or Search Context.\n *\n * @public\n */\nexport const SearchBarBase: ForwardRefExoticComponent<SearchBarBaseProps> =\n withContext(\n forwardRef((props, ref) => {\n const {\n onChange,\n onKeyDown = () => {},\n onClear = () => {},\n onSubmit = () => {},\n debounceTime = 200,\n clearButton = true,\n fullWidth = true,\n value: defaultValue,\n placeholder: defaultPlaceholder,\n inputProps: defaultInputProps = {},\n endAdornment: defaultEndAdornment,\n ...rest\n } = props;\n\n const configApi = useApi(configApiRef);\n const [value, setValue] = useState<string>('');\n\n useEffect(() => {\n setValue(prevValue =>\n prevValue !== defaultValue ? String(defaultValue) : prevValue,\n );\n }, [defaultValue]);\n\n useDebounce(() => onChange(value), debounceTime, [value]);\n\n const handleChange = useCallback(\n (e: ChangeEvent<HTMLInputElement>) => {\n setValue(e.target.value);\n },\n [setValue],\n );\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent<HTMLInputElement>) => {\n if (onKeyDown) onKeyDown(e);\n if (onSubmit && e.key === 'Enter') {\n onSubmit();\n }\n },\n [onKeyDown, onSubmit],\n );\n\n const handleClear = useCallback(() => {\n onChange('');\n if (onClear) {\n onClear();\n }\n }, [onChange, onClear]);\n\n const placeholder =\n defaultPlaceholder ??\n `Search in ${configApi.getOptionalString('app.title') || 'Backstage'}`;\n\n const startAdornment = (\n <InputAdornment position=\"start\">\n <IconButton aria-label=\"Query\" size=\"small\" disabled>\n <SearchIcon />\n </IconButton>\n </InputAdornment>\n );\n\n const endAdornment = (\n <InputAdornment position=\"end\">\n <IconButton aria-label=\"Clear\" size=\"small\" onClick={handleClear}>\n <ClearButton />\n </IconButton>\n </InputAdornment>\n );\n\n return (\n <TrackSearch>\n <InputBase\n data-testid=\"search-bar-next\"\n ref={ref}\n value={value}\n placeholder={placeholder}\n startAdornment={startAdornment}\n endAdornment={clearButton ? endAdornment : defaultEndAdornment}\n inputProps={{ 'aria-label': 'Search', ...defaultInputProps }}\n fullWidth={fullWidth}\n onChange={handleChange}\n onKeyDown={handleKeyDown}\n {...rest}\n />\n </TrackSearch>\n );\n }),\n );\n\n/**\n * Props for {@link SearchBar}.\n *\n * @public\n */\nexport type SearchBarProps = Partial<SearchBarBaseProps>;\n\n/**\n * Recommended search bar when you use the Search Provider or Search Context.\n *\n * @public\n */\nexport const SearchBar: ForwardRefExoticComponent<SearchBarProps> = withContext(\n forwardRef((props, ref) => {\n const { value: initialValue = '', onChange, ...rest } = props;\n\n const { term, setTerm } = useSearch();\n\n useEffect(() => {\n if (initialValue) {\n setTerm(String(initialValue));\n }\n }, [initialValue, setTerm]);\n\n const handleChange = useCallback(\n (newValue: string) => {\n if (onChange) {\n onChange(newValue);\n } else {\n setTerm(newValue);\n }\n },\n [onChange, setTerm],\n );\n\n return (\n <AnalyticsContext\n attributes={{ pluginId: 'search', extension: 'SearchBar' }}\n >\n <SearchBarBase\n {...rest}\n ref={ref}\n value={term}\n onChange={handleChange}\n />\n </AnalyticsContext>\n );\n }),\n);\n","/*\n * Copyright 2022 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 */\n\nimport React, { ChangeEvent, useCallback, useMemo } from 'react';\n\nimport { CircularProgress } from '@material-ui/core';\nimport {\n Autocomplete,\n AutocompleteProps,\n AutocompleteChangeDetails,\n AutocompleteChangeReason,\n AutocompleteRenderInputParams,\n} from '@material-ui/lab';\n\nimport { SearchContextProvider, useSearch } from '../../context';\nimport { SearchBar, SearchBarProps } from '../SearchBar';\n\n/**\n * Props for {@link SearchAutocomplete}.\n *\n * @public\n */\nexport type SearchAutocompleteProps<Option> = Omit<\n AutocompleteProps<Option, undefined, undefined, boolean>,\n 'renderInput' | 'disableClearable' | 'multiple'\n> & {\n 'data-testid'?: string;\n inputPlaceholder?: SearchBarProps['placeholder'];\n inputDebounceTime?: SearchBarProps['debounceTime'];\n};\n\n/**\n * Type for {@link SearchAutocomplete}.\n *\n * @public\n */\nexport type SearchAutocompleteComponent = <Option>(\n props: SearchAutocompleteProps<Option>,\n) => JSX.Element;\n\nconst withContext = (\n Component: SearchAutocompleteComponent,\n): SearchAutocompleteComponent => {\n return props => (\n <SearchContextProvider inheritParentContextIfAvailable>\n <Component {...props} />\n </SearchContextProvider>\n );\n};\n\n/**\n * Recommended search autocomplete when you use the Search Provider or Search Context.\n *\n * @public\n */\nexport const SearchAutocomplete = withContext(\n function SearchAutocompleteComponent<Option>(\n props: SearchAutocompleteProps<Option>,\n ) {\n const {\n loading,\n value,\n onChange = () => {},\n options = [],\n getOptionLabel = (option: Option) => String(option),\n inputPlaceholder,\n inputDebounceTime,\n freeSolo = true,\n fullWidth = true,\n clearOnBlur = false,\n 'data-testid': dataTestId = 'search-autocomplete',\n ...rest\n } = props;\n\n const { setTerm } = useSearch();\n\n const getInputValue = useCallback(\n (option?: null | string | Option) => {\n if (!option) return '';\n if (typeof option === 'string') return option;\n return getOptionLabel(option);\n },\n [getOptionLabel],\n );\n\n const inputValue = useMemo(\n () => getInputValue(value),\n [value, getInputValue],\n );\n\n const handleChange = useCallback(\n (\n event: ChangeEvent<{}>,\n option: null | string | Option,\n reason: AutocompleteChangeReason,\n details?: AutocompleteChangeDetails<Option>,\n ) => {\n setTerm(getInputValue(option));\n onChange(event, option, reason, details);\n },\n [getInputValue, setTerm, onChange],\n );\n\n const renderInput = useCallback(\n ({\n InputProps: { ref, endAdornment },\n InputLabelProps,\n ...params\n }: AutocompleteRenderInputParams) => (\n <SearchBar\n {...params}\n ref={ref}\n clearButton={false}\n value={inputValue}\n placeholder={inputPlaceholder}\n debounceTime={inputDebounceTime}\n endAdornment={\n loading ? (\n <CircularProgress\n data-testid=\"search-autocomplete-progressbar\"\n color=\"inherit\"\n size={20}\n />\n ) : (\n endAdornment\n )\n }\n />\n ),\n [loading, inputValue, inputPlaceholder, inputDebounceTime],\n );\n\n return (\n <Autocomplete\n {...rest}\n data-testid={dataTestId}\n value={value}\n onChange={handleChange}\n options={options}\n getOptionLabel={getOptionLabel}\n renderInput={renderInput}\n freeSolo={freeSolo}\n fullWidth={fullWidth}\n clearOnBlur={clearOnBlur}\n />\n );\n },\n);\n","/*\n * Copyright 2022 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 */\n\nimport React, { ReactNode } from 'react';\nimport {\n ListItemIcon,\n ListItemText,\n ListItemTextProps,\n} from '@material-ui/core';\n\n/**\n * Props for {@link SearchAutocompleteDefaultOption}.\n *\n * @public\n */\nexport type SearchAutocompleteDefaultOptionProps = {\n icon?: ReactNode;\n primaryText: ListItemTextProps['primary'];\n primaryTextTypographyProps?: ListItemTextProps['primaryTypographyProps'];\n secondaryText?: ListItemTextProps['secondary'];\n secondaryTextTypographyProps?: ListItemTextProps['secondaryTypographyProps'];\n disableTextTypography?: ListItemTextProps['disableTypography'];\n};\n\n/**\n * A default search autocomplete option component.\n *\n * @public\n */\nexport const SearchAutocompleteDefaultOption = ({\n icon,\n primaryText,\n primaryTextTypographyProps,\n secondaryText,\n secondaryTextTypographyProps,\n disableTextTypography,\n}: SearchAutocompleteDefaultOptionProps) => (\n <>\n {icon ? <ListItemIcon>{icon}</ListItemIcon> : null}\n <ListItemText\n primary={primaryText}\n primaryTypographyProps={primaryTextTypographyProps}\n secondary={secondaryText}\n secondaryTypographyProps={secondaryTextTypographyProps}\n disableTypography={disableTextTypography}\n />\n </>\n);\n","/*\n * Copyright 2022 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 */\n\nimport { useEffect, useRef } from 'react';\nimport useAsyncFn from 'react-use/lib/useAsyncFn';\nimport useDebounce from 'react-use/lib/useDebounce';\n\nimport { useSearch } from '../../context';\n\n/**\n * Utility hook for either asynchronously loading filter values from a given\n * function or synchronously providing a given list of default values.\n *\n * @public\n */\nexport const useAsyncFilterValues = (\n fn: ((partial: string) => Promise<string[]>) | undefined,\n inputValue: string,\n defaultValues: string[] = [],\n debounce: number = 250,\n) => {\n const valuesMemo = useRef<Record<string, string[] | Promise<string[]>>>({});\n const definiteFn = fn || (() => Promise.resolve([]));\n\n const [state, callback] = useAsyncFn(definiteFn, [inputValue], {\n loading: true,\n });\n\n // Do not invoke the given function more than necessary.\n useDebounce(\n () => {\n // Performance optimization: only invoke the callback once per inputValue\n // for the lifetime of the hook/component.\n if (valuesMemo.current[inputValue] === undefined) {\n valuesMemo.current[inputValue] = callback(inputValue).then(values => {\n // Override the value for future immediate returns.\n valuesMemo.current[inputValue] = values;\n return values;\n });\n }\n },\n debounce,\n [callback, inputValue],\n );\n\n // Immediately return the default values if they are provided.\n if (defaultValues.length) {\n return {\n loading: false,\n value: defaultValues,\n };\n }\n\n // Immediately return a memoized value if it is set (and not a promise).\n const possibleValue = valuesMemo.current[inputValue];\n if (Array.isArray(possibleValue)) {\n return {\n loading: false,\n value: possibleValue,\n };\n }\n\n return state;\n};\n\n/**\n * Utility hook for applying a given default value to the search context.\n *\n * @public\n */\nexport const useDefaultFilterValue = (\n name: string,\n defaultValue?: string | string[] | null,\n) => {\n const { setFilters } = useSearch();\n\n useEffect(() => {\n if (defaultValue && [defaultValue].flat().length > 0) {\n setFilters(prevFilters => ({\n ...prevFilters,\n [name]: defaultValue,\n }));\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n};\n","/*\n * Copyright 2022 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 */\n\nimport React, { ChangeEvent, useState } from 'react';\nimport { Chip, TextField } from '@material-ui/core';\nimport {\n Autocomplete,\n AutocompleteGetTagProps,\n AutocompleteRenderInputParams,\n} from '@material-ui/lab';\n\nimport { useSearch } from '../../context';\nimport { useAsyncFilterValues, useDefaultFilterValue } from './hooks';\nimport { SearchFilterComponentProps } from './SearchFilter';\n\n/**\n * @public\n */\nexport type SearchAutocompleteFilterProps = SearchFilterComponentProps & {\n filterSelectedOptions?: boolean;\n limitTags?: number;\n multiple?: boolean;\n};\n\n/**\n * @public\n */\nexport const AutocompleteFilter = (props: SearchAutocompleteFilterProps) => {\n const {\n className,\n defaultValue,\n name,\n values: givenValues,\n valuesDebounceMs,\n label,\n filterSelectedOptions,\n limitTags,\n multiple,\n } = props;\n const [inputValue, setInputValue] = useState<string>('');\n useDefaultFilterValue(name, defaultValue);\n const asyncValues =\n typeof givenValues === 'function' ? givenValues : undefined;\n const defaultValues =\n typeof givenValues === 'function' ? undefined : givenValues;\n const { value: values, loading } = useAsyncFilterValues(\n asyncValues,\n inputValue,\n defaultValues,\n valuesDebounceMs,\n );\n const { filters, setFilters } = useSearch();\n const filterValue =\n (filters[name] as string | string[] | undefined) || (multiple ? [] : null);\n\n // Set new filter values on input change.\n const handleChange = (\n _: ChangeEvent<{}>,\n newValue: string | string[] | null,\n ) => {\n setFilters(prevState => {\n const { [name]: filter, ...others } = prevState;\n\n if (newValue) {\n return { ...others, [name]: newValue };\n }\n return { ...others };\n });\n };\n\n // Provide the input field.\n const renderInput = (params: AutocompleteRenderInputParams) => (\n <TextField\n {...params}\n name=\"search\"\n variant=\"outlined\"\n label={label}\n fullWidth\n />\n );\n\n // Render tags as primary-colored chips.\n const renderTags = (\n tagValue: string[],\n getTagProps: AutocompleteGetTagProps,\n ) =>\n tagValue.map((option: string, index: number) => (\n <Chip label={option} color=\"primary\" {...getTagProps({ index })} />\n ));\n\n return (\n <Autocomplete\n filterSelectedOptions={filterSelectedOptions}\n limitTags={limitTags}\n multiple={multiple}\n className={className}\n id={`${multiple ? 'multi-' : ''}select-filter-${name}--select`}\n options={values || []}\n loading={loading}\n value={filterValue}\n onChange={handleChange}\n onInputChange={(_, newValue) => setInputValue(newValue)}\n renderInput={renderInput}\n renderTags={renderTags}\n />\n );\n};\n","/*\n * Copyright 2022 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 */\n\nimport React, { ReactElement, ChangeEvent } from 'react';\nimport {\n makeStyles,\n FormControl,\n FormControlLabel,\n InputLabel,\n Checkbox,\n Select,\n MenuItem,\n FormLabel,\n} from '@material-ui/core';\n\nimport { useSearch } from '../../context';\nimport {\n AutocompleteFilter,\n SearchAutocompleteFilterProps,\n} from './SearchFilter.Autocomplete';\nimport { useAsyncFilterValues, useDefaultFilterValue } from './hooks';\n\nconst useStyles = makeStyles({\n label: {\n textTransform: 'capitalize',\n },\n});\n\n/**\n * @public\n */\nexport type SearchFilterComponentProps = {\n className?: string;\n name: string;\n label?: string;\n /**\n * Either an array of values directly, or an async function to return a list\n * of values to be used in the filter. In the autocomplete filter, the last\n * input value is provided as an input to allow values to be filtered. This\n * function is debounced and values cached.\n */\n values?: string[] | ((partial: string) => Promise<string[]>);\n defaultValue?: string[] | string | null;\n /**\n * Debounce time in milliseconds, used when values is an async callback.\n * Defaults to 250ms.\n */\n valuesDebounceMs?: number;\n};\n\n/**\n * @public\n */\nexport type SearchFilterWrapperProps = SearchFilterComponentProps & {\n component: (props: SearchFilterComponentProps) => ReactElement;\n debug?: boolean;\n};\n\n/**\n * @public\n */\nexport const CheckboxFilter = (props: SearchFilterComponentProps) => {\n const {\n className,\n defaultValue,\n label,\n name,\n values: givenValues = [],\n valuesDebounceMs,\n } = props;\n const classes = useStyles();\n const { filters, setFilters } = useSearch();\n useDefaultFilterValue(name, defaultValue);\n const asyncValues =\n typeof givenValues === 'function' ? givenValues : undefined;\n const defaultValues =\n typeof givenValues === 'function' ? undefined : givenValues;\n const { value: values = [], loading } = useAsyncFilterValues(\n asyncValues,\n '',\n defaultValues,\n valuesDebounceMs,\n );\n\n const handleChange = (e: ChangeEvent<HTMLInputElement>) => {\n const {\n target: { value, checked },\n } = e;\n\n setFilters(prevFilters => {\n const { [name]: filter, ...others } = prevFilters;\n const rest = ((filter as string[]) || []).filter(i => i !== value);\n const items = checked ? [...rest, value] : rest;\n return items.length ? { ...others, [name]: items } : others;\n });\n };\n\n return (\n <FormControl\n className={className}\n disabled={loading}\n fullWidth\n data-testid=\"search-checkboxfilter-next\"\n >\n {label ? <FormLabel className={classes.label}>{label}</FormLabel> : null}\n {values.map((value: string) => (\n <FormControlLabel\n key={value}\n control={\n <Checkbox\n color=\"primary\"\n tabIndex={-1}\n inputProps={{ 'aria-labelledby': value }}\n value={value}\n name={value}\n onChange={handleChange}\n checked={((filters[name] as string[]) ?? []).includes(value)}\n />\n }\n label={value}\n />\n ))}\n </FormControl>\n );\n};\n\n/**\n * @public\n */\nexport const SelectFilter = (props: SearchFilterComponentProps) => {\n const {\n className,\n defaultValue,\n label,\n name,\n values: givenValues,\n valuesDebounceMs,\n } = props;\n const classes = useStyles();\n useDefaultFilterValue(name, defaultValue);\n const asyncValues =\n typeof givenValues === 'function' ? givenValues : undefined;\n const defaultValues =\n typeof givenValues === 'function' ? undefined : givenValues;\n const { value: values = [], loading } = useAsyncFilterValues(\n asyncValues,\n '',\n defaultValues,\n valuesDebounceMs,\n );\n const { filters, setFilters } = useSearch();\n\n const handleChange = (e: ChangeEvent<{ value: unknown }>) => {\n const {\n target: { value },\n } = e;\n\n setFilters(prevFilters => {\n const { [name]: filter, ...others } = prevFilters;\n return value ? { ...others, [name]: value as string } : others;\n });\n };\n\n return (\n <FormControl\n disabled={loading}\n className={className}\n variant=\"filled\"\n fullWidth\n data-testid=\"search-selectfilter-next\"\n >\n {label ? (\n <InputLabel className={classes.label} margin=\"dense\">\n {label}\n </InputLabel>\n ) : null}\n <Select\n variant=\"outlined\"\n value={filters[name] || ''}\n onChange={handleChange}\n >\n <MenuItem value=\"\">\n <em>All</em>\n </MenuItem>\n {values.map((value: string) => (\n <MenuItem key={value} value={value}>\n {value}\n </MenuItem>\n ))}\n </Select>\n </FormControl>\n );\n};\n\n/**\n * @public\n */\nconst SearchFilter = ({\n component: Element,\n ...props\n}: SearchFilterWrapperProps) => <Element {...props} />;\n\nSearchFilter.Checkbox = (\n props: Omit<SearchFilterWrapperProps, 'component'> &\n SearchFilterComponentProps,\n) => <SearchFilter {...props} component={CheckboxFilter} />;\n\nSearchFilter.Select = (\n props: Omit<SearchFilterWrapperProps, 'component'> &\n SearchFilterComponentProps,\n) => <SearchFilter {...props} component={SelectFilter} />;\n\n/**\n * A control surface for a given filter field name, rendered as an autocomplete\n * textfield. A hard-coded list of values may be provided, or an async function\n * which returns values may be provided instead.\n *\n * @public\n */\nSearchFilter.Autocomplete = (props: SearchAutocompleteFilterProps) => (\n <SearchFilter {...props} component={AutocompleteFilter} />\n);\n\nexport { SearchFilter };\n","/*\n * Copyright 2022 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 */\n\nimport React from 'react';\n\nimport {\n EmptyState,\n Progress,\n ResponseErrorPanel,\n} from '@backstage/core-components';\nimport { AnalyticsContext } from '@backstage/core-plugin-api';\nimport { SearchResult } from '@backstage/plugin-search-common';\n\nimport { useSearch } from '../../context';\n\n/**\n * Props for {@link SearchResultComponent}\n *\n * @public\n */\nexport type SearchResultProps = {\n children: (results: { results: SearchResult[] }) => JSX.Element;\n};\n\n/**\n * A component returning the search result.\n *\n * @public\n */\nexport const SearchResultComponent = ({ children }: SearchResultProps) => {\n const {\n result: { loading, error, value },\n } = useSearch();\n\n if (loading) {\n return <Progress />;\n }\n if (error) {\n return (\n <ResponseErrorPanel\n title=\"Error encountered while fetching search results\"\n error={error}\n />\n );\n }\n\n if (!value?.results.length) {\n return <EmptyState missing=\"data\" title=\"Sorry, no results were found\" />;\n }\n\n return <>{children({ results: value.results })}</>;\n};\n\n/**\n * @public\n */\nconst HigherOrderSearchResult = (props: SearchResultProps) => {\n return (\n <AnalyticsContext\n attributes={{\n pluginId: 'search',\n extension: 'SearchResult',\n }}\n >\n <SearchResultComponent {...props} />\n </AnalyticsContext>\n );\n};\n\nexport { HigherOrderSearchResult as SearchResult };\n","/*\n * Copyright 2022 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 */\n\nimport React from 'react';\n\nimport { Button, makeStyles } from '@material-ui/core';\nimport ArrowBackIosIcon from '@material-ui/icons/ArrowBackIos';\nimport ArrowForwardIosIcon from '@material-ui/icons/ArrowForwardIos';\n\nimport { useSearch } from '../../context';\n\nconst useStyles = makeStyles(theme => ({\n root: {\n display: 'flex',\n justifyContent: 'space-between',\n gap: theme.spacing(2),\n margin: theme.spacing(2, 0),\n },\n}));\n\n/**\n * @public\n */\nexport const SearchResultPager = () => {\n const { fetchNextPage, fetchPreviousPage } = useSearch();\n const classes = useStyles();\n\n if (!fetchNextPage && !fetchPreviousPage) {\n return <></>;\n }\n\n return (\n <nav arial-label=\"pagination navigation\" className={classes.root}>\n <Button\n aria-label=\"previous page\"\n disabled={!fetchPreviousPage}\n onClick={fetchPreviousPage}\n startIcon={<ArrowBackIosIcon />}\n >\n Previous\n </Button>\n\n <Button\n aria-label=\"next page\"\n disabled={!fetchNextPage}\n onClick={fetchNextPage}\n endIcon={<ArrowForwardIosIcon />}\n >\n Next\n </Button>\n </nav>\n );\n};\n","/*\n * Copyright 2022 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 */\n\nimport React, { ReactNode } from 'react';\nimport { AnalyticsContext, useAnalytics } from '@backstage/core-plugin-api';\nimport {\n ResultHighlight,\n SearchDocument,\n} from '@backstage/plugin-search-common';\nimport { HighlightedSearchResultText } from '../HighlightedSearchResultText';\nimport {\n ListItem,\n ListItemIcon,\n ListItemText,\n Box,\n Divider,\n} from '@material-ui/core';\nimport { Link } from '@backstage/core-components';\n\n/**\n * Props for {@link DefaultResultListItem}\n *\n * @public\n */\nexport type DefaultResultListItemProps = {\n icon?: ReactNode;\n secondaryAction?: ReactNode;\n result: SearchDocument;\n highlight?: ResultHighlight;\n rank?: number;\n lineClamp?: number;\n};\n\n/**\n * A default result list item.\n *\n * @public\n */\nexport const DefaultResultListItemComponent = ({\n result,\n highlight,\n rank,\n icon,\n secondaryAction,\n lineClamp = 5,\n}: DefaultResultListItemProps) => {\n const analytics = useAnalytics();\n const handleClick = () => {\n analytics.captureEvent('discover', result.title, {\n attributes: { to: result.location },\n value: rank,\n });\n };\n\n return (\n <Link noTrack to={result.location} onClick={handleClick}>\n <ListItem alignItems=\"center\">\n {icon && <ListItemIcon>{icon}</ListItemIcon>}\n <ListItemText\n primaryTypographyProps={{ variant: 'h6' }}\n primary={\n highlight?.fields.title ? (\n <HighlightedSearchResultText\n text={highlight.fields.title}\n preTag={highlight.preTag}\n postTag={highlight.postTag}\n />\n ) : (\n result.title\n )\n }\n secondary={\n <span\n style={{\n display: '-webkit-box',\n WebkitBoxOrient: 'vertical',\n WebkitLineClamp: lineClamp,\n overflow: 'hidden',\n }}\n >\n {highlight?.fields.text ? (\n <HighlightedSearchResultText\n text={highlight.fields.text}\n preTag={highlight.preTag}\n postTag={highlight.postTag}\n />\n ) : (\n result.text\n )}\n </span>\n }\n />\n {secondaryAction && <Box alignItems=\"flex-end\">{secondaryAction}</Box>}\n </ListItem>\n <Divider />\n </Link>\n );\n};\n\n/**\n * @public\n */\nconst HigherOrderDefaultResultListItem = (\n props: DefaultResultListItemProps,\n) => {\n return (\n <AnalyticsContext\n attributes={{\n pluginId: 'search',\n extension: 'DefaultResultListItem',\n }}\n >\n <DefaultResultListItemComponent {...props} />\n </AnalyticsContext>\n );\n};\n\nexport { HigherOrderDefaultResultListItem as DefaultResultListItem };\n"],"names":["useStyles","_a","withContext"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/plugin-search-react",
3
- "version": "1.0.2-next.1",
3
+ "version": "1.1.0-next.2",
4
4
  "main": "dist/index.esm.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "license": "Apache-2.0",
@@ -31,8 +31,8 @@
31
31
  "start": "backstage-cli package start"
32
32
  },
33
33
  "dependencies": {
34
- "@backstage/core-components": "^0.11.1-next.1",
35
- "@backstage/core-plugin-api": "^1.0.6-next.1",
34
+ "@backstage/core-components": "^0.11.1-next.2",
35
+ "@backstage/core-plugin-api": "^1.0.6-next.2",
36
36
  "@backstage/plugin-search-common": "^1.0.1-next.0",
37
37
  "@backstage/theme": "^0.2.16",
38
38
  "@backstage/types": "^1.0.0",
@@ -48,8 +48,9 @@
48
48
  "react-router": "6.0.0-beta.0 || ^6.3.0"
49
49
  },
50
50
  "devDependencies": {
51
- "@backstage/core-app-api": "^1.1.0-next.1",
52
- "@backstage/test-utils": "^1.2.0-next.1",
51
+ "@backstage/cli": "^0.19.0-next.2",
52
+ "@backstage/core-app-api": "^1.1.0-next.2",
53
+ "@backstage/test-utils": "^1.2.0-next.2",
53
54
  "@testing-library/jest-dom": "^5.10.1",
54
55
  "@testing-library/react": "^12.1.3",
55
56
  "@testing-library/react-hooks": "^8.0.0",
@@ -58,5 +59,5 @@
58
59
  "files": [
59
60
  "dist"
60
61
  ],
61
- "gitHead": "64f2e93089b61902a3302933dfec197deb10506c"
62
+ "gitHead": "24f889f173370f060725fcf9404081e40769beb4"
62
63
  }