@miso.ai/client-sdk-ui 1.10.0-beta.0 → 1.10.0-beta.10

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 (90) hide show
  1. package/dist/cjs/actor/autocomplete.js +157 -0
  2. package/dist/cjs/actor/data.js +4 -12
  3. package/dist/cjs/actor/fields.js +8 -0
  4. package/dist/cjs/actor/index.js +7 -0
  5. package/dist/cjs/actor/tracker.js +46 -70
  6. package/dist/cjs/actor/trackers.js +5 -1
  7. package/dist/cjs/actor/utils.js +16 -2
  8. package/dist/cjs/actor/view.js +14 -3
  9. package/dist/cjs/actor/views.js +9 -1
  10. package/dist/cjs/affiliation/index.js +126 -0
  11. package/dist/cjs/combo/ask/options.js +1 -1
  12. package/dist/cjs/combo/base.js +1 -1
  13. package/dist/cjs/constants.js +6 -3
  14. package/dist/cjs/defaults/ask/controls.js +1 -1
  15. package/dist/cjs/defaults/ask/phrases.js +1 -1
  16. package/dist/cjs/defaults/ask/templates.js +35 -4
  17. package/dist/cjs/element/role/index.js +7 -0
  18. package/dist/cjs/element/role/miso-affiliation.js +20 -0
  19. package/dist/cjs/layout/affiliation/affiliation.js +330 -0
  20. package/dist/cjs/layout/banner/banner.js +1 -1
  21. package/dist/cjs/layout/container/container.js +1 -1
  22. package/dist/cjs/layout/error/error.js +1 -1
  23. package/dist/cjs/layout/index.js +7 -0
  24. package/dist/cjs/layout/input/option-list.js +35 -50
  25. package/dist/cjs/layout/input/search-box.js +227 -129
  26. package/dist/cjs/layout/list/cards.js +1 -1
  27. package/dist/cjs/layout/list/carousel.js +5 -3
  28. package/dist/cjs/layout/list/collection.js +44 -49
  29. package/dist/cjs/layout/list/list.js +1 -1
  30. package/dist/cjs/layout/radio/feedback.js +1 -1
  31. package/dist/cjs/layout/radio/radio.js +1 -1
  32. package/dist/cjs/layout/raf.js +1 -1
  33. package/dist/cjs/layout/template.js +1 -1
  34. package/dist/cjs/layout/templates.js +172 -66
  35. package/dist/cjs/layout/text/text.js +1 -1
  36. package/dist/cjs/layout/text/typewriter/index.js +3 -3
  37. package/dist/cjs/layout/trackable.js +124 -0
  38. package/dist/cjs/plugin.js +1 -1
  39. package/dist/cjs/source/index.js +20 -8
  40. package/dist/cjs/util/bindings.js +58 -110
  41. package/dist/cjs/util/states.js +31 -24
  42. package/dist/cjs/util/trackers.js +75 -0
  43. package/dist/cjs/util/viewables.js +55 -0
  44. package/dist/cjs/version.js +1 -1
  45. package/dist/cjs/workflow/ask.js +60 -19
  46. package/dist/cjs/workflow/asks.js +1 -1
  47. package/dist/cjs/workflow/base.js +6 -7
  48. package/dist/cjs/workflow/explore.js +5 -2
  49. package/dist/cjs/workflow/options.js +60 -14
  50. package/dist/cjs/workflow/recommendation.js +2 -0
  51. package/dist/cjs/workflow/search.js +35 -7
  52. package/package.json +2 -2
  53. package/src/actor/autocomplete.js +131 -0
  54. package/src/actor/data.js +3 -10
  55. package/src/actor/fields.js +8 -0
  56. package/src/actor/index.js +1 -0
  57. package/src/actor/tracker.js +39 -62
  58. package/src/actor/trackers.js +3 -1
  59. package/src/actor/utils.js +14 -2
  60. package/src/actor/view.js +12 -1
  61. package/src/actor/views.js +11 -0
  62. package/src/affiliation/index.js +108 -0
  63. package/src/constants.js +10 -1
  64. package/src/defaults/ask/phrases.js +1 -1
  65. package/src/defaults/ask/templates.js +34 -2
  66. package/src/element/role/index.js +1 -0
  67. package/src/element/role/miso-affiliation.js +16 -0
  68. package/src/layout/affiliation/affiliation.js +295 -0
  69. package/src/layout/index.js +1 -0
  70. package/src/layout/input/option-list.js +35 -43
  71. package/src/layout/input/search-box.js +192 -95
  72. package/src/layout/list/carousel.js +4 -2
  73. package/src/layout/list/collection.js +42 -43
  74. package/src/layout/templates.js +127 -46
  75. package/src/layout/text/typewriter/index.js +2 -2
  76. package/src/layout/trackable.js +106 -0
  77. package/src/source/index.js +14 -1
  78. package/src/util/bindings.js +47 -103
  79. package/src/util/states.js +26 -20
  80. package/src/util/trackers.js +69 -0
  81. package/src/util/viewables.js +47 -0
  82. package/src/version.js +1 -1
  83. package/src/workflow/ask.js +37 -3
  84. package/src/workflow/base.js +2 -3
  85. package/src/workflow/explore.js +1 -1
  86. package/src/workflow/options.js +54 -13
  87. package/src/workflow/recommendation.js +1 -0
  88. package/src/workflow/search.js +33 -1
  89. package/dist/cjs/util/tracker.js +0 -348
  90. package/src/util/tracker.js +0 -318
@@ -4,14 +4,13 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
- var _commons = require("@miso.ai/commons");
8
7
  var _constants = require("../../constants.js");
9
8
  var _template = _interopRequireDefault(require("../template.js"));
9
+ var _trackable = require("../trackable.js");
10
10
  var _templates = require("../templates.js");
11
11
  const _excluded = ["templates", "itemType"];
12
12
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
13
- function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (e.indexOf(n) >= 0) continue; t[n] = r[n]; } return t; }
14
- const VALUE = Symbol.for('miso.value');
13
+ function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (e.includes(n)) continue; t[n] = r[n]; } return t; }
15
14
  function root(layout, state) {
16
15
  const {
17
16
  className,
@@ -28,7 +27,7 @@ function ready(layout, state) {
28
27
  const {
29
28
  templates
30
29
  } = layout;
31
- const values = state.value;
30
+ const values = layout._getItems(state);
32
31
 
33
32
  // TODO: handle categories, attributes, etc. by introducing sublayout
34
33
  if (values && values.length > 0 || state.ongoing) {
@@ -45,7 +44,7 @@ function list(layout, state, values) {
45
44
  } = layout;
46
45
  const listTag = templates.ordered ? 'ol' : 'ul';
47
46
  // TODO: support separator?
48
- return `<${listTag} class="${className}__list" data-item-type="${options.itemType}">${templates.items(layout, state, values)}</${listTag}>`;
47
+ return `<${listTag} class="${className}__list" data-role="list" data-item-type="${options.itemType}">${templates.items(layout, state, values)}</${listTag}>`;
49
48
  }
50
49
  function items(layout, state, values) {
51
50
  let {
@@ -84,7 +83,20 @@ const DEFAULT_TEMPLATES = Object.freeze({
84
83
  list,
85
84
  ordered: false,
86
85
  items,
87
- item
86
+ item,
87
+ productInfoBlock: _templates.productInfoBlock,
88
+ articleInfoBlock: _templates.articleInfoBlock,
89
+ brandBlock: _templates.brandBlock,
90
+ titleBlock: _templates.titleBlock,
91
+ descriptionBlock: _templates.descriptionBlock,
92
+ dateBlock: _templates.dateBlock,
93
+ priceBlock: _templates.priceBlock,
94
+ discountRateText: _templates.discountRateText,
95
+ ctaBlock: _templates.ctaBlock,
96
+ cta: _templates.cta,
97
+ imageBlock: _templates.imageBlock,
98
+ indexBlock: _templates.indexBlock,
99
+ helpers: _templates.helpers
88
100
  });
89
101
  class CollectionLayout extends _template.default {
90
102
  static get category() {
@@ -103,19 +115,12 @@ class CollectionLayout extends _template.default {
103
115
  templates: Object.assign({}, DEFAULT_TEMPLATES, templates),
104
116
  itemType
105
117
  }, options));
106
- (0, _commons.defineValues)(this, {
107
- bindings: Object.freeze({
108
- list: this._listBindings.bind(this)
109
- })
110
- });
111
118
  this._view = undefined;
119
+ this._initTrackable();
112
120
  }
113
121
  initialize(view) {
114
122
  this._view = view;
115
- const {
116
- proxyElement
117
- } = this._view = view;
118
- this._unsubscribes.push(proxyElement.on('click', this._onClick.bind(this)));
123
+ this._unsubscribes.push(view.proxyElement.on('click', this._onClick.bind(this)));
119
124
  }
120
125
  _preprocess(_ref2) {
121
126
  let {
@@ -136,7 +141,7 @@ class CollectionLayout extends _template.default {
136
141
  _html(state, rendered, incremental) {
137
142
  if (incremental) {
138
143
  const offset = rendered.value.length;
139
- const values = state.value.slice(offset);
144
+ const values = (this._getItems(state) || []).slice(offset);
140
145
  return values.length > 0 ? this.templates.items(this, state, values, {
141
146
  offset
142
147
  }) : '';
@@ -165,52 +170,40 @@ class CollectionLayout extends _template.default {
165
170
  } else {
166
171
  element.innerHTML = html;
167
172
  }
168
- this._syncValues(element, state);
173
+ this._syncBindings(element, state);
169
174
  }
170
- _syncValues(element, state) {
171
- if (!element) {
172
- return;
173
- }
174
- const values = state.value || [];
175
- let i = 0;
176
- for (const itemElement of this._listItemElements(element)) {
177
- itemElement[VALUE] = values[i++];
178
- }
175
+ _unrender() {
176
+ this._clearBindings();
177
+ }
178
+ _getItems(state) {
179
+ return state.value;
179
180
  }
180
181
  _getListElement(element) {
181
- return element.querySelector(`.${this.className}__list`);
182
+ return element.querySelector('[data-role="list"]');
182
183
  }
183
- _listItemElements(element) {
184
+ _getItemElements(element) {
184
185
  return element ? Array.from(element.querySelectorAll(`[data-role="item"]`)) : [];
185
186
  }
186
- _listBindings(rootElement) {
187
- if (!rootElement) {
188
- return [];
189
- }
190
- const bindings = [];
191
- for (const element of this._listItemElements(rootElement)) {
192
- const value = element[VALUE];
193
- if (!value) {
194
- continue;
195
- }
196
- const key = this.options.itemType === 'product' ? value.product_id : value;
197
- bindings.push({
198
- element,
199
- key,
200
- value
201
- });
202
- }
203
- return bindings;
204
- }
205
187
  _onClick(event) {
206
188
  const element = event.target.closest(`[data-role="item"]`);
207
189
  if (!element) {
208
190
  return;
209
191
  }
210
- const value = element[VALUE];
192
+ const binding = this._bindings.get(element);
193
+ if (!binding) {
194
+ return;
195
+ }
196
+ this._trackClick(event, binding);
197
+ this._emitClickEvent(event, binding);
198
+ }
199
+ _emitClickEvent(event, binding) {
211
200
  const {
212
201
  session
213
202
  } = this._view._state;
203
+ const {
204
+ value,
205
+ element
206
+ } = binding;
214
207
  this._view._events.emit('click', {
215
208
  session,
216
209
  value,
@@ -219,8 +212,10 @@ class CollectionLayout extends _template.default {
219
212
  });
220
213
  }
221
214
  destroy() {
215
+ this._destroyTrackable();
222
216
  this._view = undefined;
223
217
  super.destroy();
224
218
  }
225
219
  }
226
- exports.default = CollectionLayout;
220
+ exports.default = CollectionLayout;
221
+ (0, _trackable.makeTrackable)(CollectionLayout.prototype);
@@ -7,7 +7,7 @@ exports.default = void 0;
7
7
  var _collection = _interopRequireDefault(require("./collection.js"));
8
8
  const _excluded = ["className"];
9
9
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
10
- function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (e.indexOf(n) >= 0) continue; t[n] = r[n]; } return t; }
10
+ function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (e.includes(n)) continue; t[n] = r[n]; } return t; }
11
11
  const TYPE = 'list';
12
12
  const DEFAULT_CLASSNAME = 'miso-list';
13
13
  class ListLayout extends _collection.default {
@@ -9,7 +9,7 @@ var _radio = _interopRequireDefault(require("./radio.js"));
9
9
  var _svgs = require("../svgs.js");
10
10
  const _excluded = ["className", "templates"];
11
11
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
12
- function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (e.indexOf(n) >= 0) continue; t[n] = r[n]; } return t; }
12
+ function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (e.includes(n)) continue; t[n] = r[n]; } return t; }
13
13
  const TYPE = 'feedback';
14
14
  const DEFAULT_CLASSNAME = 'miso-feedback';
15
15
  const OPTIONS = ['helpful', 'unhelpful'];
@@ -10,7 +10,7 @@ var _template = _interopRequireDefault(require("../template.js"));
10
10
  var _templates = require("../templates.js");
11
11
  const _excluded = ["className", "templates", "field", "defaultValue"];
12
12
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
13
- function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (e.indexOf(n) >= 0) continue; t[n] = r[n]; } return t; }
13
+ function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (e.includes(n)) continue; t[n] = r[n]; } return t; }
14
14
  function root(layout) {
15
15
  const {
16
16
  className,
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.default = void 0;
7
7
  var _commons = require("@miso.ai/commons");
8
8
  const _excluded = ["role", "workflow"];
9
- function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (e.indexOf(n) >= 0) continue; t[n] = r[n]; } return t; }
9
+ function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (e.includes(n)) continue; t[n] = r[n]; } return t; }
10
10
  class RafLayout {
11
11
  constructor() {
12
12
  let _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
@@ -9,7 +9,7 @@ var _raf = _interopRequireDefault(require("./raf.js"));
9
9
  var _templates = require("./templates.js");
10
10
  const _excluded = ["className", "templates"];
11
11
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
12
- function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (e.indexOf(n) >= 0) continue; t[n] = r[n]; } return t; }
12
+ function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (e.includes(n)) continue; t[n] = r[n]; } return t; }
13
13
  class TemplateBasedLayout extends _raf.default {
14
14
  constructor() {
15
15
  let _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
@@ -3,10 +3,25 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
+ exports.affiliation = affiliation;
7
+ exports.affiliationInfoBlock = affiliationInfoBlock;
6
8
  exports.article = article;
9
+ exports.articleInfoBlock = articleInfoBlock;
10
+ exports.brandBlock = brandBlock;
11
+ exports.cta = cta;
12
+ exports.ctaBlock = ctaBlock;
13
+ exports.dateBlock = dateBlock;
14
+ exports.descriptionBlock = descriptionBlock;
15
+ exports.discountRateText = discountRateText;
16
+ exports.helpers = void 0;
17
+ exports.imageBlock = imageBlock;
18
+ exports.indexBlock = indexBlock;
19
+ exports.priceBlock = priceBlock;
7
20
  exports.product = product;
21
+ exports.productInfoBlock = productInfoBlock;
8
22
  exports.question = question;
9
23
  exports.requiresImplementation = requiresImplementation;
24
+ exports.titleBlock = titleBlock;
10
25
  exports.unimplemented = unimplemented;
11
26
  var _commons = require("@miso.ai/commons");
12
27
  var _constants = require("../constants.js");
@@ -28,83 +43,191 @@ function product(layout, state, data, meta) {
28
43
  const {
29
44
  templates
30
45
  } = layout;
31
- const [openTag, closeTag] = renderTagPair(layout, data);
32
- return [openTag, (templates.imageBlock || renderImageBlock)(layout, data, meta), (templates.infoBlock || productInfoBlock)(layout, data, meta), (templates.indexBlock || renderIndexBlock)(layout, data, meta), closeTag].join('');
46
+ const [openTag, closeTag] = tagPair(layout, data);
47
+ return [openTag, (templates.imageBlock || imageBlock)(layout, data, meta), (templates.infoBlock || templates.productInfoBlock || productInfoBlock)(layout, data, meta), closeTag].join('');
33
48
  }
34
49
  function question(layout, state, data) {
35
- const [openTag, closeTag] = renderTagPair(layout, data);
50
+ const [openTag, closeTag] = tagPair(layout, data);
36
51
  return `${openTag}${data.value || data.text || data}${closeTag}`;
37
52
  }
38
53
  function article(layout, state, data, meta) {
39
54
  const {
40
55
  templates
41
56
  } = layout;
42
- const [openTag, closeTag] = renderTagPair(layout, data);
43
- return [openTag, (templates.imageBlock || renderImageBlock)(layout, data, meta), (templates.infoBlock || articleInfoBlock)(layout, data, meta), (templates.indexBlock || renderIndexBlock)(layout, data, meta), closeTag].join('');
57
+ const [openTag, closeTag] = tagPair(layout, data);
58
+ return [openTag, (templates.imageBlock || imageBlock)(layout, data, meta), (templates.infoBlock || templates.articleInfoBlock || articleInfoBlock)(layout, data, meta), (templates.indexBlock || indexBlock)(layout, data, meta), closeTag].join('');
44
59
  }
45
- function productInfoBlock(_ref, _ref2) {
60
+ function affiliation(layout, state, data, meta) {
61
+ const {
62
+ templates
63
+ } = layout;
64
+ const [openTag, closeTag] = tagPair(layout, data);
65
+ return [openTag, (templates.infoBlock || templates.affiliationInfoBlock || affiliationInfoBlock)(layout, data, meta), (templates.imageBlock || imageBlock)(layout, data, meta), (templates.brandBlock || brandBlock)(layout, data, meta), closeTag].join('');
66
+ }
67
+ function affiliationInfoBlock(layout, data, meta) {
68
+ const {
69
+ className,
70
+ templates
71
+ } = layout;
72
+ return `<div class="${className}__item-info-container">${[(templates.titleBlock || titleBlock)(layout, data, meta), (templates.descriptionBlock || descriptionBlock)(layout, data, meta), (templates.priceBlock || priceBlock)(layout, data, meta), (templates.ctaBlock || ctaBlock)(layout, data, meta)].join('')}</div>`;
73
+ }
74
+ function productInfoBlock(layout, data, meta) {
75
+ const {
76
+ className,
77
+ templates
78
+ } = layout;
79
+ return `<div class="${className}__item-info-container">${[(templates.titleBlock || titleBlock)(layout, data, meta), (templates.descriptionBlock || descriptionBlock)(layout, data, meta), (templates.priceBlock || priceBlock)(layout, data, meta)].join('')}</div>`;
80
+ }
81
+ function articleInfoBlock(layout, data, meta) {
82
+ const {
83
+ className,
84
+ templates
85
+ } = layout;
86
+ 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>`;
87
+ }
88
+ function titleBlock(_ref, _ref2) {
46
89
  let {
47
90
  className
48
91
  } = _ref;
49
92
  let {
50
- title,
51
- description,
52
- sale_price,
53
- original_price
93
+ title
54
94
  } = _ref2;
55
- let content = '';
56
- if (title) {
57
- content += `<div class="${className}__item-title">${(0, _commons.escapeHtml)(title)}</div>`;
58
- }
59
- if (description) {
60
- content += `<div class="${className}__item-desc">${(0, _commons.escapeHtml)(description)}</div>`;
61
- }
62
- const price = sale_price || original_price;
63
- if (price) {
64
- content += `<hr><div class="${className}__item-price">${price}</div>`;
65
- // TODO: enhance this
95
+ return title ? `<div class="${className}__item-title">${(0, _commons.escapeHtml)(title)}</div>` : '';
96
+ }
97
+ function brandBlock(_ref3, _ref4) {
98
+ let {
99
+ className
100
+ } = _ref3;
101
+ let {
102
+ brand,
103
+ brand_logo
104
+ } = _ref4;
105
+ if (!brand && !brand_logo) {
106
+ return '';
66
107
  }
67
- return `<div class="${className}__item-info-container">${content}</div>`;
108
+ const content = brand_logo ? `<img class="${className}__item-brand-logo" src="${brand_logo}"${brand ? ` alt="${brand}"` : ''}>` : `<div class="${className}__item-brand">${brand}</div>`;
109
+ return `<div class="${className}__item-brand-container">${content}</div>`;
68
110
  }
69
- function articleInfoBlock(_ref3, _ref4) {
111
+ function descriptionBlock(_ref5, _ref6) {
112
+ let {
113
+ className
114
+ } = _ref5;
115
+ let {
116
+ snippet,
117
+ description
118
+ } = _ref6;
119
+ return snippet ? `<div class="${className}__item-snippet">${snippet}</div>` : description ? `<div class="${className}__item-desc">${(0, _commons.escapeHtml)(description)}</div>` : '';
120
+ }
121
+ function dateBlock(_ref7, _ref8) {
70
122
  let {
71
123
  className,
72
124
  templates
73
- } = _ref3;
125
+ } = _ref7;
74
126
  let {
75
- title,
76
- snippet,
77
- description,
78
127
  created_at,
79
128
  updated_at,
80
129
  published_at
81
- } = _ref4;
130
+ } = _ref8;
82
131
  const date = published_at || created_at || updated_at;
132
+ return date ? `<div class="${className}__item-date">${formatDate(date, templates.date)}</div>` : '';
133
+ }
134
+ function priceBlock(layout, data) {
135
+ const {
136
+ className,
137
+ templates
138
+ } = layout;
139
+ const {
140
+ sale_price,
141
+ original_price,
142
+ currency = 'USD'
143
+ } = data;
144
+ const price = sale_price || original_price;
145
+ if (!price) {
146
+ return '';
147
+ }
148
+ const has_price_difference = original_price !== undefined && sale_price !== undefined && sale_price < original_price;
149
+ const discount_rate_percent = data.discount_rate_percent || (has_price_difference ? Math.floor((1 - sale_price / original_price) * 100) : undefined);
83
150
  let content = '';
84
- if (title) {
85
- content += `<div class="${className}__item-title">${(0, _commons.escapeHtml)(title)}</div>`;
151
+ // original price
152
+ if (has_price_difference) {
153
+ content += `<span class="${className}__item-original-price miso-price" data-currency="${currency}">${original_price}</span><br>`;
86
154
  }
87
- if (date) {
88
- content += `<div class="${className}__item-date">${renderDate(date, templates.date)}</div>`;
155
+ // current price
156
+ content += `<span class="${className}__item-price miso-price" data-currency="${currency}">${price}</span>`;
157
+ // discount rate
158
+ if (discount_rate_percent) {
159
+ const text = (templates.discountRateText || discountRateText)(layout, Object.assign({}, data, {
160
+ discount_rate_percent
161
+ }));
162
+ content += ` <span class="${className}__item-discount-rate">${text}</span>`;
89
163
  }
90
- if (snippet) {
91
- content += `<div class="${className}__item-snippet">${snippet}</div>`;
92
- } else if (description) {
93
- content += `<div class="${className}__item-desc">${(0, _commons.escapeHtml)(description)}</div>`;
164
+ return `<div class="${className}__item-price-container">${content}</div>`;
165
+ }
166
+ function discountRateText(layout, _ref9) {
167
+ let {
168
+ discount_rate_percent
169
+ } = _ref9;
170
+ return `(${discount_rate_percent}% off)`;
171
+ }
172
+ function imageBlock(_ref10, _ref11) {
173
+ let {
174
+ className
175
+ } = _ref10;
176
+ let {
177
+ cover_image
178
+ } = _ref11;
179
+ if (!cover_image) {
180
+ return '';
94
181
  }
95
- return `<div class="${className}__item-info-container">${content}</div>`;
182
+ const img = `<img class="${className}__item-cover-image" src="${cover_image}">`;
183
+ return `<div class="${className}__item-cover-image-container">${img}</div>`;
184
+ }
185
+ function indexBlock(_ref12, data, _ref13) {
186
+ let {
187
+ className
188
+ } = _ref12;
189
+ let {
190
+ index
191
+ } = _ref13;
192
+ return `<div class="${className}__item-index-container"><span class="${className}__item-index miso-citation-index" data-index="${index + 1}"></span></div>`;
193
+ }
194
+ function ctaBlock(layout, data, meta) {
195
+ const {
196
+ className,
197
+ templates
198
+ } = layout;
199
+ let _cta = templates.cta || cta;
200
+ if (typeof _cta === 'function') {
201
+ _cta = _cta(layout, data, meta);
202
+ }
203
+ return _cta ? `<div class="${className}__item-cta-container">${_cta}</div>` : '';
204
+ }
205
+ function cta(layout, data, meta) {
206
+ const {
207
+ className,
208
+ templates
209
+ } = layout;
210
+ let text = templates.ctaText;
211
+ if (typeof text === 'function') {
212
+ text = text(layout, data, meta);
213
+ }
214
+ return text ? `<div class="${className}__item-cta">${text}</div>` : '';
96
215
  }
97
216
 
98
217
  // helpers //
99
- function renderTagPair(_ref5, _ref6) {
218
+ function tagPair(_ref14, _ref15) {
100
219
  let {
101
220
  className,
102
221
  options = {}
103
- } = _ref5;
222
+ } = _ref14;
104
223
  let {
105
224
  product_id,
106
225
  url
107
- } = _ref6;
226
+ } = _ref15;
227
+ let {
228
+ classSuffix = 'item-body',
229
+ role = 'item'
230
+ } = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
108
231
  const {
109
232
  link = {}
110
233
  } = options;
@@ -115,30 +238,8 @@ function renderTagPair(_ref5, _ref6) {
115
238
  const tag = url ? 'a' : 'div';
116
239
  const urlAttrs = url ? `href="${url}" target="${target}" rel="${rel}"` : '';
117
240
  const productAttrs = product_id ? `${_constants.ATTR_DATA_MISO_PRODUCT_ID}="${product_id}"` : '';
118
- return [`<${tag} class="${className}__item-body" data-role="item" ${productAttrs} ${urlAttrs}>`, `</${tag}>`];
119
- }
120
- function renderImageBlock(_ref7, _ref8) {
121
- let {
122
- className
123
- } = _ref7;
124
- let {
125
- cover_image
126
- } = _ref8;
127
- if (!cover_image) {
128
- return '';
129
- }
130
- const img = `<img class="${className}__item-cover-image" src="${cover_image}">`;
131
- return `<div class="${className}__item-cover-image-container">${img}</div>`;
132
- }
133
- function renderIndexBlock(_ref9, data, _ref10) {
134
- let {
135
- className
136
- } = _ref9;
137
- let {
138
- index
139
- } = _ref10;
140
- const i = index + 1;
141
- return `<div class="${className}__item-index-container"><span class="${className}__item-index miso-citation-index" data-index="${i}"></span></div>`;
241
+ const roleAttrs = role ? `data-role="${role}"` : '';
242
+ return [`<${tag} class="${className}__${classSuffix}" ${roleAttrs} ${productAttrs} ${urlAttrs}>`, `</${tag}>`];
142
243
  }
143
244
  const DEFAULT_DATE_OPTIONS = Object.freeze({
144
245
  locale: 'en-US',
@@ -146,7 +247,7 @@ const DEFAULT_DATE_OPTIONS = Object.freeze({
146
247
  month: 'short',
147
248
  day: 'numeric'
148
249
  });
149
- function renderDate(date) {
250
+ function formatDate(date) {
150
251
  let fn = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : DEFAULT_DATE_OPTIONS;
151
252
  switch (typeof fn) {
152
253
  case 'function':
@@ -158,4 +259,9 @@ function renderDate(date) {
158
259
  default:
159
260
  throw new Error(`Invalid date format: ${fn}`);
160
261
  }
161
- }
262
+ }
263
+ const helpers = exports.helpers = Object.freeze({
264
+ tagPair,
265
+ formatDate,
266
+ escapeHtml: _commons.escapeHtml
267
+ });
@@ -9,7 +9,7 @@ var _constants = require("../../constants.js");
9
9
  var _template = _interopRequireDefault(require("../template.js"));
10
10
  const _excluded = ["className", "templates", "tag"];
11
11
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
12
- function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (e.indexOf(n) >= 0) continue; t[n] = r[n]; } return t; }
12
+ function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (e.includes(n)) continue; t[n] = r[n]; } return t; }
13
13
  const TYPE = 'text';
14
14
  const DEFAULT_CLASSNAME = 'miso-text';
15
15
  function root(layout, state) {
@@ -12,7 +12,7 @@ var _plaintext = _interopRequireDefault(require("./plaintext.js"));
12
12
  var _utils = require("./utils.js");
13
13
  const _excluded = ["className", "tag", "format", "tooltip"];
14
14
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
15
- function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (e.indexOf(n) >= 0) continue; t[n] = r[n]; } return t; }
15
+ function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (e.includes(n)) continue; t[n] = r[n]; } return t; }
16
16
  const TYPE = 'typewriter';
17
17
  const DEFAULT_CLASSNAME = 'miso-typewriter';
18
18
  class TypewriterLayout extends _progressive.default {
@@ -86,7 +86,7 @@ class TypewriterLayout extends _progressive.default {
86
86
  onDebug
87
87
  });
88
88
  // capture citation link click if necessary
89
- this._unsubscribes.push(this._view.proxyElement.on('click', e => this._handleClick(e)));
89
+ this._unsubscribes.push(this._view.proxyElement.on('click', e => this._onClick(e)));
90
90
  }
91
91
  _getSource(index) {
92
92
  const {
@@ -172,7 +172,7 @@ class TypewriterLayout extends _progressive.default {
172
172
  }
173
173
 
174
174
  // event //
175
- _handleClick(_ref5) {
175
+ _onClick(_ref5) {
176
176
  let {
177
177
  target
178
178
  } = _ref5;