ProductSorting
Description
A product sorting component with dropdown and direction toggle. Syncs with URL parameters and updates page data. Supports custom rendering for sort select and direction button.
Import
import { ProductSorting } from '@components/frontStore/catalog/ProductSorting';
Usage
import { ProductSorting } from '@components/frontStore/catalog/ProductSorting';
function ProductPage() {
return (
<ProductSorting
sortOptions={[
{ code: '', name: 'Default' },
{ code: 'price', name: 'Price' },
{ code: 'name', name: 'Name' }
]}
/>
);
}
Props
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| sortOptions | SortOption[] | No | Default options | Available sort options |
| defaultSortBy | string | No | '' | Default sort field |
| defaultSortOrder | 'asc' | 'desc' | No | 'asc' | Default sort direction |
| showSortDirection | boolean | No | true | Show direction toggle button |
| enableUrlUpdate | boolean | No | true | Update URL on sort change |
| onSortChange | (sortState) => void | No | - | Custom sort change handler |
| renderSortSelect | RenderFunction | No | - | Custom select renderer |
| renderSortDirection | RenderFunction | No | - | Custom direction renderer |
| className | string | No | '' | Additional CSS classes |
| disabled | boolean | No | false | Disable sorting controls |
Type Definitions
SortOption
interface SortOption {
code: string; // Sort field code
name: string; // Display name
label?: string; // Optional label (overrides name)
disabled?: boolean; // Disable this option
}
SortState
interface SortState {
sortBy: string; // Current sort field
sortOrder: 'asc' | 'desc'; // Sort direction
}
Examples
Basic Sorting
import { ProductSorting } from '@components/frontStore/catalog/ProductSorting';
function CategoryPage() {
return (
<div className="toolbar">
<ProductSorting />
</div>
);
}
Custom Sort Options
import { ProductSorting } from '@components/frontStore/catalog/ProductSorting';
function ProductListing() {
return (
<ProductSorting
sortOptions={[
{ code: '', name: 'Relevance' },
{ code: 'price', name: 'Price' },
{ code: 'name', name: 'Name' },
{ code: 'newest', name: 'Newest First' },
{ code: 'rating', name: 'Customer Rating' }
]}
defaultSortBy="price"
defaultSortOrder="asc"
/>
);
}
Without Direction Toggle
import { ProductSorting } from '@components/frontStore/catalog/ProductSorting';
function SearchResults() {
return (
<ProductSorting
showSortDirection={false}
sortOptions={[
{ code: 'relevance', name: 'Most Relevant' },
{ code: 'price_low', name: 'Price: Low to High' },
{ code: 'price_high', name: 'Price: High to Low' }
]}
/>
);
}
Custom Sort Handler
import { ProductSorting } from '@components/frontStore/catalog/ProductSorting';
import { useState } from 'react';
function CustomSort() {
const [products, setProducts] = useState([]);
const handleSortChange = async ({ sortBy, sortOrder }) => {
const sorted = await fetchSortedProducts(sortBy, sortOrder);
setProducts(sorted);
};
return (
<ProductSorting
enableUrlUpdate={false}
onSortChange={handleSortChange}
/>
);
}
Custom Select Renderer
import { ProductSorting } from '@components/frontStore/catalog/ProductSorting';
function StyledSort() {
return (
<ProductSorting
renderSortSelect={({ options, value, onChange, disabled }) => (
<div className="custom-select">
<label>Sort by:</label>
<select
value={value}
onChange={(e) => onChange(e.target.value)}
disabled={disabled}
className="styled-select"
>
{options.map(option => (
<option
key={option.code}
value={option.code}
disabled={option.disabled}
>
{option.label || option.name}
</option>
))}
</select>
</div>
)}
/>
);
}
Custom Direction Button
import { ProductSorting } from '@components/frontStore/catalog/ProductSorting';
function CustomDirection() {
return (
<ProductSorting
renderSortDirection={({ sortOrder, onToggle, disabled }) => (
<button
onClick={onToggle}
disabled={disabled}
className="direction-btn"
>
{sortOrder === 'asc' ? '↑ Ascending' : '↓ Descending'}
</button>
)}
/>
);
}
Complete Toolbar
import { ProductSorting } from '@components/frontStore/catalog/ProductSorting';
import { useCategory } from '@components/frontStore/catalog/CategoryContext';
function CategoryToolbar() {
const category = useCategory();
return (
<div className="category-toolbar">
<div className="results-count">
{category.products.total} Products
</div>
<ProductSorting
sortOptions={[
{ code: '', name: 'Featured' },
{ code: 'price', name: 'Price' },
{ code: 'name', name: 'Name' },
{ code: 'newest', name: 'New Arrivals' }
]}
defaultSortBy=""
defaultSortOrder="asc"
className="ml-auto"
/>
</div>
);
}
Default Sort Options
If no sortOptions prop is provided, these defaults are used:
- Default: No sorting (empty code)
- Price: Sort by price
- Name: Sort by name
Related Components
- ProductList - Product listing display
- ProductFilter - Product filtering
- CategoryContext - Category page context