ChemPal Documentation - v0.0.13-beta.5
    Preparing search index...
    • 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.

      Parameters

      • props: FilterVariantInputProps

        Component props.

        FilterVariantInputProps interface for filter variant input component

        • [key: string]: unknown

          Additional props

        • column: CustomColumn<Product, unknown>

          Column to filter

      Returns Element

      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>
      );
      }