@constructor-io/constructorio-ui-autocomplete 1.22.1 → 1.23.0
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/dist/constructorio-ui-autocomplete-bundled.js +11 -11
- package/lib/cjs/constants.js +2 -1
- package/lib/cjs/hooks/useCioAutocomplete.js +9 -2
- package/lib/cjs/hooks/useFetchRecommendationPod.js +33 -31
- package/lib/cjs/hooks/useRecommendationsObserver.js +9 -1
- package/lib/cjs/hooks/useSections.js +2 -1
- package/lib/cjs/version.js +1 -1
- package/lib/mjs/constants.js +1 -0
- package/lib/mjs/hooks/useCioAutocomplete.js +9 -2
- package/lib/mjs/hooks/useFetchRecommendationPod.js +36 -34
- package/lib/mjs/hooks/useRecommendationsObserver.js +9 -1
- package/lib/mjs/hooks/useSections.js +2 -1
- package/lib/mjs/version.js +1 -1
- package/lib/types/constants.d.ts +1 -0
- package/lib/types/hooks/useFetchRecommendationPod.d.ts +2 -1
- package/lib/types/hooks/useSections.d.ts +1 -0
- package/lib/types/types.d.ts +1 -0
- package/lib/types/version.d.ts +1 -1
- package/package.json +1 -1
package/lib/cjs/constants.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.translationsDescription = exports.debounceDescription = exports.termsWithImagesAndCountsDescription = exports.filteredSuggestionsDescription = exports.termsWithGroupSuggestionsDescription = exports.advancedParametersDefaultDescription = exports.advancedParametersDescription = exports.customStylesDescription = exports.multipleSectionsDescription = exports.openOnFocusDescription = exports.zeroStateSectionsDescription = exports.onSubmitDefault = exports.onSubmitDescription = exports.onChangeDescription = exports.onFocusDescription = exports.customSectionDescription = exports.displaySearchTermHighlightsDescription = exports.recommendationsDescription = exports.sectionOrderDescription = exports.numResultsDescription = exports.contentDescription = exports.productsDescription = exports.searchSuggestionsDescription = exports.placeholderDescription = exports.cioJsClientOptionsDescription = exports.cioJsClientDescription = exports.apiKeyDescription = exports.fullFeaturedAndStyledExampleDescription = exports.zeroStateDescription = exports.userEventsDescription = exports.sectionsDescription = exports.hookDescription = exports.componentDescription = exports.apiKey = void 0;
|
|
3
|
+
exports.translationsDescription = exports.fetchZeroStateOnFocusDescription = exports.debounceDescription = exports.termsWithImagesAndCountsDescription = exports.filteredSuggestionsDescription = exports.termsWithGroupSuggestionsDescription = exports.advancedParametersDefaultDescription = exports.advancedParametersDescription = exports.customStylesDescription = exports.multipleSectionsDescription = exports.openOnFocusDescription = exports.zeroStateSectionsDescription = exports.onSubmitDefault = exports.onSubmitDescription = exports.onChangeDescription = exports.onFocusDescription = exports.customSectionDescription = exports.displaySearchTermHighlightsDescription = exports.recommendationsDescription = exports.sectionOrderDescription = exports.numResultsDescription = exports.contentDescription = exports.productsDescription = exports.searchSuggestionsDescription = exports.placeholderDescription = exports.cioJsClientOptionsDescription = exports.cioJsClientDescription = exports.apiKeyDescription = exports.fullFeaturedAndStyledExampleDescription = exports.zeroStateDescription = exports.userEventsDescription = exports.sectionsDescription = exports.hookDescription = exports.componentDescription = exports.apiKey = void 0;
|
|
4
4
|
// Autocomplete key index
|
|
5
5
|
exports.apiKey = 'key_M57QS8SMPdLdLx4x';
|
|
6
6
|
/// //////////////////////////////
|
|
@@ -228,6 +228,7 @@ To see this in action:
|
|
|
228
228
|
- This is because we are filtering to the "Shirts" group`;
|
|
229
229
|
exports.termsWithImagesAndCountsDescription = `Pass boolean flags for \`displaySearchSuggestionImages\` and \`displaySearchSuggestionResultCounts\` fields to display images and counts for search suggestions. These fields need to be made displayable before they can be used. Please contact your Constructor Integration Engineer for details.`;
|
|
230
230
|
exports.debounceDescription = `Pass an integer to \`debounce\` to override the recommended, default delay employed for debouncing autocomplete network requests between keystrokes as your users type into the text input field. The default value is 250, which results in a debounce delay of 250 milliseconds.`;
|
|
231
|
+
exports.fetchZeroStateOnFocusDescription = `Pass a boolean to \`fetchZeroStateOnFocus\` to override the zero state fetching behavior from initial render to input focus.`;
|
|
231
232
|
exports.translationsDescription = `Pass a \`translations\` object to display translatable words in your preferred language.
|
|
232
233
|
|
|
233
234
|
- Current translatable keys:
|
|
@@ -57,7 +57,7 @@ const useCioAutocomplete = (options) => {
|
|
|
57
57
|
const previousQuery = (0, usePrevious_1.default)(query);
|
|
58
58
|
const cioClient = (0, useCioClient_1.default)({ apiKey, cioJsClient, cioJsClientOptions });
|
|
59
59
|
// Get autocomplete sections (autocomplete + recommendations + custom)
|
|
60
|
-
const { activeSections, activeSectionsWithData, zeroStateActiveSections, request, totalNumResultsPerSection, } = (0, useSections_1.default)(query, cioClient, sections, zeroStateSections, advancedParameters);
|
|
60
|
+
const { fetchRecommendationResults, activeSections, activeSectionsWithData, zeroStateActiveSections, request, totalNumResultsPerSection, } = (0, useSections_1.default)(query, cioClient, sections, zeroStateSections, advancedParameters);
|
|
61
61
|
const features = (0, react_1.useMemo)(() => (0, utils_1.getFeatures)(request), [request]);
|
|
62
62
|
// Get dropdown items array from active sections (autocomplete + recommendations + custom)
|
|
63
63
|
const items = (0, react_1.useMemo)(() => (0, utils_1.getItemsForActiveSections)(activeSectionsWithData), [activeSectionsWithData]);
|
|
@@ -105,13 +105,16 @@ const useCioAutocomplete = (options) => {
|
|
|
105
105
|
openMenu();
|
|
106
106
|
}
|
|
107
107
|
try {
|
|
108
|
+
if ((advancedParameters === null || advancedParameters === void 0 ? void 0 : advancedParameters.fetchZeroStateOnFocus) && (items === null || items === void 0 ? void 0 : items.length) === 0) {
|
|
109
|
+
fetchRecommendationResults();
|
|
110
|
+
}
|
|
108
111
|
(_a = cioClient === null || cioClient === void 0 ? void 0 : cioClient.tracker) === null || _a === void 0 ? void 0 : _a.trackInputFocus();
|
|
109
112
|
}
|
|
110
113
|
catch (error) {
|
|
111
114
|
// eslint-disable-next-line no-console
|
|
112
115
|
console.log(error);
|
|
113
116
|
}
|
|
114
|
-
}, className: 'cio-input', 'data-testid': 'cio-input', placeholder, onKeyDownCapture: ({ code, key }) => {
|
|
117
|
+
}, className: 'cio-input', 'data-testid': 'cio-input', placeholder, onKeyDownCapture: ({ code, key, nativeEvent }) => {
|
|
115
118
|
const isEnter = code === 'Enter' || key === 'Enter';
|
|
116
119
|
const isUserInput = highlightedIndex < 0;
|
|
117
120
|
if (isOpen && isEnter && isUserInput && (query === null || query === void 0 ? void 0 : query.length)) {
|
|
@@ -126,6 +129,10 @@ const useCioAutocomplete = (options) => {
|
|
|
126
129
|
console.log(error);
|
|
127
130
|
}
|
|
128
131
|
}
|
|
132
|
+
if (code === 'Home' || code === 'End') {
|
|
133
|
+
// eslint-disable-next-line no-param-reassign
|
|
134
|
+
nativeEvent.preventDownshiftDefault = true;
|
|
135
|
+
}
|
|
129
136
|
} })),
|
|
130
137
|
getFormProps: () => ({
|
|
131
138
|
onSubmit: (event) => {
|
|
@@ -2,45 +2,47 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const tslib_1 = require("tslib");
|
|
4
4
|
const react_1 = require("react");
|
|
5
|
-
const useFetchRecommendationPod = (cioClient, recommendationPods) => {
|
|
5
|
+
const useFetchRecommendationPod = (cioClient, recommendationPods, fetchZeroStateOnFocus = false) => {
|
|
6
6
|
const [recommendationsResults, setRecommendationsResults] = (0, react_1.useState)({});
|
|
7
7
|
const [podsData, setPodsData] = (0, react_1.useState)({});
|
|
8
|
-
(0,
|
|
8
|
+
const fetchRecommendationResults = () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
|
|
9
9
|
if (!cioClient || !Array.isArray(recommendationPods) || recommendationPods.length === 0)
|
|
10
10
|
return;
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
});
|
|
32
|
-
try {
|
|
33
|
-
setRecommendationsResults(recommendationsPodResults);
|
|
34
|
-
setPodsData(recommendationsPodsData);
|
|
35
|
-
}
|
|
36
|
-
catch (error) {
|
|
37
|
-
// eslint-disable-next-line no-console
|
|
38
|
-
console.log(error);
|
|
11
|
+
const responses = yield Promise.all(recommendationPods.map((_a) => {
|
|
12
|
+
var { podId, indexSectionName } = _a, parameters = tslib_1.__rest(_a, ["podId", "indexSectionName"]);
|
|
13
|
+
return cioClient.recommendations.getRecommendations(podId, Object.assign(Object.assign({}, parameters), { section: indexSectionName }));
|
|
14
|
+
}));
|
|
15
|
+
const recommendationsPodResults = {};
|
|
16
|
+
const recommendationsPodsData = {};
|
|
17
|
+
responses.forEach(({ response, request }, index) => {
|
|
18
|
+
const { pod, results } = response;
|
|
19
|
+
if (pod === null || pod === void 0 ? void 0 : pod.id) {
|
|
20
|
+
recommendationsPodResults[pod.id] = results === null || results === void 0 ? void 0 : results.map((item) => {
|
|
21
|
+
var _a, _b;
|
|
22
|
+
return (Object.assign(Object.assign({}, item), { id: (_a = item === null || item === void 0 ? void 0 : item.data) === null || _a === void 0 ? void 0 : _a.id, section: (_b = recommendationPods[index]) === null || _b === void 0 ? void 0 : _b.indexSectionName, podId: pod.id }));
|
|
23
|
+
});
|
|
24
|
+
recommendationsPodsData[pod.id] = {
|
|
25
|
+
displayName: pod.display_name,
|
|
26
|
+
podId: pod.id,
|
|
27
|
+
request,
|
|
28
|
+
};
|
|
39
29
|
}
|
|
40
30
|
});
|
|
31
|
+
try {
|
|
32
|
+
setRecommendationsResults(recommendationsPodResults);
|
|
33
|
+
setPodsData(recommendationsPodsData);
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
// eslint-disable-next-line no-console
|
|
37
|
+
console.log(error);
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
(0, react_1.useEffect)(() => {
|
|
41
|
+
if (fetchZeroStateOnFocus)
|
|
42
|
+
return;
|
|
41
43
|
fetchRecommendationResults();
|
|
42
44
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
43
45
|
}, [cioClient]);
|
|
44
|
-
return { recommendationsResults, podsData };
|
|
46
|
+
return { fetchRecommendationResults, recommendationsResults, podsData };
|
|
45
47
|
};
|
|
46
48
|
exports.default = useFetchRecommendationPod;
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const react_1 = require("react");
|
|
4
4
|
const typeGuards_1 = require("../typeGuards");
|
|
5
|
+
const viewedRecommendations = new Set();
|
|
5
6
|
/**
|
|
6
7
|
* Custom hook that observes the visibility of recommendation sections and calls trackRecommendationView event.
|
|
7
8
|
* This is done by using the IntersectionObserver API to observe the visibility of each recommendation section.
|
|
@@ -29,8 +30,9 @@ function useRecommendationsObserver(menuIsOpen, sections, constructorIO, trackRe
|
|
|
29
30
|
const observer = new IntersectionObserver((entries) => {
|
|
30
31
|
// For each section, check if it's intersecting
|
|
31
32
|
entries.forEach((entry) => {
|
|
32
|
-
if (entry.isIntersecting) {
|
|
33
|
+
if (entry.isIntersecting && !viewedRecommendations.has(entry.target)) {
|
|
33
34
|
trackRecommendationView(entry.target, sections, constructorIO);
|
|
35
|
+
viewedRecommendations.add(entry.target);
|
|
34
36
|
}
|
|
35
37
|
});
|
|
36
38
|
}, intersectionObserverOptions);
|
|
@@ -49,6 +51,12 @@ function useRecommendationsObserver(menuIsOpen, sections, constructorIO, trackRe
|
|
|
49
51
|
});
|
|
50
52
|
};
|
|
51
53
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
54
|
+
}, [menuIsOpen, sections]);
|
|
55
|
+
// clear viewed recommendations when menu is closed
|
|
56
|
+
(0, react_1.useEffect)(() => {
|
|
57
|
+
if (!menuIsOpen) {
|
|
58
|
+
viewedRecommendations.clear();
|
|
59
|
+
}
|
|
52
60
|
}, [menuIsOpen]);
|
|
53
61
|
}
|
|
54
62
|
exports.default = useRecommendationsObserver;
|
|
@@ -18,7 +18,7 @@ function useSections(query, cioClient, sections, zeroStateSections, advancedPara
|
|
|
18
18
|
// Fetch Autocomplete Results
|
|
19
19
|
const { sectionsData: autocompleteResults, request, totalNumResultsPerSection, } = (0, useDebouncedFetchSections_1.default)(query, cioClient, autocompleteSections, advancedParameters);
|
|
20
20
|
// Fetch Recommendations Results
|
|
21
|
-
const { recommendationsResults, podsData } = (0, useFetchRecommendationPod_1.default)(cioClient, recommendationsSections);
|
|
21
|
+
const { fetchRecommendationResults, recommendationsResults, podsData } = (0, useFetchRecommendationPod_1.default)(cioClient, recommendationsSections, advancedParameters === null || advancedParameters === void 0 ? void 0 : advancedParameters.fetchZeroStateOnFocus);
|
|
22
22
|
// Remove sections if necessary
|
|
23
23
|
(0, react_1.useEffect)(() => {
|
|
24
24
|
var _a, _b;
|
|
@@ -52,6 +52,7 @@ function useSections(query, cioClient, sections, zeroStateSections, advancedPara
|
|
|
52
52
|
setActiveSectionsWithData((0, utils_1.getActiveSectionsWithData)(activeSectionConfigs, sectionsResults, sectionsRefs));
|
|
53
53
|
}, [autocompleteResults, recommendationsResults, activeSectionConfigs, podsData]);
|
|
54
54
|
return {
|
|
55
|
+
fetchRecommendationResults,
|
|
55
56
|
activeSections,
|
|
56
57
|
activeSectionsWithData,
|
|
57
58
|
zeroStateActiveSections,
|
package/lib/cjs/version.js
CHANGED
package/lib/mjs/constants.js
CHANGED
|
@@ -224,6 +224,7 @@ To see this in action:
|
|
|
224
224
|
- This is because we are filtering to the "Shirts" group`;
|
|
225
225
|
export const termsWithImagesAndCountsDescription = `Pass boolean flags for \`displaySearchSuggestionImages\` and \`displaySearchSuggestionResultCounts\` fields to display images and counts for search suggestions. These fields need to be made displayable before they can be used. Please contact your Constructor Integration Engineer for details.`;
|
|
226
226
|
export const debounceDescription = `Pass an integer to \`debounce\` to override the recommended, default delay employed for debouncing autocomplete network requests between keystrokes as your users type into the text input field. The default value is 250, which results in a debounce delay of 250 milliseconds.`;
|
|
227
|
+
export const fetchZeroStateOnFocusDescription = `Pass a boolean to \`fetchZeroStateOnFocus\` to override the zero state fetching behavior from initial render to input focus.`;
|
|
227
228
|
export const translationsDescription = `Pass a \`translations\` object to display translatable words in your preferred language.
|
|
228
229
|
|
|
229
230
|
- Current translatable keys:
|
|
@@ -53,7 +53,7 @@ const useCioAutocomplete = (options) => {
|
|
|
53
53
|
const previousQuery = usePrevious(query);
|
|
54
54
|
const cioClient = useCioClient({ apiKey, cioJsClient, cioJsClientOptions });
|
|
55
55
|
// Get autocomplete sections (autocomplete + recommendations + custom)
|
|
56
|
-
const { activeSections, activeSectionsWithData, zeroStateActiveSections, request, totalNumResultsPerSection, } = useSections(query, cioClient, sections, zeroStateSections, advancedParameters);
|
|
56
|
+
const { fetchRecommendationResults, activeSections, activeSectionsWithData, zeroStateActiveSections, request, totalNumResultsPerSection, } = useSections(query, cioClient, sections, zeroStateSections, advancedParameters);
|
|
57
57
|
const features = useMemo(() => getFeatures(request), [request]);
|
|
58
58
|
// Get dropdown items array from active sections (autocomplete + recommendations + custom)
|
|
59
59
|
const items = useMemo(() => getItemsForActiveSections(activeSectionsWithData), [activeSectionsWithData]);
|
|
@@ -110,6 +110,9 @@ const useCioAutocomplete = (options) => {
|
|
|
110
110
|
openMenu();
|
|
111
111
|
}
|
|
112
112
|
try {
|
|
113
|
+
if (advancedParameters?.fetchZeroStateOnFocus && items?.length === 0) {
|
|
114
|
+
fetchRecommendationResults();
|
|
115
|
+
}
|
|
113
116
|
cioClient?.tracker?.trackInputFocus();
|
|
114
117
|
}
|
|
115
118
|
catch (error) {
|
|
@@ -120,7 +123,7 @@ const useCioAutocomplete = (options) => {
|
|
|
120
123
|
className: 'cio-input',
|
|
121
124
|
'data-testid': 'cio-input',
|
|
122
125
|
placeholder,
|
|
123
|
-
onKeyDownCapture: ({ code, key }) => {
|
|
126
|
+
onKeyDownCapture: ({ code, key, nativeEvent }) => {
|
|
124
127
|
const isEnter = code === 'Enter' || key === 'Enter';
|
|
125
128
|
const isUserInput = highlightedIndex < 0;
|
|
126
129
|
if (isOpen && isEnter && isUserInput && query?.length) {
|
|
@@ -135,6 +138,10 @@ const useCioAutocomplete = (options) => {
|
|
|
135
138
|
console.log(error);
|
|
136
139
|
}
|
|
137
140
|
}
|
|
141
|
+
if (code === 'Home' || code === 'End') {
|
|
142
|
+
// eslint-disable-next-line no-param-reassign
|
|
143
|
+
nativeEvent.preventDownshiftDefault = true;
|
|
144
|
+
}
|
|
138
145
|
},
|
|
139
146
|
}),
|
|
140
147
|
getFormProps: () => ({
|
|
@@ -1,45 +1,47 @@
|
|
|
1
1
|
import { useEffect, useState } from 'react';
|
|
2
|
-
const useFetchRecommendationPod = (cioClient, recommendationPods) => {
|
|
2
|
+
const useFetchRecommendationPod = (cioClient, recommendationPods, fetchZeroStateOnFocus = false) => {
|
|
3
3
|
const [recommendationsResults, setRecommendationsResults] = useState({});
|
|
4
4
|
const [podsData, setPodsData] = useState({});
|
|
5
|
-
|
|
5
|
+
const fetchRecommendationResults = async () => {
|
|
6
6
|
if (!cioClient || !Array.isArray(recommendationPods) || recommendationPods.length === 0)
|
|
7
7
|
return;
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
});
|
|
31
|
-
try {
|
|
32
|
-
setRecommendationsResults(recommendationsPodResults);
|
|
33
|
-
setPodsData(recommendationsPodsData);
|
|
34
|
-
}
|
|
35
|
-
catch (error) {
|
|
36
|
-
// eslint-disable-next-line no-console
|
|
37
|
-
console.log(error);
|
|
8
|
+
const responses = await Promise.all(recommendationPods.map(({ podId, indexSectionName, ...parameters }) => cioClient.recommendations.getRecommendations(podId, {
|
|
9
|
+
...parameters,
|
|
10
|
+
section: indexSectionName,
|
|
11
|
+
})));
|
|
12
|
+
const recommendationsPodResults = {};
|
|
13
|
+
const recommendationsPodsData = {};
|
|
14
|
+
responses.forEach(({ response, request }, index) => {
|
|
15
|
+
const { pod, results } = response;
|
|
16
|
+
if (pod?.id) {
|
|
17
|
+
recommendationsPodResults[pod.id] = results?.map((item) => ({
|
|
18
|
+
...item,
|
|
19
|
+
id: item?.data?.id,
|
|
20
|
+
section: recommendationPods[index]?.indexSectionName,
|
|
21
|
+
podId: pod.id,
|
|
22
|
+
}));
|
|
23
|
+
recommendationsPodsData[pod.id] = {
|
|
24
|
+
displayName: pod.display_name,
|
|
25
|
+
podId: pod.id,
|
|
26
|
+
request,
|
|
27
|
+
};
|
|
38
28
|
}
|
|
39
|
-
};
|
|
29
|
+
});
|
|
30
|
+
try {
|
|
31
|
+
setRecommendationsResults(recommendationsPodResults);
|
|
32
|
+
setPodsData(recommendationsPodsData);
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
// eslint-disable-next-line no-console
|
|
36
|
+
console.log(error);
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
if (fetchZeroStateOnFocus)
|
|
41
|
+
return;
|
|
40
42
|
fetchRecommendationResults();
|
|
41
43
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
42
44
|
}, [cioClient]);
|
|
43
|
-
return { recommendationsResults, podsData };
|
|
45
|
+
return { fetchRecommendationResults, recommendationsResults, podsData };
|
|
44
46
|
};
|
|
45
47
|
export default useFetchRecommendationPod;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { useEffect } from 'react';
|
|
2
2
|
import { isRecommendationsSection } from '../typeGuards';
|
|
3
|
+
const viewedRecommendations = new Set();
|
|
3
4
|
/**
|
|
4
5
|
* Custom hook that observes the visibility of recommendation sections and calls trackRecommendationView event.
|
|
5
6
|
* This is done by using the IntersectionObserver API to observe the visibility of each recommendation section.
|
|
@@ -27,8 +28,9 @@ function useRecommendationsObserver(menuIsOpen, sections, constructorIO, trackRe
|
|
|
27
28
|
const observer = new IntersectionObserver((entries) => {
|
|
28
29
|
// For each section, check if it's intersecting
|
|
29
30
|
entries.forEach((entry) => {
|
|
30
|
-
if (entry.isIntersecting) {
|
|
31
|
+
if (entry.isIntersecting && !viewedRecommendations.has(entry.target)) {
|
|
31
32
|
trackRecommendationView(entry.target, sections, constructorIO);
|
|
33
|
+
viewedRecommendations.add(entry.target);
|
|
32
34
|
}
|
|
33
35
|
});
|
|
34
36
|
}, intersectionObserverOptions);
|
|
@@ -47,6 +49,12 @@ function useRecommendationsObserver(menuIsOpen, sections, constructorIO, trackRe
|
|
|
47
49
|
});
|
|
48
50
|
};
|
|
49
51
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
52
|
+
}, [menuIsOpen, sections]);
|
|
53
|
+
// clear viewed recommendations when menu is closed
|
|
54
|
+
useEffect(() => {
|
|
55
|
+
if (!menuIsOpen) {
|
|
56
|
+
viewedRecommendations.clear();
|
|
57
|
+
}
|
|
50
58
|
}, [menuIsOpen]);
|
|
51
59
|
}
|
|
52
60
|
export default useRecommendationsObserver;
|
|
@@ -15,7 +15,7 @@ export default function useSections(query, cioClient, sections, zeroStateSection
|
|
|
15
15
|
// Fetch Autocomplete Results
|
|
16
16
|
const { sectionsData: autocompleteResults, request, totalNumResultsPerSection, } = useDebouncedFetchSection(query, cioClient, autocompleteSections, advancedParameters);
|
|
17
17
|
// Fetch Recommendations Results
|
|
18
|
-
const { recommendationsResults, podsData } = useFetchRecommendationPod(cioClient, recommendationsSections);
|
|
18
|
+
const { fetchRecommendationResults, recommendationsResults, podsData } = useFetchRecommendationPod(cioClient, recommendationsSections, advancedParameters?.fetchZeroStateOnFocus);
|
|
19
19
|
// Remove sections if necessary
|
|
20
20
|
useEffect(() => {
|
|
21
21
|
const features = getFeatures(Object.values(podsData || {})?.[0]?.request);
|
|
@@ -48,6 +48,7 @@ export default function useSections(query, cioClient, sections, zeroStateSection
|
|
|
48
48
|
setActiveSectionsWithData(getActiveSectionsWithData(activeSectionConfigs, sectionsResults, sectionsRefs));
|
|
49
49
|
}, [autocompleteResults, recommendationsResults, activeSectionConfigs, podsData]);
|
|
50
50
|
return {
|
|
51
|
+
fetchRecommendationResults,
|
|
51
52
|
activeSections,
|
|
52
53
|
activeSectionsWithData,
|
|
53
54
|
zeroStateActiveSections,
|
package/lib/mjs/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export default '1.
|
|
1
|
+
export default '1.23.0';
|
package/lib/types/constants.d.ts
CHANGED
|
@@ -32,4 +32,5 @@ export declare const termsWithGroupSuggestionsDescription = "Pass integers for t
|
|
|
32
32
|
export declare const filteredSuggestionsDescription = "Pass a `filters` object under `advancedParameters` to apply filters to the suggestions. Any parameter supported by <a href=\"https://docs.constructor.io/rest_api/autocomplete_queries/\" target=\"__blank\">our autocomplete endpoint</a> can be passed under `advancedParameters`.\n\nTo see this in action:\n1. Type \"short\" in the example below.\n - Notice how the user is presented with only short pants as results.\n - This is because the results are currently filtered to belong to the \"Shorts\" group.\n2. Navigate to the \"Filtered Suggestions\" story (using the navigation menu to the left)\n3. Then use the Controls to adjust the values of `\"group_id\"` to `\"1030\"`.\n4. Next, type \"short\" in the example autocomplete input field.\n - Notice how the user is presented with only short sleeved items as results.\n - This is because we are filtering to the \"Shirts\" group";
|
|
33
33
|
export declare const termsWithImagesAndCountsDescription = "Pass boolean flags for `displaySearchSuggestionImages` and `displaySearchSuggestionResultCounts` fields to display images and counts for search suggestions. These fields need to be made displayable before they can be used. Please contact your Constructor Integration Engineer for details.";
|
|
34
34
|
export declare const debounceDescription = "Pass an integer to `debounce` to override the recommended, default delay employed for debouncing autocomplete network requests between keystrokes as your users type into the text input field. The default value is 250, which results in a debounce delay of 250 milliseconds.";
|
|
35
|
+
export declare const fetchZeroStateOnFocusDescription = "Pass a boolean to `fetchZeroStateOnFocus` to override the zero state fetching behavior from initial render to input focus.";
|
|
35
36
|
export declare const translationsDescription = "Pass a `translations` object to display translatable words in your preferred language.\n\n- Current translatable keys:\n```\n {\n \"in\": \"...\"\n }\n```\n";
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import ConstructorIOClient from '@constructor-io/constructorio-client-javascript';
|
|
2
2
|
import { Nullable } from '@constructor-io/constructorio-client-javascript/lib/types';
|
|
3
3
|
import { SectionsData, RecommendationsSectionConfiguration, PodData } from '../types';
|
|
4
|
-
declare const useFetchRecommendationPod: (cioClient: Nullable<ConstructorIOClient>, recommendationPods: RecommendationsSectionConfiguration[]) => {
|
|
4
|
+
declare const useFetchRecommendationPod: (cioClient: Nullable<ConstructorIOClient>, recommendationPods: RecommendationsSectionConfiguration[], fetchZeroStateOnFocus?: boolean) => {
|
|
5
|
+
fetchRecommendationResults: () => Promise<void>;
|
|
5
6
|
recommendationsResults: SectionsData;
|
|
6
7
|
podsData: Record<string, PodData>;
|
|
7
8
|
};
|
|
@@ -2,6 +2,7 @@ import ConstructorIO from '@constructor-io/constructorio-client-javascript';
|
|
|
2
2
|
import { Nullable } from '@constructor-io/constructorio-client-javascript/lib/types';
|
|
3
3
|
import { AdvancedParameters, UserDefinedSection, Section } from '../types';
|
|
4
4
|
export default function useSections(query: string, cioClient: Nullable<ConstructorIO>, sections: UserDefinedSection[], zeroStateSections: UserDefinedSection[] | undefined, advancedParameters?: AdvancedParameters): {
|
|
5
|
+
fetchRecommendationResults: () => Promise<void>;
|
|
5
6
|
activeSections: UserDefinedSection[];
|
|
6
7
|
activeSectionsWithData: Section[];
|
|
7
8
|
zeroStateActiveSections: number | false | undefined;
|
package/lib/types/types.d.ts
CHANGED
|
@@ -15,6 +15,7 @@ export interface AdvancedParametersBase {
|
|
|
15
15
|
displaySearchSuggestionResultCounts?: boolean;
|
|
16
16
|
debounce?: number;
|
|
17
17
|
translations?: Translations;
|
|
18
|
+
fetchZeroStateOnFocus?: boolean;
|
|
18
19
|
}
|
|
19
20
|
export type AdvancedParameters = AdvancedParametersBase & Omit<IAutocompleteParameters, 'resultsPerSection'>;
|
|
20
21
|
export type CioAutocompleteProps = CioClientConfig & {
|
package/lib/types/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const _default: "1.
|
|
1
|
+
declare const _default: "1.23.0";
|
|
2
2
|
export default _default;
|
package/package.json
CHANGED