@miso.ai/client-sdk-ui 1.11.5-beta.0 → 1.11.5-beta.2
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 +5 -2
- package/dist/cjs/layout/affiliation/affiliation.js +6 -7
- package/dist/cjs/layout/index.js +7 -0
- package/dist/cjs/layout/input/option-list.js +2 -1
- package/dist/cjs/layout/input/search-box.js +2 -1
- package/dist/cjs/layout/list/carousel.js +2 -2
- package/dist/cjs/layout/list/collection.js +7 -4
- package/dist/cjs/layout/list/gallery.js +273 -0
- package/dist/cjs/layout/mixin/swipeable.js +14 -15
- package/dist/cjs/layout/raf.js +2 -0
- package/dist/cjs/util/dom.js +101 -0
- package/dist/cjs/version.js +1 -1
- package/dist/cjs/workflow/answer-based.js +1 -1
- package/package.json +2 -2
- package/src/asset/svgs.js +5 -1
- package/src/layout/affiliation/affiliation.js +5 -7
- package/src/layout/index.js +1 -0
- package/src/layout/input/option-list.js +2 -1
- package/src/layout/input/search-box.js +2 -1
- package/src/layout/list/carousel.js +3 -3
- package/src/layout/list/collection.js +6 -4
- package/src/layout/list/gallery.js +230 -0
- package/src/layout/mixin/swipeable.js +12 -16
- package/src/layout/raf.js +1 -0
- package/src/util/dom.js +103 -0
- package/src/version.js +1 -1
- package/src/workflow/answer-based.js +2 -2
package/dist/cjs/asset/svgs.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.TRIANGLE_EQ = exports.TRIANGLE = exports.SEND = exports.SEARCH = exports.ICON_NAMES = exports.CHEVRON_NEGATIVE = void 0;
|
|
6
|
+
exports.TRIANGLE_EQ = exports.TRIANGLE = exports.SEND = exports.SEARCH = exports.ICON_NAMES = exports.CHEVRON_NEGATIVE = exports.CHEVRON = 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 }; }
|
|
@@ -20,6 +20,7 @@ const ICON_NAME = {
|
|
|
20
20
|
SEARCH: 'search',
|
|
21
21
|
TRIANGLE: 'triangle',
|
|
22
22
|
TRIANGLE_EQ: 'triangle-eq',
|
|
23
|
+
CHEVRON: 'chevron',
|
|
23
24
|
CHEVRON_NEGATIVE: 'chevron-negative'
|
|
24
25
|
};
|
|
25
26
|
|
|
@@ -30,8 +31,9 @@ const ICON_SEARCH = `<symbol id="${PREFIX}-${ICON_NAME.SEARCH}" viewBox="0 0 24
|
|
|
30
31
|
// Custom SVGs
|
|
31
32
|
const ICON_TRIANGLE = `<symbol id="${PREFIX}-${ICON_NAME.TRIANGLE}" viewBox="-5 -5 105 105"><path d="${trianglePath(5)}"/></symbol>`;
|
|
32
33
|
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>`;
|
|
34
|
+
const ICON_CHEVRON = `<symbol id="${PREFIX}-${ICON_NAME.CHEVRON}" viewBox="-100 -100 200 200"><path d="M10.61 -43.94A15 15,0,0,0,-10.61 -43.94L-60.61 6.06A15 15,0,0,0,-39.39 27.27L0 -12.12L39.39 27.27A15 15,0,0,0,60.61 6.06L10.61 -43.94Z"/></symbol>`;
|
|
33
35
|
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];
|
|
36
|
+
const ICONS = [ICON_SEND, ICON_SEARCH, ICON_TRIANGLE, ICON_TRIANGLE_EQ, ICON_CHEVRON, ICON_CHEVRON_NEGATIVE];
|
|
35
37
|
const SPRITES_SVG = `<svg id="${ID}" style="display:none;">${ICONS.join('')}</svg>`;
|
|
36
38
|
let loaded = false;
|
|
37
39
|
function loadSvgSprites() {
|
|
@@ -53,4 +55,5 @@ const SEND = exports.SEND = _icon(ICON_NAME.SEND);
|
|
|
53
55
|
const SEARCH = exports.SEARCH = _icon(ICON_NAME.SEARCH);
|
|
54
56
|
const TRIANGLE = exports.TRIANGLE = _icon(ICON_NAME.TRIANGLE);
|
|
55
57
|
const TRIANGLE_EQ = exports.TRIANGLE_EQ = _icon(ICON_NAME.TRIANGLE_EQ);
|
|
58
|
+
const CHEVRON = exports.CHEVRON = _icon(ICON_NAME.CHEVRON);
|
|
56
59
|
const CHEVRON_NEGATIVE = exports.CHEVRON_NEGATIVE = _icon(ICON_NAME.CHEVRON_NEGATIVE);
|
|
@@ -9,6 +9,7 @@ var _constants = require("../../constants.js");
|
|
|
9
9
|
var _collection = _interopRequireDefault(require("../list/collection.js"));
|
|
10
10
|
var _templates = require("../templates.js");
|
|
11
11
|
var _svgs = require("../../asset/svgs.js");
|
|
12
|
+
var _dom = require("../../util/dom.js");
|
|
12
13
|
const _excluded = ["className", "templates", "autoplay"];
|
|
13
14
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
14
15
|
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; }
|
|
@@ -18,7 +19,8 @@ function root(layout, state) {
|
|
|
18
19
|
const {
|
|
19
20
|
className,
|
|
20
21
|
role,
|
|
21
|
-
templates
|
|
22
|
+
templates,
|
|
23
|
+
options
|
|
22
24
|
} = layout;
|
|
23
25
|
const {
|
|
24
26
|
status
|
|
@@ -29,7 +31,8 @@ function root(layout, state) {
|
|
|
29
31
|
const items = layout._getItems(state);
|
|
30
32
|
const itemCount = items ? items.length : undefined;
|
|
31
33
|
const itemCountAttr = itemCount !== undefined ? ` data-item-count="${itemCount}"` : '';
|
|
32
|
-
|
|
34
|
+
const itemTypeAttr = options.itemType ? ` data-item-type="${options.itemType}"` : '';
|
|
35
|
+
return `<div class="${className} ${status}"${roleAttr}${channelAttr}${itemTypeAttr}${itemCountAttr}>${status === _constants.STATUS.READY ? templates[status](layout, state) : ''}</div>`;
|
|
33
36
|
}
|
|
34
37
|
function ready(layout, state) {
|
|
35
38
|
const {
|
|
@@ -293,12 +296,8 @@ class AffiliationLayout extends _collection.default {
|
|
|
293
296
|
if (!element) {
|
|
294
297
|
return;
|
|
295
298
|
}
|
|
299
|
+
(0, _dom.setOrRemoveAttribute)(element, 'data-item-count', itemCount);
|
|
296
300
|
this._displayedCount = itemCount;
|
|
297
|
-
if (itemCount === undefined) {
|
|
298
|
-
element.removeAttribute('data-item-count');
|
|
299
|
-
} else {
|
|
300
|
-
element.setAttribute('data-item-count', itemCount);
|
|
301
|
-
}
|
|
302
301
|
}
|
|
303
302
|
_syncItemIndex() {
|
|
304
303
|
const index = this._itemIndex;
|
package/dist/cjs/layout/index.js
CHANGED
|
@@ -57,6 +57,12 @@ Object.defineProperty(exports, "FeedbackLayout", {
|
|
|
57
57
|
return _feedback.default;
|
|
58
58
|
}
|
|
59
59
|
});
|
|
60
|
+
Object.defineProperty(exports, "GalleryLayout", {
|
|
61
|
+
enumerable: true,
|
|
62
|
+
get: function () {
|
|
63
|
+
return _gallery.default;
|
|
64
|
+
}
|
|
65
|
+
});
|
|
60
66
|
Object.defineProperty(exports, "ListLayout", {
|
|
61
67
|
enumerable: true,
|
|
62
68
|
get: function () {
|
|
@@ -113,6 +119,7 @@ var _collection = _interopRequireDefault(require("./list/collection.js"));
|
|
|
113
119
|
var _list = _interopRequireDefault(require("./list/list.js"));
|
|
114
120
|
var _cards = _interopRequireDefault(require("./list/cards.js"));
|
|
115
121
|
var _carousel = _interopRequireDefault(require("./list/carousel.js"));
|
|
122
|
+
var _gallery = _interopRequireDefault(require("./list/gallery.js"));
|
|
116
123
|
var _searchBox = _interopRequireDefault(require("./input/search-box.js"));
|
|
117
124
|
var _optionList = _interopRequireDefault(require("./input/option-list.js"));
|
|
118
125
|
var _feedback = _interopRequireDefault(require("./radio/feedback.js"));
|
|
@@ -8,6 +8,7 @@ var _commons = require("@miso.ai/commons");
|
|
|
8
8
|
var _index = require("../../actor/index.js");
|
|
9
9
|
var _template = _interopRequireDefault(require("../template.js"));
|
|
10
10
|
var _trackable = require("../mixin/trackable.js");
|
|
11
|
+
var _dom = require("../../util/dom.js");
|
|
11
12
|
const _excluded = ["className", "templates"];
|
|
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 (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
|
|
@@ -107,7 +108,7 @@ class OptionListLayout extends _template.default {
|
|
|
107
108
|
return;
|
|
108
109
|
}
|
|
109
110
|
const optionValues = this._getItems(state) || [];
|
|
110
|
-
optionsElement
|
|
111
|
+
(0, _dom.addOrRemoveClass)(optionsElement, 'empty', optionValues.length === 0);
|
|
111
112
|
}
|
|
112
113
|
_getItems(state) {
|
|
113
114
|
return state.value;
|
|
@@ -10,6 +10,7 @@ var _index = require("../../actor/index.js");
|
|
|
10
10
|
var _template = _interopRequireDefault(require("../template.js"));
|
|
11
11
|
var _templates = require("../templates.js");
|
|
12
12
|
var _svgs = require("../../asset/svgs.js");
|
|
13
|
+
var _dom = require("../../util/dom.js");
|
|
13
14
|
const _excluded = ["className", "templates", "autocomplete"];
|
|
14
15
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
15
16
|
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; }
|
|
@@ -250,7 +251,7 @@ class SearchBoxLayout extends _template.default {
|
|
|
250
251
|
return;
|
|
251
252
|
}
|
|
252
253
|
const items = context.trackItems(completions);
|
|
253
|
-
element
|
|
254
|
+
(0, _dom.addOrRemoveClass)(element, 'nonempty', items.length > 0);
|
|
254
255
|
autocompleteElement.setAttribute('data-status', status);
|
|
255
256
|
autocompleteElement.innerHTML = this.templates.completions(this, items);
|
|
256
257
|
writeToState({
|
|
@@ -50,8 +50,8 @@ function control(layout, state, direction) {
|
|
|
50
50
|
} = layout;
|
|
51
51
|
return `<div class="${className}__control-${direction}" data-role="${direction}">${templates.controlIcon(layout, state, direction)}</div>`;
|
|
52
52
|
}
|
|
53
|
-
function controlIcon(layout
|
|
54
|
-
return _svgs.CHEVRON_NEGATIVE;
|
|
53
|
+
function controlIcon(layout) {
|
|
54
|
+
return layout.options.itemType === 'image' ? _svgs.CHEVRON_NEGATIVE : _svgs.CHEVRON;
|
|
55
55
|
}
|
|
56
56
|
function indexIndicator(layout, state, values) {
|
|
57
57
|
const {
|
|
@@ -16,13 +16,15 @@ function root(layout, state) {
|
|
|
16
16
|
const {
|
|
17
17
|
className,
|
|
18
18
|
role,
|
|
19
|
-
templates
|
|
19
|
+
templates,
|
|
20
|
+
options
|
|
20
21
|
} = layout;
|
|
21
22
|
const {
|
|
22
23
|
status
|
|
23
24
|
} = state;
|
|
24
|
-
const roleAttr = role ? `data-role="${role}"` : '';
|
|
25
|
-
|
|
25
|
+
const roleAttr = role ? ` data-role="${role}"` : '';
|
|
26
|
+
const itemTypeAttr = options.itemType ? ` data-item-type="${options.itemType}"` : '';
|
|
27
|
+
return `<div class="${className} ${status}"${roleAttr}${itemTypeAttr}>${status === _constants.STATUS.READY ? templates[status](layout, state) : ''}${templates.trigger(layout, state)}${templates.loading(layout, state)}</div>`;
|
|
26
28
|
}
|
|
27
29
|
function ready(layout, state) {
|
|
28
30
|
const {
|
|
@@ -48,8 +50,9 @@ function list(layout, state, values) {
|
|
|
48
50
|
options
|
|
49
51
|
} = layout;
|
|
50
52
|
const listTag = templates.ordered ? 'ol' : 'ul';
|
|
53
|
+
const itemTypeAttr = options.itemType ? ` data-item-type="${options.itemType}"` : ''; // backward compatible
|
|
51
54
|
// TODO: support separator?
|
|
52
|
-
return `<${listTag} class="${className}__list" data-role="list"
|
|
55
|
+
return `<${listTag} class="${className}__list" data-role="list"${itemTypeAttr}>${templates.items(layout, state, values)}</${listTag}>`;
|
|
53
56
|
}
|
|
54
57
|
function items(layout, state, values) {
|
|
55
58
|
let {
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _commons = require("@miso.ai/commons");
|
|
8
|
+
var _collection = _interopRequireDefault(require("./collection.js"));
|
|
9
|
+
var _dom = require("../../util/dom.js");
|
|
10
|
+
const _excluded = ["className", "templates"];
|
|
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 (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
|
|
13
|
+
function calculateItemSizes(itemCount, columnCount) {
|
|
14
|
+
const totalSpaces = columnCount * 2;
|
|
15
|
+
let remainingSpaces = Math.max(totalSpaces - itemCount, 0);
|
|
16
|
+
let small = itemCount;
|
|
17
|
+
// turning a small block into a large block takes 3 extra spaces
|
|
18
|
+
const large = Math.min(Math.floor(remainingSpaces / 3), small);
|
|
19
|
+
small -= large;
|
|
20
|
+
remainingSpaces -= large * 3;
|
|
21
|
+
// turning a small block into a medium block takes 1 extra space
|
|
22
|
+
const medium = Math.min(remainingSpaces, small);
|
|
23
|
+
small -= medium;
|
|
24
|
+
remainingSpaces -= medium;
|
|
25
|
+
return [large, medium, small];
|
|
26
|
+
}
|
|
27
|
+
function item(layout, state, value, index) {
|
|
28
|
+
const {
|
|
29
|
+
className,
|
|
30
|
+
templates,
|
|
31
|
+
options
|
|
32
|
+
} = layout;
|
|
33
|
+
const {
|
|
34
|
+
itemType
|
|
35
|
+
} = options;
|
|
36
|
+
const body = templates[itemType](layout, state, value, {
|
|
37
|
+
index
|
|
38
|
+
});
|
|
39
|
+
const sizeClass = value._size ? ` ${className}__item-${value._size}` : '';
|
|
40
|
+
return `<li class="${className}__item${sizeClass}">${body}</li>`;
|
|
41
|
+
}
|
|
42
|
+
const DEFAULT_HEIGHT = '16rem';
|
|
43
|
+
const DEFAULT_TEMPLATES = Object.freeze(Object.assign({}, _collection.default.defaultTemplates, {
|
|
44
|
+
item
|
|
45
|
+
}));
|
|
46
|
+
const TYPE = 'gallery';
|
|
47
|
+
const DEFAULT_CLASSNAME = 'miso-gallery';
|
|
48
|
+
class GalleryLayout extends _collection.default {
|
|
49
|
+
static get type() {
|
|
50
|
+
return TYPE;
|
|
51
|
+
}
|
|
52
|
+
static get defaultTemplates() {
|
|
53
|
+
return DEFAULT_TEMPLATES;
|
|
54
|
+
}
|
|
55
|
+
static get defaultClassName() {
|
|
56
|
+
return DEFAULT_CLASSNAME;
|
|
57
|
+
}
|
|
58
|
+
constructor() {
|
|
59
|
+
let _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
60
|
+
let {
|
|
61
|
+
className = DEFAULT_CLASSNAME,
|
|
62
|
+
templates
|
|
63
|
+
} = _ref,
|
|
64
|
+
options = _objectWithoutPropertiesLoose(_ref, _excluded);
|
|
65
|
+
super(Object.assign({
|
|
66
|
+
className,
|
|
67
|
+
templates: Object.assign({}, DEFAULT_TEMPLATES, templates)
|
|
68
|
+
}, options));
|
|
69
|
+
this._galleryContext = {
|
|
70
|
+
itemAspectRatio: undefined,
|
|
71
|
+
itemCount: undefined,
|
|
72
|
+
columnCount: undefined
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
syncSize() {
|
|
76
|
+
const {
|
|
77
|
+
element
|
|
78
|
+
} = this._view;
|
|
79
|
+
const listElement = element && this._getListElement(element);
|
|
80
|
+
if (!listElement) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
this._syncListAspectRatio(listElement);
|
|
84
|
+
this._syncItemSizes(listElement);
|
|
85
|
+
}
|
|
86
|
+
_preprocess(_ref2) {
|
|
87
|
+
let {
|
|
88
|
+
state,
|
|
89
|
+
rendered
|
|
90
|
+
} = _ref2;
|
|
91
|
+
const incremental = this._shallRenderIncrementally(state, rendered);
|
|
92
|
+
const bodyHtml = incremental ? undefined : this._bodyHtml(state);
|
|
93
|
+
const itemsHtml = this._itemsHtml(state, rendered);
|
|
94
|
+
return Object.assign({}, state, (0, _commons.trimObj)({
|
|
95
|
+
incremental,
|
|
96
|
+
bodyHtml,
|
|
97
|
+
itemsHtml
|
|
98
|
+
}));
|
|
99
|
+
}
|
|
100
|
+
_bodyHtml(state) {
|
|
101
|
+
return this.templates.root(this, Object.assign({}, state, {
|
|
102
|
+
value: []
|
|
103
|
+
}));
|
|
104
|
+
}
|
|
105
|
+
_itemsHtml(state, rendered) {
|
|
106
|
+
const offset = rendered && rendered.value && rendered.value.length || 0;
|
|
107
|
+
const values = (this._getItems(state) || []).slice(offset);
|
|
108
|
+
return values.length > 0 ? this.templates.items(this, state, values, {
|
|
109
|
+
offset
|
|
110
|
+
}) : '';
|
|
111
|
+
}
|
|
112
|
+
_render(element, states, controls) {
|
|
113
|
+
this._syncItemCount(states);
|
|
114
|
+
this._syncCssVariables();
|
|
115
|
+
const listElement = this._renderListElement(element, states, controls);
|
|
116
|
+
if (!listElement) {
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
this._syncListAspectRatio(listElement);
|
|
120
|
+
this._renderItems(listElement, states, controls);
|
|
121
|
+
}
|
|
122
|
+
_renderListElement(element, _ref3) {
|
|
123
|
+
let {
|
|
124
|
+
state
|
|
125
|
+
} = _ref3;
|
|
126
|
+
const {
|
|
127
|
+
incremental,
|
|
128
|
+
bodyHtml
|
|
129
|
+
} = state;
|
|
130
|
+
if (!incremental) {
|
|
131
|
+
element.innerHTML = bodyHtml;
|
|
132
|
+
}
|
|
133
|
+
return this._getListElement(element);
|
|
134
|
+
}
|
|
135
|
+
_renderItems(listElement, states) {
|
|
136
|
+
if (states.state.incremental) {
|
|
137
|
+
this._appendItems(listElement, states);
|
|
138
|
+
} else {
|
|
139
|
+
this._updateItems(listElement, states);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
_updateItems(listElement, _ref4) {
|
|
143
|
+
let {
|
|
144
|
+
state
|
|
145
|
+
} = _ref4;
|
|
146
|
+
const {
|
|
147
|
+
itemSizes
|
|
148
|
+
} = this._galleryContext;
|
|
149
|
+
const values = this._writeItemSizes(this._getItems(state), itemSizes);
|
|
150
|
+
listElement.innerHTML = this.templates.items(this, state, values);
|
|
151
|
+
}
|
|
152
|
+
_appendItems(listElement, _ref5) {
|
|
153
|
+
let {
|
|
154
|
+
state
|
|
155
|
+
} = _ref5;
|
|
156
|
+
const {
|
|
157
|
+
itemSizes
|
|
158
|
+
} = this._galleryContext;
|
|
159
|
+
// update existing items
|
|
160
|
+
this._syncItemSizes(listElement);
|
|
161
|
+
// append new items
|
|
162
|
+
const offset = listElement.children.length;
|
|
163
|
+
const values = this._writeItemSizes(this._getItems(state).slice(offset), itemSizes, offset);
|
|
164
|
+
listElement.insertAdjacentHTML('beforeend', this.templates.items(this, state, values, {
|
|
165
|
+
offset
|
|
166
|
+
}));
|
|
167
|
+
}
|
|
168
|
+
_writeItemSizes() {
|
|
169
|
+
let values = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
|
|
170
|
+
let [large = 0, medium = 0] = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
|
|
171
|
+
let offset = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
|
|
172
|
+
let omitted = 0;
|
|
173
|
+
if (offset > 0) {
|
|
174
|
+
omitted = Math.min(offset, large);
|
|
175
|
+
offset -= omitted;
|
|
176
|
+
large -= omitted;
|
|
177
|
+
}
|
|
178
|
+
if (offset > 0) {
|
|
179
|
+
omitted = Math.min(offset, medium);
|
|
180
|
+
offset -= omitted;
|
|
181
|
+
medium -= omitted;
|
|
182
|
+
}
|
|
183
|
+
const results = [];
|
|
184
|
+
for (const value of values) {
|
|
185
|
+
let _size = 'small';
|
|
186
|
+
if (large > 0) {
|
|
187
|
+
_size = 'large';
|
|
188
|
+
large--;
|
|
189
|
+
} else if (medium > 0) {
|
|
190
|
+
_size = 'medium';
|
|
191
|
+
medium--;
|
|
192
|
+
}
|
|
193
|
+
results.push(Object.assign({}, value, {
|
|
194
|
+
_size
|
|
195
|
+
}));
|
|
196
|
+
}
|
|
197
|
+
return results;
|
|
198
|
+
}
|
|
199
|
+
_syncCssVariables() {
|
|
200
|
+
const context = this._galleryContext;
|
|
201
|
+
let {
|
|
202
|
+
itemAspectRatio = 1,
|
|
203
|
+
height = DEFAULT_HEIGHT
|
|
204
|
+
} = this.options;
|
|
205
|
+
itemAspectRatio = context.itemAspectRatio = (0, _dom.cssAspectRatio)(itemAspectRatio);
|
|
206
|
+
const {
|
|
207
|
+
element
|
|
208
|
+
} = this._view;
|
|
209
|
+
if (!element) {
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
// TODO: skip if equal to default values
|
|
213
|
+
element.style.setProperty('--miso-gallery-height', `${height}`);
|
|
214
|
+
element.style.setProperty('--miso-gallery-item-1x1-aspect-ratio', `${itemAspectRatio}`);
|
|
215
|
+
element.style.setProperty('--miso-gallery-item-1x2-aspect-ratio', `${itemAspectRatio.scaleBy([1, 2])}`);
|
|
216
|
+
}
|
|
217
|
+
_syncListAspectRatio(listElement) {
|
|
218
|
+
const context = this._galleryContext;
|
|
219
|
+
const {
|
|
220
|
+
itemCount,
|
|
221
|
+
itemAspectRatio
|
|
222
|
+
} = context;
|
|
223
|
+
const {
|
|
224
|
+
height = DEFAULT_HEIGHT
|
|
225
|
+
} = this.options;
|
|
226
|
+
const resolvedHeight = (0, _dom.resolveCssLength)(height);
|
|
227
|
+
const width = listElement.clientWidth;
|
|
228
|
+
if (width === 0) {
|
|
229
|
+
context.columnCount = undefined;
|
|
230
|
+
context.itemSizes = undefined;
|
|
231
|
+
return; // probably not visible yet
|
|
232
|
+
}
|
|
233
|
+
const columnCount = context.columnCount = Math.round(width * itemAspectRatio.width * 2 / (resolvedHeight * itemAspectRatio.height));
|
|
234
|
+
context.itemSizes = calculateItemSizes(itemCount, columnCount);
|
|
235
|
+
|
|
236
|
+
// update DOM
|
|
237
|
+
listElement.style.aspectRatio = `${columnCount} / 2`;
|
|
238
|
+
listElement.style.height = 'auto';
|
|
239
|
+
}
|
|
240
|
+
_syncItemCount() {
|
|
241
|
+
let {
|
|
242
|
+
state
|
|
243
|
+
} = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
244
|
+
const items = this._getItems(state);
|
|
245
|
+
this._galleryContext.itemCount = items ? items.length : undefined;
|
|
246
|
+
}
|
|
247
|
+
_syncItemSizes(listElement) {
|
|
248
|
+
const {
|
|
249
|
+
itemSizes = []
|
|
250
|
+
} = this._galleryContext;
|
|
251
|
+
let [large = 0, medium = 0] = itemSizes;
|
|
252
|
+
const {
|
|
253
|
+
className
|
|
254
|
+
} = this;
|
|
255
|
+
|
|
256
|
+
// update DOM
|
|
257
|
+
for (const itemElement of listElement.children) {
|
|
258
|
+
let lg = false,
|
|
259
|
+
md = false;
|
|
260
|
+
if (large > 0) {
|
|
261
|
+
lg = true;
|
|
262
|
+
large--;
|
|
263
|
+
} else if (medium > 0) {
|
|
264
|
+
md = true;
|
|
265
|
+
medium--;
|
|
266
|
+
}
|
|
267
|
+
(0, _dom.addOrRemoveClass)(itemElement, `${className}__item-large`, lg);
|
|
268
|
+
(0, _dom.addOrRemoveClass)(itemElement, `${className}__item-medium`, md);
|
|
269
|
+
(0, _dom.addOrRemoveClass)(itemElement, `${className}__item-small`, !lg && !md);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
exports.default = GalleryLayout;
|
|
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.SwipeableMixin = void 0;
|
|
7
7
|
exports.makeSwipeable = makeSwipeable;
|
|
8
8
|
var _commons = require("@miso.ai/commons");
|
|
9
|
+
var _dom = require("../../util/dom.js");
|
|
9
10
|
function makeSwipeable(prototype) {
|
|
10
11
|
(0, _commons.mixin)(prototype, SwipeableMixin.prototype);
|
|
11
12
|
}
|
|
@@ -36,7 +37,7 @@ class SwipeableMixin {
|
|
|
36
37
|
index = 0;
|
|
37
38
|
}
|
|
38
39
|
context.itemIndex = index;
|
|
39
|
-
(0, _commons.requestAnimationFrame)(() => this.
|
|
40
|
+
(0, _commons.requestAnimationFrame)(() => this._syncDisplayedSwipeableItemIndex());
|
|
40
41
|
}
|
|
41
42
|
next() {
|
|
42
43
|
if (this._swipeableContext.itemCount === undefined) {
|
|
@@ -52,7 +53,8 @@ class SwipeableMixin {
|
|
|
52
53
|
}
|
|
53
54
|
_renderSwipeable(element, states, controls) {
|
|
54
55
|
this._syncSwipeableItemCount(states);
|
|
55
|
-
this.
|
|
56
|
+
this._syncDisplayedSwipeableItemCount();
|
|
57
|
+
this._syncDisplayedSwipeableItemIndex();
|
|
56
58
|
}
|
|
57
59
|
_afterRenderSwipeable() {
|
|
58
60
|
this._emitSwipeableDisplayEvent();
|
|
@@ -74,7 +76,6 @@ class SwipeableMixin {
|
|
|
74
76
|
} else if (oldItemCount === undefined) {
|
|
75
77
|
context.itemIndex = 0;
|
|
76
78
|
}
|
|
77
|
-
this._syncDisplayedSwipeableItemCount();
|
|
78
79
|
}
|
|
79
80
|
_syncDisplayedSwipeableItemCount() {
|
|
80
81
|
const context = this._swipeableContext;
|
|
@@ -91,22 +92,20 @@ class SwipeableMixin {
|
|
|
91
92
|
if (!element) {
|
|
92
93
|
return;
|
|
93
94
|
}
|
|
95
|
+
(0, _dom.setOrRemoveAttribute)(element, 'data-item-count', itemCount);
|
|
94
96
|
context.displayedCount = itemCount;
|
|
95
|
-
if (itemCount === undefined) {
|
|
96
|
-
element.removeAttribute('data-item-count');
|
|
97
|
-
} else {
|
|
98
|
-
element.setAttribute('data-item-count', itemCount);
|
|
99
|
-
}
|
|
100
97
|
}
|
|
101
|
-
|
|
98
|
+
_syncDisplayedSwipeableItemIndex() {
|
|
102
99
|
const context = this._swipeableContext;
|
|
103
|
-
const
|
|
104
|
-
|
|
100
|
+
const {
|
|
101
|
+
itemIndex
|
|
102
|
+
} = context;
|
|
103
|
+
if (itemIndex === context.displayedIndex) {
|
|
105
104
|
return;
|
|
106
105
|
}
|
|
107
|
-
context.displayedIndex =
|
|
108
|
-
this._syncSwipeableListIndex(
|
|
109
|
-
this._syncSwipeableIndicatorIndex(
|
|
106
|
+
context.displayedIndex = itemIndex;
|
|
107
|
+
this._syncSwipeableListIndex(itemIndex);
|
|
108
|
+
this._syncSwipeableIndicatorIndex(itemIndex);
|
|
110
109
|
}
|
|
111
110
|
_syncSwipeableListIndex(index) {
|
|
112
111
|
const {
|
|
@@ -128,7 +127,7 @@ class SwipeableMixin {
|
|
|
128
127
|
}
|
|
129
128
|
let i = 0;
|
|
130
129
|
for (const item of indicatorElement.children) {
|
|
131
|
-
item
|
|
130
|
+
(0, _dom.addOrRemoveClass)(item, 'active', i === index);
|
|
132
131
|
i++;
|
|
133
132
|
}
|
|
134
133
|
}
|
package/dist/cjs/layout/raf.js
CHANGED
|
@@ -115,6 +115,8 @@ class RafLayout {
|
|
|
115
115
|
state = Object.freeze(Object.assign({}, state, stateExtra.value));
|
|
116
116
|
this._rendered.set(this._element, state);
|
|
117
117
|
notifyUpdate && notifyUpdate(...argsForNotifyUpdate.value);
|
|
118
|
+
|
|
119
|
+
// TODO: should the signature be aligned with _render?
|
|
118
120
|
this._afterRender(this._element, state);
|
|
119
121
|
}
|
|
120
122
|
_render() {
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.addOrRemoveClass = addOrRemoveClass;
|
|
7
|
+
exports.cssAspectRatio = cssAspectRatio;
|
|
8
|
+
exports.resolveCssLength = resolveCssLength;
|
|
9
|
+
exports.setOrRemoveAttribute = setOrRemoveAttribute;
|
|
10
|
+
function setOrRemoveAttribute(element, name, value) {
|
|
11
|
+
if (value === undefined) {
|
|
12
|
+
element.removeAttribute(name);
|
|
13
|
+
} else {
|
|
14
|
+
element.setAttribute(name, value);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
function addOrRemoveClass(element, name, add) {
|
|
18
|
+
if (add) {
|
|
19
|
+
element.classList.add(name);
|
|
20
|
+
} else {
|
|
21
|
+
element.classList.remove(name);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
function resolveCssLength(str) {
|
|
25
|
+
if (typeof str === 'number') {
|
|
26
|
+
return str;
|
|
27
|
+
}
|
|
28
|
+
const [value, unit] = parseLength(str);
|
|
29
|
+
switch (unit) {
|
|
30
|
+
case '':
|
|
31
|
+
case 'px':
|
|
32
|
+
return value;
|
|
33
|
+
case 'rem':
|
|
34
|
+
return remToPx(value);
|
|
35
|
+
default:
|
|
36
|
+
throw new Error(`Unsupported unit: ${unit}`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
function parseLength(str) {
|
|
40
|
+
const match = str.match(/^([+-]?(?:\d+|\d*\.\d+))([a-z]*)$/);
|
|
41
|
+
if (!match) {
|
|
42
|
+
throw new Error(`Invalid length: ${str}`);
|
|
43
|
+
}
|
|
44
|
+
const value = parseFloat(match[1]);
|
|
45
|
+
const unit = match[2] || '';
|
|
46
|
+
return [value, unit];
|
|
47
|
+
}
|
|
48
|
+
function remToPx() {
|
|
49
|
+
let value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1;
|
|
50
|
+
return value * parseFloat(getComputedStyle(document.documentElement).fontSize);
|
|
51
|
+
}
|
|
52
|
+
function cssAspectRatio(value) {
|
|
53
|
+
return value === undefined || value instanceof CssAspectRatio ? value : new CssAspectRatio(value);
|
|
54
|
+
}
|
|
55
|
+
class CssAspectRatio {
|
|
56
|
+
constructor(value) {
|
|
57
|
+
this._width = NaN;
|
|
58
|
+
this._height = NaN;
|
|
59
|
+
switch (typeof value) {
|
|
60
|
+
case 'number':
|
|
61
|
+
this._width = value;
|
|
62
|
+
this._height = 1;
|
|
63
|
+
break;
|
|
64
|
+
case 'object':
|
|
65
|
+
if (Array.isArray(value)) {
|
|
66
|
+
this._width = parseFloat(value[0]);
|
|
67
|
+
this._height = parseFloat(value[1]);
|
|
68
|
+
}
|
|
69
|
+
break;
|
|
70
|
+
case 'string':
|
|
71
|
+
const i = value.indexOf('/');
|
|
72
|
+
if (i < 0) {
|
|
73
|
+
this._width = parseFloat(value);
|
|
74
|
+
this._height = 1;
|
|
75
|
+
} else {
|
|
76
|
+
this._width = parseFloat(value.slice(0, i).trim());
|
|
77
|
+
this._height = parseFloat(value.slice(i + 1).trim());
|
|
78
|
+
}
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
if (this._width === NaN || this._height === NaN) {
|
|
82
|
+
throw new Error(`Invalid aspect ratio value: ${value}`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
get width() {
|
|
86
|
+
return this._width;
|
|
87
|
+
}
|
|
88
|
+
get height() {
|
|
89
|
+
return this._height;
|
|
90
|
+
}
|
|
91
|
+
get floatValue() {
|
|
92
|
+
return this._width / this._height;
|
|
93
|
+
}
|
|
94
|
+
scaleBy(factor) {
|
|
95
|
+
factor = cssAspectRatio(factor);
|
|
96
|
+
return cssAspectRatio([factor._width * this._width, factor._height * this._height]);
|
|
97
|
+
}
|
|
98
|
+
toString() {
|
|
99
|
+
return this._height === 1 ? `${this._width}` : `${this._width} / ${this._height}`;
|
|
100
|
+
}
|
|
101
|
+
}
|
package/dist/cjs/version.js
CHANGED
|
@@ -43,7 +43,7 @@ const DEFAULT_LAYOUTS = Object.freeze(Object.assign({}, _base.default.DEFAULT_LA
|
|
|
43
43
|
}],
|
|
44
44
|
[_constants.ROLE.ANSWER]: _index2.TypewriterLayout.type,
|
|
45
45
|
[_constants.ROLE.FEEDBACK]: _index2.FeedbackLayout.type,
|
|
46
|
-
[_constants.ROLE.IMAGES]: [_index2.
|
|
46
|
+
[_constants.ROLE.IMAGES]: [_index2.GalleryLayout.type, {
|
|
47
47
|
incremental: true,
|
|
48
48
|
itemType: 'image'
|
|
49
49
|
}],
|
package/package.json
CHANGED
package/src/asset/svgs.js
CHANGED
|
@@ -15,6 +15,7 @@ const ICON_NAME = {
|
|
|
15
15
|
SEARCH: 'search',
|
|
16
16
|
TRIANGLE: 'triangle',
|
|
17
17
|
TRIANGLE_EQ: 'triangle-eq',
|
|
18
|
+
CHEVRON: 'chevron',
|
|
18
19
|
CHEVRON_NEGATIVE: 'chevron-negative',
|
|
19
20
|
};
|
|
20
21
|
|
|
@@ -27,9 +28,11 @@ const ICON_TRIANGLE = `<symbol id="${PREFIX}-${ICON_NAME.TRIANGLE}" viewBox="-5
|
|
|
27
28
|
|
|
28
29
|
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>`;
|
|
29
30
|
|
|
31
|
+
const ICON_CHEVRON = `<symbol id="${PREFIX}-${ICON_NAME.CHEVRON}" viewBox="-100 -100 200 200"><path d="M10.61 -43.94A15 15,0,0,0,-10.61 -43.94L-60.61 6.06A15 15,0,0,0,-39.39 27.27L0 -12.12L39.39 27.27A15 15,0,0,0,60.61 6.06L10.61 -43.94Z"/></symbol>`;
|
|
32
|
+
|
|
30
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>`;
|
|
31
34
|
|
|
32
|
-
const ICONS = [ICON_SEND, ICON_SEARCH, ICON_TRIANGLE, ICON_TRIANGLE_EQ, ICON_CHEVRON_NEGATIVE];
|
|
35
|
+
const ICONS = [ICON_SEND, ICON_SEARCH, ICON_TRIANGLE, ICON_TRIANGLE_EQ, ICON_CHEVRON, ICON_CHEVRON_NEGATIVE];
|
|
33
36
|
|
|
34
37
|
const SPRITES_SVG = `<svg id="${ID}" style="display:none;">${ICONS.join('')}</svg>`;
|
|
35
38
|
|
|
@@ -59,4 +62,5 @@ export const SEND = _icon(ICON_NAME.SEND);
|
|
|
59
62
|
export const SEARCH = _icon(ICON_NAME.SEARCH);
|
|
60
63
|
export const TRIANGLE = _icon(ICON_NAME.TRIANGLE);
|
|
61
64
|
export const TRIANGLE_EQ = _icon(ICON_NAME.TRIANGLE_EQ);
|
|
65
|
+
export const CHEVRON = _icon(ICON_NAME.CHEVRON);
|
|
62
66
|
export const CHEVRON_NEGATIVE = _icon(ICON_NAME.CHEVRON_NEGATIVE);
|
|
@@ -3,12 +3,13 @@ import { STATUS } from '../../constants.js';
|
|
|
3
3
|
import CollectionLayout from '../list/collection.js';
|
|
4
4
|
import { affiliation, helpers } from '../templates.js';
|
|
5
5
|
import { TRIANGLE } from '../../asset/svgs.js';
|
|
6
|
+
import { setOrRemoveAttribute } from '../../util/dom.js';
|
|
6
7
|
|
|
7
8
|
const TYPE = 'affiliation';
|
|
8
9
|
const DEFAULT_CLASSNAME = 'miso-affiliation';
|
|
9
10
|
|
|
10
11
|
function root(layout, state) {
|
|
11
|
-
const { className, role, templates } = layout;
|
|
12
|
+
const { className, role, templates, options } = layout;
|
|
12
13
|
const { status } = state;
|
|
13
14
|
const roleAttr = role ? ` data-role="${role}"` : '';
|
|
14
15
|
const data = state.value || {};
|
|
@@ -16,7 +17,8 @@ function root(layout, state) {
|
|
|
16
17
|
const items = layout._getItems(state);
|
|
17
18
|
const itemCount = items ? items.length : undefined;
|
|
18
19
|
const itemCountAttr = itemCount !== undefined ? ` data-item-count="${itemCount}"` : '';
|
|
19
|
-
|
|
20
|
+
const itemTypeAttr = options.itemType ? ` data-item-type="${options.itemType}"` : '';
|
|
21
|
+
return `<div class="${className} ${status}"${roleAttr}${channelAttr}${itemTypeAttr}${itemCountAttr}>${status === STATUS.READY ? templates[status](layout, state) : ''}</div>`;
|
|
20
22
|
}
|
|
21
23
|
|
|
22
24
|
function ready(layout, state) {
|
|
@@ -256,12 +258,8 @@ export default class AffiliationLayout extends CollectionLayout {
|
|
|
256
258
|
if (!element) {
|
|
257
259
|
return;
|
|
258
260
|
}
|
|
261
|
+
setOrRemoveAttribute(element, 'data-item-count', itemCount);
|
|
259
262
|
this._displayedCount = itemCount;
|
|
260
|
-
if (itemCount === undefined) {
|
|
261
|
-
element.removeAttribute('data-item-count');
|
|
262
|
-
} else {
|
|
263
|
-
element.setAttribute('data-item-count', itemCount);
|
|
264
|
-
}
|
|
265
263
|
}
|
|
266
264
|
|
|
267
265
|
_syncItemIndex() {
|
package/src/layout/index.js
CHANGED
|
@@ -6,6 +6,7 @@ export { default as CollectionLayout } from './list/collection.js';
|
|
|
6
6
|
export { default as ListLayout } from './list/list.js';
|
|
7
7
|
export { default as CardsLayout } from './list/cards.js';
|
|
8
8
|
export { default as CarouselLayout } from './list/carousel.js';
|
|
9
|
+
export { default as GalleryLayout } from './list/gallery.js';
|
|
9
10
|
export { default as SearchBoxLayout } from './input/search-box.js';
|
|
10
11
|
export { default as OptionListLayout } from './input/option-list.js';
|
|
11
12
|
export { default as FeedbackLayout } from './radio/feedback.js';
|
|
@@ -2,6 +2,7 @@ import { escapeHtml } from '@miso.ai/commons';
|
|
|
2
2
|
import { fields } from '../../actor/index.js';
|
|
3
3
|
import TemplateBasedLayout from '../template.js';
|
|
4
4
|
import { makeTrackable } from '../mixin/trackable.js';
|
|
5
|
+
import { addOrRemoveClass } from '../../util/dom.js';
|
|
5
6
|
|
|
6
7
|
const TYPE = 'option-list';
|
|
7
8
|
const DEFAULT_CLASSNAME = 'miso-option-list';
|
|
@@ -96,7 +97,7 @@ export default class OptionListLayout extends TemplateBasedLayout {
|
|
|
96
97
|
return;
|
|
97
98
|
}
|
|
98
99
|
const optionValues = this._getItems(state) || [];
|
|
99
|
-
optionsElement
|
|
100
|
+
addOrRemoveClass(optionsElement, 'empty', optionValues.length === 0);
|
|
100
101
|
}
|
|
101
102
|
|
|
102
103
|
_getItems(state) {
|
|
@@ -4,6 +4,7 @@ import { fields } from '../../actor/index.js';
|
|
|
4
4
|
import TemplateBasedLayout from '../template.js';
|
|
5
5
|
import { imageBlock, productInfoBlock } from '../templates.js';
|
|
6
6
|
import { getIcon } from '../../asset/svgs.js';
|
|
7
|
+
import { addOrRemoveClass } from '../../util/dom.js';
|
|
7
8
|
|
|
8
9
|
const TYPE = 'search-box';
|
|
9
10
|
const DEFAULT_CLASSNAME = 'miso-search-box';
|
|
@@ -215,7 +216,7 @@ export default class SearchBoxLayout extends TemplateBasedLayout {
|
|
|
215
216
|
|
|
216
217
|
const items = context.trackItems(completions);
|
|
217
218
|
|
|
218
|
-
element
|
|
219
|
+
addOrRemoveClass(element, 'nonempty', items.length > 0);
|
|
219
220
|
autocompleteElement.setAttribute('data-status', status);
|
|
220
221
|
autocompleteElement.innerHTML = this.templates.completions(this, items);
|
|
221
222
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import CollectionLayout from './collection.js';
|
|
2
2
|
import { makeSwipeable } from '../mixin/swipeable.js';
|
|
3
|
-
import { CHEVRON_NEGATIVE } from '../../asset/svgs.js';
|
|
3
|
+
import { CHEVRON, CHEVRON_NEGATIVE } from '../../asset/svgs.js';
|
|
4
4
|
|
|
5
5
|
const TYPE = 'carousel';
|
|
6
6
|
const DEFAULT_CLASSNAME = 'miso-carousel';
|
|
@@ -41,8 +41,8 @@ function control(layout, state, direction) {
|
|
|
41
41
|
return `<div class="${className}__control-${direction}" data-role="${direction}">${templates.controlIcon(layout, state, direction)}</div>`;
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
function controlIcon(layout
|
|
45
|
-
return CHEVRON_NEGATIVE;
|
|
44
|
+
function controlIcon(layout) {
|
|
45
|
+
return layout.options.itemType === 'image' ? CHEVRON_NEGATIVE : CHEVRON;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
function indexIndicator(layout, state, values) {
|
|
@@ -5,10 +5,11 @@ import { makeTriggerable } from '../mixin/triggerable.js';
|
|
|
5
5
|
import { product, article, image, question, productInfoBlock, articleInfoBlock, imageInfoBlock, titleBlock, brandBlock, descriptionBlock, dateBlock, priceBlock, discountRateText, ctaBlock, cta, imageBlock, indexBlock } from '../templates.js';
|
|
6
6
|
|
|
7
7
|
function root(layout, state) {
|
|
8
|
-
const { className, role, templates } = layout;
|
|
8
|
+
const { className, role, templates, options } = layout;
|
|
9
9
|
const { status } = state;
|
|
10
|
-
const roleAttr = role ? `data-role="${role}"` : '';
|
|
11
|
-
|
|
10
|
+
const roleAttr = role ? ` data-role="${role}"` : '';
|
|
11
|
+
const itemTypeAttr = options.itemType ? ` data-item-type="${options.itemType}"` : '';
|
|
12
|
+
return `<div class="${className} ${status}"${roleAttr}${itemTypeAttr}>${status === STATUS.READY ? templates[status](layout, state) : ''}${templates.trigger(layout, state)}${templates.loading(layout, state)}</div>`;
|
|
12
13
|
}
|
|
13
14
|
|
|
14
15
|
function ready(layout, state) {
|
|
@@ -30,8 +31,9 @@ function body(layout, state, values) {
|
|
|
30
31
|
function list(layout, state, values) {
|
|
31
32
|
const { className, templates, options } = layout;
|
|
32
33
|
const listTag = templates.ordered ? 'ol' : 'ul';
|
|
34
|
+
const itemTypeAttr = options.itemType ? ` data-item-type="${options.itemType}"` : ''; // backward compatible
|
|
33
35
|
// TODO: support separator?
|
|
34
|
-
return `<${listTag} class="${className}__list" data-role="list"
|
|
36
|
+
return `<${listTag} class="${className}__list" data-role="list"${itemTypeAttr}>${templates.items(layout, state, values)}</${listTag}>`;
|
|
35
37
|
}
|
|
36
38
|
|
|
37
39
|
function items(layout, state, values, { offset = 0 } = {}) {
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import { trimObj } from '@miso.ai/commons';
|
|
2
|
+
import CollectionLayout from './collection.js';
|
|
3
|
+
import { addOrRemoveClass, resolveCssLength, cssAspectRatio } from '../../util/dom.js';
|
|
4
|
+
|
|
5
|
+
function calculateItemSizes(itemCount, columnCount) {
|
|
6
|
+
const totalSpaces = columnCount * 2;
|
|
7
|
+
let remainingSpaces = Math.max(totalSpaces - itemCount, 0);
|
|
8
|
+
|
|
9
|
+
let small = itemCount;
|
|
10
|
+
// turning a small block into a large block takes 3 extra spaces
|
|
11
|
+
const large = Math.min(Math.floor(remainingSpaces / 3), small);
|
|
12
|
+
small -= large;
|
|
13
|
+
remainingSpaces -= large * 3;
|
|
14
|
+
// turning a small block into a medium block takes 1 extra space
|
|
15
|
+
const medium = Math.min(remainingSpaces, small);
|
|
16
|
+
small -= medium;
|
|
17
|
+
remainingSpaces -= medium;
|
|
18
|
+
|
|
19
|
+
return [large, medium, small];
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function item(layout, state, value, index) {
|
|
23
|
+
const { className, templates, options } = layout;
|
|
24
|
+
const { itemType } = options;
|
|
25
|
+
const body = templates[itemType](layout, state, value, { index });
|
|
26
|
+
const sizeClass = value._size ? ` ${className}__item-${value._size}` : '';
|
|
27
|
+
return `<li class="${className}__item${sizeClass}">${body}</li>`;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const DEFAULT_HEIGHT = '16rem';
|
|
31
|
+
|
|
32
|
+
const DEFAULT_TEMPLATES = Object.freeze({
|
|
33
|
+
...CollectionLayout.defaultTemplates,
|
|
34
|
+
item,
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
const TYPE = 'gallery';
|
|
38
|
+
const DEFAULT_CLASSNAME = 'miso-gallery';
|
|
39
|
+
|
|
40
|
+
export default class GalleryLayout extends CollectionLayout {
|
|
41
|
+
|
|
42
|
+
static get type() {
|
|
43
|
+
return TYPE;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
static get defaultTemplates() {
|
|
47
|
+
return DEFAULT_TEMPLATES;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
static get defaultClassName() {
|
|
51
|
+
return DEFAULT_CLASSNAME;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
constructor({ className = DEFAULT_CLASSNAME, templates, ...options } = {}) {
|
|
55
|
+
super({
|
|
56
|
+
className,
|
|
57
|
+
templates: { ...DEFAULT_TEMPLATES, ...templates },
|
|
58
|
+
...options,
|
|
59
|
+
});
|
|
60
|
+
this._galleryContext = {
|
|
61
|
+
itemAspectRatio: undefined,
|
|
62
|
+
itemCount: undefined,
|
|
63
|
+
columnCount: undefined,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
syncSize() {
|
|
68
|
+
const { element } = this._view;
|
|
69
|
+
const listElement = element && this._getListElement(element);
|
|
70
|
+
if (!listElement) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
this._syncListAspectRatio(listElement);
|
|
74
|
+
this._syncItemSizes(listElement);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
_preprocess({ state, rendered }) {
|
|
78
|
+
const incremental = this._shallRenderIncrementally(state, rendered);
|
|
79
|
+
const bodyHtml = incremental ? undefined : this._bodyHtml(state);
|
|
80
|
+
const itemsHtml = this._itemsHtml(state, rendered);
|
|
81
|
+
return {
|
|
82
|
+
...state,
|
|
83
|
+
...trimObj({
|
|
84
|
+
incremental,
|
|
85
|
+
bodyHtml,
|
|
86
|
+
itemsHtml,
|
|
87
|
+
}),
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
_bodyHtml(state) {
|
|
92
|
+
return this.templates.root(this, { ...state, value: [] });
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
_itemsHtml(state, rendered) {
|
|
96
|
+
const offset = (rendered && rendered.value && rendered.value.length) || 0;
|
|
97
|
+
const values = (this._getItems(state) || []).slice(offset);
|
|
98
|
+
return values.length > 0 ? this.templates.items(this, state, values, { offset }) : '';
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
_render(element, states, controls) {
|
|
102
|
+
this._syncItemCount(states);
|
|
103
|
+
this._syncCssVariables();
|
|
104
|
+
const listElement = this._renderListElement(element, states, controls);
|
|
105
|
+
if (!listElement) {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
this._syncListAspectRatio(listElement);
|
|
109
|
+
this._renderItems(listElement, states, controls);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
_renderListElement(element, { state }) {
|
|
113
|
+
const { incremental, bodyHtml } = state;
|
|
114
|
+
if (!incremental) {
|
|
115
|
+
element.innerHTML = bodyHtml;
|
|
116
|
+
}
|
|
117
|
+
return this._getListElement(element);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
_renderItems(listElement, states) {
|
|
121
|
+
if (states.state.incremental) {
|
|
122
|
+
this._appendItems(listElement, states);
|
|
123
|
+
} else {
|
|
124
|
+
this._updateItems(listElement, states);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
_updateItems(listElement, { state }) {
|
|
129
|
+
const { itemSizes } = this._galleryContext;
|
|
130
|
+
const values = this._writeItemSizes(this._getItems(state), itemSizes);
|
|
131
|
+
listElement.innerHTML = this.templates.items(this, state, values);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
_appendItems(listElement, { state }) {
|
|
135
|
+
const { itemSizes } = this._galleryContext;
|
|
136
|
+
// update existing items
|
|
137
|
+
this._syncItemSizes(listElement);
|
|
138
|
+
// append new items
|
|
139
|
+
const offset = listElement.children.length;
|
|
140
|
+
const values = this._writeItemSizes(this._getItems(state).slice(offset), itemSizes, offset);
|
|
141
|
+
listElement.insertAdjacentHTML('beforeend', this.templates.items(this, state, values, { offset }));
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
_writeItemSizes(values = [], [large = 0, medium = 0] = [], offset = 0) {
|
|
145
|
+
let omitted = 0;
|
|
146
|
+
if (offset > 0) {
|
|
147
|
+
omitted = Math.min(offset, large);
|
|
148
|
+
offset -= omitted;
|
|
149
|
+
large -= omitted;
|
|
150
|
+
}
|
|
151
|
+
if (offset > 0) {
|
|
152
|
+
omitted = Math.min(offset, medium);
|
|
153
|
+
offset -= omitted;
|
|
154
|
+
medium -= omitted;
|
|
155
|
+
}
|
|
156
|
+
const results = [];
|
|
157
|
+
for (const value of values) {
|
|
158
|
+
let _size = 'small';
|
|
159
|
+
if (large > 0) {
|
|
160
|
+
_size = 'large';
|
|
161
|
+
large--;
|
|
162
|
+
} else if (medium > 0) {
|
|
163
|
+
_size = 'medium';
|
|
164
|
+
medium--;
|
|
165
|
+
}
|
|
166
|
+
results.push({ ...value, _size });
|
|
167
|
+
}
|
|
168
|
+
return results;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
_syncCssVariables() {
|
|
172
|
+
const context = this._galleryContext;
|
|
173
|
+
let { itemAspectRatio = 1, height = DEFAULT_HEIGHT } = this.options;
|
|
174
|
+
itemAspectRatio = context.itemAspectRatio = cssAspectRatio(itemAspectRatio);
|
|
175
|
+
const { element } = this._view;
|
|
176
|
+
if (!element) {
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
// TODO: skip if equal to default values
|
|
180
|
+
element.style.setProperty('--miso-gallery-height', `${height}`);
|
|
181
|
+
element.style.setProperty('--miso-gallery-item-1x1-aspect-ratio', `${itemAspectRatio}`);
|
|
182
|
+
element.style.setProperty('--miso-gallery-item-1x2-aspect-ratio', `${itemAspectRatio.scaleBy([1, 2])}`);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
_syncListAspectRatio(listElement) {
|
|
186
|
+
const context = this._galleryContext;
|
|
187
|
+
const { itemCount, itemAspectRatio } = context;
|
|
188
|
+
const { height = DEFAULT_HEIGHT } = this.options;
|
|
189
|
+
const resolvedHeight = resolveCssLength(height);
|
|
190
|
+
const width = listElement.clientWidth;
|
|
191
|
+
if (width === 0) {
|
|
192
|
+
context.columnCount = undefined;
|
|
193
|
+
context.itemSizes = undefined;
|
|
194
|
+
return; // probably not visible yet
|
|
195
|
+
}
|
|
196
|
+
const columnCount = context.columnCount = Math.round((width * itemAspectRatio.width * 2) / (resolvedHeight * itemAspectRatio.height));
|
|
197
|
+
context.itemSizes = calculateItemSizes(itemCount, columnCount);
|
|
198
|
+
|
|
199
|
+
// update DOM
|
|
200
|
+
listElement.style.aspectRatio = `${columnCount} / 2`;
|
|
201
|
+
listElement.style.height = 'auto';
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
_syncItemCount({ state } = {}) {
|
|
205
|
+
const items = this._getItems(state);
|
|
206
|
+
this._galleryContext.itemCount = items ? items.length : undefined;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
_syncItemSizes(listElement) {
|
|
210
|
+
const { itemSizes = [] } = this._galleryContext;
|
|
211
|
+
let [large = 0, medium = 0] = itemSizes;
|
|
212
|
+
const { className } = this;
|
|
213
|
+
|
|
214
|
+
// update DOM
|
|
215
|
+
for (const itemElement of listElement.children) {
|
|
216
|
+
let lg = false, md = false;
|
|
217
|
+
if (large > 0) {
|
|
218
|
+
lg = true;
|
|
219
|
+
large--;
|
|
220
|
+
} else if (medium > 0) {
|
|
221
|
+
md = true;
|
|
222
|
+
medium--;
|
|
223
|
+
}
|
|
224
|
+
addOrRemoveClass(itemElement, `${className}__item-large`, lg);
|
|
225
|
+
addOrRemoveClass(itemElement, `${className}__item-medium`, md);
|
|
226
|
+
addOrRemoveClass(itemElement, `${className}__item-small`, !lg && !md);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { mixin, requestAnimationFrame as raf } from '@miso.ai/commons';
|
|
2
|
+
import { setOrRemoveAttribute, addOrRemoveClass } from '../../util/dom.js';
|
|
2
3
|
|
|
3
4
|
export function makeSwipeable(prototype) {
|
|
4
5
|
mixin(prototype, SwipeableMixin.prototype);
|
|
@@ -33,7 +34,7 @@ export class SwipeableMixin {
|
|
|
33
34
|
index = 0;
|
|
34
35
|
}
|
|
35
36
|
context.itemIndex = index;
|
|
36
|
-
raf(() => this.
|
|
37
|
+
raf(() => this._syncDisplayedSwipeableItemIndex());
|
|
37
38
|
}
|
|
38
39
|
|
|
39
40
|
next() {
|
|
@@ -52,7 +53,8 @@ export class SwipeableMixin {
|
|
|
52
53
|
|
|
53
54
|
_renderSwipeable(element, states, controls) {
|
|
54
55
|
this._syncSwipeableItemCount(states);
|
|
55
|
-
this.
|
|
56
|
+
this._syncDisplayedSwipeableItemCount();
|
|
57
|
+
this._syncDisplayedSwipeableItemIndex();
|
|
56
58
|
}
|
|
57
59
|
|
|
58
60
|
_afterRenderSwipeable() {
|
|
@@ -74,8 +76,6 @@ export class SwipeableMixin {
|
|
|
74
76
|
} else if (oldItemCount === undefined) {
|
|
75
77
|
context.itemIndex = 0;
|
|
76
78
|
}
|
|
77
|
-
|
|
78
|
-
this._syncDisplayedSwipeableItemCount();
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
_syncDisplayedSwipeableItemCount() {
|
|
@@ -89,24 +89,20 @@ export class SwipeableMixin {
|
|
|
89
89
|
if (!element) {
|
|
90
90
|
return;
|
|
91
91
|
}
|
|
92
|
+
setOrRemoveAttribute(element, 'data-item-count', itemCount);
|
|
92
93
|
context.displayedCount = itemCount;
|
|
93
|
-
if (itemCount === undefined) {
|
|
94
|
-
element.removeAttribute('data-item-count');
|
|
95
|
-
} else {
|
|
96
|
-
element.setAttribute('data-item-count', itemCount);
|
|
97
|
-
}
|
|
98
94
|
}
|
|
99
95
|
|
|
100
|
-
|
|
96
|
+
_syncDisplayedSwipeableItemIndex() {
|
|
101
97
|
const context = this._swipeableContext;
|
|
102
|
-
const
|
|
103
|
-
if (
|
|
98
|
+
const { itemIndex } = context;
|
|
99
|
+
if (itemIndex === context.displayedIndex) {
|
|
104
100
|
return;
|
|
105
101
|
}
|
|
106
|
-
context.displayedIndex =
|
|
102
|
+
context.displayedIndex = itemIndex;
|
|
107
103
|
|
|
108
|
-
this._syncSwipeableListIndex(
|
|
109
|
-
this._syncSwipeableIndicatorIndex(
|
|
104
|
+
this._syncSwipeableListIndex(itemIndex);
|
|
105
|
+
this._syncSwipeableIndicatorIndex(itemIndex);
|
|
110
106
|
}
|
|
111
107
|
|
|
112
108
|
_syncSwipeableListIndex(index) {
|
|
@@ -126,7 +122,7 @@ export class SwipeableMixin {
|
|
|
126
122
|
}
|
|
127
123
|
let i = 0;
|
|
128
124
|
for (const item of indicatorElement.children) {
|
|
129
|
-
item
|
|
125
|
+
addOrRemoveClass(item, 'active', i === index);
|
|
130
126
|
i++;
|
|
131
127
|
}
|
|
132
128
|
}
|
package/src/layout/raf.js
CHANGED
package/src/util/dom.js
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
export function setOrRemoveAttribute(element, name, value) {
|
|
2
|
+
if (value === undefined) {
|
|
3
|
+
element.removeAttribute(name);
|
|
4
|
+
} else {
|
|
5
|
+
element.setAttribute(name, value);
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function addOrRemoveClass(element, name, add) {
|
|
10
|
+
if (add) {
|
|
11
|
+
element.classList.add(name);
|
|
12
|
+
} else {
|
|
13
|
+
element.classList.remove(name);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function resolveCssLength(str) {
|
|
18
|
+
if (typeof str === 'number') {
|
|
19
|
+
return str;
|
|
20
|
+
}
|
|
21
|
+
const [value, unit] = parseLength(str);
|
|
22
|
+
switch (unit) {
|
|
23
|
+
case '':
|
|
24
|
+
case 'px':
|
|
25
|
+
return value;
|
|
26
|
+
case 'rem':
|
|
27
|
+
return remToPx(value);
|
|
28
|
+
default:
|
|
29
|
+
throw new Error(`Unsupported unit: ${unit}`);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function parseLength(str) {
|
|
34
|
+
const match = str.match(/^([+-]?(?:\d+|\d*\.\d+))([a-z]*)$/);
|
|
35
|
+
if (!match) {
|
|
36
|
+
throw new Error(`Invalid length: ${str}`);
|
|
37
|
+
}
|
|
38
|
+
const value = parseFloat(match[1]);
|
|
39
|
+
const unit = match[2] || '';
|
|
40
|
+
return [value, unit];
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function remToPx(value = 1) {
|
|
44
|
+
return value * parseFloat(getComputedStyle(document.documentElement).fontSize);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function cssAspectRatio(value) {
|
|
48
|
+
return (value === undefined || value instanceof CssAspectRatio) ? value : new CssAspectRatio(value);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
class CssAspectRatio {
|
|
52
|
+
|
|
53
|
+
constructor(value) {
|
|
54
|
+
this._width = NaN;
|
|
55
|
+
this._height = NaN;
|
|
56
|
+
switch (typeof value) {
|
|
57
|
+
case 'number':
|
|
58
|
+
this._width = value;
|
|
59
|
+
this._height = 1;
|
|
60
|
+
break;
|
|
61
|
+
case 'object':
|
|
62
|
+
if (Array.isArray(value)) {
|
|
63
|
+
this._width = parseFloat(value[0]);
|
|
64
|
+
this._height = parseFloat(value[1]);
|
|
65
|
+
}
|
|
66
|
+
break;
|
|
67
|
+
case 'string':
|
|
68
|
+
const i = value.indexOf('/');
|
|
69
|
+
if (i < 0) {
|
|
70
|
+
this._width = parseFloat(value);
|
|
71
|
+
this._height = 1;
|
|
72
|
+
} else {
|
|
73
|
+
this._width = parseFloat(value.slice(0, i).trim());
|
|
74
|
+
this._height = parseFloat(value.slice(i + 1).trim());
|
|
75
|
+
}
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
if (this._width === NaN || this._height === NaN) {
|
|
79
|
+
throw new Error(`Invalid aspect ratio value: ${value}`);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
get width() {
|
|
84
|
+
return this._width;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
get height() {
|
|
88
|
+
return this._height;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
get floatValue() {
|
|
92
|
+
return this._width / this._height;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
scaleBy(factor) {
|
|
96
|
+
factor = cssAspectRatio(factor);
|
|
97
|
+
return cssAspectRatio([factor._width * this._width, factor._height * this._height]);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
toString() {
|
|
101
|
+
return this._height === 1 ? `${this._width}` : `${this._width} / ${this._height}`;
|
|
102
|
+
}
|
|
103
|
+
}
|
package/src/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export default '1.11.5-beta.
|
|
1
|
+
export default '1.11.5-beta.2';
|
|
@@ -2,7 +2,7 @@ import { API } from '@miso.ai/commons';
|
|
|
2
2
|
import Workflow from './base.js';
|
|
3
3
|
import { fields, FeedbackActor } from '../actor/index.js';
|
|
4
4
|
import { ROLE, STATUS, ORGANIC_QUESTION_SOURCE } from '../constants.js';
|
|
5
|
-
import { SearchBoxLayout, TextLayout, ListLayout, CarouselLayout, TypewriterLayout, FeedbackLayout, AffiliationLayout } from '../layout/index.js';
|
|
5
|
+
import { SearchBoxLayout, TextLayout, ListLayout, CarouselLayout, GalleryLayout, TypewriterLayout, FeedbackLayout, AffiliationLayout } from '../layout/index.js';
|
|
6
6
|
import { processData as processAffiliationData } from '../affiliation/index.js';
|
|
7
7
|
import { mergeRolesOptions, DEFAULT_TRACKER_OPTIONS } from './options/index.js';
|
|
8
8
|
import { writeAnswerStageToMeta, mergeInteraction } from './processors.js';
|
|
@@ -35,7 +35,7 @@ const DEFAULT_LAYOUTS = Object.freeze({
|
|
|
35
35
|
[ROLE.QUESTION]: [TextLayout.type, { tag: 'h2' }],
|
|
36
36
|
[ROLE.ANSWER]: TypewriterLayout.type,
|
|
37
37
|
[ROLE.FEEDBACK]: FeedbackLayout.type,
|
|
38
|
-
[ROLE.IMAGES]: [
|
|
38
|
+
[ROLE.IMAGES]: [GalleryLayout.type, { incremental: true, itemType: 'image' }],
|
|
39
39
|
[ROLE.SOURCES]: [ListLayout.type, { incremental: true, itemType: 'article', templates: { ordered: true } }],
|
|
40
40
|
[ROLE.AFFILIATION]: [AffiliationLayout.type, { incremental: true, itemType: 'affiliation', link: { rel: 'noopener nofollow' } }],
|
|
41
41
|
});
|