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:
Eunjae Lee authored and GitHub committed 2025-04-22 15:29:56 +00:00
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 };
}