Skip to main content

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

NameTypeRequiredDefaultDescription
sortOptionsSortOption[]NoDefault optionsAvailable sort options
defaultSortBystringNo''Default sort field
defaultSortOrder'asc' | 'desc'No'asc'Default sort direction
showSortDirectionbooleanNotrueShow direction toggle button
enableUrlUpdatebooleanNotrueUpdate URL on sort change
onSortChange(sortState) => voidNo-Custom sort change handler
renderSortSelectRenderFunctionNo-Custom select renderer
renderSortDirectionRenderFunctionNo-Custom direction renderer
classNamestringNo''Additional CSS classes
disabledbooleanNofalseDisable 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