@magento/venia-pwa-live-search 1.0.0-alpha6
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,13 @@
|
|
|
1
|
+
// Copyright 2024 Adobe
|
|
2
|
+
// All Rights Reserved.
|
|
3
|
+
//
|
|
4
|
+
// NOTICE: Adobe permits you to use, modify, and distribute this file in
|
|
5
|
+
// accordance with the terms of the Adobe license agreement accompanying
|
|
6
|
+
// it.
|
|
7
|
+
|
|
8
|
+
const htmlStringDecode = input => {
|
|
9
|
+
const doc = new DOMParser().parseFromString(input, 'text/html');
|
|
10
|
+
return doc.documentElement.textContent;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export { htmlStringDecode };
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
// Copyright 2024 Adobe
|
|
2
|
+
// All Rights Reserved.
|
|
3
|
+
//
|
|
4
|
+
// NOTICE: Adobe permits you to use, modify, and distribute this file in
|
|
5
|
+
// accordance with the terms of the Adobe license agreement accompanying
|
|
6
|
+
// it.
|
|
7
|
+
|
|
8
|
+
// Clean a URL based on provided baseUrl(s)
|
|
9
|
+
export const cleanUrl = (
|
|
10
|
+
url,
|
|
11
|
+
cleanWithProtocol = false,
|
|
12
|
+
baseUrl = '',
|
|
13
|
+
baseUrlWithoutProtocol = ''
|
|
14
|
+
) => {
|
|
15
|
+
if (!url) return url;
|
|
16
|
+
|
|
17
|
+
try {
|
|
18
|
+
if (cleanWithProtocol) {
|
|
19
|
+
return baseUrl ? url.replace(baseUrl, '') : url;
|
|
20
|
+
}
|
|
21
|
+
return baseUrlWithoutProtocol
|
|
22
|
+
? url.replace(baseUrlWithoutProtocol, '')
|
|
23
|
+
: url;
|
|
24
|
+
} catch {
|
|
25
|
+
return url;
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export const cleanSwatchUrl = (
|
|
30
|
+
url,
|
|
31
|
+
cleanWithProtocol = true,
|
|
32
|
+
baseUrl = '',
|
|
33
|
+
baseUrlWithoutProtocol = ''
|
|
34
|
+
) => {
|
|
35
|
+
if (!url) return url;
|
|
36
|
+
|
|
37
|
+
try {
|
|
38
|
+
if (cleanWithProtocol) {
|
|
39
|
+
if (baseUrl.endsWith('/')) {
|
|
40
|
+
const sanitizeBaseUrl = baseUrl.replace(/\/$/, '');
|
|
41
|
+
return sanitizeBaseUrl ? url.replace(sanitizeBaseUrl, '') : url;
|
|
42
|
+
}
|
|
43
|
+
return baseUrl ? url.replace(baseUrl, '') : url;
|
|
44
|
+
}
|
|
45
|
+
return baseUrlWithoutProtocol
|
|
46
|
+
? url.replace(baseUrlWithoutProtocol, '')
|
|
47
|
+
: url;
|
|
48
|
+
} catch {
|
|
49
|
+
return url;
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
export const sanitizeImage = (
|
|
54
|
+
img,
|
|
55
|
+
cleanWithProtocol = false,
|
|
56
|
+
baseUrl,
|
|
57
|
+
baseUrlWithoutProtocol
|
|
58
|
+
) => {
|
|
59
|
+
if (Array.isArray(img)) {
|
|
60
|
+
return img.map(i =>
|
|
61
|
+
i && i.url
|
|
62
|
+
? {
|
|
63
|
+
...i,
|
|
64
|
+
url: cleanUrl(
|
|
65
|
+
i.url,
|
|
66
|
+
cleanWithProtocol,
|
|
67
|
+
baseUrl,
|
|
68
|
+
baseUrlWithoutProtocol
|
|
69
|
+
)
|
|
70
|
+
}
|
|
71
|
+
: i
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
return img && img.url
|
|
75
|
+
? {
|
|
76
|
+
...img,
|
|
77
|
+
url: cleanUrl(
|
|
78
|
+
img.url,
|
|
79
|
+
cleanWithProtocol,
|
|
80
|
+
baseUrl,
|
|
81
|
+
baseUrlWithoutProtocol
|
|
82
|
+
)
|
|
83
|
+
}
|
|
84
|
+
: img;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
export const sanitizeRefinedImages = (
|
|
88
|
+
refinedImages,
|
|
89
|
+
baseUrl,
|
|
90
|
+
baseUrlWithoutProtocol,
|
|
91
|
+
areSwatchImages = false
|
|
92
|
+
) => {
|
|
93
|
+
if (!refinedImages || !Array.isArray(refinedImages)) return refinedImages;
|
|
94
|
+
|
|
95
|
+
return refinedImages.map(img => {
|
|
96
|
+
if (!img || !img.url) return img;
|
|
97
|
+
|
|
98
|
+
const cleanImageUrl = areSwatchImages
|
|
99
|
+
? cleanSwatchUrl(img.url, true, baseUrl, baseUrlWithoutProtocol)
|
|
100
|
+
: cleanUrl(img.url, false, baseUrl, baseUrlWithoutProtocol);
|
|
101
|
+
|
|
102
|
+
return {
|
|
103
|
+
...img,
|
|
104
|
+
url: cleanImageUrl
|
|
105
|
+
};
|
|
106
|
+
});
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
export const sanitizeProducts = (products, baseUrl, baseUrlWithoutProtocol) => {
|
|
110
|
+
if (!products || products.length === 0) return [];
|
|
111
|
+
|
|
112
|
+
return products.map(item => {
|
|
113
|
+
const prod = item.product;
|
|
114
|
+
const prodView = item.productView;
|
|
115
|
+
|
|
116
|
+
if (!prod) return item;
|
|
117
|
+
|
|
118
|
+
return {
|
|
119
|
+
...item,
|
|
120
|
+
product: {
|
|
121
|
+
...prod,
|
|
122
|
+
canonical_url: cleanUrl(
|
|
123
|
+
prod.canonical_url,
|
|
124
|
+
false,
|
|
125
|
+
baseUrl,
|
|
126
|
+
baseUrlWithoutProtocol
|
|
127
|
+
),
|
|
128
|
+
image: sanitizeImage(
|
|
129
|
+
prod.image,
|
|
130
|
+
false,
|
|
131
|
+
baseUrl,
|
|
132
|
+
baseUrlWithoutProtocol
|
|
133
|
+
),
|
|
134
|
+
small_image: sanitizeImage(
|
|
135
|
+
prod.small_image,
|
|
136
|
+
false,
|
|
137
|
+
baseUrl,
|
|
138
|
+
baseUrlWithoutProtocol
|
|
139
|
+
),
|
|
140
|
+
thumbnail: sanitizeImage(
|
|
141
|
+
prod.thumbnail,
|
|
142
|
+
false,
|
|
143
|
+
baseUrl,
|
|
144
|
+
baseUrlWithoutProtocol
|
|
145
|
+
)
|
|
146
|
+
},
|
|
147
|
+
productView: {
|
|
148
|
+
...prodView,
|
|
149
|
+
images: sanitizeImage(
|
|
150
|
+
prodView?.images,
|
|
151
|
+
true,
|
|
152
|
+
baseUrl,
|
|
153
|
+
baseUrlWithoutProtocol
|
|
154
|
+
),
|
|
155
|
+
url: cleanUrl(
|
|
156
|
+
prodView?.url,
|
|
157
|
+
true,
|
|
158
|
+
baseUrl,
|
|
159
|
+
baseUrlWithoutProtocol
|
|
160
|
+
)
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
});
|
|
164
|
+
};
|
|
@@ -0,0 +1,95 @@
|
|
|
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
|
+
//hooks error - need to check
|
|
11
|
+
//import { useTranslation } from '../context/translation';
|
|
12
|
+
|
|
13
|
+
const defaultSortOptions = () => {
|
|
14
|
+
return [
|
|
15
|
+
{ label: 'Most Relevant', value: 'relevance_DESC' },
|
|
16
|
+
{ label: 'Price: Low to High', value: 'price_ASC' },
|
|
17
|
+
{ label: 'Price: High to Low', value: 'price_DESC' }
|
|
18
|
+
];
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const getSortOptionsfromMetadata = (
|
|
22
|
+
sortMetadata,
|
|
23
|
+
displayOutOfStock,
|
|
24
|
+
categoryPath,
|
|
25
|
+
translation
|
|
26
|
+
) => {
|
|
27
|
+
const sortOptions = categoryPath
|
|
28
|
+
? [
|
|
29
|
+
{
|
|
30
|
+
label: translation?.SortDropdown?.positionLabel || 'Position', // Now uses translation
|
|
31
|
+
value: 'position_ASC'
|
|
32
|
+
}
|
|
33
|
+
]
|
|
34
|
+
: [
|
|
35
|
+
{
|
|
36
|
+
label:
|
|
37
|
+
translation?.SortDropdown?.relevanceLabel ||
|
|
38
|
+
'Most Relevant', // Now uses translation
|
|
39
|
+
value: 'relevance_DESC'
|
|
40
|
+
}
|
|
41
|
+
];
|
|
42
|
+
|
|
43
|
+
const displayInStockOnly = displayOutOfStock != '1'; // '!=' is intentional for conversion
|
|
44
|
+
|
|
45
|
+
if (sortMetadata && sortMetadata.length > 0) {
|
|
46
|
+
sortMetadata.forEach(e => {
|
|
47
|
+
if (
|
|
48
|
+
!e.attribute.includes('relevance') &&
|
|
49
|
+
!(e.attribute.includes('inStock') && displayInStockOnly) &&
|
|
50
|
+
!e.attribute.includes('position')
|
|
51
|
+
/* conditions for which we don't display the sorting option:
|
|
52
|
+
1) if the option attribute is relevance
|
|
53
|
+
2) if the option attribute is "inStock" and display out of stock products is set to no
|
|
54
|
+
3) if the option attribute is "position" and there is not a categoryPath (we're not in category browse mode) -> the conditional part is handled in setting sortOptions
|
|
55
|
+
*/
|
|
56
|
+
) {
|
|
57
|
+
if (e.numeric && e.attribute.includes('price')) {
|
|
58
|
+
sortOptions.push({
|
|
59
|
+
label: `${e.label}: Low to High`,
|
|
60
|
+
value: `${e.attribute}_ASC`
|
|
61
|
+
});
|
|
62
|
+
sortOptions.push({
|
|
63
|
+
label: `${e.label}: High to Low`,
|
|
64
|
+
value: `${e.attribute}_DESC`
|
|
65
|
+
});
|
|
66
|
+
} else {
|
|
67
|
+
sortOptions.push({
|
|
68
|
+
label: `${e.label}`,
|
|
69
|
+
value: `${e.attribute}_DESC`
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
return sortOptions;
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
const generateGQLSortInput = sortOption => {
|
|
79
|
+
// results sorted by relevance or position by default
|
|
80
|
+
if (!sortOption) {
|
|
81
|
+
return undefined;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// sort options are in format attribute_direction
|
|
85
|
+
const index = sortOption.lastIndexOf('_');
|
|
86
|
+
return [
|
|
87
|
+
{
|
|
88
|
+
attribute: sortOption.substring(0, index),
|
|
89
|
+
direction:
|
|
90
|
+
sortOption.substring(index + 1) === 'ASC' ? 'ASC' : 'DESC'
|
|
91
|
+
}
|
|
92
|
+
];
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
export { defaultSortOptions, generateGQLSortInput, getSortOptionsfromMetadata };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { useEffect, useState } from 'react';
|
|
2
|
+
|
|
3
|
+
export const useIntersectionObserver = (ref, options) => {
|
|
4
|
+
const { rootMargin } = options;
|
|
5
|
+
const [observerEntry, setObserverEntry] = useState(null);
|
|
6
|
+
|
|
7
|
+
useEffect(() => {
|
|
8
|
+
if (!ref?.current) return;
|
|
9
|
+
const observer = new IntersectionObserver(
|
|
10
|
+
([entry]) => {
|
|
11
|
+
setObserverEntry(entry);
|
|
12
|
+
if (entry.isIntersecting) {
|
|
13
|
+
observer.unobserve(entry.target);
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
{ rootMargin }
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
observer.observe(ref.current);
|
|
20
|
+
|
|
21
|
+
return () => {
|
|
22
|
+
observer.disconnect();
|
|
23
|
+
};
|
|
24
|
+
}, [ref, rootMargin]);
|
|
25
|
+
|
|
26
|
+
return observerEntry;
|
|
27
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
const validStoreDetailsKeys = [
|
|
2
|
+
'environmentId',
|
|
3
|
+
'environmentType',
|
|
4
|
+
'websiteCode',
|
|
5
|
+
'storeCode',
|
|
6
|
+
'storeViewCode',
|
|
7
|
+
'config',
|
|
8
|
+
'context',
|
|
9
|
+
'apiUrl',
|
|
10
|
+
'apiKey',
|
|
11
|
+
'route',
|
|
12
|
+
'searchQuery',
|
|
13
|
+
'baseUrl',
|
|
14
|
+
'baseUrlwithoutProtocol'
|
|
15
|
+
];
|
|
16
|
+
|
|
17
|
+
export const sanitizeString = value => {
|
|
18
|
+
// just in case, https://stackoverflow.com/a/23453651
|
|
19
|
+
if (typeof value === 'string') {
|
|
20
|
+
// eslint-disable-next-line no-useless-escape
|
|
21
|
+
value = value.replace(/[^a-z0-9áéíóúñü \.,_-]/gim, '');
|
|
22
|
+
return value.trim();
|
|
23
|
+
}
|
|
24
|
+
return value;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export const validateStoreDetailsKeys = storeDetails => {
|
|
28
|
+
Object.keys(storeDetails).forEach(key => {
|
|
29
|
+
if (!validStoreDetailsKeys.includes(key)) {
|
|
30
|
+
// eslint-disable-next-line no-console
|
|
31
|
+
console.error(`Invalid key ${key} in StoreDetailsProps`);
|
|
32
|
+
// filter out invalid keys/value
|
|
33
|
+
delete storeDetails[key];
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
storeDetails[key] = sanitizeString(storeDetails[key]);
|
|
37
|
+
});
|
|
38
|
+
return storeDetails;
|
|
39
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
//import useCustomUrl from '../hooks/useCustomUrl';
|
|
2
|
+
//import useReferrerUrl from '../hooks/useReferrerUrl';
|
|
3
|
+
import usePageView from '../hooks/eventing/usePageView';
|
|
4
|
+
import useShopperContext from '../hooks/eventing/useShopperContext';
|
|
5
|
+
import useStorefrontInstanceContext from '../hooks/eventing/useStorefrontInstanceContext';
|
|
6
|
+
import useMagentoExtensionContext from '../hooks/eventing/useMagentoExtensionContext';
|
|
7
|
+
//import useCart from '../hooks/useCart';
|
|
8
|
+
import mse from '@adobe/magento-storefront-events-sdk';
|
|
9
|
+
import msc from '@adobe/magento-storefront-event-collector';
|
|
10
|
+
|
|
11
|
+
export default function wrapUseApp(origUseApp) {
|
|
12
|
+
if (!window.magentoStorefrontEvents) {
|
|
13
|
+
window.magentoStorefrontEvents = mse;
|
|
14
|
+
}
|
|
15
|
+
msc;
|
|
16
|
+
|
|
17
|
+
return function(props) {
|
|
18
|
+
useShopperContext();
|
|
19
|
+
useStorefrontInstanceContext();
|
|
20
|
+
useMagentoExtensionContext();
|
|
21
|
+
//useCart();
|
|
22
|
+
//useCustomUrl();
|
|
23
|
+
//useReferrerUrl();
|
|
24
|
+
usePageView();
|
|
25
|
+
|
|
26
|
+
return origUseApp(props);
|
|
27
|
+
};
|
|
28
|
+
}
|