@riosst100/pwa-marketplace 1.3.3 → 1.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/dependabot.yml +28 -28
- package/package.json +18 -18
- package/src/componentOverrideMapping.js +14 -0
- package/src/components/BecomeSellerLink/becomeSellerLink.js +1 -1
- package/src/components/BecomeSellerLink/becomeSellerLink.module.css +0 -4
- package/src/components/CurrencySwitcher/currencySwitcher.himmer.js +6 -0
- package/src/components/CurrencySwitcher/currencySwitcher.module.css +102 -0
- package/src/components/CurrencySwitcher/index.js +107 -0
- package/src/components/CurrencySwitcher/switcherItem.js +47 -0
- package/src/components/CurrencySwitcher/switcherItem.module.css +20 -0
- package/src/components/FilterOption/FilterOptionModal.module.css +90 -0
- package/src/components/FilterOption/filterOptionModal.js +48 -0
- package/src/components/FilterOptionModal/filterOptionModal.js +66 -0
- package/src/components/Header/becomeSellerLink.module.css +0 -4
- package/src/components/Header/websiteSwitcher.js +0 -1
- package/src/components/Header/websiteSwitcher.module.css +107 -111
- package/src/components/WebsiteSwitcher/websiteSwitcher.js +18 -6
- package/src/components/WebsiteSwitcher/websiteSwitcher.module.css +107 -111
- package/src/overwrites/peregrine/lib/talons/FilterModal/useFilterList.js +62 -0
- package/src/overwrites/peregrine/lib/talons/MegaMenu/useMegaMenuItem.js +66 -0
- package/src/overwrites/peregrine/lib/talons/MegaMenu/useSubMenu.js +20 -0
- package/src/overwrites/peregrine/lib/talons/RootComponents/Category/useCategoryContent.js +0 -2
- package/src/overwrites/venia-ui/lib/RootComponents/Category/NoProductsFound/index.js +1 -0
- package/src/overwrites/venia-ui/lib/RootComponents/Category/NoProductsFound/noProductsFound.js +77 -0
- package/src/overwrites/venia-ui/lib/RootComponents/Category/NoProductsFound/noProductsFound.module.css +39 -0
- package/src/overwrites/venia-ui/lib/RootComponents/Category/NoProductsFound/noProductsFound.png +0 -0
- package/src/overwrites/venia-ui/lib/RootComponents/Category/category.gql.js +17 -0
- package/src/overwrites/venia-ui/lib/RootComponents/Category/category.js +91 -0
- package/src/overwrites/venia-ui/lib/RootComponents/Category/category.module.css +77 -0
- package/src/overwrites/venia-ui/lib/RootComponents/Category/categoryContent.js +12 -14
- package/src/overwrites/venia-ui/lib/RootComponents/Category/categoryContent.shimmer.js +74 -0
- package/src/overwrites/venia-ui/lib/RootComponents/Category/images/001.jpg +0 -0
- package/src/overwrites/venia-ui/lib/RootComponents/Category/images/002.jpg +0 -0
- package/src/overwrites/venia-ui/lib/RootComponents/Category/images/003.jpg +0 -0
- package/src/overwrites/venia-ui/lib/RootComponents/Category/images/004.jpg +0 -0
- package/src/overwrites/venia-ui/lib/RootComponents/Category/images/005.jpg +0 -0
- package/src/overwrites/venia-ui/lib/RootComponents/Category/images/006.jpg +0 -0
- package/src/overwrites/venia-ui/lib/RootComponents/Category/images/007.jpg +0 -0
- package/src/overwrites/venia-ui/lib/RootComponents/Category/images/008.jpg +0 -0
- package/src/overwrites/venia-ui/lib/RootComponents/Category/images/009.jpg +0 -0
- package/src/overwrites/venia-ui/lib/RootComponents/Category/images/010.jpg +0 -0
- package/src/overwrites/venia-ui/lib/RootComponents/Category/images/011.jpg +0 -0
- package/src/overwrites/venia-ui/lib/RootComponents/Category/images/012.jpg +0 -0
- package/src/overwrites/venia-ui/lib/RootComponents/Category/images/index.js +12 -0
- package/src/overwrites/venia-ui/lib/RootComponents/Category/index.js +6 -0
- package/src/overwrites/venia-ui/lib/components/Breadcrumbs/breadcrumbs.js +112 -0
- package/src/overwrites/venia-ui/lib/components/Breadcrumbs/breadcrumbs.module.css +32 -0
- package/src/overwrites/venia-ui/lib/components/Breadcrumbs/breadcrumbs.shimmer.js +24 -0
- package/src/overwrites/venia-ui/lib/components/Breadcrumbs/index.js +2 -0
- package/src/overwrites/venia-ui/lib/components/Checkbox/checkbox.js +78 -0
- package/src/overwrites/venia-ui/lib/components/Checkbox/checkbox.module.css +73 -0
- package/src/overwrites/venia-ui/lib/components/Checkbox/index.js +1 -0
- package/src/overwrites/venia-ui/lib/components/FilterModal/CurrentFilters/currentFilter.js +60 -0
- package/src/overwrites/venia-ui/lib/components/FilterModal/CurrentFilters/currentFilter.module.css +21 -0
- package/src/overwrites/venia-ui/lib/components/FilterModal/CurrentFilters/currentFilters.js +65 -0
- package/src/overwrites/venia-ui/lib/components/FilterModal/CurrentFilters/currentFilters.module.css +17 -0
- package/src/overwrites/venia-ui/lib/components/FilterModal/CurrentFilters/index.js +1 -0
- package/src/overwrites/venia-ui/lib/components/FilterModal/FilterList/filterDefault.js +18 -18
- package/src/overwrites/venia-ui/lib/components/FilterModal/FilterList/filterDefault.module.css +0 -0
- package/src/overwrites/venia-ui/lib/components/FilterModal/FilterList/filterItem.js +79 -0
- package/src/overwrites/venia-ui/lib/components/FilterModal/FilterList/filterItemRadio.js +76 -0
- package/src/overwrites/venia-ui/lib/components/FilterModal/FilterList/filterItemRadio.module.css +0 -0
- package/src/overwrites/venia-ui/lib/components/FilterModal/FilterList/filterItemRadioGroup.js +86 -0
- package/src/overwrites/venia-ui/lib/components/FilterModal/FilterList/filterList.js +265 -0
- package/src/overwrites/venia-ui/lib/components/FilterModal/FilterList/filterList.module.css +20 -0
- package/src/overwrites/venia-ui/lib/components/FilterModal/FilterList/index.js +1 -0
- package/src/overwrites/venia-ui/lib/components/FilterModal/filterBlock.js +135 -0
- package/src/overwrites/venia-ui/lib/components/FilterModal/filterBlock.module.css +25 -0
- package/src/overwrites/venia-ui/lib/components/FilterModal/filterFooter.js +49 -0
- package/src/overwrites/venia-ui/lib/components/FilterModal/filterFooter.module.css +10 -0
- package/src/overwrites/venia-ui/lib/components/FilterModal/filterModal.js +166 -0
- package/src/overwrites/venia-ui/lib/components/FilterModal/filterModal.module.css +87 -0
- package/src/overwrites/venia-ui/lib/components/FilterModal/filterSearch.module.css +3 -0
- package/src/overwrites/venia-ui/lib/components/FilterModal/index.js +1 -0
- package/src/overwrites/venia-ui/lib/components/FilterSidebar/__tests__/filterSidebar.spec.js +246 -0
- package/src/overwrites/venia-ui/lib/components/FilterSidebar/filterSidebar.js +8 -8
- package/src/overwrites/venia-ui/lib/components/FilterSidebar/filterSidebar.module.css +57 -58
- package/src/overwrites/venia-ui/lib/components/FilterSidebar/filterSidebar.shimmer.js +24 -0
- package/src/overwrites/venia-ui/lib/components/FilterSidebar/index.js +2 -0
- package/src/overwrites/venia-ui/lib/components/Gallery/addToCartButton.js +116 -0
- package/src/overwrites/venia-ui/lib/components/Gallery/addToCartButton.module.css +38 -0
- package/src/overwrites/venia-ui/lib/components/Gallery/gallery.js +56 -0
- package/src/overwrites/venia-ui/lib/components/Gallery/gallery.module.css +28 -0
- package/src/overwrites/venia-ui/lib/components/Gallery/gallery.shimmer.js +39 -0
- package/src/overwrites/venia-ui/lib/components/Gallery/index.js +3 -0
- package/src/overwrites/venia-ui/lib/components/Gallery/item.js +204 -0
- package/src/overwrites/venia-ui/lib/components/Gallery/item.module.css +109 -0
- package/src/overwrites/venia-ui/lib/components/Gallery/item.shimmer.js +38 -0
- package/src/overwrites/venia-ui/lib/components/Gallery/star.js +12 -0
- package/src/overwrites/venia-ui/lib/components/Header/accountTrigger.js +98 -0
- package/src/overwrites/venia-ui/lib/components/Header/cartTrigger.js +116 -0
- package/src/overwrites/venia-ui/lib/components/Header/header.js +12 -9
- package/src/overwrites/venia-ui/lib/components/Header/storeSwitcher.js +22 -8
- package/src/overwrites/venia-ui/lib/components/Header/storeSwitcher.module.css +107 -0
- package/src/overwrites/venia-ui/lib/components/Header/wishlistTrigger.js +23 -0
- package/src/overwrites/venia-ui/lib/components/MegaMenu/megaMenuItem.js +1 -1
- package/src/overwrites/venia-ui/lib/components/MegaMenu/submenu.module.css +0 -1
- package/src/overwrites/venia-ui/lib/components/Pagination/index.js +1 -0
- package/src/overwrites/venia-ui/lib/components/Pagination/navButton.js +65 -0
- package/src/overwrites/venia-ui/lib/components/Pagination/pagination.js +107 -0
- package/src/overwrites/venia-ui/lib/components/Pagination/tile.js +41 -0
- package/src/overwrites/venia-ui/lib/components/ProductFullDetail/CustomAttributes/AttributeType/Boolean/boolean.js +74 -0
- package/src/overwrites/venia-ui/lib/components/ProductFullDetail/CustomAttributes/AttributeType/Boolean/boolean.module.css +9 -0
- package/src/overwrites/venia-ui/lib/components/ProductFullDetail/CustomAttributes/AttributeType/Boolean/index.js +1 -0
- package/src/overwrites/venia-ui/lib/components/ProductFullDetail/CustomAttributes/AttributeType/Date/date.js +82 -0
- package/src/overwrites/venia-ui/lib/components/ProductFullDetail/CustomAttributes/AttributeType/Date/date.module.css +9 -0
- package/src/overwrites/venia-ui/lib/components/ProductFullDetail/CustomAttributes/AttributeType/Date/index.js +1 -0
- package/src/overwrites/venia-ui/lib/components/ProductFullDetail/CustomAttributes/AttributeType/DateTime/dateTime.js +85 -0
- package/src/overwrites/venia-ui/lib/components/ProductFullDetail/CustomAttributes/AttributeType/DateTime/dateTime.module.css +9 -0
- package/src/overwrites/venia-ui/lib/components/ProductFullDetail/CustomAttributes/AttributeType/DateTime/index.js +1 -0
- package/src/overwrites/venia-ui/lib/components/ProductFullDetail/CustomAttributes/AttributeType/Multiselect/index.js +1 -0
- package/src/overwrites/venia-ui/lib/components/ProductFullDetail/CustomAttributes/AttributeType/Multiselect/multiselect.js +104 -0
- package/src/overwrites/venia-ui/lib/components/ProductFullDetail/CustomAttributes/AttributeType/Multiselect/multiselect.module.css +22 -0
- package/src/overwrites/venia-ui/lib/components/ProductFullDetail/CustomAttributes/AttributeType/Price/index.js +1 -0
- package/src/overwrites/venia-ui/lib/components/ProductFullDetail/CustomAttributes/AttributeType/Price/price.js +74 -0
- package/src/overwrites/venia-ui/lib/components/ProductFullDetail/CustomAttributes/AttributeType/Price/price.module.css +9 -0
- package/src/overwrites/venia-ui/lib/components/ProductFullDetail/CustomAttributes/AttributeType/Select/index.js +1 -0
- package/src/overwrites/venia-ui/lib/components/ProductFullDetail/CustomAttributes/AttributeType/Select/select.js +99 -0
- package/src/overwrites/venia-ui/lib/components/ProductFullDetail/CustomAttributes/AttributeType/Select/select.module.css +13 -0
- package/src/overwrites/venia-ui/lib/components/ProductFullDetail/CustomAttributes/AttributeType/Text/index.js +1 -0
- package/src/overwrites/venia-ui/lib/components/ProductFullDetail/CustomAttributes/AttributeType/Text/text.js +88 -0
- package/src/overwrites/venia-ui/lib/components/ProductFullDetail/CustomAttributes/AttributeType/Text/text.module.css +13 -0
- package/src/overwrites/venia-ui/lib/components/ProductFullDetail/CustomAttributes/AttributeType/Textarea/index.js +1 -0
- package/src/overwrites/venia-ui/lib/components/ProductFullDetail/CustomAttributes/AttributeType/Textarea/textarea.js +94 -0
- package/src/overwrites/venia-ui/lib/components/ProductFullDetail/CustomAttributes/AttributeType/Textarea/textarea.module.css +13 -0
- package/src/overwrites/venia-ui/lib/components/ProductFullDetail/CustomAttributes/AttributeType/attributeType.js +67 -0
- package/src/overwrites/venia-ui/lib/components/ProductFullDetail/CustomAttributes/AttributeType/index.js +1 -0
- package/src/overwrites/venia-ui/lib/components/ProductFullDetail/CustomAttributes/customAttributes.js +64 -0
- package/src/overwrites/venia-ui/lib/components/ProductFullDetail/CustomAttributes/customAttributes.module.css +9 -0
- package/src/overwrites/venia-ui/lib/components/ProductFullDetail/CustomAttributes/index.js +1 -0
- package/src/overwrites/venia-ui/lib/components/ProductFullDetail/index.js +1 -0
- package/src/overwrites/venia-ui/lib/components/ProductFullDetail/productFullDetail.gql.js +7 -0
- package/src/overwrites/venia-ui/lib/components/ProductFullDetail/productFullDetail.js +413 -0
- package/src/overwrites/venia-ui/lib/components/ProductFullDetail/productFullDetail.module.css +203 -0
- package/src/overwrites/venia-ui/lib/components/ProductImageCarousel/carousel.js +180 -0
- package/src/overwrites/venia-ui/lib/components/ProductImageCarousel/carousel.module.css +102 -0
- package/src/overwrites/venia-ui/lib/components/ProductImageCarousel/carousel.shimmer.js +51 -0
- package/src/overwrites/venia-ui/lib/components/ProductImageCarousel/carousel.shimmer.module.css +7 -0
- package/src/overwrites/venia-ui/lib/components/ProductImageCarousel/index.js +1 -0
- package/src/overwrites/venia-ui/lib/components/ProductImageCarousel/thumbnail.js +108 -0
- package/src/overwrites/venia-ui/lib/components/ProductImageCarousel/thumbnail.module.css +47 -0
- package/src/overwrites/venia-ui/lib/components/ProductSort/index.js +2 -0
- package/src/overwrites/venia-ui/lib/components/ProductSort/productSort.js +233 -0
- package/src/overwrites/venia-ui/lib/components/ProductSort/productSort.module.css +65 -0
- package/src/overwrites/venia-ui/lib/components/ProductSort/productSort.shimmer.js +28 -0
- package/src/overwrites/venia-ui/lib/components/ProductSort/productSort.shimmer.module.css +10 -0
- package/src/overwrites/venia-ui/lib/components/ProductSort/sortItem.js +57 -0
- package/src/overwrites/venia-ui/lib/components/ProductSort/sortItem.module.css +23 -0
- package/src/overwrites/venia-ui/lib/components/QuantityStepper/index.js +1 -0
- package/src/overwrites/venia-ui/lib/components/QuantityStepper/quantityStepper.js +94 -0
- package/src/overwrites/venia-ui/lib/components/QuantityStepper/quantityStepper.module.css +78 -0
- package/src/overwrites/venia-ui/lib/components/RichContent/index.js +1 -0
- package/src/overwrites/venia-ui/lib/components/RichContent/plainHtmlRenderer.js +17 -0
- package/src/overwrites/venia-ui/lib/components/RichContent/richContent.js +59 -0
- package/src/overwrites/venia-ui/lib/components/RichContent/richContent.module.css +146 -0
- package/src/overwrites/venia-ui/lib/components/RichContent/richContentRenderers.js +7 -0
- package/src/overwrites/venia-ui/lib/components/SearchBar/searchBar.module.css +1 -2
- package/src/overwrites/venia-ui/lib/components/SearchBar/searchField.js +3 -2
- package/src/overwrites/venia-ui/lib/components/TextInput/field.module.css +50 -0
- package/src/overwrites/venia-ui/lib/components/TextInput/index.js +1 -0
- package/src/overwrites/venia-ui/lib/components/TextInput/textInput.js +48 -0
- package/src/overwrites/venia-ui/lib/components/TextInput/textInput.module.css +21 -0
- package/src/talons/FilterOption/useFilterOptionModal.js +11 -0
- package/src/talons/FilterOptionModal/useFilterOptionModal.js +11 -0
- package/src/theme/vars.js +12 -0
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import React, { useMemo, useCallback } from 'react';
|
|
2
|
+
import { ChevronDown as ArrowDown } from 'react-feather';
|
|
3
|
+
import { FormattedMessage, useIntl } from 'react-intl';
|
|
4
|
+
import { array, arrayOf, shape, string } from 'prop-types';
|
|
5
|
+
import { useDropdown } from '@magento/peregrine/lib/hooks/useDropdown';
|
|
6
|
+
|
|
7
|
+
import { useStyle } from '@magento/venia-ui/lib/classify';
|
|
8
|
+
import SortItem from './sortItem';
|
|
9
|
+
import defaultClasses from './productSort.module.css';
|
|
10
|
+
import Button from '@magento/venia-ui/lib/components/Button';
|
|
11
|
+
// import Icon from '@magento/venia-ui/lib/components/Icon';
|
|
12
|
+
import { ArrowUp2 } from 'iconsax-react';
|
|
13
|
+
import cn from 'classnames';
|
|
14
|
+
|
|
15
|
+
const ProductSort = props => {
|
|
16
|
+
const classes = useStyle(defaultClasses, props.classes);
|
|
17
|
+
const { availableSortMethods, sortProps } = props;
|
|
18
|
+
const [currentSort, setSort] = sortProps;
|
|
19
|
+
const { elementRef, expanded, setExpanded } = useDropdown();
|
|
20
|
+
const { formatMessage, locale } = useIntl();
|
|
21
|
+
|
|
22
|
+
const orderSortingList = useCallback(
|
|
23
|
+
list => {
|
|
24
|
+
return list.sort((a, b) => {
|
|
25
|
+
return a.text.localeCompare(b.text, locale, {
|
|
26
|
+
sensitivity: 'base'
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
},
|
|
30
|
+
[locale]
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
const sortMethodsFromConfig = availableSortMethods
|
|
34
|
+
? availableSortMethods
|
|
35
|
+
.map(method => {
|
|
36
|
+
const { value, label } = method;
|
|
37
|
+
if (value !== 'price' && value !== 'position') {
|
|
38
|
+
return {
|
|
39
|
+
id: `sortItem.${value}`,
|
|
40
|
+
text: label,
|
|
41
|
+
attribute: value,
|
|
42
|
+
sortDirection: 'ASC'
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
})
|
|
46
|
+
.filter(method => !!method)
|
|
47
|
+
: null;
|
|
48
|
+
|
|
49
|
+
// click event for menu items
|
|
50
|
+
const handleItemClick = useCallback(
|
|
51
|
+
sortAttribute => {
|
|
52
|
+
setSort(prevSort => {
|
|
53
|
+
return {
|
|
54
|
+
sortText: sortAttribute.text,
|
|
55
|
+
sortId: sortAttribute.id,
|
|
56
|
+
sortAttribute: sortAttribute.attribute,
|
|
57
|
+
sortDirection: sortAttribute.sortDirection,
|
|
58
|
+
sortFromSearch: prevSort.sortFromSearch
|
|
59
|
+
};
|
|
60
|
+
});
|
|
61
|
+
setExpanded(false);
|
|
62
|
+
},
|
|
63
|
+
[setExpanded, setSort]
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
const sortElements = useMemo(() => {
|
|
67
|
+
// should be not render item in collapsed mode.
|
|
68
|
+
if (!expanded) {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const defaultSortMethods = [
|
|
73
|
+
{
|
|
74
|
+
id: 'sortItem.relevance',
|
|
75
|
+
text: formatMessage({
|
|
76
|
+
id: 'sortItem.relevance',
|
|
77
|
+
defaultMessage: 'Best Match'
|
|
78
|
+
}),
|
|
79
|
+
attribute: 'relevance',
|
|
80
|
+
sortDirection: 'DESC'
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
id: 'sortItem.priceDesc',
|
|
84
|
+
text: formatMessage({
|
|
85
|
+
id: 'sortItem.priceDesc',
|
|
86
|
+
defaultMessage: 'Price: High to Low'
|
|
87
|
+
}),
|
|
88
|
+
attribute: 'price',
|
|
89
|
+
sortDirection: 'DESC'
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
id: 'sortItem.priceAsc',
|
|
93
|
+
text: formatMessage({
|
|
94
|
+
id: 'sortItem.priceAsc',
|
|
95
|
+
defaultMessage: 'Price: Low to High'
|
|
96
|
+
}),
|
|
97
|
+
attribute: 'price',
|
|
98
|
+
sortDirection: 'ASC'
|
|
99
|
+
}
|
|
100
|
+
];
|
|
101
|
+
|
|
102
|
+
// Do not display Position in Search
|
|
103
|
+
if (!currentSort.sortFromSearch) {
|
|
104
|
+
defaultSortMethods.push({
|
|
105
|
+
id: 'sortItem.position',
|
|
106
|
+
text: formatMessage({
|
|
107
|
+
id: 'sortItem.position',
|
|
108
|
+
defaultMessage: 'Position'
|
|
109
|
+
}),
|
|
110
|
+
attribute: 'position',
|
|
111
|
+
sortDirection: 'ASC'
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const allSortingMethods = sortMethodsFromConfig
|
|
116
|
+
? orderSortingList(
|
|
117
|
+
[sortMethodsFromConfig, defaultSortMethods].flat()
|
|
118
|
+
)
|
|
119
|
+
: defaultSortMethods;
|
|
120
|
+
|
|
121
|
+
const itemElements = Array.from(allSortingMethods, sortItem => {
|
|
122
|
+
const { attribute, sortDirection } = sortItem;
|
|
123
|
+
const isActive =
|
|
124
|
+
currentSort.sortAttribute === attribute &&
|
|
125
|
+
currentSort.sortDirection === sortDirection;
|
|
126
|
+
|
|
127
|
+
const key = `${attribute}--${sortDirection}`;
|
|
128
|
+
return (
|
|
129
|
+
<li key={key} className={classes.menuItem}>
|
|
130
|
+
<SortItem
|
|
131
|
+
sortItem={sortItem}
|
|
132
|
+
active={isActive}
|
|
133
|
+
onClick={handleItemClick}
|
|
134
|
+
/>
|
|
135
|
+
</li>
|
|
136
|
+
);
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
return (
|
|
140
|
+
<div className={classes.menu}>
|
|
141
|
+
<ul className='flex flex-col gap-2'>{itemElements}</ul>
|
|
142
|
+
</div>
|
|
143
|
+
);
|
|
144
|
+
}, [
|
|
145
|
+
classes.menu,
|
|
146
|
+
classes.menuItem,
|
|
147
|
+
currentSort.sortAttribute,
|
|
148
|
+
currentSort.sortDirection,
|
|
149
|
+
currentSort.sortFromSearch,
|
|
150
|
+
expanded,
|
|
151
|
+
formatMessage,
|
|
152
|
+
handleItemClick,
|
|
153
|
+
orderSortingList,
|
|
154
|
+
sortMethodsFromConfig
|
|
155
|
+
]);
|
|
156
|
+
|
|
157
|
+
// expand or collapse on click
|
|
158
|
+
const handleSortClick = () => {
|
|
159
|
+
setExpanded(!expanded);
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
const handleKeypress = e => {
|
|
163
|
+
if (e.code == 'Enter') {
|
|
164
|
+
setExpanded(expanded);
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
const result = expanded
|
|
168
|
+
? formatMessage({
|
|
169
|
+
id: 'productSort.sortButtonExpanded',
|
|
170
|
+
defaultMessage: 'Sort Button Expanded'
|
|
171
|
+
})
|
|
172
|
+
: formatMessage({
|
|
173
|
+
id: 'productSort.sortButtonCollapsed',
|
|
174
|
+
defaultMessage: 'Sort Button Collapsed'
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
return (
|
|
178
|
+
<div
|
|
179
|
+
ref={elementRef}
|
|
180
|
+
className={classes.root}
|
|
181
|
+
data-cy="ProductSort-root"
|
|
182
|
+
aria-busy="false"
|
|
183
|
+
>
|
|
184
|
+
<Button
|
|
185
|
+
priority={'low'}
|
|
186
|
+
classes={{
|
|
187
|
+
root_lowPriority: classes.sortButton
|
|
188
|
+
}}
|
|
189
|
+
onClick={handleSortClick}
|
|
190
|
+
data-cy="ProductSort-sortButton"
|
|
191
|
+
onKeyDown={handleKeypress}
|
|
192
|
+
aria-label={result}
|
|
193
|
+
className='border border-gray-100 border-solid rounded-[5px] p-2.5 flex gap-x-[15px]'
|
|
194
|
+
>
|
|
195
|
+
<span className={classes.mobileText}>
|
|
196
|
+
<FormattedMessage
|
|
197
|
+
id={'productSort.sortButton'}
|
|
198
|
+
defaultMessage={'Sort'}
|
|
199
|
+
/>
|
|
200
|
+
</span>
|
|
201
|
+
<span className={cn(classes.desktopText, 'flex items-center gap-[15px]')}>
|
|
202
|
+
<span className={classes.sortText}>
|
|
203
|
+
<FormattedMessage
|
|
204
|
+
id={'productSort.sortByButton'}
|
|
205
|
+
defaultMessage={'Sort by'}
|
|
206
|
+
/>
|
|
207
|
+
{currentSort.sortText}
|
|
208
|
+
</span>
|
|
209
|
+
<ArrowUp2 size={15} className={cn('text-gray-900 transition-all stroke-[#292D32]', expanded ? 'rotate-0' : 'rotate-180')} />
|
|
210
|
+
</span>
|
|
211
|
+
</Button>
|
|
212
|
+
{sortElements}
|
|
213
|
+
</div>
|
|
214
|
+
);
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
ProductSort.propTypes = {
|
|
218
|
+
classes: shape({
|
|
219
|
+
menuItem: string,
|
|
220
|
+
menu: string,
|
|
221
|
+
root: string,
|
|
222
|
+
sortButton: string
|
|
223
|
+
}),
|
|
224
|
+
availableSortMethods: arrayOf(
|
|
225
|
+
shape({
|
|
226
|
+
label: string,
|
|
227
|
+
value: string
|
|
228
|
+
})
|
|
229
|
+
),
|
|
230
|
+
sortProps: array
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
export default ProductSort;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
.root {
|
|
2
|
+
composes: relative from global;
|
|
3
|
+
composes: ml-2xs from global;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
.menu {
|
|
7
|
+
composes: absolute from global;
|
|
8
|
+
composes: bg-clip-padding from global;
|
|
9
|
+
composes: bg-white from global;
|
|
10
|
+
composes: border from global;
|
|
11
|
+
composes: border-solid from global;
|
|
12
|
+
composes: border-gray-100 from global;
|
|
13
|
+
composes: list-none from global;
|
|
14
|
+
composes: mb-0 from global;
|
|
15
|
+
composes: min-w-[10rem] from global;
|
|
16
|
+
composes: mt-0.5 from global;
|
|
17
|
+
composes: mx-0 from global;
|
|
18
|
+
composes: right-0 from global;
|
|
19
|
+
composes: rounded from global;
|
|
20
|
+
composes: shadow-menu from global;
|
|
21
|
+
composes: text-colorDefault from global;
|
|
22
|
+
composes: text-left from global;
|
|
23
|
+
composes: top-[110%] from global;
|
|
24
|
+
composes: z-menu from global;
|
|
25
|
+
composes: p-2.5 from global;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.menuItem {
|
|
29
|
+
composes: hover_bg-gray-100 from global;
|
|
30
|
+
composes: rounded-[5px] from global;
|
|
31
|
+
composes: relative from global;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.sortButton {
|
|
35
|
+
composes: rounded-[5px] from global;
|
|
36
|
+
composes: p-2.5 from global;
|
|
37
|
+
|
|
38
|
+
composes: min-w-[154px] from global;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.desktopText {
|
|
42
|
+
composes: hidden from global;
|
|
43
|
+
|
|
44
|
+
composes: lg_inline-flex from global;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.sortText {
|
|
48
|
+
composes: leading-normal from global;
|
|
49
|
+
composes: text-colorDefault from global;
|
|
50
|
+
composes: text-[14px] from global;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.desktopIconWrapper {
|
|
54
|
+
transform: translateX(10px);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.desktopIcon {
|
|
58
|
+
/* composes: icon from '../Icon/icon.module.css'; */
|
|
59
|
+
|
|
60
|
+
composes: stroke-gray-500 from global;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.mobileText {
|
|
64
|
+
composes: lg_hidden from global;
|
|
65
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { shape, string } from 'prop-types';
|
|
3
|
+
import { useStyle } from '@magento/venia-ui/lib/classify';
|
|
4
|
+
|
|
5
|
+
import Shimmer from '@magento/venia-ui/lib/components/Shimmer';
|
|
6
|
+
import defaultClasses from './productSort.shimmer.module.css';
|
|
7
|
+
|
|
8
|
+
const ProductSortShimmer = props => {
|
|
9
|
+
const classes = useStyle(defaultClasses, props.classes);
|
|
10
|
+
|
|
11
|
+
return (
|
|
12
|
+
<div className={classes.root} aria-live="polite" aria-busy="true">
|
|
13
|
+
<Shimmer
|
|
14
|
+
classes={{ root_button: classes.sortButtonShimmer }}
|
|
15
|
+
type="button"
|
|
16
|
+
/>
|
|
17
|
+
</div>
|
|
18
|
+
);
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
ProductSortShimmer.propTypes = {
|
|
22
|
+
classes: shape({
|
|
23
|
+
root: string,
|
|
24
|
+
sortButtonShimmer: string
|
|
25
|
+
})
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export default ProductSortShimmer;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import React, { useCallback } from 'react';
|
|
2
|
+
import { Check } from 'react-feather';
|
|
3
|
+
import { bool, func, shape, string } from 'prop-types';
|
|
4
|
+
|
|
5
|
+
import { useStyle } from '@magento/venia-ui/lib/classify';
|
|
6
|
+
import defaultClasses from './sortItem.module.css';
|
|
7
|
+
import cn from 'classnames';
|
|
8
|
+
|
|
9
|
+
const SortItem = props => {
|
|
10
|
+
const { active, onClick, sortItem } = props;
|
|
11
|
+
const classes = useStyle(defaultClasses, props.classes);
|
|
12
|
+
|
|
13
|
+
const handleClick = useCallback(
|
|
14
|
+
e => {
|
|
15
|
+
// use only left click for selection
|
|
16
|
+
if (e.button === 0) {
|
|
17
|
+
onClick(sortItem);
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
[sortItem, onClick]
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
const handleKeyDown = useCallback(
|
|
24
|
+
e => {
|
|
25
|
+
if (e.key === 'Enter' || e.key === ' ') {
|
|
26
|
+
e.preventDefault();
|
|
27
|
+
onClick(sortItem);
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
[onClick, sortItem]
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
return (
|
|
34
|
+
<button
|
|
35
|
+
className={cn(classes.root, active ? `before_block before_h-[100%] before_w-[3px] before_bg-blue-700 before_left-[-10px] before_absolute` : '')}
|
|
36
|
+
data-cy={active ? 'SortItem-activeButton' : 'SortItem-button'}
|
|
37
|
+
onMouseDown={handleClick}
|
|
38
|
+
onKeyDown={handleKeyDown}
|
|
39
|
+
>
|
|
40
|
+
<span className={classes.content}>
|
|
41
|
+
<span className={classes.text}>{sortItem.text}</span>
|
|
42
|
+
</span>
|
|
43
|
+
</button>
|
|
44
|
+
);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
SortItem.propTypes = {
|
|
48
|
+
active: bool,
|
|
49
|
+
classes: shape({
|
|
50
|
+
content: string,
|
|
51
|
+
root: string,
|
|
52
|
+
text: string
|
|
53
|
+
}),
|
|
54
|
+
onClick: func
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
export default SortItem;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
.root {
|
|
2
|
+
composes: flex from global;
|
|
3
|
+
composes: items-center from global;
|
|
4
|
+
composes: w-full from global;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.content {
|
|
8
|
+
composes: items-center from global;
|
|
9
|
+
composes: grid from global;
|
|
10
|
+
composes: grid-cols-[1fr] from global;
|
|
11
|
+
composes: grid-flow-col from global;
|
|
12
|
+
composes: gap-3 from global;
|
|
13
|
+
composes: h-[30px] from global;
|
|
14
|
+
composes: px-3 from global;
|
|
15
|
+
composes: py-0 from global;
|
|
16
|
+
composes: w-full from global;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.text {
|
|
20
|
+
composes: text-left from global;
|
|
21
|
+
composes: whitespace-nowrap from global;
|
|
22
|
+
composes: text-[14px] from global;
|
|
23
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from './quantityStepper';
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import React, { Fragment } from 'react';
|
|
2
|
+
import { useIntl } from 'react-intl';
|
|
3
|
+
import { Minus as MinusIcon, Plus as PlusIcon } from 'react-feather';
|
|
4
|
+
import { useQuantityStepper } from '@magento/peregrine/lib/talons/QuantityStepper/useQuantityStepper';
|
|
5
|
+
|
|
6
|
+
import { useStyle } from '@magento/venia-ui/lib/classify';
|
|
7
|
+
import Icon from '@magento/venia-ui/lib/components/Icon';
|
|
8
|
+
import TextInput from '../TextInput';
|
|
9
|
+
import { Message } from '@magento/venia-ui/lib/components/Field';
|
|
10
|
+
import defaultClasses from './quantityStepper.module.css';
|
|
11
|
+
|
|
12
|
+
const QuantityStepper = props => {
|
|
13
|
+
const { initialValue, itemId, label, min, onChange, message } = props;
|
|
14
|
+
const { formatMessage } = useIntl();
|
|
15
|
+
const classes = useStyle(defaultClasses, props.classes);
|
|
16
|
+
const iconClasses = { root: classes.icon };
|
|
17
|
+
|
|
18
|
+
const talonProps = useQuantityStepper({
|
|
19
|
+
initialValue,
|
|
20
|
+
min,
|
|
21
|
+
onChange
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
const {
|
|
25
|
+
isDecrementDisabled,
|
|
26
|
+
isIncrementDisabled,
|
|
27
|
+
handleBlur,
|
|
28
|
+
handleDecrement,
|
|
29
|
+
handleIncrement,
|
|
30
|
+
maskInput
|
|
31
|
+
} = talonProps;
|
|
32
|
+
|
|
33
|
+
const errorMessage = message ? <Message>{message}</Message> : null;
|
|
34
|
+
|
|
35
|
+
return (
|
|
36
|
+
<Fragment>
|
|
37
|
+
<div className={classes.root}>
|
|
38
|
+
<label className={classes.label} htmlFor={itemId}>
|
|
39
|
+
{label}
|
|
40
|
+
</label>
|
|
41
|
+
<button
|
|
42
|
+
aria-label={formatMessage({
|
|
43
|
+
id: 'quantity.buttonDecrement',
|
|
44
|
+
defaultMessage: 'Decrease Quantity'
|
|
45
|
+
})}
|
|
46
|
+
className={classes.button_decrement}
|
|
47
|
+
disabled={isDecrementDisabled}
|
|
48
|
+
onClick={handleDecrement}
|
|
49
|
+
type="button"
|
|
50
|
+
data-cy="Quantity-decrementButton"
|
|
51
|
+
>
|
|
52
|
+
<Icon classes={iconClasses} src={MinusIcon} size={22} />
|
|
53
|
+
</button>
|
|
54
|
+
<TextInput
|
|
55
|
+
aria-label={formatMessage({
|
|
56
|
+
id: 'quantity.input',
|
|
57
|
+
defaultMessage: 'Item Quantity'
|
|
58
|
+
})}
|
|
59
|
+
data-cy="QuantityStepper-input"
|
|
60
|
+
classes={{ input: classes.input }}
|
|
61
|
+
field="quantity"
|
|
62
|
+
id={itemId}
|
|
63
|
+
inputMode="numeric"
|
|
64
|
+
mask={maskInput}
|
|
65
|
+
min={min}
|
|
66
|
+
onBlur={handleBlur}
|
|
67
|
+
pattern="[0-9]*"
|
|
68
|
+
/>
|
|
69
|
+
<button
|
|
70
|
+
aria-label={formatMessage({
|
|
71
|
+
id: 'quantity.buttonIncrement',
|
|
72
|
+
defaultMessage: 'Increase Quantity'
|
|
73
|
+
})}
|
|
74
|
+
className={classes.button_increment}
|
|
75
|
+
disabled={isIncrementDisabled}
|
|
76
|
+
onClick={handleIncrement}
|
|
77
|
+
type="button"
|
|
78
|
+
data-cy="Quantity-incrementButton"
|
|
79
|
+
>
|
|
80
|
+
<Icon classes={iconClasses} src={PlusIcon} size={20} />
|
|
81
|
+
</button>
|
|
82
|
+
</div>
|
|
83
|
+
{errorMessage}
|
|
84
|
+
</Fragment>
|
|
85
|
+
);
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
QuantityStepper.defaultProps = {
|
|
89
|
+
min: 0,
|
|
90
|
+
initialValue: 1,
|
|
91
|
+
onChange: () => { }
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
export default QuantityStepper;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
.root {
|
|
2
|
+
--stroke: var(--venia-global-color-gray-600);
|
|
3
|
+
|
|
4
|
+
composes: gap-x-2xs from global;
|
|
5
|
+
composes: grid from global;
|
|
6
|
+
composes: items-center from global;
|
|
7
|
+
composes: justify-items-center from global;
|
|
8
|
+
composes: text-center from global;
|
|
9
|
+
grid-template-columns: 1fr 4rem 1fr;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.wrap {
|
|
13
|
+
composes: flex from global;
|
|
14
|
+
composes: items-center from global;
|
|
15
|
+
composes: justify-center from global;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/* TODO @TW: cannot compose */
|
|
19
|
+
.label:not(:focus):not(:active) {
|
|
20
|
+
/* composes: sr-only from global; */
|
|
21
|
+
position: absolute;
|
|
22
|
+
overflow: hidden;
|
|
23
|
+
width: 1px;
|
|
24
|
+
height: 1px;
|
|
25
|
+
clip: rect(0 0 0 0);
|
|
26
|
+
clip-path: inset(100%);
|
|
27
|
+
white-space: nowrap;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.button {
|
|
31
|
+
composes: bg-white from global;
|
|
32
|
+
composes: border-2 from global;
|
|
33
|
+
composes: border-solid from global;
|
|
34
|
+
composes: border-button from global;
|
|
35
|
+
composes: h-[2rem] from global;
|
|
36
|
+
composes: inline-flex from global;
|
|
37
|
+
composes: items-center from global;
|
|
38
|
+
composes: justify-center from global;
|
|
39
|
+
composes: rounded-full from global;
|
|
40
|
+
composes: w-[2rem] from global;
|
|
41
|
+
stroke: rgb(var(--stroke));
|
|
42
|
+
|
|
43
|
+
composes: disabled_cursor-not-allowed from global;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.button:hover {
|
|
47
|
+
--stroke: rgb(var(--venia-global-color-gray-900));
|
|
48
|
+
border-color: rgb(var(--stroke));
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/* TODO @TW: cannot compose */
|
|
52
|
+
.button:disabled,
|
|
53
|
+
.button:disabled:hover {
|
|
54
|
+
--stroke: rgb(var(--venia-global-color-gray-400));
|
|
55
|
+
/* composes: border-subtle from global; */
|
|
56
|
+
border-color: rgb(var(--venia-global-color-gray-400));
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.button_decrement {
|
|
60
|
+
composes: button;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.button_increment {
|
|
64
|
+
composes: button;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.icon {
|
|
68
|
+
composes: items-center from global;
|
|
69
|
+
composes: inline-flex from global;
|
|
70
|
+
composes: justify-center from global;
|
|
71
|
+
touch-action: manipulation;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.input {
|
|
75
|
+
composes: input from '../TextInput/textInput.module.css';
|
|
76
|
+
|
|
77
|
+
composes: text-center from global;
|
|
78
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from './richContent';
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import htmlStringImgUrlConverter from '@magento/peregrine/lib/util/htmlStringImgUrlConverter';
|
|
3
|
+
|
|
4
|
+
const toHTML = str => ({ __html: htmlStringImgUrlConverter(str) });
|
|
5
|
+
|
|
6
|
+
function PlainHtmlRenderer({ html, classes }) {
|
|
7
|
+
// Even if empty, render a div with no content, for styling purposes.
|
|
8
|
+
if (!html) {
|
|
9
|
+
return <div className={classes.root} />;
|
|
10
|
+
}
|
|
11
|
+
return (
|
|
12
|
+
<div className={classes.root} dangerouslySetInnerHTML={toHTML(html)} />
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const canRender = () => true; // backstop component, always renders
|
|
17
|
+
export const Component = PlainHtmlRenderer;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { useStyle } from '@magento/venia-ui/lib/classify';
|
|
3
|
+
import defaultClasses from './richContent.module.css';
|
|
4
|
+
import { shape, string } from 'prop-types';
|
|
5
|
+
import richContentRenderers from './richContentRenderers';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* RichContent component.
|
|
9
|
+
*
|
|
10
|
+
* This component serves as the pool to determine which type of content is being rendered
|
|
11
|
+
* and pass the data off to the correct system.
|
|
12
|
+
*
|
|
13
|
+
* @typedef RichContent
|
|
14
|
+
* @kind functional component
|
|
15
|
+
*
|
|
16
|
+
* @param {Object} props React component props
|
|
17
|
+
*
|
|
18
|
+
* @returns {React.Element} A React component that renders Heading with optional styling properties.
|
|
19
|
+
*/
|
|
20
|
+
const RichContent = props => {
|
|
21
|
+
const classes = useStyle(defaultClasses, props.classes);
|
|
22
|
+
const rendererProps = {
|
|
23
|
+
...props,
|
|
24
|
+
classes
|
|
25
|
+
};
|
|
26
|
+
for (const Renderer of richContentRenderers) {
|
|
27
|
+
const { Component, canRender } = Renderer;
|
|
28
|
+
if (canRender(rendererProps.html)) {
|
|
29
|
+
return <Component {...rendererProps} />;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
// If no renderer returned a value
|
|
33
|
+
if (process.env.NODE_ENV === 'development') {
|
|
34
|
+
console.warn(
|
|
35
|
+
`None of the following rich content renderers returned anything for the provided HTML.`,
|
|
36
|
+
richContentRenderers.map(r => `<${r.name}>`),
|
|
37
|
+
props.html
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
return null;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Props for {@link RichContent}
|
|
45
|
+
*
|
|
46
|
+
* @typedef props
|
|
47
|
+
*
|
|
48
|
+
* @property {Object} classes An object containing the class names for the RichContent
|
|
49
|
+
* @property {String} classes.root CSS class for the root container element
|
|
50
|
+
* @property {String} html Content
|
|
51
|
+
*/
|
|
52
|
+
RichContent.propTypes = {
|
|
53
|
+
classes: shape({
|
|
54
|
+
root: string
|
|
55
|
+
}),
|
|
56
|
+
html: string
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export default RichContent;
|