@miso.ai/client-sdk-ui 1.11.0-beta.1 → 1.11.0-beta.11
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/actor/data.js +6 -7
- package/dist/cjs/actor/feedback.js +6 -39
- package/dist/cjs/actor/fields.js +14 -6
- package/dist/cjs/actor/hub.js +1 -2
- package/dist/cjs/actor/index.js +0 -7
- package/dist/cjs/actor/interactions.js +4 -15
- package/dist/cjs/actor/sessions.js +2 -33
- package/dist/cjs/actor/tracker.js +25 -26
- package/dist/cjs/actor/utils.js +0 -49
- package/dist/cjs/actor/view.js +40 -40
- package/dist/cjs/actor/views.js +32 -8
- package/dist/cjs/asset/svgs.js +18 -8
- package/dist/cjs/constants.js +18 -19
- package/dist/cjs/defaults/hybrid-search/answer-box.js +19 -3
- package/dist/cjs/defaults/hybrid-search/phrases.js +5 -5
- package/dist/cjs/defaults/hybrid-search/templates.js +37 -9
- package/dist/cjs/element/role/index.js +12 -5
- package/dist/cjs/element/role/{miso-hits.js → miso-more.js} +4 -4
- package/dist/cjs/element/role/miso-total.js +20 -0
- package/dist/cjs/layout/affiliation/affiliation.js +0 -3
- package/dist/cjs/layout/banner/banner.js +0 -4
- package/dist/cjs/layout/button/more-button.js +73 -0
- package/dist/cjs/layout/container/container.js +0 -3
- package/dist/cjs/layout/error/error.js +0 -4
- package/dist/cjs/layout/index.js +7 -0
- package/dist/cjs/layout/input/facets.js +5 -5
- package/dist/cjs/layout/input/option-list.js +0 -4
- package/dist/cjs/layout/input/search-box.js +35 -17
- package/dist/cjs/layout/list/cards.js +0 -3
- package/dist/cjs/layout/list/carousel.js +0 -3
- package/dist/cjs/layout/list/collection.js +22 -7
- package/dist/cjs/layout/list/list.js +0 -3
- package/dist/cjs/layout/radio/feedback.js +0 -3
- package/dist/cjs/layout/radio/radio.js +0 -4
- package/dist/cjs/layout/raf.js +4 -2
- package/dist/cjs/layout/text/text.js +0 -4
- package/dist/cjs/layout/text/typewriter/index.js +0 -3
- package/dist/cjs/layout/triggerable.js +79 -0
- package/dist/cjs/util/states.js +0 -15
- package/dist/cjs/version.js +1 -1
- package/dist/cjs/workflow/answer-based.js +109 -111
- package/dist/cjs/workflow/ask.js +35 -27
- package/dist/cjs/workflow/asks.js +1 -1
- package/dist/cjs/workflow/autocompletable.js +33 -0
- package/dist/cjs/workflow/autocomplete.js +122 -0
- package/dist/cjs/workflow/base.js +169 -102
- package/dist/cjs/workflow/explore.js +26 -19
- package/dist/cjs/workflow/hybrid-search-answer.js +99 -0
- package/dist/cjs/workflow/hybrid-search-results.js +66 -0
- package/dist/cjs/workflow/hybrid-search-views.js +122 -0
- package/dist/cjs/workflow/hybrid-search.js +98 -103
- package/dist/cjs/workflow/options.js +32 -17
- package/dist/cjs/workflow/processors.js +191 -17
- package/dist/cjs/workflow/recommendation.js +36 -49
- package/dist/cjs/workflow/search-based.js +228 -0
- package/dist/cjs/workflow/search.js +21 -68
- package/package.json +2 -2
- package/src/actor/data.js +2 -4
- package/src/actor/feedback.js +6 -23
- package/src/actor/fields.js +14 -6
- package/src/actor/hub.js +1 -2
- package/src/actor/index.js +0 -1
- package/src/actor/interactions.js +4 -10
- package/src/actor/sessions.js +3 -30
- package/src/actor/tracker.js +25 -19
- package/src/actor/utils.js +0 -47
- package/src/actor/view.js +27 -15
- package/src/actor/views.js +36 -8
- package/src/asset/svgs.js +19 -7
- package/src/constants.js +25 -16
- package/src/defaults/hybrid-search/answer-box.js +17 -5
- package/src/defaults/hybrid-search/phrases.js +4 -4
- package/src/defaults/hybrid-search/templates.js +25 -9
- package/src/element/role/index.js +2 -1
- package/src/element/role/{miso-hits.js → miso-more.js} +3 -3
- package/src/element/role/miso-total.js +16 -0
- package/src/layout/affiliation/affiliation.js +1 -5
- package/src/layout/banner/banner.js +0 -5
- package/src/layout/button/more-button.js +69 -0
- package/src/layout/container/container.js +1 -5
- package/src/layout/error/error.js +0 -5
- package/src/layout/index.js +2 -1
- package/src/layout/input/facets.js +5 -6
- package/src/layout/input/option-list.js +0 -5
- package/src/layout/input/search-box.js +29 -19
- package/src/layout/list/cards.js +0 -4
- package/src/layout/list/carousel.js +0 -4
- package/src/layout/list/collection.js +21 -9
- package/src/layout/list/list.js +0 -4
- package/src/layout/radio/feedback.js +0 -4
- package/src/layout/radio/radio.js +0 -5
- package/src/layout/raf.js +2 -2
- package/src/layout/text/text.js +0 -5
- package/src/layout/text/typewriter/index.js +1 -5
- package/src/layout/trackable.js +1 -1
- package/src/layout/triggerable.js +76 -0
- package/src/util/states.js +0 -14
- package/src/version.js +1 -1
- package/src/workflow/answer-based.js +101 -77
- package/src/workflow/ask.js +33 -25
- package/src/workflow/asks.js +1 -1
- package/src/workflow/autocompletable.js +29 -0
- package/src/workflow/autocomplete.js +113 -0
- package/src/workflow/base.js +147 -93
- package/src/workflow/explore.js +23 -8
- package/src/workflow/hybrid-search-answer.js +92 -0
- package/src/workflow/hybrid-search-results.js +62 -0
- package/src/workflow/hybrid-search-views.js +124 -0
- package/src/workflow/hybrid-search.js +102 -73
- package/src/workflow/options.js +26 -11
- package/src/workflow/processors.js +169 -14
- package/src/workflow/recommendation.js +32 -33
- package/src/workflow/search-based.js +222 -0
- package/src/workflow/search.js +21 -65
- package/dist/cjs/actor/autocomplete.js +0 -160
- package/dist/cjs/workflow/utils.js +0 -42
- package/src/actor/autocomplete.js +0 -133
- package/src/workflow/utils.js +0 -29
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ROLE, STATUS
|
|
1
|
+
import { ROLE, STATUS } from '../../constants.js';
|
|
2
2
|
import RafLayout from '../raf.js';
|
|
3
3
|
import MisoBannerElement from '../../element/miso-banner.js';
|
|
4
4
|
import Viewables from '../../util/viewables.js';
|
|
@@ -7,10 +7,6 @@ const TYPE = 'container';
|
|
|
7
7
|
|
|
8
8
|
export default class ContainerLayout extends RafLayout {
|
|
9
9
|
|
|
10
|
-
static get category() {
|
|
11
|
-
return LAYOUT_CATEGORY.CONTAINER;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
10
|
static get type() {
|
|
15
11
|
return TYPE;
|
|
16
12
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { LAYOUT_CATEGORY } from '../../constants.js';
|
|
2
1
|
import TemplateBasedLayout from '../template.js';
|
|
3
2
|
|
|
4
3
|
const TYPE = 'error';
|
|
@@ -24,10 +23,6 @@ const DEFAULT_TEMPLATES = Object.freeze({
|
|
|
24
23
|
|
|
25
24
|
export default class ErrorLayout extends TemplateBasedLayout {
|
|
26
25
|
|
|
27
|
-
static get category() {
|
|
28
|
-
return LAYOUT_CATEGORY.ERROR;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
26
|
static get type() {
|
|
32
27
|
return TYPE;
|
|
33
28
|
}
|
package/src/layout/index.js
CHANGED
|
@@ -12,4 +12,5 @@ export { default as FeedbackLayout } from './radio/feedback.js';
|
|
|
12
12
|
export { default as TextLayout } from './text/text.js';
|
|
13
13
|
export { default as TypewriterLayout } from './text/typewriter/index.js';
|
|
14
14
|
export { default as AffiliationLayout } from './affiliation/affiliation.js';
|
|
15
|
-
export { default as FacetsLayout } from './input/facets.js';
|
|
15
|
+
export { default as FacetsLayout } from './input/facets.js';
|
|
16
|
+
export { default as MoreButtonLayout } from './button/more-button.js';
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { escapeHtml } from '@miso.ai/commons';
|
|
2
|
-
import { LAYOUT_CATEGORY } from '../../constants.js';
|
|
3
2
|
import TemplateBasedLayout from '../template.js';
|
|
4
3
|
import Bindings from '../../util/bindings.js';
|
|
5
4
|
|
|
@@ -88,10 +87,6 @@ function getSelectedValues(facets) {
|
|
|
88
87
|
|
|
89
88
|
export default class FacetsLayout extends TemplateBasedLayout {
|
|
90
89
|
|
|
91
|
-
static get category() {
|
|
92
|
-
return LAYOUT_CATEGORY.FILTERS;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
90
|
static get type() {
|
|
96
91
|
return TYPE;
|
|
97
92
|
}
|
|
@@ -125,11 +120,11 @@ export default class FacetsLayout extends TemplateBasedLayout {
|
|
|
125
120
|
|
|
126
121
|
_render(element, data, controls) {
|
|
127
122
|
super._render(element, data, controls);
|
|
128
|
-
this._syncSelections();
|
|
129
123
|
}
|
|
130
124
|
|
|
131
125
|
_afterRender(element, state) {
|
|
132
126
|
this._syncBindings(element, state);
|
|
127
|
+
this._syncSelections();
|
|
133
128
|
}
|
|
134
129
|
|
|
135
130
|
_unrender() {
|
|
@@ -220,6 +215,10 @@ export default class FacetsLayout extends TemplateBasedLayout {
|
|
|
220
215
|
}
|
|
221
216
|
|
|
222
217
|
_handleClick(event) {
|
|
218
|
+
// only left click
|
|
219
|
+
if (event.button !== 0) {
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
223
222
|
const element = event.target.closest(`[data-role="option"]`);
|
|
224
223
|
if (!element) {
|
|
225
224
|
return;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { escapeHtml } from '@miso.ai/commons';
|
|
2
|
-
import { LAYOUT_CATEGORY } from '../../constants.js';
|
|
3
2
|
import { fields } from '../../actor/index.js';
|
|
4
3
|
import TemplateBasedLayout from '../template.js';
|
|
5
4
|
import { makeTrackable } from '../trackable.js';
|
|
@@ -41,10 +40,6 @@ const DEFAULT_TEMPLATES = Object.freeze({
|
|
|
41
40
|
|
|
42
41
|
export default class OptionListLayout extends TemplateBasedLayout {
|
|
43
42
|
|
|
44
|
-
static get category() {
|
|
45
|
-
return LAYOUT_CATEGORY.QUERY;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
43
|
static get type() {
|
|
49
44
|
return TYPE;
|
|
50
45
|
}
|
|
@@ -1,29 +1,39 @@
|
|
|
1
1
|
import { defineValues, escapeHtml, findInAncestors, debounce } from '@miso.ai/commons';
|
|
2
|
-
import {
|
|
2
|
+
import { STATUS, EVENT_TYPE } from '../../constants.js';
|
|
3
3
|
import { fields } from '../../actor/index.js';
|
|
4
4
|
import TemplateBasedLayout from '../template.js';
|
|
5
5
|
import { imageBlock, productInfoBlock } from '../templates.js';
|
|
6
|
-
import {
|
|
6
|
+
import { getIcon } from '../../asset/svgs.js';
|
|
7
7
|
|
|
8
8
|
const TYPE = 'search-box';
|
|
9
9
|
const DEFAULT_CLASSNAME = 'miso-search-box';
|
|
10
10
|
const DEFAULT_AUTOCOMPLETE_CLASSNAME = 'miso-autocomplete';
|
|
11
11
|
|
|
12
12
|
function root(layout) {
|
|
13
|
-
const { className, role, options,
|
|
14
|
-
const { placeholder
|
|
13
|
+
const { className, templates, role, options, autocomplete } = layout;
|
|
14
|
+
const { placeholder } = options;
|
|
15
15
|
const roleAttr = role ? `data-role="${role}"` : '';
|
|
16
|
-
const buttonContent = buttonText || workflow === 'search' ? SEARCH : SEND;
|
|
17
16
|
return `
|
|
18
17
|
<div class="${className}" ${roleAttr}>
|
|
19
18
|
<div class="${className}__input-group">
|
|
20
19
|
<input class="${className}__input" type="text" data-role="input" ${placeholder ? `placeholder="${placeholder}"` : ''}>
|
|
21
|
-
<button class="${className}__button" type="submit" data-role="submit">${buttonContent}</button>
|
|
20
|
+
<button class="${className}__button" type="submit" data-role="submit">${templates.buttonContent(layout)}</button>
|
|
22
21
|
</div>
|
|
23
22
|
<div class="${autocomplete.className}" data-role="autocomplete"></div>
|
|
24
23
|
</div>`.trim();
|
|
25
24
|
}
|
|
26
25
|
|
|
26
|
+
function buttonContent(layout) {
|
|
27
|
+
const { templates, options } = layout;
|
|
28
|
+
if (options.buttonText) {
|
|
29
|
+
return options.buttonText; // legacy
|
|
30
|
+
}
|
|
31
|
+
const { buttonText, buttonIcon } = templates;
|
|
32
|
+
const text = typeof buttonText === 'function' ? buttonText(layout) : `${buttonText}`;
|
|
33
|
+
const icon = typeof buttonIcon === 'function' ? buttonIcon(layout) : (getIcon(buttonIcon) || `${buttonIcon}`);
|
|
34
|
+
return text + icon;
|
|
35
|
+
}
|
|
36
|
+
|
|
27
37
|
function completions(layout, items) {
|
|
28
38
|
const { templates, workflow, autocomplete } = layout;
|
|
29
39
|
// use options under layout.autocomplete from now on
|
|
@@ -68,10 +78,7 @@ function product(layout, { product }) {
|
|
|
68
78
|
|
|
69
79
|
function completionList(layout, type, items) {
|
|
70
80
|
const { className, templates } = layout;
|
|
71
|
-
return
|
|
72
|
-
<ul class="${className}__${type}-list" data-role="${type}-list">
|
|
73
|
-
${items.map(item => templates.completionItem(layout, type, item)).join('')}
|
|
74
|
-
</ul>`.trim();
|
|
81
|
+
return `<ul class="${className}__${type}-list" data-role="${type}-list">${items.map(item => templates.completionItem(layout, type, item)).join('')}</ul>`;
|
|
75
82
|
}
|
|
76
83
|
|
|
77
84
|
function completionItem(layout, type, item) {
|
|
@@ -84,6 +91,9 @@ function completionItem(layout, type, item) {
|
|
|
84
91
|
|
|
85
92
|
const DEFAULT_TEMPLATES = Object.freeze({
|
|
86
93
|
root,
|
|
94
|
+
buttonContent,
|
|
95
|
+
buttonText: '',
|
|
96
|
+
buttonIcon: 'search',
|
|
87
97
|
completions,
|
|
88
98
|
completionList,
|
|
89
99
|
completionItem,
|
|
@@ -102,10 +112,6 @@ const DEFAULT_AUTOCOMPLETE_OPTIONS = Object.freeze({
|
|
|
102
112
|
|
|
103
113
|
export default class SearchBoxLayout extends TemplateBasedLayout {
|
|
104
114
|
|
|
105
|
-
static get category() {
|
|
106
|
-
return LAYOUT_CATEGORY.QUERY;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
115
|
static get type() {
|
|
110
116
|
return TYPE;
|
|
111
117
|
}
|
|
@@ -141,7 +147,7 @@ export default class SearchBoxLayout extends TemplateBasedLayout {
|
|
|
141
147
|
proxyElement.on('click', (e) => this._handleClick(e)),
|
|
142
148
|
proxyElement.on('focusin', (e) => this._handleFocusIn(e)),
|
|
143
149
|
proxyElement.on('focusout', (e) => this._handleFocusOut(e)),
|
|
144
|
-
hub.on(fields.
|
|
150
|
+
hub.on(fields.completions(), () => view.refresh({ force: true })),
|
|
145
151
|
];
|
|
146
152
|
}
|
|
147
153
|
|
|
@@ -175,7 +181,7 @@ export default class SearchBoxLayout extends TemplateBasedLayout {
|
|
|
175
181
|
state = super._preprocess({ state });
|
|
176
182
|
return {
|
|
177
183
|
...state,
|
|
178
|
-
completions: this._view.hub.states[fields.
|
|
184
|
+
completions: this._view.hub.states[fields.completions()],
|
|
179
185
|
};
|
|
180
186
|
}
|
|
181
187
|
|
|
@@ -185,6 +191,9 @@ export default class SearchBoxLayout extends TemplateBasedLayout {
|
|
|
185
191
|
super._render(element, data, controls);
|
|
186
192
|
}
|
|
187
193
|
this._updateCompletions(element, data, controls);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
_afterRender(element, state) {
|
|
188
197
|
this._fullfillFocusRequest(element);
|
|
189
198
|
this._fullfillValueRequest(element);
|
|
190
199
|
}
|
|
@@ -193,7 +202,8 @@ export default class SearchBoxLayout extends TemplateBasedLayout {
|
|
|
193
202
|
if (!state.completions) {
|
|
194
203
|
return;
|
|
195
204
|
}
|
|
196
|
-
const { status = STATUS.INITIAL,
|
|
205
|
+
const { status = STATUS.INITIAL, session, value: completions } = state.completions;
|
|
206
|
+
const { index } = session;
|
|
197
207
|
if (rendered && rendered.completions.index === index && rendered.completions.status === status) {
|
|
198
208
|
return;
|
|
199
209
|
}
|
|
@@ -276,7 +286,7 @@ export default class SearchBoxLayout extends TemplateBasedLayout {
|
|
|
276
286
|
}
|
|
277
287
|
|
|
278
288
|
_handleKeyDown({ key, target, isComposing }) {
|
|
279
|
-
if (!isComposing && key === 'Enter' && target.matches('input')) {
|
|
289
|
+
if (!isComposing && key === 'Enter' && target.matches('[data-role="input"]')) {
|
|
280
290
|
this._submit(target.value);
|
|
281
291
|
target.blur();
|
|
282
292
|
}
|
|
@@ -332,7 +342,7 @@ export default class SearchBoxLayout extends TemplateBasedLayout {
|
|
|
332
342
|
if (!options) {
|
|
333
343
|
return;
|
|
334
344
|
}
|
|
335
|
-
this._view.tracker.submit(value);
|
|
345
|
+
this._view.tracker.submit({ value }); // not array
|
|
336
346
|
}
|
|
337
347
|
|
|
338
348
|
}
|
package/src/layout/list/cards.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import { STATUS
|
|
1
|
+
import { STATUS } from '../../constants.js';
|
|
2
2
|
import TemplateBasedLayout from '../template.js';
|
|
3
3
|
import { makeTrackable } from '../trackable.js';
|
|
4
|
+
import { makeTriggerable } from '../triggerable.js';
|
|
4
5
|
import { product, article, question, productInfoBlock, articleInfoBlock, titleBlock, brandBlock, descriptionBlock, dateBlock, priceBlock, discountRateText, ctaBlock, cta, imageBlock, indexBlock } from '../templates.js';
|
|
5
6
|
|
|
6
7
|
function root(layout, state) {
|
|
7
8
|
const { className, role, templates } = layout;
|
|
8
9
|
const { status } = state;
|
|
9
10
|
const roleAttr = role ? `data-role="${role}"` : '';
|
|
10
|
-
return `<div class="${className} ${status}" ${roleAttr}>${status === STATUS.READY ? templates[status](layout, state) : ''}</div>`;
|
|
11
|
+
return `<div class="${className} ${status}" ${roleAttr}>${status === STATUS.READY ? templates[status](layout, state) : ''}${templates.trigger(layout, state)}${templates.loading(layout, state)}</div>`;
|
|
11
12
|
}
|
|
12
13
|
|
|
13
14
|
function ready(layout, state) {
|
|
@@ -15,7 +16,7 @@ function ready(layout, state) {
|
|
|
15
16
|
const values = layout._getItems(state);
|
|
16
17
|
|
|
17
18
|
// TODO: handle categories, attributes, etc. by introducing sublayout
|
|
18
|
-
if ((values && values.length > 0) || state.ongoing) {
|
|
19
|
+
if ((values && values.length > 0) || state.ongoing) { // TODO: ad-hoc ongoing?
|
|
19
20
|
return templates.list(layout, state, values);
|
|
20
21
|
} else {
|
|
21
22
|
return templates.empty(layout, state);
|
|
@@ -42,6 +43,15 @@ function item(layout, state, value, index) {
|
|
|
42
43
|
return `<li class="${className}__item">${body}</li>`;
|
|
43
44
|
}
|
|
44
45
|
|
|
46
|
+
function trigger(layout, state) {
|
|
47
|
+
const { className } = layout;
|
|
48
|
+
return `<div class="${className}__trigger" data-role="trigger"></div>`;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function loading() {
|
|
52
|
+
return `<div class="miso-loading" aria-label="Loading" data-role="loading"></div>`;
|
|
53
|
+
}
|
|
54
|
+
|
|
45
55
|
// TODO: let templates.js control what to be included here
|
|
46
56
|
|
|
47
57
|
const DEFAULT_TEMPLATES = Object.freeze({
|
|
@@ -67,14 +77,12 @@ const DEFAULT_TEMPLATES = Object.freeze({
|
|
|
67
77
|
cta,
|
|
68
78
|
imageBlock,
|
|
69
79
|
indexBlock,
|
|
80
|
+
trigger,
|
|
81
|
+
loading,
|
|
70
82
|
});
|
|
71
83
|
|
|
72
84
|
export default class CollectionLayout extends TemplateBasedLayout {
|
|
73
85
|
|
|
74
|
-
static get category() {
|
|
75
|
-
return LAYOUT_CATEGORY.LIST;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
86
|
static get defaultTemplates() {
|
|
79
87
|
return DEFAULT_TEMPLATES;
|
|
80
88
|
}
|
|
@@ -86,6 +94,7 @@ export default class CollectionLayout extends TemplateBasedLayout {
|
|
|
86
94
|
...options,
|
|
87
95
|
});
|
|
88
96
|
this._initTrackable();
|
|
97
|
+
this._initTriggerable();
|
|
89
98
|
}
|
|
90
99
|
|
|
91
100
|
initialize(view) {
|
|
@@ -106,8 +115,7 @@ export default class CollectionLayout extends TemplateBasedLayout {
|
|
|
106
115
|
// TODO: compare item ids as well
|
|
107
116
|
return this.options.incremental &&
|
|
108
117
|
rendered && rendered.value && rendered.value.length > 0 &&
|
|
109
|
-
|
|
110
|
-
rendered.status === STATUS.READY &&
|
|
118
|
+
state.value && state.value.length >= rendered.value.length &&
|
|
111
119
|
state.session && rendered.session &&
|
|
112
120
|
state.session.id === rendered.session.id;
|
|
113
121
|
}
|
|
@@ -138,10 +146,12 @@ export default class CollectionLayout extends TemplateBasedLayout {
|
|
|
138
146
|
|
|
139
147
|
_afterRender(element, state) {
|
|
140
148
|
this._syncBindings(element, state);
|
|
149
|
+
this._syncTrigger(element, state);
|
|
141
150
|
}
|
|
142
151
|
|
|
143
152
|
_unrender() {
|
|
144
153
|
this._clearBindings();
|
|
154
|
+
this._untrackTrigger();
|
|
145
155
|
}
|
|
146
156
|
|
|
147
157
|
_getItems(state) {
|
|
@@ -177,6 +187,7 @@ export default class CollectionLayout extends TemplateBasedLayout {
|
|
|
177
187
|
|
|
178
188
|
destroy() {
|
|
179
189
|
this._destroyTrackable();
|
|
190
|
+
this._destroyTriggerable();
|
|
180
191
|
this._view = undefined;
|
|
181
192
|
super.destroy();
|
|
182
193
|
}
|
|
@@ -184,3 +195,4 @@ export default class CollectionLayout extends TemplateBasedLayout {
|
|
|
184
195
|
}
|
|
185
196
|
|
|
186
197
|
makeTrackable(CollectionLayout.prototype);
|
|
198
|
+
makeTriggerable(CollectionLayout.prototype);
|
package/src/layout/list/list.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { findInAncestors, requestAnimationFrame as raf } from '@miso.ai/commons';
|
|
2
|
-
import { LAYOUT_CATEGORY } from '../../constants.js';
|
|
3
2
|
import TemplateBasedLayout from '../template.js';
|
|
4
3
|
import { requiresImplementation } from '../templates.js';
|
|
5
4
|
|
|
@@ -30,10 +29,6 @@ const DEFAULT_TEMPLATES = Object.freeze({
|
|
|
30
29
|
|
|
31
30
|
export default class RadioLayout extends TemplateBasedLayout {
|
|
32
31
|
|
|
33
|
-
static get category() {
|
|
34
|
-
return LAYOUT_CATEGORY.RADIO;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
32
|
static get defaultTemplates() {
|
|
38
33
|
return DEFAULT_TEMPLATES;
|
|
39
34
|
}
|
package/src/layout/raf.js
CHANGED
|
@@ -2,8 +2,8 @@ import { defineValues, requestAnimationFrame as raf, capture } from '@miso.ai/co
|
|
|
2
2
|
|
|
3
3
|
export default class RafLayout {
|
|
4
4
|
|
|
5
|
-
constructor({ role, workflow, ...options } = {}) {
|
|
6
|
-
defineValues(this, { role, workflow, options });
|
|
5
|
+
constructor({ role, workflow, workflowOptions, ...options } = {}) {
|
|
6
|
+
defineValues(this, { role, workflow, workflowOptions, options });
|
|
7
7
|
this._unsubscribes = [];
|
|
8
8
|
this._rendered = new WeakMap();
|
|
9
9
|
this._element = undefined;
|
package/src/layout/text/text.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { escapeHtml } from '@miso.ai/commons';
|
|
2
|
-
import { LAYOUT_CATEGORY } from '../../constants.js';
|
|
3
2
|
import TemplateBasedLayout from '../template.js';
|
|
4
3
|
|
|
5
4
|
const TYPE = 'text';
|
|
@@ -42,10 +41,6 @@ const DEFAULT_TEMPLATES = Object.freeze({
|
|
|
42
41
|
|
|
43
42
|
export default class TextLayout extends TemplateBasedLayout {
|
|
44
43
|
|
|
45
|
-
static get category() {
|
|
46
|
-
return LAYOUT_CATEGORY.TEXT;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
44
|
static get type() {
|
|
50
45
|
return TYPE;
|
|
51
46
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { trimObj, defineValues, Resolution, pacer } from '@miso.ai/commons';
|
|
2
|
-
import {
|
|
2
|
+
import { STATUS } from '../../../constants.js';
|
|
3
3
|
import ProgressiveLayout from '../../progressive.js';
|
|
4
4
|
import PlaintextRenderer from './plaintext.js';
|
|
5
5
|
import { containerElement, cursorClassName, fromSameSession, normalizeOnDebug } from './utils.js';
|
|
@@ -9,10 +9,6 @@ const DEFAULT_CLASSNAME = 'miso-typewriter';
|
|
|
9
9
|
|
|
10
10
|
export default class TypewriterLayout extends ProgressiveLayout {
|
|
11
11
|
|
|
12
|
-
static get category() {
|
|
13
|
-
return LAYOUT_CATEGORY.TEXT;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
12
|
static get type() {
|
|
17
13
|
return TYPE;
|
|
18
14
|
}
|
package/src/layout/trackable.js
CHANGED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { mixin, viewable as whenViewable } from '@miso.ai/commons';
|
|
2
|
+
import { STATUS } from '../constants.js';
|
|
3
|
+
import { fields } from '../actor/index.js';
|
|
4
|
+
|
|
5
|
+
export function makeTriggerable(prototype) {
|
|
6
|
+
mixin(prototype, TriggerableMixin.prototype);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export class TriggerableMixin {
|
|
10
|
+
|
|
11
|
+
_initTriggerable() {
|
|
12
|
+
this._trigger = undefined;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
_syncTrigger(element, state) {
|
|
16
|
+
if (!this.options.infiniteScroll) {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
const workflowPaginationOptions = this.workflowOptions.pagination;
|
|
20
|
+
if (!workflowPaginationOptions.active || workflowPaginationOptions.mode !== 'infiniteScroll') {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
// only track trigger when ready
|
|
24
|
+
if (state.status === STATUS.READY) {
|
|
25
|
+
this._trackTrigger(element);
|
|
26
|
+
} else {
|
|
27
|
+
this._untrackTrigger();
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
async _trackTrigger(element) {
|
|
32
|
+
if (this._trigger) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
const triggerElement = element.querySelector('[data-role="trigger"]');
|
|
36
|
+
if (!triggerElement) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
const ac = new AbortController();
|
|
40
|
+
this._trigger = Object.freeze({
|
|
41
|
+
element: triggerElement,
|
|
42
|
+
ac,
|
|
43
|
+
});
|
|
44
|
+
let result = false;
|
|
45
|
+
try {
|
|
46
|
+
await whenViewable(triggerElement, { area: 1, duration: 0, signal: ac.signal });
|
|
47
|
+
result = true;
|
|
48
|
+
} catch (e) {
|
|
49
|
+
if (e.name !== 'AbortError') {
|
|
50
|
+
throw e;
|
|
51
|
+
}
|
|
52
|
+
} finally {
|
|
53
|
+
this._trigger = undefined;
|
|
54
|
+
}
|
|
55
|
+
if (result) {
|
|
56
|
+
this._onTrigger();
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
_onTrigger() {
|
|
61
|
+
this._view.hub.trigger(fields.more());
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
_untrackTrigger() {
|
|
65
|
+
if (!this._trigger) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
this._trigger.ac && this._trigger.ac.abort();
|
|
69
|
+
this._trigger = undefined;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
_destroyTriggerable() {
|
|
73
|
+
this._untrackTrigger();
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
}
|
package/src/util/states.js
CHANGED
|
@@ -4,20 +4,6 @@ import { EVENT_TYPE, TRACKING_STATUS, validateEventType, validateTrackingStatus
|
|
|
4
4
|
const { IMPRESSION, VIEWABLE, CLICK } = EVENT_TYPE;
|
|
5
5
|
const { UNTRACKED, TRIGGERED } = TRACKING_STATUS;
|
|
6
6
|
|
|
7
|
-
/*
|
|
8
|
-
const STATES = {
|
|
9
|
-
NEW: Object.freeze({
|
|
10
|
-
[IMPRESSION]: UNTRACKED,
|
|
11
|
-
[VIEWABLE]: UNTRACKED,
|
|
12
|
-
}),
|
|
13
|
-
UNTRACKED: Object.freeze({
|
|
14
|
-
[IMPRESSION]: UNTRACKED,
|
|
15
|
-
[VIEWABLE]: UNTRACKED,
|
|
16
|
-
[CLICK]: UNTRACKED,
|
|
17
|
-
}),
|
|
18
|
-
};
|
|
19
|
-
*/
|
|
20
|
-
|
|
21
7
|
const UNTRACKED_STATES = Object.freeze({
|
|
22
8
|
[IMPRESSION]: UNTRACKED,
|
|
23
9
|
[VIEWABLE]: UNTRACKED,
|
package/src/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export default '1.11.0-beta.
|
|
1
|
+
export default '1.11.0-beta.11';
|