@trackunit/filters-filter-bar 2.17.34 → 2.17.36

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/index.cjs.js CHANGED
@@ -287,7 +287,7 @@ const LOADING_INDICATOR = {
287
287
  *
288
288
  * @returns {ReactElement} - Returns the DynamicFilterList component.
289
289
  */
290
- const DynamicFilterList = ({ rowCount, keyMapper, labelMapper, onChange, checked, count, showRequestMoreUseSearch = false, pagination, type = undefined, className, }) => {
290
+ const DynamicFilterList = ({ rowCount, keyMapper, labelMapper, onChange, checked, count, showRequestMoreUseSearch = false, pagination, type = undefined, className, "data-testid": dataTestId, }) => {
291
291
  const [t] = useTranslation();
292
292
  const showSearchMoreHint = showRequestMoreUseSearch && pagination === undefined;
293
293
  const updatedRowCount = react.useMemo(() => (showSearchMoreHint ? rowCount + 1 : rowCount), [rowCount, showSearchMoreHint]);
@@ -311,7 +311,7 @@ const DynamicFilterList = ({ rowCount, keyMapper, labelMapper, onChange, checked
311
311
  separator: "none",
312
312
  estimateItemSize: () => ITEM_HEIGHT,
313
313
  });
314
- return (jsxRuntime.jsx(reactFilterComponents.FilterBody, { className: "flex h-full min-h-0 flex-col overflow-hidden", children: jsxRuntime.jsx(reactComponents.List, { className: tailwindMerge.twMerge("min-h-0 max-w-sm flex-1 overflow-y-auto", className), ...list, children: ({ key, listItemProps, item }) => {
314
+ return (jsxRuntime.jsx(reactFilterComponents.FilterBody, { className: "flex h-full min-h-0 flex-col overflow-hidden", children: jsxRuntime.jsx(reactComponents.List, { ...list, className: tailwindMerge.twMerge("min-h-0 max-w-sm flex-1 overflow-y-auto", className), "data-testid": dataTestId, children: ({ key, listItemProps, item }) => {
315
315
  if (!item) {
316
316
  return null;
317
317
  }
@@ -580,6 +580,12 @@ const DefaultMinMaxFilter = ({ filterDefinition, filterName, value, setValue, fi
580
580
  return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(reactFilterComponents.FilterHeader, { onReset: () => filterBarActions.resetIndividualFilterToInitialState(filterDefinition.filterKey), resetLabel: t("filtersBar.resetFilter"), showReset: filterBarActions.appliedFilterKeys().includes(filterDefinition.filterKey), title: filterDefinition.title }), jsxRuntime.jsxs(reactFilterComponents.FilterBody, { children: [jsxRuntime.jsxs("div", { className: "flex gap-1 px-1 pb-0.5 pt-1", children: [jsxRuntime.jsx(reactFormComponents.NumberField, { addonAfter: unit, className: "w-40", label: t("filtersBar.defaultMinMaxFilters.min"), max: filterDefinition.type === "minMax" ? filterDefinition.maximumNumber : undefined, min: filterDefinition.type === "minMax" ? filterDefinition.minimumNumber : undefined, onChange: e => setMinValue(e.target.value === "" ? undefined : Number(e.target.value)), value: minValue ?? "" }), jsxRuntime.jsx(reactFormComponents.NumberField, { addonAfter: unit, className: "w-40", label: t("filtersBar.defaultMinMaxFilters.max"), max: filterDefinition.type === "minMax" ? filterDefinition.maximumNumber : undefined, min: filterDefinition.type === "minMax" ? filterDefinition.minimumNumber : undefined, onChange: e => setMaxValue(e.target.value === "" ? undefined : Number(e.target.value)), value: maxValue ?? "" })] }), jsxRuntime.jsx(reactFilterComponents.FilterFooter, { children: jsxRuntime.jsx(reactComponents.Button, { onClick: handleApply, size: "small", variant: "primary", children: t("filtersBar.defaultMinMaxFilters.apply") }) })] })] }));
581
581
  };
582
582
 
583
+ /**
584
+ * Constrains the radio option list to the filter shell so a long list scrolls inside the menu.
585
+ */
586
+ const RadioFilterResults = ({ isChecked, loading, onSelect, results, selectedKey, showRequestMoreUseSearch, }) => (jsxRuntime.jsx("div", { className: "grid min-h-0 grid-rows-[minmax(0,1fr)] overflow-hidden", children: jsxRuntime.jsx(FilterResults, { loading: loading, results: results, children: res => (jsxRuntime.jsx(reactFormComponents.RadioGroup, { className: "h-full min-h-0 w-full overflow-hidden", formGroupClassName: "grid h-full min-h-0 grid-rows-[minmax(0,1fr)]", id: "DefaultRadioFilter", onChange: event => {
587
+ onSelect(event.currentTarget.value);
588
+ }, value: selectedKey, children: jsxRuntime.jsx(DynamicFilterList, { checked: index => isChecked(res[index]?.key || ""), className: "m-1 mt-0 h-full", count: index => res[index]?.count, "data-testid": "default-radio-filter-results", keyMapper: index => res[index]?.key || "", labelMapper: index => res[index]?.label || "", rowCount: res.length, showRequestMoreUseSearch: showRequestMoreUseSearch, type: "Radio" }) })) }) }));
583
589
  /**
584
590
  * DefaultRadioFilter is a React component that renders a filter with radio button options based on the provided props.
585
591
  *
@@ -604,9 +610,7 @@ const DefaultRadioFilter = ({ filterDefinition, filterBarActions, options, loadi
604
610
  onChange: customSearch?.onChange ?? setSearchText,
605
611
  onClear: customSearch?.onClear ?? (() => setSearchText("")),
606
612
  count: filteredOptions.length,
607
- } }), jsxRuntime.jsx(FilterResults, { loading: loading, results: customSearch ? options : filteredOptions, children: res => (jsxRuntime.jsx(reactFormComponents.RadioGroup, { id: "DefaultRadioFilter", onChange: e => {
608
- handleClick(e.currentTarget.value);
609
- }, value: selectedRadioId?.key || "", children: jsxRuntime.jsx(DynamicFilterList, { checked: index => filterBarActions.objectIncludesValue(filterDefinition.filterKey, res[index]?.key || ""), className: "m-1 mt-0", count: index => res[index]?.count, keyMapper: index => res[index]?.key || "", labelMapper: index => res[index]?.label || "", rowCount: res.length, showRequestMoreUseSearch: showRequestMoreUseSearch, type: "Radio" }) })) })] }));
613
+ } }), jsxRuntime.jsx(RadioFilterResults, { isChecked: key => filterBarActions.objectIncludesValue(filterDefinition.filterKey, key), loading: loading, onSelect: handleClick, results: customSearch ? options : filteredOptions, selectedKey: selectedRadioId?.key || "", showRequestMoreUseSearch: showRequestMoreUseSearch })] }));
610
614
  };
611
615
 
612
616
  /**
package/index.esm.js CHANGED
@@ -285,7 +285,7 @@ const LOADING_INDICATOR = {
285
285
  *
286
286
  * @returns {ReactElement} - Returns the DynamicFilterList component.
287
287
  */
288
- const DynamicFilterList = ({ rowCount, keyMapper, labelMapper, onChange, checked, count, showRequestMoreUseSearch = false, pagination, type = undefined, className, }) => {
288
+ const DynamicFilterList = ({ rowCount, keyMapper, labelMapper, onChange, checked, count, showRequestMoreUseSearch = false, pagination, type = undefined, className, "data-testid": dataTestId, }) => {
289
289
  const [t] = useTranslation();
290
290
  const showSearchMoreHint = showRequestMoreUseSearch && pagination === undefined;
291
291
  const updatedRowCount = useMemo(() => (showSearchMoreHint ? rowCount + 1 : rowCount), [rowCount, showSearchMoreHint]);
@@ -309,7 +309,7 @@ const DynamicFilterList = ({ rowCount, keyMapper, labelMapper, onChange, checked
309
309
  separator: "none",
310
310
  estimateItemSize: () => ITEM_HEIGHT,
311
311
  });
312
- return (jsx(FilterBody, { className: "flex h-full min-h-0 flex-col overflow-hidden", children: jsx(List, { className: twMerge("min-h-0 max-w-sm flex-1 overflow-y-auto", className), ...list, children: ({ key, listItemProps, item }) => {
312
+ return (jsx(FilterBody, { className: "flex h-full min-h-0 flex-col overflow-hidden", children: jsx(List, { ...list, className: twMerge("min-h-0 max-w-sm flex-1 overflow-y-auto", className), "data-testid": dataTestId, children: ({ key, listItemProps, item }) => {
313
313
  if (!item) {
314
314
  return null;
315
315
  }
@@ -578,6 +578,12 @@ const DefaultMinMaxFilter = ({ filterDefinition, filterName, value, setValue, fi
578
578
  return (jsxs(Fragment, { children: [jsx(FilterHeader$1, { onReset: () => filterBarActions.resetIndividualFilterToInitialState(filterDefinition.filterKey), resetLabel: t("filtersBar.resetFilter"), showReset: filterBarActions.appliedFilterKeys().includes(filterDefinition.filterKey), title: filterDefinition.title }), jsxs(FilterBody, { children: [jsxs("div", { className: "flex gap-1 px-1 pb-0.5 pt-1", children: [jsx(NumberField, { addonAfter: unit, className: "w-40", label: t("filtersBar.defaultMinMaxFilters.min"), max: filterDefinition.type === "minMax" ? filterDefinition.maximumNumber : undefined, min: filterDefinition.type === "minMax" ? filterDefinition.minimumNumber : undefined, onChange: e => setMinValue(e.target.value === "" ? undefined : Number(e.target.value)), value: minValue ?? "" }), jsx(NumberField, { addonAfter: unit, className: "w-40", label: t("filtersBar.defaultMinMaxFilters.max"), max: filterDefinition.type === "minMax" ? filterDefinition.maximumNumber : undefined, min: filterDefinition.type === "minMax" ? filterDefinition.minimumNumber : undefined, onChange: e => setMaxValue(e.target.value === "" ? undefined : Number(e.target.value)), value: maxValue ?? "" })] }), jsx(FilterFooter, { children: jsx(Button, { onClick: handleApply, size: "small", variant: "primary", children: t("filtersBar.defaultMinMaxFilters.apply") }) })] })] }));
579
579
  };
580
580
 
581
+ /**
582
+ * Constrains the radio option list to the filter shell so a long list scrolls inside the menu.
583
+ */
584
+ const RadioFilterResults = ({ isChecked, loading, onSelect, results, selectedKey, showRequestMoreUseSearch, }) => (jsx("div", { className: "grid min-h-0 grid-rows-[minmax(0,1fr)] overflow-hidden", children: jsx(FilterResults, { loading: loading, results: results, children: res => (jsx(RadioGroup, { className: "h-full min-h-0 w-full overflow-hidden", formGroupClassName: "grid h-full min-h-0 grid-rows-[minmax(0,1fr)]", id: "DefaultRadioFilter", onChange: event => {
585
+ onSelect(event.currentTarget.value);
586
+ }, value: selectedKey, children: jsx(DynamicFilterList, { checked: index => isChecked(res[index]?.key || ""), className: "m-1 mt-0 h-full", count: index => res[index]?.count, "data-testid": "default-radio-filter-results", keyMapper: index => res[index]?.key || "", labelMapper: index => res[index]?.label || "", rowCount: res.length, showRequestMoreUseSearch: showRequestMoreUseSearch, type: "Radio" }) })) }) }));
581
587
  /**
582
588
  * DefaultRadioFilter is a React component that renders a filter with radio button options based on the provided props.
583
589
  *
@@ -602,9 +608,7 @@ const DefaultRadioFilter = ({ filterDefinition, filterBarActions, options, loadi
602
608
  onChange: customSearch?.onChange ?? setSearchText,
603
609
  onClear: customSearch?.onClear ?? (() => setSearchText("")),
604
610
  count: filteredOptions.length,
605
- } }), jsx(FilterResults, { loading: loading, results: customSearch ? options : filteredOptions, children: res => (jsx(RadioGroup, { id: "DefaultRadioFilter", onChange: e => {
606
- handleClick(e.currentTarget.value);
607
- }, value: selectedRadioId?.key || "", children: jsx(DynamicFilterList, { checked: index => filterBarActions.objectIncludesValue(filterDefinition.filterKey, res[index]?.key || ""), className: "m-1 mt-0", count: index => res[index]?.count, keyMapper: index => res[index]?.key || "", labelMapper: index => res[index]?.label || "", rowCount: res.length, showRequestMoreUseSearch: showRequestMoreUseSearch, type: "Radio" }) })) })] }));
611
+ } }), jsx(RadioFilterResults, { isChecked: key => filterBarActions.objectIncludesValue(filterDefinition.filterKey, key), loading: loading, onSelect: handleClick, results: customSearch ? options : filteredOptions, selectedKey: selectedRadioId?.key || "", showRequestMoreUseSearch: showRequestMoreUseSearch })] }));
608
612
  };
609
613
 
610
614
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trackunit/filters-filter-bar",
3
- "version": "2.17.34",
3
+ "version": "2.17.36",
4
4
  "repository": "https://github.com/Trackunit/manager",
5
5
  "license": "SEE LICENSE IN LICENSE.txt",
6
6
  "engines": {
@@ -11,18 +11,18 @@
11
11
  "tailwind-merge": "^3.7.0",
12
12
  "string-ts": "^2.0.0",
13
13
  "zod": "^3.25.76",
14
- "@trackunit/iris-app-api": "2.13.9",
15
- "@trackunit/react-core-hooks": "1.31.27",
16
- "@trackunit/react-filter-components": "2.17.32",
17
- "@trackunit/react-date-and-time-components": "2.17.32",
18
- "@trackunit/shared-utils": "1.22.35",
19
- "@trackunit/react-form-components": "2.17.31",
20
- "@trackunit/iris-app-runtime-core-api": "1.27.26",
21
- "@trackunit/geo-json-utils": "1.21.35",
22
- "@trackunit/i18n-library-translation": "2.14.27",
23
- "@trackunit/css-class-variance-utilities": "2.6.35",
24
- "@trackunit/react-components": "6.0.29",
25
- "@trackunit/react-router-components": "1.3.32"
14
+ "@trackunit/iris-app-api": "2.13.11",
15
+ "@trackunit/react-core-hooks": "1.31.29",
16
+ "@trackunit/react-filter-components": "2.17.34",
17
+ "@trackunit/react-date-and-time-components": "2.17.34",
18
+ "@trackunit/shared-utils": "1.22.37",
19
+ "@trackunit/react-form-components": "2.17.33",
20
+ "@trackunit/iris-app-runtime-core-api": "1.27.28",
21
+ "@trackunit/geo-json-utils": "1.21.37",
22
+ "@trackunit/i18n-library-translation": "2.14.29",
23
+ "@trackunit/css-class-variance-utilities": "2.6.37",
24
+ "@trackunit/react-components": "6.0.31",
25
+ "@trackunit/react-router-components": "1.3.34"
26
26
  },
27
27
  "peerDependencies": {
28
28
  "@apollo/client": "^3.13.8",
@@ -55,11 +55,15 @@ interface DynamicFilterListProps {
55
55
  * A class name to apply to the filter list.
56
56
  */
57
57
  className?: string;
58
+ /**
59
+ * Test id for the scrollable list container.
60
+ */
61
+ "data-testid"?: string;
58
62
  }
59
63
  /**
60
64
  * DynamicFilterList is a React component that displays a list of dynamic filters with options like CheckBoxes or Radio buttons.
61
65
  *
62
66
  * @returns {ReactElement} - Returns the DynamicFilterList component.
63
67
  */
64
- export declare const DynamicFilterList: ({ rowCount, keyMapper, labelMapper, onChange, checked, count, showRequestMoreUseSearch, pagination, type, className, }: DynamicFilterListProps) => ReactElement;
68
+ export declare const DynamicFilterList: ({ rowCount, keyMapper, labelMapper, onChange, checked, count, showRequestMoreUseSearch, pagination, type, className, "data-testid": dataTestId, }: DynamicFilterListProps) => ReactElement;
65
69
  export {};