@usereactify/search 5.0.0-beta.1 → 5.0.0-beta.2

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 (143) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/dist/package.json +66 -0
  3. package/dist/src/components/Example/ExampleFilterList.d.ts +4 -0
  4. package/dist/src/components/Example/ExampleFilterList.js +19 -0
  5. package/dist/src/components/Example/ExampleFilterRange.d.ts +4 -0
  6. package/dist/src/components/Example/ExampleFilterRange.js +21 -0
  7. package/dist/src/components/Example/ExampleFilterSlider.d.ts +4 -0
  8. package/dist/src/components/Example/ExampleFilterSlider.js +20 -0
  9. package/dist/src/components/Example/ExampleFilterStack.d.ts +4 -0
  10. package/dist/src/components/Example/ExampleFilterStack.js +12 -0
  11. package/dist/src/components/Example/ExampleResultCardCallout.d.ts +4 -0
  12. package/dist/src/components/Example/ExampleResultCardCallout.js +21 -0
  13. package/dist/src/components/Example/ExampleResultCardProduct.d.ts +4 -0
  14. package/dist/src/components/Example/ExampleResultCardProduct.js +18 -0
  15. package/dist/src/components/Example/ExampleResultPaginationLoadMore.d.ts +4 -0
  16. package/dist/src/components/Example/ExampleResultPaginationLoadMore.js +11 -0
  17. package/dist/src/components/Example/ExampleResultPaginationNextPrev.d.ts +4 -0
  18. package/dist/src/components/Example/ExampleResultPaginationNextPrev.js +13 -0
  19. package/dist/src/components/Example/ExampleResultPaginationNumbered.d.ts +4 -0
  20. package/dist/src/components/Example/ExampleResultPaginationNumbered.js +26 -0
  21. package/dist/src/components/Example/ExampleSortby.d.ts +4 -0
  22. package/dist/src/components/Example/ExampleSortby.js +12 -0
  23. package/dist/src/components/Example/index.d.ts +10 -0
  24. package/dist/src/components/Example/index.js +22 -0
  25. package/dist/src/components/Filter/Filter.d.ts +20 -0
  26. package/dist/src/components/Filter/Filter.js +89 -0
  27. package/dist/src/components/Filter/FilterStack.d.ts +7 -0
  28. package/dist/src/components/Filter/FilterStack.js +16 -0
  29. package/dist/src/components/Filter/index.d.ts +2 -0
  30. package/dist/src/components/Filter/index.js +14 -0
  31. package/dist/src/components/ReactifySearchBase/ReactifySearchBase.d.ts +42 -0
  32. package/dist/src/components/ReactifySearchBase/ReactifySearchBase.js +140 -0
  33. package/dist/src/components/ReactifySearchBase/index.d.ts +1 -0
  34. package/dist/src/components/ReactifySearchBase/index.js +13 -0
  35. package/dist/src/components/Result/ResultCardCallout.d.ts +12 -0
  36. package/dist/src/components/Result/ResultCardCallout.js +46 -0
  37. package/dist/src/components/Result/ResultCardProduct.d.ts +13 -0
  38. package/dist/src/components/Result/ResultCardProduct.js +63 -0
  39. package/dist/src/components/Result/ResultPaginationLoadMore.d.ts +7 -0
  40. package/dist/src/components/Result/ResultPaginationLoadMore.js +16 -0
  41. package/dist/src/components/Result/ResultPaginationNextPrev.d.ts +7 -0
  42. package/dist/src/components/Result/ResultPaginationNextPrev.js +16 -0
  43. package/dist/src/components/Result/ResultPaginationNumbered.d.ts +7 -0
  44. package/dist/src/components/Result/ResultPaginationNumbered.js +19 -0
  45. package/dist/src/components/Result/ResultStack.d.ts +40 -0
  46. package/dist/src/components/Result/ResultStack.js +107 -0
  47. package/dist/src/components/Result/ResultStateProvider.d.ts +6 -0
  48. package/dist/src/components/Result/ResultStateProvider.js +10 -0
  49. package/dist/src/components/Result/index.d.ts +7 -0
  50. package/dist/src/components/Result/index.js +19 -0
  51. package/dist/src/components/Search/SearchInput.d.ts +8 -0
  52. package/dist/src/components/Search/SearchInput.js +17 -0
  53. package/dist/src/components/Search/index.d.ts +1 -0
  54. package/dist/src/components/Search/index.js +13 -0
  55. package/dist/src/components/Sensor/SensorCollection.d.ts +2 -0
  56. package/dist/src/components/Sensor/SensorCollection.js +44 -0
  57. package/dist/src/components/Sensor/SensorInventoryAvailable.d.ts +2 -0
  58. package/dist/src/components/Sensor/SensorInventoryAvailable.js +52 -0
  59. package/dist/src/components/Sensor/SensorPublished.d.ts +2 -0
  60. package/dist/src/components/Sensor/SensorPublished.js +16 -0
  61. package/dist/src/components/Sensor/SensorSearch.d.ts +2 -0
  62. package/dist/src/components/Sensor/SensorSearch.js +82 -0
  63. package/dist/src/components/Sensor/SensorSort.d.ts +2 -0
  64. package/dist/src/components/Sensor/SensorSort.js +204 -0
  65. package/dist/src/components/Sensor/SensorSortScore.d.ts +2 -0
  66. package/dist/src/components/Sensor/SensorSortScore.js +12 -0
  67. package/dist/src/components/Sensor/SensorStack.d.ts +3 -0
  68. package/dist/src/components/Sensor/SensorStack.js +31 -0
  69. package/dist/src/components/Sensor/index.d.ts +8 -0
  70. package/dist/src/components/Sensor/index.js +29 -0
  71. package/dist/src/components/Sortby/Sortby.d.ts +7 -0
  72. package/dist/src/components/Sortby/Sortby.js +16 -0
  73. package/dist/src/components/Sortby/index.d.ts +1 -0
  74. package/dist/src/components/Sortby/index.js +13 -0
  75. package/dist/src/components/Utility/UtilityAuthenticatedReactiveBase.d.ts +2 -0
  76. package/dist/src/components/Utility/UtilityAuthenticatedReactiveBase.js +14 -0
  77. package/dist/src/components/Utility/index.d.ts +1 -0
  78. package/dist/src/components/Utility/index.js +13 -0
  79. package/dist/src/components/index.d.ts +8 -0
  80. package/dist/src/components/index.js +20 -0
  81. package/dist/src/hooks/index.d.ts +14 -0
  82. package/dist/src/hooks/index.js +26 -0
  83. package/dist/src/hooks/reactivesearch/index.d.ts +8 -0
  84. package/dist/src/hooks/reactivesearch/index.js +20 -0
  85. package/dist/src/hooks/reactivesearch/useReactiveBaseProps.d.ts +7 -0
  86. package/dist/src/hooks/reactivesearch/useReactiveBaseProps.js +43 -0
  87. package/dist/src/hooks/reactivesearch/useReactiveDataSearchProps.d.ts +26 -0
  88. package/dist/src/hooks/reactivesearch/useReactiveDataSearchProps.js +70 -0
  89. package/dist/src/hooks/reactivesearch/useReactiveFilterListProps.d.ts +73 -0
  90. package/dist/src/hooks/reactivesearch/useReactiveFilterListProps.js +21 -0
  91. package/dist/src/hooks/reactivesearch/useReactiveFilterRangeProps.d.ts +70 -0
  92. package/dist/src/hooks/reactivesearch/useReactiveFilterRangeProps.js +21 -0
  93. package/dist/src/hooks/reactivesearch/useReactiveFilterSharedProps.d.ts +67 -0
  94. package/dist/src/hooks/reactivesearch/useReactiveFilterSharedProps.js +105 -0
  95. package/dist/src/hooks/reactivesearch/useReactiveFilterSliderProps.d.ts +68 -0
  96. package/dist/src/hooks/reactivesearch/useReactiveFilterSliderProps.js +21 -0
  97. package/dist/src/hooks/reactivesearch/useReactiveReactProp.d.ts +3 -0
  98. package/dist/src/hooks/reactivesearch/useReactiveReactProp.js +25 -0
  99. package/dist/src/hooks/reactivesearch/useReactiveResultStackProps.d.ts +17 -0
  100. package/dist/src/hooks/reactivesearch/useReactiveResultStackProps.js +31 -0
  101. package/dist/src/hooks/useAnalytics.d.ts +95 -0
  102. package/dist/src/hooks/useAnalytics.js +110 -0
  103. package/dist/src/hooks/useConfig.d.ts +4 -0
  104. package/dist/src/hooks/useConfig.js +81 -0
  105. package/dist/src/hooks/useCuration.d.ts +2 -0
  106. package/dist/src/hooks/useCuration.js +52 -0
  107. package/dist/src/hooks/useFilterCollapsedState.d.ts +8 -0
  108. package/dist/src/hooks/useFilterCollapsedState.js +27 -0
  109. package/dist/src/hooks/useFilterListProps.d.ts +12 -0
  110. package/dist/src/hooks/useFilterListProps.js +35 -0
  111. package/dist/src/hooks/useFilterStack.d.ts +2 -0
  112. package/dist/src/hooks/useFilterStack.js +46 -0
  113. package/dist/src/hooks/useFilters.d.ts +4 -0
  114. package/dist/src/hooks/useFilters.js +22 -0
  115. package/dist/src/hooks/usePagination.d.ts +14 -0
  116. package/dist/src/hooks/usePagination.js +97 -0
  117. package/dist/src/hooks/usePaginationLoadMore.d.ts +15 -0
  118. package/dist/src/hooks/usePaginationLoadMore.js +37 -0
  119. package/dist/src/hooks/useProductPrice.d.ts +10 -0
  120. package/dist/src/hooks/useProductPrice.js +63 -0
  121. package/dist/src/hooks/useReactifySearchContext.d.ts +78 -0
  122. package/dist/src/hooks/useReactifySearchContext.js +10 -0
  123. package/dist/src/hooks/useSearch.d.ts +8 -0
  124. package/dist/src/hooks/useSearch.js +36 -0
  125. package/dist/src/hooks/useSortby.d.ts +6 -0
  126. package/dist/src/hooks/useSortby.js +41 -0
  127. package/dist/src/index.d.ts +3 -0
  128. package/dist/src/index.js +18 -0
  129. package/dist/src/types/config.d.ts +26 -0
  130. package/dist/src/types/config.js +2 -0
  131. package/dist/src/types/elastic.d.ts +209 -0
  132. package/dist/src/types/elastic.js +18 -0
  133. package/dist/src/types/firestore.d.ts +280 -0
  134. package/dist/src/types/firestore.js +18 -0
  135. package/dist/src/types/graphql.d.ts +26545 -0
  136. package/dist/src/types/graphql.js +4687 -0
  137. package/dist/src/types/index.d.ts +3 -0
  138. package/dist/src/types/index.js +15 -0
  139. package/dist/src/types/reactivesearch.d.ts +73 -0
  140. package/dist/src/types/reactivesearch.js +2 -0
  141. package/dist/src/types/shopify.d.ts +21 -0
  142. package/dist/src/types/shopify.js +27 -0
  143. package/package.json +3 -2
@@ -0,0 +1,97 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.usePagination = void 0;
7
+ const react_1 = __importDefault(require("react"));
8
+ const hooks_1 = require("../hooks");
9
+ const usePagination = (input) => {
10
+ const { track } = (0, hooks_1.useAnalytics)();
11
+ const buildPagePath = react_1.default.useCallback((page) => {
12
+ const currentPath = window.location.pathname;
13
+ return currentPath.includes("page=")
14
+ ? currentPath.replace(/page=\d+/g, `page=${page}`)
15
+ : `${currentPath}${currentPath.includes("?") ? "&" : "?"}page=${page}`;
16
+ }, []);
17
+ const pagesToShow = react_1.default.useMemo(() => getPages(input.pages, input.totalPages, input.currentPage), [input.pages, input.totalPages, input.currentPage]);
18
+ // default input.currentPage is zero-indexed, actualCurrentPage is one-indexed
19
+ const actualCurrentPage = react_1.default.useMemo(() => input.currentPage + 1, [input.currentPage]);
20
+ const hasNextPage = react_1.default.useMemo(() => actualCurrentPage < input.totalPages, [actualCurrentPage, input.totalPages]);
21
+ const hasPreviousPage = react_1.default.useMemo(() => actualCurrentPage > 1, [actualCurrentPage]);
22
+ const hasPage = react_1.default.useCallback((pageNumber) => {
23
+ return pageNumber >= 0 && pageNumber < input.totalPages;
24
+ }, [input.totalPages]);
25
+ const handlePageChange = react_1.default.useCallback((pageNumber, event) => {
26
+ event === null || event === void 0 ? void 0 : event.preventDefault();
27
+ if (!hasPage(pageNumber)) {
28
+ return;
29
+ }
30
+ input.setPage(pageNumber);
31
+ track({
32
+ eventName: "paginationChange",
33
+ payload: {
34
+ page: pageNumber,
35
+ source: window.location.pathname.includes("/search")
36
+ ? "search"
37
+ : "collection",
38
+ },
39
+ });
40
+ }, [input.setPage, track]);
41
+ const handleNextPage = react_1.default.useCallback((event) => {
42
+ handlePageChange(input.currentPage + 1, event);
43
+ }, [hasNextPage, input.currentPage, handlePageChange]);
44
+ const handlePreviousPage = react_1.default.useCallback((event) => {
45
+ handlePageChange(input.currentPage - 1, event);
46
+ }, [hasPreviousPage, input.currentPage, handlePageChange]);
47
+ return react_1.default.useMemo(() => ({
48
+ currentPage: input.currentPage,
49
+ totalPages: input.totalPages,
50
+ pagesToShow,
51
+ hasNextPage,
52
+ buildPagePath,
53
+ hasPreviousPage,
54
+ actualCurrentPage,
55
+ handleNextPage,
56
+ handlePreviousPage,
57
+ handlePageChange,
58
+ }), [
59
+ input.currentPage,
60
+ input.totalPages,
61
+ pagesToShow,
62
+ hasNextPage,
63
+ buildPagePath,
64
+ hasPreviousPage,
65
+ actualCurrentPage,
66
+ handleNextPage,
67
+ handlePreviousPage,
68
+ handlePageChange,
69
+ ]);
70
+ };
71
+ exports.usePagination = usePagination;
72
+ // get a list of pages to display buttons for
73
+ // @todo this is super hacky and needs to be cleaned up
74
+ const getPages = (pages, totalPages, currentPage) => {
75
+ const pagesToShow = pages > totalPages ? totalPages : pages;
76
+ const buffer = Math.floor(pagesToShow / 2);
77
+ let list = [];
78
+ let start = 0;
79
+ if (totalPages <= 5 || currentPage < buffer + 1) {
80
+ start = 0;
81
+ }
82
+ else {
83
+ if (totalPages - buffer <= currentPage) {
84
+ start =
85
+ currentPage + 1 === totalPages
86
+ ? currentPage - (pagesToShow - 1)
87
+ : currentPage - (buffer + buffer / 2);
88
+ }
89
+ else {
90
+ start = currentPage - buffer;
91
+ }
92
+ }
93
+ Array.apply(null, Array(pagesToShow)).map((item, index) => {
94
+ list.push(start + index);
95
+ });
96
+ return list;
97
+ };
@@ -0,0 +1,15 @@
1
+ import { ReactivesearchResultProps } from "../types/reactivesearch";
2
+ export declare const usePaginationLoadMore: (input: ReactivesearchResultProps) => {
3
+ loading: boolean;
4
+ hasMore: boolean;
5
+ handleLoadMore: () => void;
6
+ resultStats: {
7
+ time: number;
8
+ hidden: number;
9
+ promoted: number;
10
+ currentPage: number;
11
+ numberOfPages: number;
12
+ numberOfResults?: number;
13
+ displayedResults: number;
14
+ };
15
+ };
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.usePaginationLoadMore = void 0;
7
+ const react_1 = __importDefault(require("react"));
8
+ const hooks_1 = require("../hooks");
9
+ const usePaginationLoadMore = (input) => {
10
+ const analyticsHook = (0, hooks_1.useAnalytics)();
11
+ const filterStack = (0, hooks_1.useFilterStack)();
12
+ const hasMore = input.resultStats.displayedResults !== input.resultStats.numberOfResults;
13
+ const handleLoadMore = react_1.default.useCallback(() => {
14
+ input.loadMore();
15
+ analyticsHook.track({
16
+ eventName: "paginationChange",
17
+ payload: {
18
+ page: Math.ceil(input.resultStats.displayedResults / ((filterStack === null || filterStack === void 0 ? void 0 : filterStack.pageSize) || 20)) + 1,
19
+ source: window.location.pathname.includes("/search")
20
+ ? "search"
21
+ : "collection",
22
+ },
23
+ });
24
+ }, [input.loadMore, analyticsHook.track, input.resultStats, filterStack]);
25
+ return react_1.default.useMemo(() => ({
26
+ loading: input.loading,
27
+ hasMore,
28
+ handleLoadMore,
29
+ resultStats: input.resultStats,
30
+ }), [
31
+ input.loading,
32
+ hasMore,
33
+ handleLoadMore,
34
+ input.resultStats,
35
+ ]);
36
+ };
37
+ exports.usePaginationLoadMore = usePaginationLoadMore;
@@ -0,0 +1,10 @@
1
+ import currency from "currency.js";
2
+ import { ElasticProduct } from "../types/elastic";
3
+ export declare const useProductPrice: (product: ElasticProduct) => {
4
+ price?: currency;
5
+ onSale: boolean;
6
+ currencyCode: string;
7
+ compareAtPrice?: currency;
8
+ formattedPrice?: string;
9
+ formattedCompareAtPrice?: string;
10
+ };
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.useProductPrice = void 0;
7
+ const react_1 = __importDefault(require("react"));
8
+ const currency_js_1 = __importDefault(require("currency.js"));
9
+ const useProductPrice = (product) => {
10
+ return react_1.default.useMemo(() => {
11
+ var _a, _b, _c, _d;
12
+ const variant = (_a = product.variants) === null || _a === void 0 ? void 0 : _a[0];
13
+ if (!variant) {
14
+ return {
15
+ onSale: false,
16
+ price: undefined,
17
+ currencyCode: "AUD",
18
+ compareAtPrice: undefined,
19
+ };
20
+ }
21
+ // @todo select the appropriate currency
22
+ const priceSet = (_b = variant.presentment_prices) === null || _b === void 0 ? void 0 : _b[0];
23
+ if (!priceSet || !priceSet.price) {
24
+ return {
25
+ onSale: false,
26
+ price: undefined,
27
+ currencyCode: "AUD",
28
+ compareAtPrice: undefined,
29
+ };
30
+ }
31
+ const currencyCode = (_c = priceSet.price.currency_code) !== null && _c !== void 0 ? _c : "AUD";
32
+ const price = priceSet.price.amount
33
+ ? (0, currency_js_1.default)(priceSet.price.amount)
34
+ : undefined;
35
+ const formattedPrice = price ? formatPrice(price, currencyCode) : undefined;
36
+ const compareAtPrice = ((_d = priceSet.compare_at_price) === null || _d === void 0 ? void 0 : _d.amount)
37
+ ? (0, currency_js_1.default)(priceSet.compare_at_price.amount)
38
+ : undefined;
39
+ const formattedCompareAtPrice = compareAtPrice
40
+ ? formatPrice(compareAtPrice, currencyCode)
41
+ : undefined;
42
+ const onSale = !!compareAtPrice && !!price && compareAtPrice.intValue > price.intValue;
43
+ return {
44
+ price,
45
+ onSale,
46
+ currencyCode,
47
+ compareAtPrice,
48
+ formattedPrice,
49
+ formattedCompareAtPrice,
50
+ };
51
+ }, [product]);
52
+ };
53
+ exports.useProductPrice = useProductPrice;
54
+ const formatPrice = (price, currencyCode) => {
55
+ let priceString = new Intl.NumberFormat("en-AU", {
56
+ style: "currency",
57
+ currency: currencyCode,
58
+ }).format(price.value);
59
+ if ("AUD" === currencyCode) {
60
+ priceString = `AU ${priceString}`;
61
+ }
62
+ return priceString;
63
+ };
@@ -0,0 +1,78 @@
1
+ import React from "react";
2
+ import { Config } from "../types";
3
+ export declare const ReactifySearchContext: React.Context<{
4
+ config: Config;
5
+ options: {
6
+ mode: "search" | "collection" | "instant-search";
7
+ index: string;
8
+ shopifyPermanentDomain: string;
9
+ filterStackHandle?: string | undefined;
10
+ credentials: {
11
+ username: string;
12
+ password: string;
13
+ endpoint: string;
14
+ };
15
+ onRedirect?: ((type: "redirect" | "search", url: string) => void) | undefined;
16
+ theme: Record<string, unknown>;
17
+ additionalComponentHandles?: string[] | undefined;
18
+ } & ({
19
+ mode: "search";
20
+ } | {
21
+ mode: "collection";
22
+ collection: {
23
+ id: number;
24
+ handle: string;
25
+ title: string;
26
+ };
27
+ } | {
28
+ mode: "instant-search";
29
+ });
30
+ search: {
31
+ searchQuery: string;
32
+ setSearchQuery: React.Dispatch<React.SetStateAction<string>>;
33
+ instantSearchVisible: boolean;
34
+ setInstantSearchVisible: React.Dispatch<React.SetStateAction<boolean>>;
35
+ };
36
+ sortby: {
37
+ sortOption: string;
38
+ setSortOption: React.Dispatch<React.SetStateAction<string>>;
39
+ };
40
+ } | undefined>;
41
+ export declare const useReactifySearchContext: () => {
42
+ config: Config;
43
+ options: {
44
+ mode: "search" | "collection" | "instant-search";
45
+ index: string;
46
+ shopifyPermanentDomain: string;
47
+ filterStackHandle?: string | undefined;
48
+ credentials: {
49
+ username: string;
50
+ password: string;
51
+ endpoint: string;
52
+ };
53
+ onRedirect?: ((type: "redirect" | "search", url: string) => void) | undefined;
54
+ theme: Record<string, unknown>;
55
+ additionalComponentHandles?: string[] | undefined;
56
+ } & ({
57
+ mode: "search";
58
+ } | {
59
+ mode: "collection";
60
+ collection: {
61
+ id: number;
62
+ handle: string;
63
+ title: string;
64
+ };
65
+ } | {
66
+ mode: "instant-search";
67
+ });
68
+ search: {
69
+ searchQuery: string;
70
+ setSearchQuery: React.Dispatch<React.SetStateAction<string>>;
71
+ instantSearchVisible: boolean;
72
+ setInstantSearchVisible: React.Dispatch<React.SetStateAction<boolean>>;
73
+ };
74
+ sortby: {
75
+ sortOption: string;
76
+ setSortOption: React.Dispatch<React.SetStateAction<string>>;
77
+ };
78
+ };
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.useReactifySearchContext = exports.ReactifySearchContext = void 0;
7
+ const react_1 = __importDefault(require("react"));
8
+ exports.ReactifySearchContext = react_1.default.createContext(undefined);
9
+ const useReactifySearchContext = () => react_1.default.useContext(exports.ReactifySearchContext);
10
+ exports.useReactifySearchContext = useReactifySearchContext;
@@ -0,0 +1,8 @@
1
+ import React from "react";
2
+ export declare const useSearch: () => {
3
+ searchQuery: string;
4
+ setSearchQuery: React.Dispatch<React.SetStateAction<string>>;
5
+ submitSearch: (localSearchQuery?: string | undefined) => void;
6
+ showInstantSearchResults: boolean;
7
+ setShowInstantSearchResults: React.Dispatch<React.SetStateAction<boolean>>;
8
+ };
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.useSearch = void 0;
7
+ const react_1 = __importDefault(require("react"));
8
+ const hooks_1 = require("../hooks");
9
+ const useSearch = () => {
10
+ const { options, config, search } = (0, hooks_1.useReactifySearchContext)();
11
+ const handleSubmitSearch = react_1.default.useCallback((localSearchQuery) => {
12
+ const actualSearchQuery = localSearchQuery !== null && localSearchQuery !== void 0 ? localSearchQuery : search.searchQuery;
13
+ if (!actualSearchQuery)
14
+ return;
15
+ const redirect = config.redirects.find((redirect) => redirect.query.trim().toLowerCase() ===
16
+ actualSearchQuery.trim().toLowerCase());
17
+ search.setInstantSearchVisible(false);
18
+ if (options.onRedirect) {
19
+ options.onRedirect(redirect ? "redirect" : "search", redirect ? redirect.url : `/search?q=${actualSearchQuery}`);
20
+ }
21
+ else if (redirect) {
22
+ window.location.href = redirect.url;
23
+ }
24
+ else {
25
+ window.location.href = `/search?q=${actualSearchQuery}`;
26
+ }
27
+ }, [search.searchQuery]);
28
+ return {
29
+ searchQuery: search.searchQuery,
30
+ setSearchQuery: search.setSearchQuery,
31
+ submitSearch: handleSubmitSearch,
32
+ showInstantSearchResults: !!search.instantSearchVisible && !!search.searchQuery,
33
+ setShowInstantSearchResults: search.setInstantSearchVisible,
34
+ };
35
+ };
36
+ exports.useSearch = useSearch;
@@ -0,0 +1,6 @@
1
+ import { ConfigSort } from "../types";
2
+ export declare const useSortby: () => {
3
+ sortOption: ConfigSort | undefined;
4
+ sortOptions: Array<ConfigSort>;
5
+ setSortOption: (sortOptionHandle: string, ignoreHistoryState?: boolean | undefined) => void;
6
+ };
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.useSortby = void 0;
7
+ const react_1 = __importDefault(require("react"));
8
+ const hooks_1 = require("../hooks");
9
+ const useSortby = () => {
10
+ const { options, config, sortby } = (0, hooks_1.useReactifySearchContext)();
11
+ const { track } = (0, hooks_1.useAnalytics)();
12
+ const sortOptions = react_1.default.useMemo(() => {
13
+ return config.sort
14
+ .sort((a, b) => `${a.position}`.localeCompare(`${b.position}`))
15
+ .filter(({ visibility }) => ["all", options.mode].includes(visibility));
16
+ }, [options.mode, config]);
17
+ const sortOption = react_1.default.useMemo(() => sortOptions.find(({ handle }) => handle === sortby.sortOption) ||
18
+ sortOptions[0], [sortOptions, sortby.sortOption]);
19
+ const setSortOption = react_1.default.useCallback((sortOptionHandle, ignoreHistoryState = false) => {
20
+ sortby.setSortOption(sortOptionHandle);
21
+ if (!ignoreHistoryState) {
22
+ const url = new URL(window.location.href);
23
+ url.searchParams.has("sort")
24
+ ? url.searchParams.set("sort", sortOptionHandle)
25
+ : url.searchParams.append("sort", sortOptionHandle);
26
+ window.history.pushState({}, "", url.toString());
27
+ }
28
+ track({
29
+ eventName: "sortChange",
30
+ payload: {
31
+ type: sortOptionHandle,
32
+ },
33
+ });
34
+ }, [window.location.href]);
35
+ return {
36
+ sortOptions,
37
+ sortOption,
38
+ setSortOption,
39
+ };
40
+ };
41
+ exports.useSortby = useSortby;
@@ -0,0 +1,3 @@
1
+ export * from "./components";
2
+ export * from "./hooks";
3
+ export * from "./types";
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
10
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
11
+ };
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ __exportStar(require("./components"), exports);
14
+ __exportStar(require("./hooks"), exports);
15
+ __exportStar(require("./types"), exports);
16
+ const package_json_1 = require("../package.json");
17
+ const debug = require("debug")("reactify-search:");
18
+ debug(`${package_json_1.name} v${package_json_1.version}`);
@@ -0,0 +1,26 @@
1
+ import { Sort, Filter, FilterOption, Redirect, Field, Curation } from "./firestore";
2
+ export interface Config {
3
+ index: string;
4
+ sort: ConfigSort[];
5
+ fields: ConfigField[];
6
+ filters: ConfigFilter[];
7
+ redirects: ConfigRedirect[];
8
+ curations: ConfigCuration[];
9
+ }
10
+ export declare type ConfigSort = Omit<Sort, "enabled">;
11
+ export declare type ConfigField = Omit<Field, "enabled">;
12
+ export declare type ConfigRedirect = Omit<Redirect, "enabled" | "keywords">;
13
+ export declare type ConfigFilter = Omit<Filter, "enabled" | "keywords"> & {
14
+ options: Omit<FilterOption, "enabled">[];
15
+ };
16
+ export declare type ConfigFilterOption = Omit<FilterOption, "enabled">;
17
+ export declare type ConfigCuration = Omit<Curation, "keywords" | "boosting" | "longRunningTask" | "callouts"> & {
18
+ boosting: {
19
+ groupings: (NonNullable<NonNullable<Curation["boosting"]>["groupings"]>[0] & {
20
+ query: string;
21
+ })[];
22
+ sortings: (NonNullable<NonNullable<Curation["boosting"]>["sortings"]>[0] & {
23
+ query: string;
24
+ })[];
25
+ };
26
+ };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,209 @@
1
+ import { Callout } from "./firestore";
2
+ import { Maybe, ProductVariantInventoryPolicy, MetafieldValueType } from "./graphql";
3
+ export declare enum ElasticDocumentType {
4
+ Callout = "callout",
5
+ Product = "product"
6
+ }
7
+ export declare type ElasticDocument = ElasticCallout | ElasticProduct;
8
+ export interface ElasticCallout {
9
+ type: ElasticDocumentType.Callout;
10
+ key: string;
11
+ callout: Omit<Callout, "keywords">;
12
+ /** elastic callouts are always published */
13
+ published: true;
14
+ /** elastic callouts are always attached to one curation */
15
+ curations: [ElasticCuration];
16
+ }
17
+ export interface ElasticProduct {
18
+ type: ElasticDocumentType.Product;
19
+ /** the log id from which this product was last uploaded */
20
+ lastLogId: string;
21
+ /** legacy resource id */
22
+ id: number;
23
+ storefrontId: string;
24
+ title: string;
25
+ description: string;
26
+ vendor: string;
27
+ product_type: string;
28
+ handle: string;
29
+ url: string;
30
+ tags: string[];
31
+ collection_titles: string[];
32
+ /** tag prefixes defined in tagKeys are split to their own attributes */
33
+ [key: `tags_${string}`]: string[] | undefined;
34
+ /** decimal number e.g. 99.95 */
35
+ price_min: number;
36
+ /** decimal number e.g. 99.95 */
37
+ price_max: number;
38
+ /** array of option names e.g. ["Colour", "Size"] */
39
+ options: string[];
40
+ /** @todo it would be better to use ProductStatus directly, which has uppercase */
41
+ status: "active" | "archived" | "draft";
42
+ published: boolean;
43
+ /** ISO 8601 datetime */
44
+ published_at: Maybe<string>;
45
+ /** ISO 8601 datetime */
46
+ updated_at: string;
47
+ /** ISO 8601 datetime */
48
+ created_at: string;
49
+ tracks_inventory: boolean;
50
+ /** originalSrc URL for featured image */
51
+ image: Maybe<string>;
52
+ /** array of images (undefined if images are disabled in sync settings) */
53
+ images?: ElasticImage[];
54
+ /** array of variants attached to product (undefined if variants are disabled in sync settings) */
55
+ variants?: ElasticVariant[];
56
+ /** price ranges from presentment prices (undefined if presentment prices or variants are disabled in sync settings) */
57
+ presentment_price_ranges?: {
58
+ min_variant_price: ElasticPresentmentPrice[];
59
+ max_variant_price: ElasticPresentmentPrice[];
60
+ };
61
+ /** array of variant skus (undefined if variants are disabled in sync settings) */
62
+ variant_skus?: string[];
63
+ /** combined array of option values from all option types (undefined if variants are disabled in sync settings) */
64
+ variant_options?: string[];
65
+ /** array of collections which this product belongs to (undefined if collections are disabled in sync settings) */
66
+ collections?: ElasticCollection[];
67
+ /** array of whitelisted metafields (undefined if metafields are disabled in sync settings) */
68
+ metafields?: ElasticMetafield[];
69
+ /** decimal number e.g. 99.95 (undefined if variants are disabled in sync settings) */
70
+ discount_amount?: number;
71
+ /** combined inventory for all variants (undefined if variants are disabled in sync settings) */
72
+ inventory_total?: number;
73
+ /** number of days since published, null if unpublished */
74
+ published_days: Maybe<number>;
75
+ /** collection of curations that this product is attached to */
76
+ curations?: ElasticCuration[];
77
+ }
78
+ export interface ElasticVariant {
79
+ /** legacy resource id */
80
+ id: number;
81
+ storefrontId: string;
82
+ title: string;
83
+ sku: Maybe<string>;
84
+ barcode: Maybe<string>;
85
+ /** array of presentment prices (undefined if presentment prices are disabled in sync settings) */
86
+ presentment_prices?: {
87
+ price: ElasticPresentmentPrice;
88
+ compare_at_price: Maybe<ElasticPresentmentPrice>;
89
+ }[];
90
+ /** decimal number e.g. 99.95 */
91
+ price: number;
92
+ /** decimal number e.g. 99.95 */
93
+ compare_at_price: Maybe<number>;
94
+ /** value string for option 1 e.g. Blue */
95
+ option1: Maybe<string>;
96
+ /** value string for option 2 e.g. Medium */
97
+ option2: Maybe<string>;
98
+ /** value string for option 3 */
99
+ option3: Maybe<string>;
100
+ /** sort position within the product */
101
+ position: number;
102
+ inventory_policy: ProductVariantInventoryPolicy;
103
+ inventory_quantity: number;
104
+ available: boolean;
105
+ /** array of images (only available if this variant has been merged from another product and if images are enabled in sync settings) */
106
+ images?: ElasticImage[];
107
+ }
108
+ export interface ElasticCollection {
109
+ /** legacy resource id */
110
+ id: number;
111
+ storefrontId: string;
112
+ handle: string;
113
+ title: string;
114
+ position: number;
115
+ }
116
+ export interface ElasticMetafield {
117
+ key: string;
118
+ type: string;
119
+ value: string;
120
+ namespace: string;
121
+ /**
122
+ * Legacy valueType attribute which is no longer provided by Shopify. We still
123
+ * populate this field to prevent any frontends breaking which rely on it.
124
+ *
125
+ * @see https://shopify.dev/apps/metafields/definitions/types
126
+ */
127
+ value_type: MetafieldValueType;
128
+ }
129
+ export interface ElasticPresentmentPrice {
130
+ /** decimal number e.g. 99.95 */
131
+ amount: number;
132
+ currency_code: string;
133
+ }
134
+ export interface ElasticImage {
135
+ /** originalSrc URL */
136
+ src: string;
137
+ /** alt text */
138
+ alt: Maybe<string>;
139
+ }
140
+ export interface ElasticCuration {
141
+ id: string;
142
+ hidden: boolean;
143
+ position?: number;
144
+ searchTerm?: string;
145
+ collectionHandle?: string;
146
+ }
147
+ export declare type ElasticBulkOperationUpdate = [
148
+ {
149
+ update: {
150
+ _index: string;
151
+ _id: string;
152
+ };
153
+ },
154
+ {
155
+ script?: {
156
+ lang: "painless";
157
+ source: string;
158
+ params?: Record<string, any>;
159
+ };
160
+ upsert?: Partial<ElasticProduct>;
161
+ scripted_upsert?: true;
162
+ doc?: Partial<ElasticProduct>;
163
+ doc_as_upsert?: true;
164
+ }
165
+ ];
166
+ export declare type ElasticBulkOperationIndex = [
167
+ {
168
+ index: {
169
+ _index: string;
170
+ _id: string;
171
+ };
172
+ },
173
+ ElasticDocument
174
+ ];
175
+ export declare type ElasticBulkOperation = ElasticBulkOperationUpdate | ElasticBulkOperationIndex;
176
+ export declare type ElasticSearchResult<T = ElasticDocument> = {
177
+ hits: {
178
+ hits: ElasticHit<T>[];
179
+ };
180
+ };
181
+ export declare type ElasticHit<T = ElasticDocument> = {
182
+ _id: string;
183
+ _source: T;
184
+ _score: number | null;
185
+ };
186
+ export declare enum ElasticDataType {
187
+ Text = "text",
188
+ Long = "long",
189
+ Date = "date",
190
+ Float = "float",
191
+ Nested = "nested",
192
+ Keyword = "keyword",
193
+ Boolean = "boolean"
194
+ }
195
+ export interface ElasticProperty {
196
+ analyzer?: string;
197
+ type: ElasticDataType;
198
+ ignore_above?: number;
199
+ fields?: {
200
+ [key: string]: ElasticField;
201
+ };
202
+ properties?: {
203
+ [key: string]: ElasticProperty;
204
+ };
205
+ }
206
+ export interface ElasticField {
207
+ type: ElasticDataType;
208
+ ignore_above?: number;
209
+ }