@trackunit/filters-filter-bar 2.6.42 → 2.6.45
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
|
@@ -706,6 +706,24 @@ const useFiltersMenu = ({ filterBarDefinition, filterBarConfig, hiddenFilters =
|
|
|
706
706
|
]);
|
|
707
707
|
};
|
|
708
708
|
|
|
709
|
+
/**
|
|
710
|
+
* The filters menu's search box, registered as the menu's first keyboard stop so ArrowDown enters
|
|
711
|
+
* the filter rows and ArrowUp from the first row comes back here.
|
|
712
|
+
*
|
|
713
|
+
* It is a component rather than a few lines in `FiltersMenuContent` because `useMenuSearchField`
|
|
714
|
+
* registers through Floating UI's `FloatingList`, whose context `MenuContent` opens around its
|
|
715
|
+
* children -- a caller that also renders the `MenuContent` sits outside that context and registers
|
|
716
|
+
* nothing.
|
|
717
|
+
*
|
|
718
|
+
* @param {FiltersMenuSearchFieldProps} props The current query, its setter, and the id of the list this field filters
|
|
719
|
+
* @returns {ReactElement} The registered search input
|
|
720
|
+
*/
|
|
721
|
+
const FiltersMenuSearchField = ({ searchText, setSearchText, filtersListId, }) => {
|
|
722
|
+
const [t] = useTranslation();
|
|
723
|
+
const { getSearchFieldProps } = reactComponents.useMenuSearchField();
|
|
724
|
+
return (jsxRuntime.jsx(reactFormComponents.Search, { "aria-controls": filtersListId, "data-testid": "starred-filters-menu-search", fieldSize: "small", id: "search-filters-list", onChange: e => setSearchText(e.currentTarget.value), onClear: () => setSearchText(""), placeholder: t("filtersBar.searchFiltersPlaceholder"), value: searchText, ...getSearchFieldProps() }));
|
|
725
|
+
};
|
|
726
|
+
|
|
709
727
|
const FilterGroupSection = ({ filterBarConfig, group, showSeparator, showTitle, }) => {
|
|
710
728
|
const titleId = react.useId();
|
|
711
729
|
return (jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [jsxRuntime.jsxs("div", { children: [showTitle ? (jsxRuntime.jsx(reactComponents.Text, { className: "h-7 p-2 text-neutral-400", "data-testid": `${group.key}-group-title`, id: titleId, size: "small", uppercase: true, weight: "bold", children: group.title })) : null, jsxRuntime.jsx("div", { "aria-labelledby": showTitle ? titleId : undefined, className: "grid", "data-testid": `${group.key}-group-list`, role: "group", children: jsxRuntime.jsx(FiltersRenderer, { filterBarConfig: filterBarConfig, filters: group.filters, visualStyle: "list-item" }) })] }), showSeparator ? jsxRuntime.jsx(reactComponents.MenuDivider, {}) : null] }));
|
|
@@ -732,75 +750,6 @@ const ResetFiltersButton = ({ resetFiltersToInitialState, "data-testid": dataTes
|
|
|
732
750
|
}, ref: ref, size: "small", style: style, variant: "ghost", children: [t("filtersBar.resetFilters"), jsxRuntime.jsx("span", { className: "sr-only", children: t("filtersBar.resetFiltersSR") })] }));
|
|
733
751
|
};
|
|
734
752
|
|
|
735
|
-
const firstEnabledMenuItem = (root) => root?.querySelector('[role="menuitem"]:not([aria-disabled="true"])') ?? null;
|
|
736
|
-
/**
|
|
737
|
-
* Bridges Search and the registered FilterBar rows: Down from Search enters the first matching
|
|
738
|
-
* item; Up from that item returns to Search. Initial focus lands on Search when it is shown,
|
|
739
|
-
* otherwise on the first enabled row.
|
|
740
|
-
*
|
|
741
|
-
* @returns {UseFiltersMenuSearchNavigationResult} Search ref, panel-node callback, and Search ArrowDown handler
|
|
742
|
-
*/
|
|
743
|
-
const useFiltersMenuSearchNavigation = ({ showSearch, }) => {
|
|
744
|
-
const searchInputRef = react.useRef(null);
|
|
745
|
-
const panelRef = react.useRef(null);
|
|
746
|
-
const onPanelArrowUp = react.useCallback((event) => {
|
|
747
|
-
if (event.key !== "ArrowUp") {
|
|
748
|
-
return;
|
|
749
|
-
}
|
|
750
|
-
const firstItem = firstEnabledMenuItem(panelRef.current);
|
|
751
|
-
const active = document.activeElement;
|
|
752
|
-
if (firstItem && active && (active === firstItem || firstItem.contains(active))) {
|
|
753
|
-
// Capture on the menu root so this wins over useListNavigation's
|
|
754
|
-
// loop:true wrap (React onKeyDown on the floating element).
|
|
755
|
-
event.preventDefault();
|
|
756
|
-
event.stopImmediatePropagation();
|
|
757
|
-
searchInputRef.current?.focus();
|
|
758
|
-
}
|
|
759
|
-
}, []);
|
|
760
|
-
const setPanelNode = react.useCallback((node) => {
|
|
761
|
-
if (panelRef.current) {
|
|
762
|
-
panelRef.current.removeEventListener("keydown", onPanelArrowUp, true);
|
|
763
|
-
}
|
|
764
|
-
panelRef.current = node;
|
|
765
|
-
if (node && showSearch) {
|
|
766
|
-
// Attach here, not in an effect: MenuContent's ref is set after the
|
|
767
|
-
// first paint, and a [showSearch]-only effect can snapshot a null panel.
|
|
768
|
-
node.addEventListener("keydown", onPanelArrowUp, true);
|
|
769
|
-
}
|
|
770
|
-
}, [onPanelArrowUp, showSearch]);
|
|
771
|
-
react.useEffect(() => {
|
|
772
|
-
const focusInitialTarget = () => {
|
|
773
|
-
if (showSearch) {
|
|
774
|
-
searchInputRef.current?.focus();
|
|
775
|
-
return;
|
|
776
|
-
}
|
|
777
|
-
firstEnabledMenuItem(panelRef.current)?.focus();
|
|
778
|
-
};
|
|
779
|
-
// Floating UI's default initialFocus is 0 (the trigger). FilterBar cannot
|
|
780
|
-
// use initialFocus={1}: that would land on Reset when Search is hidden.
|
|
781
|
-
const frame = requestAnimationFrame(focusInitialTarget);
|
|
782
|
-
return () => cancelAnimationFrame(frame);
|
|
783
|
-
}, [showSearch]);
|
|
784
|
-
const handleSearchKeyDown = react.useCallback((event) => {
|
|
785
|
-
if (event.key !== "ArrowDown") {
|
|
786
|
-
return;
|
|
787
|
-
}
|
|
788
|
-
const firstItem = firstEnabledMenuItem(panelRef.current);
|
|
789
|
-
if (firstItem) {
|
|
790
|
-
// Stop list-navigation from owning this ArrowDown so activeIndex stays
|
|
791
|
-
// unset and ArrowUp from the first row can return to Search.
|
|
792
|
-
event.preventDefault();
|
|
793
|
-
event.stopPropagation();
|
|
794
|
-
firstItem.focus();
|
|
795
|
-
}
|
|
796
|
-
}, []);
|
|
797
|
-
return react.useMemo(() => ({
|
|
798
|
-
searchInputRef,
|
|
799
|
-
setPanelNode,
|
|
800
|
-
handleSearchKeyDown,
|
|
801
|
-
}), [setPanelNode, handleSearchKeyDown]);
|
|
802
|
-
};
|
|
803
|
-
|
|
804
753
|
/**
|
|
805
754
|
*
|
|
806
755
|
*/
|
|
@@ -808,25 +757,13 @@ const FiltersMenuContent = ({ filterBarConfig, setShowCustomFilters, setSearchTe
|
|
|
808
757
|
const [t] = useTranslation();
|
|
809
758
|
const filtersListId = react.useId();
|
|
810
759
|
const showSearch = filterBarDefinitionCount > 5;
|
|
811
|
-
const { searchInputRef, setPanelNode, handleSearchKeyDown } = useFiltersMenuSearchNavigation({
|
|
812
|
-
showSearch,
|
|
813
|
-
});
|
|
814
|
-
const setPanelRef = react.useCallback((node) => {
|
|
815
|
-
setPanelNode(node);
|
|
816
|
-
if (typeof ref === "function") {
|
|
817
|
-
ref(node);
|
|
818
|
-
}
|
|
819
|
-
else if (ref) {
|
|
820
|
-
ref.current = node;
|
|
821
|
-
}
|
|
822
|
-
}, [setPanelNode, ref]);
|
|
823
760
|
const visibleGroups = searchText
|
|
824
761
|
? searchResultsGrouped
|
|
825
762
|
: showCustomFilters
|
|
826
763
|
? filtersToShowGrouped
|
|
827
764
|
: removeCustomFieldsGroup(filtersToShowGrouped);
|
|
828
765
|
const hasVisibleFilters = visibleGroups.some(group => group.filters.length > 0);
|
|
829
|
-
return (jsxRuntime.jsxs(reactComponents.MenuContent, { "aria-label": t("filtersBar.filtersHeading"), className: tailwindMerge.twMerge("max-h-[min(600px,calc(100dvh-32px))] grid-rows-[minmax(0,1fr)] overflow-y-hidden p-0", className), "data-testid": dataTestId, listClassName: "grid-rows-min-fr !max-h-none min-h-0 gap-y-0 !overflow-y-hidden p-0", ref:
|
|
766
|
+
return (jsxRuntime.jsxs(reactComponents.MenuContent, { "aria-label": t("filtersBar.filtersHeading"), autoFocus: true, className: tailwindMerge.twMerge("max-h-[min(600px,calc(100dvh-32px))] grid-rows-[minmax(0,1fr)] overflow-y-hidden p-0", className), "data-testid": dataTestId, listClassName: "grid-rows-min-fr !max-h-none min-h-0 gap-y-0 !overflow-y-hidden p-0", ref: ref, style: style, children: [jsxRuntime.jsxs("div", { children: [jsxRuntime.jsxs("div", { className: "flex flex-col gap-1 p-1", children: [showSearch ? (jsxRuntime.jsx(FiltersMenuSearchField, { filtersListId: filtersListId, searchText: searchText, setSearchText: setSearchText })) : null, jsxRuntime.jsxs("div", { className: "flex h-7 items-center justify-between gap-1 pl-3", children: [jsxRuntime.jsx(reactComponents.Text, { className: "text-neutral-400", size: "small", children: jsxRuntime.jsx(FiltersAppliedCountLabel, { filterBarConfig: filterBarConfig }) }), filterBarConfig.appliedFilterKeys().length > 0 ? (jsxRuntime.jsx(ResetFiltersButton, { resetFiltersToInitialState: filterBarConfig.resetFiltersToInitialState })) : null] })] }), jsxRuntime.jsx(reactComponents.MenuDivider, {})] }), jsxRuntime.jsxs("div", { className: "flex min-h-0 flex-col gap-1 overflow-auto p-1", "data-testid": "starred-filters-menu-list", id: filtersListId, children: [searchText && !hasVisibleFilters ? (jsxRuntime.jsx("div", { "aria-live": "polite", role: "status", children: jsxRuntime.jsx(reactComponents.Text, { className: "p-2 text-neutral-400", size: "small", children: t("filtersBar.emptyResults") }) })) : (jsxRuntime.jsx(GroupedFiltersList, { className: "flex flex-col gap-1", filterBarConfig: filterBarConfig, filtersGrouped: visibleGroups })), hasCustomFields && !showCustomFilters && !searchText ? (jsxRuntime.jsx(CustomFieldsHiddenGroup, { appliedCustomFields: appliedCustomFields, filterBarConfig: filterBarConfig, filtersListId: filtersListId, onClickShow: () => {
|
|
830
767
|
setShowCustomFilters(true);
|
|
831
768
|
} })) : null] })] }));
|
|
832
769
|
};
|
package/index.esm.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
|
|
2
2
|
import { registerTranslations, useNamespaceTranslation } from '@trackunit/i18n-library-translation';
|
|
3
|
-
import { useMemo, useState, useEffect, useCallback, useId,
|
|
3
|
+
import { useMemo, useState, useEffect, useCallback, useId, Fragment as Fragment$1, useRef } from 'react';
|
|
4
4
|
import { twMerge } from 'tailwind-merge';
|
|
5
5
|
import { Filter, FilterBody, RadioFilterItem, CheckBoxFilterItem, FilterHeader as FilterHeader$1, FilterFooter } from '@trackunit/react-filter-components';
|
|
6
|
-
import { Button, Icon, useList, List, Text, useTextSearch, MenuDivider, MenuContent, ZStack, IconButton, Badge, useViewportBreakpoints, MenuTree, Popover, PopoverTrigger, Tooltip, PopoverContent, useCustomEncoding, useSearchParamSync, useStorageKey, useWatch } from '@trackunit/react-components';
|
|
6
|
+
import { Button, Icon, useList, List, Text, useTextSearch, useMenuSearchField, MenuDivider, MenuContent, ZStack, IconButton, Badge, useViewportBreakpoints, MenuTree, Popover, PopoverTrigger, Tooltip, PopoverContent, useCustomEncoding, useSearchParamSync, useStorageKey, useWatch } from '@trackunit/react-components';
|
|
7
7
|
import { useAnalytics, useCurrentUser } from '@trackunit/react-core-hooks';
|
|
8
8
|
import { capitalize } from 'string-ts';
|
|
9
9
|
import { createEvent } from '@trackunit/iris-app-runtime-core-api';
|
|
@@ -704,6 +704,24 @@ const useFiltersMenu = ({ filterBarDefinition, filterBarConfig, hiddenFilters =
|
|
|
704
704
|
]);
|
|
705
705
|
};
|
|
706
706
|
|
|
707
|
+
/**
|
|
708
|
+
* The filters menu's search box, registered as the menu's first keyboard stop so ArrowDown enters
|
|
709
|
+
* the filter rows and ArrowUp from the first row comes back here.
|
|
710
|
+
*
|
|
711
|
+
* It is a component rather than a few lines in `FiltersMenuContent` because `useMenuSearchField`
|
|
712
|
+
* registers through Floating UI's `FloatingList`, whose context `MenuContent` opens around its
|
|
713
|
+
* children -- a caller that also renders the `MenuContent` sits outside that context and registers
|
|
714
|
+
* nothing.
|
|
715
|
+
*
|
|
716
|
+
* @param {FiltersMenuSearchFieldProps} props The current query, its setter, and the id of the list this field filters
|
|
717
|
+
* @returns {ReactElement} The registered search input
|
|
718
|
+
*/
|
|
719
|
+
const FiltersMenuSearchField = ({ searchText, setSearchText, filtersListId, }) => {
|
|
720
|
+
const [t] = useTranslation();
|
|
721
|
+
const { getSearchFieldProps } = useMenuSearchField();
|
|
722
|
+
return (jsx(Search, { "aria-controls": filtersListId, "data-testid": "starred-filters-menu-search", fieldSize: "small", id: "search-filters-list", onChange: e => setSearchText(e.currentTarget.value), onClear: () => setSearchText(""), placeholder: t("filtersBar.searchFiltersPlaceholder"), value: searchText, ...getSearchFieldProps() }));
|
|
723
|
+
};
|
|
724
|
+
|
|
707
725
|
const FilterGroupSection = ({ filterBarConfig, group, showSeparator, showTitle, }) => {
|
|
708
726
|
const titleId = useId();
|
|
709
727
|
return (jsxs("div", { className: "flex flex-col gap-1", children: [jsxs("div", { children: [showTitle ? (jsx(Text, { className: "h-7 p-2 text-neutral-400", "data-testid": `${group.key}-group-title`, id: titleId, size: "small", uppercase: true, weight: "bold", children: group.title })) : null, jsx("div", { "aria-labelledby": showTitle ? titleId : undefined, className: "grid", "data-testid": `${group.key}-group-list`, role: "group", children: jsx(FiltersRenderer, { filterBarConfig: filterBarConfig, filters: group.filters, visualStyle: "list-item" }) })] }), showSeparator ? jsx(MenuDivider, {}) : null] }));
|
|
@@ -730,75 +748,6 @@ const ResetFiltersButton = ({ resetFiltersToInitialState, "data-testid": dataTes
|
|
|
730
748
|
}, ref: ref, size: "small", style: style, variant: "ghost", children: [t("filtersBar.resetFilters"), jsx("span", { className: "sr-only", children: t("filtersBar.resetFiltersSR") })] }));
|
|
731
749
|
};
|
|
732
750
|
|
|
733
|
-
const firstEnabledMenuItem = (root) => root?.querySelector('[role="menuitem"]:not([aria-disabled="true"])') ?? null;
|
|
734
|
-
/**
|
|
735
|
-
* Bridges Search and the registered FilterBar rows: Down from Search enters the first matching
|
|
736
|
-
* item; Up from that item returns to Search. Initial focus lands on Search when it is shown,
|
|
737
|
-
* otherwise on the first enabled row.
|
|
738
|
-
*
|
|
739
|
-
* @returns {UseFiltersMenuSearchNavigationResult} Search ref, panel-node callback, and Search ArrowDown handler
|
|
740
|
-
*/
|
|
741
|
-
const useFiltersMenuSearchNavigation = ({ showSearch, }) => {
|
|
742
|
-
const searchInputRef = useRef(null);
|
|
743
|
-
const panelRef = useRef(null);
|
|
744
|
-
const onPanelArrowUp = useCallback((event) => {
|
|
745
|
-
if (event.key !== "ArrowUp") {
|
|
746
|
-
return;
|
|
747
|
-
}
|
|
748
|
-
const firstItem = firstEnabledMenuItem(panelRef.current);
|
|
749
|
-
const active = document.activeElement;
|
|
750
|
-
if (firstItem && active && (active === firstItem || firstItem.contains(active))) {
|
|
751
|
-
// Capture on the menu root so this wins over useListNavigation's
|
|
752
|
-
// loop:true wrap (React onKeyDown on the floating element).
|
|
753
|
-
event.preventDefault();
|
|
754
|
-
event.stopImmediatePropagation();
|
|
755
|
-
searchInputRef.current?.focus();
|
|
756
|
-
}
|
|
757
|
-
}, []);
|
|
758
|
-
const setPanelNode = useCallback((node) => {
|
|
759
|
-
if (panelRef.current) {
|
|
760
|
-
panelRef.current.removeEventListener("keydown", onPanelArrowUp, true);
|
|
761
|
-
}
|
|
762
|
-
panelRef.current = node;
|
|
763
|
-
if (node && showSearch) {
|
|
764
|
-
// Attach here, not in an effect: MenuContent's ref is set after the
|
|
765
|
-
// first paint, and a [showSearch]-only effect can snapshot a null panel.
|
|
766
|
-
node.addEventListener("keydown", onPanelArrowUp, true);
|
|
767
|
-
}
|
|
768
|
-
}, [onPanelArrowUp, showSearch]);
|
|
769
|
-
useEffect(() => {
|
|
770
|
-
const focusInitialTarget = () => {
|
|
771
|
-
if (showSearch) {
|
|
772
|
-
searchInputRef.current?.focus();
|
|
773
|
-
return;
|
|
774
|
-
}
|
|
775
|
-
firstEnabledMenuItem(panelRef.current)?.focus();
|
|
776
|
-
};
|
|
777
|
-
// Floating UI's default initialFocus is 0 (the trigger). FilterBar cannot
|
|
778
|
-
// use initialFocus={1}: that would land on Reset when Search is hidden.
|
|
779
|
-
const frame = requestAnimationFrame(focusInitialTarget);
|
|
780
|
-
return () => cancelAnimationFrame(frame);
|
|
781
|
-
}, [showSearch]);
|
|
782
|
-
const handleSearchKeyDown = useCallback((event) => {
|
|
783
|
-
if (event.key !== "ArrowDown") {
|
|
784
|
-
return;
|
|
785
|
-
}
|
|
786
|
-
const firstItem = firstEnabledMenuItem(panelRef.current);
|
|
787
|
-
if (firstItem) {
|
|
788
|
-
// Stop list-navigation from owning this ArrowDown so activeIndex stays
|
|
789
|
-
// unset and ArrowUp from the first row can return to Search.
|
|
790
|
-
event.preventDefault();
|
|
791
|
-
event.stopPropagation();
|
|
792
|
-
firstItem.focus();
|
|
793
|
-
}
|
|
794
|
-
}, []);
|
|
795
|
-
return useMemo(() => ({
|
|
796
|
-
searchInputRef,
|
|
797
|
-
setPanelNode,
|
|
798
|
-
handleSearchKeyDown,
|
|
799
|
-
}), [setPanelNode, handleSearchKeyDown]);
|
|
800
|
-
};
|
|
801
|
-
|
|
802
751
|
/**
|
|
803
752
|
*
|
|
804
753
|
*/
|
|
@@ -806,25 +755,13 @@ const FiltersMenuContent = ({ filterBarConfig, setShowCustomFilters, setSearchTe
|
|
|
806
755
|
const [t] = useTranslation();
|
|
807
756
|
const filtersListId = useId();
|
|
808
757
|
const showSearch = filterBarDefinitionCount > 5;
|
|
809
|
-
const { searchInputRef, setPanelNode, handleSearchKeyDown } = useFiltersMenuSearchNavigation({
|
|
810
|
-
showSearch,
|
|
811
|
-
});
|
|
812
|
-
const setPanelRef = useCallback((node) => {
|
|
813
|
-
setPanelNode(node);
|
|
814
|
-
if (typeof ref === "function") {
|
|
815
|
-
ref(node);
|
|
816
|
-
}
|
|
817
|
-
else if (ref) {
|
|
818
|
-
ref.current = node;
|
|
819
|
-
}
|
|
820
|
-
}, [setPanelNode, ref]);
|
|
821
758
|
const visibleGroups = searchText
|
|
822
759
|
? searchResultsGrouped
|
|
823
760
|
: showCustomFilters
|
|
824
761
|
? filtersToShowGrouped
|
|
825
762
|
: removeCustomFieldsGroup(filtersToShowGrouped);
|
|
826
763
|
const hasVisibleFilters = visibleGroups.some(group => group.filters.length > 0);
|
|
827
|
-
return (jsxs(MenuContent, { "aria-label": t("filtersBar.filtersHeading"), className: twMerge("max-h-[min(600px,calc(100dvh-32px))] grid-rows-[minmax(0,1fr)] overflow-y-hidden p-0", className), "data-testid": dataTestId, listClassName: "grid-rows-min-fr !max-h-none min-h-0 gap-y-0 !overflow-y-hidden p-0", ref:
|
|
764
|
+
return (jsxs(MenuContent, { "aria-label": t("filtersBar.filtersHeading"), autoFocus: true, className: twMerge("max-h-[min(600px,calc(100dvh-32px))] grid-rows-[minmax(0,1fr)] overflow-y-hidden p-0", className), "data-testid": dataTestId, listClassName: "grid-rows-min-fr !max-h-none min-h-0 gap-y-0 !overflow-y-hidden p-0", ref: ref, style: style, children: [jsxs("div", { children: [jsxs("div", { className: "flex flex-col gap-1 p-1", children: [showSearch ? (jsx(FiltersMenuSearchField, { filtersListId: filtersListId, searchText: searchText, setSearchText: setSearchText })) : null, jsxs("div", { className: "flex h-7 items-center justify-between gap-1 pl-3", children: [jsx(Text, { className: "text-neutral-400", size: "small", children: jsx(FiltersAppliedCountLabel, { filterBarConfig: filterBarConfig }) }), filterBarConfig.appliedFilterKeys().length > 0 ? (jsx(ResetFiltersButton, { resetFiltersToInitialState: filterBarConfig.resetFiltersToInitialState })) : null] })] }), jsx(MenuDivider, {})] }), jsxs("div", { className: "flex min-h-0 flex-col gap-1 overflow-auto p-1", "data-testid": "starred-filters-menu-list", id: filtersListId, children: [searchText && !hasVisibleFilters ? (jsx("div", { "aria-live": "polite", role: "status", children: jsx(Text, { className: "p-2 text-neutral-400", size: "small", children: t("filtersBar.emptyResults") }) })) : (jsx(GroupedFiltersList, { className: "flex flex-col gap-1", filterBarConfig: filterBarConfig, filtersGrouped: visibleGroups })), hasCustomFields && !showCustomFilters && !searchText ? (jsx(CustomFieldsHiddenGroup, { appliedCustomFields: appliedCustomFields, filterBarConfig: filterBarConfig, filtersListId: filtersListId, onClickShow: () => {
|
|
828
765
|
setShowCustomFilters(true);
|
|
829
766
|
} })) : null] })] }));
|
|
830
767
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@trackunit/filters-filter-bar",
|
|
3
|
-
"version": "2.6.
|
|
3
|
+
"version": "2.6.45",
|
|
4
4
|
"repository": "https://github.com/Trackunit/manager",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
6
6
|
"engines": {
|
|
@@ -11,17 +11,17 @@
|
|
|
11
11
|
"tailwind-merge": "^2.0.0",
|
|
12
12
|
"string-ts": "^2.0.0",
|
|
13
13
|
"zod": "^3.25.76",
|
|
14
|
-
"@trackunit/iris-app-api": "2.4.
|
|
15
|
-
"@trackunit/react-core-hooks": "1.21.
|
|
16
|
-
"@trackunit/react-filter-components": "2.6.
|
|
17
|
-
"@trackunit/react-date-and-time-components": "2.6.
|
|
18
|
-
"@trackunit/shared-utils": "1.16.
|
|
19
|
-
"@trackunit/react-form-components": "2.6.
|
|
20
|
-
"@trackunit/iris-app-runtime-core-api": "1.17.
|
|
21
|
-
"@trackunit/geo-json-utils": "1.15.
|
|
22
|
-
"@trackunit/i18n-library-translation": "2.4.
|
|
23
|
-
"@trackunit/css-class-variance-utilities": "1.14.
|
|
24
|
-
"@trackunit/react-components": "2.11.
|
|
14
|
+
"@trackunit/iris-app-api": "2.4.29",
|
|
15
|
+
"@trackunit/react-core-hooks": "1.21.38",
|
|
16
|
+
"@trackunit/react-filter-components": "2.6.44",
|
|
17
|
+
"@trackunit/react-date-and-time-components": "2.6.44",
|
|
18
|
+
"@trackunit/shared-utils": "1.16.30",
|
|
19
|
+
"@trackunit/react-form-components": "2.6.44",
|
|
20
|
+
"@trackunit/iris-app-runtime-core-api": "1.17.38",
|
|
21
|
+
"@trackunit/geo-json-utils": "1.15.29",
|
|
22
|
+
"@trackunit/i18n-library-translation": "2.4.38",
|
|
23
|
+
"@trackunit/css-class-variance-utilities": "1.14.27",
|
|
24
|
+
"@trackunit/react-components": "2.11.6"
|
|
25
25
|
},
|
|
26
26
|
"peerDependencies": {
|
|
27
27
|
"@apollo/client": "^3.13.8",
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { ReactElement } from "react";
|
|
2
|
+
interface FiltersMenuSearchFieldProps {
|
|
3
|
+
searchText: string;
|
|
4
|
+
setSearchText: (text: string) => void;
|
|
5
|
+
filtersListId: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* The filters menu's search box, registered as the menu's first keyboard stop so ArrowDown enters
|
|
9
|
+
* the filter rows and ArrowUp from the first row comes back here.
|
|
10
|
+
*
|
|
11
|
+
* It is a component rather than a few lines in `FiltersMenuContent` because `useMenuSearchField`
|
|
12
|
+
* registers through Floating UI's `FloatingList`, whose context `MenuContent` opens around its
|
|
13
|
+
* children -- a caller that also renders the `MenuContent` sits outside that context and registers
|
|
14
|
+
* nothing.
|
|
15
|
+
*
|
|
16
|
+
* @param {FiltersMenuSearchFieldProps} props The current query, its setter, and the id of the list this field filters
|
|
17
|
+
* @returns {ReactElement} The registered search input
|
|
18
|
+
*/
|
|
19
|
+
export declare const FiltersMenuSearchField: ({ searchText, setSearchText, filtersListId, }: FiltersMenuSearchFieldProps) => ReactElement;
|
|
20
|
+
export {};
|
package/migrations/entry.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"entry.js","sourceRoot":"","sources":["../../../../../libs/filters/filter-bar/migrations/entry.ts"],"names":[],"mappings":"","sourcesContent":["export {};\n"]}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { KeyboardEvent, Ref, RefCallback } from "react";
|
|
2
|
-
export interface UseFiltersMenuSearchNavigationResult {
|
|
3
|
-
searchInputRef: Ref<HTMLInputElement>;
|
|
4
|
-
setPanelNode: RefCallback<HTMLDivElement>;
|
|
5
|
-
handleSearchKeyDown: (event: KeyboardEvent<HTMLInputElement>) => void;
|
|
6
|
-
}
|
|
7
|
-
/**
|
|
8
|
-
* Bridges Search and the registered FilterBar rows: Down from Search enters the first matching
|
|
9
|
-
* item; Up from that item returns to Search. Initial focus lands on Search when it is shown,
|
|
10
|
-
* otherwise on the first enabled row.
|
|
11
|
-
*
|
|
12
|
-
* @returns {UseFiltersMenuSearchNavigationResult} Search ref, panel-node callback, and Search ArrowDown handler
|
|
13
|
-
*/
|
|
14
|
-
export declare const useFiltersMenuSearchNavigation: ({ showSearch, }: {
|
|
15
|
-
showSearch: boolean;
|
|
16
|
-
}) => UseFiltersMenuSearchNavigationResult;
|