@miso.ai/client-sdk-ui 1.10.0-beta.0 → 1.10.0-beta.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/actor/autocomplete.js +157 -0
- package/dist/cjs/actor/data.js +4 -12
- package/dist/cjs/actor/fields.js +8 -0
- package/dist/cjs/actor/index.js +7 -0
- package/dist/cjs/actor/tracker.js +46 -70
- package/dist/cjs/actor/trackers.js +5 -1
- package/dist/cjs/actor/utils.js +16 -2
- package/dist/cjs/actor/view.js +14 -3
- package/dist/cjs/actor/views.js +9 -1
- package/dist/cjs/affiliation/index.js +126 -0
- package/dist/cjs/combo/ask/options.js +1 -1
- package/dist/cjs/combo/base.js +1 -1
- package/dist/cjs/constants.js +6 -3
- package/dist/cjs/defaults/ask/controls.js +1 -1
- package/dist/cjs/defaults/ask/phrases.js +1 -1
- package/dist/cjs/defaults/ask/templates.js +35 -4
- package/dist/cjs/element/role/index.js +7 -0
- package/dist/cjs/element/role/miso-affiliation.js +20 -0
- package/dist/cjs/layout/affiliation/affiliation.js +330 -0
- package/dist/cjs/layout/banner/banner.js +1 -1
- package/dist/cjs/layout/container/container.js +1 -1
- package/dist/cjs/layout/error/error.js +1 -1
- package/dist/cjs/layout/index.js +7 -0
- package/dist/cjs/layout/input/option-list.js +35 -50
- package/dist/cjs/layout/input/search-box.js +227 -129
- package/dist/cjs/layout/list/cards.js +1 -1
- package/dist/cjs/layout/list/carousel.js +5 -3
- package/dist/cjs/layout/list/collection.js +44 -49
- package/dist/cjs/layout/list/list.js +1 -1
- package/dist/cjs/layout/radio/feedback.js +1 -1
- package/dist/cjs/layout/radio/radio.js +1 -1
- package/dist/cjs/layout/raf.js +1 -1
- package/dist/cjs/layout/template.js +1 -1
- package/dist/cjs/layout/templates.js +172 -66
- package/dist/cjs/layout/text/text.js +1 -1
- package/dist/cjs/layout/text/typewriter/index.js +3 -3
- package/dist/cjs/layout/trackable.js +124 -0
- package/dist/cjs/plugin.js +1 -1
- package/dist/cjs/source/index.js +20 -8
- package/dist/cjs/util/bindings.js +58 -110
- package/dist/cjs/util/states.js +31 -24
- package/dist/cjs/util/trackers.js +75 -0
- package/dist/cjs/util/viewables.js +55 -0
- package/dist/cjs/version.js +1 -1
- package/dist/cjs/workflow/ask.js +60 -19
- package/dist/cjs/workflow/asks.js +1 -1
- package/dist/cjs/workflow/base.js +6 -7
- package/dist/cjs/workflow/explore.js +5 -2
- package/dist/cjs/workflow/options.js +60 -14
- package/dist/cjs/workflow/recommendation.js +2 -0
- package/dist/cjs/workflow/search.js +35 -7
- package/package.json +2 -2
- package/src/actor/autocomplete.js +131 -0
- package/src/actor/data.js +3 -10
- package/src/actor/fields.js +8 -0
- package/src/actor/index.js +1 -0
- package/src/actor/tracker.js +39 -62
- package/src/actor/trackers.js +3 -1
- package/src/actor/utils.js +14 -2
- package/src/actor/view.js +12 -1
- package/src/actor/views.js +11 -0
- package/src/affiliation/index.js +108 -0
- package/src/constants.js +10 -1
- package/src/defaults/ask/phrases.js +1 -1
- package/src/defaults/ask/templates.js +34 -2
- package/src/element/role/index.js +1 -0
- package/src/element/role/miso-affiliation.js +16 -0
- package/src/layout/affiliation/affiliation.js +295 -0
- package/src/layout/index.js +1 -0
- package/src/layout/input/option-list.js +35 -43
- package/src/layout/input/search-box.js +192 -95
- package/src/layout/list/carousel.js +4 -2
- package/src/layout/list/collection.js +42 -43
- package/src/layout/templates.js +127 -46
- package/src/layout/text/typewriter/index.js +2 -2
- package/src/layout/trackable.js +106 -0
- package/src/source/index.js +14 -1
- package/src/util/bindings.js +47 -103
- package/src/util/states.js +26 -20
- package/src/util/trackers.js +69 -0
- package/src/util/viewables.js +47 -0
- package/src/version.js +1 -1
- package/src/workflow/ask.js +37 -3
- package/src/workflow/base.js +2 -3
- package/src/workflow/explore.js +1 -1
- package/src/workflow/options.js +54 -13
- package/src/workflow/recommendation.js +1 -0
- package/src/workflow/search.js +33 -1
- package/dist/cjs/util/tracker.js +0 -348
- package/src/util/tracker.js +0 -318
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
import { CarouselItemViewabilityObserver, requestAnimationFrame as raf } from '@miso.ai/commons';
|
|
2
|
+
import { STATUS, LAYOUT_CATEGORY, EVENT_TYPE } from '../../constants.js';
|
|
3
|
+
import CollectionLayout from '../list/collection.js';
|
|
4
|
+
import { affiliation } from '../templates.js';
|
|
5
|
+
|
|
6
|
+
const TYPE = 'affiliation';
|
|
7
|
+
const DEFAULT_CLASSNAME = 'miso-affiliation';
|
|
8
|
+
|
|
9
|
+
function root(layout, state) {
|
|
10
|
+
const { className, role, templates } = layout;
|
|
11
|
+
const { status } = state;
|
|
12
|
+
const roleAttr = role ? ` data-role="${role}"` : '';
|
|
13
|
+
const data = state.value || {};
|
|
14
|
+
const channelAttr = data.channel ? ` data-channel="${data.channel}"` : '';
|
|
15
|
+
return `<div class="${className} ${status}"${roleAttr}${channelAttr}>${status === STATUS.READY ? templates[status](layout, state) : ''}</div>`;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function ready(layout, state) {
|
|
19
|
+
const { templates } = layout;
|
|
20
|
+
const items = layout._getItems(state);
|
|
21
|
+
|
|
22
|
+
if (items && items.length > 0) {
|
|
23
|
+
return templates.control(layout, state, 'previous') + templates.body(layout, state) + templates.control(layout, state, 'next');
|
|
24
|
+
} else {
|
|
25
|
+
return templates.empty(layout, state);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function control(layout, state, direction) {
|
|
30
|
+
const { className } = layout;
|
|
31
|
+
return `<div class="${className}__control-${direction}" data-role="${direction}"></div>`;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function body(layout, state) {
|
|
35
|
+
const { className, templates } = layout;
|
|
36
|
+
const items = layout._getItems(state);
|
|
37
|
+
return `<div class="${className}__body">${templates.list(layout, state, items)}</div>`;
|
|
38
|
+
}
|
|
39
|
+
|
|
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
|
+
function item(layout, state, value, index) {
|
|
53
|
+
const { className, templates, options } = layout;
|
|
54
|
+
const { itemType } = options;
|
|
55
|
+
const header = templates.itemHeader(layout, state, value, { index });
|
|
56
|
+
const body = templates[itemType](layout, state, value, { index });
|
|
57
|
+
return `<li class="${className}__item">${header}${body}</li>`;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function itemHeader(layout, state, value, meta) {
|
|
61
|
+
const { className, templates } = layout;
|
|
62
|
+
let { headerText } = templates;
|
|
63
|
+
if (typeof headerText === 'function') {
|
|
64
|
+
headerText = headerText(layout, state, value, meta);
|
|
65
|
+
}
|
|
66
|
+
if (!headerText) {
|
|
67
|
+
return '';
|
|
68
|
+
}
|
|
69
|
+
return `<div class="${className}__item-header"><div class="${className}__item-header-tab">${headerText}</div></div>`;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const DEFAULT_TEMPLATES = Object.freeze({
|
|
73
|
+
root,
|
|
74
|
+
[STATUS.READY]: ready,
|
|
75
|
+
control,
|
|
76
|
+
body,
|
|
77
|
+
header,
|
|
78
|
+
item,
|
|
79
|
+
itemHeader,
|
|
80
|
+
affiliation,
|
|
81
|
+
ctaText: 'View',
|
|
82
|
+
headerText: 'Featured',
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
const INHERITED_DEFAULT_TEMPLATES = Object.freeze({
|
|
86
|
+
...CollectionLayout.defaultTemplates,
|
|
87
|
+
...DEFAULT_TEMPLATES,
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
function normalizeAutoplayOptions(options) {
|
|
91
|
+
if (options === true) {
|
|
92
|
+
options = { interval: 5000 };
|
|
93
|
+
} else if (typeof options === 'number') {
|
|
94
|
+
if (options <= 0) {
|
|
95
|
+
options = false;
|
|
96
|
+
} else {
|
|
97
|
+
options = { interval: Math.max(options, 500) };
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return options;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function autoplayOptionsEquals(a, b) {
|
|
104
|
+
if (a === b) {
|
|
105
|
+
return true;
|
|
106
|
+
}
|
|
107
|
+
if (!a || !b) {
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
return a.interval === b.interval;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export default class AffiliationLayout extends CollectionLayout {
|
|
114
|
+
|
|
115
|
+
static get category() {
|
|
116
|
+
return LAYOUT_CATEGORY.AFFILIATION;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
static get type() {
|
|
120
|
+
return TYPE;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
static get defaultTemplates() {
|
|
124
|
+
return INHERITED_DEFAULT_TEMPLATES;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
static get defaultClassName() {
|
|
128
|
+
return DEFAULT_CLASSNAME;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
constructor({ className = DEFAULT_CLASSNAME, templates, autoplay, ...options } = {}) {
|
|
132
|
+
super({ className, itemType: 'affiliation', templates: { ...DEFAULT_TEMPLATES, ...templates }, ...options });
|
|
133
|
+
this._itemCount = undefined;
|
|
134
|
+
this._itemIndex = 0;
|
|
135
|
+
this._displayedCount = undefined;
|
|
136
|
+
this._displayedIndex = undefined;
|
|
137
|
+
this._viewable = undefined;
|
|
138
|
+
this._autoplay = {};
|
|
139
|
+
|
|
140
|
+
this.autoplay(autoplay);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
initialize(view) {
|
|
144
|
+
super.initialize(view);
|
|
145
|
+
const { viewable: options } = this._view.trackerOptions || {};
|
|
146
|
+
this._viewable = new CarouselItemViewabilityObserver(this._onViewable.bind(this), options);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
autoplay(options = true) {
|
|
150
|
+
options = normalizeAutoplayOptions(options);
|
|
151
|
+
if (autoplayOptionsEquals(options, this._autoplay.options)) {
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
if (this._autoplay.options) {
|
|
155
|
+
clearInterval(this._autoplay.intervalId);
|
|
156
|
+
}
|
|
157
|
+
this._autoplay = { options };
|
|
158
|
+
// TODO: use slower transition speed for autoplay
|
|
159
|
+
// TODO: pause on hover
|
|
160
|
+
// TODO: cooldown after manual interaction
|
|
161
|
+
if (options) {
|
|
162
|
+
this._autoplay.intervalId = setInterval(() => this.next(), options.interval);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
get itemIndex() {
|
|
167
|
+
return this._itemIndex;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
set itemIndex(index) {
|
|
171
|
+
if (this._itemCount === undefined) {
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
if (index < 0) {
|
|
175
|
+
index = this._itemCount - 1;
|
|
176
|
+
} else if (index >= this._itemCount) {
|
|
177
|
+
index = 0;
|
|
178
|
+
}
|
|
179
|
+
this._itemIndex = index;
|
|
180
|
+
raf(() => this._syncItemIndex());
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
next() {
|
|
184
|
+
if (this._itemCount === undefined) {
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
this.itemIndex++;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
previous() {
|
|
191
|
+
if (this._itemCount === undefined) {
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
this.itemIndex--;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
_getItems(state) {
|
|
198
|
+
const { products } = state.value || {};
|
|
199
|
+
return products;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
_render(element, states, controls) {
|
|
203
|
+
super._render(element, states, controls);
|
|
204
|
+
|
|
205
|
+
// update item count, but raf to display as attribute
|
|
206
|
+
const items = this._getItems(states.state);
|
|
207
|
+
this._itemCount = items ? items.length : undefined;
|
|
208
|
+
|
|
209
|
+
raf(() => {
|
|
210
|
+
this._syncItemCount();
|
|
211
|
+
this._syncItemIndex();
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
_syncElement(element) {
|
|
216
|
+
const oldElement = this._element;
|
|
217
|
+
super._syncElement(element);
|
|
218
|
+
this._syncViewableElement(oldElement, element);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
_syncViewableElement(oldElement, newElement) {
|
|
222
|
+
if (oldElement === newElement) {
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
oldElement && this._viewable.unobserve(oldElement);
|
|
226
|
+
newElement && this._viewable.observe(newElement);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
_syncItemCount() {
|
|
230
|
+
const itemCount = this._itemCount;
|
|
231
|
+
if (itemCount === this._displayedCount) {
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
let { element } = this._view;
|
|
235
|
+
element = element.firstElementChild;
|
|
236
|
+
if (!element) {
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
this._displayedCount = itemCount;
|
|
240
|
+
if (itemCount === undefined) {
|
|
241
|
+
element.removeAttribute('data-item-count');
|
|
242
|
+
} else {
|
|
243
|
+
element.setAttribute('data-item-count', itemCount);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
_syncItemIndex() {
|
|
248
|
+
const index = this._itemIndex;
|
|
249
|
+
if (index === this._displayedIndex) {
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
const { element } = this._view;
|
|
253
|
+
const listElement = element && this._getListElement(element);
|
|
254
|
+
if (!listElement) {
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
this._displayedIndex = index;
|
|
258
|
+
listElement.style.left = `${-index * 100}%`;
|
|
259
|
+
this._viewable.display(index);
|
|
260
|
+
this._view._events.emit('display', { index });
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
_onViewable(index) {
|
|
264
|
+
const item = this._getRenderedItemData(index);
|
|
265
|
+
if (!item) {
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
this._view._track(EVENT_TYPE.VIEWABLE, [item]);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
_getRenderedItemData(index) {
|
|
272
|
+
const { value } = this._rendered.get(this._element) || {};
|
|
273
|
+
if (!value) {
|
|
274
|
+
return undefined;
|
|
275
|
+
}
|
|
276
|
+
const { products = [] } = value;
|
|
277
|
+
return products[index];
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
_trackViewables() {} // omit default behavior for we want to track by other means
|
|
281
|
+
|
|
282
|
+
_onClick(event) {
|
|
283
|
+
super._onClick(event);
|
|
284
|
+
const element = event.target;
|
|
285
|
+
if (element.closest(`[data-role="previous"]`)) {
|
|
286
|
+
this.previous();
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
289
|
+
if (element.closest(`[data-role="next"]`)) {
|
|
290
|
+
this.next();
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
}
|
package/src/layout/index.js
CHANGED
|
@@ -11,3 +11,4 @@ export { default as OptionListLayout } from './input/option-list.js';
|
|
|
11
11
|
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
|
+
export { default as AffiliationLayout } from './affiliation/affiliation.js';
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { escapeHtml } from '@miso.ai/commons';
|
|
2
2
|
import { LAYOUT_CATEGORY } from '../../constants.js';
|
|
3
3
|
import { fields } from '../../actor/index.js';
|
|
4
4
|
import TemplateBasedLayout from '../template.js';
|
|
5
|
-
|
|
6
|
-
const OPTION_VALUE = Symbol.for('miso.option-value');
|
|
5
|
+
import { makeTrackable } from '../trackable.js';
|
|
7
6
|
|
|
8
7
|
const TYPE = 'option-list';
|
|
9
8
|
const DEFAULT_CLASSNAME = 'miso-option-list';
|
|
@@ -64,11 +63,7 @@ export default class OptionListLayout extends TemplateBasedLayout {
|
|
|
64
63
|
templates: { ...DEFAULT_TEMPLATES, ...templates },
|
|
65
64
|
...options,
|
|
66
65
|
});
|
|
67
|
-
|
|
68
|
-
bindings: Object.freeze({
|
|
69
|
-
list: this._listBindings.bind(this),
|
|
70
|
-
}),
|
|
71
|
-
});
|
|
66
|
+
this._initTrackable();
|
|
72
67
|
}
|
|
73
68
|
|
|
74
69
|
initialize(view) {
|
|
@@ -89,59 +84,48 @@ export default class OptionListLayout extends TemplateBasedLayout {
|
|
|
89
84
|
|
|
90
85
|
_render(element, data, controls) {
|
|
91
86
|
super._render(element, data, controls);
|
|
92
|
-
|
|
87
|
+
const { state } = data;
|
|
88
|
+
this._syncBindings(element, state);
|
|
89
|
+
this._syncOptionValues(element, state);
|
|
93
90
|
}
|
|
94
91
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
92
|
+
_unrender() {
|
|
93
|
+
this._clearBindings();
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
_syncOptionValues(element, state) {
|
|
97
|
+
const optionsElement = element && this._getOptionsElement(element);
|
|
100
98
|
if (!optionsElement) {
|
|
101
99
|
return;
|
|
102
100
|
}
|
|
103
|
-
const optionValues = state
|
|
101
|
+
const optionValues = this._getItems(state) || [];
|
|
104
102
|
optionsElement.classList[optionValues.length === 0 ? 'add' : 'remove']('empty');
|
|
105
|
-
let i = 0;
|
|
106
|
-
for (const optionElement of this._listOptionElements(optionsElement)) {
|
|
107
|
-
optionElement[OPTION_VALUE] = optionValues[i++];
|
|
108
|
-
}
|
|
109
103
|
}
|
|
110
104
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
return [];
|
|
114
|
-
}
|
|
115
|
-
const optionsElement = this._getOptionsElement(rootElement);
|
|
116
|
-
const bindings = [];
|
|
117
|
-
for (const element of this._listOptionElements(optionsElement)) {
|
|
118
|
-
const value = element[OPTION_VALUE];
|
|
119
|
-
if (!value) {
|
|
120
|
-
continue;
|
|
121
|
-
}
|
|
122
|
-
const key = value.text || value;
|
|
123
|
-
bindings.push({ key, value, element });
|
|
124
|
-
}
|
|
125
|
-
return bindings;
|
|
105
|
+
_getItems(state) {
|
|
106
|
+
return state.value;
|
|
126
107
|
}
|
|
127
108
|
|
|
128
109
|
_getOptionsElement(element) {
|
|
129
110
|
return element.querySelector(`[data-role="options"]`);
|
|
130
111
|
}
|
|
131
112
|
|
|
132
|
-
|
|
133
|
-
return
|
|
113
|
+
_getItemElements(element) {
|
|
114
|
+
return element ? Array.from(element.querySelectorAll(`[data-role="option"]`)) : [];
|
|
134
115
|
}
|
|
135
116
|
|
|
136
|
-
_handleClick(
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
117
|
+
_handleClick(event) {
|
|
118
|
+
const element = event.target.closest(`[data-role="option"]`);
|
|
119
|
+
if (!element) {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
const binding = this._bindings.get(element);
|
|
123
|
+
const option = binding && binding.value;
|
|
124
|
+
if (!option) {
|
|
143
125
|
return;
|
|
144
126
|
}
|
|
127
|
+
this._trackClick(event, binding);
|
|
128
|
+
this._submit(option.text);
|
|
145
129
|
}
|
|
146
130
|
|
|
147
131
|
async _submit(value) {
|
|
@@ -152,4 +136,12 @@ export default class OptionListLayout extends TemplateBasedLayout {
|
|
|
152
136
|
this._view.hub.trigger(fields.query(), { q: value });
|
|
153
137
|
}
|
|
154
138
|
|
|
139
|
+
destroy() {
|
|
140
|
+
this._destroyTrackable();
|
|
141
|
+
this._view = undefined;
|
|
142
|
+
super.destroy();
|
|
143
|
+
}
|
|
144
|
+
|
|
155
145
|
}
|
|
146
|
+
|
|
147
|
+
makeTrackable(OptionListLayout.prototype);
|