@miso.ai/client-sdk-ui 1.11.4 → 1.11.5-beta.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 (39) hide show
  1. package/dist/cjs/actor/views.js +1 -0
  2. package/dist/cjs/asset/svgs.js +10 -4
  3. package/dist/cjs/constants.js +3 -2
  4. package/dist/cjs/element/role/index.js +7 -0
  5. package/dist/cjs/element/role/miso-images.js +20 -0
  6. package/dist/cjs/layout/input/option-list.js +1 -1
  7. package/dist/cjs/layout/input/select.js +1 -1
  8. package/dist/cjs/layout/list/carousel.js +43 -84
  9. package/dist/cjs/layout/list/collection.js +11 -5
  10. package/dist/cjs/layout/mixin/swipeable.js +165 -0
  11. package/dist/cjs/layout/{trackable.js → mixin/trackable.js} +4 -3
  12. package/dist/cjs/layout/{triggerable.js → mixin/triggerable.js} +2 -2
  13. package/dist/cjs/layout/radio/radio.js +11 -7
  14. package/dist/cjs/layout/templates.js +24 -5
  15. package/dist/cjs/layout/text/typewriter/index.js +2 -0
  16. package/dist/cjs/util/trackers.js +18 -5
  17. package/dist/cjs/version.js +1 -1
  18. package/dist/cjs/workflow/answer-based.js +23 -4
  19. package/dist/cjs/workflow/search.js +0 -1
  20. package/package.json +2 -2
  21. package/src/actor/views.js +1 -0
  22. package/src/asset/svgs.js +9 -1
  23. package/src/constants.js +3 -0
  24. package/src/element/role/index.js +1 -0
  25. package/src/element/role/miso-images.js +16 -0
  26. package/src/layout/input/option-list.js +1 -1
  27. package/src/layout/input/select.js +1 -1
  28. package/src/layout/list/carousel.js +39 -86
  29. package/src/layout/list/collection.js +13 -6
  30. package/src/layout/mixin/swipeable.js +162 -0
  31. package/src/layout/{trackable.js → mixin/trackable.js} +4 -3
  32. package/src/layout/{triggerable.js → mixin/triggerable.js} +2 -2
  33. package/src/layout/radio/radio.js +7 -7
  34. package/src/layout/templates.js +26 -5
  35. package/src/layout/text/typewriter/index.js +2 -1
  36. package/src/util/trackers.js +17 -4
  37. package/src/version.js +1 -1
  38. package/src/workflow/answer-based.js +14 -4
  39. package/src/workflow/search.js +0 -1
@@ -216,6 +216,7 @@ class ViewsActor {
216
216
  }
217
217
  _getTrackerOptions(role) {
218
218
  const allTrackerOptions = this._options.resolved.trackers;
219
+ // TODO: don't need this anymore
219
220
  return (0, _trackers.normalizeTrackerOptions)(allTrackerOptions && allTrackerOptions[role] || false);
220
221
  }
221
222
  _getContainerTracker() {
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.TRIANGLE = exports.SEND = exports.SEARCH = exports.ICON_NAMES = void 0;
6
+ exports.TRIANGLE_EQ = exports.TRIANGLE = exports.SEND = exports.SEARCH = exports.ICON_NAMES = exports.CHEVRON_NEGATIVE = void 0;
7
7
  exports.getIcon = getIcon;
8
8
  var _version = _interopRequireDefault(require("../version.js"));
9
9
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
@@ -18,7 +18,9 @@ const ID = `${PREFIX}-svg-${_version.default.replaceAll('.', '_')}`;
18
18
  const ICON_NAME = {
19
19
  SEND: 'send',
20
20
  SEARCH: 'search',
21
- TRIANGLE: 'triangle'
21
+ TRIANGLE: 'triangle',
22
+ TRIANGLE_EQ: 'triangle-eq',
23
+ CHEVRON_NEGATIVE: 'chevron-negative'
22
24
  };
23
25
 
24
26
  // CC0 SVGs
@@ -27,7 +29,9 @@ const ICON_SEARCH = `<symbol id="${PREFIX}-${ICON_NAME.SEARCH}" viewBox="0 0 24
27
29
 
28
30
  // Custom SVGs
29
31
  const ICON_TRIANGLE = `<symbol id="${PREFIX}-${ICON_NAME.TRIANGLE}" viewBox="-5 -5 105 105"><path d="${trianglePath(5)}"/></symbol>`;
30
- const ICONS = [ICON_SEND, ICON_SEARCH, ICON_TRIANGLE];
32
+ const ICON_TRIANGLE_EQ = `<symbol id="${PREFIX}-${ICON_NAME.TRIANGLE_EQ}" viewBox="-100 -100 200 200"><path d="M12.99 -77.5A15 15,0,0,0,-12.99 -77.5L-73.61 27.5A15 15,0,0,0,-60.62 50L60.62 50A15 15,0,0,0,73.61 27.5L12.99 -77.5Z"/></symbol>`;
33
+ const ICON_CHEVRON_NEGATIVE = `<symbol id="${PREFIX}-${ICON_NAME.CHEVRON_NEGATIVE}" viewBox="-100 -100 200 200"><path d="M100 100V-200H-200V200H200ZM-10.61 -43.94A15 15,0,0,1,10.61 -43.94L60.61 6.06A15 15,0,0,1,39.39 27.27L0 -12.12L-39.39 27.27A15 15,0,0,1,-60.61 6.06L-10.61 -43.94Z"/></symbol>`;
34
+ const ICONS = [ICON_SEND, ICON_SEARCH, ICON_TRIANGLE, ICON_TRIANGLE_EQ, ICON_CHEVRON_NEGATIVE];
31
35
  const SPRITES_SVG = `<svg id="${ID}" style="display:none;">${ICONS.join('')}</svg>`;
32
36
  let loaded = false;
33
37
  function loadSvgSprites() {
@@ -47,4 +51,6 @@ function getIcon(name) {
47
51
  }
48
52
  const SEND = exports.SEND = _icon(ICON_NAME.SEND);
49
53
  const SEARCH = exports.SEARCH = _icon(ICON_NAME.SEARCH);
50
- const TRIANGLE = exports.TRIANGLE = _icon(ICON_NAME.TRIANGLE);
54
+ const TRIANGLE = exports.TRIANGLE = _icon(ICON_NAME.TRIANGLE);
55
+ const TRIANGLE_EQ = exports.TRIANGLE_EQ = _icon(ICON_NAME.TRIANGLE_EQ);
56
+ const CHEVRON_NEGATIVE = exports.CHEVRON_NEGATIVE = _icon(ICON_NAME.CHEVRON_NEGATIVE);
@@ -25,6 +25,7 @@ const ROLE = exports.ROLE = Object.freeze({
25
25
  ITEMS: 'items',
26
26
  QUESTION: 'question',
27
27
  ANSWER: 'answer',
28
+ IMAGES: 'images',
28
29
  SOURCES: 'sources',
29
30
  RELATED_RESOURCES: 'related_resources',
30
31
  QUERY_SUGGESTIONS: 'query_suggestions',
@@ -37,11 +38,11 @@ const ROLE = exports.ROLE = Object.freeze({
37
38
  SORT: 'sort',
38
39
  ERROR: 'error'
39
40
  });
40
- const DATA_ROLE_SET = new Set([ROLE.PRODUCTS, ROLE.CATEGORIES, ROLE.ATTRIBUTES, ROLE.RESULTS, ROLE.ITEMS, ROLE.QUESTION, ROLE.ANSWER, ROLE.SOURCES, ROLE.RELATED_RESOURCES, ROLE.QUERY_SUGGESTIONS, ROLE.RELATED_QUESTIONS, ROLE.AFFILIATION, ROLE.FACETS, ROLE.TOTAL]);
41
+ const DATA_ROLE_SET = new Set([ROLE.PRODUCTS, ROLE.CATEGORIES, ROLE.ATTRIBUTES, ROLE.RESULTS, ROLE.ITEMS, ROLE.QUESTION, ROLE.ANSWER, ROLE.IMAGES, ROLE.SOURCES, ROLE.RELATED_RESOURCES, ROLE.QUERY_SUGGESTIONS, ROLE.RELATED_QUESTIONS, ROLE.AFFILIATION, ROLE.FACETS, ROLE.TOTAL]);
41
42
  function isDataRole(role) {
42
43
  return DATA_ROLE_SET.has(role);
43
44
  }
44
- const PRODUCT_ROLE_SET = new Set([ROLE.PRODUCTS, ROLE.SOURCES, ROLE.RELATED_RESOURCES]);
45
+ const PRODUCT_ROLE_SET = new Set([ROLE.PRODUCTS, ROLE.IMAGES, ROLE.SOURCES, ROLE.RELATED_RESOURCES]);
45
46
  function isProductRole(role) {
46
47
  return PRODUCT_ROLE_SET.has(role);
47
48
  }
@@ -33,6 +33,12 @@ Object.defineProperty(exports, "MisoFeedbackElement", {
33
33
  return _misoFeedback.default;
34
34
  }
35
35
  });
36
+ Object.defineProperty(exports, "MisoImagesElement", {
37
+ enumerable: true,
38
+ get: function () {
39
+ return _misoImages.default;
40
+ }
41
+ });
36
42
  Object.defineProperty(exports, "MisoKeywordsElement", {
37
43
  enumerable: true,
38
44
  get: function () {
@@ -120,6 +126,7 @@ var _misoProducts = _interopRequireDefault(require("./miso-products.js"));
120
126
  var _misoQuestion = _interopRequireDefault(require("./miso-question.js"));
121
127
  var _misoAnswer = _interopRequireDefault(require("./miso-answer.js"));
122
128
  var _misoSources = _interopRequireDefault(require("./miso-sources.js"));
129
+ var _misoImages = _interopRequireDefault(require("./miso-images.js"));
123
130
  var _misoRelatedResources = _interopRequireDefault(require("./miso-related-resources.js"));
124
131
  var _misoRelatedQuestions = _interopRequireDefault(require("./miso-related-questions.js"));
125
132
  var _misoAffiliation = _interopRequireDefault(require("./miso-affiliation.js"));
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _misoComponent = _interopRequireDefault(require("./miso-component.js"));
8
+ var _constants = require("../../constants.js");
9
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
10
+ class MisoImagesElement extends _misoComponent.default {
11
+ constructor() {
12
+ super({
13
+ role: _constants.ROLE.IMAGES
14
+ });
15
+ }
16
+ static get tagName() {
17
+ return 'miso-images';
18
+ }
19
+ }
20
+ exports.default = MisoImagesElement;
@@ -7,7 +7,7 @@ exports.default = void 0;
7
7
  var _commons = require("@miso.ai/commons");
8
8
  var _index = require("../../actor/index.js");
9
9
  var _template = _interopRequireDefault(require("../template.js"));
10
- var _trackable = require("../trackable.js");
10
+ var _trackable = require("../mixin/trackable.js");
11
11
  const _excluded = ["className", "templates"];
12
12
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
13
13
  function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.default = void 0;
7
7
  var _commons = require("@miso.ai/commons");
8
8
  var _template = _interopRequireDefault(require("../template.js"));
9
- var _trackable = require("../trackable.js");
9
+ var _trackable = require("../mixin/trackable.js");
10
10
  const _excluded = ["className", "templates"];
11
11
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
12
12
  function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
@@ -5,39 +5,60 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.default = void 0;
7
7
  var _collection = _interopRequireDefault(require("./collection.js"));
8
+ var _swipeable = require("../mixin/swipeable.js");
9
+ var _svgs = require("../../asset/svgs.js");
8
10
  const _excluded = ["className", "templates"];
9
11
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
10
12
  function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
11
13
  const TYPE = 'carousel';
12
14
  const DEFAULT_CLASSNAME = 'miso-carousel';
13
15
  const DEFAULT_TEMPLATES = Object.freeze({
14
- ready,
15
- carousel,
16
- previous: chevron,
17
- next: chevron
16
+ body,
17
+ controls,
18
+ controlContainer,
19
+ control,
20
+ controlIcon,
21
+ indexIndicator,
22
+ indexIndicatorItem: () => ``,
23
+ trigger: () => `` // no trigger element
18
24
  });
19
25
  const INHERITED_DEFAULT_TEMPLATES = Object.freeze(Object.assign({}, _collection.default.defaultTemplates, DEFAULT_TEMPLATES));
20
- function ready(layout, state) {
26
+ function body(layout, state, values) {
21
27
  const {
28
+ className,
29
+ templates
30
+ } = layout;
31
+ return `<div class="${className}__viewport"><div class="${className}__viewport-inner">${templates.list(layout, state, values)}</div></div>${templates.controls(layout, state, values)}`;
32
+ }
33
+ function controls(layout, state, values) {
34
+ const {
35
+ templates
36
+ } = layout;
37
+ return `${templates.controlContainer(layout, state, 'previous')}${templates.controlContainer(layout, state, 'next')}${templates.indexIndicator(layout, state, values)}`;
38
+ }
39
+ function controlContainer(layout, state, direction) {
40
+ const {
41
+ className,
22
42
  templates
23
43
  } = layout;
24
- const items = layout._getItems(state);
25
- const nonEmpty = items && items.length > 0;
26
- const html = Object.getPrototypeOf(layout.constructor).defaultTemplates.ready(layout, state);
27
- return nonEmpty ? templates.carousel(layout, state, html) : html;
44
+ return `<div class="${className}__control-container-${direction}">${templates.control(layout, state, direction)}</div>`;
28
45
  }
29
- function carousel(layout, state, content) {
46
+ function control(layout, state, direction) {
30
47
  const {
31
48
  className,
32
49
  templates
33
50
  } = layout;
34
- return `<div class="${className}__control-previous" data-role="previous">${templates.previous(layout, state)}</div><div class="${className}__viewport">${content}</div><div class="${className}__control-next" data-role="next">${templates.next(layout, state)}</div>`;
51
+ return `<div class="${className}__control-${direction}" data-role="${direction}">${templates.controlIcon(layout, state, direction)}</div>`;
35
52
  }
36
- function chevron(layout) {
53
+ function controlIcon(layout, state, direction) {
54
+ return _svgs.CHEVRON_NEGATIVE;
55
+ }
56
+ function indexIndicator(layout, state, values) {
37
57
  const {
38
- className
58
+ className,
59
+ templates
39
60
  } = layout;
40
- return `<svg class="${className}__control-button" shape-rendering="geometricPrecision" stroke="currentColor" stroke-width="24" fill="#fff" viewBox="-30 -30 358 572"><path d="M285.77 441c16.24 16.17 16.32 42.46.15 58.7-16.16 16.24-42.45 16.32-58.69.16l-215-214.47c-16.24-16.16-16.32-42.45-.15-58.69L227.23 12.08c16.24-16.17 42.53-16.09 58.69.15 16.17 16.24 16.09 42.54-.15 58.7l-185.5 185.04L285.77 441z"/></svg>`;
61
+ return `<ul class="${className}__index-indicator" data-role="index-indicator">${values.map(value => `<li class="${className}__index-indicator-item">${templates.indexIndicatorItem(layout, state, value)}</li>`).join('')}</ul>`;
41
62
  }
42
63
  class CarouselLayout extends _collection.default {
43
64
  static get type() {
@@ -60,82 +81,20 @@ class CarouselLayout extends _collection.default {
60
81
  className,
61
82
  templates: Object.assign({}, DEFAULT_TEMPLATES, templates)
62
83
  }, options));
63
- window.addEventListener('resize', this.syncSize = this.syncSize.bind(this));
64
- this._page = 0;
65
- this._unsubscribes = [];
84
+ this._initSwipeable();
66
85
  }
67
86
  _render(element, states, controls) {
68
87
  super._render(element, states, controls);
69
- const {
70
- state
71
- } = states;
72
- const items = this._getItems(state);
73
- this._itemCount = items ? items.length : undefined;
74
- this.syncSize();
75
- }
76
- get page() {
77
- return this._page;
78
- }
79
- get pageSize() {
80
- return this._pageSize;
88
+ this._renderSwipeable(element, states, controls);
81
89
  }
82
- next() {
83
- this._setPage(this._page + 1);
84
- }
85
- previous() {
86
- this._setPage(this._page - 1);
87
- }
88
- syncSize() {
89
- if (this._itemCount === undefined) {
90
- return; // data not ready yet
91
- }
92
- const grid = this._findGridElement();
93
- if (!grid) {
94
- return;
95
- }
96
- // update page size, page count and new page index
97
- const firstShownItemIndex = this._pageSize === undefined ? 0 : this._page * this._pageSize;
98
- const pageSize = this._pageSize = window.getComputedStyle(grid).getPropertyValue('grid-template-columns').split(' ').length;
99
- this._pageCount = Math.ceil(this._itemCount / this._pageSize);
100
- this._setPage(Math.floor(firstShownItemIndex / pageSize));
101
- }
102
- _setPage(page) {
103
- if (page < 0) {
104
- page = this._pageCount - 1;
105
- } else if (page >= this._pageCount) {
106
- page = 0;
107
- }
108
- if (page === this._page) {
109
- return;
110
- }
111
- this._page = page;
112
- const grid = this._findGridElement();
113
- if (grid) {
114
- const offset = page === 0 ? '' : `repeat(${page}, 0)`;
115
- grid.style.setProperty('grid-template-rows', `${offset} 1fr repeat(10, 0)`);
116
- }
117
- }
118
- _findGridElement() {
119
- const {
120
- element
121
- } = this._view;
122
- return element && element.querySelector(`.${this.className}__list`);
90
+ _afterRender(element, state) {
91
+ super._afterRender(element, state);
92
+ this._afterRenderSwipeable(element, state);
123
93
  }
124
94
  _onClick(event) {
95
+ this._onClickSwipeable(event);
125
96
  super._onClick(event);
126
- const element = event.target;
127
- if (element.closest(`[data-role="previous"]`)) {
128
- this.previous();
129
- return;
130
- }
131
- if (element.closest(`[data-role="next"]`)) {
132
- this.next();
133
- return;
134
- }
135
- }
136
- destroy() {
137
- window.removeEventListener('resize', this.syncSize);
138
- super.destroy();
139
97
  }
140
98
  }
141
- exports.default = CarouselLayout;
99
+ exports.default = CarouselLayout;
100
+ (0, _swipeable.makeSwipeable)(CarouselLayout.prototype);
@@ -6,8 +6,8 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.default = void 0;
7
7
  var _constants = require("../../constants.js");
8
8
  var _template = _interopRequireDefault(require("../template.js"));
9
- var _trackable = require("../trackable.js");
10
- var _triggerable = require("../triggerable.js");
9
+ var _trackable = require("../mixin/trackable.js");
10
+ var _triggerable = require("../mixin/triggerable.js");
11
11
  var _templates = require("../templates.js");
12
12
  const _excluded = ["templates", "itemType"];
13
13
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
@@ -28,16 +28,19 @@ function ready(layout, state) {
28
28
  const {
29
29
  templates
30
30
  } = layout;
31
- const values = layout._getItems(state);
31
+ const values = layout._getItems(state) || [];
32
32
 
33
33
  // TODO: handle categories, attributes, etc. by introducing sublayout
34
- if (values && values.length > 0 || state.ongoing) {
34
+ if (values.length > 0 || state.ongoing) {
35
35
  // TODO: ad-hoc ongoing?
36
- return templates.list(layout, state, values);
36
+ return templates.body(layout, state, values);
37
37
  } else {
38
38
  return templates.empty(layout, state);
39
39
  }
40
40
  }
41
+ function body(layout, state, values) {
42
+ return layout.templates.list(layout, state, values);
43
+ }
41
44
  function list(layout, state, values) {
42
45
  const {
43
46
  className,
@@ -87,16 +90,19 @@ function loading() {
87
90
  const DEFAULT_TEMPLATES = Object.freeze({
88
91
  product: _templates.product,
89
92
  article: _templates.article,
93
+ image: _templates.image,
90
94
  question: _templates.question,
91
95
  root,
92
96
  [_constants.STATUS.READY]: ready,
93
97
  empty: () => ``,
98
+ body,
94
99
  list,
95
100
  ordered: false,
96
101
  items,
97
102
  item,
98
103
  productInfoBlock: _templates.productInfoBlock,
99
104
  articleInfoBlock: _templates.articleInfoBlock,
105
+ imageInfoBlock: _templates.imageInfoBlock,
100
106
  brandBlock: _templates.brandBlock,
101
107
  titleBlock: _templates.titleBlock,
102
108
  descriptionBlock: _templates.descriptionBlock,
@@ -0,0 +1,165 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.SwipeableMixin = void 0;
7
+ exports.makeSwipeable = makeSwipeable;
8
+ var _commons = require("@miso.ai/commons");
9
+ function makeSwipeable(prototype) {
10
+ (0, _commons.mixin)(prototype, SwipeableMixin.prototype);
11
+ }
12
+ class SwipeableMixin {
13
+ _initSwipeable() {
14
+ this._swipeableContext = {
15
+ itemCount: undefined,
16
+ itemIndex: undefined,
17
+ displayedCount: undefined,
18
+ displayedIndex: undefined,
19
+ displayEventIndex: undefined
20
+ };
21
+ }
22
+
23
+ // TODO: autoplay
24
+
25
+ get itemIndex() {
26
+ return this._swipeableContext.itemIndex;
27
+ }
28
+ set itemIndex(index) {
29
+ const context = this._swipeableContext;
30
+ if (context.itemCount === undefined) {
31
+ return;
32
+ }
33
+ if (index < 0) {
34
+ index = context.itemCount - 1;
35
+ } else if (index >= context.itemCount) {
36
+ index = 0;
37
+ }
38
+ context.itemIndex = index;
39
+ (0, _commons.requestAnimationFrame)(() => this._syncSwipeableItemIndex());
40
+ }
41
+ next() {
42
+ if (this._swipeableContext.itemCount === undefined) {
43
+ return;
44
+ }
45
+ this.itemIndex++;
46
+ }
47
+ previous() {
48
+ if (this._swipeableContext.itemCount === undefined) {
49
+ return;
50
+ }
51
+ this.itemIndex--;
52
+ }
53
+ _renderSwipeable(element, states, controls) {
54
+ this._syncSwipeableItemCount(states);
55
+ this._syncSwipeableItemIndex();
56
+ }
57
+ _afterRenderSwipeable() {
58
+ this._emitSwipeableDisplayEvent();
59
+ }
60
+ _syncSwipeableItemCount() {
61
+ let {
62
+ state
63
+ } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
64
+ const context = this._swipeableContext;
65
+ const items = this._getItems(state);
66
+ const oldItemCount = context.itemCount;
67
+ const itemCount = context.itemCount = items ? items.length : undefined;
68
+ if (itemCount === oldItemCount) {
69
+ return;
70
+ }
71
+ // TODO: concern count === 0
72
+ if (itemCount === undefined) {
73
+ context.itemIndex = undefined;
74
+ } else if (oldItemCount === undefined) {
75
+ context.itemIndex = 0;
76
+ }
77
+ this._syncDisplayedSwipeableItemCount();
78
+ }
79
+ _syncDisplayedSwipeableItemCount() {
80
+ const context = this._swipeableContext;
81
+ const {
82
+ itemCount
83
+ } = context;
84
+ if (itemCount === context.displayedCount) {
85
+ return;
86
+ }
87
+ let {
88
+ element
89
+ } = this._view;
90
+ element = element.firstElementChild;
91
+ if (!element) {
92
+ return;
93
+ }
94
+ context.displayedCount = itemCount;
95
+ if (itemCount === undefined) {
96
+ element.removeAttribute('data-item-count');
97
+ } else {
98
+ element.setAttribute('data-item-count', itemCount);
99
+ }
100
+ }
101
+ _syncSwipeableItemIndex() {
102
+ const context = this._swipeableContext;
103
+ const index = context.itemIndex;
104
+ if (index === context.displayedIndex) {
105
+ return;
106
+ }
107
+ context.displayedIndex = index;
108
+ this._syncSwipeableListIndex(index);
109
+ this._syncSwipeableIndicatorIndex(index);
110
+ }
111
+ _syncSwipeableListIndex(index) {
112
+ const {
113
+ element
114
+ } = this._view;
115
+ const listElement = element && this._getListElement(element);
116
+ if (!listElement) {
117
+ return;
118
+ }
119
+ listElement.style.left = `${-index * 100}%`;
120
+ }
121
+ _syncSwipeableIndicatorIndex(index) {
122
+ const {
123
+ element
124
+ } = this._view;
125
+ const indicatorElement = element && this._getSwipeableIndicatorElement(element);
126
+ if (!indicatorElement) {
127
+ return;
128
+ }
129
+ let i = 0;
130
+ for (const item of indicatorElement.children) {
131
+ item.classList[i === index ? 'add' : 'remove']('active');
132
+ i++;
133
+ }
134
+ }
135
+ _getSwipeableIndicatorElement(element) {
136
+ return element.querySelector('[data-role="index-indicator"]');
137
+ }
138
+ _emitSwipeableDisplayEvent() {
139
+ const context = this._swipeableContext;
140
+ const index = context.displayedIndex;
141
+ if (context.displayEventIndex === index) {
142
+ return;
143
+ }
144
+ context.displayEventIndex = index;
145
+ this._view._events.emit('display', {
146
+ index
147
+ });
148
+ }
149
+ _onClickSwipeable(event) {
150
+ const {
151
+ target
152
+ } = event;
153
+ if (target.closest(`[data-role="previous"]`)) {
154
+ event.preventDefault();
155
+ this.previous();
156
+ }
157
+ if (target.closest(`[data-role="next"]`)) {
158
+ event.preventDefault();
159
+ this.next();
160
+ }
161
+ }
162
+
163
+ // TODO: swipe gesture
164
+ }
165
+ exports.SwipeableMixin = SwipeableMixin;
@@ -6,9 +6,9 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.TrackableMixin = void 0;
7
7
  exports.makeTrackable = makeTrackable;
8
8
  var _commons = require("@miso.ai/commons");
9
- var _bindings = _interopRequireDefault(require("../util/bindings.js"));
10
- var _viewables = _interopRequireDefault(require("../util/viewables.js"));
11
- var _trackers = require("../util/trackers.js");
9
+ var _bindings = _interopRequireDefault(require("../../util/bindings.js"));
10
+ var _viewables = _interopRequireDefault(require("../../util/viewables.js"));
11
+ var _trackers = require("../../util/trackers.js");
12
12
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
13
13
  function makeTrackable(prototype) {
14
14
  (0, _commons.mixin)(prototype, TrackableMixin.prototype);
@@ -96,6 +96,7 @@ class TrackableMixin {
96
96
  click: options
97
97
  } = this._view.tracker.options || {};
98
98
  if ((0, _trackers.validateClick)(options, event, binding)) {
99
+ (0, _trackers.markAsTracked)(event);
99
100
  this._view.tracker.click([binding.value]);
100
101
  }
101
102
  }
@@ -6,8 +6,8 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.TriggerableMixin = void 0;
7
7
  exports.makeTriggerable = makeTriggerable;
8
8
  var _commons = require("@miso.ai/commons");
9
- var _constants = require("../constants.js");
10
- var _index = require("../actor/index.js");
9
+ var _constants = require("../../constants.js");
10
+ var _index = require("../../actor/index.js");
11
11
  function makeTriggerable(prototype) {
12
12
  (0, _commons.mixin)(prototype, TriggerableMixin.prototype);
13
13
  }
@@ -63,7 +63,11 @@ class RadioLayout extends _template.default {
63
63
  proxyElement
64
64
  } = view;
65
65
  this._unsubscribes = [...this._unsubscribes, view.hub.on(this._field, () => this._refresh()), proxyElement.on('click', e => this._handleClick(e))];
66
- this._defaultValue ? this._select(this._defaultValue) : this._clear();
66
+ this._defaultValue ? this._select(this._defaultValue, {
67
+ silent: true
68
+ }) : this._clear({
69
+ silent: true
70
+ });
67
71
  }
68
72
  _preprocess(states, controls) {
69
73
  if (states.rendered) {
@@ -117,18 +121,18 @@ class RadioLayout extends _template.default {
117
121
  }
118
122
  this._state = undefined;
119
123
  }
120
- _select(value) {
124
+ _select(value, options) {
121
125
  this._submit({
122
126
  value
123
- });
127
+ }, options);
124
128
  }
125
- _clear() {
129
+ _clear(options) {
126
130
  this._submit({
127
131
  unselected: true
128
- });
132
+ }, options);
129
133
  }
130
- async _submit(state) {
131
- this._view.hub.update(this._field, state);
134
+ async _submit(state, options) {
135
+ this._view.hub.update(this._field, state, options);
132
136
  }
133
137
  }
134
138
  exports.default = RadioLayout;
@@ -14,7 +14,9 @@ exports.dateBlock = dateBlock;
14
14
  exports.descriptionBlock = descriptionBlock;
15
15
  exports.discountRateText = discountRateText;
16
16
  exports.helpers = void 0;
17
+ exports.image = image;
17
18
  exports.imageBlock = imageBlock;
19
+ exports.imageInfoBlock = imageInfoBlock;
18
20
  exports.indexBlock = indexBlock;
19
21
  exports.priceBlock = priceBlock;
20
22
  exports.product = product;
@@ -59,6 +61,13 @@ function article(layout, state, data, meta) {
59
61
  const [openTag, closeTag] = tagPair(layout, data);
60
62
  return [openTag, (templates.imageBlock || imageBlock)(layout, data, meta), (templates.infoBlock || templates.articleInfoBlock || articleInfoBlock)(layout, data, meta), (templates.indexBlock || indexBlock)(layout, data, meta), closeTag].join('');
61
63
  }
64
+ function image(layout, state, data, meta) {
65
+ const {
66
+ templates
67
+ } = layout;
68
+ const [openTag, closeTag] = tagPair(layout, data);
69
+ return [openTag, (templates.imageBlock || imageBlock)(layout, data, meta), (templates.infoBlock || templates.imageInfoBlock || imageInfoBlock)(layout, data, meta), closeTag].join('');
70
+ }
62
71
  function affiliation(layout, state, data, meta) {
63
72
  const {
64
73
  templates
@@ -91,6 +100,13 @@ function articleInfoBlock(layout, data, meta) {
91
100
  } = layout;
92
101
  return `<div class="${className}__item-info-container">${[(templates.titleBlock || titleBlock)(layout, data, meta), (templates.dateBlock || dateBlock)(layout, data, meta), (templates.descriptionBlock || descriptionBlock)(layout, data, meta), (templates.ctaBlock || ctaBlock)(layout, data, meta)].join('')}</div>`;
93
102
  }
103
+ function imageInfoBlock(layout, data, meta) {
104
+ const {
105
+ className,
106
+ templates
107
+ } = layout;
108
+ return `<div class="${className}__item-info-container">${[(templates.titleBlock || titleBlock)(layout, data, meta)].join('')}</div>`;
109
+ }
94
110
  function titleBlock(_ref, _ref2) {
95
111
  let {
96
112
  className
@@ -182,14 +198,17 @@ function imageBlock(layout, data) {
182
198
  templates
183
199
  } = layout;
184
200
  const {
185
- cover_image
201
+ cover_image,
202
+ image_src,
203
+ image_alt
186
204
  } = data;
187
- if (!cover_image) {
205
+ if (!cover_image && !image_src) {
188
206
  return '';
189
207
  }
190
- const img = `<img class="${className}__item-cover-image" src="${cover_image}">`;
191
- const brand = meta.brand ? (templates.brandBlock || brandBlock)(layout, data, meta) : '';
192
- return `<div class="${className}__item-cover-image-container">${img}${brand}</div>`;
208
+ const subtype = image_src ? 'image' : 'cover-image';
209
+ const img = subtype === 'image' ? `<img class="${className}__item-${subtype}" src="${image_src}"${image_alt ? ` alt="${image_alt}"` : ''}>` : `<img class="${className}__item-${subtype}" src="${cover_image}">`;
210
+ const brand = subtype === 'cover-image' && meta.brand ? (templates.brandBlock || brandBlock)(layout, data, meta) : '';
211
+ return `<div class="${className}__item-${subtype}-container">${img}${brand}</div>`;
193
212
  }
194
213
  function indexBlock(_ref10, data, _ref11) {
195
214
  let {
@@ -189,6 +189,7 @@ class TypewriterLayout extends _progressive.default {
189
189
  const index = parseInt(citationLinkElement.dataset.index);
190
190
  if (!Number.isNaN(index)) {
191
191
  this._view._events.emit('citation-click', {
192
+ event,
192
193
  index
193
194
  });
194
195
  }
@@ -206,6 +207,7 @@ class TypewriterLayout extends _progressive.default {
206
207
  } = anchorElement;
207
208
  if (href) {
208
209
  this._view._events.emit('link-click', (0, _commons.trimObj)({
210
+ event,
209
211
  url: href,
210
212
  text: innerText ? innerText.trim() : '',
211
213
  className: className || '',