You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

寻求shadcn/ui data-table结合日期范围选择器的过滤实现示例

用shadcn/ui Date Range Picker过滤data-table数据的实现方案

核心思路

shadcn/ui的data-table基于TanStack Table,实现日期范围过滤需要两步:

  1. 给日期列配置范围过滤函数
  2. 在Date Range Picker的选择回调中,将选中的日期范围同步为表格列的过滤值

步骤1:配置日期列的自定义过滤函数

TanStack Table默认没有日期范围过滤,需要自定义filterFn处理{from, to}格式的过滤值。假设你的表格数据中日期字段为createdAt:

import { FilterFn } from "@tanstack/react-table";

// 自定义日期范围过滤函数
const dateRangeFilterFn: FilterFn<YourDataType> = (row, columnId, filterValue) => {
  const rowDate = row.getValue(columnId) as Date;
  const { from, to } = filterValue as { from?: Date; to?: Date };

  if (!from && !to) return true; // 无过滤条件时显示所有数据
  if (from && to) return rowDate >= from && rowDate <= to;
  if (from) return rowDate >= from;
  if (to) return rowDate <= to;
  return true;
};

// 表格列配置
const columns = [
  // 其他列...
  {
    accessorKey: "createdAt",
    header: "创建日期",
    cell: ({ row }) => format(row.getValue("createdAt"), "LLL dd, y"),
    filterFn: dateRangeFilterFn, // 绑定自定义过滤函数
  },
];

步骤2:修改Date Range Picker的选择回调

将选中的日期范围同步到表格的过滤状态中,替换你原来的setDate逻辑:

import { useState } from "react";
import { useReactTable } from "@tanstack/react-table";

// 初始化表格实例,必须开启过滤功能
const table = useReactTable({
  data: yourTableData,
  columns,
  enableFilters: true,
  // 其他配置...
});

// 日期范围状态
const [date, setDate] = useState<{ from?: Date; to?: Date } | undefined>(undefined);

// 处理日期选择的回调
const handleDateSelect = (selectedDate: { from?: Date; to?: Date } | undefined) => {
  setDate(selectedDate);
  // 将选中的日期范围设置为日期列的过滤值
  table.getColumn("createdAt")?.setFilterValue(selectedDate);
};

// 修改你的Date Range Picker组件,替换onSelect为自定义回调
<div className={cn("grid gap-2", className)}>
  <Popover>
    <PopoverTrigger asChild>
      <Button
        id="date"
        variant="outline"
        className={cn(
          "w-[300px] justify-start text-left font-normal",
          !date && "text-muted-foreground"
        )}
      >
        <CalendarIcon className="mr-2 h-4 w-4" />
        {date?.from ? (
          date.to ? (
            <>
              {format(date.from, "LLL dd, y")} -{" "}
              {format(date.to, "LLL dd, y")}
            </>
          ) : (
            format(date.from, "LLL dd, y")
          )
        ) : (
          <span>Pick a date</span>
        )}
      </Button>
    </PopoverTrigger>
    <PopoverContent className="w-auto p-0" align="start">
      <Calendar
        initialFocus
        mode="range"
        defaultMonth={date?.from}
        selected={date}
        onSelect={handleDateSelect} // 替换为自定义回调
        numberOfMonths={2}
      />
    </PopoverContent>
  </Popover>
</div>

步骤3:处理清空过滤

如果需要手动清空日期过滤,可以添加一个清空按钮:

<Button
  variant="ghost"
  size="sm"
  onClick={() => {
    setDate(undefined);
    table.getColumn("createdAt")?.setFilterValue(undefined);
  }}
>
  清空日期过滤
</Button>

关键注意点

  • 确保表格配置中enableFilters为true,否则过滤功能不生效
  • 过滤值是{from?: Date; to?: Date}格式的对象,filterFn需对应处理这种类型
  • 表格数据中的日期需为Date类型,如果是字符串需要先转换

内容的提问来源于stack exchange,提问作者Daryll santos

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 03:10:38