@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.
- package/.release-please-manifest.json +1 -1
- package/CHANGELOG.md +13 -0
- package/lib/common/categories/config/range/typeGuards.d.ts +8 -0
- package/lib/common/categories/config/range/typeGuards.js +9 -0
- package/lib/components/Filter/components/SearchAllFilters/common/constants.d.ts +3 -13
- package/lib/components/Filter/components/SearchAllFilters/common/constants.js +12 -36
- package/lib/components/Filter/components/SearchAllFilters/components/OutlinedInput/constants.d.ts +2 -0
- package/lib/components/Filter/components/SearchAllFilters/components/OutlinedInput/constants.js +7 -0
- package/lib/components/Filter/components/SearchAllFilters/components/OutlinedInput/outlinedInput.d.ts +2 -0
- package/lib/components/Filter/components/SearchAllFilters/components/OutlinedInput/outlinedInput.js +13 -0
- package/lib/components/Filter/components/SearchAllFilters/components/OutlinedInput/utils.d.ts +11 -0
- package/lib/components/Filter/components/SearchAllFilters/components/OutlinedInput/utils.js +17 -0
- package/lib/components/Filter/components/SearchAllFilters/components/VariableSizeList/VariableSizeList.d.ts +2 -0
- package/lib/components/Filter/components/SearchAllFilters/components/VariableSizeList/VariableSizeList.js +9 -10
- package/lib/components/Filter/components/SearchAllFilters/context/context.d.ts +2 -0
- package/lib/components/Filter/components/SearchAllFilters/context/context.js +10 -0
- package/lib/components/Filter/components/SearchAllFilters/context/hook.d.ts +6 -0
- package/lib/components/Filter/components/SearchAllFilters/context/hook.js +9 -0
- package/lib/components/Filter/components/SearchAllFilters/context/types.d.ts +11 -0
- package/lib/components/Filter/components/SearchAllFilters/context/types.js +1 -0
- package/lib/components/Filter/components/SearchAllFilters/searchAllFilters.d.ts +2 -19
- package/lib/components/Filter/components/SearchAllFilters/searchAllFilters.js +37 -74
- package/lib/components/Filter/components/SearchAllFilters/searchAllFilters.styles.d.ts +2 -2
- package/lib/components/Filter/components/SearchAllFilters/searchAllFilters.styles.js +7 -8
- package/lib/components/Filter/components/SearchAllFilters/stories/args.d.ts +3 -0
- package/lib/components/Filter/components/SearchAllFilters/stories/args.js +8 -0
- package/lib/components/Filter/components/SearchAllFilters/stories/searchAllFilters.stories.d.ts +6 -0
- package/lib/components/Filter/components/SearchAllFilters/stories/searchAllFilters.stories.js +19 -0
- package/lib/components/Filter/components/SearchAllFilters/types.d.ts +10 -0
- package/lib/components/Filter/components/SearchAllFilters/types.js +1 -0
- package/lib/components/Filter/components/adapters/tanstack/ColumnFiltersAdapter/columnFiltersAdapter.js +10 -1
- package/lib/components/Filter/components/adapters/tanstack/ColumnFiltersAdapter/types.d.ts +5 -1
- package/lib/components/Filter/components/adapters/tanstack/ColumnFiltersAdapter/utils.js +105 -10
- package/lib/components/Filter/components/surfaces/popper/Popper/popper.styles.d.ts +6 -0
- package/lib/components/Filter/components/surfaces/popper/Popper/popper.styles.js +18 -0
- package/lib/components/Filter/components/surfaces/types.d.ts +3 -1
- package/lib/components/Filter/components/surfaces/types.js +2 -0
- package/lib/styles/common/mui/textField.d.ts +11 -0
- package/lib/styles/common/mui/textField.js +22 -0
- package/lib/views/ExploreView/exploreView.js +1 -1
- package/package.json +1 -1
- package/src/common/categories/config/range/typeGuards.ts +14 -0
- package/src/components/Filter/components/SearchAllFilters/common/constants.ts +24 -37
- package/src/components/Filter/components/SearchAllFilters/components/OutlinedInput/constants.ts +9 -0
- package/src/components/Filter/components/SearchAllFilters/components/OutlinedInput/outlinedInput.tsx +31 -0
- package/src/components/Filter/components/SearchAllFilters/components/OutlinedInput/utils.ts +22 -0
- package/src/components/Filter/components/SearchAllFilters/components/VariableSizeList/VariableSizeList.tsx +12 -13
- package/src/components/Filter/components/SearchAllFilters/context/context.ts +12 -0
- package/src/components/Filter/components/SearchAllFilters/context/hook.ts +11 -0
- package/src/components/Filter/components/SearchAllFilters/context/types.ts +12 -0
- package/src/components/Filter/components/SearchAllFilters/searchAllFilters.styles.ts +8 -9
- package/src/components/Filter/components/SearchAllFilters/searchAllFilters.tsx +70 -132
- package/src/components/Filter/components/SearchAllFilters/stories/args.ts +15 -0
- package/src/components/Filter/components/SearchAllFilters/stories/searchAllFilters.stories.tsx +29 -0
- package/src/components/Filter/components/SearchAllFilters/types.ts +16 -0
- package/src/components/Filter/components/adapters/tanstack/ColumnFiltersAdapter/columnFiltersAdapter.tsx +12 -1
- package/src/components/Filter/components/adapters/tanstack/ColumnFiltersAdapter/types.ts +10 -1
- package/src/components/Filter/components/adapters/tanstack/ColumnFiltersAdapter/utils.ts +147 -12
- package/src/components/Filter/components/surfaces/popper/Popper/popper.styles.ts +20 -0
- package/src/components/Filter/components/surfaces/types.ts +2 -0
- package/src/styles/common/mui/textField.ts +33 -0
- package/src/views/ExploreView/exploreView.tsx +3 -0
- package/lib/components/Filter/components/SearchAllFilters/components/AutocompletePopper/autocompletePopper.styles.d.ts +0 -3
- package/lib/components/Filter/components/SearchAllFilters/components/AutocompletePopper/autocompletePopper.styles.js +0 -15
- package/lib/components/Filter/components/SearchAllFilters/searchAllFilters.stories.d.ts +0 -6
- package/lib/components/Filter/components/SearchAllFilters/searchAllFilters.stories.js +0 -82
- package/lib/components/Filter/components/SearchAllFiltersSearch/components/SearchCloseButton/searchCloseButton.d.ts +0 -1
- package/lib/components/Filter/components/SearchAllFiltersSearch/components/SearchCloseButton/searchCloseButton.js +0 -13
- package/lib/components/Filter/components/SearchAllFiltersSearch/searchAllFiltersSearch.d.ts +0 -2
- package/lib/components/Filter/components/SearchAllFiltersSearch/searchAllFiltersSearch.js +0 -12
- package/lib/components/Filter/components/SearchAllFiltersSearch/searchAllFiltersSearch.styles.d.ts +0 -5
- package/lib/components/Filter/components/SearchAllFiltersSearch/searchAllFiltersSearch.styles.js +0 -34
- package/src/components/Filter/components/SearchAllFilters/components/AutocompletePopper/autocompletePopper.styles.ts +0 -16
- package/src/components/Filter/components/SearchAllFilters/searchAllFilters.stories.tsx +0 -92
- package/src/components/Filter/components/SearchAllFiltersSearch/components/SearchCloseButton/searchCloseButton.tsx +0 -25
- package/src/components/Filter/components/SearchAllFiltersSearch/searchAllFiltersSearch.styles.ts +0 -35
- package/src/components/Filter/components/SearchAllFiltersSearch/searchAllFiltersSearch.tsx +0 -29
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [43.0.0](https://github.com/DataBiosphere/findable-ui/compare/v42.1.0...v43.0.0) (2025-08-19)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### ⚠ BREAKING CHANGES
|
|
7
|
+
|
|
8
|
+
* add surfacetype prop to searchallfilters ([#636](https://github.com/DataBiosphere/findable-ui/issues/636)) (#637)
|
|
9
|
+
|
|
10
|
+
### Features
|
|
11
|
+
|
|
12
|
+
* add surfacetype prop to searchallfilters ([#636](https://github.com/DataBiosphere/findable-ui/issues/636)) ([#637](https://github.com/DataBiosphere/findable-ui/issues/637)) ([026f522](https://github.com/DataBiosphere/findable-ui/commit/026f522e383dca64903b68859f10997ead191fe9))
|
|
13
|
+
* update columnfiltersadapter to handle grouping of column filters ([#632](https://github.com/DataBiosphere/findable-ui/issues/632)) ([#633](https://github.com/DataBiosphere/findable-ui/issues/633)) ([23c54e9](https://github.com/DataBiosphere/findable-ui/commit/23c54e99a83522d8eef4b2f4b544b3cb3367ce32))
|
|
14
|
+
* update columnfiltersadapter to handle range category filtering ([#634](https://github.com/DataBiosphere/findable-ui/issues/634)) ([#635](https://github.com/DataBiosphere/findable-ui/issues/635)) ([5b5a5b8](https://github.com/DataBiosphere/findable-ui/commit/5b5a5b8d36c2d847f2b97bfbb55f094f5961dbb5))
|
|
15
|
+
|
|
3
16
|
## [42.1.0](https://github.com/DataBiosphere/findable-ui/compare/v42.0.1...v42.1.0) (2025-08-13)
|
|
4
17
|
|
|
5
18
|
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { RangeCategoryView } from "../../views/range/types";
|
|
2
|
+
import { CategoryConfig } from "../types";
|
|
3
|
+
/**
|
|
4
|
+
* Determine if the given category config is a range category.
|
|
5
|
+
* @param categoryConfig - Category config.
|
|
6
|
+
* @returns True if the category config is a range category, false otherwise.
|
|
7
|
+
*/
|
|
8
|
+
export declare function isRangeCategoryConfig(categoryConfig: CategoryConfig): categoryConfig is RangeCategoryView;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { VIEW_KIND } from "../../views/types";
|
|
2
|
+
/**
|
|
3
|
+
* Determine if the given category config is a range category.
|
|
4
|
+
* @param categoryConfig - Category config.
|
|
5
|
+
* @returns True if the category config is a range category, false otherwise.
|
|
6
|
+
*/
|
|
7
|
+
export function isRangeCategoryConfig(categoryConfig) {
|
|
8
|
+
return categoryConfig.viewKind === VIEW_KIND.RANGE;
|
|
9
|
+
}
|
|
@@ -1,18 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { AutocompleteProps } from "@mui/material";
|
|
2
2
|
import { DividerItem, NoResultsItem } from "./entites";
|
|
3
3
|
export declare const DEFAULT_LIST_HEIGHT = 0;
|
|
4
4
|
export declare const DIVIDER_HEIGHT = 17;
|
|
5
|
-
export declare const
|
|
6
|
-
export declare const
|
|
7
|
-
export declare const DEFAULT_SLOT_PROPS: {
|
|
8
|
-
paper: Partial<PaperProps>;
|
|
9
|
-
popper: Partial<PopperProps>;
|
|
10
|
-
};
|
|
11
|
-
export declare const DRAWER_PAPER_PROPS: Partial<PaperProps>;
|
|
12
|
-
export declare const DRAWER_POPPER_PROPS: Partial<PopperProps>;
|
|
13
|
-
export declare const DRAWER_SLOT_PROPS: {
|
|
14
|
-
paper: Partial<PaperProps>;
|
|
15
|
-
popper: Partial<PopperProps>;
|
|
16
|
-
};
|
|
5
|
+
export declare const POPPER_MENU_SLOT_PROPS: AutocompleteProps<string, false, false, true>["slotProps"];
|
|
6
|
+
export declare const POPPER_DRAWER_SLOT_PROPS: AutocompleteProps<string, false, false, true>["slotProps"];
|
|
17
7
|
export declare const DIVIDER_ITEM: DividerItem;
|
|
18
8
|
export declare const NO_RESULTS_ITEM: NoResultsItem;
|
|
@@ -1,47 +1,23 @@
|
|
|
1
1
|
import { ITEM_TYPE } from "./entites";
|
|
2
2
|
export const DEFAULT_LIST_HEIGHT = 0;
|
|
3
3
|
export const DIVIDER_HEIGHT = 17;
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
},
|
|
8
|
-
variant: "menu",
|
|
9
|
-
};
|
|
10
|
-
export const DEFAULT_POPPER_PROPS = {
|
|
11
|
-
modifiers: [
|
|
12
|
-
{
|
|
13
|
-
name: "offset",
|
|
14
|
-
options: {
|
|
15
|
-
offset: [0, 8],
|
|
16
|
-
},
|
|
17
|
-
},
|
|
18
|
-
],
|
|
4
|
+
const POPPER_MENU_PAPER_PROPS = { variant: "menu" };
|
|
5
|
+
const POPPER_MENU_POPPER_PROPS = {
|
|
6
|
+
modifiers: [{ name: "offset", options: { offset: [0, 8] } }],
|
|
19
7
|
placement: "bottom-start",
|
|
20
8
|
};
|
|
21
|
-
export const
|
|
22
|
-
paper:
|
|
23
|
-
popper:
|
|
24
|
-
};
|
|
25
|
-
export const DRAWER_PAPER_PROPS = {
|
|
26
|
-
elevation: 0,
|
|
27
|
-
sx: {
|
|
28
|
-
width: 312,
|
|
29
|
-
},
|
|
9
|
+
export const POPPER_MENU_SLOT_PROPS = {
|
|
10
|
+
paper: POPPER_MENU_PAPER_PROPS,
|
|
11
|
+
popper: POPPER_MENU_POPPER_PROPS,
|
|
30
12
|
};
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
name: "offset",
|
|
35
|
-
options: {
|
|
36
|
-
offset: [-16, 8],
|
|
37
|
-
},
|
|
38
|
-
},
|
|
39
|
-
],
|
|
13
|
+
const POPPER_DRAWER_PAPER_PROPS = { elevation: 0 };
|
|
14
|
+
const POPPER_DRAWER_POPPER_PROPS = {
|
|
15
|
+
modifiers: [{ name: "offset", options: { offset: [-16, 8] } }],
|
|
40
16
|
popperOptions: { strategy: "absolute" },
|
|
41
17
|
};
|
|
42
|
-
export const
|
|
43
|
-
paper:
|
|
44
|
-
popper:
|
|
18
|
+
export const POPPER_DRAWER_SLOT_PROPS = {
|
|
19
|
+
paper: POPPER_DRAWER_PAPER_PROPS,
|
|
20
|
+
popper: POPPER_DRAWER_POPPER_PROPS,
|
|
45
21
|
};
|
|
46
22
|
export const DIVIDER_ITEM = {
|
|
47
23
|
type: ITEM_TYPE.DIVIDER,
|
package/lib/components/Filter/components/SearchAllFilters/components/OutlinedInput/constants.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { TEXT_FIELD_PROPS as MUI_TEXT_FIELD_PROPS } from "../../../../../../styles/common/mui/textField";
|
|
2
|
+
export const TEXT_FIELD_PROPS = {
|
|
3
|
+
color: MUI_TEXT_FIELD_PROPS.COLOR.SECONDARY,
|
|
4
|
+
fullWidth: true,
|
|
5
|
+
placeholder: "Search all filters...",
|
|
6
|
+
size: MUI_TEXT_FIELD_PROPS.SIZE.SMALL,
|
|
7
|
+
};
|
package/lib/components/Filter/components/SearchAllFilters/components/OutlinedInput/outlinedInput.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { ClearInputAdornment } from "../../../../../common/OutlinedInput/components/InputAdornment/components/ClearInputAdornment/clearInputAdornment";
|
|
3
|
+
import { SearchInputAdornment } from "../../../../../common/OutlinedInput/components/InputAdornment/components/SearchInputAdornment/searchInputAdornment";
|
|
4
|
+
import { StyledOutlinedInput } from "../../../../../common/OutlinedInput/outlinedInput.styles";
|
|
5
|
+
import { useAutocomplete } from "../../context/hook";
|
|
6
|
+
import { TEXT_FIELD_PROPS } from "./constants";
|
|
7
|
+
import { isButtonIn } from "./utils";
|
|
8
|
+
export const OutlinedInput = (props) => {
|
|
9
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars -- Intended behavior, destructure InputLabelProps, as they are not used on the component.
|
|
10
|
+
const { InputLabelProps, InputProps, ...outlinedInputProps } = props;
|
|
11
|
+
const { onClear, open, searchTerm, surfaceType } = useAutocomplete();
|
|
12
|
+
return (React.createElement(StyledOutlinedInput, { ...TEXT_FIELD_PROPS, ...InputProps, ...outlinedInputProps, endAdornment: React.createElement(ClearInputAdornment, { in: isButtonIn(surfaceType, searchTerm, open), onClick: onClear }), hasValue: !!searchTerm, startAdornment: React.createElement(SearchInputAdornment, null) }));
|
|
13
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { SURFACE_TYPE } from "../../../surfaces/types";
|
|
2
|
+
/**
|
|
3
|
+
* Returns true if the clear button should display.
|
|
4
|
+
* Displays always for popper drawer surface type when open.
|
|
5
|
+
* Displays when there is a search term for other surface types when open.
|
|
6
|
+
* @param surfaceType - Surface type.
|
|
7
|
+
* @param searchTerm - Search term.
|
|
8
|
+
* @param open - Autocomplete open state.
|
|
9
|
+
* @returns True if the clear button should display.
|
|
10
|
+
*/
|
|
11
|
+
export declare function isButtonIn(surfaceType: SURFACE_TYPE, searchTerm: string, open: boolean): boolean;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { SURFACE_TYPE } from "../../../surfaces/types";
|
|
2
|
+
/**
|
|
3
|
+
* Returns true if the clear button should display.
|
|
4
|
+
* Displays always for popper drawer surface type when open.
|
|
5
|
+
* Displays when there is a search term for other surface types when open.
|
|
6
|
+
* @param surfaceType - Surface type.
|
|
7
|
+
* @param searchTerm - Search term.
|
|
8
|
+
* @param open - Autocomplete open state.
|
|
9
|
+
* @returns True if the clear button should display.
|
|
10
|
+
*/
|
|
11
|
+
export function isButtonIn(surfaceType, searchTerm, open) {
|
|
12
|
+
if (!open)
|
|
13
|
+
return false;
|
|
14
|
+
if (surfaceType === SURFACE_TYPE.POPPER_DRAWER)
|
|
15
|
+
return true;
|
|
16
|
+
return !!searchTerm;
|
|
17
|
+
}
|
|
@@ -3,6 +3,7 @@ import React from "react";
|
|
|
3
3
|
import { VariableSizeListProps as ListProps } from "react-window";
|
|
4
4
|
import { SelectCategoryView } from "../../../../../../common/entities";
|
|
5
5
|
import { OnFilterFn } from "../../../../../../hooks/useCategoryFilter";
|
|
6
|
+
import { SURFACE_TYPE } from "../../../surfaces/types";
|
|
6
7
|
export type ItemSizeByItemKey = Map<string, number>;
|
|
7
8
|
export interface VariableSizeListProps {
|
|
8
9
|
autocompleteListProps: Omit<MListProps, "children">;
|
|
@@ -12,6 +13,7 @@ export interface VariableSizeListProps {
|
|
|
12
13
|
overscanCount?: ListProps["overscanCount"];
|
|
13
14
|
searchTerm: string;
|
|
14
15
|
selectCategoryViews: SelectCategoryView[];
|
|
16
|
+
surfaceType: SURFACE_TYPE;
|
|
15
17
|
width?: ListProps["width"];
|
|
16
18
|
}
|
|
17
19
|
export declare const VariableSizeList: React.ForwardRefExoticComponent<VariableSizeListProps & React.RefAttributes<HTMLUListElement>>;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { Divider, List as MList } from "@mui/material";
|
|
2
2
|
import React, { createContext, forwardRef, useCallback, useContext, useEffect, useRef, useState, } from "react";
|
|
3
3
|
import { VariableSizeList as List, } from "react-window";
|
|
4
|
-
import { BREAKPOINT_FN_NAME, useBreakpointHelper, } from "../../../../../../hooks/useBreakpointHelper";
|
|
5
4
|
import { useWindowResize } from "../../../../../../hooks/useWindowResize";
|
|
6
5
|
import { LIST_ITEM_HEIGHT, LIST_MARGIN, MAX_DISPLAYABLE_LIST_ITEMS, MAX_LIST_HEIGHT_PX, } from "../../../../common/constants";
|
|
7
6
|
import { getSortMatchesFn } from "../../../../common/utils";
|
|
8
7
|
import { StyledList } from "../../../FilterList/filterList.styles";
|
|
8
|
+
import { SURFACE_TYPE } from "../../../surfaces/types";
|
|
9
9
|
import { DIVIDER_HEIGHT, DIVIDER_ITEM, NO_RESULTS_ITEM, } from "../../common/constants";
|
|
10
10
|
import { ITEM_TYPE, } from "../../common/entites";
|
|
11
11
|
import VariableSizeListItem from "../VariableSizeListItem/variableSizeListItem";
|
|
@@ -32,10 +32,9 @@ const OuterElement = forwardRef(function OuterElement({ children, ...props }, re
|
|
|
32
32
|
return (React.createElement("div", { ref: ref, ...props },
|
|
33
33
|
React.createElement(MList, { ref: autocompleteListRef, style: { maxHeight: "none", padding: 0 }, ...autocompleteListProps }, children)));
|
|
34
34
|
});
|
|
35
|
-
export const VariableSizeList = forwardRef(function VariableSizeList({ autocompleteListProps, height: initHeight = MAX_LIST_HEIGHT_PX, itemSize = LIST_ITEM_HEIGHT, onFilter, overscanCount = MAX_DISPLAYABLE_LIST_ITEMS * 2, searchTerm, selectCategoryViews, width = "100%", }, autocompleteListRef) {
|
|
35
|
+
export const VariableSizeList = forwardRef(function VariableSizeList({ autocompleteListProps, height: initHeight = MAX_LIST_HEIGHT_PX, itemSize = LIST_ITEM_HEIGHT, onFilter, overscanCount = MAX_DISPLAYABLE_LIST_ITEMS * 2, searchTerm, selectCategoryViews, surfaceType, width = "100%", }, autocompleteListRef) {
|
|
36
36
|
const filteredItems = applyMenuFilter(selectCategoryViews, searchTerm);
|
|
37
37
|
let resizeRequired = true;
|
|
38
|
-
const bpDownMd = useBreakpointHelper(BREAKPOINT_FN_NAME.DOWN, "md");
|
|
39
38
|
const { height: windowHeight } = useWindowResize();
|
|
40
39
|
const [height, setHeight] = useState(initHeight);
|
|
41
40
|
const itemSizeByItemKeyRef = useRef(new Map());
|
|
@@ -47,8 +46,8 @@ export const VariableSizeList = forwardRef(function VariableSizeList({ autocompl
|
|
|
47
46
|
// Sets height of list.
|
|
48
47
|
useEffect(() => {
|
|
49
48
|
if (innerRef.current && outerRef.current)
|
|
50
|
-
setHeight(calculateListHeight(outerRef.current, innerRef.current, windowHeight,
|
|
51
|
-
}, [
|
|
49
|
+
setHeight(calculateListHeight(outerRef.current, innerRef.current, windowHeight, surfaceType));
|
|
50
|
+
}, [surfaceType, windowHeight]);
|
|
52
51
|
// Clears VariableSizeList cache (offsets and measurements) when values are updated (filtered).
|
|
53
52
|
// Facilitates correct positioning of list items when list is updated.
|
|
54
53
|
useEffect(() => {
|
|
@@ -72,7 +71,7 @@ export const VariableSizeList = forwardRef(function VariableSizeList({ autocompl
|
|
|
72
71
|
outerRef.current) {
|
|
73
72
|
// Set height of list.
|
|
74
73
|
resizeRequired = false;
|
|
75
|
-
setHeight(calculateListHeight(outerRef.current, innerRef.current, windowHeight,
|
|
74
|
+
setHeight(calculateListHeight(outerRef.current, innerRef.current, windowHeight, surfaceType));
|
|
76
75
|
}
|
|
77
76
|
listRef.current?.resetAfterIndex(0); // Facilitates correct positioning of list items when list scrolls.
|
|
78
77
|
});
|
|
@@ -119,15 +118,15 @@ function applyMenuFilter(selectCategoryViews, inputValue) {
|
|
|
119
118
|
* @param outerListElem - Outer list element to reference list position from.
|
|
120
119
|
* @param innerListElem - Element containing list items.
|
|
121
120
|
* @param windowHeight - Window height.
|
|
122
|
-
* @param
|
|
121
|
+
* @param surfaceType - Type of surface "POPPER_MENU" or "POPPER_DRAWER".
|
|
123
122
|
* @returns calculated height.
|
|
124
123
|
*/
|
|
125
|
-
function calculateListHeight(outerListElem, innerListElem, windowHeight,
|
|
124
|
+
function calculateListHeight(outerListElem, innerListElem, windowHeight, surfaceType) {
|
|
126
125
|
// Calculate max possible list height, based on window height and top position of the list element.
|
|
127
126
|
const maxHeight = windowHeight - outerListElem.getBoundingClientRect().top;
|
|
128
|
-
if
|
|
127
|
+
// Return the maximum possible height if the list is in a popper drawer.
|
|
128
|
+
if (surfaceType === SURFACE_TYPE.POPPER_DRAWER)
|
|
129
129
|
return maxHeight;
|
|
130
|
-
}
|
|
131
130
|
// Grab the first and last element in the list.
|
|
132
131
|
const { firstElementChild: firstListEl, lastElementChild: lastListEl } = innerListElem;
|
|
133
132
|
// Grab the scroll position to adjust calculated list height.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { createContext } from "react";
|
|
2
|
+
import { SURFACE_TYPE } from "../../surfaces/types";
|
|
3
|
+
export const AutocompleteContext = createContext({
|
|
4
|
+
onClear: () => undefined,
|
|
5
|
+
onFilter: () => undefined,
|
|
6
|
+
open: false,
|
|
7
|
+
searchTerm: "",
|
|
8
|
+
selectCategoryViews: [],
|
|
9
|
+
surfaceType: SURFACE_TYPE.POPPER_MENU,
|
|
10
|
+
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { SelectCategoryView } from "../../../../../common/entities";
|
|
2
|
+
import { OnFilterFn } from "../../../../../hooks/useCategoryFilter";
|
|
3
|
+
import { SURFACE_TYPE } from "../../surfaces/types";
|
|
4
|
+
export interface AutocompleteContextProps {
|
|
5
|
+
onClear: () => void;
|
|
6
|
+
onFilter: OnFilterFn;
|
|
7
|
+
open: boolean;
|
|
8
|
+
searchTerm: string;
|
|
9
|
+
selectCategoryViews: SelectCategoryView[];
|
|
10
|
+
surfaceType: SURFACE_TYPE;
|
|
11
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,19 +1,2 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
import { SelectCategoryView } from "../../../../common/entities";
|
|
4
|
-
import { OnFilterFn } from "../../../../hooks/useCategoryFilter";
|
|
5
|
-
export interface SearchAllFiltersProps {
|
|
6
|
-
categoryViews: CategoryView[];
|
|
7
|
-
onFilter: OnFilterFn;
|
|
8
|
-
}
|
|
9
|
-
interface ListboxContextValue {
|
|
10
|
-
onClearSearch: () => void;
|
|
11
|
-
onCloseSearch: () => void;
|
|
12
|
-
onFilter: OnFilterFn;
|
|
13
|
-
open: boolean;
|
|
14
|
-
searchTerm: string;
|
|
15
|
-
selectCategoryViews: SelectCategoryView[];
|
|
16
|
-
}
|
|
17
|
-
export declare const ListboxContext: React.Context<ListboxContextValue>;
|
|
18
|
-
export declare const SearchAllFilters: ({ categoryViews, onFilter, }: SearchAllFiltersProps) => JSX.Element;
|
|
19
|
-
export {};
|
|
1
|
+
import { SearchAllFiltersProps } from "./types";
|
|
2
|
+
export declare const SearchAllFilters: ({ categoryViews, className, onFilter, surfaceType, ...props }: SearchAllFiltersProps) => JSX.Element;
|
|
@@ -1,103 +1,66 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, { useCallback, useRef, useState } from "react";
|
|
2
2
|
import { isSelectCategoryView } from "../../../../common/categories/views/select/typeGuards";
|
|
3
3
|
import { SELECTOR } from "../../../../common/selectors";
|
|
4
|
-
import { BREAKPOINT_FN_NAME, useBreakpointHelper, } from "../../../../hooks/useBreakpointHelper";
|
|
5
4
|
import { TEST_IDS } from "../../../../tests/testIds";
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import { DEFAULT_SLOT_PROPS, DRAWER_SLOT_PROPS } from "./common/constants";
|
|
5
|
+
import { StyledPopper, StyledPopperDrawer, } from "../surfaces/popper/Popper/popper.styles";
|
|
6
|
+
import { SURFACE_TYPE } from "../surfaces/types";
|
|
7
|
+
import { POPPER_DRAWER_SLOT_PROPS, POPPER_MENU_SLOT_PROPS, } from "./common/constants";
|
|
10
8
|
import { OVERFLOW_STYLE } from "./common/entites";
|
|
11
9
|
import { setElementsOverflowStyle } from "./common/utils";
|
|
12
|
-
import {
|
|
10
|
+
import { OutlinedInput } from "./components/OutlinedInput/outlinedInput";
|
|
13
11
|
import { VariableSizeList } from "./components/VariableSizeList/VariableSizeList";
|
|
14
|
-
import {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
onClearSearch: () => undefined,
|
|
18
|
-
onCloseSearch: () => undefined,
|
|
19
|
-
onFilter: () => undefined,
|
|
20
|
-
open: false,
|
|
21
|
-
searchTerm: "",
|
|
22
|
-
selectCategoryViews: [],
|
|
23
|
-
});
|
|
12
|
+
import { AutocompleteContext } from "./context/context";
|
|
13
|
+
import { useAutocomplete } from "./context/hook";
|
|
14
|
+
import { StyledAutocomplete } from "./searchAllFilters.styles";
|
|
24
15
|
const Listbox = React.forwardRef(function Listbox(props, ref) {
|
|
25
16
|
props = Object.assign({}, props, {
|
|
26
17
|
children: undefined, // Content is controlled by VariableSizeList
|
|
27
18
|
});
|
|
28
|
-
const { onFilter, searchTerm, selectCategoryViews } =
|
|
29
|
-
return (React.createElement(VariableSizeList, { autocompleteListProps: props, onFilter: onFilter, ref: ref, searchTerm: searchTerm, selectCategoryViews: selectCategoryViews }));
|
|
19
|
+
const { onFilter, searchTerm, selectCategoryViews, surfaceType } = useAutocomplete();
|
|
20
|
+
return (React.createElement(VariableSizeList, { autocompleteListProps: props, onFilter: onFilter, ref: ref, searchTerm: searchTerm, selectCategoryViews: selectCategoryViews, surfaceType: surfaceType }));
|
|
30
21
|
});
|
|
31
|
-
export const SearchAllFilters = ({ categoryViews, onFilter, }) => {
|
|
32
|
-
const { open: isDrawerOpen } = useDrawer();
|
|
33
|
-
const bpUpMd = useBreakpointHelper(BREAKPOINT_FN_NAME.UP, "md");
|
|
22
|
+
export const SearchAllFilters = ({ categoryViews, className, onFilter, surfaceType = SURFACE_TYPE.POPPER_MENU, ...props /* Mui AutocompleteProps */ }) => {
|
|
34
23
|
const autocompleteRef = useRef(null);
|
|
35
24
|
const [open, setOpen] = useState(false);
|
|
36
25
|
const [searchTerm, setSearchTerm] = useState("");
|
|
37
|
-
const selectCategoryViews = categoryViews.filter(
|
|
38
|
-
// Handles background scroll action
|
|
39
|
-
const handleBackgroundScroll = (overflowStyle) => {
|
|
40
|
-
if (
|
|
26
|
+
const selectCategoryViews = categoryViews.filter(isSelectCategoryView);
|
|
27
|
+
// Handles background scroll action.
|
|
28
|
+
const handleBackgroundScroll = useCallback((overflowStyle) => {
|
|
29
|
+
if (surfaceType === SURFACE_TYPE.POPPER_MENU) {
|
|
41
30
|
setElementsOverflowStyle([
|
|
42
31
|
document.querySelector(SELECTOR.BODY),
|
|
43
32
|
document.getElementById(SELECTOR.SIDEBAR_POSITIONER),
|
|
44
33
|
], overflowStyle);
|
|
45
34
|
}
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
const onChange = (event) => {
|
|
49
|
-
setSearchTerm(event.target.value);
|
|
50
|
-
};
|
|
51
|
-
// Clear search
|
|
52
|
-
const onClearSearch = () => {
|
|
53
|
-
setSearchTerm("");
|
|
54
|
-
};
|
|
55
|
-
// Close search.
|
|
56
|
-
const onCloseSearch = () => {
|
|
35
|
+
}, [surfaceType]);
|
|
36
|
+
const onClose = useCallback(() => {
|
|
57
37
|
setSearchTerm("");
|
|
58
38
|
setOpen(false);
|
|
59
39
|
handleBackgroundScroll(OVERFLOW_STYLE.NONE);
|
|
60
|
-
|
|
61
|
-
// Callback fired when the popup requests to be opened.
|
|
62
|
-
const onOpen = () => {
|
|
63
|
-
handleBackgroundScroll(OVERFLOW_STYLE.HIDDEN);
|
|
64
|
-
};
|
|
65
|
-
// Open search.
|
|
66
|
-
const onOpenSearch = () => {
|
|
67
|
-
if (open) {
|
|
68
|
-
return;
|
|
69
|
-
}
|
|
70
|
-
setOpen(true);
|
|
71
|
-
};
|
|
72
|
-
useEffect(() => {
|
|
73
|
-
if (!open) {
|
|
40
|
+
setTimeout(() => {
|
|
74
41
|
autocompleteRef.current?.querySelector("input")?.blur();
|
|
75
|
-
}
|
|
76
|
-
}, [
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
42
|
+
}, 100);
|
|
43
|
+
}, [handleBackgroundScroll]);
|
|
44
|
+
const onOpen = useCallback(() => {
|
|
45
|
+
setOpen(true);
|
|
46
|
+
handleBackgroundScroll(OVERFLOW_STYLE.HIDDEN);
|
|
47
|
+
}, [handleBackgroundScroll]);
|
|
48
|
+
const onClear = useCallback(() => {
|
|
49
|
+
setSearchTerm("");
|
|
50
|
+
if (surfaceType === SURFACE_TYPE.POPPER_DRAWER)
|
|
51
|
+
onClose();
|
|
52
|
+
}, [onClose, surfaceType]);
|
|
53
|
+
return (React.createElement(AutocompleteContext.Provider, { value: {
|
|
54
|
+
onClear,
|
|
87
55
|
onFilter,
|
|
88
56
|
open,
|
|
89
57
|
searchTerm,
|
|
90
58
|
selectCategoryViews,
|
|
59
|
+
surfaceType,
|
|
91
60
|
} },
|
|
92
|
-
React.createElement(
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
},
|
|
98
|
-
inputProps: {
|
|
99
|
-
...props.inputProps,
|
|
100
|
-
onChange,
|
|
101
|
-
},
|
|
102
|
-
}), slotProps: bpUpMd ? DEFAULT_SLOT_PROPS : DRAWER_SLOT_PROPS })));
|
|
61
|
+
React.createElement(StyledAutocomplete, { className: className, "data-testid": TEST_IDS.SEARCH_ALL_FILTERS, filterOptions: (options) => options, freeSolo: true, onClose: onClose, onInputChange: (_, v = "") => setSearchTerm(v), onOpen: onOpen, open: open, options: [""], ref: autocompleteRef, renderInput: OutlinedInput, slotProps: surfaceType === SURFACE_TYPE.POPPER_MENU
|
|
62
|
+
? POPPER_MENU_SLOT_PROPS
|
|
63
|
+
: POPPER_DRAWER_SLOT_PROPS, slots: surfaceType === SURFACE_TYPE.POPPER_MENU
|
|
64
|
+
? { listbox: Listbox, popper: StyledPopper }
|
|
65
|
+
: { listbox: Listbox, popper: StyledPopperDrawer }, value: searchTerm, ...props })));
|
|
103
66
|
};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { Autocomplete
|
|
2
|
-
export declare const
|
|
1
|
+
import { Autocomplete } from "@mui/material";
|
|
2
|
+
export declare const StyledAutocomplete: typeof Autocomplete;
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import styled from "@emotion/styled";
|
|
2
|
-
import { Autocomplete
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
&.Mui-expanded {
|
|
2
|
+
import { Autocomplete } from "@mui/material";
|
|
3
|
+
export const StyledAutocomplete = styled(Autocomplete) `
|
|
4
|
+
&.MuiAutocomplete-root {
|
|
6
5
|
.MuiOutlinedInput-root {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
padding: 0 12px;
|
|
7
|
+
|
|
8
|
+
.MuiAutocomplete-input {
|
|
9
|
+
padding: 10px 0;
|
|
11
10
|
}
|
|
12
11
|
}
|
|
13
12
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { fn } from "@storybook/test";
|
|
2
|
+
import { BIOLOGICAL_SEX, DONOR_COUNT, GENUS_SPECIES, } from "../../Filters/stories/constants";
|
|
3
|
+
import { SURFACE_TYPE } from "../../surfaces/types";
|
|
4
|
+
export const DEFAULT_ARGS = {
|
|
5
|
+
categoryViews: [BIOLOGICAL_SEX, GENUS_SPECIES, DONOR_COUNT],
|
|
6
|
+
onFilter: fn(),
|
|
7
|
+
surfaceType: SURFACE_TYPE.POPPER_MENU,
|
|
8
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Box } from "@mui/material";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import { PALETTE } from "../../../../../styles/common/constants/palette";
|
|
4
|
+
import { SearchAllFilters } from "../searchAllFilters";
|
|
5
|
+
import { DEFAULT_ARGS } from "./args";
|
|
6
|
+
const meta = {
|
|
7
|
+
component: SearchAllFilters,
|
|
8
|
+
decorators: [
|
|
9
|
+
(Story) => (React.createElement(Box, { sx: { backgroundColor: PALETTE.COMMON_WHITE, minWidth: 264 } },
|
|
10
|
+
React.createElement(Story, null))),
|
|
11
|
+
],
|
|
12
|
+
};
|
|
13
|
+
export default meta;
|
|
14
|
+
const DefaultStory = () => {
|
|
15
|
+
return React.createElement(SearchAllFilters, { ...DEFAULT_ARGS });
|
|
16
|
+
};
|
|
17
|
+
export const Default = {
|
|
18
|
+
render: () => React.createElement(DefaultStory, null),
|
|
19
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { AutocompleteProps } from "@mui/material";
|
|
2
|
+
import { CategoryView } from "../../../../common/categories/views/types";
|
|
3
|
+
import { OnFilterFn } from "../../../../hooks/useCategoryFilter";
|
|
4
|
+
import { BaseComponentProps } from "../../../types";
|
|
5
|
+
import { SURFACE_TYPE } from "../surfaces/types";
|
|
6
|
+
export interface SearchAllFiltersProps extends Omit<AutocompleteProps<string, false, false, true>, "options" | "renderInput">, BaseComponentProps {
|
|
7
|
+
categoryViews: CategoryView[];
|
|
8
|
+
onFilter: OnFilterFn;
|
|
9
|
+
surfaceType?: SURFACE_TYPE;
|
|
10
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { useCallback } from "react";
|
|
2
|
+
import { VIEW_KIND } from "../../../../../../common/categories/views/types";
|
|
2
3
|
import { CLEAR_ALL, } from "../../../../../../common/entities";
|
|
3
4
|
import { updater } from "../../../../../Table/components/TableFeatures/ColumnFilter/utils";
|
|
4
5
|
import { buildColumnFilters, getColumnFiltersCount } from "./utils";
|
|
@@ -7,11 +8,19 @@ export const ColumnFiltersAdapter = ({ renderSurface, table, }) => {
|
|
|
7
8
|
const count = getColumnFiltersCount(table);
|
|
8
9
|
const onFilter = useCallback((categoryKey, selectedCategoryValue,
|
|
9
10
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars -- `selected` is not required by TanStack adapter.
|
|
10
|
-
_selected
|
|
11
|
+
_selected,
|
|
12
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars -- `categorySection` is not required by TanStack adapter.
|
|
13
|
+
_categorySection, viewKind) => {
|
|
11
14
|
if (categoryKey === CLEAR_ALL) {
|
|
12
15
|
table.resetColumnFilters();
|
|
13
16
|
return;
|
|
14
17
|
}
|
|
18
|
+
// Range filters use direct value assignment (e.g., [min, max] tuple for numeric ranges).
|
|
19
|
+
if (viewKind === VIEW_KIND.RANGE) {
|
|
20
|
+
table.getColumn(categoryKey)?.setFilterValue(selectedCategoryValue);
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
// Select filters use an updater function to toggle individual values in/out of the filter array.
|
|
15
24
|
table
|
|
16
25
|
.getColumn(categoryKey)
|
|
17
26
|
?.setFilterValue(updater(selectedCategoryValue));
|
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
import { RowData, Table } from "@tanstack/react-table";
|
|
1
|
+
import { RowData, Table, TableMeta as TanStackTableMeta } from "@tanstack/react-table";
|
|
2
|
+
import { CategoryGroup } from "../../../../../../config/entities";
|
|
2
3
|
import { SurfaceProps } from "../../../surfaces/types";
|
|
3
4
|
export interface ColumnFiltersAdapterProps<T extends RowData> {
|
|
4
5
|
renderSurface: (props: SurfaceProps) => JSX.Element | null;
|
|
5
6
|
table: Table<T>;
|
|
6
7
|
}
|
|
8
|
+
export interface ColumnFiltersTableMeta<T extends RowData> extends TanStackTableMeta<T> {
|
|
9
|
+
categoryGroups?: CategoryGroup[];
|
|
10
|
+
}
|