feat(filters): move the availability preset into a bar dimension (#188)
This commit is contained in:
@@ -5,13 +5,17 @@ import Switch from 'antd/es/switch';
|
||||
import Tag from 'antd/es/tag';
|
||||
import Slider from 'antd/es/slider';
|
||||
import InputNumber from 'antd/es/input-number';
|
||||
import Segmented from 'antd/es/segmented';
|
||||
import {
|
||||
buildCategoryTree,
|
||||
categoryPath,
|
||||
formatPriceRange,
|
||||
ItemStatus,
|
||||
SaleState,
|
||||
saleStateFromStatuses,
|
||||
STATUS_OPTIONS,
|
||||
statusLabel,
|
||||
STOREFRONT_SALE_STATUSES,
|
||||
toCategoryTreeData
|
||||
} from '../../filters';
|
||||
import type { FilterDimension } from './dimension';
|
||||
@@ -269,3 +273,59 @@ export const statusDimension: FilterDimension = {
|
||||
}
|
||||
}))
|
||||
};
|
||||
|
||||
const SALE_STATE_LABELS: Record<SaleState, string> = {
|
||||
'not-sold': 'Not sold',
|
||||
sold: 'Sold',
|
||||
all: 'All'
|
||||
};
|
||||
|
||||
/**
|
||||
* The storefront's three-way availability preset.
|
||||
*
|
||||
* A bar dimension rather than a drawer one: it is the coarsest cut a customer
|
||||
* makes and is worth having visible without opening anything. Before #188 it
|
||||
* was hand-written markup in App.tsx because the shared component had no way to
|
||||
* say "this belongs in the bar", which is the gap that design closed.
|
||||
*/
|
||||
export const availabilityDimension: FilterDimension = {
|
||||
key: 'availability',
|
||||
placement: 'bar',
|
||||
|
||||
render: ({ filters, onChange }) => (
|
||||
<Segmented
|
||||
aria-label="Filter by availability"
|
||||
value={saleStateFromStatuses(
|
||||
filters.status,
|
||||
STOREFRONT_SALE_STATUSES,
|
||||
filters.favoritesOnly ? 'all' : 'not-sold'
|
||||
)}
|
||||
onChange={(value) => {
|
||||
const state = value as SaleState;
|
||||
// The default is stored as "no preference" rather than as an explicit
|
||||
// list, which keeps it out of the URL and out of the chip row.
|
||||
onChange({
|
||||
...filters,
|
||||
status: state === 'not-sold' ? null : STOREFRONT_SALE_STATUSES[state]
|
||||
});
|
||||
}}
|
||||
options={[
|
||||
{ label: SALE_STATE_LABELS['not-sold'], value: 'not-sold' },
|
||||
{ label: SALE_STATE_LABELS.sold, value: 'sold' },
|
||||
{ label: SALE_STATE_LABELS.all, value: 'all' }
|
||||
]}
|
||||
/>
|
||||
),
|
||||
|
||||
chips: ({ filters, onChange }) => {
|
||||
const state = saleStateFromStatuses(filters.status, STOREFRONT_SALE_STATUSES, 'not-sold');
|
||||
if (state === 'not-sold') return [];
|
||||
return [
|
||||
{
|
||||
key: 'availability',
|
||||
label: SALE_STATE_LABELS[state],
|
||||
onRemove: () => onChange({ ...filters, status: null })
|
||||
}
|
||||
];
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user