@magento/venia-pwa-live-search 1.0.0-alpha10
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/package.json +31 -0
- package/postcss.config.js +3 -0
- package/src/api/fragments.js +193 -0
- package/src/api/graphql.js +26 -0
- package/src/api/mutations.js +94 -0
- package/src/api/queries.js +225 -0
- package/src/api/search.js +222 -0
- package/src/components/AddToCartButton/AddToCartButton.jsx +32 -0
- package/src/components/AddToCartButton/AddToCartButton.stories.mdx +14 -0
- package/src/components/AddToCartButton/index.js +10 -0
- package/src/components/Alert/Alert.jsx +155 -0
- package/src/components/Alert/index.js +11 -0
- package/src/components/Breadcrumbs/Breadcrumbs.jsx +34 -0
- package/src/components/Breadcrumbs/MockPages.js +14 -0
- package/src/components/Breadcrumbs/index.js +11 -0
- package/src/components/ButtonShimmer/ButtonShimmer.css +32 -0
- package/src/components/ButtonShimmer/ButtonShimmer.jsx +23 -0
- package/src/components/ButtonShimmer/index.js +11 -0
- package/src/components/CategoryFilters/CategoryFilters.jsx +59 -0
- package/src/components/CategoryFilters/index.js +10 -0
- package/src/components/Facets/Facets.jsx +50 -0
- package/src/components/Facets/Range/RangeFacet.js +20 -0
- package/src/components/Facets/Scalar/ScalarFacet.js +29 -0
- package/src/components/Facets/SelectedFilters.js +80 -0
- package/src/components/Facets/format.js +52 -0
- package/src/components/Facets/index.js +14 -0
- package/src/components/Facets/mocks.js +119 -0
- package/src/components/FacetsShimmer/FacetsShimmer.css +49 -0
- package/src/components/FacetsShimmer/FacetsShimmer.jsx +25 -0
- package/src/components/FacetsShimmer/index.js +11 -0
- package/src/components/FilterButton/FilterButton.jsx +40 -0
- package/src/components/FilterButton/index.js +11 -0
- package/src/components/ImageCarousel/Image.jsx +34 -0
- package/src/components/ImageCarousel/ImageCarousel.jsx +103 -0
- package/src/components/ImageCarousel/index.js +11 -0
- package/src/components/InputButtonGroup/InputButtonGroup.jsx +120 -0
- package/src/components/InputButtonGroup/index.js +11 -0
- package/src/components/LabelledInput/LabelledInput.jsx +51 -0
- package/src/components/LabelledInput/index.js +11 -0
- package/src/components/Loading/Loading.jsx +32 -0
- package/src/components/Loading/index.js +11 -0
- package/src/components/NoResults/NoResults.jsx +55 -0
- package/src/components/NoResults/index.js +11 -0
- package/src/components/Pagination/Pagination.jsx +105 -0
- package/src/components/Pagination/index.js +10 -0
- package/src/components/PerPagePicker/PerPagePicker.jsx +114 -0
- package/src/components/PerPagePicker/index.js +11 -0
- package/src/components/Pill/Pill.jsx +34 -0
- package/src/components/Pill/index.js +11 -0
- package/src/components/Pill/mock.js +23 -0
- package/src/components/ProductCardShimmer/ProductCardShimmer.css +72 -0
- package/src/components/ProductCardShimmer/ProductCardShimmer.jsx +28 -0
- package/src/components/ProductCardShimmer/index.js +11 -0
- package/src/components/ProductItem/MockData.js +508 -0
- package/src/components/ProductItem/ProductItem.css +84 -0
- package/src/components/ProductItem/ProductItem.jsx +347 -0
- package/src/components/ProductItem/ProductPrice.jsx +181 -0
- package/src/components/ProductItem/index.js +11 -0
- package/src/components/ProductList/MockData.js +190 -0
- package/src/components/ProductList/ProductList.jsx +127 -0
- package/src/components/ProductList/index.js +11 -0
- package/src/components/ProductList/product-list.css +18 -0
- package/src/components/SearchBar/SearchBar.jsx +33 -0
- package/src/components/SearchBar/index.js +11 -0
- package/src/components/Shimmer/Shimmer.css +82 -0
- package/src/components/Shimmer/Shimmer.jsx +66 -0
- package/src/components/Shimmer/index.js +11 -0
- package/src/components/Slider/Slider.css +61 -0
- package/src/components/Slider/Slider.jsx +103 -0
- package/src/components/Slider/index.jsx +11 -0
- package/src/components/SliderDoubleControl/SliderDoubleControl.css +83 -0
- package/src/components/SliderDoubleControl/SliderDoubleControl.jsx +220 -0
- package/src/components/SliderDoubleControl/index.js +11 -0
- package/src/components/SortDropdown/SortDropdown.jsx +126 -0
- package/src/components/SortDropdown/index.js +11 -0
- package/src/components/SwatchButton/SwatchButton.jsx +72 -0
- package/src/components/SwatchButton/index.js +11 -0
- package/src/components/SwatchButtonGroup/SwatchButtonGroup.jsx +86 -0
- package/src/components/SwatchButtonGroup/index.js +11 -0
- package/src/components/ViewSwitcher/ViewSwitcher.jsx +46 -0
- package/src/components/ViewSwitcher/index.js +11 -0
- package/src/components/WishlistButton/WishlistButton.jsx +67 -0
- package/src/components/WishlistButton/index.js +11 -0
- package/src/containers/App.jsx +145 -0
- package/src/containers/LiveSearchPLPLoader.jsx +24 -0
- package/src/containers/LiveSearchPopoverLoader.jsx +190 -0
- package/src/containers/LiveSearchSRLPLoader.jsx +24 -0
- package/src/containers/ProductListingPage.jsx +66 -0
- package/src/containers/ProductsContainer.jsx +145 -0
- package/src/containers/ProductsHeader.jsx +123 -0
- package/src/context/attributeMetadata.js +63 -0
- package/src/context/cart.js +97 -0
- package/src/context/displayChange.js +90 -0
- package/src/context/events.js +160 -0
- package/src/context/index.js +19 -0
- package/src/context/products.jsx +336 -0
- package/src/context/resultsModifierContext.js +35 -0
- package/src/context/search.jsx +127 -0
- package/src/context/store.jsx +93 -0
- package/src/context/translation.jsx +125 -0
- package/src/context/widgetConfig.jsx +120 -0
- package/src/context/wishlist.jsx +97 -0
- package/src/hooks/eventing/useEventListener.js +13 -0
- package/src/hooks/eventing/useLocation.js +21 -0
- package/src/hooks/eventing/useMagentoExtensionContext.js +28 -0
- package/src/hooks/eventing/usePageView.js +36 -0
- package/src/hooks/eventing/useShopperContext.js +33 -0
- package/src/hooks/eventing/useStorefrontInstanceContext.js +46 -0
- package/src/hooks/eventing/useViewedOffsets.js +74 -0
- package/src/hooks/useAccessibleDropdown.js +148 -0
- package/src/hooks/useLiveSearchPLPConfig.js +112 -0
- package/src/hooks/useLiveSearchPopoverConfig.js +83 -0
- package/src/hooks/useLiveSearchSRLPConfig.js +97 -0
- package/src/hooks/usePagination.js +83 -0
- package/src/hooks/useRangeFacet.js +62 -0
- package/src/hooks/useScalarFacet.js +61 -0
- package/src/hooks/useSliderFacet.js +43 -0
- package/src/i18n/Sorani.js +60 -0
- package/src/i18n/ar_AE.js +60 -0
- package/src/i18n/bg_BG.js +60 -0
- package/src/i18n/bn_IN.js +60 -0
- package/src/i18n/ca_ES.js +60 -0
- package/src/i18n/cs_CZ.js +60 -0
- package/src/i18n/da_DK.js +60 -0
- package/src/i18n/de_DE.js +60 -0
- package/src/i18n/el_GR.js +60 -0
- package/src/i18n/en_GA.js +60 -0
- package/src/i18n/en_GB.js +60 -0
- package/src/i18n/en_US.js +70 -0
- package/src/i18n/es_ES.js +60 -0
- package/src/i18n/et_EE.js +60 -0
- package/src/i18n/eu_ES.js +60 -0
- package/src/i18n/fa_IR.js +60 -0
- package/src/i18n/fi_FI.js +60 -0
- package/src/i18n/fr_FR.js +60 -0
- package/src/i18n/gl_ES.js +60 -0
- package/src/i18n/hi_IN.js +60 -0
- package/src/i18n/hu_HU.js +60 -0
- package/src/i18n/hy_AM.js +60 -0
- package/src/i18n/id_ID.js +60 -0
- package/src/i18n/index.js +89 -0
- package/src/i18n/it_IT.js +60 -0
- package/src/i18n/ja_JP.js +60 -0
- package/src/i18n/ko_KR.js +60 -0
- package/src/i18n/lt_LT.js +60 -0
- package/src/i18n/lv_LV.js +60 -0
- package/src/i18n/nb_NO.js +60 -0
- package/src/i18n/nl_NL.js +60 -0
- package/src/i18n/pt_BR.js +60 -0
- package/src/i18n/pt_PT.js +60 -0
- package/src/i18n/ro_RO.js +60 -0
- package/src/i18n/ru_RU.js +60 -0
- package/src/i18n/sv_SE.js +60 -0
- package/src/i18n/th_TH.js +60 -0
- package/src/i18n/tr_TR.js +60 -0
- package/src/i18n/zh_Hans_CN.js +60 -0
- package/src/i18n/zh_Hant_TW.js +60 -0
- package/src/icons/NoImage.svg +1 -0
- package/src/icons/adjustments.svg +3 -0
- package/src/icons/cart.svg +3 -0
- package/src/icons/checkmark.svg +3 -0
- package/src/icons/chevron.svg +3 -0
- package/src/icons/emptyHeart.svg +3 -0
- package/src/icons/error.svg +3 -0
- package/src/icons/filledHeart.svg +3 -0
- package/src/icons/filter.svg +29 -0
- package/src/icons/gridView.svg +11 -0
- package/src/icons/info.svg +3 -0
- package/src/icons/listView.svg +5 -0
- package/src/icons/loading.svg +6 -0
- package/src/icons/plus.svg +4 -0
- package/src/icons/sort.svg +18 -0
- package/src/icons/warning.svg +3 -0
- package/src/icons/x.svg +3 -0
- package/src/index.jsx +65 -0
- package/src/queries/customerGroupCode.gql.js +10 -0
- package/src/queries/eventing/getMagentoExtensionContext.gql.js +13 -0
- package/src/queries/eventing/getPageType.gql.js +14 -0
- package/src/queries/eventing/getStorefrontContext.gql.js +27 -0
- package/src/queries/index.js +3 -0
- package/src/queries/liveSearchPlpConfigs.gql.js +30 -0
- package/src/queries/liveSearchPopoverConfigs.gql.js +28 -0
- package/src/styles/autocomplete.module.css +56 -0
- package/src/styles/index.css +1638 -0
- package/src/styles/searchBar.module.css +119 -0
- package/src/styles/tokens.css +99 -0
- package/src/targets/intercept.js +21 -0
- package/src/utils/constants.js +26 -0
- package/src/utils/decodeHtmlString.js +13 -0
- package/src/utils/dom.js +14 -0
- package/src/utils/eventing/getCookie.js +9 -0
- package/src/utils/eventing/usePageTypeFromUrl.js +26 -0
- package/src/utils/getProductImage.js +94 -0
- package/src/utils/getProductPrice.js +83 -0
- package/src/utils/getUserViewHistory.js +27 -0
- package/src/utils/handleUrlFilters.js +164 -0
- package/src/utils/htmlStringDecode.js +13 -0
- package/src/utils/modifyResults.js +164 -0
- package/src/utils/sort.js +95 -0
- package/src/utils/useIntersectionObserver.js +27 -0
- package/src/utils/validateStoreDetails.js +39 -0
- package/src/wrappers/wrapUseApp.js +28 -0
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2024 Adobe
|
|
3
|
+
All Rights Reserved.
|
|
4
|
+
|
|
5
|
+
NOTICE: Adobe permits you to use, modify, and distribute this file in
|
|
6
|
+
accordance with the terms of the Adobe license agreement accompanying
|
|
7
|
+
it.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import React, { useState } from 'react';
|
|
11
|
+
|
|
12
|
+
import { useProducts, useTranslation } from '../../context';
|
|
13
|
+
import PlusIcon from '../../icons/plus.svg';
|
|
14
|
+
import { BOOLEAN_NO, BOOLEAN_YES } from '../../utils/constants';
|
|
15
|
+
import { LabelledInput } from '../LabelledInput';
|
|
16
|
+
|
|
17
|
+
const numberOfOptionsShown = 5;
|
|
18
|
+
|
|
19
|
+
const InputButtonGroup = ({
|
|
20
|
+
title,
|
|
21
|
+
attribute,
|
|
22
|
+
buckets,
|
|
23
|
+
isSelected,
|
|
24
|
+
onChange,
|
|
25
|
+
type,
|
|
26
|
+
inputGroupTitleSlot
|
|
27
|
+
}) => {
|
|
28
|
+
const translation = useTranslation();
|
|
29
|
+
const productsCtx = useProducts();
|
|
30
|
+
|
|
31
|
+
const [showMore, setShowMore] = useState(buckets.length < numberOfOptionsShown);
|
|
32
|
+
|
|
33
|
+
const numberOfOptions = showMore ? buckets.length : numberOfOptionsShown;
|
|
34
|
+
|
|
35
|
+
const onInputChange = (title, e) => {
|
|
36
|
+
onChange({
|
|
37
|
+
value: title,
|
|
38
|
+
selected: e?.target?.checked
|
|
39
|
+
});
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const formatLabel = (title, bucket) => {
|
|
43
|
+
if (bucket.__typename === 'RangeBucket') {
|
|
44
|
+
const currencyRate = productsCtx.currencyRate || '1';
|
|
45
|
+
const currencySymbol = productsCtx.currencySymbol || '$';
|
|
46
|
+
const from = bucket?.from
|
|
47
|
+
? (parseFloat(currencyRate) * parseInt(bucket.from.toFixed(0), 10)).toFixed(2)
|
|
48
|
+
: 0;
|
|
49
|
+
const to = bucket?.to
|
|
50
|
+
? ` - ${currencySymbol}${(
|
|
51
|
+
parseFloat(currencyRate) * parseInt(bucket.to.toFixed(0), 10)
|
|
52
|
+
).toFixed(2)}`
|
|
53
|
+
: translation.InputButtonGroup.priceRange;
|
|
54
|
+
return `${currencySymbol}${from}${to}`;
|
|
55
|
+
} else if (bucket.__typename === 'CategoryView') {
|
|
56
|
+
return productsCtx.categoryPath ? (bucket.name !== undefined && bucket.name !== null ? bucket.name : bucket.title) : bucket.title;
|
|
57
|
+
} else if (bucket.title === BOOLEAN_YES) {
|
|
58
|
+
return title;
|
|
59
|
+
} else if (bucket.title === BOOLEAN_NO) {
|
|
60
|
+
const excludedMessageTranslation = translation.InputButtonGroup.priceExcludedMessage;
|
|
61
|
+
const excludedMessage = excludedMessageTranslation.replace('{title}', `${title}`);
|
|
62
|
+
return excludedMessage;
|
|
63
|
+
}
|
|
64
|
+
return bucket.title;
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
return (
|
|
68
|
+
<div className="ds-sdk-input pt-md">
|
|
69
|
+
{inputGroupTitleSlot ? (
|
|
70
|
+
inputGroupTitleSlot(title)
|
|
71
|
+
) : (
|
|
72
|
+
<label className="ds-sdk-input__label text-base font-normal text-gray-900">
|
|
73
|
+
{title}
|
|
74
|
+
</label>
|
|
75
|
+
)}
|
|
76
|
+
<fieldset className="ds-sdk-input__options mt-md">
|
|
77
|
+
<div className="space-y-4">
|
|
78
|
+
{buckets.slice(0, numberOfOptions).map((option) => {
|
|
79
|
+
if (!option.title) {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
const checked = isSelected(option.title);
|
|
83
|
+
const noShowPriceBucketCount = option.__typename === 'RangeBucket';
|
|
84
|
+
return (
|
|
85
|
+
<LabelledInput
|
|
86
|
+
key={formatLabel(title, option)}
|
|
87
|
+
name={`${option.title}-${attribute}`}
|
|
88
|
+
attribute={attribute}
|
|
89
|
+
label={formatLabel(title, option)}
|
|
90
|
+
checked={!!checked}
|
|
91
|
+
value={option.title}
|
|
92
|
+
count={noShowPriceBucketCount ? null : option.count}
|
|
93
|
+
onChange={(e) => onInputChange(option.title, e)}
|
|
94
|
+
type={type}
|
|
95
|
+
/>
|
|
96
|
+
);
|
|
97
|
+
})}
|
|
98
|
+
{!showMore && buckets.length > numberOfOptionsShown && (
|
|
99
|
+
<div
|
|
100
|
+
className="ds-sdk-input__fieldset__show-more flex items-center text-gray-700 cursor-pointer"
|
|
101
|
+
onClick={() => setShowMore(true)}
|
|
102
|
+
>
|
|
103
|
+
<img src={PlusIcon} height="16px" width="16px" className="h-md w-md fill-gray-500" />
|
|
104
|
+
{/* <PlusIcon className="h-md w-md fill-gray-500" /> */}
|
|
105
|
+
<button
|
|
106
|
+
type="button"
|
|
107
|
+
className="ml-sm font-light cursor-pointer border-none bg-transparent hover:border-none hover:bg-transparent focus:border-none focus:bg-transparent active:border-none active:bg-transparent active:shadow-none text-sm"
|
|
108
|
+
>
|
|
109
|
+
{translation.InputButtonGroup.showmore}
|
|
110
|
+
</button>
|
|
111
|
+
</div>
|
|
112
|
+
)}
|
|
113
|
+
</div>
|
|
114
|
+
</fieldset>
|
|
115
|
+
<div className="ds-sdk-input__border border-t mt-md border-gray-200" />
|
|
116
|
+
</div>
|
|
117
|
+
);
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
export default InputButtonGroup;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2024 Adobe
|
|
3
|
+
All Rights Reserved.
|
|
4
|
+
|
|
5
|
+
NOTICE: Adobe permits you to use, modify, and distribute this file in
|
|
6
|
+
accordance with the terms of the Adobe license agreement accompanying
|
|
7
|
+
it.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
export * from './InputButtonGroup';
|
|
11
|
+
export { default as InputButtonGroup } from './InputButtonGroup';
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2024 Adobe
|
|
3
|
+
All Rights Reserved.
|
|
4
|
+
|
|
5
|
+
NOTICE: Adobe permits you to use, modify, and distribute this file in
|
|
6
|
+
accordance with the terms of the Adobe license agreement accompanying
|
|
7
|
+
it.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import React from 'react';
|
|
11
|
+
|
|
12
|
+
export const LabelledInput = ({
|
|
13
|
+
type,
|
|
14
|
+
checked,
|
|
15
|
+
onChange,
|
|
16
|
+
name,
|
|
17
|
+
label,
|
|
18
|
+
attribute,
|
|
19
|
+
value,
|
|
20
|
+
count,
|
|
21
|
+
}) => {
|
|
22
|
+
return (
|
|
23
|
+
<div className="ds-sdk-labelled-input flex items-center">
|
|
24
|
+
<input
|
|
25
|
+
id={name}
|
|
26
|
+
name={
|
|
27
|
+
type === 'checkbox'
|
|
28
|
+
? `checkbox-group-${attribute}`
|
|
29
|
+
: `radio-group-${attribute}`
|
|
30
|
+
}
|
|
31
|
+
type={type}
|
|
32
|
+
className="ds-sdk-labelled-input__input focus:ring-0 h-md w-md border-0 cursor-pointer accent-gray-600 min-w-[16px]"
|
|
33
|
+
checked={checked}
|
|
34
|
+
aria-checked={checked}
|
|
35
|
+
onChange={onChange}
|
|
36
|
+
value={value}
|
|
37
|
+
/>
|
|
38
|
+
<label
|
|
39
|
+
htmlFor={name}
|
|
40
|
+
className="ds-sdk-labelled-input__label ml-sm block-display text-sm font-light text-gray-700 cursor-pointer"
|
|
41
|
+
>
|
|
42
|
+
{label}
|
|
43
|
+
{count != null && (
|
|
44
|
+
<span className="text-[12px] font-light text-gray-700 ml-1">
|
|
45
|
+
{`(${count})`}
|
|
46
|
+
</span>
|
|
47
|
+
)}
|
|
48
|
+
</label>
|
|
49
|
+
</div>
|
|
50
|
+
);
|
|
51
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2024 Adobe
|
|
3
|
+
All Rights Reserved.
|
|
4
|
+
|
|
5
|
+
NOTICE: Adobe permits you to use, modify, and distribute this file in
|
|
6
|
+
accordance with the terms of the Adobe license agreement accompanying
|
|
7
|
+
it.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
export * from './LabelledInput';
|
|
11
|
+
export { LabelledInput as default } from './LabelledInput';
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2024 Adobe
|
|
3
|
+
All Rights Reserved.
|
|
4
|
+
|
|
5
|
+
NOTICE: Adobe permits you to use, modify, and distribute this file in
|
|
6
|
+
accordance with the terms of the Adobe license agreement accompanying
|
|
7
|
+
it.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import React from 'react';
|
|
11
|
+
import LoadingIcon from '../../icons/loading.svg';
|
|
12
|
+
|
|
13
|
+
export const Loading = ({ label }) => {
|
|
14
|
+
const isMobile = typeof window !== 'undefined' &&
|
|
15
|
+
window.matchMedia('only screen and (max-width: 768px)').matches;
|
|
16
|
+
|
|
17
|
+
return (
|
|
18
|
+
<div
|
|
19
|
+
className={`ds-sdk-loading flex h-screen justify-center items-center ${
|
|
20
|
+
isMobile ? 'loading-spinner-on-mobile' : ''
|
|
21
|
+
}`}
|
|
22
|
+
>
|
|
23
|
+
<div className="ds-sdk-loading__spinner bg-gray-100 rounded-full p-xs flex w-fit my-lg outline-gray-200">
|
|
24
|
+
{/* <LoadingIcon className="inline-block mr-xs ml-xs w-md animate-spin fill-primary" /> */}
|
|
25
|
+
<img src={LoadingIcon} className={`inline-block mr-xs ml-xs w-md animate-spin fill-primary`} />
|
|
26
|
+
<span className="ds-sdk-loading__spinner-label p-xs">{label}</span>
|
|
27
|
+
</div>
|
|
28
|
+
</div>
|
|
29
|
+
);
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export default Loading;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2024 Adobe
|
|
3
|
+
All Rights Reserved.
|
|
4
|
+
|
|
5
|
+
NOTICE: Adobe permits you to use, modify, and distribute this file in
|
|
6
|
+
accordance with the terms of the Adobe license agreement accompanying
|
|
7
|
+
it.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
export * from './Loading';
|
|
11
|
+
export { default } from './Loading';
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2024 Adobe
|
|
3
|
+
All Rights Reserved.
|
|
4
|
+
|
|
5
|
+
NOTICE: Adobe permits you to use, modify, and distribute this file in
|
|
6
|
+
accordance with the terms of the Adobe license agreement accompanying
|
|
7
|
+
it.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import React from 'react';
|
|
11
|
+
|
|
12
|
+
export const NoResults = ({ heading, subheading, isError }) => {
|
|
13
|
+
return (
|
|
14
|
+
<div className="ds-sdk-no-results__page">
|
|
15
|
+
{isError ? (
|
|
16
|
+
<svg
|
|
17
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
18
|
+
className="h-28 w-28 my-0 mx-auto stroke-gray-400"
|
|
19
|
+
fill="none"
|
|
20
|
+
viewBox="0 0 24 24"
|
|
21
|
+
stroke="currentColor"
|
|
22
|
+
strokeWidth="2"
|
|
23
|
+
>
|
|
24
|
+
<path
|
|
25
|
+
strokeLinecap="round"
|
|
26
|
+
strokeLinejoin="round"
|
|
27
|
+
d="M9.172 16.172a4 4 0 015.656 0M9 10h.01M15 10h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
|
|
28
|
+
/>
|
|
29
|
+
</svg>
|
|
30
|
+
) : (
|
|
31
|
+
<svg
|
|
32
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
33
|
+
className="h-28 w-28 my-0 mx-auto stroke-gray-400"
|
|
34
|
+
fill="none"
|
|
35
|
+
viewBox="0 0 24 24"
|
|
36
|
+
strokeWidth="1.5"
|
|
37
|
+
>
|
|
38
|
+
<path
|
|
39
|
+
strokeLinecap="round"
|
|
40
|
+
strokeLinejoin="round"
|
|
41
|
+
d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"
|
|
42
|
+
/>
|
|
43
|
+
</svg>
|
|
44
|
+
)}
|
|
45
|
+
<h1 className="ds-sdk-no-results__page__heading text-2xl text-center text-gray-600">
|
|
46
|
+
{heading}
|
|
47
|
+
</h1>
|
|
48
|
+
<h3 className="ds-sdk-no-results__page__subheading text-lg text-center text-gray-500">
|
|
49
|
+
{subheading}
|
|
50
|
+
</h3>
|
|
51
|
+
</div>
|
|
52
|
+
);
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export default NoResults;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2024 Adobe
|
|
3
|
+
All Rights Reserved.
|
|
4
|
+
|
|
5
|
+
NOTICE: Adobe permits you to use, modify, and distribute this file in
|
|
6
|
+
accordance with the terms of the Adobe license agreement accompanying
|
|
7
|
+
it.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
export * from './NoResults';
|
|
11
|
+
export { default } from './NoResults';
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2024 Adobe
|
|
3
|
+
All Rights Reserved.
|
|
4
|
+
|
|
5
|
+
NOTICE: Adobe permits you to use, modify, and distribute this file in
|
|
6
|
+
accordance with the terms of the Adobe license agreement accompanying
|
|
7
|
+
it.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import React, { useEffect } from 'react';
|
|
11
|
+
|
|
12
|
+
import { useProducts } from '../../context';
|
|
13
|
+
import { ELLIPSIS, usePagination } from '../../hooks/usePagination';
|
|
14
|
+
import Chevron from '../../icons/chevron.svg';
|
|
15
|
+
|
|
16
|
+
export const Pagination = ({ onPageChange, totalPages, currentPage }) => {
|
|
17
|
+
const productsCtx = useProducts();
|
|
18
|
+
const paginationRange = usePagination({
|
|
19
|
+
currentPage,
|
|
20
|
+
totalPages,
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
const { currentPage: ctxCurrentPage, totalPages: ctxTotalPages } = productsCtx;
|
|
25
|
+
if (ctxCurrentPage > ctxTotalPages) {
|
|
26
|
+
onPageChange(ctxTotalPages);
|
|
27
|
+
}
|
|
28
|
+
}, []); // Only run on mount
|
|
29
|
+
|
|
30
|
+
const onPrevious = () => {
|
|
31
|
+
if (currentPage > 1) {
|
|
32
|
+
onPageChange(currentPage - 1);
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const onNext = () => {
|
|
37
|
+
if (currentPage < totalPages) {
|
|
38
|
+
onPageChange(currentPage + 1);
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
return (
|
|
43
|
+
<ul className="ds-plp-pagination flex justify-center items-center mt-2 mb-6 list-none">
|
|
44
|
+
<img src={Chevron} className={`h-sm w-sm transform rotate-90 ${
|
|
45
|
+
currentPage === 1
|
|
46
|
+
? 'stroke-gray-400 cursor-not-allowed'
|
|
47
|
+
: 'stroke-gray-600 cursor-pointer'
|
|
48
|
+
}`}
|
|
49
|
+
onClick={onPrevious}
|
|
50
|
+
/>
|
|
51
|
+
{/* <Chevron
|
|
52
|
+
className={`h-sm w-sm transform rotate-90 ${
|
|
53
|
+
currentPage === 1
|
|
54
|
+
? 'stroke-gray-400 cursor-not-allowed'
|
|
55
|
+
: 'stroke-gray-600 cursor-pointer'
|
|
56
|
+
}`}
|
|
57
|
+
onClick={onPrevious}
|
|
58
|
+
/> */}
|
|
59
|
+
|
|
60
|
+
{paginationRange?.map((page) => {
|
|
61
|
+
if (page === ELLIPSIS) {
|
|
62
|
+
return (
|
|
63
|
+
<li
|
|
64
|
+
key={`ellipsis-${Math.random()}`}
|
|
65
|
+
className="ds-plp-pagination__dots text-gray-500 mx-sm my-auto"
|
|
66
|
+
>
|
|
67
|
+
...
|
|
68
|
+
</li>
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return (
|
|
73
|
+
<li
|
|
74
|
+
key={page}
|
|
75
|
+
className={`ds-plp-pagination__item flex items-center cursor-pointer text-center text-gray-500 my-auto mx-sm ${
|
|
76
|
+
currentPage === page
|
|
77
|
+
? 'ds-plp-pagination__item--current text-black font-medium underline underline-offset-4 decoration-black'
|
|
78
|
+
: ''
|
|
79
|
+
}`}
|
|
80
|
+
onClick={() => onPageChange(page)}
|
|
81
|
+
>
|
|
82
|
+
{page}
|
|
83
|
+
</li>
|
|
84
|
+
);
|
|
85
|
+
})}
|
|
86
|
+
<img src={Chevron} className={`h-sm w-sm transform -rotate-90 ${
|
|
87
|
+
currentPage === totalPages
|
|
88
|
+
? 'stroke-gray-400 cursor-not-allowed'
|
|
89
|
+
: 'stroke-gray-600 cursor-pointer'
|
|
90
|
+
}`}
|
|
91
|
+
onClick={onNext}
|
|
92
|
+
/>
|
|
93
|
+
{/* <Chevron
|
|
94
|
+
className={`h-sm w-sm transform -rotate-90 ${
|
|
95
|
+
currentPage === totalPages
|
|
96
|
+
? 'stroke-gray-400 cursor-not-allowed'
|
|
97
|
+
: 'stroke-gray-600 cursor-pointer'
|
|
98
|
+
}`}
|
|
99
|
+
onClick={onNext}
|
|
100
|
+
/> */}
|
|
101
|
+
</ul>
|
|
102
|
+
);
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
export default Pagination;
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2024 Adobe
|
|
3
|
+
All Rights Reserved.
|
|
4
|
+
|
|
5
|
+
NOTICE: Adobe permits you to use, modify, and distribute this file in
|
|
6
|
+
accordance with the terms of the Adobe license agreement accompanying
|
|
7
|
+
it.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import React, { useEffect, useRef } from 'react';
|
|
11
|
+
import { useAccessibleDropdown } from '../../hooks/useAccessibleDropdown';
|
|
12
|
+
import Chevron from '../../icons/chevron.svg';
|
|
13
|
+
|
|
14
|
+
export const PerPagePicker = ({ value, pageSizeOptions, onChange }) => {
|
|
15
|
+
const pageSizeButton = useRef(null);
|
|
16
|
+
const pageSizeMenu = useRef(null);
|
|
17
|
+
|
|
18
|
+
const selectedOption = pageSizeOptions.find((e) => e.value === value);
|
|
19
|
+
|
|
20
|
+
const {
|
|
21
|
+
isDropdownOpen,
|
|
22
|
+
setIsDropdownOpen,
|
|
23
|
+
activeIndex,
|
|
24
|
+
setActiveIndex,
|
|
25
|
+
select,
|
|
26
|
+
setIsFocus,
|
|
27
|
+
listRef,
|
|
28
|
+
} = useAccessibleDropdown({
|
|
29
|
+
options: pageSizeOptions,
|
|
30
|
+
value,
|
|
31
|
+
onChange,
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
useEffect(() => {
|
|
35
|
+
const menuRef = pageSizeMenu.current;
|
|
36
|
+
const handleBlur = () => {
|
|
37
|
+
setIsFocus(false);
|
|
38
|
+
setIsDropdownOpen(false);
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const handleFocus = () => {
|
|
42
|
+
if (menuRef?.parentElement?.querySelector(':hover') !== menuRef) {
|
|
43
|
+
setIsFocus(false);
|
|
44
|
+
setIsDropdownOpen(false);
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
menuRef?.addEventListener('blur', handleBlur);
|
|
49
|
+
menuRef?.addEventListener('focusin', handleFocus);
|
|
50
|
+
menuRef?.addEventListener('focusout', handleFocus);
|
|
51
|
+
|
|
52
|
+
return () => {
|
|
53
|
+
menuRef?.removeEventListener('blur', handleBlur);
|
|
54
|
+
menuRef?.removeEventListener('focusin', handleFocus);
|
|
55
|
+
menuRef?.removeEventListener('focusout', handleFocus);
|
|
56
|
+
};
|
|
57
|
+
}, []);
|
|
58
|
+
|
|
59
|
+
return (
|
|
60
|
+
<div
|
|
61
|
+
ref={pageSizeMenu}
|
|
62
|
+
className="ds-sdk-per-page-picker ml-2 mr-2 relative inline-block text-left bg-gray-100 rounded-md outline outline-1 outline-gray-200 hover:outline-gray-600 h-[32px]"
|
|
63
|
+
>
|
|
64
|
+
<button
|
|
65
|
+
className="group flex justify-center items-center font-normal text-sm text-gray-700 rounded-md hover:cursor-pointer border-none bg-transparent hover:border-none hover:bg-transparent focus:border-none focus:bg-transparent active:border-none active:bg-transparent active:shadow-none h-full w-full px-sm"
|
|
66
|
+
ref={pageSizeButton}
|
|
67
|
+
onClick={() => setIsDropdownOpen(!isDropdownOpen)}
|
|
68
|
+
onFocus={() => setIsFocus(false)}
|
|
69
|
+
onBlur={() => setIsFocus(false)}
|
|
70
|
+
>
|
|
71
|
+
{selectedOption ? `${selectedOption.label}` : '24'}
|
|
72
|
+
<img src={Chevron} className={`flex-shrink-0 m-auto ml-sm h-md w-md stroke-1 stroke-gray-600 ${
|
|
73
|
+
isDropdownOpen ? '' : 'rotate-180'
|
|
74
|
+
}`} />
|
|
75
|
+
{/* <Chevron
|
|
76
|
+
className={`flex-shrink-0 m-auto ml-sm h-md w-md stroke-1 stroke-gray-600 ${
|
|
77
|
+
isDropdownOpen ? '' : 'rotate-180'
|
|
78
|
+
}`}
|
|
79
|
+
/> */}
|
|
80
|
+
</button>
|
|
81
|
+
|
|
82
|
+
{isDropdownOpen && (
|
|
83
|
+
<ul
|
|
84
|
+
ref={listRef}
|
|
85
|
+
className="ds-sdk-per-page-picker__items origin-top-right absolute hover:cursor-pointer right-0 w-full rounded-md shadow-2xl bg-white ring-1 ring-black ring-opacity-5 focus:outline-none mt-2 z-20"
|
|
86
|
+
>
|
|
87
|
+
{pageSizeOptions.map((option, i) => (
|
|
88
|
+
<li
|
|
89
|
+
key={i}
|
|
90
|
+
aria-selected={option.value === selectedOption?.value}
|
|
91
|
+
onMouseOver={() => setActiveIndex(i)}
|
|
92
|
+
className={`py-xs hover:bg-gray-100 hover:text-gray-900 ${
|
|
93
|
+
i === activeIndex ? 'bg-gray-100 text-gray-900' : ''
|
|
94
|
+
}`}
|
|
95
|
+
>
|
|
96
|
+
<a
|
|
97
|
+
className={`ds-sdk-per-page-picker__items--item block-display px-md py-sm text-sm mb-0
|
|
98
|
+
no-underline active:no-underline focus:no-underline hover:no-underline
|
|
99
|
+
hover:text-gray-900 ${
|
|
100
|
+
option.value === selectedOption?.value
|
|
101
|
+
? 'ds-sdk-per-page-picker__items--item-selected font-semibold text-gray-900'
|
|
102
|
+
: 'font-normal text-gray-800'
|
|
103
|
+
}`}
|
|
104
|
+
onClick={() => select(option.value)}
|
|
105
|
+
>
|
|
106
|
+
{option.label}
|
|
107
|
+
</a>
|
|
108
|
+
</li>
|
|
109
|
+
))}
|
|
110
|
+
</ul>
|
|
111
|
+
)}
|
|
112
|
+
</div>
|
|
113
|
+
);
|
|
114
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2024 Adobe
|
|
3
|
+
All Rights Reserved.
|
|
4
|
+
|
|
5
|
+
NOTICE: Adobe permits you to use, modify, and distribute this file in
|
|
6
|
+
accordance with the terms of the Adobe license agreement accompanying
|
|
7
|
+
it.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
export { PerPagePicker } from './PerPagePicker';
|
|
11
|
+
export { PerPagePicker as default } from './PerPagePicker';
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2024 Adobe
|
|
3
|
+
All Rights Reserved.
|
|
4
|
+
|
|
5
|
+
NOTICE: Adobe permits you to use, modify, and distribute this file in
|
|
6
|
+
accordance with the terms of the Adobe license agreement accompanying
|
|
7
|
+
it.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import React from 'react';
|
|
11
|
+
import CloseIcon from '../../icons/plus.svg';
|
|
12
|
+
|
|
13
|
+
const defaultIcon = (
|
|
14
|
+
<img src={CloseIcon} className="h-[12px] w-[12px] rotate-45 inline-block ml-sm cursor-pointer fill-gray-700" />
|
|
15
|
+
// <CloseIcon className="h-[12px] w-[12px] rotate-45 inline-block ml-sm cursor-pointer fill-gray-700" />
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
export const Pill = ({ label, onClick, CTA = defaultIcon, type }) => {
|
|
19
|
+
const containerClasses =
|
|
20
|
+
type === 'transparent'
|
|
21
|
+
? 'ds-sdk-pill inline-flex justify-content items-center rounded-full w-fit min-h-[32px] px-4 py-1'
|
|
22
|
+
: 'ds-sdk-pill inline-flex justify-content items-center bg-gray-100 rounded-full w-fit outline outline-gray-200 min-h-[32px] px-4 py-1';
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<div key={label} className={containerClasses}>
|
|
26
|
+
<span className="ds-sdk-pill__label font-normal text-sm">{label}</span>
|
|
27
|
+
<span className="ds-sdk-pill__cta" onClick={onClick}>
|
|
28
|
+
{CTA}
|
|
29
|
+
</span>
|
|
30
|
+
</div>
|
|
31
|
+
);
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export default Pill;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2024 Adobe
|
|
3
|
+
All Rights Reserved.
|
|
4
|
+
|
|
5
|
+
NOTICE: Adobe permits you to use, modify, and distribute this file in
|
|
6
|
+
accordance with the terms of the Adobe license agreement accompanying
|
|
7
|
+
it.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
export * from './Pill';
|
|
11
|
+
export { default } from './Pill';
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2024 Adobe
|
|
3
|
+
All Rights Reserved.
|
|
4
|
+
|
|
5
|
+
NOTICE: Adobe permits you to use, modify, and distribute this file in
|
|
6
|
+
accordance with the terms of the Adobe license agreement accompanying
|
|
7
|
+
it.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
export const CTA = (
|
|
11
|
+
<svg
|
|
12
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
13
|
+
className="h-5 w-5 inline-block ml-2 cursor-pointer mb-0.5"
|
|
14
|
+
viewBox="0 0 20 20"
|
|
15
|
+
fill="currentColor"
|
|
16
|
+
>
|
|
17
|
+
<path
|
|
18
|
+
fillRule="evenodd"
|
|
19
|
+
d="M10 5a1 1 0 011 1v3h3a1 1 0 110 2h-3v3a1 1 0 11-2 0v-3H6a1 1 0 110-2h3V6a1 1 0 011-1z"
|
|
20
|
+
clipRule="evenodd"
|
|
21
|
+
/>
|
|
22
|
+
</svg>
|
|
23
|
+
);
|