Component props.
FilterVariantInputProps interface for filter variant input component
Additional props
Column to filter
A 32px-tall MUI Slider bound to the column's debounced filter.
// Price column — getFullRange() returns [0, 1000] from facet data.
<RangeColumnFilter column={priceColumn} />
// Initial render: two thumbs at 0 and 1000.
// Dragging the right thumb to 250 →
// column.setFilterValueDebounced([0, 250])
// which narrows the table to prices ≤ $250 via TanStack's inNumberRange.
export default function RangeColumnFilter({ column }: FilterVariantInputProps) {
function ValueLabelComponent(props: SliderValueLabelProps) {
const { children, value } = props;
return (
<Tooltip
enterTouchDelay={0}
placement="top"
title={value}
className={`${styles["range-column-filter-tooltip"]} no-padding`}
>
{children}
</Tooltip>
);
}
const [MIN, MAX] = column.getFullRange();
const filterValue = column.getFilterValue() as number[] | undefined;
const [columnFilterRange, setColumnFilterRange] = useState<number[]>(filterValue || [MIN, MAX]);
// Content-based key so the effect only fires when the external filter
// actually changes — not on every render, where `getFilterValue()` may
// return a fresh array reference with the same contents and would otherwise
// clobber in-progress local state.
const filterKey = filterValue ? filterValue.join("�") : "";
useEffect(() => {
setColumnFilterRange(filterValue || [MIN, MAX]);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [filterKey, MIN, MAX]);
const handleColumnFilterChange = (_event: Event, newValue: number[]) => {
setColumnFilterRange(newValue);
column.setFilterValueDebounced(newValue);
};
return (
<Box
className={styles["range-column-filter"]}
// Center the slider vertically in the filter cell and leave a right-side
// gap so it doesn't kiss the next filter's input.
sx={{
m: 0,
mr: 0.5,
px: 1,
display: "flex",
alignItems: "center",
height: 32,
}}
>
<Slider
value={columnFilterRange}
valueLabelDisplay="auto"
min={MIN}
max={MAX}
size="small"
onChange={handleColumnFilterChange}
getAriaLabel={() => `${column.getHeaderText()} range`}
slots={{ valueLabel: ValueLabelComponent }}
sx={{ p: 0, m: 0 }}
/>
</Box>
);
}
Compact range (slider) filter for header columns. The column header is rendered directly above, so we no longer show a duplicate header and inline MIN / MAX labels — the
valueLabelDisplay="auto"tooltip surfaces the live values on hover/focus.