@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 +30 -0
- package/dist/components/SearchFilter/SearchFilter.Autocomplete.esm.js +12 -4
- package/dist/components/SearchFilter/SearchFilter.Autocomplete.esm.js.map +1 -1
- package/dist/components/SearchFilter/SearchFilter.esm.js +10 -9
- package/dist/components/SearchFilter/SearchFilter.esm.js.map +1 -1
- package/dist/components/SearchFilter/hooks.esm.js +8 -2
- package/dist/components/SearchFilter/hooks.esm.js.map +1 -1
- package/dist/components/SearchFilter/types.esm.js +17 -0
- package/dist/components/SearchFilter/types.esm.js.map +1 -0
- package/dist/index.d.ts +14 -2
- package/package.json +13 -13
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
|
|
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 {
|
|
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'
|
|
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":";;;;;;;;;AAyCa,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,EAAM,MAAA,aAAA,GACJ,OAAO,WAAA,KAAgB,UACnB,GAAA,KAAA,CAAA,GACA,aAAa,GAAI,CAAA,CAAA,CAAA,KAAK,0BAA2B,CAAA,CAAC,CAAC,CAAA;AACzD,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,oBAAuB,GAAA,0BAAA;AAAA,IAC3B,QAAQ,IAAI;AAAA,GACd;AACA,EAAA,MAAM,WAAc,GAAA,oBAAA,KAAyB,QAAW,GAAA,EAAK,GAAA,IAAA,CAAA;AAG7D,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,QAAO,OAAA;AAAA,UACL,GAAG,MAAA;AAAA,UACH,CAAC,IAAI,GAAG,KAAA,CAAM,OAAQ,CAAA,QAAQ,CAC1B,GAAA,QAAA,CAAS,GAAI,CAAA,CAAA,CAAA,KAAK,CAAE,CAAA,KAAK,IACzB,QAAS,CAAA;AAAA,SACf;AAAA;AAEF,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,MAAQ,EAAA,KAAA,qBACnB,GAAA,CAAA,IAAA,EAAA,EAAK,OAAO,MAAO,CAAA,KAAA,EAAO,OAAM,SAAW,EAAA,GAAG,YAAY,EAAE,KAAA,EAAO,CAAA,EAAG,CACxE,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,cAAA,EAAgB,YAAU,MAAO,CAAA,KAAA;AAAA,MACjC,WAAA;AAAA,MACA;AAAA;AAAA,GACF;AAEJ;;;;"}
|
|
@@ -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
|
-
|
|
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
|
|
78
|
+
label,
|
|
78
79
|
control: /* @__PURE__ */ jsx(
|
|
79
80
|
Checkbox,
|
|
80
81
|
{
|
|
81
82
|
color: "primary",
|
|
82
|
-
inputProps: { "aria-labelledby":
|
|
83
|
+
inputProps: { "aria-labelledby": label },
|
|
83
84
|
value,
|
|
84
|
-
name:
|
|
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
|
|
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 =
|
|
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<
|
|
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?:
|
|
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.
|
|
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": "
|
|
68
|
-
"@backstage/core-plugin-api": "
|
|
69
|
-
"@backstage/frontend-plugin-api": "
|
|
70
|
-
"@backstage/plugin-search-common": "
|
|
71
|
-
"@backstage/theme": "
|
|
72
|
-
"@backstage/types": "
|
|
73
|
-
"@backstage/version-bridge": "
|
|
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": "
|
|
84
|
-
"@backstage/core-app-api": "
|
|
85
|
-
"@backstage/frontend-app-api": "
|
|
86
|
-
"@backstage/frontend-test-utils": "
|
|
87
|
-
"@backstage/test-utils": "
|
|
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",
|