@miso.ai/client-sdk-ui 1.10.0-beta.12 → 1.10.0-beta.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/asset/svgs.js +14 -4
- package/dist/cjs/layout/affiliation/affiliation.js +66 -42
- package/dist/cjs/layout/templates.js +51 -31
- package/dist/cjs/version.js +1 -1
- package/package.json +2 -2
- package/src/asset/svgs.js +13 -2
- package/src/layout/affiliation/affiliation.js +54 -30
- package/src/layout/templates.js +24 -18
- package/src/version.js +1 -1
package/dist/cjs/asset/svgs.js
CHANGED
|
@@ -3,16 +3,25 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.SEND = exports.SEARCH = void 0;
|
|
6
|
+
exports.TRIANGLE = exports.SEND = exports.SEARCH = void 0;
|
|
7
7
|
var _version = _interopRequireDefault(require("../version.js"));
|
|
8
8
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
9
|
+
function trianglePath(r) {
|
|
10
|
+
const l = 100;
|
|
11
|
+
const d = r * Math.tan(3 * Math.PI / 8);
|
|
12
|
+
const e = d * Math.sin(Math.PI / 4);
|
|
13
|
+
return `M${r} 0L${l - d} 0A${r} ${r} 0 0 1 ${l - e} ${e}L${e} ${l - e}A${r} ${r} 0 0 1 0 ${l - d}L0 ${r}Z`;
|
|
14
|
+
}
|
|
9
15
|
const PREFIX = 'miso-ui-icon';
|
|
10
16
|
const ID = `${PREFIX}-svg-${_version.default.replaceAll('.', '_')}`;
|
|
11
17
|
|
|
12
|
-
//
|
|
18
|
+
// CC0 SVGs
|
|
13
19
|
const ICON_SEND = `<symbol id="${PREFIX}-send" viewBox="0 0 32 32"><path fill="currentColor" d="M11.499,19.173l5.801,-5.849c0.389,-0.392 1.022,-0.394 1.414,-0.006c0.392,0.389 0.395,1.022 0.006,1.414l-5.798,5.847l5.306,8.002c0.207,0.313 0.572,0.483 0.945,0.441c0.373,-0.042 0.691,-0.289 0.824,-0.64l9.024,-23.904c0.138,-0.366 0.05,-0.78 -0.226,-1.058c-0.276,-0.278 -0.689,-0.369 -1.057,-0.233l-24.004,8.892c-0.353,0.13 -0.602,0.448 -0.646,0.821c-0.044,0.373 0.125,0.74 0.438,0.948l7.973,5.325Z"/></symbol>`;
|
|
14
20
|
const ICON_SEARCH = `<symbol id="${PREFIX}-search" viewBox="0 0 24 24"><path fill="currentColor" d="M4 11C4 7.13401 7.13401 4 11 4C14.866 4 18 7.13401 18 11C18 14.866 14.866 18 11 18C7.13401 18 4 14.866 4 11ZM11 2C6.02944 2 2 6.02944 2 11C2 15.9706 6.02944 20 11 20C13.125 20 15.078 19.2635 16.6177 18.0319L20.2929 21.7071C20.6834 22.0976 21.3166 22.0976 21.7071 21.7071C22.0976 21.3166 22.0976 20.6834 21.7071 20.2929L18.0319 16.6177C19.2635 15.078 20 13.125 20 11C20 6.02944 15.9706 2 11 2Z"/></symbol>`;
|
|
15
|
-
|
|
21
|
+
|
|
22
|
+
// Custom SVGs
|
|
23
|
+
const ICON_TRIANGLE = `<symbol id="${PREFIX}-triangle" viewBox="-5 -5 105 105"><path d="${trianglePath(5)}"/></symbol>`;
|
|
24
|
+
const ICONS = [ICON_SEND, ICON_SEARCH, ICON_TRIANGLE];
|
|
16
25
|
const SPRITES_SVG = `<svg id="${ID}" style="display:none;">${ICONS.join('')}</svg>`;
|
|
17
26
|
let loaded = false;
|
|
18
27
|
function loadSvgSprites() {
|
|
@@ -27,4 +36,5 @@ function getSvg(name) {
|
|
|
27
36
|
return `<svg class="miso-ui-icon miso-ui-icon-${name}"><use href="#${PREFIX}-${name}"></use></svg>`;
|
|
28
37
|
}
|
|
29
38
|
const SEND = exports.SEND = getSvg('send');
|
|
30
|
-
const SEARCH = exports.SEARCH = getSvg('search');
|
|
39
|
+
const SEARCH = exports.SEARCH = getSvg('search');
|
|
40
|
+
const TRIANGLE = exports.TRIANGLE = getSvg('triangle');
|
|
@@ -8,6 +8,7 @@ var _commons = require("@miso.ai/commons");
|
|
|
8
8
|
var _constants = require("../../constants.js");
|
|
9
9
|
var _collection = _interopRequireDefault(require("../list/collection.js"));
|
|
10
10
|
var _templates = require("../templates.js");
|
|
11
|
+
var _svgs = require("../../asset/svgs.js");
|
|
11
12
|
const _excluded = ["className", "templates", "autoplay"];
|
|
12
13
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
13
14
|
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; }
|
|
@@ -33,40 +34,35 @@ function ready(layout, state) {
|
|
|
33
34
|
} = layout;
|
|
34
35
|
const items = layout._getItems(state);
|
|
35
36
|
if (items && items.length > 0) {
|
|
36
|
-
return templates.
|
|
37
|
+
return templates.controlContainer(layout, state, 'previous') + templates.body(layout, state) + templates.controlContainer(layout, state, 'next');
|
|
37
38
|
} else {
|
|
38
39
|
return templates.empty(layout, state);
|
|
39
40
|
}
|
|
40
41
|
}
|
|
41
|
-
function
|
|
42
|
+
function controlContainer(layout, state, direction) {
|
|
42
43
|
const {
|
|
43
|
-
className
|
|
44
|
+
className,
|
|
45
|
+
templates
|
|
44
46
|
} = layout;
|
|
45
|
-
return `<div class="${className}__control-${direction}
|
|
47
|
+
return `<div class="${className}__control-${direction}-container">${templates.control(layout, state, direction)}</div>`;
|
|
46
48
|
}
|
|
47
|
-
function
|
|
49
|
+
function control(layout, state, direction) {
|
|
48
50
|
const {
|
|
49
51
|
className,
|
|
50
52
|
templates
|
|
51
53
|
} = layout;
|
|
52
|
-
|
|
53
|
-
return `<div class="${className}__body">${templates.list(layout, state, items)}</div>`;
|
|
54
|
+
return `<div class="${className}__control-${direction}" data-role="${direction}">${templates.controlIcon(layout, state, direction)}</div>`;
|
|
54
55
|
}
|
|
55
|
-
function
|
|
56
|
+
function controlIcon(layout, state, direction) {
|
|
57
|
+
return _svgs.TRIANGLE;
|
|
58
|
+
}
|
|
59
|
+
function body(layout, state) {
|
|
56
60
|
const {
|
|
57
61
|
className,
|
|
58
62
|
templates
|
|
59
63
|
} = layout;
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
} = templates;
|
|
63
|
-
if (typeof headerText === 'function') {
|
|
64
|
-
headerText = headerText(layout, state);
|
|
65
|
-
}
|
|
66
|
-
if (!headerText) {
|
|
67
|
-
return '';
|
|
68
|
-
}
|
|
69
|
-
return `<div class="${className}__header"><div class="${className}__header-tab">${headerText}</div></div>`;
|
|
64
|
+
const items = layout._getItems(state);
|
|
65
|
+
return `<div class="${className}__body">${templates.list(layout, state, items)}</div>`;
|
|
70
66
|
}
|
|
71
67
|
function item(layout, state, value, index) {
|
|
72
68
|
const {
|
|
@@ -83,7 +79,7 @@ function item(layout, state, value, index) {
|
|
|
83
79
|
const body = templates[itemType](layout, state, value, {
|
|
84
80
|
index
|
|
85
81
|
});
|
|
86
|
-
return `<li class="${className}__item">${header}${body}</li>`;
|
|
82
|
+
return `<li class="${className}__item"><div class="${className}__item-inner">${header}${body}</div></li>`;
|
|
87
83
|
}
|
|
88
84
|
function itemHeader(layout, state, value, meta) {
|
|
89
85
|
const {
|
|
@@ -91,45 +87,67 @@ function itemHeader(layout, state, value, meta) {
|
|
|
91
87
|
templates
|
|
92
88
|
} = layout;
|
|
93
89
|
let {
|
|
94
|
-
|
|
90
|
+
itemHeaderLeftText,
|
|
91
|
+
itemHeaderRightText
|
|
95
92
|
} = templates;
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
}
|
|
99
|
-
|
|
93
|
+
itemHeaderLeftText = _templates.helpers.asFunction(itemHeaderLeftText)(layout, state, value, meta);
|
|
94
|
+
itemHeaderRightText = _templates.helpers.asFunction(itemHeaderRightText)(layout, state, value, meta);
|
|
95
|
+
return `<div class="${className}__item-header">
|
|
96
|
+
<div class="${className}__item-header-left">${itemHeaderLeftText}</div>
|
|
97
|
+
<div class="${className}__item-header-right">${itemHeaderRightText}</div>
|
|
98
|
+
</div>`;
|
|
99
|
+
}
|
|
100
|
+
function itemHeaderRightText(layout, state, value, meta) {
|
|
101
|
+
const {
|
|
102
|
+
templates
|
|
103
|
+
} = layout;
|
|
104
|
+
const logoImg = _templates.helpers.asFunction(templates.logoImg)(layout, state, value, meta);
|
|
105
|
+
return logoImg ? `Selected by ${logoImg}` : '';
|
|
106
|
+
}
|
|
107
|
+
function logoImg(layout, state, value, meta) {
|
|
108
|
+
const {
|
|
109
|
+
className,
|
|
110
|
+
templates
|
|
111
|
+
} = layout;
|
|
112
|
+
const logoUrl = _templates.helpers.asFunction(templates.logoUrl)(layout, state, value, meta);
|
|
113
|
+
if (!logoUrl) {
|
|
100
114
|
return '';
|
|
101
115
|
}
|
|
102
|
-
|
|
116
|
+
const logoAltText = _templates.helpers.asFunction(templates.logoAltText)(layout, state, value, meta);
|
|
117
|
+
const logoAltTextAttr = logoAltText ? ` alt="${logoAltText}"` : '';
|
|
118
|
+
return `<img class="${className}__item-header-logo" src="${logoUrl}"${logoAltTextAttr}>`;
|
|
103
119
|
}
|
|
104
120
|
const DEFAULT_TEMPLATES = Object.freeze({
|
|
105
121
|
root,
|
|
106
122
|
[_constants.STATUS.READY]: ready,
|
|
123
|
+
controlContainer,
|
|
107
124
|
control,
|
|
125
|
+
controlIcon,
|
|
108
126
|
body,
|
|
109
|
-
header,
|
|
110
127
|
item,
|
|
111
128
|
itemHeader,
|
|
112
129
|
affiliation: _templates.affiliation,
|
|
113
|
-
ctaText: 'View',
|
|
114
|
-
|
|
130
|
+
ctaText: 'View deal',
|
|
131
|
+
itemHeaderLeftText: `Today's best deals`,
|
|
132
|
+
itemHeaderRightText,
|
|
133
|
+
logoImg
|
|
115
134
|
});
|
|
116
135
|
const INHERITED_DEFAULT_TEMPLATES = Object.freeze(Object.assign({}, _collection.default.defaultTemplates, DEFAULT_TEMPLATES));
|
|
136
|
+
|
|
137
|
+
/*
|
|
117
138
|
function normalizeAutoplayOptions(options) {
|
|
118
139
|
if (options === true) {
|
|
119
|
-
options = {
|
|
120
|
-
interval: 5000
|
|
121
|
-
};
|
|
140
|
+
options = { interval: 10000 };
|
|
122
141
|
} else if (typeof options === 'number') {
|
|
123
142
|
if (options <= 0) {
|
|
124
143
|
options = false;
|
|
125
144
|
} else {
|
|
126
|
-
options = {
|
|
127
|
-
interval: Math.max(options, 500)
|
|
128
|
-
};
|
|
145
|
+
options = { interval: Math.max(options, 500) };
|
|
129
146
|
}
|
|
130
147
|
}
|
|
131
148
|
return options;
|
|
132
149
|
}
|
|
150
|
+
|
|
133
151
|
function autoplayOptionsEquals(a, b) {
|
|
134
152
|
if (a === b) {
|
|
135
153
|
return true;
|
|
@@ -139,6 +157,8 @@ function autoplayOptionsEquals(a, b) {
|
|
|
139
157
|
}
|
|
140
158
|
return a.interval === b.interval;
|
|
141
159
|
}
|
|
160
|
+
*/
|
|
161
|
+
|
|
142
162
|
class AffiliationLayout extends _collection.default {
|
|
143
163
|
static get category() {
|
|
144
164
|
return _constants.LAYOUT_CATEGORY.AFFILIATION;
|
|
@@ -156,8 +176,7 @@ class AffiliationLayout extends _collection.default {
|
|
|
156
176
|
let _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
157
177
|
let {
|
|
158
178
|
className = DEFAULT_CLASSNAME,
|
|
159
|
-
templates
|
|
160
|
-
autoplay
|
|
179
|
+
templates
|
|
161
180
|
} = _ref,
|
|
162
181
|
options = _objectWithoutPropertiesLoose(_ref, _excluded);
|
|
163
182
|
super(Object.assign({
|
|
@@ -170,8 +189,12 @@ class AffiliationLayout extends _collection.default {
|
|
|
170
189
|
this._displayedCount = undefined;
|
|
171
190
|
this._displayedIndex = undefined;
|
|
172
191
|
this._viewable = undefined;
|
|
192
|
+
|
|
193
|
+
// TODO: extract this
|
|
194
|
+
/*
|
|
173
195
|
this._autoplay = {};
|
|
174
196
|
this.autoplay(autoplay);
|
|
197
|
+
*/
|
|
175
198
|
}
|
|
176
199
|
initialize(view) {
|
|
177
200
|
super.initialize(view);
|
|
@@ -180,8 +203,9 @@ class AffiliationLayout extends _collection.default {
|
|
|
180
203
|
} = this._view.trackerOptions || {};
|
|
181
204
|
this._viewable = new _commons.CarouselItemViewabilityObserver(this._onViewable.bind(this), options);
|
|
182
205
|
}
|
|
183
|
-
|
|
184
|
-
|
|
206
|
+
|
|
207
|
+
/*
|
|
208
|
+
autoplay(options = false) {
|
|
185
209
|
options = normalizeAutoplayOptions(options);
|
|
186
210
|
if (autoplayOptionsEquals(options, this._autoplay.options)) {
|
|
187
211
|
return;
|
|
@@ -189,9 +213,7 @@ class AffiliationLayout extends _collection.default {
|
|
|
189
213
|
if (this._autoplay.options) {
|
|
190
214
|
clearInterval(this._autoplay.intervalId);
|
|
191
215
|
}
|
|
192
|
-
this._autoplay = {
|
|
193
|
-
options
|
|
194
|
-
};
|
|
216
|
+
this._autoplay = { options };
|
|
195
217
|
// TODO: use slower transition speed for autoplay
|
|
196
218
|
// TODO: pause on hover
|
|
197
219
|
// TODO: cooldown after manual interaction
|
|
@@ -199,6 +221,8 @@ class AffiliationLayout extends _collection.default {
|
|
|
199
221
|
this._autoplay.intervalId = setInterval(() => this.next(), options.interval);
|
|
200
222
|
}
|
|
201
223
|
}
|
|
224
|
+
*/
|
|
225
|
+
|
|
202
226
|
get itemIndex() {
|
|
203
227
|
return this._itemIndex;
|
|
204
228
|
}
|
|
@@ -315,7 +339,6 @@ class AffiliationLayout extends _collection.default {
|
|
|
315
339
|
_trackViewables() {} // omit default behavior for we want to track by other means
|
|
316
340
|
|
|
317
341
|
_onClick(event) {
|
|
318
|
-
super._onClick(event);
|
|
319
342
|
const element = event.target;
|
|
320
343
|
if (element.closest(`[data-role="previous"]`)) {
|
|
321
344
|
this.previous();
|
|
@@ -325,6 +348,7 @@ class AffiliationLayout extends _collection.default {
|
|
|
325
348
|
this.next();
|
|
326
349
|
return;
|
|
327
350
|
}
|
|
351
|
+
super._onClick(event);
|
|
328
352
|
}
|
|
329
353
|
}
|
|
330
354
|
exports.default = AffiliationLayout;
|
|
@@ -25,6 +25,8 @@ exports.titleBlock = titleBlock;
|
|
|
25
25
|
exports.unimplemented = unimplemented;
|
|
26
26
|
var _commons = require("@miso.ai/commons");
|
|
27
27
|
var _constants = require("../constants.js");
|
|
28
|
+
const _excluded = ["classSuffix", "role"];
|
|
29
|
+
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; }
|
|
28
30
|
function requiresImplementation() {
|
|
29
31
|
for (var _len = arguments.length, names = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
30
32
|
names[_key] = arguments[_key];
|
|
@@ -61,8 +63,12 @@ function affiliation(layout, state, data, meta) {
|
|
|
61
63
|
const {
|
|
62
64
|
templates
|
|
63
65
|
} = layout;
|
|
64
|
-
const [openTag, closeTag] = tagPair(layout, data
|
|
65
|
-
|
|
66
|
+
const [openTag, closeTag] = tagPair(layout, data, {
|
|
67
|
+
link: false
|
|
68
|
+
});
|
|
69
|
+
return [openTag, (templates.infoBlock || templates.affiliationInfoBlock || affiliationInfoBlock)(layout, data, meta), (templates.imageBlock || imageBlock)(layout, data, Object.assign({
|
|
70
|
+
brand: true
|
|
71
|
+
}, meta)), closeTag].join('');
|
|
66
72
|
}
|
|
67
73
|
function affiliationInfoBlock(layout, data, meta) {
|
|
68
74
|
const {
|
|
@@ -169,26 +175,28 @@ function discountRateText(layout, _ref9) {
|
|
|
169
175
|
} = _ref9;
|
|
170
176
|
return `(${discount_rate_percent}% off)`;
|
|
171
177
|
}
|
|
172
|
-
function imageBlock(
|
|
173
|
-
|
|
174
|
-
className
|
|
175
|
-
|
|
176
|
-
|
|
178
|
+
function imageBlock(layout, data, meta) {
|
|
179
|
+
const {
|
|
180
|
+
className,
|
|
181
|
+
templates
|
|
182
|
+
} = layout;
|
|
183
|
+
const {
|
|
177
184
|
cover_image
|
|
178
|
-
} =
|
|
185
|
+
} = data;
|
|
179
186
|
if (!cover_image) {
|
|
180
187
|
return '';
|
|
181
188
|
}
|
|
182
189
|
const img = `<img class="${className}__item-cover-image" src="${cover_image}">`;
|
|
183
|
-
|
|
190
|
+
const brand = meta.brand ? (templates.brandBlock || brandBlock)(layout, data, meta) : '';
|
|
191
|
+
return `<div class="${className}__item-cover-image-container">${img}${brand}</div>`;
|
|
184
192
|
}
|
|
185
|
-
function indexBlock(
|
|
193
|
+
function indexBlock(_ref10, data, _ref11) {
|
|
186
194
|
let {
|
|
187
195
|
className
|
|
188
|
-
} =
|
|
196
|
+
} = _ref10;
|
|
189
197
|
let {
|
|
190
198
|
index
|
|
191
|
-
} =
|
|
199
|
+
} = _ref11;
|
|
192
200
|
return `<div class="${className}__item-index-container"><span class="${className}__item-index miso-citation-index" data-index="${index + 1}"></span></div>`;
|
|
193
201
|
}
|
|
194
202
|
function ctaBlock(layout, data, meta) {
|
|
@@ -196,38 +204,45 @@ function ctaBlock(layout, data, meta) {
|
|
|
196
204
|
className,
|
|
197
205
|
templates
|
|
198
206
|
} = layout;
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
_cta = _cta(layout, data, meta);
|
|
202
|
-
}
|
|
203
|
-
return _cta ? `<div class="${className}__item-cta-container">${_cta}</div>` : '';
|
|
207
|
+
const cta = helpers.asFunction(templates.cta)(layout, data, meta);
|
|
208
|
+
return cta ? `<div class="${className}__item-cta-container">${cta}</div>` : '';
|
|
204
209
|
}
|
|
205
210
|
function cta(layout, data, meta) {
|
|
206
211
|
const {
|
|
207
|
-
className,
|
|
208
212
|
templates
|
|
209
213
|
} = layout;
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
214
|
+
const {
|
|
215
|
+
url
|
|
216
|
+
} = data;
|
|
217
|
+
if (!url) {
|
|
218
|
+
return '';
|
|
213
219
|
}
|
|
214
|
-
|
|
220
|
+
const [openTag, closeTag] = tagPair(layout, {
|
|
221
|
+
url
|
|
222
|
+
}, {
|
|
223
|
+
classSuffix: 'item-cta',
|
|
224
|
+
role: 'cta'
|
|
225
|
+
});
|
|
226
|
+
const ctaText = helpers.asFunction(templates.ctaText)(layout, data, meta);
|
|
227
|
+
return ctaText ? `${openTag}${ctaText}${closeTag}` : '';
|
|
215
228
|
}
|
|
216
229
|
|
|
217
230
|
// helpers //
|
|
218
|
-
function tagPair(
|
|
231
|
+
function tagPair(_ref13, _ref14) {
|
|
219
232
|
let {
|
|
220
233
|
className,
|
|
221
234
|
options = {}
|
|
222
|
-
} =
|
|
235
|
+
} = _ref13;
|
|
223
236
|
let {
|
|
224
237
|
product_id,
|
|
225
238
|
url
|
|
226
|
-
} =
|
|
239
|
+
} = _ref14;
|
|
240
|
+
let _ref12 = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
227
241
|
let {
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
242
|
+
classSuffix = 'item-body',
|
|
243
|
+
role = 'item'
|
|
244
|
+
} = _ref12,
|
|
245
|
+
meta = _objectWithoutPropertiesLoose(_ref12, _excluded);
|
|
231
246
|
const {
|
|
232
247
|
link = {}
|
|
233
248
|
} = options;
|
|
@@ -235,8 +250,8 @@ function tagPair(_ref14, _ref15) {
|
|
|
235
250
|
target = '_blank',
|
|
236
251
|
rel = 'noopener'
|
|
237
252
|
} = link; // TODO: other properties
|
|
238
|
-
const tag = url ? 'a' : 'div';
|
|
239
|
-
const urlAttrs = url ? `href="${url}" target="${target}" rel="${rel}"` : '';
|
|
253
|
+
const tag = meta.link !== false && url ? 'a' : 'div';
|
|
254
|
+
const urlAttrs = meta.link !== false && url ? `href="${url}" target="${target}" rel="${rel}"` : '';
|
|
240
255
|
const productAttrs = product_id ? `${_constants.ATTR_DATA_MISO_PRODUCT_ID}="${product_id}"` : '';
|
|
241
256
|
const roleAttrs = role ? `data-role="${role}"` : '';
|
|
242
257
|
return [`<${tag} class="${className}__${classSuffix}" ${roleAttrs} ${productAttrs} ${urlAttrs}>`, `</${tag}>`];
|
|
@@ -260,8 +275,13 @@ function formatDate(date) {
|
|
|
260
275
|
throw new Error(`Invalid date format: ${fn}`);
|
|
261
276
|
}
|
|
262
277
|
}
|
|
278
|
+
function asFunction() {
|
|
279
|
+
let template = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
|
|
280
|
+
return typeof template === 'function' ? template : () => template;
|
|
281
|
+
}
|
|
263
282
|
const helpers = exports.helpers = Object.freeze({
|
|
264
283
|
tagPair,
|
|
265
284
|
formatDate,
|
|
266
|
-
escapeHtml: _commons.escapeHtml
|
|
285
|
+
escapeHtml: _commons.escapeHtml,
|
|
286
|
+
asFunction
|
|
267
287
|
});
|
package/dist/cjs/version.js
CHANGED
package/package.json
CHANGED
package/src/asset/svgs.js
CHANGED
|
@@ -1,13 +1,23 @@
|
|
|
1
1
|
import version from '../version.js';
|
|
2
2
|
|
|
3
|
+
function trianglePath(r) {
|
|
4
|
+
const l = 100;
|
|
5
|
+
const d = r * Math.tan(3 * Math.PI / 8);
|
|
6
|
+
const e = d * Math.sin(Math.PI / 4);
|
|
7
|
+
return `M${r} 0L${l-d} 0A${r} ${r} 0 0 1 ${l-e} ${e}L${e} ${l-e}A${r} ${r} 0 0 1 0 ${l-d}L0 ${r}Z`;
|
|
8
|
+
}
|
|
9
|
+
|
|
3
10
|
const PREFIX = 'miso-ui-icon';
|
|
4
11
|
const ID = `${PREFIX}-svg-${version.replaceAll('.', '_')}`;
|
|
5
12
|
|
|
6
|
-
//
|
|
13
|
+
// CC0 SVGs
|
|
7
14
|
const ICON_SEND = `<symbol id="${PREFIX}-send" viewBox="0 0 32 32"><path fill="currentColor" d="M11.499,19.173l5.801,-5.849c0.389,-0.392 1.022,-0.394 1.414,-0.006c0.392,0.389 0.395,1.022 0.006,1.414l-5.798,5.847l5.306,8.002c0.207,0.313 0.572,0.483 0.945,0.441c0.373,-0.042 0.691,-0.289 0.824,-0.64l9.024,-23.904c0.138,-0.366 0.05,-0.78 -0.226,-1.058c-0.276,-0.278 -0.689,-0.369 -1.057,-0.233l-24.004,8.892c-0.353,0.13 -0.602,0.448 -0.646,0.821c-0.044,0.373 0.125,0.74 0.438,0.948l7.973,5.325Z"/></symbol>`;
|
|
8
15
|
const ICON_SEARCH = `<symbol id="${PREFIX}-search" viewBox="0 0 24 24"><path fill="currentColor" d="M4 11C4 7.13401 7.13401 4 11 4C14.866 4 18 7.13401 18 11C18 14.866 14.866 18 11 18C7.13401 18 4 14.866 4 11ZM11 2C6.02944 2 2 6.02944 2 11C2 15.9706 6.02944 20 11 20C13.125 20 15.078 19.2635 16.6177 18.0319L20.2929 21.7071C20.6834 22.0976 21.3166 22.0976 21.7071 21.7071C22.0976 21.3166 22.0976 20.6834 21.7071 20.2929L18.0319 16.6177C19.2635 15.078 20 13.125 20 11C20 6.02944 15.9706 2 11 2Z"/></symbol>`;
|
|
9
16
|
|
|
10
|
-
|
|
17
|
+
// Custom SVGs
|
|
18
|
+
const ICON_TRIANGLE = `<symbol id="${PREFIX}-triangle" viewBox="-5 -5 105 105"><path d="${trianglePath(5)}"/></symbol>`;
|
|
19
|
+
|
|
20
|
+
const ICONS = [ICON_SEND, ICON_SEARCH, ICON_TRIANGLE];
|
|
11
21
|
|
|
12
22
|
const SPRITES_SVG = `<svg id="${ID}" style="display:none;">${ICONS.join('')}</svg>`;
|
|
13
23
|
|
|
@@ -29,3 +39,4 @@ function getSvg(name) {
|
|
|
29
39
|
|
|
30
40
|
export const SEND = getSvg('send');
|
|
31
41
|
export const SEARCH = getSvg('search');
|
|
42
|
+
export const TRIANGLE = getSvg('triangle');
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { CarouselItemViewabilityObserver, requestAnimationFrame as raf } from '@miso.ai/commons';
|
|
2
2
|
import { STATUS, LAYOUT_CATEGORY, EVENT_TYPE } from '../../constants.js';
|
|
3
3
|
import CollectionLayout from '../list/collection.js';
|
|
4
|
-
import { affiliation } from '../templates.js';
|
|
4
|
+
import { affiliation, helpers } from '../templates.js';
|
|
5
|
+
import { TRIANGLE } from '../../asset/svgs.js';
|
|
5
6
|
|
|
6
7
|
const TYPE = 'affiliation';
|
|
7
8
|
const DEFAULT_CLASSNAME = 'miso-affiliation';
|
|
@@ -20,15 +21,24 @@ function ready(layout, state) {
|
|
|
20
21
|
const items = layout._getItems(state);
|
|
21
22
|
|
|
22
23
|
if (items && items.length > 0) {
|
|
23
|
-
return templates.
|
|
24
|
+
return templates.controlContainer(layout, state, 'previous') + templates.body(layout, state) + templates.controlContainer(layout, state, 'next');
|
|
24
25
|
} else {
|
|
25
26
|
return templates.empty(layout, state);
|
|
26
27
|
}
|
|
27
28
|
}
|
|
28
29
|
|
|
30
|
+
function controlContainer(layout, state, direction) {
|
|
31
|
+
const { className, templates } = layout;
|
|
32
|
+
return `<div class="${className}__control-${direction}-container">${templates.control(layout, state, direction)}</div>`;
|
|
33
|
+
}
|
|
34
|
+
|
|
29
35
|
function control(layout, state, direction) {
|
|
30
|
-
const { className } = layout;
|
|
31
|
-
return `<div class="${className}__control-${direction}" data-role="${direction}"
|
|
36
|
+
const { className, templates } = layout;
|
|
37
|
+
return `<div class="${className}__control-${direction}" data-role="${direction}">${templates.controlIcon(layout, state, direction)}</div>`;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function controlIcon(layout, state, direction) {
|
|
41
|
+
return TRIANGLE;
|
|
32
42
|
}
|
|
33
43
|
|
|
34
44
|
function body(layout, state) {
|
|
@@ -37,49 +47,56 @@ function body(layout, state) {
|
|
|
37
47
|
return `<div class="${className}__body">${templates.list(layout, state, items)}</div>`;
|
|
38
48
|
}
|
|
39
49
|
|
|
40
|
-
function header(layout, state) {
|
|
41
|
-
const { className, templates } = layout;
|
|
42
|
-
let { headerText } = templates;
|
|
43
|
-
if (typeof headerText === 'function') {
|
|
44
|
-
headerText = headerText(layout, state);
|
|
45
|
-
}
|
|
46
|
-
if (!headerText) {
|
|
47
|
-
return '';
|
|
48
|
-
}
|
|
49
|
-
return `<div class="${className}__header"><div class="${className}__header-tab">${headerText}</div></div>`;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
50
|
function item(layout, state, value, index) {
|
|
53
51
|
const { className, templates, options } = layout;
|
|
54
52
|
const { itemType } = options;
|
|
55
53
|
const header = templates.itemHeader(layout, state, value, { index });
|
|
56
54
|
const body = templates[itemType](layout, state, value, { index });
|
|
57
|
-
return `<li class="${className}__item">${header}${body}</li>`;
|
|
55
|
+
return `<li class="${className}__item"><div class="${className}__item-inner">${header}${body}</div></li>`;
|
|
58
56
|
}
|
|
59
57
|
|
|
60
58
|
function itemHeader(layout, state, value, meta) {
|
|
61
59
|
const { className, templates } = layout;
|
|
62
|
-
let {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
}
|
|
66
|
-
|
|
60
|
+
let { itemHeaderLeftText, itemHeaderRightText } = templates;
|
|
61
|
+
itemHeaderLeftText = helpers.asFunction(itemHeaderLeftText)(layout, state, value, meta);
|
|
62
|
+
itemHeaderRightText = helpers.asFunction(itemHeaderRightText)(layout, state, value, meta);
|
|
63
|
+
return `<div class="${className}__item-header">
|
|
64
|
+
<div class="${className}__item-header-left">${itemHeaderLeftText}</div>
|
|
65
|
+
<div class="${className}__item-header-right">${itemHeaderRightText}</div>
|
|
66
|
+
</div>`;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function itemHeaderRightText(layout, state, value, meta) {
|
|
70
|
+
const { templates } = layout;
|
|
71
|
+
const logoImg = helpers.asFunction(templates.logoImg)(layout, state, value, meta);
|
|
72
|
+
return logoImg ? `Selected by ${logoImg}` : '';
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function logoImg(layout, state, value, meta) {
|
|
76
|
+
const { className, templates } = layout;
|
|
77
|
+
const logoUrl = helpers.asFunction(templates.logoUrl)(layout, state, value, meta);
|
|
78
|
+
if (!logoUrl) {
|
|
67
79
|
return '';
|
|
68
80
|
}
|
|
69
|
-
|
|
81
|
+
const logoAltText = helpers.asFunction(templates.logoAltText)(layout, state, value, meta);
|
|
82
|
+
const logoAltTextAttr = logoAltText ? ` alt="${logoAltText}"` : '';
|
|
83
|
+
return `<img class="${className}__item-header-logo" src="${logoUrl}"${logoAltTextAttr}>`;
|
|
70
84
|
}
|
|
71
85
|
|
|
72
86
|
const DEFAULT_TEMPLATES = Object.freeze({
|
|
73
87
|
root,
|
|
74
88
|
[STATUS.READY]: ready,
|
|
89
|
+
controlContainer,
|
|
75
90
|
control,
|
|
91
|
+
controlIcon,
|
|
76
92
|
body,
|
|
77
|
-
header,
|
|
78
93
|
item,
|
|
79
94
|
itemHeader,
|
|
80
95
|
affiliation,
|
|
81
|
-
ctaText: 'View',
|
|
82
|
-
|
|
96
|
+
ctaText: 'View deal',
|
|
97
|
+
itemHeaderLeftText: `Today's best deals`,
|
|
98
|
+
itemHeaderRightText,
|
|
99
|
+
logoImg,
|
|
83
100
|
});
|
|
84
101
|
|
|
85
102
|
const INHERITED_DEFAULT_TEMPLATES = Object.freeze({
|
|
@@ -87,9 +104,10 @@ const INHERITED_DEFAULT_TEMPLATES = Object.freeze({
|
|
|
87
104
|
...DEFAULT_TEMPLATES,
|
|
88
105
|
});
|
|
89
106
|
|
|
107
|
+
/*
|
|
90
108
|
function normalizeAutoplayOptions(options) {
|
|
91
109
|
if (options === true) {
|
|
92
|
-
options = { interval:
|
|
110
|
+
options = { interval: 10000 };
|
|
93
111
|
} else if (typeof options === 'number') {
|
|
94
112
|
if (options <= 0) {
|
|
95
113
|
options = false;
|
|
@@ -109,6 +127,7 @@ function autoplayOptionsEquals(a, b) {
|
|
|
109
127
|
}
|
|
110
128
|
return a.interval === b.interval;
|
|
111
129
|
}
|
|
130
|
+
*/
|
|
112
131
|
|
|
113
132
|
export default class AffiliationLayout extends CollectionLayout {
|
|
114
133
|
|
|
@@ -135,9 +154,12 @@ export default class AffiliationLayout extends CollectionLayout {
|
|
|
135
154
|
this._displayedCount = undefined;
|
|
136
155
|
this._displayedIndex = undefined;
|
|
137
156
|
this._viewable = undefined;
|
|
138
|
-
this._autoplay = {};
|
|
139
157
|
|
|
158
|
+
// TODO: extract this
|
|
159
|
+
/*
|
|
160
|
+
this._autoplay = {};
|
|
140
161
|
this.autoplay(autoplay);
|
|
162
|
+
*/
|
|
141
163
|
}
|
|
142
164
|
|
|
143
165
|
initialize(view) {
|
|
@@ -146,7 +168,8 @@ export default class AffiliationLayout extends CollectionLayout {
|
|
|
146
168
|
this._viewable = new CarouselItemViewabilityObserver(this._onViewable.bind(this), options);
|
|
147
169
|
}
|
|
148
170
|
|
|
149
|
-
|
|
171
|
+
/*
|
|
172
|
+
autoplay(options = false) {
|
|
150
173
|
options = normalizeAutoplayOptions(options);
|
|
151
174
|
if (autoplayOptionsEquals(options, this._autoplay.options)) {
|
|
152
175
|
return;
|
|
@@ -162,6 +185,7 @@ export default class AffiliationLayout extends CollectionLayout {
|
|
|
162
185
|
this._autoplay.intervalId = setInterval(() => this.next(), options.interval);
|
|
163
186
|
}
|
|
164
187
|
}
|
|
188
|
+
*/
|
|
165
189
|
|
|
166
190
|
get itemIndex() {
|
|
167
191
|
return this._itemIndex;
|
|
@@ -280,7 +304,6 @@ export default class AffiliationLayout extends CollectionLayout {
|
|
|
280
304
|
_trackViewables() {} // omit default behavior for we want to track by other means
|
|
281
305
|
|
|
282
306
|
_onClick(event) {
|
|
283
|
-
super._onClick(event);
|
|
284
307
|
const element = event.target;
|
|
285
308
|
if (element.closest(`[data-role="previous"]`)) {
|
|
286
309
|
this.previous();
|
|
@@ -290,6 +313,7 @@ export default class AffiliationLayout extends CollectionLayout {
|
|
|
290
313
|
this.next();
|
|
291
314
|
return;
|
|
292
315
|
}
|
|
316
|
+
super._onClick(event);
|
|
293
317
|
}
|
|
294
318
|
|
|
295
319
|
}
|
package/src/layout/templates.js
CHANGED
|
@@ -44,12 +44,11 @@ export function article(layout, state, data, meta) {
|
|
|
44
44
|
|
|
45
45
|
export function affiliation(layout, state, data, meta) {
|
|
46
46
|
const { templates } = layout;
|
|
47
|
-
const [openTag, closeTag] = tagPair(layout, data);
|
|
47
|
+
const [openTag, closeTag] = tagPair(layout, data, { link: false});
|
|
48
48
|
return [
|
|
49
49
|
openTag,
|
|
50
50
|
(templates.infoBlock || templates.affiliationInfoBlock || affiliationInfoBlock)(layout, data, meta),
|
|
51
|
-
(templates.imageBlock || imageBlock)(layout, data, meta),
|
|
52
|
-
(templates.brandBlock || brandBlock)(layout, data, meta),
|
|
51
|
+
(templates.imageBlock || imageBlock)(layout, data, { brand: true, ...meta, }),
|
|
53
52
|
closeTag,
|
|
54
53
|
].join('');
|
|
55
54
|
}
|
|
@@ -133,12 +132,15 @@ export function discountRateText(layout, { discount_rate_percent }) {
|
|
|
133
132
|
return `(${discount_rate_percent}% off)`;
|
|
134
133
|
}
|
|
135
134
|
|
|
136
|
-
export function imageBlock(
|
|
135
|
+
export function imageBlock(layout, data, meta) {
|
|
136
|
+
const { className, templates } = layout;
|
|
137
|
+
const { cover_image } = data;
|
|
137
138
|
if (!cover_image) {
|
|
138
139
|
return '';
|
|
139
140
|
}
|
|
140
141
|
const img = `<img class="${className}__item-cover-image" src="${cover_image}">`;
|
|
141
|
-
|
|
142
|
+
const brand = meta.brand ? (templates.brandBlock || brandBlock)(layout, data, meta) : '';
|
|
143
|
+
return `<div class="${className}__item-cover-image-container">${img}${brand}</div>`;
|
|
142
144
|
}
|
|
143
145
|
|
|
144
146
|
export function indexBlock({ className }, data, { index }) {
|
|
@@ -147,28 +149,27 @@ export function indexBlock({ className }, data, { index }) {
|
|
|
147
149
|
|
|
148
150
|
export function ctaBlock(layout, data, meta) {
|
|
149
151
|
const { className, templates } = layout;
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
_cta = _cta(layout, data, meta);
|
|
153
|
-
}
|
|
154
|
-
return _cta ? `<div class="${className}__item-cta-container">${_cta}</div>` : '';
|
|
152
|
+
const cta = helpers.asFunction(templates.cta)(layout, data, meta);
|
|
153
|
+
return cta ? `<div class="${className}__item-cta-container">${cta}</div>` : '';
|
|
155
154
|
}
|
|
156
155
|
|
|
157
156
|
export function cta(layout, data, meta) {
|
|
158
|
-
const {
|
|
159
|
-
|
|
160
|
-
if (
|
|
161
|
-
|
|
157
|
+
const { templates } = layout;
|
|
158
|
+
const { url } = data;
|
|
159
|
+
if (!url) {
|
|
160
|
+
return '';
|
|
162
161
|
}
|
|
163
|
-
|
|
162
|
+
const [openTag, closeTag] = tagPair(layout, { url }, { classSuffix: 'item-cta', role: 'cta' });
|
|
163
|
+
const ctaText = helpers.asFunction(templates.ctaText)(layout, data, meta);
|
|
164
|
+
return ctaText ? `${openTag}${ctaText}${closeTag}` : '';
|
|
164
165
|
}
|
|
165
166
|
|
|
166
167
|
// helpers //
|
|
167
|
-
function tagPair({ className, options = {} }, { product_id, url }, { classSuffix = 'item-body', role = 'item' } = {}) {
|
|
168
|
+
function tagPair({ className, options = {} }, { product_id, url }, { classSuffix = 'item-body', role = 'item', ...meta } = {}) {
|
|
168
169
|
const { link = {} } = options;
|
|
169
170
|
const { target = '_blank', rel = 'noopener' } = link; // TODO: other properties
|
|
170
|
-
const tag = url ? 'a' : 'div';
|
|
171
|
-
const urlAttrs = url ? `href="${url}" target="${target}" rel="${rel}"` : '';
|
|
171
|
+
const tag = meta.link !== false && url ? 'a' : 'div';
|
|
172
|
+
const urlAttrs = meta.link !== false && url ? `href="${url}" target="${target}" rel="${rel}"` : '';
|
|
172
173
|
const productAttrs = product_id ? `${ATTR_DATA_MISO_PRODUCT_ID}="${product_id}"` : '';
|
|
173
174
|
const roleAttrs = role ? `data-role="${role}"` : '';
|
|
174
175
|
return [`<${tag} class="${className}__${classSuffix}" ${roleAttrs} ${productAttrs} ${urlAttrs}>`, `</${tag}>`];
|
|
@@ -189,8 +190,13 @@ function formatDate(date, fn = DEFAULT_DATE_OPTIONS) {
|
|
|
189
190
|
}
|
|
190
191
|
}
|
|
191
192
|
|
|
193
|
+
function asFunction(template = '') {
|
|
194
|
+
return typeof template === 'function' ? template : () => template;
|
|
195
|
+
}
|
|
196
|
+
|
|
192
197
|
export const helpers = Object.freeze({
|
|
193
198
|
tagPair,
|
|
194
199
|
formatDate,
|
|
195
200
|
escapeHtml,
|
|
201
|
+
asFunction,
|
|
196
202
|
});
|
package/src/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export default '1.10.0-beta.
|
|
1
|
+
export default '1.10.0-beta.14';
|