@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,119 @@
|
|
|
1
|
+
.root {
|
|
2
|
+
composes: items-center from global;
|
|
3
|
+
composes: justify-items-center from global;
|
|
4
|
+
composes: justify-self-center from global;
|
|
5
|
+
composes: max-w-site from global;
|
|
6
|
+
composes: px-xs from global;
|
|
7
|
+
composes: py-0 from global;
|
|
8
|
+
composes: w-full from global;
|
|
9
|
+
|
|
10
|
+
@apply hidden;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.root_open {
|
|
14
|
+
composes: root;
|
|
15
|
+
|
|
16
|
+
composes: z-dropdown from global;
|
|
17
|
+
@apply grid;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.form {
|
|
21
|
+
composes: grid from global;
|
|
22
|
+
composes: items-center from global;
|
|
23
|
+
composes: justify-items-stretch from global;
|
|
24
|
+
composes: w-full from global;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.container {
|
|
28
|
+
composes: inline-flex from global;
|
|
29
|
+
composes: items-center from global;
|
|
30
|
+
composes: justify-center from global;
|
|
31
|
+
composes: max-w-[24rem] from global;
|
|
32
|
+
composes: pb-xs from global;
|
|
33
|
+
composes: relative from global;
|
|
34
|
+
composes: w-full from global;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.search {
|
|
38
|
+
composes: grid from global;
|
|
39
|
+
composes: relative from global;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.autocomplete {
|
|
43
|
+
composes: grid from global;
|
|
44
|
+
/* composes: relative from global; */
|
|
45
|
+
composes: z-menu from global;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.popover {
|
|
49
|
+
composes: absolute from global;
|
|
50
|
+
composes: bg-white from global;
|
|
51
|
+
composes: gap-3 from global;
|
|
52
|
+
composes: grid from global;
|
|
53
|
+
composes: left-0 from global;
|
|
54
|
+
composes: p-xs from global;
|
|
55
|
+
composes: rounded-b-md from global;
|
|
56
|
+
composes: rounded-t-none from global;
|
|
57
|
+
composes: shadow-inputFocus from global;
|
|
58
|
+
composes: text-sm from global;
|
|
59
|
+
composes: z-menu from global;
|
|
60
|
+
transition-property: opacity, transform, visibility;
|
|
61
|
+
top: 2.5rem;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.root_hidden {
|
|
65
|
+
composes: root;
|
|
66
|
+
|
|
67
|
+
composes: invisible from global;
|
|
68
|
+
composes: opacity-0 from global;
|
|
69
|
+
transform: translate3d(0, -2rem, 0);
|
|
70
|
+
transition-duration: 192ms;
|
|
71
|
+
transition-timing-function: var(--venia-global-anim-out);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.root_visible {
|
|
75
|
+
composes: root;
|
|
76
|
+
|
|
77
|
+
composes: opacity-100 from global;
|
|
78
|
+
composes: visible from global;
|
|
79
|
+
transform: translate3d(0, 0, 0);
|
|
80
|
+
transition-duration: 224ms;
|
|
81
|
+
transition-timing-function: var(--venia-global-anim-in);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.message {
|
|
85
|
+
composes: px-3 from global;
|
|
86
|
+
composes: py-0 from global;
|
|
87
|
+
composes: text-center from global;
|
|
88
|
+
composes: text-subtle from global;
|
|
89
|
+
|
|
90
|
+
composes: empty_hidden from global;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
.suggestions {
|
|
94
|
+
composes: gap-2xs from global;
|
|
95
|
+
composes: grid from global;
|
|
96
|
+
|
|
97
|
+
composes: empty_hidden from global;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.product-price {
|
|
101
|
+
display: grid;
|
|
102
|
+
grid-area: product-price;
|
|
103
|
+
height: 100%;
|
|
104
|
+
justify-content: left !important;
|
|
105
|
+
width: 100%;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.livesearch_root .ds-sdk-add-to-cart-button button svg {
|
|
109
|
+
display: none !important;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
.search input {
|
|
113
|
+
padding-left: calc(1.875rem * var(--iconsBefore, 0) + 0.625rem);
|
|
114
|
+
padding-right: calc(1.875rem * var(--iconsAfter, 0) + 0.625rem);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/* .popover {
|
|
118
|
+
|
|
119
|
+
} */
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/* Tokens */
|
|
2
|
+
.ds-widgets {
|
|
3
|
+
@import 'tailwindcss/base';
|
|
4
|
+
@import 'tailwindcss/components';
|
|
5
|
+
@import 'tailwindcss/utilities';
|
|
6
|
+
|
|
7
|
+
font-size: 1.6rem;
|
|
8
|
+
|
|
9
|
+
/* Colors */
|
|
10
|
+
--color-body: #fff;
|
|
11
|
+
--color-on-body: #222;
|
|
12
|
+
|
|
13
|
+
--color-surface: #e6e6e6;
|
|
14
|
+
--color-on-surface: #222;
|
|
15
|
+
|
|
16
|
+
--color-primary: #222;
|
|
17
|
+
--color-on-primary: #fff;
|
|
18
|
+
|
|
19
|
+
--color-secondary: #ff0000;
|
|
20
|
+
--color-on-secondary: #fff;
|
|
21
|
+
|
|
22
|
+
--color-gray-1: #f3f4f6;
|
|
23
|
+
--color-gray-2: #e5e7eb;
|
|
24
|
+
--color-gray-3: #d1d5db;
|
|
25
|
+
--color-gray-4: #9ca3af;
|
|
26
|
+
--color-gray-5: #6b7280;
|
|
27
|
+
--color-gray-6: #4b5563;
|
|
28
|
+
--color-gray-7: #374151;
|
|
29
|
+
--color-gray-8: #1f2937;
|
|
30
|
+
--color-gray-9: #111827;
|
|
31
|
+
|
|
32
|
+
/* Spacing: gaps, margin, padding, etc. */
|
|
33
|
+
--spacing-xxs: 0.15625em;
|
|
34
|
+
--spacing-xs: 0.3125em;
|
|
35
|
+
--spacing-sm: 0.625em;
|
|
36
|
+
--spacing-md: 1.25em;
|
|
37
|
+
--spacing-lg: 2.5em;
|
|
38
|
+
--spacing-xl: 3.75em;
|
|
39
|
+
--spacing-2xl: 4.25em;
|
|
40
|
+
--spacing-3xl: 4.75em;
|
|
41
|
+
|
|
42
|
+
/* Font Families */
|
|
43
|
+
--font-body: sans-serif;
|
|
44
|
+
|
|
45
|
+
/* Font Sizes */
|
|
46
|
+
--font-xs: 0.75em;
|
|
47
|
+
--font-sm: 0.875em;
|
|
48
|
+
--font-md: 1em;
|
|
49
|
+
--font-lg: 1.125em;
|
|
50
|
+
--font-xl: 1.25em;
|
|
51
|
+
--font-2xl: 1.5em;
|
|
52
|
+
--font-3xl: 1.875em;
|
|
53
|
+
--font-4xl: 2.25em;
|
|
54
|
+
--font-5xl: 3em;
|
|
55
|
+
|
|
56
|
+
/* Font Weights */
|
|
57
|
+
--font-thin: 100;
|
|
58
|
+
--font-extralight: 200;
|
|
59
|
+
--font-light: 300;
|
|
60
|
+
--font-normal: 400;
|
|
61
|
+
--font-medium: 500;
|
|
62
|
+
--font-semibold: 600;
|
|
63
|
+
--font-bold: 700;
|
|
64
|
+
--font-extrabold: 800;
|
|
65
|
+
--font-black: 900;
|
|
66
|
+
|
|
67
|
+
/* Line Heights */
|
|
68
|
+
--leading-none: 1;
|
|
69
|
+
--leading-tight: 1.25;
|
|
70
|
+
--leading-snug: 1.375;
|
|
71
|
+
--leading-normal: 1.5;
|
|
72
|
+
--leading-relaxed: 1.625;
|
|
73
|
+
--leading-loose: 2;
|
|
74
|
+
--leading-3: '.75em';
|
|
75
|
+
--leading-4: '1em';
|
|
76
|
+
--leading-5: '1.25em';
|
|
77
|
+
--leading-6: '1.5em';
|
|
78
|
+
--leading-7: '1.75em';
|
|
79
|
+
--leading-8: '2em';
|
|
80
|
+
--leading-9: '2.25em';
|
|
81
|
+
--leading-10: '2.5em';
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.ds-widgets input[type='checkbox'] {
|
|
85
|
+
font-size: 80%;
|
|
86
|
+
margin: 0;
|
|
87
|
+
top: 0;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
.block-display {
|
|
91
|
+
display: block;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.loading-spinner-on-mobile {
|
|
95
|
+
position: fixed;
|
|
96
|
+
top: 50%;
|
|
97
|
+
left: 50%;
|
|
98
|
+
transform: translate(-50%, -50%);
|
|
99
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module.exports = targets => {
|
|
2
|
+
const { specialFeatures } = targets.of('@magento/pwa-buildpack');
|
|
3
|
+
specialFeatures.tap(flags => {
|
|
4
|
+
/**
|
|
5
|
+
* Wee need to activate esModules, GQL Queries and deactivate cssModules to allow build pack to load our extension
|
|
6
|
+
* {@link https://magento.github.io/pwa-studio/pwa-buildpack/reference/configure-webpack/#special-flags}.
|
|
7
|
+
*/
|
|
8
|
+
flags[targets.name] = {
|
|
9
|
+
esModules: true,
|
|
10
|
+
cssModules: false,
|
|
11
|
+
graphqlQueries: true
|
|
12
|
+
};
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
targets.of('@magento/peregrine').talons.tap(talons => {
|
|
16
|
+
talons.App.useApp.wrapWith(
|
|
17
|
+
`@magento/venia-pwa-live-search/src/wrappers/wrapUseApp`
|
|
18
|
+
);
|
|
19
|
+
return talons;
|
|
20
|
+
});
|
|
21
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
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
|
+
export const DEFAULT_PAGE_SIZE = 24;
|
|
9
|
+
export const DEFAULT_PAGE_SIZE_OPTIONS = '12,24,36';
|
|
10
|
+
export const DEFAULT_MIN_QUERY_LENGTH = 3;
|
|
11
|
+
export const PRODUCT_COLUMNS = {
|
|
12
|
+
desktop: 4,
|
|
13
|
+
tablet: 3,
|
|
14
|
+
mobile: 2
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export const SEARCH_SORT_DEFAULT = [
|
|
18
|
+
{ attribute: 'relevance', direction: 'DESC' }
|
|
19
|
+
];
|
|
20
|
+
export const CATEGORY_SORT_DEFAULT = [
|
|
21
|
+
{ attribute: 'position', direction: 'ASC' }
|
|
22
|
+
];
|
|
23
|
+
|
|
24
|
+
export const SEARCH_UNIT_ID = 'livesearch-plp';
|
|
25
|
+
export const BOOLEAN_YES = 'yes';
|
|
26
|
+
export const BOOLEAN_NO = 'no';
|
|
@@ -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 decodeHtmlString = input => {
|
|
9
|
+
const doc = new DOMParser().parseFromString(input, 'text/html');
|
|
10
|
+
return doc.documentElement.textContent;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export { decodeHtmlString };
|
package/src/utils/dom.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
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
|
+
export const moveToTop = () => {
|
|
9
|
+
window.scrollTo({ top: 0 });
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export const classNames = (...classes) => {
|
|
13
|
+
return classes.filter(Boolean).join(' ');
|
|
14
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export const getDecodedCookie = key => {
|
|
2
|
+
const encodedCookie = document.cookie
|
|
3
|
+
.split('; ')
|
|
4
|
+
.find(row => row.startsWith(key))
|
|
5
|
+
.split('=')[1];
|
|
6
|
+
const decodedCookie = decodeURIComponent(encodedCookie);
|
|
7
|
+
const value = JSON.parse(decodedCookie);
|
|
8
|
+
return value;
|
|
9
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// src/hooks/eventing/usePageTypeFromUrl.js
|
|
2
|
+
import { useQuery } from '@apollo/client';
|
|
3
|
+
import query from '../../queries/eventing/getPageType.gql';
|
|
4
|
+
|
|
5
|
+
const pagetypeMap = {
|
|
6
|
+
CMS_PAGE: 'CMS',
|
|
7
|
+
CATEGORY: 'Category',
|
|
8
|
+
PRODUCT: 'Product',
|
|
9
|
+
'/cart': 'Cart',
|
|
10
|
+
'/checkout': 'Checkout'
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
const usePageTypeFromUrl = pathname => {
|
|
14
|
+
const { data } = useQuery(query.resolvePagetypeQuery, {
|
|
15
|
+
fetchPolicy: 'cache-and-network',
|
|
16
|
+
nextFetchPolicy: 'cache-first',
|
|
17
|
+
variables: { url: pathname }
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
const type = data?.urlResolver?.type;
|
|
21
|
+
const pageType = pagetypeMap[type] || pagetypeMap[pathname];
|
|
22
|
+
|
|
23
|
+
return pageType;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export default usePageTypeFromUrl;
|
|
@@ -0,0 +1,94 @@
|
|
|
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 getProductImageURLs = (images, amount = 3, topImageUrl) => {
|
|
9
|
+
const imageUrlArray = [];
|
|
10
|
+
//const url = new URL(window.location.href);
|
|
11
|
+
//original protocol
|
|
12
|
+
//const protocol = url.protocol;
|
|
13
|
+
|
|
14
|
+
//making protocol empty
|
|
15
|
+
//const protocol = '';
|
|
16
|
+
// const topImageUrl = "http://master-7rqtwti-wdxwuaerh4gbm.eu-4.magentosite.cloud/media/catalog/product/3/1/31t0a-sopll._ac_.jpg";
|
|
17
|
+
for (const image of images) {
|
|
18
|
+
const imageUrl = image.url?.replace(/^https?:\/\//, '');
|
|
19
|
+
if (imageUrl) {
|
|
20
|
+
//original
|
|
21
|
+
//imageUrlArray.push(`${protocol}//${imageUrl}`);
|
|
22
|
+
|
|
23
|
+
//to remove protocol
|
|
24
|
+
imageUrlArray.push(`${imageUrl}`);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (topImageUrl) {
|
|
29
|
+
//original
|
|
30
|
+
// const topImageUrlFormatted = `${protocol}//${topImageUrl.replace(
|
|
31
|
+
// /^https?:\/\//,
|
|
32
|
+
// ''
|
|
33
|
+
// )}`;
|
|
34
|
+
|
|
35
|
+
//to remove protocol
|
|
36
|
+
const topImageUrlFormatted = `${topImageUrl.replace(
|
|
37
|
+
/^https?:\/\//,
|
|
38
|
+
''
|
|
39
|
+
)}`;
|
|
40
|
+
|
|
41
|
+
const index = topImageUrlFormatted.indexOf(topImageUrlFormatted);
|
|
42
|
+
if (index > -1) {
|
|
43
|
+
imageUrlArray.splice(index, 1);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
imageUrlArray.unshift(topImageUrlFormatted);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return imageUrlArray.slice(0, amount);
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const resolveImageUrl = (url, opts) => {
|
|
53
|
+
const [base, query] = url.split('?');
|
|
54
|
+
const params = new URLSearchParams(query);
|
|
55
|
+
|
|
56
|
+
Object.entries(opts).forEach(([key, value]) => {
|
|
57
|
+
if (value !== undefined && value !== null) {
|
|
58
|
+
params.set(key, String(value));
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
return `${base}?${params.toString()}`;
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
const generateOptimizedImages = (imageUrls, baseImageWidth) => {
|
|
66
|
+
const baseOptions = {
|
|
67
|
+
fit: 'cover',
|
|
68
|
+
crop: false,
|
|
69
|
+
dpi: 1
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
const imageUrlArray = [];
|
|
73
|
+
|
|
74
|
+
for (const imageUrl of imageUrls) {
|
|
75
|
+
const src = resolveImageUrl(imageUrl, {
|
|
76
|
+
...baseOptions,
|
|
77
|
+
width: baseImageWidth
|
|
78
|
+
});
|
|
79
|
+
const dpiSet = [1, 2, 3];
|
|
80
|
+
const srcset = dpiSet.map(dpi => {
|
|
81
|
+
return `${resolveImageUrl(imageUrl, {
|
|
82
|
+
...baseOptions,
|
|
83
|
+
auto: 'webp',
|
|
84
|
+
quality: 80,
|
|
85
|
+
width: baseImageWidth * dpi
|
|
86
|
+
})} ${dpi}x`;
|
|
87
|
+
});
|
|
88
|
+
imageUrlArray.push({ src, srcset });
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return imageUrlArray;
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
export { generateOptimizedImages, getProductImageURLs };
|
|
@@ -0,0 +1,83 @@
|
|
|
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
|
+
import getSymbolFromCurrency from 'currency-symbol-map';
|
|
9
|
+
|
|
10
|
+
const getProductPrice = (
|
|
11
|
+
product,
|
|
12
|
+
currencySymbol,
|
|
13
|
+
currencyRate,
|
|
14
|
+
useMaximum = false,
|
|
15
|
+
useFinal = false
|
|
16
|
+
) => {
|
|
17
|
+
let priceType;
|
|
18
|
+
let price;
|
|
19
|
+
if ('product' in product) {
|
|
20
|
+
priceType = product?.product?.price_range?.minimum_price;
|
|
21
|
+
|
|
22
|
+
if (useMaximum) {
|
|
23
|
+
priceType = product?.product?.price_range?.maximum_price;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
price = priceType?.regular_price;
|
|
27
|
+
if (useFinal) {
|
|
28
|
+
price = priceType?.final_price;
|
|
29
|
+
}
|
|
30
|
+
} else {
|
|
31
|
+
//getting error because the nullish coalescing operator (??) isn't supported by your Babel/Webpack setup yet.
|
|
32
|
+
// priceType =
|
|
33
|
+
// product?.refineProduct?.priceRange?.minimum ??
|
|
34
|
+
// product?.refineProduct?.price;
|
|
35
|
+
|
|
36
|
+
//workaround
|
|
37
|
+
priceType =
|
|
38
|
+
product &&
|
|
39
|
+
product.refineProduct &&
|
|
40
|
+
product.refineProduct.priceRange &&
|
|
41
|
+
product.refineProduct.priceRange.minimum
|
|
42
|
+
? product.refineProduct.priceRange.minimum
|
|
43
|
+
: product &&
|
|
44
|
+
product.refineProduct &&
|
|
45
|
+
product.refineProduct.price
|
|
46
|
+
? product.refineProduct.price
|
|
47
|
+
: undefined;
|
|
48
|
+
|
|
49
|
+
if (useMaximum) {
|
|
50
|
+
priceType = product?.refineProduct?.priceRange?.maximum;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
price = priceType?.regular?.amount;
|
|
54
|
+
if (useFinal) {
|
|
55
|
+
price = priceType?.final?.amount;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// if currency symbol is configurable within Commerce, that symbol is used
|
|
60
|
+
let currency = price?.currency;
|
|
61
|
+
|
|
62
|
+
if (currencySymbol) {
|
|
63
|
+
currency = currencySymbol;
|
|
64
|
+
} else {
|
|
65
|
+
//getting error because the nullish coalescing operator (??) isn't supported by your Babel/Webpack setup yet.
|
|
66
|
+
//currency = getSymbolFromCurrency(currency) ?? '$';
|
|
67
|
+
|
|
68
|
+
// work around
|
|
69
|
+
currency =
|
|
70
|
+
getSymbolFromCurrency(currency) !== undefined &&
|
|
71
|
+
getSymbolFromCurrency(currency) !== null
|
|
72
|
+
? getSymbolFromCurrency(currency)
|
|
73
|
+
: '$';
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const convertedPrice = currencyRate
|
|
77
|
+
? price?.value * parseFloat(currencyRate)
|
|
78
|
+
: price?.value;
|
|
79
|
+
|
|
80
|
+
return convertedPrice ? `${currency}${convertedPrice.toFixed(2)}` : '';
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
export { getProductPrice };
|
|
@@ -0,0 +1,27 @@
|
|
|
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 getUserViewHistory = () => {
|
|
9
|
+
const userViewHistory = localStorage?.getItem('ds-view-history-time-decay')
|
|
10
|
+
? JSON.parse(localStorage.getItem('ds-view-history-time-decay'))
|
|
11
|
+
: null;
|
|
12
|
+
|
|
13
|
+
if (userViewHistory && Array.isArray(userViewHistory)) {
|
|
14
|
+
// https://git.corp.adobe.com/magento-datalake/magento2-snowplow-js/blob/main/src/utils.js#L177
|
|
15
|
+
// this shows localStorage is guaranteed sorted by unique by most recent timestamp as last index.
|
|
16
|
+
|
|
17
|
+
// MSRCH-2740: send the top 200 most recently viewed unique SKUs
|
|
18
|
+
return userViewHistory.slice(-200).map(v => ({
|
|
19
|
+
sku: v.sku,
|
|
20
|
+
dateTime: v.date
|
|
21
|
+
}));
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return [];
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export { getUserViewHistory };
|
|
@@ -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
|
+
// Luma Specific URL handling
|
|
9
|
+
import { DEFAULT_PAGE_SIZE } from '../utils/constants';
|
|
10
|
+
|
|
11
|
+
const nonFilterKeys = {
|
|
12
|
+
search: 'q',
|
|
13
|
+
search_query: 'search_query',
|
|
14
|
+
pagination: 'p',
|
|
15
|
+
sort: 'product_list_order',
|
|
16
|
+
page_size: 'page_size'
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const addUrlFilter = filter => {
|
|
20
|
+
const url = new URL(window.location.href);
|
|
21
|
+
const params = new URLSearchParams(url.searchParams);
|
|
22
|
+
const attribute = filter.attribute;
|
|
23
|
+
if (filter.range) {
|
|
24
|
+
const filt = filter.range;
|
|
25
|
+
if (getValueFromUrl(attribute)) {
|
|
26
|
+
params.delete(attribute);
|
|
27
|
+
params.append(attribute, `${filt.from}--${filt.to}`);
|
|
28
|
+
} else {
|
|
29
|
+
params.append(attribute, `${filt.from}--${filt.to}`);
|
|
30
|
+
}
|
|
31
|
+
} else {
|
|
32
|
+
const filt = filter.in || [];
|
|
33
|
+
const filterParams = params.getAll(attribute);
|
|
34
|
+
filt.map(f => {
|
|
35
|
+
if (!filterParams.includes(f)) {
|
|
36
|
+
params.append(attribute, f);
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
setWindowHistory(url.pathname, params);
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const removeUrlFilter = (name, option) => {
|
|
44
|
+
const url = new URL(window.location.href);
|
|
45
|
+
const params = new URLSearchParams(url.searchParams);
|
|
46
|
+
const allValues = url.searchParams.getAll(name);
|
|
47
|
+
params.delete(name);
|
|
48
|
+
if (option) {
|
|
49
|
+
allValues.splice(allValues.indexOf(option), 1);
|
|
50
|
+
allValues.forEach(val => params.append(name, val));
|
|
51
|
+
}
|
|
52
|
+
setWindowHistory(url.pathname, params);
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const removeAllUrlFilters = () => {
|
|
56
|
+
const url = new URL(window.location.href);
|
|
57
|
+
const params = new URLSearchParams(url.searchParams);
|
|
58
|
+
for (const key of url.searchParams.keys()) {
|
|
59
|
+
if (!Object.values(nonFilterKeys).includes(key)) {
|
|
60
|
+
params.delete(key);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
setWindowHistory(url.pathname, params);
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const handleUrlSort = sortOption => {
|
|
67
|
+
const url = new URL(window.location.href);
|
|
68
|
+
const params = new URLSearchParams(url.searchParams);
|
|
69
|
+
params.set('product_list_order', sortOption);
|
|
70
|
+
setWindowHistory(url.pathname, params);
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
const handleViewType = viewType => {
|
|
74
|
+
const url = new URL(window.location.href);
|
|
75
|
+
const params = new URLSearchParams(url.searchParams);
|
|
76
|
+
params.set('view_type', viewType);
|
|
77
|
+
setWindowHistory(url.pathname, params);
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
const handleUrlPageSize = pageSizeOption => {
|
|
81
|
+
const url = new URL(window.location.href);
|
|
82
|
+
const params = new URLSearchParams(url.searchParams);
|
|
83
|
+
if (pageSizeOption === DEFAULT_PAGE_SIZE) {
|
|
84
|
+
params.delete('page_size');
|
|
85
|
+
} else {
|
|
86
|
+
params.set('page_size', pageSizeOption.toString());
|
|
87
|
+
}
|
|
88
|
+
setWindowHistory(url.pathname, params);
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
const handleUrlPagination = pageNumber => {
|
|
92
|
+
const url = new URL(window.location.href);
|
|
93
|
+
const params = new URLSearchParams(url.searchParams);
|
|
94
|
+
if (pageNumber === 1) {
|
|
95
|
+
params.delete('p');
|
|
96
|
+
} else {
|
|
97
|
+
params.set('p', pageNumber.toString());
|
|
98
|
+
}
|
|
99
|
+
setWindowHistory(url.pathname, params);
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
const getFiltersFromUrl = filterableAttributes => {
|
|
103
|
+
const params = getSearchParams();
|
|
104
|
+
|
|
105
|
+
const filters = [];
|
|
106
|
+
for (const [key, value] of params.entries()) {
|
|
107
|
+
if (
|
|
108
|
+
filterableAttributes.includes(key) &&
|
|
109
|
+
!Object.values(nonFilterKeys).includes(key)
|
|
110
|
+
) {
|
|
111
|
+
if (value.includes('--')) {
|
|
112
|
+
const range = value.split('--');
|
|
113
|
+
const filter = {
|
|
114
|
+
attribute: key,
|
|
115
|
+
range: { from: Number(range[0]), to: Number(range[1]) }
|
|
116
|
+
};
|
|
117
|
+
filters.push(filter);
|
|
118
|
+
} else {
|
|
119
|
+
const attributeIndex = filters.findIndex(
|
|
120
|
+
filter => filter.attribute == key
|
|
121
|
+
);
|
|
122
|
+
if (attributeIndex !== -1) {
|
|
123
|
+
filters[attributeIndex].in.push(value);
|
|
124
|
+
} else {
|
|
125
|
+
const filter = { attribute: key, in: [value] };
|
|
126
|
+
filters.push(filter);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return filters;
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
const getValueFromUrl = param => {
|
|
136
|
+
const params = getSearchParams();
|
|
137
|
+
const filter = params.get(param);
|
|
138
|
+
return filter || '';
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
const getSearchParams = () => {
|
|
142
|
+
const search = window.location.search;
|
|
143
|
+
return new URLSearchParams(search);
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
const setWindowHistory = (pathname, params) => {
|
|
147
|
+
if (params.toString() === '') {
|
|
148
|
+
window.history.pushState({}, '', `${pathname}`);
|
|
149
|
+
} else {
|
|
150
|
+
window.history.pushState({}, '', `${pathname}?${params.toString()}`);
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
export {
|
|
155
|
+
addUrlFilter,
|
|
156
|
+
getFiltersFromUrl,
|
|
157
|
+
getValueFromUrl,
|
|
158
|
+
handleUrlPageSize,
|
|
159
|
+
handleUrlPagination,
|
|
160
|
+
handleUrlSort,
|
|
161
|
+
handleViewType,
|
|
162
|
+
removeAllUrlFilters,
|
|
163
|
+
removeUrlFilter
|
|
164
|
+
};
|