@constructor-io/constructorio-ui-autocomplete 1.23.27 → 1.23.29
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 +9 -9
- package/lib/cjs/components/Autocomplete/AutocompleteResults/AutocompleteResults.js +2 -2
- package/lib/cjs/components/Autocomplete/SectionItem/SectionItem.js +2 -2
- package/lib/cjs/components/Autocomplete/SectionItem/SectionItemText.js +2 -2
- package/lib/cjs/components/Autocomplete/SectionItemsList/SectionItemsList.js +5 -4
- package/lib/cjs/hooks/useCioAutocomplete.js +12 -9
- package/lib/cjs/hooks/useCioClient.js +2 -2
- package/lib/cjs/hooks/useDownShift.js +3 -3
- package/lib/cjs/hooks/useSections/useActiveSectionsWithData.js +2 -2
- package/lib/cjs/hooks/useSections/useRemoveSections.js +2 -2
- package/lib/cjs/{beaconUtils.js → utils/beaconUtils.js} +6 -65
- package/lib/cjs/utils/features.js +61 -0
- package/lib/cjs/utils/format.js +35 -0
- package/lib/cjs/utils/helpers.js +149 -0
- package/lib/cjs/utils/storage.js +63 -0
- package/lib/cjs/utils/tracking.js +52 -0
- package/lib/cjs/version.js +1 -1
- package/lib/mjs/components/Autocomplete/AutocompleteResults/AutocompleteResults.js +1 -1
- package/lib/mjs/components/Autocomplete/SectionItem/SectionItem.js +1 -1
- package/lib/mjs/components/Autocomplete/SectionItem/SectionItemText.js +1 -1
- package/lib/mjs/components/Autocomplete/SectionItemsList/SectionItemsList.js +2 -1
- package/lib/mjs/hooks/useCioAutocomplete.js +4 -1
- package/lib/mjs/hooks/useCioClient.js +1 -1
- package/lib/mjs/hooks/useDownShift.js +1 -1
- package/lib/mjs/hooks/useSections/useActiveSectionsWithData.js +1 -1
- package/lib/mjs/hooks/useSections/useRemoveSections.js +1 -1
- package/lib/mjs/{beaconUtils.js → utils/beaconUtils.js} +1 -55
- package/lib/mjs/utils/features.js +56 -0
- package/lib/mjs/utils/format.js +29 -0
- package/lib/mjs/{utils.js → utils/helpers.js} +1 -98
- package/lib/mjs/utils/storage.js +55 -0
- package/lib/mjs/utils/tracking.js +41 -0
- package/lib/mjs/version.js +1 -1
- package/lib/types/{beaconUtils.d.ts → utils/beaconUtils.d.ts} +0 -5
- package/lib/types/utils/features.d.ts +9 -0
- package/lib/types/utils/format.d.ts +5 -0
- package/lib/types/{utils.d.ts → utils/helpers.d.ts} +2 -16
- package/lib/types/utils/storage.d.ts +5 -0
- package/lib/types/utils/tracking.d.ts +7 -0
- package/lib/types/version.d.ts +1 -1
- package/package.json +1 -1
- package/lib/cjs/utils.js +0 -259
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const tslib_1 = require("tslib");
|
|
4
4
|
const react_1 = tslib_1.__importStar(require("react"));
|
|
5
|
-
const
|
|
5
|
+
const format_1 = require("../../../utils/format");
|
|
6
6
|
const CioAutocompleteProvider_1 = require("../CioAutocompleteProvider");
|
|
7
7
|
const SectionItemsList_1 = tslib_1.__importDefault(require("../SectionItemsList/SectionItemsList"));
|
|
8
8
|
const CloseIcon_1 = tslib_1.__importDefault(require("./CloseIcon"));
|
|
@@ -14,7 +14,7 @@ const DefaultRenderResults = ({ sections }) => sections === null || sections ===
|
|
|
14
14
|
key = section.podId;
|
|
15
15
|
break;
|
|
16
16
|
case 'custom':
|
|
17
|
-
key = (0,
|
|
17
|
+
key = (0, format_1.toKebabCase)(section.displayName);
|
|
18
18
|
break;
|
|
19
19
|
case 'autocomplete':
|
|
20
20
|
key = section.indexSectionName;
|
|
@@ -5,7 +5,7 @@ const react_1 = tslib_1.__importStar(require("react"));
|
|
|
5
5
|
const CioAutocompleteProvider_1 = require("../CioAutocompleteProvider");
|
|
6
6
|
const typeGuards_1 = require("../../../typeGuards");
|
|
7
7
|
const SectionItemText_1 = tslib_1.__importDefault(require("./SectionItemText"));
|
|
8
|
-
const
|
|
8
|
+
const helpers_1 = require("../../../utils/helpers");
|
|
9
9
|
const SearchSuggestionItem_1 = tslib_1.__importDefault(require("./SearchSuggestionItem"));
|
|
10
10
|
function SectionItem(props) {
|
|
11
11
|
var _a, _b;
|
|
@@ -21,7 +21,7 @@ function SectionItem(props) {
|
|
|
21
21
|
}
|
|
22
22
|
else if ((0, typeGuards_1.isInGroupSuggestion)(item)) {
|
|
23
23
|
defaultChildren = (react_1.default.createElement("p", { className: 'cio-term-in-group' },
|
|
24
|
-
(0,
|
|
24
|
+
(0, helpers_1.translate)('in', translations),
|
|
25
25
|
' ',
|
|
26
26
|
react_1.default.createElement(SectionItemText_1.default, { item: item, query: query, highlightSearchTerm: displaySearchTermHighlights })));
|
|
27
27
|
}
|
|
@@ -3,11 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
const tslib_1 = require("tslib");
|
|
4
4
|
const react_1 = tslib_1.__importDefault(require("react"));
|
|
5
5
|
const typeGuards_1 = require("../../../typeGuards");
|
|
6
|
-
const
|
|
6
|
+
const helpers_1 = require("../../../utils/helpers");
|
|
7
7
|
function SectionItemText({ item, query, highlightSearchTerm, }) {
|
|
8
8
|
const itemText = (0, typeGuards_1.isInGroupSuggestion)(item) ? item.groupName : item.value;
|
|
9
9
|
if (highlightSearchTerm) {
|
|
10
|
-
const queryRegex = new RegExp(`(${(0,
|
|
10
|
+
const queryRegex = new RegExp(`(${(0, helpers_1.escapeRegExp)(query)})`, 'gi');
|
|
11
11
|
const queryIncludedInText = queryRegex.test(itemText);
|
|
12
12
|
if (query && queryIncludedInText) {
|
|
13
13
|
const splitText = itemText.split(queryRegex);
|
|
@@ -4,7 +4,8 @@ const tslib_1 = require("tslib");
|
|
|
4
4
|
const react_1 = tslib_1.__importStar(require("react"));
|
|
5
5
|
const SectionItem_1 = tslib_1.__importDefault(require("../SectionItem/SectionItem"));
|
|
6
6
|
const CustomSectionItem_1 = tslib_1.__importDefault(require("../SectionItem/CustomSectionItem"));
|
|
7
|
-
const
|
|
7
|
+
const helpers_1 = require("../../../utils/helpers");
|
|
8
|
+
const format_1 = require("../../../utils/format");
|
|
8
9
|
const CioAutocompleteProvider_1 = require("../CioAutocompleteProvider");
|
|
9
10
|
const NoResults_1 = tslib_1.__importDefault(require("../AutocompleteResults/NoResults"));
|
|
10
11
|
// eslint-disable-next-line func-names
|
|
@@ -34,13 +35,13 @@ const DefaultRenderSectionItemsList = function ({ section }) {
|
|
|
34
35
|
// Display no results message
|
|
35
36
|
if (!((_a = section === null || section === void 0 ? void 0 : section.data) === null || _a === void 0 ? void 0 : _a.length) && displayNoResultsMessage)
|
|
36
37
|
return (react_1.default.createElement("li", Object.assign({}, getSectionProps(section)),
|
|
37
|
-
react_1.default.createElement("h5", { className: 'cio-section-name cio-sectionName', "aria-hidden": true }, (0,
|
|
38
|
+
react_1.default.createElement("h5", { className: 'cio-section-name cio-sectionName', "aria-hidden": true }, (0, format_1.camelToStartCase)(sectionTitle)),
|
|
38
39
|
react_1.default.createElement(NoResults_1.default, null)));
|
|
39
40
|
if (!((_b = section === null || section === void 0 ? void 0 : section.data) === null || _b === void 0 ? void 0 : _b.length))
|
|
40
41
|
return null;
|
|
41
42
|
// @deprecated `cio-sectionName` will be removed in the next major release
|
|
42
43
|
return (react_1.default.createElement("li", Object.assign({}, getSectionProps(section)),
|
|
43
|
-
react_1.default.createElement("h5", { className: 'cio-section-name cio-sectionName', "aria-hidden": true }, (0,
|
|
44
|
+
react_1.default.createElement("h5", { className: 'cio-section-name cio-sectionName', "aria-hidden": true }, (0, format_1.camelToStartCase)(sectionTitle)),
|
|
44
45
|
react_1.default.createElement("ul", { className: 'cio-section-items', role: 'none' }, (_c = section === null || section === void 0 ? void 0 : section.data) === null || _c === void 0 ? void 0 : _c.map((item) => {
|
|
45
46
|
if (typeof (section === null || section === void 0 ? void 0 : section.renderItem) === 'function') {
|
|
46
47
|
return (react_1.default.createElement(CustomSectionItem_1.default, { renderItem: section.renderItem, item: item, query: query, key: item.id }));
|
|
@@ -50,7 +51,7 @@ const DefaultRenderSectionItemsList = function ({ section }) {
|
|
|
50
51
|
displayShowAllResultsButton &&
|
|
51
52
|
type === 'autocomplete' &&
|
|
52
53
|
section.indexSectionName === 'Products' && (react_1.default.createElement("div", { className: 'cio-section-footer' },
|
|
53
|
-
react_1.default.createElement("button", { "data-cnstrc-search-submit-btn": true, className: 'cio-show-all-results-button', type: 'button', onClick: onSubmit }, (0,
|
|
54
|
+
react_1.default.createElement("button", { "data-cnstrc-search-submit-btn": true, className: 'cio-show-all-results-button', type: 'button', onClick: onSubmit }, (0, helpers_1.translate)('show all results', translations))))));
|
|
54
55
|
};
|
|
55
56
|
function SectionItemsList(props) {
|
|
56
57
|
const { section, children = DefaultRenderSectionItemsList } = props;
|
|
@@ -7,7 +7,10 @@ const react_1 = require("react");
|
|
|
7
7
|
const useCioClient_1 = tslib_1.__importDefault(require("./useCioClient"));
|
|
8
8
|
const useDownShift_1 = tslib_1.__importDefault(require("./useDownShift"));
|
|
9
9
|
const usePrevious_1 = tslib_1.__importDefault(require("./usePrevious"));
|
|
10
|
-
const
|
|
10
|
+
const helpers_1 = require("../utils/helpers");
|
|
11
|
+
const format_1 = require("../utils/format");
|
|
12
|
+
const tracking_1 = require("../utils/tracking");
|
|
13
|
+
const features_1 = require("../utils/features");
|
|
11
14
|
const useConsoleErrors_1 = tslib_1.__importDefault(require("./useConsoleErrors"));
|
|
12
15
|
const useSections_1 = tslib_1.__importDefault(require("./useSections"));
|
|
13
16
|
const useRecommendationsObserver_1 = tslib_1.__importDefault(require("./useRecommendationsObserver"));
|
|
@@ -32,9 +35,9 @@ const useCioAutocomplete = (options) => {
|
|
|
32
35
|
const cioClient = (0, useCioClient_1.default)({ apiKey, cioJsClient, cioJsClientOptions });
|
|
33
36
|
// Get autocomplete sections (autocomplete + recommendations + custom)
|
|
34
37
|
const { fetchRecommendationResults, activeSections, activeSectionsWithData, zeroStateActiveSections, request, totalNumResultsPerSection, } = (0, useSections_1.default)(query, cioClient, sections, zeroStateSections, advancedParameters);
|
|
35
|
-
const features = (0, react_1.useMemo)(() => (0,
|
|
38
|
+
const features = (0, react_1.useMemo)(() => (0, features_1.getFeatures)(request), [request]);
|
|
36
39
|
// Get dropdown items array from active sections (autocomplete + recommendations + custom)
|
|
37
|
-
const items = (0, react_1.useMemo)(() => (0,
|
|
40
|
+
const items = (0, react_1.useMemo)(() => (0, helpers_1.getItemsForActiveSections)(activeSectionsWithData), [activeSectionsWithData]);
|
|
38
41
|
const { isOpen, getMenuProps, getLabelProps, openMenu, closeMenu, highlightedIndex, getInputProps, getItemProps: getItemPropsDownShift, } = (0, useDownShift_1.default)(Object.assign({ setQuery,
|
|
39
42
|
items,
|
|
40
43
|
onSubmit,
|
|
@@ -44,7 +47,7 @@ const useCioAutocomplete = (options) => {
|
|
|
44
47
|
// Log console errors
|
|
45
48
|
(0, useConsoleErrors_1.default)(sections, activeSections);
|
|
46
49
|
// Track recommendation view
|
|
47
|
-
(0, useRecommendationsObserver_1.default)(isOpen, activeSectionsWithData, cioClient,
|
|
50
|
+
(0, useRecommendationsObserver_1.default)(isOpen, activeSectionsWithData, cioClient, tracking_1.trackRecommendationView);
|
|
48
51
|
return {
|
|
49
52
|
query,
|
|
50
53
|
sections: activeSectionsWithData,
|
|
@@ -58,7 +61,7 @@ const useCioAutocomplete = (options) => {
|
|
|
58
61
|
closeMenu,
|
|
59
62
|
getItemProps: (item) => {
|
|
60
63
|
var _a;
|
|
61
|
-
const { index, sectionId } = (0,
|
|
64
|
+
const { index, sectionId } = (0, helpers_1.getItemPosition)({ item, items });
|
|
62
65
|
const sectionItemTestId = `cio-item-${sectionId === null || sectionId === void 0 ? void 0 : sectionId.replace(' ', '')}`;
|
|
63
66
|
return Object.assign(Object.assign({}, getItemPropsDownShift({ item, index })), {
|
|
64
67
|
// @deprecated `sectionItemTestId` will be removed as a className in the next major version
|
|
@@ -104,7 +107,7 @@ const useCioAutocomplete = (options) => {
|
|
|
104
107
|
onSubmit({ query });
|
|
105
108
|
}
|
|
106
109
|
try {
|
|
107
|
-
(0,
|
|
110
|
+
(0, tracking_1.trackSearchSubmit)(cioClient, query, { originalQuery: query });
|
|
108
111
|
}
|
|
109
112
|
catch (error) {
|
|
110
113
|
// eslint-disable-next-line no-console
|
|
@@ -123,7 +126,7 @@ const useCioAutocomplete = (options) => {
|
|
|
123
126
|
onSubmit({ query });
|
|
124
127
|
}
|
|
125
128
|
try {
|
|
126
|
-
(0,
|
|
129
|
+
(0, tracking_1.trackSearchSubmit)(cioClient, query, { originalQuery: query });
|
|
127
130
|
}
|
|
128
131
|
catch (error) {
|
|
129
132
|
// eslint-disable-next-line no-console
|
|
@@ -142,7 +145,7 @@ const useCioAutocomplete = (options) => {
|
|
|
142
145
|
const { type } = section;
|
|
143
146
|
let sectionTitle;
|
|
144
147
|
const indexSectionName = type !== 'custom' && section.indexSectionName
|
|
145
|
-
? (0,
|
|
148
|
+
? (0, format_1.toKebabCase)(section.indexSectionName)
|
|
146
149
|
: '';
|
|
147
150
|
switch (type) {
|
|
148
151
|
case 'recommendations':
|
|
@@ -165,7 +168,7 @@ const useCioAutocomplete = (options) => {
|
|
|
165
168
|
// ... they should be styled accordingly
|
|
166
169
|
const sectionListingType = (0, typeGuards_1.isCustomSection)(section)
|
|
167
170
|
? 'custom'
|
|
168
|
-
: (0,
|
|
171
|
+
: (0, format_1.toKebabCase)(section.indexSectionName || ((_a = section.data[0]) === null || _a === void 0 ? void 0 : _a.section) || 'Products');
|
|
169
172
|
const attributes = {
|
|
170
173
|
className: `cio-section cio-section-${sectionListingType} ${getDeprecatedClassNames()}`,
|
|
171
174
|
ref: section.ref,
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const react_1 = require("react");
|
|
4
|
-
const
|
|
4
|
+
const helpers_1 = require("../utils/helpers");
|
|
5
5
|
const useCioClient = ({ apiKey, cioJsClient, cioJsClientOptions }) => {
|
|
6
6
|
if (!apiKey && !cioJsClient) {
|
|
7
7
|
// eslint-disable-next-line no-console
|
|
8
8
|
console.error('Either apiKey or cioJsClient is required');
|
|
9
9
|
}
|
|
10
|
-
return (0, react_1.useMemo)(() => cioJsClient || (0,
|
|
10
|
+
return (0, react_1.useMemo)(() => cioJsClient || (0, helpers_1.getCioClient)(apiKey, cioJsClientOptions), [apiKey, cioJsClient, cioJsClientOptions]);
|
|
11
11
|
};
|
|
12
12
|
exports.default = useCioClient;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const tslib_1 = require("tslib");
|
|
4
4
|
const downshift_1 = require("downshift");
|
|
5
|
-
const
|
|
5
|
+
const tracking_1 = require("../utils/tracking");
|
|
6
6
|
let idCounter = 0;
|
|
7
7
|
const useDownShift = (_a) => {
|
|
8
8
|
var { setQuery, items, onSubmit, cioClient, previousQuery = '' } = _a, rest = tslib_1.__rest(_a, ["setQuery", "items", "onSubmit", "cioClient", "previousQuery"]);
|
|
@@ -16,7 +16,7 @@ const useDownShift = (_a) => {
|
|
|
16
16
|
try {
|
|
17
17
|
if ((selectedItem === null || selectedItem === void 0 ? void 0 : selectedItem.section) === 'Search Suggestions') {
|
|
18
18
|
setQuery(selectedItem.value || '');
|
|
19
|
-
(0,
|
|
19
|
+
(0, tracking_1.trackSearchSubmit)(cioClient, selectedItem.value, {
|
|
20
20
|
originalQuery: previousQuery,
|
|
21
21
|
});
|
|
22
22
|
}
|
|
@@ -37,7 +37,7 @@ const useDownShift = (_a) => {
|
|
|
37
37
|
// This does not apply to custom user defined sections that aren't part of Constructor index
|
|
38
38
|
}
|
|
39
39
|
else if (selectedItem.result_id) {
|
|
40
|
-
(0,
|
|
40
|
+
(0, tracking_1.trackAutocompleteSelect)(cioClient, selectedItem.value, {
|
|
41
41
|
originalQuery: previousQuery,
|
|
42
42
|
section: selectedItem.section,
|
|
43
43
|
});
|
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
/* eslint-disable max-params */
|
|
4
4
|
const react_1 = require("react");
|
|
5
|
-
const
|
|
5
|
+
const helpers_1 = require("../../utils/helpers");
|
|
6
6
|
function useActiveSectionsWithData(sectionsResults, activeSections, sectionsRefs, query, podsData) {
|
|
7
7
|
const [activeSectionsWithData, setActiveSectionsWithData] = (0, react_1.useState)([]);
|
|
8
8
|
// Add to active sections the results data and refs when autocomplete results or recommendation results fetched
|
|
9
9
|
(0, react_1.useEffect)(() => {
|
|
10
|
-
const activeSectionsWithDataValue = (0,
|
|
10
|
+
const activeSectionsWithDataValue = (0, helpers_1.getActiveSectionsWithData)(activeSections, sectionsResults, sectionsRefs, podsData);
|
|
11
11
|
if (activeSectionsWithDataValue.length || !query) {
|
|
12
12
|
setActiveSectionsWithData(activeSectionsWithDataValue);
|
|
13
13
|
}
|
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
/* eslint-disable max-params */
|
|
4
4
|
const react_1 = require("react");
|
|
5
|
-
const
|
|
5
|
+
const features_1 = require("../../utils/features");
|
|
6
6
|
function useRemoveSections(sections, podsData, setActiveSections, showZeroStateSections, zeroStateSections) {
|
|
7
7
|
// Remove sections if necessary
|
|
8
8
|
(0, react_1.useEffect)(() => {
|
|
9
9
|
var _a, _b;
|
|
10
|
-
const features = (0,
|
|
10
|
+
const features = (0, features_1.getFeatures)((_b = (_a = Object.values(podsData || {})) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.request);
|
|
11
11
|
if (showZeroStateSections) {
|
|
12
12
|
if (!features.featureDisplayZeroStateRecommendations) {
|
|
13
13
|
setActiveSections([]);
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.storeRecentAction = exports.getLastAction = exports.getRecentActions = exports.storeRecentSearch = exports.getRecentSearches = exports.
|
|
3
|
+
exports.storeRecentAction = exports.getLastAction = exports.getRecentActions = exports.storeRecentSearch = exports.getRecentSearches = exports.cleanTerm = exports.CONSTANTS = void 0;
|
|
4
4
|
// eslint-disable-next-line import/no-cycle
|
|
5
|
-
const
|
|
5
|
+
const storage_1 = require("./storage");
|
|
6
6
|
exports.CONSTANTS = {
|
|
7
7
|
SEARCH_SUBMIT: 'SEARCH_SUBMIT',
|
|
8
8
|
RECENT_ACTIONS_STORAGE_KEY: {
|
|
@@ -20,38 +20,6 @@ exports.CONSTANTS = {
|
|
|
20
20
|
RECENT_SEARCHES_STORAGE_COUNT: 100,
|
|
21
21
|
RECENT_ACTION_STORAGE_COUNT: 5,
|
|
22
22
|
};
|
|
23
|
-
// Return storage engine based on scope
|
|
24
|
-
const getStorageEngine = (scope) => {
|
|
25
|
-
if (scope === 'local') {
|
|
26
|
-
return localStorage;
|
|
27
|
-
}
|
|
28
|
-
return sessionStorage;
|
|
29
|
-
};
|
|
30
|
-
exports.getStorageEngine = getStorageEngine;
|
|
31
|
-
// Set item in storage
|
|
32
|
-
const storageSetItem = (key, value) => {
|
|
33
|
-
try {
|
|
34
|
-
const storageEngine = (0, exports.getStorageEngine)(key.scope);
|
|
35
|
-
return storageEngine.setItem(key.key, value);
|
|
36
|
-
}
|
|
37
|
-
catch (e) {
|
|
38
|
-
(0, utils_1.logger)(`storageSetItem error: ${e}`);
|
|
39
|
-
return null;
|
|
40
|
-
}
|
|
41
|
-
};
|
|
42
|
-
exports.storageSetItem = storageSetItem;
|
|
43
|
-
// Remove item in storage
|
|
44
|
-
const storageRemoveItem = (key) => {
|
|
45
|
-
try {
|
|
46
|
-
const storageEngine = (0, exports.getStorageEngine)(key.scope);
|
|
47
|
-
return storageEngine.removeItem(key.key);
|
|
48
|
-
}
|
|
49
|
-
catch (e) {
|
|
50
|
-
(0, utils_1.logger)(`storageRemoveItem error: ${e}`);
|
|
51
|
-
return null;
|
|
52
|
-
}
|
|
53
|
-
};
|
|
54
|
-
exports.storageRemoveItem = storageRemoveItem;
|
|
55
23
|
/*
|
|
56
24
|
* Use the text content of the resulting HTML node(s) created from the
|
|
57
25
|
* term
|
|
@@ -69,38 +37,11 @@ const cleanTerm = (term) => {
|
|
|
69
37
|
return texts.join('');
|
|
70
38
|
};
|
|
71
39
|
exports.cleanTerm = cleanTerm;
|
|
72
|
-
// Retrieves item from storage for key
|
|
73
|
-
const storageGetItem = (key) => {
|
|
74
|
-
try {
|
|
75
|
-
const storageEngine = (0, exports.getStorageEngine)(key.scope);
|
|
76
|
-
return storageEngine.getItem(key.key);
|
|
77
|
-
}
|
|
78
|
-
catch (e) {
|
|
79
|
-
(0, utils_1.logger)(`storageGetItem error: ${e}`);
|
|
80
|
-
return null;
|
|
81
|
-
}
|
|
82
|
-
};
|
|
83
|
-
exports.storageGetItem = storageGetItem;
|
|
84
|
-
// Retrieve array from storage
|
|
85
|
-
const storageGetArray = (key) => {
|
|
86
|
-
const item = (0, exports.storageGetItem)(key);
|
|
87
|
-
if (item) {
|
|
88
|
-
try {
|
|
89
|
-
const array = JSON.parse(item);
|
|
90
|
-
return array;
|
|
91
|
-
}
|
|
92
|
-
catch (e) {
|
|
93
|
-
(0, utils_1.logger)(`storageGetArray error: ${e}`);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
return null;
|
|
97
|
-
};
|
|
98
|
-
exports.storageGetArray = storageGetArray;
|
|
99
40
|
/*
|
|
100
41
|
* Returns a list of recent searches
|
|
101
42
|
*/
|
|
102
43
|
const getRecentSearches = () => {
|
|
103
|
-
const recentSearches = (0,
|
|
44
|
+
const recentSearches = (0, storage_1.storageGetArray)(exports.CONSTANTS.RECENT_SEARCHES_STORAGE_KEY) || [];
|
|
104
45
|
// upgrade the array to store timestamps if it isn't already
|
|
105
46
|
recentSearches.forEach((item, i) => {
|
|
106
47
|
if (typeof item === 'string') {
|
|
@@ -139,14 +80,14 @@ const storeRecentSearch = (term, suggestionData) => {
|
|
|
139
80
|
while (recentSearches.length > exports.CONSTANTS.RECENT_SEARCHES_STORAGE_COUNT) {
|
|
140
81
|
recentSearches.shift();
|
|
141
82
|
}
|
|
142
|
-
(0,
|
|
83
|
+
(0, storage_1.storageSetItem)(exports.CONSTANTS.RECENT_SEARCHES_STORAGE_KEY, JSON.stringify(recentSearches));
|
|
143
84
|
}
|
|
144
85
|
};
|
|
145
86
|
exports.storeRecentSearch = storeRecentSearch;
|
|
146
87
|
/*
|
|
147
88
|
* Returns a list of recent actions
|
|
148
89
|
*/
|
|
149
|
-
const getRecentActions = () => (0,
|
|
90
|
+
const getRecentActions = () => (0, storage_1.storageGetArray)(exports.CONSTANTS.RECENT_ACTIONS_STORAGE_KEY) || [];
|
|
150
91
|
exports.getRecentActions = getRecentActions;
|
|
151
92
|
/*
|
|
152
93
|
* Returns the last action
|
|
@@ -177,7 +118,7 @@ const storeRecentAction = (action) => {
|
|
|
177
118
|
if (recentActions.length > exports.CONSTANTS.RECENT_ACTION_STORAGE_COUNT) {
|
|
178
119
|
recentActions = recentActions.slice(-1 * exports.CONSTANTS.RECENT_ACTION_STORAGE_COUNT);
|
|
179
120
|
}
|
|
180
|
-
(0,
|
|
121
|
+
(0, storage_1.storageSetItem)(exports.CONSTANTS.RECENT_ACTIONS_STORAGE_KEY, JSON.stringify(recentActions));
|
|
181
122
|
}
|
|
182
123
|
};
|
|
183
124
|
exports.storeRecentAction = storeRecentAction;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getFeatures = void 0;
|
|
4
|
+
const storage_1 = require("./storage");
|
|
5
|
+
const AUTOSUGGEST_CUSTOM_UI_VARIANTS = [
|
|
6
|
+
'custom_autosuggest_ui_result_count',
|
|
7
|
+
'custom_autosuggest_ui_image',
|
|
8
|
+
'custom_autosuggest_ui_image_result_count',
|
|
9
|
+
'custom_autosuggest_ui_disable_recommendations_in_zero_state',
|
|
10
|
+
];
|
|
11
|
+
const AUTOSUGGEST_CUSTOM_UI_STORAGE_KEY = {
|
|
12
|
+
scope: 'session',
|
|
13
|
+
key: '_constructorio_custom_autosuggest_ui',
|
|
14
|
+
};
|
|
15
|
+
const isCustomAutosuggestUiVariant = (variant) => AUTOSUGGEST_CUSTOM_UI_VARIANTS.includes(variant);
|
|
16
|
+
const getCustomUiVariantFromStorage = () => {
|
|
17
|
+
const item = (0, storage_1.storageGetItem)(AUTOSUGGEST_CUSTOM_UI_STORAGE_KEY);
|
|
18
|
+
return item && isCustomAutosuggestUiVariant(item) ? item : null;
|
|
19
|
+
};
|
|
20
|
+
// eslint-disable-next-line import/prefer-default-export
|
|
21
|
+
function getFeatures(request) {
|
|
22
|
+
var _a, _b, _c, _d;
|
|
23
|
+
let featureDisplaySearchSuggestionImages = false;
|
|
24
|
+
let featureDisplaySearchSuggestionResultCounts = false;
|
|
25
|
+
let featureDisplayZeroStateRecommendations = true;
|
|
26
|
+
let customAutosuggestUi = null;
|
|
27
|
+
if (((_a = request === null || request === void 0 ? void 0 : request.features) === null || _a === void 0 ? void 0 : _a.custom_autosuggest_ui) === true &&
|
|
28
|
+
isCustomAutosuggestUiVariant((_b = request === null || request === void 0 ? void 0 : request.feature_variants) === null || _b === void 0 ? void 0 : _b.custom_autosuggest_ui)) {
|
|
29
|
+
customAutosuggestUi = (_d = (_c = request === null || request === void 0 ? void 0 : request.feature_variants) === null || _c === void 0 ? void 0 : _c.custom_autosuggest_ui) !== null && _d !== void 0 ? _d : null;
|
|
30
|
+
}
|
|
31
|
+
// If a variant is set in the session storage, override the request variant
|
|
32
|
+
const customVariantFromStorage = getCustomUiVariantFromStorage();
|
|
33
|
+
if (customVariantFromStorage) {
|
|
34
|
+
customAutosuggestUi = customVariantFromStorage;
|
|
35
|
+
}
|
|
36
|
+
if (customAutosuggestUi !== null) {
|
|
37
|
+
switch (customAutosuggestUi) {
|
|
38
|
+
case 'custom_autosuggest_ui_result_count':
|
|
39
|
+
featureDisplaySearchSuggestionResultCounts = true;
|
|
40
|
+
break;
|
|
41
|
+
case 'custom_autosuggest_ui_image':
|
|
42
|
+
featureDisplaySearchSuggestionImages = true;
|
|
43
|
+
break;
|
|
44
|
+
case 'custom_autosuggest_ui_image_result_count':
|
|
45
|
+
featureDisplaySearchSuggestionImages = true;
|
|
46
|
+
featureDisplaySearchSuggestionResultCounts = true;
|
|
47
|
+
break;
|
|
48
|
+
case 'custom_autosuggest_ui_disable_recommendations_in_zero_state':
|
|
49
|
+
featureDisplayZeroStateRecommendations = false;
|
|
50
|
+
break;
|
|
51
|
+
default:
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return {
|
|
56
|
+
featureDisplaySearchSuggestionImages,
|
|
57
|
+
featureDisplaySearchSuggestionResultCounts,
|
|
58
|
+
featureDisplayZeroStateRecommendations,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
exports.getFeatures = getFeatures;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.stringifyWithDefaults = exports.toKebabCase = exports.camelToStartCase = void 0;
|
|
4
|
+
const helpers_1 = require("./helpers");
|
|
5
|
+
const camelToStartCase = (camelCaseString) => camelCaseString
|
|
6
|
+
// insert a space between lower & upper
|
|
7
|
+
.replace(/([a-z])([A-Z])/g, '$1 $2')
|
|
8
|
+
// space before last upper in a sequence followed by lower
|
|
9
|
+
.replace(/\b([A-Z]+)([A-Z])([a-z])/, '$1 $2$3')
|
|
10
|
+
// uppercase the first letter
|
|
11
|
+
.replace(/([a-zA-Z])/, (str) => str.toUpperCase());
|
|
12
|
+
exports.camelToStartCase = camelToStartCase;
|
|
13
|
+
const toKebabCase = (str) => str
|
|
14
|
+
.replace(/([A-Z])([A-Z][a-z])/g, '$1-$2')
|
|
15
|
+
.replace(/([a-z])([A-Z])/g, '$1-$2')
|
|
16
|
+
.replace(/[\s_]+/g, '-')
|
|
17
|
+
.toLowerCase();
|
|
18
|
+
exports.toKebabCase = toKebabCase;
|
|
19
|
+
const stringifyWithDefaults = (obj) => {
|
|
20
|
+
// Stringify non-function values normally. Add a template block for functions to be replaced later
|
|
21
|
+
let res = JSON.stringify(obj, (key, value) => (value instanceof Function ? `${key}_CODE` : value), ' ');
|
|
22
|
+
// Replace template blocks with function strings
|
|
23
|
+
Array.from(res.matchAll(/"(\w*)_CODE"/g)).forEach((match) => {
|
|
24
|
+
const [codePlaceholder, key] = match;
|
|
25
|
+
const functionString = helpers_1.functionStrings[key];
|
|
26
|
+
if (functionString) {
|
|
27
|
+
res = res.replaceAll(codePlaceholder, functionString);
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
console.error(`Function string for ${key} not found.`); // eslint-disable-line
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
return res;
|
|
34
|
+
};
|
|
35
|
+
exports.stringifyWithDefaults = stringifyWithDefaults;
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.logger = exports.translate = exports.getItemsForActiveSections = exports.escapeRegExp = exports.getActiveSectionsWithData = exports.getCioClient = exports.disableStoryActions = exports.functionStrings = exports.getStoryParams = exports.sleep = exports.clearConstructorRequests = exports.getItemPosition = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const constructorio_client_javascript_1 = tslib_1.__importDefault(require("@constructor-io/constructorio-client-javascript"));
|
|
6
|
+
const version_1 = tslib_1.__importDefault(require("../version"));
|
|
7
|
+
const getItemPosition = ({ item, items }) => {
|
|
8
|
+
var _a;
|
|
9
|
+
const index = items.findIndex((itemInFlatList) => (itemInFlatList === null || itemInFlatList === void 0 ? void 0 : itemInFlatList.id) === (item === null || item === void 0 ? void 0 : item.id));
|
|
10
|
+
const sectionId = (_a = items[index]) === null || _a === void 0 ? void 0 : _a.section;
|
|
11
|
+
return { sectionId, index };
|
|
12
|
+
};
|
|
13
|
+
exports.getItemPosition = getItemPosition;
|
|
14
|
+
function clearConstructorRequests() {
|
|
15
|
+
var _a;
|
|
16
|
+
// eslint-disable-next-line
|
|
17
|
+
if ((_a = window.localStorage) === null || _a === void 0 ? void 0 : _a._constructorio_requests) {
|
|
18
|
+
window.localStorage.removeItem('_constructorio_requests');
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
exports.clearConstructorRequests = clearConstructorRequests;
|
|
22
|
+
// Function to emulate pausing between interactions
|
|
23
|
+
function sleep(ms) {
|
|
24
|
+
// eslint-disable-next-line
|
|
25
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
26
|
+
}
|
|
27
|
+
exports.sleep = sleep;
|
|
28
|
+
// More on Story layout: https://storybook.js.org/docs/react/configure/story-layout
|
|
29
|
+
const getStoryParams = (storyCode, templateCode, importCode) => {
|
|
30
|
+
const code = `
|
|
31
|
+
${importCode}
|
|
32
|
+
${storyCode}
|
|
33
|
+
${templateCode}
|
|
34
|
+
`;
|
|
35
|
+
return {
|
|
36
|
+
docs: {
|
|
37
|
+
source: {
|
|
38
|
+
code,
|
|
39
|
+
language: 'jsx',
|
|
40
|
+
format: true,
|
|
41
|
+
type: 'code',
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
};
|
|
46
|
+
exports.getStoryParams = getStoryParams;
|
|
47
|
+
exports.functionStrings = {
|
|
48
|
+
onSubmit: `(submitEvent) => console.dir(submitEvent)`,
|
|
49
|
+
renderItem: `({ item, query, getItemProps }) => (
|
|
50
|
+
<div {...getItemProps(item)}>
|
|
51
|
+
<a href={item.data?.url}>
|
|
52
|
+
<h3>{item.value}</h3>
|
|
53
|
+
<img src={item.data?.image_url} alt={item.value} />
|
|
54
|
+
</a>
|
|
55
|
+
<p>{item.data?.price}</p>
|
|
56
|
+
</div>
|
|
57
|
+
)`,
|
|
58
|
+
};
|
|
59
|
+
const disableStoryActions = (story) => {
|
|
60
|
+
// eslint-disable-next-line
|
|
61
|
+
story.parameters.actions = { argTypesRegex: null };
|
|
62
|
+
};
|
|
63
|
+
exports.disableStoryActions = disableStoryActions;
|
|
64
|
+
const getCioClient = (apiKey, cioJsClientOptions) => {
|
|
65
|
+
if (apiKey && typeof window !== 'undefined') {
|
|
66
|
+
const cioClient = new constructorio_client_javascript_1.default(Object.assign({ apiKey, sendTrackingEvents: true, version: `cio-ui-autocomplete-${version_1.default}` }, cioJsClientOptions));
|
|
67
|
+
// eslint-disable-next-line no-console
|
|
68
|
+
cioClient.tracker.on('error', (error) => console.error(error));
|
|
69
|
+
return cioClient;
|
|
70
|
+
}
|
|
71
|
+
return null;
|
|
72
|
+
};
|
|
73
|
+
exports.getCioClient = getCioClient;
|
|
74
|
+
const getActiveSectionsWithData = (activeSections, sectionsResults, sectionsRefs, podsData) => {
|
|
75
|
+
const activeSectionsWithData = [];
|
|
76
|
+
const getSectionData = (sectionConfig) => {
|
|
77
|
+
const { type } = sectionConfig;
|
|
78
|
+
let sectionData;
|
|
79
|
+
switch (type) {
|
|
80
|
+
case 'recommendations':
|
|
81
|
+
sectionData = sectionsResults[sectionConfig.podId];
|
|
82
|
+
break;
|
|
83
|
+
case 'custom':
|
|
84
|
+
// Copy id from data to the top level
|
|
85
|
+
sectionData = sectionConfig.data.map((item) => {
|
|
86
|
+
var _a;
|
|
87
|
+
return (Object.assign(Object.assign({}, item), { id: (item === null || item === void 0 ? void 0 : item.id) || ((_a = item === null || item === void 0 ? void 0 : item.data) === null || _a === void 0 ? void 0 : _a.id) }));
|
|
88
|
+
});
|
|
89
|
+
break;
|
|
90
|
+
default:
|
|
91
|
+
// Autocomplete
|
|
92
|
+
sectionData = sectionsResults[sectionConfig.indexSectionName];
|
|
93
|
+
}
|
|
94
|
+
return sectionData;
|
|
95
|
+
};
|
|
96
|
+
activeSections === null || activeSections === void 0 ? void 0 : activeSections.forEach((sectionConfig, index) => {
|
|
97
|
+
const sectionData = getSectionData(sectionConfig);
|
|
98
|
+
if (Array.isArray(sectionData)) {
|
|
99
|
+
const section = Object.assign(Object.assign({}, sectionConfig), { data: sectionData });
|
|
100
|
+
if (sectionConfig.type === 'recommendations') {
|
|
101
|
+
section.displayName =
|
|
102
|
+
sectionConfig.displayName || podsData[sectionConfig.podId].displayName;
|
|
103
|
+
}
|
|
104
|
+
// If ref passed as part of `SectionConfiguration`, use it.
|
|
105
|
+
// Otherwise, use the ref from our library generated refs array
|
|
106
|
+
const userDefinedSectionRef = sectionConfig.ref;
|
|
107
|
+
const libraryGeneratedSectionRef = sectionsRefs.current[index];
|
|
108
|
+
section.ref = userDefinedSectionRef || libraryGeneratedSectionRef;
|
|
109
|
+
activeSectionsWithData.push(section);
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
return activeSectionsWithData;
|
|
113
|
+
};
|
|
114
|
+
exports.getActiveSectionsWithData = getActiveSectionsWithData;
|
|
115
|
+
const escapeRegExp = (string) => string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
116
|
+
exports.escapeRegExp = escapeRegExp;
|
|
117
|
+
const getItemsForActiveSections = (activeSectionsWithData) => {
|
|
118
|
+
const items = [];
|
|
119
|
+
activeSectionsWithData === null || activeSectionsWithData === void 0 ? void 0 : activeSectionsWithData.forEach((config) => {
|
|
120
|
+
if (config === null || config === void 0 ? void 0 : config.data) {
|
|
121
|
+
items.push(...config.data);
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
return items;
|
|
125
|
+
};
|
|
126
|
+
exports.getItemsForActiveSections = getItemsForActiveSections;
|
|
127
|
+
const translate = (word, translations) => {
|
|
128
|
+
const localTranslations = {
|
|
129
|
+
in: 'in',
|
|
130
|
+
'show all results': 'show all results',
|
|
131
|
+
};
|
|
132
|
+
if (translations)
|
|
133
|
+
return translations[word];
|
|
134
|
+
return localTranslations[word] || word;
|
|
135
|
+
};
|
|
136
|
+
exports.translate = translate;
|
|
137
|
+
const logger = (error) => {
|
|
138
|
+
var _a;
|
|
139
|
+
try {
|
|
140
|
+
if (typeof process !== 'undefined' && ((_a = process === null || process === void 0 ? void 0 : process.env) === null || _a === void 0 ? void 0 : _a.LOGGER)) {
|
|
141
|
+
// eslint-disable-next-line no-console
|
|
142
|
+
console.log(error);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
catch (e) {
|
|
146
|
+
// process variable is not available and logger should not be active
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
exports.logger = logger;
|