Skip to content

Commit 720198d

Browse files
feat(table): implement range filtering with min/max constraints in TableRangeFilter
1 parent 349b88c commit 720198d

3 files changed

Lines changed: 64 additions & 2 deletions

File tree

apps/demo/src/Views/Ui/components/Table/Table.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ export const TableDemo = () => {
5555
enableSorting: true,
5656
filterPlaceholder: `${t("table.placeholder.min")},${t("table.placeholder.max")}`,
5757
header: "Age",
58+
meta: {
59+
rangeFilterMax: 20,
60+
rangeFilterMin: 1,
61+
},
5862
},
5963
{
6064
accessorKey: "city",

packages/ui/src/FormWidgets/DebouncedInput/index.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { IInputProperties, Input } from "../Input";
1212
export interface DebouncedInputProperties extends IInputProperties {
1313
debounceTime?: number;
1414
onInputChange: (value: number | readonly string[] | string) => void;
15+
sanitizeValue?: (value: string) => string;
1516
}
1617

1718
export const DebouncedInput = forwardRef<
@@ -24,6 +25,7 @@ export const DebouncedInput = forwardRef<
2425
debounceTime = 500,
2526
defaultValue = "",
2627
onInputChange,
28+
sanitizeValue,
2729
type = "text",
2830
...inputProperties
2931
},
@@ -50,7 +52,13 @@ export const DebouncedInput = forwardRef<
5052
}, [debouncedValue]);
5153

5254
const handleInputChange = (event: ChangeEvent<HTMLInputElement>) => {
53-
setInputValue(event.target.value);
55+
let rawValue = event.target.value;
56+
57+
if (sanitizeValue) {
58+
rawValue = sanitizeValue(rawValue);
59+
}
60+
61+
setInputValue(rawValue);
5462
};
5563

5664
return (

packages/ui/src/Table/TableRangeFilter.tsx

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,24 @@ export const TableRangeFilter = <TData,>({
2424
? [...filterValue]
2525
: [undefined, undefined];
2626

27-
currentFilter[index] = value !== "" ? Number(value) : undefined;
27+
const numericValue = value !== "" ? Number(value) : undefined;
28+
29+
if (numericValue !== undefined) {
30+
const { rangeFilterMax, rangeFilterMin } = column.columnDef.meta ?? {};
31+
32+
if (rangeFilterMin !== undefined && numericValue < rangeFilterMin) {
33+
currentFilter[index] = rangeFilterMin;
34+
} else if (
35+
rangeFilterMax !== undefined &&
36+
numericValue > rangeFilterMax
37+
) {
38+
currentFilter[index] = rangeFilterMax;
39+
} else {
40+
currentFilter[index] = numericValue;
41+
}
42+
} else {
43+
currentFilter[index] = undefined;
44+
}
2845

2946
const isFilterActive = currentFilter.some(
3047
(filterInput) => filterInput !== undefined,
@@ -37,6 +54,37 @@ export const TableRangeFilter = <TData,>({
3754
const key = column.id || String(column.columnDef.accessorKey);
3855
const meta = column.columnDef.meta;
3956

57+
const clampRangeValue = (value: string): string => {
58+
if (
59+
meta?.rangeFilterMin === undefined &&
60+
meta?.rangeFilterMax === undefined
61+
) {
62+
return value;
63+
}
64+
65+
const numericValue = Number(value);
66+
67+
if (Number.isNaN(numericValue)) {
68+
return value;
69+
}
70+
71+
if (
72+
meta.rangeFilterMin !== undefined &&
73+
numericValue < meta.rangeFilterMin
74+
) {
75+
return String(meta.rangeFilterMin);
76+
}
77+
78+
if (
79+
meta.rangeFilterMax !== undefined &&
80+
numericValue > meta.rangeFilterMax
81+
) {
82+
return String(meta.rangeFilterMax);
83+
}
84+
85+
return value;
86+
};
87+
4088
return (
4189
<div className="number-range-filter">
4290
<DebouncedInput
@@ -54,6 +102,7 @@ export const TableRangeFilter = <TData,>({
54102
column.columnDef.filterPlaceholder?.split(",")[0] ??
55103
column.columnDef.filterPlaceholder
56104
}
105+
sanitizeValue={clampRangeValue}
57106
type="number"
58107
/>
59108
<DebouncedInput
@@ -71,6 +120,7 @@ export const TableRangeFilter = <TData,>({
71120
column.columnDef.filterPlaceholder?.split(",")[1] ??
72121
column.columnDef.filterPlaceholder
73122
}
123+
sanitizeValue={clampRangeValue}
74124
type="number"
75125
/>
76126
</div>

0 commit comments

Comments
 (0)