@mcabreradev/filter
Version:
A powerful, SQL-like array filtering library for TypeScript and JavaScript with advanced pattern matching, MongoDB-style operators, deep object comparison, and zero dependencies
88 lines (87 loc) • 3.16 kB
JavaScript
import { useMemo, useState, useEffect } from 'preact/hooks';
import { filter } from '../../core/filter/filter';
export function useFilter(data, expression, options) {
const filtered = useMemo(() => {
if (!expression || data.length === 0) {
return data;
}
return filter(data, expression, options);
}, [data, expression, options]);
const isFiltering = useMemo(() => {
return expression !== null && data.length > 0;
}, [expression, data]);
return { filtered, isFiltering };
}
export function useFilteredState(data, initialExpression, options) {
const [expression, setExpression] = useState(initialExpression || null);
const filtered = useMemo(() => {
if (!expression || data.length === 0) {
return data;
}
return filter(data, expression, options);
}, [data, expression, options]);
const reset = () => setExpression(null);
return { filtered, expression, setExpression, reset };
}
export function useDebouncedFilter(data, expression, options) {
const { delay = 300, filterOptions = {} } = options || {};
const [debouncedExpr, setDebouncedExpr] = useState(null);
const [isPending, setIsPending] = useState(true);
useEffect(() => {
setIsPending(true);
const timer = setTimeout(() => {
setDebouncedExpr(expression);
setIsPending(false);
}, delay);
return () => clearTimeout(timer);
}, [expression, delay]);
const filtered = useMemo(() => {
if (!debouncedExpr || data.length === 0) {
return data;
}
return filter(data, debouncedExpr, filterOptions);
}, [data, debouncedExpr, filterOptions]);
return { filtered, isPending };
}
export function usePaginatedFilter(data, expression, options) {
const { pageSize: initialPageSize = 10, initialPage = 1, filterOptions = {} } = options || {};
const [currentPage, setCurrentPage] = useState(initialPage);
const [pageSize, setPageSizeState] = useState(initialPageSize);
const filtered = useMemo(() => {
if (!expression || data.length === 0) {
return data;
}
return filter(data, expression, filterOptions);
}, [data, expression, filterOptions]);
const totalPages = useMemo(() => {
return Math.ceil(filtered.length / pageSize);
}, [filtered.length, pageSize]);
const paginatedResults = useMemo(() => {
const start = (currentPage - 1) * pageSize;
return filtered.slice(start, start + pageSize);
}, [filtered, currentPage, pageSize]);
const setPage = (page) => {
setCurrentPage(Math.max(1, Math.min(page, totalPages)));
};
const setPageSize = (size) => {
setPageSizeState(Math.max(1, size));
setCurrentPage(1);
};
const nextPage = () => {
setPage(currentPage + 1);
};
const prevPage = () => {
setPage(currentPage - 1);
};
return {
paginatedResults,
currentPage,
totalPages,
pageSize,
setPage,
setPageSize,
nextPage,
prevPage,
};
}
export { filter };