feat: open dropdown right after adding a filter (#20819)
* feat: open dropdown right after adding a filter * clean up timeout
This commit is contained in:
1 parent
cf83b0a236
commit
9004dcb93b
4 files changed
+45
-2
No files matched your search
@@ -23,6 +23,7 @@ import { CTA_CONTAINER_CLASS_NAME } from "./lib/utils";
|
||||
export type DataTableContextType = {
|
||||
tableIdentifier: string;
|
||||
ctaContainerRef: React.RefObject<HTMLDivElement>;
|
||||
filterToOpen: React.MutableRefObject<string | undefined>;
|
||||
|
||||
activeFilters: ActiveFilters;
|
||||
clearAll: (exclude?: string[]) => void;
|
||||
@@ -81,6 +82,7 @@ export function DataTableProvider({
|
||||
defaultPageSize = DEFAULT_PAGE_SIZE,
|
||||
ctaContainerClassName = CTA_CONTAINER_CLASS_NAME,
|
||||
}: DataTableProviderProps) {
|
||||
const filterToOpen = useRef<string | undefined>(undefined);
|
||||
const [activeFilters, setActiveFilters] = useQueryState(
|
||||
"activeFilters",
|
||||
parseAsArrayOf(parseAsJson(ZActiveFilter.parse)).withDefault(DEFAULT_ACTIVE_FILTERS)
|
||||
@@ -216,6 +218,7 @@ export function DataTableProvider({
|
||||
value={{
|
||||
tableIdentifier,
|
||||
ctaContainerRef,
|
||||
filterToOpen,
|
||||
activeFilters,
|
||||
addFilter,
|
||||
clearAll,
|
||||
|
||||
@@ -30,6 +30,7 @@ import {
|
||||
} from "../../lib/dateRange";
|
||||
import type { FilterableColumn, DateRangeFilterOptions } from "../../lib/types";
|
||||
import { ZDateRangeFilterValue, ColumnFilterType } from "../../lib/types";
|
||||
import { useFilterPopoverOpen } from "./useFilterPopoverOpen";
|
||||
|
||||
type DateRangeFilterProps = {
|
||||
column: Extract<FilterableColumn, { type: ColumnFilterType.DATE_RANGE }>;
|
||||
@@ -38,6 +39,7 @@ type DateRangeFilterProps = {
|
||||
};
|
||||
|
||||
export const DateRangeFilter = ({ column, options, showClearButton = false }: DateRangeFilterProps) => {
|
||||
const { open, onOpenChange } = useFilterPopoverOpen(column.id);
|
||||
const filterValue = useFilterValue(column.id, ZDateRangeFilterValue);
|
||||
const { updateFilter, removeFilter } = useDataTable();
|
||||
const range = options?.range ?? "past";
|
||||
@@ -136,7 +138,7 @@ export const DateRangeFilter = ({ column, options, showClearButton = false }: Da
|
||||
}
|
||||
|
||||
return (
|
||||
<Popover>
|
||||
<Popover open={open} onOpenChange={onOpenChange}>
|
||||
<PopoverTrigger asChild>
|
||||
<Button
|
||||
color="secondary"
|
||||
|
||||
@@ -15,6 +15,7 @@ import {
|
||||
isNumberFilterValue,
|
||||
} from "../../lib/utils";
|
||||
import { FilterOptions } from "./FilterOptions";
|
||||
import { useFilterPopoverOpen } from "./useFilterPopoverOpen";
|
||||
import { numberFilterOperatorOptions, useTextFilterOperatorOptions } from "./utils";
|
||||
|
||||
const FILTER_ICONS: Record<ColumnFilterType, IconName> = {
|
||||
@@ -132,9 +133,10 @@ function AppliedFilterValue({
|
||||
export function FilterPopover({ column }: FilterPopoverProps) {
|
||||
const icon = column.icon || FILTER_ICONS[column.type];
|
||||
const filterValue = useFilterValue(column.id, ZFilterValue);
|
||||
const { open, onOpenChange } = useFilterPopoverOpen(column.id);
|
||||
|
||||
return (
|
||||
<Popover>
|
||||
<Popover open={open} onOpenChange={onOpenChange}>
|
||||
<PopoverTrigger asChild>
|
||||
<Button
|
||||
color="secondary"
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
import { useState, useEffect, useCallback } from "react";
|
||||
|
||||
import { useDataTable } from "../../hooks";
|
||||
|
||||
export function useFilterPopoverOpen(columnId: string) {
|
||||
const { filterToOpen } = useDataTable();
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
let timeoutId: NodeJS.Timeout | undefined;
|
||||
|
||||
if (filterToOpen.current === columnId) {
|
||||
timeoutId = setTimeout(() => {
|
||||
setOpen(true);
|
||||
}, 0);
|
||||
}
|
||||
|
||||
return () => {
|
||||
if (timeoutId) {
|
||||
clearTimeout(timeoutId);
|
||||
}
|
||||
};
|
||||
}, [filterToOpen, columnId]);
|
||||
|
||||
const onOpenChange = useCallback(
|
||||
(open: boolean) => {
|
||||
if (filterToOpen.current === columnId && !open) {
|
||||
filterToOpen.current = undefined;
|
||||
}
|
||||
setOpen(open);
|
||||
},
|
||||
[filterToOpen, columnId]
|
||||
);
|
||||
|
||||
return { open, onOpenChange };
|
||||
}
|
||||
Reference in new issue
Block a user