@backstage/plugin-search-react 1.8.8 → 1.9.0-next.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,35 @@
1
1
  # @backstage/plugin-search-react
2
2
 
3
+ ## 1.9.0-next.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies
8
+ - @backstage/core-plugin-api@1.10.7-next.0
9
+ - @backstage/core-components@0.17.2-next.1
10
+ - @backstage/frontend-plugin-api@0.10.2-next.1
11
+ - @backstage/theme@0.6.6-next.0
12
+ - @backstage/types@1.2.1
13
+ - @backstage/version-bridge@1.0.11
14
+ - @backstage/plugin-search-common@1.2.18-next.0
15
+
16
+ ## 1.9.0-next.0
17
+
18
+ ### Minor Changes
19
+
20
+ - 611c941: Allow search filters to provide labels and values separately, and not only values
21
+
22
+ ### Patch Changes
23
+
24
+ - Updated dependencies
25
+ - @backstage/theme@0.6.6-next.0
26
+ - @backstage/core-components@0.17.2-next.0
27
+ - @backstage/frontend-plugin-api@0.10.2-next.0
28
+ - @backstage/core-plugin-api@1.10.6
29
+ - @backstage/types@1.2.1
30
+ - @backstage/version-bridge@1.0.11
31
+ - @backstage/plugin-search-common@1.2.18-next.0
32
+
3
33
  ## 1.8.8
4
34
 
5
35
  ### Patch Changes
@@ -5,6 +5,7 @@ import TextField from '@material-ui/core/TextField';
5
5
  import Autocomplete from '@material-ui/lab/Autocomplete';
6
6
  import { useSearch } from '../../context/SearchContext.esm.js';
7
7
  import { useDefaultFilterValue, useAsyncFilterValues } from './hooks.esm.js';
8
+ import { ensureFilterValueWithLabel } from './types.esm.js';
8
9
 
9
10
  const AutocompleteFilter = (props) => {
10
11
  const {
@@ -21,7 +22,7 @@ const AutocompleteFilter = (props) => {
21
22
  const [inputValue, setInputValue] = useState("");
22
23
  useDefaultFilterValue(name, defaultValue);
23
24
  const asyncValues = typeof givenValues === "function" ? givenValues : void 0;
24
- const defaultValues = typeof givenValues === "function" ? void 0 : givenValues;
25
+ const defaultValues = typeof givenValues === "function" ? void 0 : givenValues?.map((v) => ensureFilterValueWithLabel(v));
25
26
  const { value: values, loading } = useAsyncFilterValues(
26
27
  asyncValues,
27
28
  inputValue,
@@ -29,12 +30,18 @@ const AutocompleteFilter = (props) => {
29
30
  valuesDebounceMs
30
31
  );
31
32
  const { filters, setFilters } = useSearch();
32
- const filterValue = filters[name] || (multiple ? [] : null);
33
+ const filterValueWithLabel = ensureFilterValueWithLabel(
34
+ filters[name]
35
+ );
36
+ const filterValue = filterValueWithLabel || (multiple ? [] : null);
33
37
  const handleChange = (_, newValue) => {
34
38
  setFilters((prevState) => {
35
39
  const { [name]: filter, ...others } = prevState;
36
40
  if (newValue) {
37
- return { ...others, [name]: newValue };
41
+ return {
42
+ ...others,
43
+ [name]: Array.isArray(newValue) ? newValue.map((v) => v.value) : newValue.value
44
+ };
38
45
  }
39
46
  return { ...others };
40
47
  });
@@ -49,7 +56,7 @@ const AutocompleteFilter = (props) => {
49
56
  fullWidth: true
50
57
  }
51
58
  );
52
- const renderTags = (tagValue, getTagProps) => tagValue.map((option, index) => /* @__PURE__ */ jsx(Chip, { label: option, color: "primary", ...getTagProps({ index }) }));
59
+ const renderTags = (tagValue, getTagProps) => tagValue.map((option, index) => /* @__PURE__ */ jsx(Chip, { label: option.label, color: "primary", ...getTagProps({ index }) }));
53
60
  return /* @__PURE__ */ jsx(
54
61
  Autocomplete,
55
62
  {
@@ -63,6 +70,7 @@ const AutocompleteFilter = (props) => {
63
70
  value: filterValue,
64
71
  onChange: handleChange,
65
72
  onInputChange: (_, newValue) => setInputValue(newValue),
73
+ getOptionLabel: (option) => option.label,
66
74
  renderInput,
67
75
  renderTags
68
76
  }
@@ -1 +1 @@
1
- {"version":3,"file":"SearchFilter.Autocomplete.esm.js","sources":["../../../src/components/SearchFilter/SearchFilter.Autocomplete.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 { ChangeEvent, useState } from 'react';\nimport Chip from '@material-ui/core/Chip';\nimport TextField from '@material-ui/core/TextField';\nimport Autocomplete, {\n AutocompleteGetTagProps,\n AutocompleteRenderInputParams,\n} from '@material-ui/lab/Autocomplete';\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"],"names":[],"mappings":";;;;;;;;AAwCa,MAAA,kBAAA,GAAqB,CAAC,KAAyC,KAAA;AAC1E,EAAM,MAAA;AAAA,IACJ,SAAA;AAAA,IACA,YAAA;AAAA,IACA,IAAA;AAAA,IACA,MAAQ,EAAA,WAAA;AAAA,IACR,gBAAA;AAAA,IACA,KAAA;AAAA,IACA,qBAAA;AAAA,IACA,SAAA;AAAA,IACA;AAAA,GACE,GAAA,KAAA;AACJ,EAAA,MAAM,CAAC,UAAA,EAAY,aAAa,CAAA,GAAI,SAAiB,EAAE,CAAA;AACvD,EAAA,qBAAA,CAAsB,MAAM,YAAY,CAAA;AACxC,EAAA,MAAM,WACJ,GAAA,OAAO,WAAgB,KAAA,UAAA,GAAa,WAAc,GAAA,KAAA,CAAA;AACpD,EAAA,MAAM,aACJ,GAAA,OAAO,WAAgB,KAAA,UAAA,GAAa,KAAY,CAAA,GAAA,WAAA;AAClD,EAAA,MAAM,EAAE,KAAA,EAAO,MAAQ,EAAA,OAAA,EAAY,GAAA,oBAAA;AAAA,IACjC,WAAA;AAAA,IACA,UAAA;AAAA,IACA,aAAA;AAAA,IACA;AAAA,GACF;AACA,EAAA,MAAM,EAAE,OAAA,EAAS,UAAW,EAAA,GAAI,SAAU,EAAA;AAC1C,EAAA,MAAM,cACH,OAAQ,CAAA,IAAI,CAAwC,KAAA,QAAA,GAAW,EAAK,GAAA,IAAA,CAAA;AAGvE,EAAM,MAAA,YAAA,GAAe,CACnB,CAAA,EACA,QACG,KAAA;AACH,IAAA,UAAA,CAAW,CAAa,SAAA,KAAA;AACtB,MAAA,MAAM,EAAE,CAAC,IAAI,GAAG,MAAQ,EAAA,GAAG,QAAW,GAAA,SAAA;AAEtC,MAAA,IAAI,QAAU,EAAA;AACZ,QAAA,OAAO,EAAE,GAAG,MAAA,EAAQ,CAAC,IAAI,GAAG,QAAS,EAAA;AAAA;AAEvC,MAAO,OAAA,EAAE,GAAG,MAAO,EAAA;AAAA,KACpB,CAAA;AAAA,GACH;AAGA,EAAM,MAAA,WAAA,GAAc,CAAC,MACnB,qBAAA,GAAA;AAAA,IAAC,SAAA;AAAA,IAAA;AAAA,MACE,GAAG,MAAA;AAAA,MACJ,IAAK,EAAA,QAAA;AAAA,MACL,OAAQ,EAAA,UAAA;AAAA,MACR,KAAA;AAAA,MACA,SAAS,EAAA;AAAA;AAAA,GACX;AAIF,EAAM,MAAA,UAAA,GAAa,CACjB,QACA,EAAA,WAAA,KAEA,SAAS,GAAI,CAAA,CAAC,QAAgB,KAC5B,qBAAA,GAAA,CAAC,QAAK,KAAO,EAAA,MAAA,EAAQ,OAAM,SAAW,EAAA,GAAG,YAAY,EAAE,KAAA,EAAO,CAAA,EAAG,CAClE,CAAA;AAEH,EACE,uBAAA,GAAA;AAAA,IAAC,YAAA;AAAA,IAAA;AAAA,MACC,qBAAA;AAAA,MACA,SAAA;AAAA,MACA,QAAA;AAAA,MACA,SAAA;AAAA,MACA,IAAI,CAAG,EAAA,QAAA,GAAW,QAAW,GAAA,EAAE,iBAAiB,IAAI,CAAA,QAAA,CAAA;AAAA,MACpD,OAAA,EAAS,UAAU,EAAC;AAAA,MACpB,OAAA;AAAA,MACA,KAAO,EAAA,WAAA;AAAA,MACP,QAAU,EAAA,YAAA;AAAA,MACV,aAAe,EAAA,CAAC,CAAG,EAAA,QAAA,KAAa,cAAc,QAAQ,CAAA;AAAA,MACtD,WAAA;AAAA,MACA;AAAA;AAAA,GACF;AAEJ;;;;"}
1
+ {"version":3,"file":"SearchFilter.Autocomplete.esm.js","sources":["../../../src/components/SearchFilter/SearchFilter.Autocomplete.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 { ChangeEvent, useState } from 'react';\nimport Chip from '@material-ui/core/Chip';\nimport TextField from '@material-ui/core/TextField';\nimport Autocomplete, {\n AutocompleteGetTagProps,\n AutocompleteRenderInputParams,\n} from '@material-ui/lab/Autocomplete';\n\nimport { useSearch } from '../../context';\nimport { useAsyncFilterValues, useDefaultFilterValue } from './hooks';\nimport { SearchFilterComponentProps } from './SearchFilter';\nimport { ensureFilterValueWithLabel, FilterValueWithLabel } from './types';\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'\n ? undefined\n : givenValues?.map(v => ensureFilterValueWithLabel(v));\n const { value: values, loading } = useAsyncFilterValues(\n asyncValues,\n inputValue,\n defaultValues,\n valuesDebounceMs,\n );\n const { filters, setFilters } = useSearch();\n const filterValueWithLabel = ensureFilterValueWithLabel(\n filters[name] as string | string[] | undefined,\n );\n const filterValue = filterValueWithLabel || (multiple ? [] : null);\n\n // Set new filter values on input change.\n const handleChange = (\n _: ChangeEvent<{}>,\n newValue: FilterValueWithLabel | FilterValueWithLabel[] | null,\n ) => {\n setFilters(prevState => {\n const { [name]: filter, ...others } = prevState;\n\n if (newValue) {\n return {\n ...others,\n [name]: Array.isArray(newValue)\n ? newValue.map(v => v.value)\n : newValue.value,\n };\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: FilterValueWithLabel[],\n getTagProps: AutocompleteGetTagProps,\n ) =>\n tagValue.map((option, index: number) => (\n <Chip label={option.label} 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 getOptionLabel={option => option.label}\n renderInput={renderInput}\n renderTags={renderTags}\n />\n );\n};\n"],"names":[],"mappings":"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"}
@@ -11,6 +11,7 @@ import { Select } from '@backstage/core-components';
11
11
  import { useSearch } from '../../context/SearchContext.esm.js';
12
12
  import { AutocompleteFilter } from './SearchFilter.Autocomplete.esm.js';
13
13
  import { useDefaultFilterValue, useAsyncFilterValues } from './hooks.esm.js';
14
+ import { ensureFilterValueWithLabel } from './types.esm.js';
14
15
 
15
16
  const useStyles = makeStyles({
16
17
  label: {
@@ -31,7 +32,7 @@ const CheckboxFilter = (props) => {
31
32
  const {
32
33
  className,
33
34
  defaultValue,
34
- label,
35
+ label: formLabel,
35
36
  name,
36
37
  values: givenValues = [],
37
38
  valuesDebounceMs
@@ -40,7 +41,7 @@ const CheckboxFilter = (props) => {
40
41
  const { filters, setFilters } = useSearch();
41
42
  useDefaultFilterValue(name, defaultValue);
42
43
  const asyncValues = typeof givenValues === "function" ? givenValues : void 0;
43
- const defaultValues = typeof givenValues === "function" ? void 0 : givenValues;
44
+ const defaultValues = typeof givenValues === "function" ? void 0 : givenValues.map((v) => ensureFilterValueWithLabel(v));
44
45
  const { value: values = [], loading } = useAsyncFilterValues(
45
46
  asyncValues,
46
47
  "",
@@ -66,22 +67,22 @@ const CheckboxFilter = (props) => {
66
67
  fullWidth: true,
67
68
  "data-testid": "search-checkboxfilter-next",
68
69
  children: [
69
- label ? /* @__PURE__ */ jsx(FormLabel, { className: classes.label, children: label }) : null,
70
- values.map((value) => /* @__PURE__ */ jsx(
70
+ !!formLabel && /* @__PURE__ */ jsx(FormLabel, { className: classes.label, children: formLabel }),
71
+ values.map(({ value, label }) => /* @__PURE__ */ jsx(
71
72
  FormControlLabel,
72
73
  {
73
74
  classes: {
74
75
  root: classes.checkboxWrapper,
75
76
  label: classes.textWrapper
76
77
  },
77
- label: value,
78
+ label,
78
79
  control: /* @__PURE__ */ jsx(
79
80
  Checkbox,
80
81
  {
81
82
  color: "primary",
82
- inputProps: { "aria-labelledby": value },
83
+ inputProps: { "aria-labelledby": label },
83
84
  value,
84
- name: value,
85
+ name: label,
85
86
  onChange: handleChange,
86
87
  checked: (filters[name] ?? []).includes(value)
87
88
  }
@@ -104,7 +105,7 @@ const SelectFilter = (props) => {
104
105
  } = props;
105
106
  useDefaultFilterValue(name, defaultValue);
106
107
  const asyncValues = typeof givenValues === "function" ? givenValues : void 0;
107
- const defaultValues = typeof givenValues === "function" ? void 0 : givenValues;
108
+ const defaultValues = typeof givenValues === "function" ? void 0 : givenValues?.map((v) => ensureFilterValueWithLabel(v));
108
109
  const { value: values = [], loading } = useAsyncFilterValues(
109
110
  asyncValues,
110
111
  "",
@@ -120,7 +121,7 @@ const SelectFilter = (props) => {
120
121
  return value !== allOptionValue.current ? { ...others, [name]: value } : others;
121
122
  });
122
123
  };
123
- const items = [allOption, ...values.map((value) => ({ value, label: value }))];
124
+ const items = [allOption, ...values];
124
125
  return /* @__PURE__ */ jsx(
125
126
  FormControl,
126
127
  {
@@ -1 +1 @@
1
- {"version":3,"file":"SearchFilter.esm.js","sources":["../../../src/components/SearchFilter/SearchFilter.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 { ReactElement, ChangeEvent, useRef } from 'react';\nimport { capitalize } from 'lodash';\nimport { v4 as uuid } from 'uuid';\nimport FormControl from '@material-ui/core/FormControl';\nimport FormControlLabel from '@material-ui/core/FormControlLabel';\nimport Checkbox from '@material-ui/core/Checkbox';\nimport FormLabel from '@material-ui/core/FormLabel';\nimport { makeStyles } from '@material-ui/core/styles';\nimport { Select, SelectedItems } from '@backstage/core-components';\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 checkboxWrapper: {\n display: 'flex',\n alignItems: 'center',\n width: '100%',\n },\n textWrapper: {\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\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 classes={{\n root: classes.checkboxWrapper,\n label: classes.textWrapper,\n }}\n label={value}\n control={\n <Checkbox\n color=\"primary\"\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 />\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 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 allOptionValue = useRef(uuid());\n const allOption = { value: allOptionValue.current, label: 'All' };\n const { filters, setFilters } = useSearch();\n\n const handleChange = (value: SelectedItems) => {\n setFilters(prevFilters => {\n const { [name]: filter, ...others } = prevFilters;\n return value !== allOptionValue.current\n ? { ...others, [name]: value as string }\n : others;\n });\n };\n\n const items = [allOption, ...values.map(value => ({ value, label: value }))];\n\n return (\n <FormControl\n disabled={loading}\n className={className}\n variant=\"filled\"\n fullWidth\n data-testid=\"search-selectfilter-next\"\n >\n <Select\n label={label ?? capitalize(name)}\n selected={(filters[name] || allOptionValue.current) as string}\n onChange={handleChange}\n items={items}\n />\n </FormControl>\n );\n};\n\n/**\n * @public\n */\nconst SearchFilter = (props: SearchFilterWrapperProps) => {\n const { component: Element, ...elementProps } = props;\n return <Element {...elementProps} />;\n};\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"],"names":["uuid"],"mappings":"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"}
1
+ {"version":3,"file":"SearchFilter.esm.js","sources":["../../../src/components/SearchFilter/SearchFilter.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 { ReactElement, ChangeEvent, useRef } from 'react';\nimport { capitalize } from 'lodash';\nimport { v4 as uuid } from 'uuid';\nimport FormControl from '@material-ui/core/FormControl';\nimport FormControlLabel from '@material-ui/core/FormControlLabel';\nimport Checkbox from '@material-ui/core/Checkbox';\nimport FormLabel from '@material-ui/core/FormLabel';\nimport { makeStyles } from '@material-ui/core/styles';\nimport { Select, SelectedItems } from '@backstage/core-components';\n\nimport { useSearch } from '../../context';\nimport {\n AutocompleteFilter,\n SearchAutocompleteFilterProps,\n} from './SearchFilter.Autocomplete';\nimport { useAsyncFilterValues, useDefaultFilterValue } from './hooks';\nimport { ensureFilterValueWithLabel, FilterValue } from './types';\n\nconst useStyles = makeStyles({\n label: {\n textTransform: 'capitalize',\n },\n checkboxWrapper: {\n display: 'flex',\n alignItems: 'center',\n width: '100%',\n },\n textWrapper: {\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\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?: FilterValue[] | ((partial: string) => Promise<FilterValue[]>);\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: formLabel,\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'\n ? undefined\n : givenValues.map(v => ensureFilterValueWithLabel(v));\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 {!!formLabel && (\n <FormLabel className={classes.label}>{formLabel}</FormLabel>\n )}\n {values.map(({ value, label }) => (\n <FormControlLabel\n key={value}\n classes={{\n root: classes.checkboxWrapper,\n label: classes.textWrapper,\n }}\n label={label}\n control={\n <Checkbox\n color=\"primary\"\n inputProps={{ 'aria-labelledby': label }}\n value={value}\n name={label}\n onChange={handleChange}\n checked={((filters[name] as string[]) ?? []).includes(value)}\n />\n }\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 useDefaultFilterValue(name, defaultValue);\n const asyncValues =\n typeof givenValues === 'function' ? givenValues : undefined;\n const defaultValues =\n typeof givenValues === 'function'\n ? undefined\n : givenValues?.map(v => ensureFilterValueWithLabel(v));\n const { value: values = [], loading } = useAsyncFilterValues(\n asyncValues,\n '',\n defaultValues,\n valuesDebounceMs,\n );\n const allOptionValue = useRef(uuid());\n const allOption = { value: allOptionValue.current, label: 'All' };\n const { filters, setFilters } = useSearch();\n\n const handleChange = (value: SelectedItems) => {\n setFilters(prevFilters => {\n const { [name]: filter, ...others } = prevFilters;\n return value !== allOptionValue.current\n ? { ...others, [name]: value as string }\n : others;\n });\n };\n\n const items = [allOption, ...values];\n\n return (\n <FormControl\n disabled={loading}\n className={className}\n variant=\"filled\"\n fullWidth\n data-testid=\"search-selectfilter-next\"\n >\n <Select\n label={label ?? capitalize(name)}\n selected={(filters[name] || allOptionValue.current) as string}\n onChange={handleChange}\n items={items}\n />\n </FormControl>\n );\n};\n\n/**\n * @public\n */\nconst SearchFilter = (props: SearchFilterWrapperProps) => {\n const { component: Element, ...elementProps } = props;\n return <Element {...elementProps} />;\n};\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"],"names":["uuid"],"mappings":"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"}
@@ -1,11 +1,17 @@
1
- import { useRef, useEffect } from 'react';
1
+ import { useRef, useCallback, useEffect } from 'react';
2
2
  import useAsyncFn from 'react-use/esm/useAsyncFn';
3
3
  import useDebounce from 'react-use/esm/useDebounce';
4
4
  import { useSearch } from '../../context/SearchContext.esm.js';
5
+ import { ensureFilterValueWithLabel } from './types.esm.js';
5
6
 
6
7
  const useAsyncFilterValues = (fn, inputValue, defaultValues = [], debounce = 250) => {
7
8
  const valuesMemo = useRef({});
8
- const definiteFn = fn || (() => Promise.resolve([]));
9
+ const definiteFn = useCallback(
10
+ async (partial) => {
11
+ return (await fn?.(partial))?.map((v) => ensureFilterValueWithLabel(v)) || [];
12
+ },
13
+ [fn]
14
+ );
9
15
  const [state, callback] = useAsyncFn(definiteFn, [inputValue], {
10
16
  loading: true
11
17
  });
@@ -1 +1 @@
1
- {"version":3,"file":"hooks.esm.js","sources":["../../../src/components/SearchFilter/hooks.ts"],"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 { useEffect, useRef } from 'react';\nimport useAsyncFn from 'react-use/esm/useAsyncFn';\nimport useDebounce from 'react-use/esm/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"],"names":[],"mappings":";;;;;AA4Ba,MAAA,oBAAA,GAAuB,CAClC,EACA,EAAA,UAAA,EACA,gBAA0B,EAAC,EAC3B,WAAmB,GAChB,KAAA;AACH,EAAM,MAAA,UAAA,GAAa,MAAqD,CAAA,EAAE,CAAA;AAC1E,EAAA,MAAM,aAAa,EAAO,KAAA,MAAM,OAAQ,CAAA,OAAA,CAAQ,EAAE,CAAA,CAAA;AAElD,EAAM,MAAA,CAAC,OAAO,QAAQ,CAAA,GAAI,WAAW,UAAY,EAAA,CAAC,UAAU,CAAG,EAAA;AAAA,IAC7D,OAAS,EAAA;AAAA,GACV,CAAA;AAGD,EAAA,WAAA;AAAA,IACE,MAAM;AAGJ,MAAA,IAAI,UAAW,CAAA,OAAA,CAAQ,UAAU,CAAA,KAAM,KAAW,CAAA,EAAA;AAChD,QAAA,UAAA,CAAW,QAAQ,UAAU,CAAA,GAAI,SAAS,UAAU,CAAA,CAAE,KAAK,CAAU,MAAA,KAAA;AAEnE,UAAW,UAAA,CAAA,OAAA,CAAQ,UAAU,CAAI,GAAA,MAAA;AACjC,UAAO,OAAA,MAAA;AAAA,SACR,CAAA;AAAA;AACH,KACF;AAAA,IACA,QAAA;AAAA,IACA,CAAC,UAAU,UAAU;AAAA,GACvB;AAGA,EAAA,IAAI,cAAc,MAAQ,EAAA;AACxB,IAAO,OAAA;AAAA,MACL,OAAS,EAAA,KAAA;AAAA,MACT,KAAO,EAAA;AAAA,KACT;AAAA;AAIF,EAAM,MAAA,aAAA,GAAgB,UAAW,CAAA,OAAA,CAAQ,UAAU,CAAA;AACnD,EAAI,IAAA,KAAA,CAAM,OAAQ,CAAA,aAAa,CAAG,EAAA;AAChC,IAAO,OAAA;AAAA,MACL,OAAS,EAAA,KAAA;AAAA,MACT,KAAO,EAAA;AAAA,KACT;AAAA;AAGF,EAAO,OAAA,KAAA;AACT;AAOa,MAAA,qBAAA,GAAwB,CACnC,IAAA,EACA,YACG,KAAA;AACH,EAAM,MAAA,EAAE,UAAW,EAAA,GAAI,SAAU,EAAA;AAEjC,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,gBAAgB,CAAC,YAAY,EAAE,IAAK,EAAA,CAAE,SAAS,CAAG,EAAA;AACpD,MAAA,UAAA,CAAW,CAAgB,WAAA,MAAA;AAAA,QACzB,GAAG,WAAA;AAAA,QACH,CAAC,IAAI,GAAG;AAAA,OACR,CAAA,CAAA;AAAA;AACJ,GAEF,EAAG,EAAE,CAAA;AACP;;;;"}
1
+ {"version":3,"file":"hooks.esm.js","sources":["../../../src/components/SearchFilter/hooks.ts"],"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 { useCallback, useEffect, useRef } from 'react';\nimport useAsyncFn from 'react-use/esm/useAsyncFn';\nimport useDebounce from 'react-use/esm/useDebounce';\n\nimport { useSearch } from '../../context';\nimport {\n ensureFilterValueWithLabel,\n FilterValue,\n FilterValueWithLabel,\n} from './types';\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<FilterValue[]>) | undefined,\n inputValue: string,\n defaultValues: FilterValueWithLabel[] = [],\n debounce: number = 250,\n) => {\n const valuesMemo = useRef<\n Record<string, FilterValueWithLabel[] | Promise<FilterValueWithLabel[]>>\n >({});\n const definiteFn = useCallback(\n async (partial: string) => {\n return (\n (await fn?.(partial))?.map(v => ensureFilterValueWithLabel(v)) || []\n );\n },\n [fn],\n );\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"],"names":[],"mappings":";;;;;;AAiCa,MAAA,oBAAA,GAAuB,CAClC,EACA,EAAA,UAAA,EACA,gBAAwC,EAAC,EACzC,WAAmB,GAChB,KAAA;AACH,EAAM,MAAA,UAAA,GAAa,MAEjB,CAAA,EAAE,CAAA;AACJ,EAAA,MAAM,UAAa,GAAA,WAAA;AAAA,IACjB,OAAO,OAAoB,KAAA;AACzB,MACG,OAAA,CAAA,MAAM,EAAK,GAAA,OAAO,CAAI,GAAA,GAAA,CAAI,OAAK,0BAA2B,CAAA,CAAC,CAAC,CAAA,IAAK,EAAC;AAAA,KAEvE;AAAA,IACA,CAAC,EAAE;AAAA,GACL;AAEA,EAAM,MAAA,CAAC,OAAO,QAAQ,CAAA,GAAI,WAAW,UAAY,EAAA,CAAC,UAAU,CAAG,EAAA;AAAA,IAC7D,OAAS,EAAA;AAAA,GACV,CAAA;AAGD,EAAA,WAAA;AAAA,IACE,MAAM;AAGJ,MAAA,IAAI,UAAW,CAAA,OAAA,CAAQ,UAAU,CAAA,KAAM,KAAW,CAAA,EAAA;AAChD,QAAA,UAAA,CAAW,QAAQ,UAAU,CAAA,GAAI,SAAS,UAAU,CAAA,CAAE,KAAK,CAAU,MAAA,KAAA;AAEnE,UAAW,UAAA,CAAA,OAAA,CAAQ,UAAU,CAAI,GAAA,MAAA;AACjC,UAAO,OAAA,MAAA;AAAA,SACR,CAAA;AAAA;AACH,KACF;AAAA,IACA,QAAA;AAAA,IACA,CAAC,UAAU,UAAU;AAAA,GACvB;AAGA,EAAA,IAAI,cAAc,MAAQ,EAAA;AACxB,IAAO,OAAA;AAAA,MACL,OAAS,EAAA,KAAA;AAAA,MACT,KAAO,EAAA;AAAA,KACT;AAAA;AAIF,EAAM,MAAA,aAAA,GAAgB,UAAW,CAAA,OAAA,CAAQ,UAAU,CAAA;AACnD,EAAI,IAAA,KAAA,CAAM,OAAQ,CAAA,aAAa,CAAG,EAAA;AAChC,IAAO,OAAA;AAAA,MACL,OAAS,EAAA,KAAA;AAAA,MACT,KAAO,EAAA;AAAA,KACT;AAAA;AAGF,EAAO,OAAA,KAAA;AACT;AAOa,MAAA,qBAAA,GAAwB,CACnC,IAAA,EACA,YACG,KAAA;AACH,EAAM,MAAA,EAAE,UAAW,EAAA,GAAI,SAAU,EAAA;AAEjC,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,gBAAgB,CAAC,YAAY,EAAE,IAAK,EAAA,CAAE,SAAS,CAAG,EAAA;AACpD,MAAA,UAAA,CAAW,CAAgB,WAAA,MAAA;AAAA,QACzB,GAAG,WAAA;AAAA,QACH,CAAC,IAAI,GAAG;AAAA,OACR,CAAA,CAAA;AAAA;AACJ,GAEF,EAAG,EAAE,CAAA;AACP;;;;"}
@@ -0,0 +1,17 @@
1
+ function ensureFilterValueWithLabel(value) {
2
+ if (value === void 0) {
3
+ return void 0;
4
+ }
5
+ if (Array.isArray(value)) {
6
+ return value.map(
7
+ (v) => ensureFilterValueWithLabel(v)
8
+ );
9
+ }
10
+ if (typeof value === "string") {
11
+ return { value, label: value };
12
+ }
13
+ return value;
14
+ }
15
+
16
+ export { ensureFilterValueWithLabel };
17
+ //# sourceMappingURL=types.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.esm.js","sources":["../../../src/components/SearchFilter/types.ts"],"sourcesContent":["/*\n * Copyright 2025 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\n/**\n * @public\n */\nexport type FilterValueWithLabel = { value: string; label: string };\n\n/**\n * @public\n */\nexport type FilterValue = string | FilterValueWithLabel;\n\n/**\n * Ensure a value is on object form, with a label.\n * Accepts undefined, a single value, or an array of values and returns the\n * expected result - a filter value/label or an array of such, if any.\n */\nexport function ensureFilterValueWithLabel<T extends FilterValue>(\n value: T | T[] | undefined,\n): typeof value extends undefined\n ? undefined\n : typeof value extends ArrayLike<any>\n ? FilterValueWithLabel[]\n : FilterValueWithLabel {\n if (value === undefined) {\n return undefined as any;\n }\n\n if (Array.isArray(value)) {\n return value.map(\n v => ensureFilterValueWithLabel(v) as FilterValueWithLabel,\n ) as any;\n }\n\n if (typeof value === 'string') {\n return { value, label: value } as FilterValueWithLabel as any;\n }\n return value as FilterValueWithLabel as any;\n}\n"],"names":[],"mappings":"AA+BO,SAAS,2BACd,KAKuB,EAAA;AACvB,EAAA,IAAI,UAAU,KAAW,CAAA,EAAA;AACvB,IAAO,OAAA,KAAA,CAAA;AAAA;AAGT,EAAI,IAAA,KAAA,CAAM,OAAQ,CAAA,KAAK,CAAG,EAAA;AACxB,IAAA,OAAO,KAAM,CAAA,GAAA;AAAA,MACX,CAAA,CAAA,KAAK,2BAA2B,CAAC;AAAA,KACnC;AAAA;AAGF,EAAI,IAAA,OAAO,UAAU,QAAU,EAAA;AAC7B,IAAO,OAAA,EAAE,KAAO,EAAA,KAAA,EAAO,KAAM,EAAA;AAAA;AAE/B,EAAO,OAAA,KAAA;AACT;;;;"}
package/dist/index.d.ts CHANGED
@@ -198,6 +198,18 @@ type SearchAutocompleteFilterProps = SearchFilterComponentProps & {
198
198
  */
199
199
  declare const AutocompleteFilter: (props: SearchAutocompleteFilterProps) => react_jsx_runtime.JSX.Element;
200
200
 
201
+ /**
202
+ * @public
203
+ */
204
+ type FilterValueWithLabel = {
205
+ value: string;
206
+ label: string;
207
+ };
208
+ /**
209
+ * @public
210
+ */
211
+ type FilterValue = string | FilterValueWithLabel;
212
+
201
213
  /**
202
214
  * @public
203
215
  */
@@ -211,7 +223,7 @@ type SearchFilterComponentProps = {
211
223
  * input value is provided as an input to allow values to be filtered. This
212
224
  * function is debounced and values cached.
213
225
  */
214
- values?: string[] | ((partial: string) => Promise<string[]>);
226
+ values?: FilterValue[] | ((partial: string) => Promise<FilterValue[]>);
215
227
  defaultValue?: string[] | string | null;
216
228
  /**
217
229
  * Debounce time in milliseconds, used when values is an async callback.
@@ -760,4 +772,4 @@ type SearchContextProviderProps = PropsWithChildren<{
760
772
  */
761
773
  declare const SearchContextProvider: (props: SearchContextProviderProps) => react_jsx_runtime.JSX.Element;
762
774
 
763
- export { AutocompleteFilter, CheckboxFilter, HigherOrderDefaultResultListItem as DefaultResultListItem, type DefaultResultListItemProps, HighlightedSearchResultText, type HighlightedSearchResultTextClassKey, type HighlightedSearchResultTextProps, MockSearchApi, type SearchApi, SearchAutocomplete, type SearchAutocompleteComponent, SearchAutocompleteDefaultOption, type SearchAutocompleteDefaultOptionProps, type SearchAutocompleteFilterProps, type SearchAutocompleteProps, SearchBar, SearchBarBase, type SearchBarBaseProps, type SearchBarProps, SearchContextProvider, type SearchContextProviderProps, type SearchContextState, type SearchContextValue, SearchFilter, type SearchFilterComponentProps, type SearchFilterWrapperProps, SearchPagination, SearchPaginationBase, type SearchPaginationBaseProps, type SearchPaginationLimitOption, type SearchPaginationLimitText, type SearchPaginationProps, SearchResult, SearchResultApi, type SearchResultApiProps, SearchResultComponent, SearchResultContext, type SearchResultContextProps, SearchResultGroup, SearchResultGroupFilterFieldLayout, type SearchResultGroupFilterFieldLayoutProps, type SearchResultGroupFilterFieldPropsWith, SearchResultGroupLayout, type SearchResultGroupLayoutProps, type SearchResultGroupProps, SearchResultGroupSelectFilterField, type SearchResultGroupSelectFilterFieldProps, SearchResultGroupTextFilterField, type SearchResultGroupTextFilterFieldProps, SearchResultList, type SearchResultListItemExtensionOptions, type SearchResultListItemExtensionProps, SearchResultListItemExtensions, type SearchResultListItemExtensionsProps, SearchResultListLayout, type SearchResultListLayoutProps, type SearchResultListProps, SearchResultPager, type SearchResultProps, SearchResultState, type SearchResultStateProps, SelectFilter, createSearchResultListItemExtension, searchApiRef, useSearch, useSearchContextCheck, useSearchResultListItemExtensions };
775
+ export { AutocompleteFilter, CheckboxFilter, HigherOrderDefaultResultListItem as DefaultResultListItem, type DefaultResultListItemProps, type FilterValue, type FilterValueWithLabel, HighlightedSearchResultText, type HighlightedSearchResultTextClassKey, type HighlightedSearchResultTextProps, MockSearchApi, type SearchApi, SearchAutocomplete, type SearchAutocompleteComponent, SearchAutocompleteDefaultOption, type SearchAutocompleteDefaultOptionProps, type SearchAutocompleteFilterProps, type SearchAutocompleteProps, SearchBar, SearchBarBase, type SearchBarBaseProps, type SearchBarProps, SearchContextProvider, type SearchContextProviderProps, type SearchContextState, type SearchContextValue, SearchFilter, type SearchFilterComponentProps, type SearchFilterWrapperProps, SearchPagination, SearchPaginationBase, type SearchPaginationBaseProps, type SearchPaginationLimitOption, type SearchPaginationLimitText, type SearchPaginationProps, SearchResult, SearchResultApi, type SearchResultApiProps, SearchResultComponent, SearchResultContext, type SearchResultContextProps, SearchResultGroup, SearchResultGroupFilterFieldLayout, type SearchResultGroupFilterFieldLayoutProps, type SearchResultGroupFilterFieldPropsWith, SearchResultGroupLayout, type SearchResultGroupLayoutProps, type SearchResultGroupProps, SearchResultGroupSelectFilterField, type SearchResultGroupSelectFilterFieldProps, SearchResultGroupTextFilterField, type SearchResultGroupTextFilterFieldProps, SearchResultList, type SearchResultListItemExtensionOptions, type SearchResultListItemExtensionProps, SearchResultListItemExtensions, type SearchResultListItemExtensionsProps, SearchResultListLayout, type SearchResultListLayoutProps, type SearchResultListProps, SearchResultPager, type SearchResultProps, SearchResultState, type SearchResultStateProps, SelectFilter, createSearchResultListItemExtension, searchApiRef, useSearch, useSearchContextCheck, useSearchResultListItemExtensions };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/plugin-search-react",
3
- "version": "1.8.8",
3
+ "version": "1.9.0-next.1",
4
4
  "backstage": {
5
5
  "role": "web-library",
6
6
  "pluginId": "search",
@@ -64,13 +64,13 @@
64
64
  "test": "backstage-cli package test"
65
65
  },
66
66
  "dependencies": {
67
- "@backstage/core-components": "^0.17.1",
68
- "@backstage/core-plugin-api": "^1.10.6",
69
- "@backstage/frontend-plugin-api": "^0.10.1",
70
- "@backstage/plugin-search-common": "^1.2.17",
71
- "@backstage/theme": "^0.6.5",
72
- "@backstage/types": "^1.2.1",
73
- "@backstage/version-bridge": "^1.0.11",
67
+ "@backstage/core-components": "0.17.2-next.1",
68
+ "@backstage/core-plugin-api": "1.10.7-next.0",
69
+ "@backstage/frontend-plugin-api": "0.10.2-next.1",
70
+ "@backstage/plugin-search-common": "1.2.18-next.0",
71
+ "@backstage/theme": "0.6.6-next.0",
72
+ "@backstage/types": "1.2.1",
73
+ "@backstage/version-bridge": "1.0.11",
74
74
  "@material-ui/core": "^4.12.2",
75
75
  "@material-ui/icons": "^4.9.1",
76
76
  "@material-ui/lab": "4.0.0-alpha.61",
@@ -80,11 +80,11 @@
80
80
  "uuid": "^11.0.2"
81
81
  },
82
82
  "devDependencies": {
83
- "@backstage/cli": "^0.32.0",
84
- "@backstage/core-app-api": "^1.16.1",
85
- "@backstage/frontend-app-api": "^0.11.1",
86
- "@backstage/frontend-test-utils": "^0.3.1",
87
- "@backstage/test-utils": "^1.7.7",
83
+ "@backstage/cli": "0.32.1-next.2",
84
+ "@backstage/core-app-api": "1.16.2-next.0",
85
+ "@backstage/frontend-app-api": "0.11.2-next.2",
86
+ "@backstage/frontend-test-utils": "0.3.2-next.2",
87
+ "@backstage/test-utils": "1.7.8-next.1",
88
88
  "@testing-library/dom": "^10.0.0",
89
89
  "@testing-library/jest-dom": "^6.0.0",
90
90
  "@testing-library/react": "^16.0.0",