@databiosphere/findable-ui 42.1.0 → 43.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/.release-please-manifest.json +1 -1
  2. package/CHANGELOG.md +13 -0
  3. package/lib/common/categories/config/range/typeGuards.d.ts +8 -0
  4. package/lib/common/categories/config/range/typeGuards.js +9 -0
  5. package/lib/components/Filter/components/SearchAllFilters/common/constants.d.ts +3 -13
  6. package/lib/components/Filter/components/SearchAllFilters/common/constants.js +12 -36
  7. package/lib/components/Filter/components/SearchAllFilters/components/OutlinedInput/constants.d.ts +2 -0
  8. package/lib/components/Filter/components/SearchAllFilters/components/OutlinedInput/constants.js +7 -0
  9. package/lib/components/Filter/components/SearchAllFilters/components/OutlinedInput/outlinedInput.d.ts +2 -0
  10. package/lib/components/Filter/components/SearchAllFilters/components/OutlinedInput/outlinedInput.js +13 -0
  11. package/lib/components/Filter/components/SearchAllFilters/components/OutlinedInput/utils.d.ts +11 -0
  12. package/lib/components/Filter/components/SearchAllFilters/components/OutlinedInput/utils.js +17 -0
  13. package/lib/components/Filter/components/SearchAllFilters/components/VariableSizeList/VariableSizeList.d.ts +2 -0
  14. package/lib/components/Filter/components/SearchAllFilters/components/VariableSizeList/VariableSizeList.js +9 -10
  15. package/lib/components/Filter/components/SearchAllFilters/context/context.d.ts +2 -0
  16. package/lib/components/Filter/components/SearchAllFilters/context/context.js +10 -0
  17. package/lib/components/Filter/components/SearchAllFilters/context/hook.d.ts +6 -0
  18. package/lib/components/Filter/components/SearchAllFilters/context/hook.js +9 -0
  19. package/lib/components/Filter/components/SearchAllFilters/context/types.d.ts +11 -0
  20. package/lib/components/Filter/components/SearchAllFilters/context/types.js +1 -0
  21. package/lib/components/Filter/components/SearchAllFilters/searchAllFilters.d.ts +2 -19
  22. package/lib/components/Filter/components/SearchAllFilters/searchAllFilters.js +37 -74
  23. package/lib/components/Filter/components/SearchAllFilters/searchAllFilters.styles.d.ts +2 -2
  24. package/lib/components/Filter/components/SearchAllFilters/searchAllFilters.styles.js +7 -8
  25. package/lib/components/Filter/components/SearchAllFilters/stories/args.d.ts +3 -0
  26. package/lib/components/Filter/components/SearchAllFilters/stories/args.js +8 -0
  27. package/lib/components/Filter/components/SearchAllFilters/stories/searchAllFilters.stories.d.ts +6 -0
  28. package/lib/components/Filter/components/SearchAllFilters/stories/searchAllFilters.stories.js +19 -0
  29. package/lib/components/Filter/components/SearchAllFilters/types.d.ts +10 -0
  30. package/lib/components/Filter/components/SearchAllFilters/types.js +1 -0
  31. package/lib/components/Filter/components/adapters/tanstack/ColumnFiltersAdapter/columnFiltersAdapter.js +10 -1
  32. package/lib/components/Filter/components/adapters/tanstack/ColumnFiltersAdapter/types.d.ts +5 -1
  33. package/lib/components/Filter/components/adapters/tanstack/ColumnFiltersAdapter/utils.js +105 -10
  34. package/lib/components/Filter/components/surfaces/popper/Popper/popper.styles.d.ts +6 -0
  35. package/lib/components/Filter/components/surfaces/popper/Popper/popper.styles.js +18 -0
  36. package/lib/components/Filter/components/surfaces/types.d.ts +3 -1
  37. package/lib/components/Filter/components/surfaces/types.js +2 -0
  38. package/lib/styles/common/mui/textField.d.ts +11 -0
  39. package/lib/styles/common/mui/textField.js +22 -0
  40. package/lib/views/ExploreView/exploreView.js +1 -1
  41. package/package.json +1 -1
  42. package/src/common/categories/config/range/typeGuards.ts +14 -0
  43. package/src/components/Filter/components/SearchAllFilters/common/constants.ts +24 -37
  44. package/src/components/Filter/components/SearchAllFilters/components/OutlinedInput/constants.ts +9 -0
  45. package/src/components/Filter/components/SearchAllFilters/components/OutlinedInput/outlinedInput.tsx +31 -0
  46. package/src/components/Filter/components/SearchAllFilters/components/OutlinedInput/utils.ts +22 -0
  47. package/src/components/Filter/components/SearchAllFilters/components/VariableSizeList/VariableSizeList.tsx +12 -13
  48. package/src/components/Filter/components/SearchAllFilters/context/context.ts +12 -0
  49. package/src/components/Filter/components/SearchAllFilters/context/hook.ts +11 -0
  50. package/src/components/Filter/components/SearchAllFilters/context/types.ts +12 -0
  51. package/src/components/Filter/components/SearchAllFilters/searchAllFilters.styles.ts +8 -9
  52. package/src/components/Filter/components/SearchAllFilters/searchAllFilters.tsx +70 -132
  53. package/src/components/Filter/components/SearchAllFilters/stories/args.ts +15 -0
  54. package/src/components/Filter/components/SearchAllFilters/stories/searchAllFilters.stories.tsx +29 -0
  55. package/src/components/Filter/components/SearchAllFilters/types.ts +16 -0
  56. package/src/components/Filter/components/adapters/tanstack/ColumnFiltersAdapter/columnFiltersAdapter.tsx +12 -1
  57. package/src/components/Filter/components/adapters/tanstack/ColumnFiltersAdapter/types.ts +10 -1
  58. package/src/components/Filter/components/adapters/tanstack/ColumnFiltersAdapter/utils.ts +147 -12
  59. package/src/components/Filter/components/surfaces/popper/Popper/popper.styles.ts +20 -0
  60. package/src/components/Filter/components/surfaces/types.ts +2 -0
  61. package/src/styles/common/mui/textField.ts +33 -0
  62. package/src/views/ExploreView/exploreView.tsx +3 -0
  63. package/lib/components/Filter/components/SearchAllFilters/components/AutocompletePopper/autocompletePopper.styles.d.ts +0 -3
  64. package/lib/components/Filter/components/SearchAllFilters/components/AutocompletePopper/autocompletePopper.styles.js +0 -15
  65. package/lib/components/Filter/components/SearchAllFilters/searchAllFilters.stories.d.ts +0 -6
  66. package/lib/components/Filter/components/SearchAllFilters/searchAllFilters.stories.js +0 -82
  67. package/lib/components/Filter/components/SearchAllFiltersSearch/components/SearchCloseButton/searchCloseButton.d.ts +0 -1
  68. package/lib/components/Filter/components/SearchAllFiltersSearch/components/SearchCloseButton/searchCloseButton.js +0 -13
  69. package/lib/components/Filter/components/SearchAllFiltersSearch/searchAllFiltersSearch.d.ts +0 -2
  70. package/lib/components/Filter/components/SearchAllFiltersSearch/searchAllFiltersSearch.js +0 -12
  71. package/lib/components/Filter/components/SearchAllFiltersSearch/searchAllFiltersSearch.styles.d.ts +0 -5
  72. package/lib/components/Filter/components/SearchAllFiltersSearch/searchAllFiltersSearch.styles.js +0 -34
  73. package/src/components/Filter/components/SearchAllFilters/components/AutocompletePopper/autocompletePopper.styles.ts +0 -16
  74. package/src/components/Filter/components/SearchAllFilters/searchAllFilters.stories.tsx +0 -92
  75. package/src/components/Filter/components/SearchAllFiltersSearch/components/SearchCloseButton/searchCloseButton.tsx +0 -25
  76. package/src/components/Filter/components/SearchAllFiltersSearch/searchAllFiltersSearch.styles.ts +0 -35
  77. package/src/components/Filter/components/SearchAllFiltersSearch/searchAllFiltersSearch.tsx +0 -29
@@ -1,17 +1,48 @@
1
+ import { isRangeCategoryConfig } from "../../../../../../common/categories/config/range/typeGuards";
1
2
  import { getColumnHeader } from "../../../../../Table/common/utils";
2
3
  import { getSortedFacetedValues } from "../../../../../Table/featureOptions/facetedColumn/utils";
4
+ /**
5
+ * Adapter for TanStack table to category configs.
6
+ * @param table - Table.
7
+ * @returns Category configs.
8
+ */
9
+ function buildCategoryConfigs(table) {
10
+ return table
11
+ .getAllColumns()
12
+ .filter((column) => column.getCanFilter())
13
+ .map(mapCategoryConfig);
14
+ }
15
+ /**
16
+ * Adapter for TanStack table to category filters.
17
+ * @param table - Table.
18
+ * @param categoryGroups - Category groups.
19
+ * @returns Category filters.
20
+ */
21
+ function buildCategoryFilters(table, categoryGroups) {
22
+ return categoryGroups.reduce((acc, categoryGroup) => {
23
+ const categoryFilter = mapCategoryFilter(table, categoryGroup);
24
+ if (categoryFilter)
25
+ acc.push(categoryFilter);
26
+ return acc;
27
+ }, []);
28
+ }
3
29
  /**
4
30
  * Adapter for TanStack table column filters to category filters.
5
31
  * @param table - Table.
6
32
  * @returns Category filters.
7
33
  */
8
34
  export function buildColumnFilters(table) {
9
- // Build the category views; single category filter.
10
- const categoryViews = table
11
- .getAllColumns()
12
- .filter((column) => column.getCanFilter())
13
- .map(mapColumnToCategoryView);
14
- return [{ categoryViews }];
35
+ const { options } = table;
36
+ const { meta = {} } = options;
37
+ const { categoryGroups } = meta;
38
+ if (!categoryGroups) {
39
+ // Build single category group with all (filterable) columns.
40
+ const categoryConfigs = buildCategoryConfigs(table);
41
+ // Build category filters from single category group.
42
+ return buildCategoryFilters(table, [{ categoryConfigs, label: "" }]);
43
+ }
44
+ // Build category filters from category groups.
45
+ return buildCategoryFilters(table, categoryGroups);
15
46
  }
16
47
  /**
17
48
  * Adapter for TanStack table column filters to selected count.
@@ -24,12 +55,75 @@ export function getColumnFiltersCount(table) {
24
55
  .columnFilters.reduce((acc, columnFilter) => acc + columnFilter.value.length, 0);
25
56
  }
26
57
  /**
27
- * Adapter for TanStack column to category view.
28
- * Currently supports only select category views.
58
+ * Adapter for TanStack column to category config.
59
+ * @param column - Column.
60
+ * @returns Category config.
61
+ */
62
+ function mapCategoryConfig(column) {
63
+ return {
64
+ key: column.id,
65
+ label: getColumnHeader(column),
66
+ };
67
+ }
68
+ /**
69
+ * Adapter for TanStack table to category filter.
70
+ * @param table - Table.
71
+ * @param categoryGroup - Category group.
72
+ * @returns Category filter.
73
+ */
74
+ function mapCategoryFilter(table, categoryGroup) {
75
+ const { categoryConfigs, label } = categoryGroup;
76
+ const categoryViews = categoryConfigs.reduce((acc, categoryConfig) => {
77
+ const column = table.getColumn(categoryConfig.key);
78
+ if (!column)
79
+ return acc;
80
+ if (!column.getCanFilter())
81
+ return acc;
82
+ let categoryView;
83
+ if (isRangeCategoryConfig(categoryConfig)) {
84
+ // Build range category view.
85
+ categoryView = mapColumnToRangeCategoryView(column, categoryConfig);
86
+ }
87
+ else {
88
+ // Build select category view.
89
+ categoryView = mapColumnToSelectCategoryView(column, categoryConfig);
90
+ }
91
+ return [...acc, categoryView];
92
+ }, []);
93
+ if (categoryViews.length === 0)
94
+ return;
95
+ return { categoryViews, label };
96
+ }
97
+ /**
98
+ * Adapter for TanStack column to range category view.
99
+ * @param column - Column.
100
+ * @param categoryConfig - Category config.
101
+ * @returns Range category view.
102
+ */
103
+ function mapColumnToRangeCategoryView(column, categoryConfig) {
104
+ const minMax = column.getFacetedMinMaxValues();
105
+ const isDisabled = !minMax;
106
+ // Selected values for the column.
107
+ const filterValue = (column.getFilterValue() || [null, null]);
108
+ return {
109
+ annotation: undefined,
110
+ isDisabled,
111
+ key: column.id,
112
+ label: getColumnHeader(column),
113
+ max: minMax?.[1] || Infinity,
114
+ min: minMax?.[0] || -Infinity,
115
+ selectedMax: filterValue[1],
116
+ selectedMin: filterValue[0],
117
+ ...categoryConfig,
118
+ };
119
+ }
120
+ /**
121
+ * Adapter for TanStack column to select category view.
29
122
  * @param column - Column.
30
- * @returns Category view.
123
+ * @param categoryConfig - Category config.
124
+ * @returns Select category view.
31
125
  */
32
- function mapColumnToCategoryView(column) {
126
+ function mapColumnToSelectCategoryView(column, categoryConfig) {
33
127
  const facetedUniqueValues = column.getFacetedUniqueValues();
34
128
  const isDisabled = facetedUniqueValues.size === 0;
35
129
  const values = mapColumnToSelectCategoryValueView(column);
@@ -40,6 +134,7 @@ function mapColumnToCategoryView(column) {
40
134
  key: column.id,
41
135
  label: getColumnHeader(column),
42
136
  values,
137
+ ...categoryConfig,
43
138
  };
44
139
  }
45
140
  /**
@@ -0,0 +1,6 @@
1
+ export declare const StyledPopper: import("@emotion/styled").StyledComponent<import("@mui/material").PopperProps & import("react").RefAttributes<HTMLDivElement> & {
2
+ theme?: import("@emotion/react").Theme;
3
+ }, {}, {}>;
4
+ export declare const StyledPopperDrawer: import("@emotion/styled").StyledComponent<import("@mui/material").PopperProps & import("react").RefAttributes<HTMLDivElement> & {
5
+ theme?: import("@emotion/react").Theme;
6
+ }, {}, {}>;
@@ -0,0 +1,18 @@
1
+ import styled from "@emotion/styled";
2
+ import { Popper } from "@mui/material";
3
+ import { PALETTE } from "../../../../../../styles/common/constants/palette";
4
+ export const StyledPopper = styled(Popper) `
5
+ .MuiPaper-root {
6
+ width: 368px;
7
+ }
8
+ `;
9
+ export const StyledPopperDrawer = styled(Popper) `
10
+ .MuiPaper-root {
11
+ background-color: ${PALETTE.SMOKE_LIGHT};
12
+ width: 312px;
13
+
14
+ .MuiList-root {
15
+ margin: 0;
16
+ }
17
+ }
18
+ `;
@@ -7,5 +7,7 @@ export interface SurfaceProps {
7
7
  }
8
8
  export declare enum SURFACE_TYPE {
9
9
  DRAWER = "DRAWER",
10
- MENU = "MENU"
10
+ MENU = "MENU",
11
+ POPPER_DRAWER = "POPPER_DRAWER",
12
+ POPPER_MENU = "POPPER_MENU"
11
13
  }
@@ -2,4 +2,6 @@ export var SURFACE_TYPE;
2
2
  (function (SURFACE_TYPE) {
3
3
  SURFACE_TYPE["DRAWER"] = "DRAWER";
4
4
  SURFACE_TYPE["MENU"] = "MENU";
5
+ SURFACE_TYPE["POPPER_DRAWER"] = "POPPER_DRAWER";
6
+ SURFACE_TYPE["POPPER_MENU"] = "POPPER_MENU";
5
7
  })(SURFACE_TYPE || (SURFACE_TYPE = {}));
@@ -0,0 +1,11 @@
1
+ import { TextFieldProps } from "@mui/material";
2
+ type TextFieldPropsOptions = {
3
+ COLOR: typeof COLOR;
4
+ SIZE: typeof SIZE;
5
+ VARIANT: typeof VARIANT;
6
+ };
7
+ declare const COLOR: Record<string, TextFieldProps["color"]>;
8
+ declare const SIZE: Record<string, TextFieldProps["size"]>;
9
+ declare const VARIANT: Record<string, TextFieldProps["variant"]>;
10
+ export declare const TEXT_FIELD_PROPS: TextFieldPropsOptions;
11
+ export {};
@@ -0,0 +1,22 @@
1
+ const COLOR = {
2
+ ERROR: "error",
3
+ INFO: "info",
4
+ PRIMARY: "primary",
5
+ SECONDARY: "secondary",
6
+ SUCCESS: "success",
7
+ WARNING: "warning",
8
+ };
9
+ const SIZE = {
10
+ MEDIUM: "medium",
11
+ SMALL: "small",
12
+ };
13
+ const VARIANT = {
14
+ FILLED: "filled",
15
+ OUTLINED: "outlined",
16
+ STANDARD: "standard",
17
+ };
18
+ export const TEXT_FIELD_PROPS = {
19
+ COLOR,
20
+ SIZE,
21
+ VARIANT,
22
+ };
@@ -99,7 +99,7 @@ export const ExploreView = (props) => {
99
99
  React.createElement(SidebarTools, { "data-testid": TEST_IDS.FILTER_CONTROLS },
100
100
  React.createElement(SidebarLabel, { label: "Filters" }),
101
101
  React.createElement(ClearAllFilters, null),
102
- React.createElement(SearchAllFilters, { categoryViews: categoryViews, onFilter: onFilterChange.bind(null, true) })),
102
+ React.createElement(SearchAllFilters, { categoryViews: categoryViews, onFilter: onFilterChange.bind(null, true), surfaceType: mdDown ? SURFACE_TYPE.POPPER_DRAWER : SURFACE_TYPE.POPPER_MENU })),
103
103
  React.createElement(Filters, { categoryFilters: categoryFilters, onFilter: onFilterChange.bind(null, false), surfaceType: mdDown ? SURFACE_TYPE.DRAWER : SURFACE_TYPE.MENU, trackFilterOpened: trackingConfig?.trackFilterOpened }))),
104
104
  React.createElement(IndexView, { className: props.className, categoryFilters: categoryFilters, entityListType: entityListType, entityName: label, loading: loading })));
105
105
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@databiosphere/findable-ui",
3
- "version": "42.1.0",
3
+ "version": "43.0.0",
4
4
  "description": "",
5
5
  "scripts": {
6
6
  "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js",
@@ -0,0 +1,14 @@
1
+ import { RangeCategoryView } from "../../views/range/types";
2
+ import { VIEW_KIND } from "../../views/types";
3
+ import { CategoryConfig } from "../types";
4
+
5
+ /**
6
+ * Determine if the given category config is a range category.
7
+ * @param categoryConfig - Category config.
8
+ * @returns True if the category config is a range category, false otherwise.
9
+ */
10
+ export function isRangeCategoryConfig(
11
+ categoryConfig: CategoryConfig
12
+ ): categoryConfig is RangeCategoryView {
13
+ return categoryConfig.viewKind === VIEW_KIND.RANGE;
14
+ }
@@ -1,55 +1,42 @@
1
- import { PaperProps, PopperProps } from "@mui/material";
1
+ import { AutocompleteProps, PaperProps, PopperProps } from "@mui/material";
2
2
  import { DividerItem, ITEM_TYPE, NoResultsItem } from "./entites";
3
3
 
4
4
  export const DEFAULT_LIST_HEIGHT = 0;
5
5
 
6
6
  export const DIVIDER_HEIGHT = 17;
7
7
 
8
- export const DEFAULT_PAPER_PROPS: Partial<PaperProps> = {
9
- sx: {
10
- width: 368,
11
- },
12
- variant: "menu",
13
- };
14
- export const DEFAULT_POPPER_PROPS: Partial<PopperProps> = {
15
- modifiers: [
16
- {
17
- name: "offset",
18
- options: {
19
- offset: [0, 8],
20
- },
21
- },
22
- ],
8
+ const POPPER_MENU_PAPER_PROPS: Partial<PaperProps> = { variant: "menu" };
9
+
10
+ const POPPER_MENU_POPPER_PROPS: Partial<PopperProps> = {
11
+ modifiers: [{ name: "offset", options: { offset: [0, 8] } }],
23
12
  placement: "bottom-start",
24
13
  };
25
14
 
26
- export const DEFAULT_SLOT_PROPS = {
27
- paper: DEFAULT_PAPER_PROPS,
28
- popper: DEFAULT_POPPER_PROPS,
15
+ export const POPPER_MENU_SLOT_PROPS: AutocompleteProps<
16
+ string,
17
+ false,
18
+ false,
19
+ true
20
+ >["slotProps"] = {
21
+ paper: POPPER_MENU_PAPER_PROPS,
22
+ popper: POPPER_MENU_POPPER_PROPS,
29
23
  };
30
24
 
31
- export const DRAWER_PAPER_PROPS: Partial<PaperProps> = {
32
- elevation: 0,
33
- sx: {
34
- width: 312,
35
- },
36
- };
25
+ const POPPER_DRAWER_PAPER_PROPS: Partial<PaperProps> = { elevation: 0 };
37
26
 
38
- export const DRAWER_POPPER_PROPS: Partial<PopperProps> = {
39
- modifiers: [
40
- {
41
- name: "offset",
42
- options: {
43
- offset: [-16, 8],
44
- },
45
- },
46
- ],
27
+ const POPPER_DRAWER_POPPER_PROPS: Partial<PopperProps> = {
28
+ modifiers: [{ name: "offset", options: { offset: [-16, 8] } }],
47
29
  popperOptions: { strategy: "absolute" },
48
30
  };
49
31
 
50
- export const DRAWER_SLOT_PROPS = {
51
- paper: DRAWER_PAPER_PROPS,
52
- popper: DRAWER_POPPER_PROPS,
32
+ export const POPPER_DRAWER_SLOT_PROPS: AutocompleteProps<
33
+ string,
34
+ false,
35
+ false,
36
+ true
37
+ >["slotProps"] = {
38
+ paper: POPPER_DRAWER_PAPER_PROPS,
39
+ popper: POPPER_DRAWER_POPPER_PROPS,
53
40
  };
54
41
 
55
42
  export const DIVIDER_ITEM: DividerItem = {
@@ -0,0 +1,9 @@
1
+ import { OutlinedInputProps } from "@mui/material";
2
+ import { TEXT_FIELD_PROPS as MUI_TEXT_FIELD_PROPS } from "../../../../../../styles/common/mui/textField";
3
+
4
+ export const TEXT_FIELD_PROPS: OutlinedInputProps = {
5
+ color: MUI_TEXT_FIELD_PROPS.COLOR.SECONDARY,
6
+ fullWidth: true,
7
+ placeholder: "Search all filters...",
8
+ size: MUI_TEXT_FIELD_PROPS.SIZE.SMALL,
9
+ };
@@ -0,0 +1,31 @@
1
+ import { AutocompleteRenderInputParams } from "@mui/material";
2
+ import React from "react";
3
+ import { ClearInputAdornment } from "../../../../../common/OutlinedInput/components/InputAdornment/components/ClearInputAdornment/clearInputAdornment";
4
+ import { SearchInputAdornment } from "../../../../../common/OutlinedInput/components/InputAdornment/components/SearchInputAdornment/searchInputAdornment";
5
+ import { StyledOutlinedInput } from "../../../../../common/OutlinedInput/outlinedInput.styles";
6
+ import { useAutocomplete } from "../../context/hook";
7
+ import { TEXT_FIELD_PROPS } from "./constants";
8
+ import { isButtonIn } from "./utils";
9
+
10
+ export const OutlinedInput = (
11
+ props: AutocompleteRenderInputParams
12
+ ): JSX.Element => {
13
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars -- Intended behavior, destructure InputLabelProps, as they are not used on the component.
14
+ const { InputLabelProps, InputProps, ...outlinedInputProps } = props;
15
+ const { onClear, open, searchTerm, surfaceType } = useAutocomplete();
16
+ return (
17
+ <StyledOutlinedInput
18
+ {...TEXT_FIELD_PROPS}
19
+ {...InputProps}
20
+ {...outlinedInputProps}
21
+ endAdornment={
22
+ <ClearInputAdornment
23
+ in={isButtonIn(surfaceType, searchTerm, open)}
24
+ onClick={onClear}
25
+ />
26
+ }
27
+ hasValue={!!searchTerm}
28
+ startAdornment={<SearchInputAdornment />}
29
+ />
30
+ );
31
+ };
@@ -0,0 +1,22 @@
1
+ import { SURFACE_TYPE } from "../../../surfaces/types";
2
+
3
+ /**
4
+ * Returns true if the clear button should display.
5
+ * Displays always for popper drawer surface type when open.
6
+ * Displays when there is a search term for other surface types when open.
7
+ * @param surfaceType - Surface type.
8
+ * @param searchTerm - Search term.
9
+ * @param open - Autocomplete open state.
10
+ * @returns True if the clear button should display.
11
+ */
12
+ export function isButtonIn(
13
+ surfaceType: SURFACE_TYPE,
14
+ searchTerm: string,
15
+ open: boolean
16
+ ): boolean {
17
+ if (!open) return false;
18
+
19
+ if (surfaceType === SURFACE_TYPE.POPPER_DRAWER) return true;
20
+
21
+ return !!searchTerm;
22
+ }
@@ -15,10 +15,6 @@ import {
15
15
  VariableSizeListProps as ListProps,
16
16
  } from "react-window";
17
17
  import { SelectCategoryView } from "../../../../../../common/entities";
18
- import {
19
- BREAKPOINT_FN_NAME,
20
- useBreakpointHelper,
21
- } from "../../../../../../hooks/useBreakpointHelper";
22
18
  import { OnFilterFn } from "../../../../../../hooks/useCategoryFilter";
23
19
  import { useWindowResize } from "../../../../../../hooks/useWindowResize";
24
20
  import {
@@ -29,6 +25,7 @@ import {
29
25
  } from "../../../../common/constants";
30
26
  import { getSortMatchesFn } from "../../../../common/utils";
31
27
  import { StyledList } from "../../../FilterList/filterList.styles";
28
+ import { SURFACE_TYPE } from "../../../surfaces/types";
32
29
  import {
33
30
  DIVIDER_HEIGHT,
34
31
  DIVIDER_ITEM,
@@ -51,6 +48,7 @@ export interface VariableSizeListProps {
51
48
  overscanCount?: ListProps["overscanCount"];
52
49
  searchTerm: string;
53
50
  selectCategoryViews: SelectCategoryView[];
51
+ surfaceType: SURFACE_TYPE;
54
52
  width?: ListProps["width"]; // Width of list; default to 100% width of parent element.
55
53
  }
56
54
 
@@ -125,13 +123,13 @@ export const VariableSizeList = forwardRef<
125
123
  overscanCount = MAX_DISPLAYABLE_LIST_ITEMS * 2,
126
124
  searchTerm,
127
125
  selectCategoryViews,
126
+ surfaceType,
128
127
  width = "100%",
129
128
  }: VariableSizeListProps,
130
129
  autocompleteListRef
131
130
  ): JSX.Element {
132
131
  const filteredItems = applyMenuFilter(selectCategoryViews, searchTerm);
133
132
  let resizeRequired = true;
134
- const bpDownMd = useBreakpointHelper(BREAKPOINT_FN_NAME.DOWN, "md");
135
133
  const { height: windowHeight } = useWindowResize();
136
134
  const [height, setHeight] = useState<number>(initHeight);
137
135
  const itemSizeByItemKeyRef = useRef<ItemSizeByItemKey>(new Map());
@@ -153,10 +151,10 @@ export const VariableSizeList = forwardRef<
153
151
  outerRef.current,
154
152
  innerRef.current,
155
153
  windowHeight,
156
- bpDownMd
154
+ surfaceType
157
155
  )
158
156
  );
159
- }, [bpDownMd, windowHeight]);
157
+ }, [surfaceType, windowHeight]);
160
158
 
161
159
  // Clears VariableSizeList cache (offsets and measurements) when values are updated (filtered).
162
160
  // Facilitates correct positioning of list items when list is updated.
@@ -198,7 +196,7 @@ export const VariableSizeList = forwardRef<
198
196
  outerRef.current,
199
197
  innerRef.current,
200
198
  windowHeight,
201
- bpDownMd
199
+ surfaceType
202
200
  )
203
201
  );
204
202
  }
@@ -266,20 +264,21 @@ function applyMenuFilter(
266
264
  * @param outerListElem - Outer list element to reference list position from.
267
265
  * @param innerListElem - Element containing list items.
268
266
  * @param windowHeight - Window height.
269
- * @param bpDownMd - True if viewport is "md" or smaller.
267
+ * @param surfaceType - Type of surface "POPPER_MENU" or "POPPER_DRAWER".
270
268
  * @returns calculated height.
271
269
  */
272
270
  function calculateListHeight(
273
271
  outerListElem: HTMLDivElement,
274
272
  innerListElem: HTMLUListElement,
275
273
  windowHeight: number,
276
- bpDownMd: boolean
274
+ surfaceType: SURFACE_TYPE
277
275
  ): number {
278
276
  // Calculate max possible list height, based on window height and top position of the list element.
279
277
  const maxHeight = windowHeight - outerListElem.getBoundingClientRect().top;
280
- if (bpDownMd) {
281
- return maxHeight;
282
- }
278
+
279
+ // Return the maximum possible height if the list is in a popper drawer.
280
+ if (surfaceType === SURFACE_TYPE.POPPER_DRAWER) return maxHeight;
281
+
283
282
  // Grab the first and last element in the list.
284
283
  const { firstElementChild: firstListEl, lastElementChild: lastListEl } =
285
284
  innerListElem;
@@ -0,0 +1,12 @@
1
+ import { createContext } from "react";
2
+ import { SURFACE_TYPE } from "../../surfaces/types";
3
+ import { AutocompleteContextProps } from "./types";
4
+
5
+ export const AutocompleteContext = createContext<AutocompleteContextProps>({
6
+ onClear: (): void => undefined,
7
+ onFilter: (): void => undefined,
8
+ open: false,
9
+ searchTerm: "",
10
+ selectCategoryViews: [],
11
+ surfaceType: SURFACE_TYPE.POPPER_MENU,
12
+ });
@@ -0,0 +1,11 @@
1
+ import { useContext } from "react";
2
+ import { AutocompleteContext } from "./context";
3
+ import { AutocompleteContextProps } from "./types";
4
+
5
+ /**
6
+ * Returns autocomplete context.
7
+ * @returns autocomplete context.
8
+ */
9
+ export const useAutocomplete = (): AutocompleteContextProps => {
10
+ return useContext(AutocompleteContext);
11
+ };
@@ -0,0 +1,12 @@
1
+ import { SelectCategoryView } from "../../../../../common/entities";
2
+ import { OnFilterFn } from "../../../../../hooks/useCategoryFilter";
3
+ import { SURFACE_TYPE } from "../../surfaces/types";
4
+
5
+ export interface AutocompleteContextProps {
6
+ onClear: () => void;
7
+ onFilter: OnFilterFn;
8
+ open: boolean;
9
+ searchTerm: string;
10
+ selectCategoryViews: SelectCategoryView[];
11
+ surfaceType: SURFACE_TYPE;
12
+ }
@@ -1,15 +1,14 @@
1
1
  import styled from "@emotion/styled";
2
- import { Autocomplete as MAutocomplete } from "@mui/material";
3
- import { PALETTE } from "../../../../styles/common/constants/palette";
2
+ import { Autocomplete } from "@mui/material";
4
3
 
5
- export const Autocomplete = styled(MAutocomplete)`
6
- &.Mui-expanded {
4
+ export const StyledAutocomplete = styled(Autocomplete)`
5
+ &.MuiAutocomplete-root {
7
6
  .MuiOutlinedInput-root {
8
- .MuiIconButton-root {
9
- .MuiSvgIcon-root {
10
- color: ${PALETTE.INK_MAIN};
11
- }
7
+ padding: 0 12px;
8
+
9
+ .MuiAutocomplete-input {
10
+ padding: 10px 0;
12
11
  }
13
12
  }
14
13
  }
15
- ` as typeof MAutocomplete;
14
+ ` as typeof Autocomplete;