diff --git a/packages/common/src/components/Filter/GroupedEnumFilter.tsx b/packages/common/src/components/Filter/GroupedEnumFilter.tsx
index 733a3e236..2d546564e 100644
--- a/packages/common/src/components/Filter/GroupedEnumFilter.tsx
+++ b/packages/common/src/components/Filter/GroupedEnumFilter.tsx
@@ -11,7 +11,7 @@ import {
import { EnumValue } from '../../utils';
-import { FilterTypeProps } from './types';
+import { FilterTypeProps, InlineFilter } from './types';
/**
* This Filter type enables selecting one or many enum values that are separated by groups.
@@ -40,7 +40,8 @@ export const GroupedEnumFilter = ({
supportedGroups = [],
placeholderLabel,
showFilter = true,
-}: FilterTypeProps) => {
+ hasInlineFilter = false,
+}: FilterTypeProps & InlineFilter) => {
const [isExpanded, setExpanded] = useState(false);
// simplify lookup
@@ -76,6 +77,36 @@ export const GroupedEnumFilter = ({
compareTo: (option) => option.id === id && option.groupId === groupId,
} as SelectOptionObject);
+ const options = supportedGroups.map(({ label, groupId }) => (
+
+ {supportedEnumValues
+ .filter((item) => item.groupId === groupId)
+ .map(({ id, label }) => (
+
+ ))}
+
+ ));
+
+ const onFilter = (_, textInput) => {
+ if (textInput === '') {
+ return options;
+ }
+
+ const filteredGroups = options
+ .map((group) => {
+ const filteredGroup = React.cloneElement(group, {
+ children: group.props.children.filter((item) => {
+ // options are not plain strings but the our toString() method
+ // converts them in a meaningful way
+ return item.props.value.toString().toLowerCase().includes(textInput.toLowerCase());
+ }),
+ });
+ if (filteredGroup.props.children.length > 0) return filteredGroup;
+ })
+ .filter((newGroup) => newGroup);
+ return filteredGroups;
+ };
+
return (
<>
{/**
@@ -123,16 +154,10 @@ export const GroupedEnumFilter = ({
placeholderText={placeholderLabel}
isOpen={isExpanded}
onToggle={setExpanded}
+ hasInlineFilter={hasInlineFilter}
+ onFilter={onFilter}
>
- {supportedGroups.map(({ label, groupId }) => (
-
- {supportedEnumValues
- .filter((item) => item.groupId === groupId)
- .map(({ id, label }) => (
-
- ))}
-
- ))}
+ {options}
,
)}
>
diff --git a/packages/common/src/components/Filter/SearchableGroupedEnumFilter.tsx b/packages/common/src/components/Filter/SearchableGroupedEnumFilter.tsx
new file mode 100644
index 000000000..cea87df6e
--- /dev/null
+++ b/packages/common/src/components/Filter/SearchableGroupedEnumFilter.tsx
@@ -0,0 +1,11 @@
+import React from 'react';
+
+import { GroupedEnumFilter } from './GroupedEnumFilter';
+import { FilterTypeProps } from './types';
+
+/**
+ * GroupedEnumFilter with inline search enabled.
+ */
+export const SearchableGroupedEnumFilter = (props: FilterTypeProps) => (
+
+);
diff --git a/packages/common/src/components/Filter/index.ts b/packages/common/src/components/Filter/index.ts
index 9e6c7c398..14d0286fb 100644
--- a/packages/common/src/components/Filter/index.ts
+++ b/packages/common/src/components/Filter/index.ts
@@ -4,6 +4,7 @@ export * from './DateRangeFilter';
export * from './EnumFilter';
export * from './FreetextFilter';
export * from './GroupedEnumFilter';
+export * from './SearchableGroupedEnumFilter';
export * from './SwitchFilter';
export * from './types';
// @endindex
diff --git a/packages/common/src/components/Filter/types.ts b/packages/common/src/components/Filter/types.ts
index 27a314619..992c85e86 100644
--- a/packages/common/src/components/Filter/types.ts
+++ b/packages/common/src/components/Filter/types.ts
@@ -44,3 +44,7 @@ export interface FilterTypeProps {
/** Text that explains how to use the filter. */
helperText?: string | React.ReactNode;
}
+
+export interface InlineFilter {
+ hasInlineFilter?: boolean;
+}
diff --git a/packages/common/src/components/FilterGroup/matchers.ts b/packages/common/src/components/FilterGroup/matchers.ts
index 6cc517c56..7c3f172ac 100644
--- a/packages/common/src/components/FilterGroup/matchers.ts
+++ b/packages/common/src/components/FilterGroup/matchers.ts
@@ -7,6 +7,7 @@ import {
EnumFilter,
FreetextFilter,
GroupedEnumFilter,
+ SearchableGroupedEnumFilter,
SwitchFilter,
} from '../Filter';
@@ -103,6 +104,11 @@ const groupedEnumMatcher = {
matchValue: enumMatcher.matchValue,
};
+const searchableGroupedEnumMatcher = {
+ filterType: 'searchableGroupedEnum',
+ matchValue: enumMatcher.matchValue,
+};
+
const dateMatcher = {
filterType: 'date',
matchValue: (value: string) => (filter: string) => areSameDayInUTCZero(value, filter),
@@ -122,6 +128,7 @@ export const defaultValueMatchers: ValueMatcher[] = [
freetextMatcher,
enumMatcher,
groupedEnumMatcher,
+ searchableGroupedEnumMatcher,
sliderMatcher,
dateMatcher,
dateRangeMatcher,
@@ -134,6 +141,7 @@ export const defaultSupportedFilters: Record = {
freetext: FreetextFilter,
groupedEnum: GroupedEnumFilter,
slider: SwitchFilter,
+ searchableGroupedEnum: SearchableGroupedEnumFilter,
};
/**