@wirdestack/react-filter
v1.0.0
Published
A small attribute filter
Readme
React-filter
React-filter is a small attribute filter leveraging @material/ui for graphic components.
Table of content
Motivation
I needed a lightweight generic way to filter attributes on objects in an efficent manner.
Lightweight for me means no deep dependencies making upgrading your project complex.
I built a few components and used them in my own project and once I had a need for it in multiple projects I decided to make a open source lib out of it.
Requirements
- React >= 19
- @mui/material => 6.4.1
How to install
$ npm i @wirdestack/react-filterHow to use
Simple example
import { useFilter, FilterChip, FilterSlider, FilterToggle } from '@wirdestack/react-filter';
import type { FilterStructure, ChipOptions, SliderOptions, ToggleChoice } from '@wirdestack/react-filter';
type Product = {
id: number;
name: string;
amount: string;
brandName: string;
width: number;
height: number;
price: number;
quickDelivery: boolean;
};
type Products = ReadonlyArray<Product>;
type Params = Readonly<{
products: Products
}>;
const filterStructure: FilterStructure<Product> = {
brandName: { filterType: 'chip', type: 'string', sort: 'asc' },
width: { filterType: 'chip', type: 'number', sort: 'desc' },
height: { filterType: 'slider' },
price: { filterType: 'slider' },
quickDelivery: { filterType: 'toggle' },
};
export default function ProductsWithFilter({ products }: Params) {
const [currentFilter, setCurrentFilter] = useState({});
const { options, filteredItems, availableOptions } = useFilter<Product>(products, filterStructure, currentFilter);
return <div className="products-with-filter">
<div className="filter">
<FilterChip
label="Brand"
filterName="brandName"
options={options['brandName'] as ChipOptions}
availableOptions={availableOptions['brandName'] as ChipOptions}
currentFilter={currentFilter}
filter={(filter) => setCurrentFilter(filter)}
/>
<FilterChip
label="Width"
filterName="width"
options={options['width'] as ChipOptions}
availableOptions={availableOptions['width'] as ChipOptions}
currentFilter={currentFilter}
filter={(filter) => setCurrentFilter(filter)}
/>
<FilterSlider
label="Height"
filterName="height"
options={options['height'] as SliderOptions}
availableOptions={availableOptions['height'] as SliderOptions}
currentFilter={currentFilter}
filter={(filter) => setCurrentFilter(filter)}
unit={'cm'}
/>
<FilterSlider
label="Price"
filterName="price"
options={options['price'] as SliderOptions}
availableOptions={availableOptions['price'] as SliderOptions}
currentFilter={currentFilter}
filter={(filter) => setCurrentFilter(filter)}
unit={'€'}
unitAsPrefix={true}
/>
<FilterToggle
label="Only quick delivery"
filterName="quickDelivery"
value={currentFilter['quickDelivery'] as ToggleChoice}
currentFilter={currentFilter}
filter={(filter) => setCurrentFilter(filter)}
/>
</div>
<ProductList products={filteredItems} />
</div>;
}Optional if you want to style your component, add in your CSS somewhere:
:root {
--react-filter-distance: 8px; /* Row gaps and padding will be base on this. */
--react-filter-color: #9BCAC5; /* Your project's primary color. */
/*OR*/
--distance: 8px;
--primary-color: #9BCAC5; /* Your project's primary color? */
--react-filter-text-color: white; /* If you want to override text-color (on dark background for instance). */
/* Add this to decide to decide what language to use for the toggle button. Default is swedish. */
--react-filter-yes: 'Yes';
--react-filter-no: 'No';
}API
Component API
| Component | Description | | -------------- | ----------------------------------------------------------------- | | FilterChip | Will render filter for an attribute of the type chip. | | FilterSlider | Will render filter for an attribute of the type slider. | | FilterToggle | Will render filter for an attribute of the type toggle. | | FilterChipSkeleton | A placeholder for FilterChip while the page loads if you want less CLS on your site. | | FilterSliderSkeleton | A placeholder for FilterSlider while the page loads if you want less CLS on your site. |
Hook API
| Hook | Description | | ---------------- | ----------------------------------------------------------------- | | useFilter | Takes the following params: - Array of object to filter. - The filterstructure that defines what to filter on. - Current filter choices.Returns an object with the following:- options: Options that can be filtered on.- filteredItems: The items that matched the current filter.- availableOptions: Where options contains the current selected options, this contains all the available options you can pick. |
Contributing
Anyone is free to open a PR and contribute to this project... just be civilized!
Also, please join in on the discussions, feedback is appreciated.
