useFacets
Overview
The useFacets hook is designed to manage the facets state for an e-commerce site. It enables customers to retrieve the set of facets for the current query and easily select or deselect them as needed. This hook is particularly useful for filtering results based on the active query.
Usage
import { useFacets } from "@unbxd-ui/react-search-hooks";
The useFacets hook must be used within the wrapper (in CSR, SSR and Custom Hooks approaches) to ensure that the respective component(s) and the search functionality work properly.
Code Example
// This is a sample example.
// Please go through the entire documentation for understanding different usecases and update as per your needs.
import { useFacets } from '@unbxd-ui/react-search-hooks';
const FacetComponent = () => {
const { facets, stats, selectedFacets, getFacetByName, addFacet, removeFacet, clearFacet } = useFacets();
return (
<div>
{/* Basic facet display */}
{Object.keys(facets).map(facetKey => {
const facet = getFacetByName(facetKey);
return (
<div key={facetKey}>
<h3>{facet.displayName}</h3>
{facet.values.map(option => (
<label key={option.value}>
<input
type="checkbox"
checked={selectedFacets[facetKey]?.values.includes(option.value)}
onChange={(e) => {
if (e.target.checked) {
addFacet(facetKey, [option.value], true);
} else {
removeFacet(facetKey, option.value);
}
}}
/>
{option.value} ({option.count})
</label>
))}
</div>
);
})}
</div>
);
};
Range Facet Example:
// This is a sample example.
// Please go through the entire documentation for understanding different usecases and update as per your needs.
import { useFacets } from '@unbxd-ui/react-search-hooks';
import { useState } from 'react';
const PriceRangeFacet = () => {
const { stats, selectedFacets, addFacet, removeFacet } = useFacets();
const [minValue, setMinValue] = useState('');
const [maxValue, setMaxValue] = useState('');
const priceStats = stats?.price || { min: 0, max: 1000 };
const selectedPrice = selectedFacets?.price?.values?.[0];
const applyPriceRange = () => {
const min = parseFloat(minValue) || priceStats.min;
const max = parseFloat(maxValue) || priceStats.max;
const rangeValue = {
start: min.toString(),
end: max.toString(),
dataId: `${min}-${max}`,
count: 0
};
addFacet('price', [rangeValue]);
};
const clearPriceRange = () => {
removeFacet('price', selectedPrice);
};
return (
<div className="price-range-facet">
<h3>Price Range</h3>
<div>
<input
type="number"
placeholder={`Min (${priceStats.min})`}
value={minValue}
onChange={(e) => setMinValue(e.target.value)}
/>
<input
type="number"
placeholder={`Max (${priceStats.max})`}
value={maxValue}
onChange={(e) => setMaxValue(e.target.value)}
/>
<button onClick={applyPriceRange}>Apply</button>
{selectedPrice && (
<button onClick={clearPriceRange}>Clear</button>
)}
</div>
{selectedPrice && (
<p>Selected: ${selectedPrice.start} - ${selectedPrice.end}</p>
)}
</div>
);
};
Multiple Facets with Apply All:
// This is a sample example.
// Please go through the entire documentation for understanding different usecases and update as per your needs.
import { useFacets } from '@unbxd-ui/react-search-hooks';
import { useState } from 'react';
const MultiSelectFacets = () => {
const { facets, selectedFacets, addMultipleFacets, clearFacet } = useFacets();
const [tempSelections, setTempSelections] = useState({});
const handleTempSelection = (facetName, value, checked) => {
setTempSelections(prev => {
const current = prev[facetName] || [];
if (checked) {
return { ...prev, [facetName]: [...current, value] };
} else {
return { ...prev, [facetName]: current.filter(v => v !== value) };
}
});
};
const applyAllFilters = () => {
const facetsToApply = Object.entries(tempSelections)
.filter(([, values]) => values.length > 0)
.map(([name, values]) => ({ name, value: values }));
addMultipleFacets(facetsToApply);
setTempSelections({});
};
const clearAllFilters = () => {
clearFacet(); // Clear all facets
setTempSelections({});
};
return (
<div className="multi-select-facets">
<div className="facet-actions">
<button onClick={applyAllFilters}>Apply All Filters</button>
<button onClick={clearAllFilters}>Clear All</button>
</div>
{Object.keys(facets).map(facetKey => {
const facet = facets[facetKey];
return (
<div key={facetKey} className="facet-group">
<h3>{facet.displayName}</h3>
{facet.values.map(option => (
<label key={option.value}>
<input
type="checkbox"
checked={tempSelections[facetKey]?.includes(option.value) || false}
onChange={(e) => handleTempSelection(facetKey, option.value, e.target.checked)}
/>
{option.value} ({option.count})
</label>
))}
</div>
);
})}
{/* Show current selections */}
<div className="current-selections">
<h4>Current Filters:</h4>
{Object.entries(selectedFacets).map(([facetName, facetData]) => (
<div key={facetName}>
<strong>{facetData.displayName}:</strong> {facetData.values.join(', ')}
<button onClick={() => clearFacet(facetName)}>Clear</button>
</div>
))}
</div>
</div>
);
};
Hook API
Return Values
- This value returns all the facets for a particular query in their original form, exactly as provided by the API.
Format Example:
facets = {
multilevel: {
list: [{
displayName: "categoryPath"
filterField: "categoryPath"
level: 1
values: [{count: 27, name: "Wall Decor"} , {count: 23, name: "Drinkaware}],
breadcrumb: {}
}]
},
range: {
list: [
{
displayName: 'sellingPrice' ,
facetName: 'sellingPrice' ,
position: 1 ,
values: {counts: ['230.0', 46, '6408.0', 5, '12546.0', 3], end: 62010, gap: 6178 , start: 230}
}
]
},
text: {
list: [
{
displayName: "Color",
facetName: "v_color_uFilter",
filterField: "v_color_uFilter"
position: 4
values: ['Beige', 1, 'Black', 7, 'Black with Red Piping', 2]
}
]
}
}
- This value returns the stats object for a particular query in their original form, exactly as provided by the API.
Format Example:
stats = {
"price": {
"min": 10.99,
"max": 299.99,
"count": 156,
"mean": 89.45,
"sum": 13954.2
},
"rating": {
"min": 1.0,
"max": 5.0,
"count": 203,
"mean": 4.2,
"sum": 852.6
}
}
- This value returns the selectedFacets object, containing information about the currently selected facets.
Format Example:
selectedFacets = {
"color_uFilter": {
"displayName": "Color",
"type": "text",
"values": ["Red", "Blue"]
},
"price": {
"displayName": "Price",
"type": "range",
"values": [
{
"start": "50.0",
"end": "200.0",
"dataId": "50.0-200.0",
"count": 45
}
]
},
"categoryPath": {
"displayName": "Category",
"type": "multilevel",
"values": ["Shoes>Sports>Running"]
}
}
- This function returns an object for a specific facet, with name passed as the parameter.
- Parameters:
name
is the name of the facet from the feed.searchStr
(OPTIONAL) parameter is a search string that can be used to filter and search for specific facet values.
- Usage:
getFacetByName(name, searchStr);
- Example
getFacetByName('storage_uFilter');
//If needs to be used for search in the facet block pass this searchStr.
getFacetByName('color_uFilter', "blac");
Return Format Example:
// getFacetByName('color_uFilter') returns:
{
"displayName": "Color",
"position": 1,
"level": undefined,
"type": "text",
"searchStr": undefined,
"values": [
{ "value": "Red", "count": 45 },
{ "value": "Blue", "count": 32 },
{ "value": "Green", "count": 28 }
]
}
// getFacetByName('price') returns:
{
"displayName": "Price Range",
"position": 2,
"level": undefined,
"type": "range",
"gap": 50,
"start": 0,
"end": 500,
"values": [
{ start: '295.0' , end: '9955.0' , count : 49, dataId: '295.0-9955.0'},
{ start: '9955.0' , end: '19615.0' , count : 5, dataId: '9955.0-19615.0'}
]
}
- This function simply adds the selected facet to the selectedFacets object, which represents the state of the currently selected facets.The selection of the facet can be either
single select
ormultiselect
based on one of the parametermultiselect
. - Parameters:
name
is the name of the facet from the feed for which the selection is made.value
is the value of the facet which has been selected.multiselect
parameter determines whether the selection is a single or multiple select. If set to false, the passed value will be selected, replacing any previously selected value (i.e., single select). If set to true, multiple values can be passed as an array, and all those values will be selected simultaneously (i.e., multiple select).
- Usage:
addFacet(name, value, multiselect);
- Example:
// Adding text facet value - single select
addFacet('color_uFilter', ['blue'], false);
// Adding text facet value - multi select
addFacet('color_uFilter', ['blue', 'red'], true);
// Adding range facet value which is not a slider (multi select)
addFacet('price', [{ count: 4 , dataId: "9955.0-19615.0" , end: "19615.0", start: "9955.0"}] , true);
// Adding range facet value which is a slider (single select)
addFacet('price', [{ count: 4 , dataId: "9955.0-19615.0" , end: "19615.0", start: "9955.0"}]);
// Adding multilevel facet value - single select
addFacet('categoryPath', 'Sofa Set,Sofa Sets'); // This will add categoryPath: "Sofa Set > Sofa Sets"
The addMultipleFacets
function enables batch application of multiple facets simultaneously. This is particularly useful when implementing features like a global "Apply Filters" button that needs to apply multiple selected facets at once.
Parameters
facets
: An array of facet objects with the following structure:name
: The name of the facet (e.g., "storage_uFilter").value
: Array of string values to apply for this facet.
// Example usage:
addMultipleFacets([
{
name: "color_uFilter", // Text facet
value: ["Red", "Blue", "Green"]
},
{
name: "brand_uFilter", // Text facet
value: ["Nike", "Adidas"]
},
{
name: "price", // Range facet
value: [{ count: 4 , dataId: "9955.0-19615.0" , end: "19615.0", start: "9955.0"}]
},
{
name: "categoryPath", // Multilevel facet
value: ["Sofa Set,Sofa Sets", "Furniture,Living Room"]
}
]);
When updating 'facets', ensure you pass the complete set of currently selected facets from the UI, rather than just the ones that have recently changed. This hook will replace the existing facet values entirely with this new value.
Notes
- The function safely handles empty arrays and undefined inputs
- Multiple values can be specified for each facet
- Changes are applied atomically, updating all facets in a single state update
- This function removes/de-selects the passed in value from the selectedFacets in the state.
- Parameters:
name
is the name of the facet from the feed for which the de-selection is made.value
is the value which needs to removed from the selectedFacets object in the state.
- Usage:
removeFacet(name, value);
- Example:
//Removing text facet
removeFacet('storage_uFilter', 'With storage');
//Removing range facet
removeFacet('price', { count: 4, dataId: "9955.0-19615.0", end: "19615.0" , start:"9955.0"});
The clearFacet
function removes facet selections from the state. It can either clear a specific facet or all selected facets.
Parameters
name
(optional): string - The facet identifier to clear. If omitted, all selected facets will be cleared.
Usage
clearFacet(name)
Examples
// Clear a specific facet
clearFacet("storage_uFilter"); // Removes all selected values for the storage facet
// Clear all selected facets
clearFacet(); // Resets the entire facet selection state
Notes
- When clearing a specific facet, all values selected for that facet will be removed
- The function handles undefined or non-existent facet names gracefully
- Triggers a FACET_CLEARED event after successful execution