diff --git a/apps/demo/src/Views/Ui/components/Table/Table.tsx b/apps/demo/src/Views/Ui/components/Table/Table.tsx index 073406d91..f3a97403b 100644 --- a/apps/demo/src/Views/Ui/components/Table/Table.tsx +++ b/apps/demo/src/Views/Ui/components/Table/Table.tsx @@ -55,6 +55,10 @@ export const TableDemo = () => { enableSorting: true, filterPlaceholder: `${t("table.placeholder.min")},${t("table.placeholder.max")}`, header: "Age", + meta: { + rangeFilterMax: 100, + rangeFilterMin: 1, + }, }, { accessorKey: "city", diff --git a/packages/ui/src/FormWidgets/DebouncedInput/index.tsx b/packages/ui/src/FormWidgets/DebouncedInput/index.tsx index b30325119..f497e0545 100644 --- a/packages/ui/src/FormWidgets/DebouncedInput/index.tsx +++ b/packages/ui/src/FormWidgets/DebouncedInput/index.tsx @@ -12,6 +12,7 @@ import { IInputProperties, Input } from "../Input"; export interface DebouncedInputProperties extends IInputProperties { debounceTime?: number; onInputChange: (value: number | readonly string[] | string) => void; + sanitizeValue?: (value: string) => string; } export const DebouncedInput = forwardRef< @@ -24,6 +25,7 @@ export const DebouncedInput = forwardRef< debounceTime = 500, defaultValue = "", onInputChange, + sanitizeValue, type = "text", ...inputProperties }, @@ -50,7 +52,13 @@ export const DebouncedInput = forwardRef< }, [debouncedValue]); const handleInputChange = (event: ChangeEvent) => { - setInputValue(event.target.value); + let rawValue = event.target.value; + + if (sanitizeValue) { + rawValue = sanitizeValue(rawValue); + } + + setInputValue(rawValue); }; return ( diff --git a/packages/ui/src/Table/TableRangeFilter.tsx b/packages/ui/src/Table/TableRangeFilter.tsx index bf2d0246f..f8da9e29c 100644 --- a/packages/ui/src/Table/TableRangeFilter.tsx +++ b/packages/ui/src/Table/TableRangeFilter.tsx @@ -24,7 +24,24 @@ export const TableRangeFilter = ({ ? [...filterValue] : [undefined, undefined]; - currentFilter[index] = value !== "" ? Number(value) : undefined; + const numericValue = value !== "" ? Number(value) : undefined; + + if (numericValue !== undefined) { + const { rangeFilterMax, rangeFilterMin } = column.columnDef.meta ?? {}; + + if (rangeFilterMin !== undefined && numericValue < rangeFilterMin) { + currentFilter[index] = rangeFilterMin; + } else if ( + rangeFilterMax !== undefined && + numericValue > rangeFilterMax + ) { + currentFilter[index] = rangeFilterMax; + } else { + currentFilter[index] = numericValue; + } + } else { + currentFilter[index] = undefined; + } const isFilterActive = currentFilter.some( (filterInput) => filterInput !== undefined, @@ -35,6 +52,38 @@ export const TableRangeFilter = ({ const filterValue = column.getFilterValue() as (number | undefined)[]; const key = column.id || String(column.columnDef.accessorKey); + const meta = column.columnDef.meta; + + const clampRangeValue = (value: string): string => { + if ( + meta?.rangeFilterMin === undefined && + meta?.rangeFilterMax === undefined + ) { + return value; + } + + const numericValue = Number(value); + + if (Number.isNaN(numericValue)) { + return value; + } + + if ( + meta.rangeFilterMin !== undefined && + numericValue < meta.rangeFilterMin + ) { + return String(meta.rangeFilterMin); + } + + if ( + meta.rangeFilterMax !== undefined && + numericValue > meta.rangeFilterMax + ) { + return String(meta.rangeFilterMax); + } + + return value; + }; return (
@@ -45,12 +94,15 @@ export const TableRangeFilter = ({ ? filterValue[0] : "" } + max={meta?.rangeFilterMax} + min={meta?.rangeFilterMin} name={`range-start-${key}`} onInputChange={(value) => updateRangeFilter(column, 0, value)} placeholder={ column.columnDef.filterPlaceholder?.split(",")[0] ?? column.columnDef.filterPlaceholder } + sanitizeValue={clampRangeValue} type="number" /> ({ ? filterValue[1] : "" } + max={meta?.rangeFilterMax} + min={meta?.rangeFilterMin} name={`range-end-${key}`} onInputChange={(value) => updateRangeFilter(column, 1, value)} placeholder={ column.columnDef.filterPlaceholder?.split(",")[1] ?? column.columnDef.filterPlaceholder } + sanitizeValue={clampRangeValue} type="number" />
diff --git a/packages/ui/src/Table/types.ts b/packages/ui/src/Table/types.ts index 19e42d4fb..c267f0d04 100644 --- a/packages/ui/src/Table/types.ts +++ b/packages/ui/src/Table/types.ts @@ -46,6 +46,8 @@ declare module "@tanstack/react-table" { interface ColumnMeta { filterOptions?: FilterOption[]; filterVariant?: TFilterVariant; + rangeFilterMax?: number; + rangeFilterMin?: number; serverFilterFn?: TFilterFn; } }