@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.
Files changed (202) hide show
  1. package/package.json +31 -0
  2. package/postcss.config.js +3 -0
  3. package/src/api/fragments.js +193 -0
  4. package/src/api/graphql.js +26 -0
  5. package/src/api/mutations.js +94 -0
  6. package/src/api/queries.js +225 -0
  7. package/src/api/search.js +222 -0
  8. package/src/components/AddToCartButton/AddToCartButton.jsx +32 -0
  9. package/src/components/AddToCartButton/AddToCartButton.stories.mdx +14 -0
  10. package/src/components/AddToCartButton/index.js +10 -0
  11. package/src/components/Alert/Alert.jsx +155 -0
  12. package/src/components/Alert/index.js +11 -0
  13. package/src/components/Breadcrumbs/Breadcrumbs.jsx +34 -0
  14. package/src/components/Breadcrumbs/MockPages.js +14 -0
  15. package/src/components/Breadcrumbs/index.js +11 -0
  16. package/src/components/ButtonShimmer/ButtonShimmer.css +32 -0
  17. package/src/components/ButtonShimmer/ButtonShimmer.jsx +23 -0
  18. package/src/components/ButtonShimmer/index.js +11 -0
  19. package/src/components/CategoryFilters/CategoryFilters.jsx +59 -0
  20. package/src/components/CategoryFilters/index.js +10 -0
  21. package/src/components/Facets/Facets.jsx +50 -0
  22. package/src/components/Facets/Range/RangeFacet.js +20 -0
  23. package/src/components/Facets/Scalar/ScalarFacet.js +29 -0
  24. package/src/components/Facets/SelectedFilters.js +80 -0
  25. package/src/components/Facets/format.js +52 -0
  26. package/src/components/Facets/index.js +14 -0
  27. package/src/components/Facets/mocks.js +119 -0
  28. package/src/components/FacetsShimmer/FacetsShimmer.css +49 -0
  29. package/src/components/FacetsShimmer/FacetsShimmer.jsx +25 -0
  30. package/src/components/FacetsShimmer/index.js +11 -0
  31. package/src/components/FilterButton/FilterButton.jsx +40 -0
  32. package/src/components/FilterButton/index.js +11 -0
  33. package/src/components/ImageCarousel/Image.jsx +34 -0
  34. package/src/components/ImageCarousel/ImageCarousel.jsx +103 -0
  35. package/src/components/ImageCarousel/index.js +11 -0
  36. package/src/components/InputButtonGroup/InputButtonGroup.jsx +120 -0
  37. package/src/components/InputButtonGroup/index.js +11 -0
  38. package/src/components/LabelledInput/LabelledInput.jsx +51 -0
  39. package/src/components/LabelledInput/index.js +11 -0
  40. package/src/components/Loading/Loading.jsx +32 -0
  41. package/src/components/Loading/index.js +11 -0
  42. package/src/components/NoResults/NoResults.jsx +55 -0
  43. package/src/components/NoResults/index.js +11 -0
  44. package/src/components/Pagination/Pagination.jsx +105 -0
  45. package/src/components/Pagination/index.js +10 -0
  46. package/src/components/PerPagePicker/PerPagePicker.jsx +114 -0
  47. package/src/components/PerPagePicker/index.js +11 -0
  48. package/src/components/Pill/Pill.jsx +34 -0
  49. package/src/components/Pill/index.js +11 -0
  50. package/src/components/Pill/mock.js +23 -0
  51. package/src/components/ProductCardShimmer/ProductCardShimmer.css +72 -0
  52. package/src/components/ProductCardShimmer/ProductCardShimmer.jsx +28 -0
  53. package/src/components/ProductCardShimmer/index.js +11 -0
  54. package/src/components/ProductItem/MockData.js +508 -0
  55. package/src/components/ProductItem/ProductItem.css +84 -0
  56. package/src/components/ProductItem/ProductItem.jsx +347 -0
  57. package/src/components/ProductItem/ProductPrice.jsx +181 -0
  58. package/src/components/ProductItem/index.js +11 -0
  59. package/src/components/ProductList/MockData.js +190 -0
  60. package/src/components/ProductList/ProductList.jsx +127 -0
  61. package/src/components/ProductList/index.js +11 -0
  62. package/src/components/ProductList/product-list.css +18 -0
  63. package/src/components/SearchBar/SearchBar.jsx +33 -0
  64. package/src/components/SearchBar/index.js +11 -0
  65. package/src/components/Shimmer/Shimmer.css +82 -0
  66. package/src/components/Shimmer/Shimmer.jsx +66 -0
  67. package/src/components/Shimmer/index.js +11 -0
  68. package/src/components/Slider/Slider.css +61 -0
  69. package/src/components/Slider/Slider.jsx +103 -0
  70. package/src/components/Slider/index.jsx +11 -0
  71. package/src/components/SliderDoubleControl/SliderDoubleControl.css +83 -0
  72. package/src/components/SliderDoubleControl/SliderDoubleControl.jsx +220 -0
  73. package/src/components/SliderDoubleControl/index.js +11 -0
  74. package/src/components/SortDropdown/SortDropdown.jsx +126 -0
  75. package/src/components/SortDropdown/index.js +11 -0
  76. package/src/components/SwatchButton/SwatchButton.jsx +72 -0
  77. package/src/components/SwatchButton/index.js +11 -0
  78. package/src/components/SwatchButtonGroup/SwatchButtonGroup.jsx +86 -0
  79. package/src/components/SwatchButtonGroup/index.js +11 -0
  80. package/src/components/ViewSwitcher/ViewSwitcher.jsx +46 -0
  81. package/src/components/ViewSwitcher/index.js +11 -0
  82. package/src/components/WishlistButton/WishlistButton.jsx +67 -0
  83. package/src/components/WishlistButton/index.js +11 -0
  84. package/src/containers/App.jsx +145 -0
  85. package/src/containers/LiveSearchPLPLoader.jsx +24 -0
  86. package/src/containers/LiveSearchPopoverLoader.jsx +190 -0
  87. package/src/containers/LiveSearchSRLPLoader.jsx +24 -0
  88. package/src/containers/ProductListingPage.jsx +66 -0
  89. package/src/containers/ProductsContainer.jsx +145 -0
  90. package/src/containers/ProductsHeader.jsx +123 -0
  91. package/src/context/attributeMetadata.js +63 -0
  92. package/src/context/cart.js +97 -0
  93. package/src/context/displayChange.js +90 -0
  94. package/src/context/events.js +160 -0
  95. package/src/context/index.js +19 -0
  96. package/src/context/products.jsx +336 -0
  97. package/src/context/resultsModifierContext.js +35 -0
  98. package/src/context/search.jsx +127 -0
  99. package/src/context/store.jsx +93 -0
  100. package/src/context/translation.jsx +125 -0
  101. package/src/context/widgetConfig.jsx +120 -0
  102. package/src/context/wishlist.jsx +97 -0
  103. package/src/hooks/eventing/useEventListener.js +13 -0
  104. package/src/hooks/eventing/useLocation.js +21 -0
  105. package/src/hooks/eventing/useMagentoExtensionContext.js +28 -0
  106. package/src/hooks/eventing/usePageView.js +36 -0
  107. package/src/hooks/eventing/useShopperContext.js +33 -0
  108. package/src/hooks/eventing/useStorefrontInstanceContext.js +46 -0
  109. package/src/hooks/eventing/useViewedOffsets.js +74 -0
  110. package/src/hooks/useAccessibleDropdown.js +148 -0
  111. package/src/hooks/useLiveSearchPLPConfig.js +112 -0
  112. package/src/hooks/useLiveSearchPopoverConfig.js +83 -0
  113. package/src/hooks/useLiveSearchSRLPConfig.js +97 -0
  114. package/src/hooks/usePagination.js +83 -0
  115. package/src/hooks/useRangeFacet.js +62 -0
  116. package/src/hooks/useScalarFacet.js +61 -0
  117. package/src/hooks/useSliderFacet.js +43 -0
  118. package/src/i18n/Sorani.js +60 -0
  119. package/src/i18n/ar_AE.js +60 -0
  120. package/src/i18n/bg_BG.js +60 -0
  121. package/src/i18n/bn_IN.js +60 -0
  122. package/src/i18n/ca_ES.js +60 -0
  123. package/src/i18n/cs_CZ.js +60 -0
  124. package/src/i18n/da_DK.js +60 -0
  125. package/src/i18n/de_DE.js +60 -0
  126. package/src/i18n/el_GR.js +60 -0
  127. package/src/i18n/en_GA.js +60 -0
  128. package/src/i18n/en_GB.js +60 -0
  129. package/src/i18n/en_US.js +70 -0
  130. package/src/i18n/es_ES.js +60 -0
  131. package/src/i18n/et_EE.js +60 -0
  132. package/src/i18n/eu_ES.js +60 -0
  133. package/src/i18n/fa_IR.js +60 -0
  134. package/src/i18n/fi_FI.js +60 -0
  135. package/src/i18n/fr_FR.js +60 -0
  136. package/src/i18n/gl_ES.js +60 -0
  137. package/src/i18n/hi_IN.js +60 -0
  138. package/src/i18n/hu_HU.js +60 -0
  139. package/src/i18n/hy_AM.js +60 -0
  140. package/src/i18n/id_ID.js +60 -0
  141. package/src/i18n/index.js +89 -0
  142. package/src/i18n/it_IT.js +60 -0
  143. package/src/i18n/ja_JP.js +60 -0
  144. package/src/i18n/ko_KR.js +60 -0
  145. package/src/i18n/lt_LT.js +60 -0
  146. package/src/i18n/lv_LV.js +60 -0
  147. package/src/i18n/nb_NO.js +60 -0
  148. package/src/i18n/nl_NL.js +60 -0
  149. package/src/i18n/pt_BR.js +60 -0
  150. package/src/i18n/pt_PT.js +60 -0
  151. package/src/i18n/ro_RO.js +60 -0
  152. package/src/i18n/ru_RU.js +60 -0
  153. package/src/i18n/sv_SE.js +60 -0
  154. package/src/i18n/th_TH.js +60 -0
  155. package/src/i18n/tr_TR.js +60 -0
  156. package/src/i18n/zh_Hans_CN.js +60 -0
  157. package/src/i18n/zh_Hant_TW.js +60 -0
  158. package/src/icons/NoImage.svg +1 -0
  159. package/src/icons/adjustments.svg +3 -0
  160. package/src/icons/cart.svg +3 -0
  161. package/src/icons/checkmark.svg +3 -0
  162. package/src/icons/chevron.svg +3 -0
  163. package/src/icons/emptyHeart.svg +3 -0
  164. package/src/icons/error.svg +3 -0
  165. package/src/icons/filledHeart.svg +3 -0
  166. package/src/icons/filter.svg +29 -0
  167. package/src/icons/gridView.svg +11 -0
  168. package/src/icons/info.svg +3 -0
  169. package/src/icons/listView.svg +5 -0
  170. package/src/icons/loading.svg +6 -0
  171. package/src/icons/plus.svg +4 -0
  172. package/src/icons/sort.svg +18 -0
  173. package/src/icons/warning.svg +3 -0
  174. package/src/icons/x.svg +3 -0
  175. package/src/index.jsx +65 -0
  176. package/src/queries/customerGroupCode.gql.js +10 -0
  177. package/src/queries/eventing/getMagentoExtensionContext.gql.js +13 -0
  178. package/src/queries/eventing/getPageType.gql.js +14 -0
  179. package/src/queries/eventing/getStorefrontContext.gql.js +27 -0
  180. package/src/queries/index.js +3 -0
  181. package/src/queries/liveSearchPlpConfigs.gql.js +30 -0
  182. package/src/queries/liveSearchPopoverConfigs.gql.js +28 -0
  183. package/src/styles/autocomplete.module.css +56 -0
  184. package/src/styles/index.css +1638 -0
  185. package/src/styles/searchBar.module.css +119 -0
  186. package/src/styles/tokens.css +99 -0
  187. package/src/targets/intercept.js +21 -0
  188. package/src/utils/constants.js +26 -0
  189. package/src/utils/decodeHtmlString.js +13 -0
  190. package/src/utils/dom.js +14 -0
  191. package/src/utils/eventing/getCookie.js +9 -0
  192. package/src/utils/eventing/usePageTypeFromUrl.js +26 -0
  193. package/src/utils/getProductImage.js +94 -0
  194. package/src/utils/getProductPrice.js +83 -0
  195. package/src/utils/getUserViewHistory.js +27 -0
  196. package/src/utils/handleUrlFilters.js +164 -0
  197. package/src/utils/htmlStringDecode.js +13 -0
  198. package/src/utils/modifyResults.js +164 -0
  199. package/src/utils/sort.js +95 -0
  200. package/src/utils/useIntersectionObserver.js +27 -0
  201. package/src/utils/validateStoreDetails.js +39 -0
  202. package/src/wrappers/wrapUseApp.js +28 -0
@@ -0,0 +1,112 @@
1
+ // src/hooks/useLiveSearchPLPConfig.js
2
+ import { useQuery, useMutation } from '@apollo/client';
3
+ import { GET_STORE_CONFIG_FOR_PLP, GET_CUSTOMER_GROUP_CODE } from '../queries';
4
+ import CATEGORY_OPERATIONS from '@magento/peregrine/lib/talons/RootComponents/Category/categoryContent.gql';
5
+ import { useCartContext } from '@magento/peregrine/lib/context/cart';
6
+ import { useEventingContext } from '@magento/peregrine/lib/context/eventing';
7
+ import operations from '@magento/peregrine/lib/talons/Gallery/addToCart.gql';
8
+
9
+ export const useLiveSearchPLPConfig = ({ categoryId }) => {
10
+ const { getCategoryContentQuery } = CATEGORY_OPERATIONS;
11
+ const { data: categoryData } = useQuery(getCategoryContentQuery, {
12
+ fetchPolicy: 'cache-and-network',
13
+ nextFetchPolicy: 'cache-first',
14
+ //skip: !categoryId,
15
+ variables: {
16
+ id: categoryId
17
+ }
18
+ });
19
+
20
+ const {
21
+ data: storeConfigData,
22
+ loading: loadingStoreConfig,
23
+ error: errorStoreConfig
24
+ } = useQuery(GET_STORE_CONFIG_FOR_PLP);
25
+
26
+ const { data: customerData, loading: loadingCustomer } = useQuery(
27
+ GET_CUSTOMER_GROUP_CODE
28
+ );
29
+
30
+ const loading = loadingStoreConfig || loadingCustomer;
31
+ const error = errorStoreConfig;
32
+
33
+ // Extract store config from the response
34
+ const storeConfig = storeConfigData?.storeConfig;
35
+ const currency = storeConfigData?.currency;
36
+ const baseUrl = storeConfig?.base_url || '';
37
+ const baseUrlwithoutProtocol = baseUrl
38
+ ?.replace(/^https?:/, '')
39
+ .replace(/\/$/, '');
40
+ const customerGroupCode =
41
+ customerData?.customer?.group_code ||
42
+ 'b6589fc6ab0dc82cf12099d1c2d40ab994e8410c';
43
+
44
+ const [{ cartId }] = useCartContext();
45
+ const [addToCart] = useMutation(operations.ADD_ITEM);
46
+ const [, { dispatch }] = useEventingContext();
47
+
48
+ //console.log("categoryData ==",categoryData);
49
+ const config = {
50
+ environmentId: storeConfig?.ls_environment_id || '',
51
+ environmentType: storeConfig?.ls_environment_type || '',
52
+ //apiKey: storeConfig?.ls_service_api_key || '',
53
+ apiKey: '',
54
+ websiteCode: storeConfig?.website_code || '',
55
+ storeCode: storeConfig?.store_group_code || '',
56
+ storeViewCode: storeConfig?.store_code || '',
57
+ config: {
58
+ pageSize: storeConfig?.ls_page_size_default || '8',
59
+ perPageConfig: {
60
+ pageSizeOptions:
61
+ storeConfig?.ls_page_size_options || '12,24,36',
62
+ defaultPageSizeOption: storeConfig?.ls_page_size_default || '12'
63
+ },
64
+ minQueryLength: storeConfig?.ls_min_query_length || '3',
65
+ currencySymbol:
66
+ currency?.default_display_currency_symbol || '\u0024',
67
+ currencyCode: currency?.default_display_currency_code || 'USD',
68
+ currencyRate: '1',
69
+ displayOutOfStock: storeConfig?.ls_display_out_of_stock || '',
70
+ allowAllProducts: storeConfig?.ls_allow_all || '',
71
+ currentCategoryUrlPath:
72
+ categoryData?.categories?.items[0]?.url_path,
73
+ categoryName: categoryData?.categories?.items[0]?.name,
74
+ displayMode: '',
75
+ locale: storeConfig?.ls_locale || 'en_US',
76
+ resolveCartId: () => cartId,
77
+ addToCart: async (sku, options, quantity) => {
78
+ try {
79
+ await addToCart({
80
+ variables: {
81
+ cartId,
82
+ cartItem: {
83
+ quantity,
84
+ entered_options: options,
85
+ sku: sku
86
+ }
87
+ }
88
+ });
89
+
90
+ dispatch({
91
+ type: 'CART_ADD_ITEM',
92
+ payload: {
93
+ cartId,
94
+ sku: sku,
95
+ selectedOptions: null,
96
+ quantity
97
+ }
98
+ });
99
+ } catch (error) {
100
+ console.error('Error adding to cart:', error);
101
+ }
102
+ }
103
+ },
104
+ context: {
105
+ customerGroup: customerGroupCode
106
+ },
107
+ baseUrl,
108
+ baseUrlwithoutProtocol
109
+ };
110
+
111
+ return { config, loading, error };
112
+ };
@@ -0,0 +1,83 @@
1
+ import { useQuery } from '@apollo/client';
2
+ import {
3
+ GET_STORE_CONFIG_FOR_LIVE_SEARCH_POPOVER,
4
+ GET_CUSTOMER_GROUP_CODE
5
+ } from '../queries';
6
+ import { useUserContext } from '@magento/peregrine/lib/context/user';
7
+
8
+ export const useLiveSearchPopoverConfig = () => {
9
+ const [{ isSignedIn }] = useUserContext();
10
+
11
+ const {
12
+ data: storeData,
13
+ loading: storeLoading,
14
+ error: storeError
15
+ } = useQuery(GET_STORE_CONFIG_FOR_LIVE_SEARCH_POPOVER);
16
+
17
+ const {
18
+ data: customerData,
19
+ loading: customerLoading,
20
+ error: customerError
21
+ } = useQuery(GET_CUSTOMER_GROUP_CODE, {
22
+ skip: !isSignedIn,
23
+ fetchPolicy: 'cache-and-network'
24
+ });
25
+
26
+ const storeConfig = storeData?.storeConfig || {};
27
+ const currency = storeData?.currency || {};
28
+ const baseUrl = storeConfig.base_url || '';
29
+ const baseUrlwithoutProtocol = baseUrl
30
+ .replace(/^https?:/, '')
31
+ .replace(/\/$/, '');
32
+ const customerGroupCode =
33
+ isSignedIn && customerData?.customer?.group_code
34
+ ? customerData.customer.group_code
35
+ : 'b6589fc6ab0dc82cf12099d1c2d40ab994e8410c';
36
+
37
+ const configReady =
38
+ !storeLoading &&
39
+ (!isSignedIn || !customerLoading) &&
40
+ !storeError &&
41
+ (!isSignedIn || !customerError) &&
42
+ storeConfig?.ls_environment_id; // required field
43
+
44
+ if (!configReady) {
45
+ return {
46
+ storeDetails: null,
47
+ storeLoading,
48
+ customerLoading,
49
+ storeError,
50
+ customerError,
51
+ configReady: false
52
+ };
53
+ }
54
+
55
+ const storeDetails = {
56
+ environmentId: storeConfig.ls_environment_id || '',
57
+ websiteCode: storeConfig.website_code || '',
58
+ storeCode: storeConfig.store_group_code || '',
59
+ storeViewCode: storeConfig.store_code || '',
60
+ config: {
61
+ pageSize: storeConfig.ls_page_size_default || '8',
62
+ minQueryLength: storeConfig.ls_min_query_length || '3',
63
+ currencySymbol:
64
+ currency.default_display_currency_symbol || '\u0024',
65
+ currencyCode: currency.default_display_currency_code || 'USD',
66
+ locale: storeConfig.ls_locale || 'en_US'
67
+ },
68
+ context: {
69
+ customerGroup: customerGroupCode
70
+ },
71
+ baseUrl,
72
+ baseUrlwithoutProtocol
73
+ };
74
+
75
+ return {
76
+ storeDetails,
77
+ storeLoading,
78
+ customerLoading,
79
+ storeError,
80
+ customerError,
81
+ configReady
82
+ };
83
+ };
@@ -0,0 +1,97 @@
1
+ // src/hooks/useLiveSearchSRLPConfig.js
2
+ import { useQuery, useMutation } from '@apollo/client';
3
+ import { GET_STORE_CONFIG_FOR_PLP, GET_CUSTOMER_GROUP_CODE } from '../queries';
4
+ import { useCartContext } from '@magento/peregrine/lib/context/cart';
5
+ import { useEventingContext } from '@magento/peregrine/lib/context/eventing';
6
+ import operations from '@magento/peregrine/lib/talons/Gallery/addToCart.gql';
7
+
8
+ export const useLiveSearchSRLPConfig = () => {
9
+ const {
10
+ data: storeConfigData,
11
+ loading: loadingStoreConfig,
12
+ error: errorStoreConfig
13
+ } = useQuery(GET_STORE_CONFIG_FOR_PLP);
14
+
15
+ const { data: customerData, loading: loadingCustomer } = useQuery(
16
+ GET_CUSTOMER_GROUP_CODE
17
+ );
18
+
19
+ const loading = loadingStoreConfig || loadingCustomer;
20
+ const error = errorStoreConfig;
21
+
22
+ // Extract store config from the response
23
+ const storeConfig = storeConfigData?.storeConfig;
24
+ const currency = storeConfigData?.currency;
25
+ const baseUrl = storeConfig?.base_url || '';
26
+ const baseUrlwithoutProtocol = baseUrl
27
+ ?.replace(/^https?:/, '')
28
+ .replace(/\/$/, '');
29
+ const customerGroupCode =
30
+ customerData?.customer?.group_code ||
31
+ 'b6589fc6ab0dc82cf12099d1c2d40ab994e8410c';
32
+
33
+ const [{ cartId }] = useCartContext();
34
+ const [addToCart] = useMutation(operations.ADD_ITEM);
35
+ const [, { dispatch }] = useEventingContext();
36
+
37
+ const config = {
38
+ environmentId: storeConfig?.ls_environment_id || '',
39
+ environmentType: storeConfig?.ls_environment_type || '',
40
+ apiKey: '',
41
+ websiteCode: storeConfig?.website_code || '',
42
+ storeCode: storeConfig?.store_group_code || '',
43
+ storeViewCode: storeConfig?.store_code || '',
44
+ searchQuery: 'query',
45
+ config: {
46
+ pageSize: storeConfig?.ls_page_size_default || '8',
47
+ perPageConfig: {
48
+ pageSizeOptions:
49
+ storeConfig?.ls_page_size_options || '12,24,36',
50
+ defaultPageSizeOption: storeConfig?.ls_page_size_default || '12'
51
+ },
52
+ minQueryLength: storeConfig?.ls_min_query_length || '3',
53
+ currencySymbol:
54
+ currency?.default_display_currency_symbol || '\u0024',
55
+ currencyCode: currency?.default_display_currency_code || 'USD',
56
+ currencyRate: '1',
57
+ displayOutOfStock: storeConfig?.ls_display_out_of_stock || '',
58
+ allowAllProducts: storeConfig?.ls_allow_all || '',
59
+ locale: storeConfig?.ls_locale || 'en_US',
60
+ resolveCartId: () => cartId,
61
+ addToCart: async (sku, options, quantity) => {
62
+ try {
63
+ await addToCart({
64
+ variables: {
65
+ cartId,
66
+ cartItem: {
67
+ quantity,
68
+ entered_options: options,
69
+ sku: sku
70
+ }
71
+ }
72
+ });
73
+
74
+ dispatch({
75
+ type: 'CART_ADD_ITEM',
76
+ payload: {
77
+ cartId,
78
+ sku: sku,
79
+ selectedOptions: null,
80
+ quantity
81
+ }
82
+ });
83
+ } catch (error) {
84
+ console.error('Error adding to cart:', error);
85
+ }
86
+ }
87
+ },
88
+ context: {
89
+ customerGroup: customerGroupCode
90
+ },
91
+ baseUrl,
92
+ baseUrlwithoutProtocol
93
+ };
94
+ console.log('SRLP config : ', config);
95
+
96
+ return { config, loading, error };
97
+ };
@@ -0,0 +1,83 @@
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 { useMemo } from 'react';
11
+
12
+ export const ELLIPSIS = '...';
13
+
14
+ const getRange = (start, end) => {
15
+ const length = end - start + 1;
16
+ return Array.from({ length }, (_, index) => start + index);
17
+ };
18
+
19
+ export const usePagination = ({
20
+ currentPage,
21
+ totalPages,
22
+ siblingCount = 1
23
+ }) => {
24
+ const paginationRange = useMemo(() => {
25
+ const firstPageIndex = 1;
26
+ const lastPageIndex = totalPages;
27
+ const totalPagePills = siblingCount + 5; // siblingCount + firstPage + lastPage + currentPage + 2 * ellipsis(...)
28
+
29
+ const leftSiblingIndex = Math.max(currentPage - siblingCount, 1);
30
+ const rightSiblingIndex = Math.min(
31
+ currentPage + siblingCount,
32
+ totalPages
33
+ );
34
+
35
+ // We do not show the left/right dots(...) if there is just one page left to be inserted between the extremes of sibling and the page limits.
36
+ const showLeftDots = leftSiblingIndex > 2;
37
+ const showRightDots = rightSiblingIndex < totalPages - 2;
38
+
39
+ // Case 1 - the total page count is less than the page pills we want to show.
40
+
41
+ // < 1 2 3 4 5 6 >
42
+ if (totalPages <= totalPagePills) {
43
+ return getRange(1, totalPages);
44
+ }
45
+
46
+ // Case 2 - the total page count is greater than the page pills and only the dots on the right are shown
47
+
48
+ // < 1 2 3 4 ... 25 >
49
+ if (!showLeftDots && showRightDots) {
50
+ const leftItemCount = 3 + 2 * siblingCount;
51
+ const leftRange = getRange(1, leftItemCount);
52
+ return [...leftRange, ELLIPSIS, totalPages];
53
+ }
54
+
55
+ // Case 3 - the total page count is greater than the page pills and only the dots on the left are shown
56
+
57
+ // < 1 ... 22 23 24 25 >
58
+ if (showLeftDots && !showRightDots) {
59
+ const rightItemCount = 3 + 2 * siblingCount;
60
+ const rightRange = getRange(
61
+ totalPages - rightItemCount + 1,
62
+ totalPages
63
+ );
64
+ return [firstPageIndex, ELLIPSIS, ...rightRange];
65
+ }
66
+
67
+ // Case 4 - the total page count is greater than the page pills and both the right and left dots are shown
68
+
69
+ // < 1 ... 19 20 21 ... 25 >
70
+ if (showLeftDots && showRightDots) {
71
+ const middleRange = getRange(leftSiblingIndex, rightSiblingIndex);
72
+ return [
73
+ firstPageIndex,
74
+ ELLIPSIS,
75
+ ...middleRange,
76
+ ELLIPSIS,
77
+ lastPageIndex
78
+ ];
79
+ }
80
+ }, [currentPage, totalPages, siblingCount]);
81
+
82
+ return paginationRange;
83
+ };
@@ -0,0 +1,62 @@
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 { useSearch } from '../context';
11
+
12
+ const useRangeFacet = ({ attribute, buckets }) => {
13
+ const processedBuckets = {};
14
+
15
+ buckets.forEach(bucket => {
16
+ processedBuckets[bucket.title] = {
17
+ from: bucket.from,
18
+ to: bucket.to
19
+ };
20
+ });
21
+
22
+ const searchCtx = useSearch();
23
+
24
+ const filter = searchCtx?.filters?.find(e => e.attribute === attribute);
25
+
26
+ const isSelected = title => {
27
+ const selected = filter
28
+ ? processedBuckets[title].from === filter.range?.from &&
29
+ processedBuckets[title].to === filter.range?.to
30
+ : false;
31
+ return selected;
32
+ };
33
+
34
+ const onChange = value => {
35
+ const selectedRange = processedBuckets[value];
36
+
37
+ if (!filter) {
38
+ const newFilter = {
39
+ attribute,
40
+ range: {
41
+ from: selectedRange.from,
42
+ to: selectedRange.to
43
+ }
44
+ };
45
+ searchCtx.createFilter(newFilter);
46
+ return;
47
+ }
48
+
49
+ const newFilter = {
50
+ ...filter,
51
+ range: {
52
+ from: selectedRange.from,
53
+ to: selectedRange.to
54
+ }
55
+ };
56
+ searchCtx.updateFilter(newFilter);
57
+ };
58
+
59
+ return { isSelected, onChange };
60
+ };
61
+
62
+ export default useRangeFacet;
@@ -0,0 +1,61 @@
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 { useSearch } from '../context';
11
+
12
+ const useScalarFacet = facet => {
13
+ const searchCtx = useSearch();
14
+
15
+ const filter = searchCtx?.filters?.find(
16
+ e => e.attribute === facet.attribute
17
+ );
18
+
19
+ const isSelected = attribute => {
20
+ return filter ? filter.in?.includes(attribute) : false;
21
+ };
22
+
23
+ const onChange = (value, selected) => {
24
+ if (!filter) {
25
+ const newFilter = {
26
+ attribute: facet.attribute,
27
+ in: [value]
28
+ };
29
+
30
+ searchCtx.createFilter(newFilter);
31
+ return;
32
+ }
33
+
34
+ const newFilter = { ...filter };
35
+ const currentFilterIn = filter.in || [];
36
+
37
+ newFilter.in = selected
38
+ ? [...currentFilterIn, value]
39
+ : filter.in?.filter(e => e !== value);
40
+
41
+ const filterUnselected = filter.in?.filter(
42
+ x => !newFilter.in?.includes(x)
43
+ );
44
+
45
+ if (newFilter.in?.length) {
46
+ if (filterUnselected?.length) {
47
+ searchCtx.removeFilter(facet.attribute, filterUnselected[0]);
48
+ }
49
+ searchCtx.updateFilter(newFilter);
50
+ return;
51
+ }
52
+
53
+ if (!newFilter.in?.length) {
54
+ searchCtx.removeFilter(facet.attribute);
55
+ }
56
+ };
57
+
58
+ return { isSelected, onChange };
59
+ };
60
+
61
+ export default useScalarFacet;
@@ -0,0 +1,43 @@
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 { useSearch } from '../context';
11
+
12
+ const useSliderFacet = ({ attribute }) => {
13
+ const searchCtx = useSearch();
14
+
15
+ const onChange = (from, to) => {
16
+ const filter = searchCtx?.filters?.find(e => e.attribute === attribute);
17
+
18
+ if (!filter) {
19
+ const newFilter = {
20
+ attribute,
21
+ range: {
22
+ from,
23
+ to
24
+ }
25
+ };
26
+ searchCtx.createFilter(newFilter);
27
+ return;
28
+ }
29
+
30
+ const newFilter = {
31
+ ...filter,
32
+ range: {
33
+ from,
34
+ to
35
+ }
36
+ };
37
+ searchCtx.updateFilter(newFilter);
38
+ };
39
+
40
+ return { onChange };
41
+ };
42
+
43
+ export default useSliderFacet;
@@ -0,0 +1,60 @@
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 Sorani = {
11
+ Filter: {
12
+ title: 'فلتەرەکان',
13
+ showTitle: 'پیشاندانی فلتەرەکان',
14
+ hideTitle: 'شاردنەوەی فلتەرەکان',
15
+ clearAll: 'سڕینەوەی هەمووان'
16
+ },
17
+ InputButtonGroup: {
18
+ title: 'پۆلەکان',
19
+ price: 'نرخ',
20
+ customPrice: 'نرخی بەکەسیکراو',
21
+ priceIncluded: 'بەڵێ',
22
+ priceExcluded: 'نەخێر',
23
+ priceExcludedMessage: 'نا {title}',
24
+ priceRange: ' و سەرووتر',
25
+ showmore: 'بینینی زیاتر'
26
+ },
27
+ Loading: {
28
+ title: 'بارکردن'
29
+ },
30
+ NoResults: {
31
+ heading: 'هیچ ئەنجامێک بۆ گەڕانەکەت نییە.',
32
+ subheading: 'تكایە دیسان هەوڵ بدەوە...'
33
+ },
34
+ SortDropdown: {
35
+ title: 'پۆلێنکردن بەگوێرەی',
36
+ option: 'پۆلێنکردن بەگوێرەی: {selectedOption}',
37
+ relevanceLabel: 'پەیوەندیدارترین',
38
+ positionLabel: 'شوێن'
39
+ },
40
+ CategoryFilters: {
41
+ results: 'ئەنجامەکان بۆ {phrase}',
42
+ products: '{totalCount} بەرهەمەکان'
43
+ },
44
+ ProductCard: {
45
+ asLowAs: 'بەقەد نزمیی {discountPrice}',
46
+ startingAt: 'دەستپێدەکات لە {productPrice}',
47
+ bundlePrice: 'لە {fromBundlePrice} بۆ {toBundlePrice}',
48
+ from: 'لە {productPrice}'
49
+ },
50
+ ProductContainers: {
51
+ minquery:
52
+ 'زاراوەی گەڕانەکەت {variables.phrase} بەلانی کەم نەگەیشتۆتە {minQueryLength} پیت.',
53
+ noresults: 'گەڕانەکەت هیچ ئەنجامێکی نەبوو.',
54
+ pagePicker: 'پیشاندانی {pageSize} لە هەر لاپەڕەیەکدا',
55
+ showAll: 'هەموو'
56
+ },
57
+ SearchBar: {
58
+ placeholder: 'گەڕان...'
59
+ }
60
+ };
@@ -0,0 +1,60 @@
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 ar_AE = {
11
+ Filter: {
12
+ title: 'عوامل التصفية',
13
+ showTitle: 'إظهار عوامل التصفية',
14
+ hideTitle: 'إخفاء عوامل التصفية',
15
+ clearAll: 'مسح الكل'
16
+ },
17
+ InputButtonGroup: {
18
+ title: 'الفئات',
19
+ price: 'السعر',
20
+ customPrice: 'السعر المخصص',
21
+ priceIncluded: 'نعم.',
22
+ priceExcluded: 'لا',
23
+ priceExcludedMessage: 'ليس {title}',
24
+ priceRange: ' وما بعده',
25
+ showmore: 'إظهار أكثر'
26
+ },
27
+ Loading: {
28
+ title: 'تحميل'
29
+ },
30
+ NoResults: {
31
+ heading: 'لا يوجد نتائج لبحثك.',
32
+ subheading: 'الرجاء المحاولة مرة أخرى...'
33
+ },
34
+ SortDropdown: {
35
+ title: 'فرز حسب',
36
+ option: 'فرز حسب: {selectedOption}',
37
+ relevanceLabel: 'الأكثر صلة',
38
+ positionLabel: 'الموضع'
39
+ },
40
+ CategoryFilters: {
41
+ results: 'النتائج لـ {phrase}',
42
+ products: 'منتجات {totalCount}'
43
+ },
44
+ ProductCard: {
45
+ asLowAs: 'بقيمة {discountPrice} فقط',
46
+ startingAt: 'بدءًا من {productPrice}',
47
+ bundlePrice: 'من {fromBundlePrice} إلى {toBundlePrice}',
48
+ from: 'من {productPrice}'
49
+ },
50
+ ProductContainers: {
51
+ minquery:
52
+ 'مصطلح البحث الخاص بك {variables.phrase} لم يصل إلى {minQueryLength} من الأحرف كحد أدنى.',
53
+ noresults: 'لا يوجد لبحثك أي نتائج.',
54
+ pagePicker: 'إظهار {pageSize} لكل صفحة',
55
+ showAll: 'الكل'
56
+ },
57
+ SearchBar: {
58
+ placeholder: 'بحث...'
59
+ }
60
+ };