use-searchable-list
Version:
A hook to filter an array/list of objects.
76 lines (75 loc) • 2.25 kB
JavaScript
// src/index.ts
import { useState, useEffect, useMemo } from "react";
var defaults = {
clearOnEmpty: false,
firstLetterCheck: true,
debounce: true,
delay: 300
};
var useSearchableList = (property, props = defaults) => {
const { clearOnEmpty, firstLetterCheck, debounce, delay } = useMemo(
() => ({ ...defaults, ...props }),
[props]
);
if (!isPrimitive(property)) {
throw new Error("Invalid property used to filter. Only primitive types are allowed.");
}
const [origin, setOrigin] = useState([]);
const [state, setState] = useState([]);
const [searchTerm, setSearchTerm] = useState("");
const [initialized, setInitialized] = useState(false);
const setValue = (value) => {
setOrigin(value);
setState(value);
};
const filter = (value) => {
setSearchTerm(value.toString());
};
useEffect(() => {
if (initialized) {
if (debounce) {
const delayTimeout = setTimeout(() => {
applyFilter();
}, delay);
return () => clearTimeout(delayTimeout);
} else {
applyFilter();
}
} else {
setState(origin);
setInitialized(true);
}
}, [searchTerm]);
const applyFilter = () => {
if (searchTerm === "" || searchTerm === void 0) {
reset();
} else if (searchTerm.length === 1 && firstLetterCheck) {
const filteredList = origin.filter((element) => {
const propertyValue = element[property];
return isPrimitive(propertyValue) && propertyValue.toString().toLowerCase().startsWith(searchTerm.toLowerCase());
});
setState(filteredList);
} else {
const filteredList = origin.filter((element) => {
const propertyValue = element[property];
return isPrimitive(propertyValue) && propertyValue.toString().toLowerCase().includes(searchTerm.toLowerCase());
});
setState(filteredList);
}
};
const reset = () => {
if (clearOnEmpty) {
setState([]);
} else {
setState(origin);
}
};
return [state, setValue, filter];
};
var isPrimitive = (value) => {
return typeof value === "string" || typeof value === "number" || typeof value === "boolean";
};
var src_default = useSearchableList;
export {
src_default as default
};