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