function FilterMenu()

in src/data-table/filter-menu.tsx [223:340]


function FilterMenu(props: Props) {
  const [, theme] = useStyletron();
  const locale = React.useContext(LocaleContext);
  const [isOpen, setIsOpen] = React.useState(false);
  const [highlightIndex, setHighlightIndex] = React.useState(-1);
  const [query, setQuery] = React.useState('');

  const [activeColumn, setActiveColumn] = React.useState(null);
  const handleOptionClick = React.useCallback(setActiveColumn, []);
  const handleClose = React.useCallback(() => {
    setIsOpen(false);
    setActiveColumn(null);
    setHighlightIndex(-1);
    setQuery('');
  }, []);

  const filterableColumns = React.useMemo(() => {
    return props.columns.filter((column) => {
      return column.filterable && !props.filters.has(column.title);
    });
  }, [props.columns, props.filters]);

  const columns = React.useMemo(() => {
    return filterableColumns.filter((column) => matchesQuery(column.title, query));
  }, [filterableColumns, query]);

  const Filter = React.useMemo(() => {
    if (!activeColumn) return null;
    // @ts-ignore
    return activeColumn.renderFilter;
  }, [activeColumn]);

  const activeColumnData = React.useMemo(() => {
    const columnIndex = props.columns.findIndex((c) => c === activeColumn);
    if (columnIndex < 0) return [];
    return props.rows.map((row) => props.columns[columnIndex].mapDataToValue(row.data));
  }, [props.columns, props.rows, activeColumn]);

  // @ts-ignore
  function handleKeyDown(event) {
    if (event.keyCode === 13) {
      event.preventDefault();
      // @ts-ignore
      setActiveColumn(columns[highlightIndex]);
    }
    if (event.keyCode === 38) {
      event.preventDefault();
      setHighlightIndex(Math.max(0, highlightIndex - 1));
    }
    if (event.keyCode === 40) {
      event.preventDefault();
      if (!isOpen) {
        setIsOpen(true);
      } else {
        setHighlightIndex(Math.min(columns.length - 1, highlightIndex + 1));
      }
    }
  }

  return (
    <Popover
      focusLock
      returnFocus={true}
      placement={PLACEMENT.bottomLeft}
      content={() => {
        if (Filter && activeColumn) {
          return (
            <Filter
              data={activeColumnData}
              close={handleClose}
              // @ts-ignore
              setFilter={(filterParams) => props.onSetFilter(activeColumn.title, filterParams)}
            />
          );
        }
        return (
          <Options
            columns={columns}
            highlightIndex={highlightIndex}
            // @ts-ignore
            onClick={handleOptionClick}
            onKeyDown={handleKeyDown}
            onMouseEnter={setHighlightIndex}
            onQueryChange={setQuery}
            query={query}
            searchable={filterableColumns.length >= 10}
          />
        );
      }}
      onClick={() => {
        if (isOpen) {
          handleClose();
        } else {
          setIsOpen(true);
        }
      }}
      onClickOutside={handleClose}
      onEsc={handleClose}
      isOpen={isOpen}
      ignoreBoundary
    >
      <Button
        shape={SHAPE.pill}
        size={SIZE.compact}
        overrides={{
          BaseButton: {
            style: {
              marginLeft: theme.sizing.scale500,
              marginBottom: theme.sizing.scale500,
            },
          },
        }}
      >
        {locale.datatable.filterAdd}
      </Button>
    </Popover>
  );
}