@searchspring/snap-preact 0.25.1 → 0.27.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.
Files changed (35) hide show
  1. package/dist/cjs/Instantiators/RecommendationInstantiator.d.ts +20 -21
  2. package/dist/cjs/Instantiators/RecommendationInstantiator.d.ts.map +1 -1
  3. package/dist/cjs/Instantiators/RecommendationInstantiator.js +75 -50
  4. package/dist/cjs/Snap.d.ts +17 -15
  5. package/dist/cjs/Snap.d.ts.map +1 -1
  6. package/dist/cjs/Snap.js +314 -236
  7. package/dist/cjs/components/BranchOverride.d.ts +1 -6
  8. package/dist/cjs/components/BranchOverride.d.ts.map +1 -1
  9. package/dist/cjs/components/BranchOverride.js +2 -234
  10. package/dist/cjs/create/index.d.ts +1 -1
  11. package/dist/cjs/create/index.d.ts.map +1 -1
  12. package/dist/cjs/create/index.js +2 -2
  13. package/dist/cjs/getBundleDetails/getBundleDetails.d.ts +7 -0
  14. package/dist/cjs/getBundleDetails/getBundleDetails.d.ts.map +1 -0
  15. package/dist/cjs/getBundleDetails/getBundleDetails.js +64 -0
  16. package/dist/cjs/types.d.ts +1 -0
  17. package/dist/cjs/types.d.ts.map +1 -1
  18. package/dist/esm/Instantiators/RecommendationInstantiator.d.ts +20 -21
  19. package/dist/esm/Instantiators/RecommendationInstantiator.d.ts.map +1 -1
  20. package/dist/esm/Instantiators/RecommendationInstantiator.js +63 -40
  21. package/dist/esm/Snap.d.ts +17 -15
  22. package/dist/esm/Snap.d.ts.map +1 -1
  23. package/dist/esm/Snap.js +157 -111
  24. package/dist/esm/components/BranchOverride.d.ts +1 -6
  25. package/dist/esm/components/BranchOverride.d.ts.map +1 -1
  26. package/dist/esm/components/BranchOverride.js +1 -172
  27. package/dist/esm/create/index.d.ts +1 -1
  28. package/dist/esm/create/index.d.ts.map +1 -1
  29. package/dist/esm/create/index.js +1 -1
  30. package/dist/esm/getBundleDetails/getBundleDetails.d.ts +7 -0
  31. package/dist/esm/getBundleDetails/getBundleDetails.d.ts.map +1 -0
  32. package/dist/esm/getBundleDetails/getBundleDetails.js +22 -0
  33. package/dist/esm/types.d.ts +1 -0
  34. package/dist/esm/types.d.ts.map +1 -1
  35. package/package.json +13 -12
package/dist/esm/Snap.js CHANGED
@@ -7,18 +7,46 @@ import { Logger, LogMode } from '@searchspring/snap-logger';
7
7
  import { Tracker } from '@searchspring/snap-tracker';
8
8
  import { version, DomTargeter, url, cookies, featureFlags } from '@searchspring/snap-toolbox';
9
9
  import { getContext } from '@searchspring/snap-toolbox';
10
+ import { ControllerTypes } from '@searchspring/snap-controller';
10
11
  import { default as createSearchController } from './create/createSearchController';
11
- const BRANCH_COOKIE = 'ssBranch';
12
- const SS_DEV_COOKIE = 'ssDev';
13
- var DynamicImportNames;
14
- (function (DynamicImportNames) {
15
- DynamicImportNames["SEARCH"] = "searchController";
16
- DynamicImportNames["AUTOCOMPLETE"] = "autocompleteController";
17
- DynamicImportNames["FINDER"] = "finderController";
18
- DynamicImportNames["RECOMMENDATION"] = "recommendationController";
19
- })(DynamicImportNames || (DynamicImportNames = {}));
12
+ export const BRANCH_COOKIE = 'ssBranch';
13
+ export const SS_DEV_COOKIE = 'ssDev';
14
+ const COMPONENT_ERROR = `Uncaught Error - Invalid value passed as the component.
15
+ This usually happens when you pass a JSX Element, and not a function that returns the component, in the snap config.
16
+
17
+ instead of -
18
+
19
+ targeters: [
20
+ {
21
+ selector: '#searchspring-content',
22
+ hideTarget: true,
23
+ component: <Content/>,
24
+ },
25
+ ]
26
+
27
+ or -
28
+
29
+ targeters: [
30
+ {
31
+ selector: '#searchspring-content',
32
+ hideTarget: true,
33
+ component: Content,
34
+ },
35
+ ]
36
+
37
+ please try -
38
+
39
+ targeters: [
40
+ {
41
+ selector: '#searchspring-content',
42
+ hideTarget: true,
43
+ component: () => Content
44
+ },
45
+ ]
46
+
47
+ The error above happened in the following targeter in the Snap Config`;
20
48
  export class Snap {
21
- constructor(config) {
49
+ constructor(config, services) {
22
50
  this.getInstantiator = (id) => {
23
51
  return this._instantiatorPromises[id] || Promise.reject(`getInstantiator could not find instantiator with id: ${id}`);
24
52
  };
@@ -30,44 +58,45 @@ export class Snap {
30
58
  controllerIds.forEach((id) => getControllerPromises.push(this.getController(id)));
31
59
  return Promise.all(getControllerPromises);
32
60
  };
33
- this.createController = (type, config, services, urlConfig, resolve, context) => {
61
+ this.createController = async (type, config, services, urlConfig, context, callback) => {
34
62
  let importPromise;
35
63
  switch (type) {
36
- case DynamicImportNames.SEARCH:
64
+ case ControllerTypes.search:
37
65
  importPromise = import('./create/createSearchController');
38
66
  break;
39
- case DynamicImportNames.AUTOCOMPLETE:
67
+ case ControllerTypes.autocomplete:
40
68
  importPromise = import('./create/createAutocompleteController');
41
69
  break;
42
- case DynamicImportNames.FINDER:
70
+ case ControllerTypes.finder:
43
71
  importPromise = import('./create/createFinderController');
44
72
  break;
45
- case DynamicImportNames.RECOMMENDATION:
73
+ case ControllerTypes.recommendation:
46
74
  importPromise = import('./create/createRecommendationController');
47
75
  break;
48
76
  }
49
- return importPromise.then((_) => {
50
- if (!this.controllers[config.id]) {
51
- this.controllers[config.id] = _.default({
52
- url: deepmerge(this.config.url || {}, urlConfig || {}),
53
- controller: config,
54
- context: deepmerge(this.context || {}, context || {}),
55
- }, {
56
- client: services?.client || this.client,
57
- store: services?.store,
58
- urlManager: services?.urlManager,
59
- eventManager: services?.eventManager,
60
- profiler: services?.profiler,
61
- logger: services?.logger,
62
- tracker: services?.tracker || this.tracker,
63
- });
64
- resolve(this.controllers[config.id]);
65
- }
66
- return this.controllers[config.id];
67
- });
77
+ const creationFunc = (await importPromise).default;
78
+ if (!this.controllers[config.id]) {
79
+ this.controllers[config.id] = creationFunc({
80
+ url: deepmerge(this.config.url || {}, urlConfig || {}),
81
+ controller: config,
82
+ context: deepmerge(this.context || {}, context || {}),
83
+ }, {
84
+ client: services?.client || this.client,
85
+ store: services?.store,
86
+ urlManager: services?.urlManager,
87
+ eventManager: services?.eventManager,
88
+ profiler: services?.profiler,
89
+ logger: services?.logger,
90
+ tracker: services?.tracker || this.tracker,
91
+ });
92
+ }
93
+ if (callback) {
94
+ await callback(this.controllers[config.id]);
95
+ }
96
+ return this.controllers[config.id];
68
97
  };
69
98
  this.config = config;
70
- this.logger = new Logger('Snap Preact ');
99
+ this.logger = services?.logger || new Logger('Snap Preact ');
71
100
  let globalContext = {};
72
101
  try {
73
102
  // get global context
@@ -80,12 +109,14 @@ export class Snap {
80
109
  this.config = deepmerge(this.config || {}, globalContext.config || {}, {
81
110
  isMergeableObject: isPlainObject,
82
111
  });
83
- this.context = deepmerge(globalContext || {}, this.config.context || {});
84
- if (!this.config?.client?.globals?.siteId) {
112
+ this.context = deepmerge(this.config.context || {}, globalContext || {}, {
113
+ isMergeableObject: isPlainObject,
114
+ });
115
+ if ((!services?.client || !services?.tracker) && !this.config?.client?.globals?.siteId) {
85
116
  throw new Error(`Snap: config provided must contain a valid config.client.globals.siteId value`);
86
117
  }
87
- this.client = new Client(this.config.client.globals, this.config.client.config);
88
- this.tracker = new Tracker(this.config.client.globals);
118
+ this.client = services?.client || new Client(this.config.client.globals, this.config.client.config);
119
+ this.tracker = services?.tracker || new Tracker(this.config.client.globals);
89
120
  this._controllerPromises = {};
90
121
  this._instantiatorPromises = {};
91
122
  this.controllers = {};
@@ -111,12 +142,21 @@ export class Snap {
111
142
  }
112
143
  this.logger.setMode(LogMode.DEVELOPMENT);
113
144
  this.logger.warn(`...loading build... '${branchParam}'`);
145
+ // get the path and siteId from the current bundle script in case its not the same as the client config
146
+ let path = `https://snapui.searchspring.io/${this.config.client.globals.siteId}/`;
147
+ const script = document.querySelector('script[src*="//snapui.searchspring.io"]');
148
+ if (script) {
149
+ const scriptRoot = script.getAttribute('src').match(/\/\/snapui.searchspring.io\/[a-zA-Z0-9]{6}\//);
150
+ if (scriptRoot) {
151
+ path = scriptRoot.toString();
152
+ }
153
+ }
114
154
  // append script with new branch in path
115
- const script = document.createElement('script');
116
- const src = `https://snapui.searchspring.io/${this.config.client.globals.siteId}/${branchParam}/bundle.js`;
117
- script.src = src;
118
- script.setAttribute(BRANCH_COOKIE, '');
119
- document.head.appendChild(script);
155
+ const branchScript = document.createElement('script');
156
+ const src = `${path}${branchParam}/bundle.js`;
157
+ branchScript.src = src;
158
+ branchScript.setAttribute(BRANCH_COOKIE, branchParam);
159
+ document.head.appendChild(branchScript);
120
160
  new DomTargeter([
121
161
  {
122
162
  selector: 'body',
@@ -124,14 +164,27 @@ export class Snap {
124
164
  action: 'append',
125
165
  element: () => {
126
166
  const branchContainer = document.createElement('div');
127
- branchContainer.className = 'ss__branch--target';
167
+ branchContainer.id = 'searchspring-branch-override';
128
168
  return branchContainer;
129
169
  },
130
170
  },
131
171
  },
132
172
  ], async (target, elem) => {
173
+ let bundleDetails, error;
174
+ try {
175
+ const getBundleDetails = (await import('./getBundleDetails/getBundleDetails')).getBundleDetails;
176
+ bundleDetails = await getBundleDetails(src);
177
+ }
178
+ catch (err) {
179
+ error = err;
180
+ }
133
181
  const BranchOverride = (await import('./components/BranchOverride')).BranchOverride;
134
- render(_jsx(BranchOverride, { branch: branchParam, cookieName: BRANCH_COOKIE, bundleUrl: src }), elem);
182
+ render(_jsx(BranchOverride, { name: branchParam, details: bundleDetails, error: error, onRemoveClick: () => {
183
+ cookies.unset(BRANCH_COOKIE);
184
+ const urlState = url(window.location.href);
185
+ delete urlState.params.query['branch'];
186
+ window.location.href = urlState.url();
187
+ } }), elem);
135
188
  });
136
189
  // prevent further instantiation of config
137
190
  return;
@@ -187,7 +240,7 @@ export class Snap {
187
240
  const targetFunction = async (target, elem, originalElem) => {
188
241
  runSearch();
189
242
  const onTarget = target.onTarget;
190
- onTarget && onTarget(target, elem, originalElem);
243
+ onTarget && (await onTarget(target, elem, originalElem));
191
244
  try {
192
245
  const Component = await target.component();
193
246
  setTimeout(() => {
@@ -195,44 +248,10 @@ export class Snap {
195
248
  });
196
249
  }
197
250
  catch (err) {
198
- this.logger.error(`Uncaught Error - Invalid value passed as the component.
199
- This usually happens when you pass a JSX Element, and not a function that returns the component, in the snap config.
200
-
201
- instead of -
202
-
203
- targeters: [
204
- {
205
- selector: '#searchspring-content',
206
- hideTarget: true,
207
- component: <Content/>,
208
- },
209
- ]
210
-
211
- or -
212
-
213
- targeters: [
214
- {
215
- selector: '#searchspring-content',
216
- hideTarget: true,
217
- component: Content,
218
- },
219
- ]
220
-
221
- please try -
222
-
223
- targeters: [
224
- {
225
- selector: '#searchspring-content',
226
- hideTarget: true,
227
- component: () => Content
228
- },
229
- ]
230
-
231
-
232
- The error above happened in the following targeter in the Snap Config`, target);
251
+ this.logger.error(COMPONENT_ERROR, target);
233
252
  }
234
253
  };
235
- controller?.targeters?.forEach(async (target, target_index) => {
254
+ controller?.targeters?.forEach((target, target_index) => {
236
255
  if (!target.selector) {
237
256
  throw new Error(`Targets at index ${target_index} missing selector value (string).`);
238
257
  }
@@ -274,16 +293,23 @@ The error above happened in the following targeter in the Snap Config`, target);
274
293
  };
275
294
  const targetFunction = async (target, elem, originalElem) => {
276
295
  const onTarget = target.onTarget;
277
- onTarget && onTarget(target, elem, originalElem);
278
- const Component = (await target.component());
279
- setTimeout(() => {
280
- render(_jsx(Component, { controller: this.controllers[controller.config.id], input: originalElem, ...target.props }), elem);
281
- });
296
+ onTarget && (await onTarget(target, elem, originalElem));
297
+ try {
298
+ const Component = (await target.component());
299
+ setTimeout(() => {
300
+ render(_jsx(Component, { controller: this.controllers[controller.config.id], input: originalElem, ...target.props }), elem);
301
+ });
302
+ }
303
+ catch (err) {
304
+ this.logger.error(COMPONENT_ERROR, target);
305
+ }
282
306
  };
283
307
  if (!controller?.targeters || controller?.targeters.length === 0) {
284
- this.createController(DynamicImportNames.AUTOCOMPLETE, controller.config, controller.services, controller.url, resolve, controller.context);
308
+ this.createController(ControllerTypes.autocomplete, controller.config, controller.services, controller.url, controller.context, (cntrlr) => {
309
+ resolve(cntrlr);
310
+ });
285
311
  }
286
- controller?.targeters?.forEach(async (target, target_index) => {
312
+ controller?.targeters?.forEach((target, target_index) => {
287
313
  if (!target.selector) {
288
314
  throw new Error(`Targets at index ${target_index} missing selector value (string).`);
289
315
  }
@@ -306,7 +332,9 @@ The error above happened in the following targeter in the Snap Config`, target);
306
332
  ...target,
307
333
  },
308
334
  ], async (target, elem, originalElem) => {
309
- const cntrlr = await this.createController(DynamicImportNames.AUTOCOMPLETE, controller.config, controller.services, controller.url, resolve, controller.context);
335
+ const cntrlr = await this.createController(ControllerTypes.autocomplete, controller.config, controller.services, controller.url, controller.context, (cntrlr) => {
336
+ resolve(cntrlr);
337
+ });
310
338
  runBind();
311
339
  targetFunction({ controller: cntrlr, ...target }, elem, originalElem);
312
340
  cntrlr.addTargeter(targeter);
@@ -333,16 +361,23 @@ The error above happened in the following targeter in the Snap Config`, target);
333
361
  };
334
362
  const targetFunction = async (target, elem, originalElem) => {
335
363
  const onTarget = target.onTarget;
336
- onTarget && onTarget(target, elem, originalElem);
337
- const Component = await target.component();
338
- setTimeout(() => {
339
- render(_jsx(Component, { controller: this.controllers[controller.config.id], ...target.props }), elem);
340
- });
364
+ onTarget && (await onTarget(target, elem, originalElem));
365
+ try {
366
+ const Component = await target.component();
367
+ setTimeout(() => {
368
+ render(_jsx(Component, { controller: this.controllers[controller.config.id], ...target.props }), elem);
369
+ });
370
+ }
371
+ catch (err) {
372
+ this.logger.error(COMPONENT_ERROR, target);
373
+ }
341
374
  };
342
375
  if (!controller?.targeters || controller?.targeters.length === 0) {
343
- this.createController(DynamicImportNames.FINDER, controller.config, controller.services, controller.url, resolve, controller.context);
376
+ this.createController(ControllerTypes.finder, controller.config, controller.services, controller.url, controller.context, (cntrlr) => {
377
+ resolve(cntrlr);
378
+ });
344
379
  }
345
- controller?.targeters?.forEach(async (target, target_index) => {
380
+ controller?.targeters?.forEach((target, target_index) => {
346
381
  if (!target.selector) {
347
382
  throw new Error(`Targets at index ${target_index} missing selector value (string).`);
348
383
  }
@@ -350,7 +385,9 @@ The error above happened in the following targeter in the Snap Config`, target);
350
385
  throw new Error(`Targets at index ${target_index} missing component value (Component).`);
351
386
  }
352
387
  const targeter = new DomTargeter([{ ...target }], async (target, elem, originalElem) => {
353
- const cntrlr = await this.createController(DynamicImportNames.FINDER, controller.config, controller.services, controller.url, resolve, controller.context);
388
+ const cntrlr = await this.createController(ControllerTypes.finder, controller.config, controller.services, controller.url, controller.context, (cntrlr) => {
389
+ resolve(cntrlr);
390
+ });
354
391
  runSearch();
355
392
  targetFunction({ controller: cntrlr, ...target }, elem, originalElem);
356
393
  cntrlr.addTargeter(targeter);
@@ -377,16 +414,23 @@ The error above happened in the following targeter in the Snap Config`, target);
377
414
  };
378
415
  const targetFunction = async (target, elem, originalElem) => {
379
416
  const onTarget = target.onTarget;
380
- onTarget && onTarget(target, elem, originalElem);
381
- const Component = await target.component();
382
- setTimeout(() => {
383
- render(_jsx(Component, { controller: this.controllers[controller.config.id], ...target.props }), elem);
384
- });
417
+ onTarget && (await onTarget(target, elem, originalElem));
418
+ try {
419
+ const Component = await target.component();
420
+ setTimeout(() => {
421
+ render(_jsx(Component, { controller: this.controllers[controller.config.id], ...target.props }), elem);
422
+ });
423
+ }
424
+ catch (err) {
425
+ this.logger.error(COMPONENT_ERROR, target);
426
+ }
385
427
  };
386
428
  if (!controller?.targeters || controller?.targeters.length === 0) {
387
- this.createController(DynamicImportNames.RECOMMENDATION, controller.config, controller.services, controller.url, resolve, controller.context);
429
+ this.createController(ControllerTypes.recommendation, controller.config, controller.services, controller.url, controller.context, (cntrlr) => {
430
+ resolve(cntrlr);
431
+ });
388
432
  }
389
- controller?.targeters?.forEach(async (target, target_index) => {
433
+ controller?.targeters?.forEach((target, target_index) => {
390
434
  if (!target.selector) {
391
435
  throw new Error(`Targets at index ${target_index} missing selector value (string).`);
392
436
  }
@@ -394,7 +438,9 @@ The error above happened in the following targeter in the Snap Config`, target);
394
438
  throw new Error(`Targets at index ${target_index} missing component value (Component).`);
395
439
  }
396
440
  const targeter = new DomTargeter([{ ...target }], async (target, elem, originalElem) => {
397
- const cntrlr = await this.createController(DynamicImportNames.RECOMMENDATION, controller.config, controller.services, controller.url, resolve, controller.context);
441
+ const cntrlr = await this.createController(ControllerTypes.recommendation, controller.config, controller.services, controller.url, controller.context, (cntrlr) => {
442
+ resolve(cntrlr);
443
+ });
398
444
  runSearch();
399
445
  targetFunction({ controller: cntrlr, ...target }, elem, originalElem);
400
446
  cntrlr.addTargeter(targeter);
@@ -412,11 +458,11 @@ The error above happened in the following targeter in the Snap Config`, target);
412
458
  });
413
459
  if (this.config?.instantiators?.recommendation) {
414
460
  try {
415
- this._instantiatorPromises.recommendations = import('./Instantiators/RecommendationInstantiator').then(({ RecommendationInstantiator }) => {
461
+ this._instantiatorPromises.recommendation = import('./Instantiators/RecommendationInstantiator').then(({ RecommendationInstantiator }) => {
416
462
  return new RecommendationInstantiator(this.config.instantiators.recommendation, {
417
- client: this.config.instantiators.recommendation?.services?.client || this.client,
418
- tracker: this.config.instantiators.recommendation?.services?.tracker || this.tracker,
419
- logger: this.config.instantiators.recommendation?.services?.logger || this.logger,
463
+ client: this.client,
464
+ tracker: this.tracker,
465
+ logger: this.logger,
420
466
  }, this.context);
421
467
  });
422
468
  }
@@ -1,7 +1,2 @@
1
- /// <reference types="react" />
2
- export declare const BranchOverride: (props: {
3
- branch: string;
4
- cookieName: string;
5
- bundleUrl: string;
6
- }) => JSX.Element;
1
+ export { BranchOverride } from '@searchspring/snap-preact-components';
7
2
  //# sourceMappingURL=BranchOverride.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"BranchOverride.d.ts","sourceRoot":"","sources":["../../../src/components/BranchOverride.tsx"],"names":[],"mappings":";AA8IA,eAAO,MAAM,cAAc,UAAW;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,KAAG,WA+FjG,CAAC"}
1
+ {"version":3,"file":"BranchOverride.d.ts","sourceRoot":"","sources":["../../../src/components/BranchOverride.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC"}
@@ -1,172 +1 @@
1
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "preact/jsx-runtime";
2
- import { useState, useEffect } from 'preact/hooks';
3
- import { url, cookies } from '@searchspring/snap-toolbox';
4
- const icons = {
5
- 'close-thin': 'M56 5.638l-22.362 22.362 22.362 22.362-5.638 5.638-22.362-22.362-22.362 22.362-5.638-5.638 22.362-22.362-22.362-22.362 5.638-5.638 22.362 22.362 22.362-22.362z',
6
- warn: 'M31.2981 5.28228C29.8323 2.74341 26.1677 2.74341 24.7019 5.28228L0.515899 47.1737C-0.94992 49.7126 0.88235 52.8861 3.81399 52.8861H52.186C55.1176 52.8861 56.9499 49.7126 55.4841 47.1737L31.2981 5.28228ZM25.2229 35.0037L24.8264 18.837C24.8264 18.655 24.8923 18.4729 25.047 18.3686C25.1794 18.2387 25.3776 18.1601 25.5759 18.1601H30.4241C30.6223 18.1601 30.8206 18.238 30.953 18.3686C31.1071 18.4729 31.1736 18.655 31.1736 18.837L30.7988 35.0037C30.7988 35.3679 30.4682 35.6542 30.0493 35.6542H25.9724C25.5759 35.6542 25.2453 35.3679 25.2229 35.0037ZM25.1788 43.9593V39.0131C25.1788 38.5447 25.487 38.1541 25.8618 38.1541H30.0929C30.4894 38.1541 30.82 38.5447 30.82 39.0131V43.9593C30.82 44.4277 30.4894 44.8183 30.0929 44.8183H25.8618C25.487 44.8183 25.1788 44.4277 25.1788 43.9593Z',
7
- };
8
- const fetchBundleDetails = async (url) => {
9
- return new Promise((resolve, reject) => {
10
- const request = new XMLHttpRequest();
11
- request.open('HEAD', url, true);
12
- request.onreadystatechange = () => {
13
- if (request.readyState === XMLHttpRequest.DONE) {
14
- const status = request.status;
15
- if (status === 0 || (status >= 200 && status < 400)) {
16
- resolve({
17
- lastModified: request.getResponseHeader('Last-Modified').split(',')[1],
18
- });
19
- }
20
- else {
21
- reject();
22
- }
23
- }
24
- };
25
- request.onerror = () => reject();
26
- request.send();
27
- });
28
- };
29
- const darkTheme = {
30
- main: {
31
- border: '0',
32
- background: 'rgba(59, 35, 173, 0.9)',
33
- color: '#fff',
34
- boxShadow: '#4c3ce2 1px 1px 3px 0px',
35
- },
36
- top: {
37
- background: 'rgba(59, 35, 173, 0.3)',
38
- border: '1px solid #4c3de1',
39
- logo: {
40
- src: 'https://snapui.searchspring.io/searchspring_light.svg',
41
- },
42
- button: {
43
- border: '1px solid #fff',
44
- content: 'STOP PREVIEW',
45
- },
46
- close: {
47
- fill: '#fff',
48
- },
49
- },
50
- details: {
51
- content: 'Preview functionality may differ from production.',
52
- branch: {
53
- color: '#03cee1',
54
- style: 'italic',
55
- },
56
- additional: {
57
- color: '#03cee1',
58
- },
59
- },
60
- };
61
- const lightTheme = {
62
- main: {
63
- border: '1px solid #ccc',
64
- background: 'rgba(255, 255, 255, 0.9)',
65
- color: '#515151',
66
- boxShadow: 'rgba(81, 81, 81, 0.5) 1px 1px 3px 0px',
67
- },
68
- top: {
69
- background: 'rgba(255, 255, 255, 0.3)',
70
- border: '1px solid #ccc',
71
- logo: {
72
- src: 'https://snapui.searchspring.io/searchspring.svg',
73
- },
74
- button: {
75
- border: '1px solid #515151',
76
- content: 'STOP PREVIEW',
77
- },
78
- close: {
79
- fill: '#515151',
80
- },
81
- },
82
- details: {
83
- content: 'Preview functionality may differ from production.',
84
- branch: {
85
- color: '#3a23ad',
86
- style: 'italic',
87
- },
88
- additional: {
89
- color: '#3a23ad',
90
- },
91
- },
92
- };
93
- const failureTheme = {
94
- main: {
95
- border: '0',
96
- background: 'rgba(130, 6, 6, 0.9)',
97
- color: '#fff',
98
- boxShadow: 'rgba(130, 6, 6, 0.4) 1px 1px 3px 0px',
99
- },
100
- top: {
101
- background: 'rgba(130, 6, 6, 0.3)',
102
- border: '1px solid #760000',
103
- logo: {
104
- src: 'https://snapui.searchspring.io/searchspring_light.svg',
105
- },
106
- button: {
107
- border: '1px solid #fff',
108
- content: 'REMOVE',
109
- },
110
- close: {
111
- fill: '#fff',
112
- },
113
- },
114
- details: {
115
- content: 'Incorrect branch name or branch no longer exists.',
116
- branch: {
117
- color: '#be9628',
118
- style: 'none',
119
- },
120
- additional: {
121
- color: '#be9628',
122
- },
123
- },
124
- };
125
- const themes = {
126
- darkTheme,
127
- lightTheme,
128
- failureTheme,
129
- };
130
- export const BranchOverride = (props) => {
131
- const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
132
- const [themeName, setThemeName] = useState(prefersDark ? 'darkTheme' : 'lightTheme');
133
- const [details, setDetails] = useState(null);
134
- useEffect(() => {
135
- async function getDetails() {
136
- try {
137
- const details = await fetchBundleDetails(props.bundleUrl);
138
- setDetails(details);
139
- }
140
- catch (err) {
141
- setThemeName('failureTheme');
142
- setDetails('failure');
143
- }
144
- }
145
- getDetails();
146
- }, []);
147
- return (props.branch &&
148
- details && (_jsxs("div", { class: "ss__branch-override", style: `width: 360px; height: 120px; overflow: hidden; transition: height ease 0.5s 0.5s, right ease 0.5s; font-size: 14px; position: fixed; z-index: 9999; bottom: 50px; right: 0; background: ${themes[themeName].main.background}; color: ${themes[themeName].main.color}; border: ${themes[themeName].main.border}; border-right: 0; border-top-left-radius: 5px; border-bottom-left-radius: 5px; box-shadow: ${themes[themeName].main.boxShadow};`, onClick: (e) => {
149
- e.preventDefault();
150
- e.stopPropagation();
151
- const popup = document.querySelector('.ss__branch-override');
152
- popup.style.transition = 'height ease 0.2s, right ease 0.5s 0.2s';
153
- popup.style.right = '-1px';
154
- popup.style.height = '120px';
155
- popup.style.cursor = 'auto';
156
- }, children: [_jsxs("div", { style: `padding: 10px; position: relative; background: ${themes[themeName].top.background}; border-bottom: ${themes[themeName].top.border}; margin-bottom: 10px;`, children: [_jsx("img", { src: themes[themeName].top.logo.src, style: `display: inline-block; height: 30px; vertical-align: middle;` }), _jsx("div", { style: "display: inline-block; float: right; padding: 5px; cursor: pointer;", onClick: (e) => {
157
- e.preventDefault();
158
- e.stopPropagation();
159
- const popup = document.querySelector('.ss__branch-override');
160
- popup.style.transition = 'height ease 0.5s 0.5s, right ease 0.5s';
161
- popup.style.right = '-316px';
162
- popup.style.height = '50px';
163
- popup.style.cursor = 'pointer';
164
- }, children: _jsx("svg", { viewBox: "0 0 56 56", xmlns: "http://www.w3.org/2000/svg", width: "18px", height: "18px", children: _jsx("path", { fill: themes[themeName].top.close.fill, d: icons['close-thin'] }) }) }), _jsx("div", { style: `border-radius: 5px; padding: 6px; height: 100%; line-height: 14px; text-align: center; cursor: pointer; font-size: 10px; border: ${themes[themeName].top.button.border}; float: right; margin-right: 14px;`, onClick: (e) => {
165
- e.preventDefault();
166
- e.stopPropagation();
167
- cookies.unset(props.cookieName);
168
- const urlState = url(window.location.href);
169
- delete urlState.params.query['branch'];
170
- window.location.href = urlState.url();
171
- }, children: themes[themeName].top.button.content })] }), _jsxs("div", { style: "padding: 0px 15px; font-size: 12px;", children: [_jsx("span", { style: `font-weight: bold; font-style: ${themes[themeName].details.branch.style}; color: ${themes[themeName].details.branch.color}; font-size: 14px; line-height: 20px; display: inline-block; max-width: 180px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;`, children: details == 'failure' ? (_jsxs(_Fragment, { children: [_jsx("svg", { style: "margin-right: 10px;", viewBox: "0 0 56 56", xmlns: "http://www.w3.org/2000/svg", width: "18px", height: "18px", children: _jsx("path", { fill: themes[themeName].details.branch.color, d: icons['warn'] }) }), "Branch not found!"] })) : (props.branch) }), _jsx("span", { style: `float: right; font-style: italic; color: ${themes[themeName].details.additional.color}; font-size: 12px; line-height: 20px;`, children: details?.lastModified || props.branch }), _jsx("br", {}), themes[themeName].details.content] })] })));
172
- };
1
+ export { BranchOverride } from '@searchspring/snap-preact-components';
@@ -1,5 +1,5 @@
1
1
  export { default as createAutocompleteController } from './createAutocompleteController';
2
2
  export { default as createFinderController } from './createFinderController';
3
- export { default as createRecommendationsController } from './createRecommendationController';
3
+ export { default as createRecommendationController } from './createRecommendationController';
4
4
  export { default as createSearchController } from './createSearchController';
5
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/create/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,4BAA4B,EAAE,MAAM,gCAAgC,CAAC;AACzF,OAAO,EAAE,OAAO,IAAI,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAC7E,OAAO,EAAE,OAAO,IAAI,+BAA+B,EAAE,MAAM,kCAAkC,CAAC;AAC9F,OAAO,EAAE,OAAO,IAAI,sBAAsB,EAAE,MAAM,0BAA0B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/create/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,4BAA4B,EAAE,MAAM,gCAAgC,CAAC;AACzF,OAAO,EAAE,OAAO,IAAI,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAC7E,OAAO,EAAE,OAAO,IAAI,8BAA8B,EAAE,MAAM,kCAAkC,CAAC;AAC7F,OAAO,EAAE,OAAO,IAAI,sBAAsB,EAAE,MAAM,0BAA0B,CAAC"}
@@ -1,4 +1,4 @@
1
1
  export { default as createAutocompleteController } from './createAutocompleteController';
2
2
  export { default as createFinderController } from './createFinderController';
3
- export { default as createRecommendationsController } from './createRecommendationController';
3
+ export { default as createRecommendationController } from './createRecommendationController';
4
4
  export { default as createSearchController } from './createSearchController';
@@ -0,0 +1,7 @@
1
+ declare type BundleDetails = {
2
+ url: string;
3
+ lastModified: string;
4
+ };
5
+ export declare const getBundleDetails: (url: string) => Promise<BundleDetails>;
6
+ export {};
7
+ //# sourceMappingURL=getBundleDetails.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getBundleDetails.d.ts","sourceRoot":"","sources":["../../../src/getBundleDetails/getBundleDetails.ts"],"names":[],"mappings":"AAAA,aAAK,aAAa,GAAG;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,eAAO,MAAM,gBAAgB,QAAe,MAAM,KAAG,QAAQ,aAAa,CAuBzE,CAAC"}
@@ -0,0 +1,22 @@
1
+ export const getBundleDetails = async (url) => {
2
+ return new Promise((resolve, reject) => {
3
+ const request = new XMLHttpRequest();
4
+ request.open('HEAD', url, true);
5
+ request.onreadystatechange = () => {
6
+ if (request.readyState === request.DONE) {
7
+ const status = request.status;
8
+ if (status === 0 || (status >= 200 && status < 400)) {
9
+ resolve({
10
+ url,
11
+ lastModified: request.getResponseHeader('Last-Modified').split(',')[1].trim(),
12
+ });
13
+ }
14
+ else {
15
+ reject({ message: 'Branch not found!', description: 'Incorrect branch name or branch no longer exists.' });
16
+ }
17
+ }
18
+ };
19
+ request.onerror = () => reject({ message: 'Branch load fail!', description: 'There was an error with the request.' });
20
+ request.send();
21
+ });
22
+ };