@constructor-io/constructorio-ui-autocomplete 1.23.26 → 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.
Files changed (45) hide show
  1. package/dist/constructorio-ui-autocomplete-bundled.js +10 -10
  2. package/lib/cjs/components/Autocomplete/AutocompleteResults/AutocompleteResults.js +2 -2
  3. package/lib/cjs/components/Autocomplete/SectionItem/SectionItem.js +2 -2
  4. package/lib/cjs/components/Autocomplete/SectionItem/SectionItemText.js +2 -2
  5. package/lib/cjs/components/Autocomplete/SectionItemsList/SectionItemsList.js +5 -4
  6. package/lib/cjs/hooks/useCioAutocomplete.js +14 -9
  7. package/lib/cjs/hooks/useCioClient.js +2 -2
  8. package/lib/cjs/hooks/useCustomBlur.js +18 -0
  9. package/lib/cjs/hooks/useDownShift.js +10 -3
  10. package/lib/cjs/hooks/useSections/useActiveSectionsWithData.js +2 -2
  11. package/lib/cjs/hooks/useSections/useRemoveSections.js +2 -2
  12. package/lib/cjs/{beaconUtils.js → utils/beaconUtils.js} +6 -65
  13. package/lib/cjs/utils/features.js +61 -0
  14. package/lib/cjs/utils/format.js +35 -0
  15. package/lib/cjs/utils/helpers.js +149 -0
  16. package/lib/cjs/utils/storage.js +63 -0
  17. package/lib/cjs/utils/tracking.js +52 -0
  18. package/lib/cjs/version.js +1 -1
  19. package/lib/mjs/components/Autocomplete/AutocompleteResults/AutocompleteResults.js +1 -1
  20. package/lib/mjs/components/Autocomplete/SectionItem/SectionItem.js +1 -1
  21. package/lib/mjs/components/Autocomplete/SectionItem/SectionItemText.js +1 -1
  22. package/lib/mjs/components/Autocomplete/SectionItemsList/SectionItemsList.js +2 -1
  23. package/lib/mjs/hooks/useCioAutocomplete.js +6 -1
  24. package/lib/mjs/hooks/useCioClient.js +1 -1
  25. package/lib/mjs/hooks/useCustomBlur.js +15 -0
  26. package/lib/mjs/hooks/useDownShift.js +9 -1
  27. package/lib/mjs/hooks/useSections/useActiveSectionsWithData.js +1 -1
  28. package/lib/mjs/hooks/useSections/useRemoveSections.js +1 -1
  29. package/lib/mjs/{beaconUtils.js → utils/beaconUtils.js} +1 -55
  30. package/lib/mjs/utils/features.js +56 -0
  31. package/lib/mjs/utils/format.js +29 -0
  32. package/lib/mjs/{utils.js → utils/helpers.js} +1 -98
  33. package/lib/mjs/utils/storage.js +55 -0
  34. package/lib/mjs/utils/tracking.js +41 -0
  35. package/lib/mjs/version.js +1 -1
  36. package/lib/types/hooks/useCustomBlur.d.ts +2 -0
  37. package/lib/types/{beaconUtils.d.ts → utils/beaconUtils.d.ts} +0 -5
  38. package/lib/types/utils/features.d.ts +9 -0
  39. package/lib/types/utils/format.d.ts +5 -0
  40. package/lib/types/{utils.d.ts → utils/helpers.d.ts} +2 -16
  41. package/lib/types/utils/storage.d.ts +5 -0
  42. package/lib/types/utils/tracking.d.ts +7 -0
  43. package/lib/types/version.d.ts +1 -1
  44. package/package.json +1 -1
  45. package/lib/cjs/utils.js +0 -259
@@ -0,0 +1,9 @@
1
+ import { AutocompleteRequestType } from '@constructor-io/constructorio-client-javascript';
2
+ declare const AUTOSUGGEST_CUSTOM_UI_VARIANTS: string[];
3
+ export type CustomAutosuggestUiVariant = (typeof AUTOSUGGEST_CUSTOM_UI_VARIANTS)[number];
4
+ export declare function getFeatures(request: Partial<AutocompleteRequestType>): {
5
+ featureDisplaySearchSuggestionImages: boolean;
6
+ featureDisplaySearchSuggestionResultCounts: boolean;
7
+ featureDisplayZeroStateRecommendations: boolean;
8
+ };
9
+ export {};
@@ -0,0 +1,5 @@
1
+ type CamelToStartCase = (camelCaseString: string) => string;
2
+ export declare const camelToStartCase: CamelToStartCase;
3
+ export declare const toKebabCase: (str: string) => string;
4
+ export declare const stringifyWithDefaults: (obj: any) => string;
5
+ export {};
@@ -1,6 +1,6 @@
1
1
  import ConstructorIOClient from '@constructor-io/constructorio-client-javascript';
2
- import { AutocompleteRequestType, Nullable, ConstructorClientOptions } from '@constructor-io/constructorio-client-javascript/lib/types';
3
- import { Item, Section, UserDefinedSection, SectionsData, Translations, PodData } from './types';
2
+ import { ConstructorClientOptions } from '@constructor-io/constructorio-client-javascript/lib/types';
3
+ import { Item, Section, UserDefinedSection, SectionsData, Translations, PodData } from '../types';
4
4
  export type GetItemPosition = (args: {
5
5
  item: Item;
6
6
  items: Item[];
@@ -8,16 +8,7 @@ export type GetItemPosition = (args: {
8
8
  index: number;
9
9
  sectionId: string;
10
10
  };
11
- export declare function getFeatures(request: Partial<AutocompleteRequestType>): {
12
- featureDisplaySearchSuggestionImages: boolean;
13
- featureDisplaySearchSuggestionResultCounts: boolean;
14
- featureDisplayZeroStateRecommendations: boolean;
15
- };
16
11
  export declare const getItemPosition: GetItemPosition;
17
- type CamelToStartCase = (camelCaseString: string) => string;
18
- export declare const camelToStartCase: CamelToStartCase;
19
- export declare const toKebabCase: (str: string) => string;
20
- export declare function isTrackingRequestSent(trackingRequestUrl: string): any;
21
12
  export declare function clearConstructorRequests(): void;
22
13
  export declare function sleep(ms: number): Promise<unknown>;
23
14
  export declare const getStoryParams: (storyCode: any, templateCode: any, importCode: any) => {
@@ -34,15 +25,10 @@ export declare const functionStrings: {
34
25
  onSubmit: string;
35
26
  renderItem: string;
36
27
  };
37
- export declare const stringifyWithDefaults: (obj: any) => string;
38
28
  export declare const disableStoryActions: (story: any) => void;
39
29
  export declare const getCioClient: (apiKey?: string, cioJsClientOptions?: ConstructorClientOptions) => ConstructorIOClient | null;
40
30
  export declare const getActiveSectionsWithData: (activeSections: UserDefinedSection[], sectionsResults: SectionsData, sectionsRefs: React.MutableRefObject<React.RefObject<HTMLLIElement>[]>, podsData: Record<string, PodData>) => Section[];
41
31
  export declare const escapeRegExp: (string: string) => string;
42
- export declare const trackRecommendationView: (target: HTMLElement, activeSectionsWithData: Section[], cioClient: Nullable<ConstructorIOClient>) => void;
43
32
  export declare const getItemsForActiveSections: (activeSectionsWithData: Section[]) => Item[];
44
33
  export declare const translate: (word: string, translations?: Translations) => any;
45
- export declare const trackSearchSubmit: (cioClient: any, term: any, autocompleteData?: {}) => void;
46
- export declare const trackAutocompleteSelect: (cioClient: any, itemName: any, autocompleteData?: any) => void;
47
34
  export declare const logger: (error: any) => void;
48
- export {};
@@ -0,0 +1,5 @@
1
+ export declare const getStorageEngine: (scope: any) => Storage;
2
+ export declare const storageGetItem: (key: any) => string | null;
3
+ export declare const storageGetArray: (key: any) => any;
4
+ export declare const storageSetItem: (key: any, value: any) => void | null;
5
+ export declare const storageRemoveItem: (key: any) => void | null;
@@ -0,0 +1,7 @@
1
+ import { Nullable } from '@constructor-io/constructorio-client-javascript';
2
+ import ConstructorIOClient from '@constructor-io/constructorio-client-javascript/lib/types/constructorio';
3
+ import { Section } from '../types';
4
+ export declare function isTrackingRequestSent(trackingRequestUrl: string): any;
5
+ export declare const trackRecommendationView: (target: HTMLElement, activeSectionsWithData: Section[], cioClient: Nullable<ConstructorIOClient>) => void;
6
+ export declare const trackSearchSubmit: (cioClient: any, term: any, autocompleteData?: {}) => void;
7
+ export declare const trackAutocompleteSelect: (cioClient: any, itemName: any, autocompleteData?: any) => void;
@@ -1,2 +1,2 @@
1
- declare const _default: "1.23.26";
1
+ declare const _default: "1.23.29";
2
2
  export default _default;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@constructor-io/constructorio-ui-autocomplete",
3
- "version": "1.23.26",
3
+ "version": "1.23.29",
4
4
  "description": "Constructor.io Autocomplete UI library for web applications",
5
5
  "main": "lib/cjs/index.js",
6
6
  "module": "lib/mjs/index.js",
package/lib/cjs/utils.js DELETED
@@ -1,259 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.logger = exports.trackAutocompleteSelect = exports.trackSearchSubmit = exports.translate = exports.getItemsForActiveSections = exports.trackRecommendationView = exports.escapeRegExp = exports.getActiveSectionsWithData = exports.getCioClient = exports.disableStoryActions = exports.stringifyWithDefaults = exports.functionStrings = exports.getStoryParams = exports.sleep = exports.clearConstructorRequests = exports.isTrackingRequestSent = exports.toKebabCase = exports.camelToStartCase = exports.getItemPosition = exports.getFeatures = void 0;
4
- const tslib_1 = require("tslib");
5
- const constructorio_client_javascript_1 = tslib_1.__importDefault(require("@constructor-io/constructorio-client-javascript"));
6
- // eslint-disable-next-line import/no-cycle
7
- const beaconUtils_1 = require("./beaconUtils");
8
- const typeGuards_1 = require("./typeGuards");
9
- const version_1 = tslib_1.__importDefault(require("./version"));
10
- function getFeatures(request) {
11
- var _a, _b;
12
- let featureDisplaySearchSuggestionImages = false;
13
- let featureDisplaySearchSuggestionResultCounts = false;
14
- let featureDisplayZeroStateRecommendations = true;
15
- if (((_a = request === null || request === void 0 ? void 0 : request.features) === null || _a === void 0 ? void 0 : _a.custom_autosuggest_ui) === true) {
16
- switch ((_b = request === null || request === void 0 ? void 0 : request.feature_variants) === null || _b === void 0 ? void 0 : _b.custom_autosuggest_ui) {
17
- case 'custom_autosuggest_ui_result_count':
18
- featureDisplaySearchSuggestionResultCounts = true;
19
- break;
20
- case 'custom_autosuggest_ui_image':
21
- featureDisplaySearchSuggestionImages = true;
22
- break;
23
- case 'custom_autosuggest_ui_image_result_count':
24
- featureDisplaySearchSuggestionImages = true;
25
- featureDisplaySearchSuggestionResultCounts = true;
26
- break;
27
- case 'custom_autosuggest_ui_disable_recommendations_in_zero_state':
28
- featureDisplayZeroStateRecommendations = false;
29
- break;
30
- default:
31
- break;
32
- }
33
- }
34
- return {
35
- featureDisplaySearchSuggestionImages,
36
- featureDisplaySearchSuggestionResultCounts,
37
- featureDisplayZeroStateRecommendations,
38
- };
39
- }
40
- exports.getFeatures = getFeatures;
41
- const getItemPosition = ({ item, items }) => {
42
- var _a;
43
- const index = items.findIndex((itemInFlatList) => (itemInFlatList === null || itemInFlatList === void 0 ? void 0 : itemInFlatList.id) === (item === null || item === void 0 ? void 0 : item.id));
44
- const sectionId = (_a = items[index]) === null || _a === void 0 ? void 0 : _a.section;
45
- return { sectionId, index };
46
- };
47
- exports.getItemPosition = getItemPosition;
48
- const camelToStartCase = (camelCaseString) => camelCaseString
49
- // insert a space between lower & upper
50
- .replace(/([a-z])([A-Z])/g, '$1 $2')
51
- // space before last upper in a sequence followed by lower
52
- .replace(/\b([A-Z]+)([A-Z])([a-z])/, '$1 $2$3')
53
- // uppercase the first letter
54
- .replace(/([a-zA-Z])/, (str) => str.toUpperCase());
55
- exports.camelToStartCase = camelToStartCase;
56
- const toKebabCase = (str) => str
57
- .replace(/([A-Z])([A-Z][a-z])/g, '$1-$2')
58
- .replace(/([a-z])([A-Z])/g, '$1-$2')
59
- .replace(/[\s_]+/g, '-')
60
- .toLowerCase();
61
- exports.toKebabCase = toKebabCase;
62
- function isTrackingRequestSent(trackingRequestUrl) {
63
- var _a, _b;
64
- // eslint-disable-next-line
65
- const trackingRequestsQueue = (_a = window.localStorage) === null || _a === void 0 ? void 0 : _a._constructorio_requests;
66
- return (trackingRequestsQueue &&
67
- ((_b = JSON.parse(trackingRequestsQueue)) === null || _b === void 0 ? void 0 : _b.some((request) => { var _a; return (_a = request === null || request === void 0 ? void 0 : request.url) === null || _a === void 0 ? void 0 : _a.includes(trackingRequestUrl); })));
68
- }
69
- exports.isTrackingRequestSent = isTrackingRequestSent;
70
- function clearConstructorRequests() {
71
- var _a;
72
- // eslint-disable-next-line
73
- if ((_a = window.localStorage) === null || _a === void 0 ? void 0 : _a._constructorio_requests) {
74
- window.localStorage.removeItem('_constructorio_requests');
75
- }
76
- }
77
- exports.clearConstructorRequests = clearConstructorRequests;
78
- // Function to emulate pausing between interactions
79
- function sleep(ms) {
80
- // eslint-disable-next-line
81
- return new Promise((resolve) => setTimeout(resolve, ms));
82
- }
83
- exports.sleep = sleep;
84
- // More on Story layout: https://storybook.js.org/docs/react/configure/story-layout
85
- const getStoryParams = (storyCode, templateCode, importCode) => {
86
- const code = `
87
- ${importCode}
88
- ${storyCode}
89
- ${templateCode}
90
- `;
91
- return {
92
- docs: {
93
- source: {
94
- code,
95
- language: 'jsx',
96
- format: true,
97
- type: 'code',
98
- },
99
- },
100
- };
101
- };
102
- exports.getStoryParams = getStoryParams;
103
- exports.functionStrings = {
104
- onSubmit: `(submitEvent) => console.dir(submitEvent)`,
105
- renderItem: `({ item, query, getItemProps }) => (
106
- <div {...getItemProps(item)}>
107
- <a href={item.data?.url}>
108
- <h3>{item.value}</h3>
109
- <img src={item.data?.image_url} alt={item.value} />
110
- </a>
111
- <p>{item.data?.price}</p>
112
- </div>
113
- )`,
114
- };
115
- const stringifyWithDefaults = (obj) => {
116
- // Stringify non-function values normally. Add a template block for functions to be replaced later
117
- let res = JSON.stringify(obj, (key, value) => (value instanceof Function ? `${key}_CODE` : value), ' ');
118
- // Replace template blocks with function strings
119
- Array.from(res.matchAll(/"(\w*)_CODE"/g)).forEach((match) => {
120
- const [codePlaceholder, key] = match;
121
- const functionString = exports.functionStrings[key];
122
- if (functionString) {
123
- res = res.replaceAll(codePlaceholder, functionString);
124
- }
125
- else {
126
- console.error(`Function string for ${key} not found.`); // eslint-disable-line
127
- }
128
- });
129
- return res;
130
- };
131
- exports.stringifyWithDefaults = stringifyWithDefaults;
132
- const disableStoryActions = (story) => {
133
- // eslint-disable-next-line
134
- story.parameters.actions = { argTypesRegex: null };
135
- };
136
- exports.disableStoryActions = disableStoryActions;
137
- const getCioClient = (apiKey, cioJsClientOptions) => {
138
- if (apiKey && typeof window !== 'undefined') {
139
- const cioClient = new constructorio_client_javascript_1.default(Object.assign({ apiKey, sendTrackingEvents: true, version: `cio-ui-autocomplete-${version_1.default}` }, cioJsClientOptions));
140
- // eslint-disable-next-line no-console
141
- cioClient.tracker.on('error', (error) => console.error(error));
142
- return cioClient;
143
- }
144
- return null;
145
- };
146
- exports.getCioClient = getCioClient;
147
- const getActiveSectionsWithData = (activeSections, sectionsResults, sectionsRefs, podsData) => {
148
- const activeSectionsWithData = [];
149
- const getSectionData = (sectionConfig) => {
150
- const { type } = sectionConfig;
151
- let sectionData;
152
- switch (type) {
153
- case 'recommendations':
154
- sectionData = sectionsResults[sectionConfig.podId];
155
- break;
156
- case 'custom':
157
- // Copy id from data to the top level
158
- sectionData = sectionConfig.data.map((item) => {
159
- var _a;
160
- 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) }));
161
- });
162
- break;
163
- default:
164
- // Autocomplete
165
- sectionData = sectionsResults[sectionConfig.indexSectionName];
166
- }
167
- return sectionData;
168
- };
169
- activeSections === null || activeSections === void 0 ? void 0 : activeSections.forEach((sectionConfig, index) => {
170
- const sectionData = getSectionData(sectionConfig);
171
- if (Array.isArray(sectionData)) {
172
- const section = Object.assign(Object.assign({}, sectionConfig), { data: sectionData });
173
- if (sectionConfig.type === 'recommendations') {
174
- section.displayName =
175
- sectionConfig.displayName || podsData[sectionConfig.podId].displayName;
176
- }
177
- // If ref passed as part of `SectionConfiguration`, use it.
178
- // Otherwise, use the ref from our library generated refs array
179
- const userDefinedSectionRef = sectionConfig.ref;
180
- const libraryGeneratedSectionRef = sectionsRefs.current[index];
181
- section.ref = userDefinedSectionRef || libraryGeneratedSectionRef;
182
- activeSectionsWithData.push(section);
183
- }
184
- });
185
- return activeSectionsWithData;
186
- };
187
- exports.getActiveSectionsWithData = getActiveSectionsWithData;
188
- const escapeRegExp = (string) => string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
189
- exports.escapeRegExp = escapeRegExp;
190
- const trackRecommendationView = (target, activeSectionsWithData, cioClient) => {
191
- if (target.dataset.cnstrcRecommendationsPodId) {
192
- // Pull recommendations from activeSectionsWithData by podId surfaced on target
193
- const recommendationSection = activeSectionsWithData.find((section) => (0, typeGuards_1.isRecommendationsSection)(section) &&
194
- section.podId === target.dataset.cnstrcRecommendationsPodId);
195
- const recommendationItems = recommendationSection === null || recommendationSection === void 0 ? void 0 : recommendationSection.data.map((item) => {
196
- var _a, _b;
197
- return ({
198
- itemId: (_a = item.data) === null || _a === void 0 ? void 0 : _a.id,
199
- itemName: item.value,
200
- variationId: (_b = item.data) === null || _b === void 0 ? void 0 : _b.variation_id,
201
- });
202
- });
203
- cioClient === null || cioClient === void 0 ? void 0 : cioClient.tracker.trackRecommendationView({
204
- podId: target.dataset.cnstrcRecommendationsPodId,
205
- numResultsViewed: (recommendationItems === null || recommendationItems === void 0 ? void 0 : recommendationItems.length) || 0,
206
- url: window.location.href,
207
- section: target.dataset.cnstrcSection,
208
- items: recommendationItems,
209
- });
210
- }
211
- };
212
- exports.trackRecommendationView = trackRecommendationView;
213
- const getItemsForActiveSections = (activeSectionsWithData) => {
214
- const items = [];
215
- activeSectionsWithData === null || activeSectionsWithData === void 0 ? void 0 : activeSectionsWithData.forEach((config) => {
216
- if (config === null || config === void 0 ? void 0 : config.data) {
217
- items.push(...config.data);
218
- }
219
- });
220
- return items;
221
- };
222
- exports.getItemsForActiveSections = getItemsForActiveSections;
223
- const translate = (word, translations) => {
224
- const localTranslations = {
225
- in: 'in',
226
- 'show all results': 'show all results',
227
- };
228
- if (translations)
229
- return translations[word];
230
- return localTranslations[word] || word;
231
- };
232
- exports.translate = translate;
233
- const trackSearchSubmit = (cioClient, term, autocompleteData = {}) => {
234
- cioClient === null || cioClient === void 0 ? void 0 : cioClient.tracker.trackSearchSubmit(term, autocompleteData);
235
- (0, beaconUtils_1.storageSetItem)(beaconUtils_1.CONSTANTS.SEARCH_TERM_STORAGE_KEY, term);
236
- (0, beaconUtils_1.storeRecentSearch)(term, {});
237
- (0, beaconUtils_1.storeRecentAction)(beaconUtils_1.CONSTANTS.SEARCH_SUBMIT);
238
- };
239
- exports.trackSearchSubmit = trackSearchSubmit;
240
- const trackAutocompleteSelect = (cioClient, itemName, autocompleteData = {}) => {
241
- cioClient === null || cioClient === void 0 ? void 0 : cioClient.tracker.trackAutocompleteSelect(itemName, autocompleteData);
242
- if ((autocompleteData === null || autocompleteData === void 0 ? void 0 : autocompleteData.section) === 'Products') {
243
- (0, beaconUtils_1.storageRemoveItem)(beaconUtils_1.CONSTANTS.SEARCH_TERM_STORAGE_KEY);
244
- }
245
- };
246
- exports.trackAutocompleteSelect = trackAutocompleteSelect;
247
- const logger = (error) => {
248
- var _a;
249
- try {
250
- if (typeof process !== 'undefined' && ((_a = process === null || process === void 0 ? void 0 : process.env) === null || _a === void 0 ? void 0 : _a.LOGGER)) {
251
- // eslint-disable-next-line no-console
252
- console.log(error);
253
- }
254
- }
255
- catch (e) {
256
- // process variable is not available and logger should not be active
257
- }
258
- };
259
- exports.logger = logger;