neo.mjs 6.3.11 → 6.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/apps/ServiceWorker.mjs +2 -2
  2. package/examples/ConfigurationViewport.mjs +21 -9
  3. package/examples/ServiceWorker.mjs +2 -2
  4. package/examples/container/dialog/MainContainerController.mjs +20 -16
  5. package/examples/dialog/DemoDialog.mjs +24 -3
  6. package/examples/form/field/select/MainContainer.mjs +28 -6
  7. package/package.json +1 -1
  8. package/resources/scss/src/component/Base.scss +26 -0
  9. package/resources/scss/src/form/field/Picker.scss +0 -3
  10. package/resources/scss/src/menu/List.scss +4 -8
  11. package/resources/scss/theme-dark/menu/List.scss +2 -1
  12. package/resources/scss/theme-light/menu/List.scss +1 -0
  13. package/src/DefaultConfig.mjs +2 -2
  14. package/src/button/Base.mjs +41 -6
  15. package/src/component/Base.mjs +236 -44
  16. package/src/container/Dialog.mjs +3 -3
  17. package/src/core/Base.mjs +20 -0
  18. package/src/form/Container.mjs +2 -0
  19. package/src/form/field/Picker.mjs +30 -47
  20. package/src/form/field/Time.mjs +8 -8
  21. package/src/form/field/trigger/Base.mjs +1 -1
  22. package/src/form/field/trigger/CopyToClipboard.mjs +5 -1
  23. package/src/grid/View.mjs +5 -2
  24. package/src/grid/header/Button.mjs +10 -10
  25. package/src/list/Base.mjs +17 -14
  26. package/src/list/plugin/Animate.mjs +3 -3
  27. package/src/main/DomAccess.mjs +272 -28
  28. package/src/menu/List.mjs +35 -90
  29. package/src/table/Container.mjs +2 -2
  30. package/src/table/header/Button.mjs +21 -23
  31. package/src/tree/Accordion.mjs +1 -1
  32. package/src/util/Array.mjs +4 -18
  33. package/src/util/Css.mjs +6 -8
  34. package/src/util/HashHistory.mjs +10 -3
  35. package/src/util/Rectangle.mjs +444 -7
  36. package/test/siesta/siesta-node.js +2 -1
  37. package/test/siesta/siesta.js +1 -0
  38. package/test/siesta/tests/Rectangle.mjs +409 -0
@@ -1,6 +1,24 @@
1
1
  import Base from '../core/Base.mjs';
2
2
  import DeltaUpdates from './mixin/DeltaUpdates.mjs';
3
3
  import Observable from '../core/Observable.mjs';
4
+ import Rectangle from '../util/Rectangle.mjs';
5
+
6
+ const
7
+ lengthRE = /^\d+\w+$/,
8
+ fontSizeProps = [
9
+ 'font-size',
10
+ 'font-size-adjust',
11
+ 'font-style',
12
+ 'font-weight',
13
+ 'font-family',
14
+ 'font-kerning',
15
+ 'font-stretch',
16
+ 'line-height',
17
+ 'text-transform',
18
+ 'text-decoration',
19
+ 'letter-spacing',
20
+ 'word-break'
21
+ ];
4
22
 
5
23
  /**
6
24
  * @class Neo.main.DomAccess
@@ -44,12 +62,14 @@ class DomAccess extends Base {
44
62
  remote: {
45
63
  app: [
46
64
  'addScript',
65
+ 'align',
47
66
  'applyBodyCls',
48
67
  'blur',
49
68
  'execCommand',
50
69
  'focus',
51
70
  'getAttributes',
52
71
  'getBoundingClientRect',
72
+ 'measure',
53
73
  'scrollBy',
54
74
  'scrollIntoView',
55
75
  'scrollTo',
@@ -82,10 +102,13 @@ class DomAccess extends Base {
82
102
  construct(config) {
83
103
  super.construct(config);
84
104
 
85
- let me = this,
86
- node;
105
+ const
106
+ me = this,
107
+ syncAligns = me.syncAligns.bind(me);
87
108
 
88
109
  if (Neo.config.renderCountDeltas) {
110
+ let node;
111
+
89
112
  setInterval(() => {
90
113
  node = document.getElementById('neo-delta-updates');
91
114
 
@@ -94,8 +117,58 @@ class DomAccess extends Base {
94
117
  }
95
118
 
96
119
  me.countDeltasPer250ms = 0;
97
- }, 250);
120
+ }, 250)
98
121
  }
122
+
123
+ // Set up our aligning callback which is called when things change which may
124
+ // mean that alignments need to be updated.
125
+ me.syncAligns = () => requestAnimationFrame(syncAligns);
126
+ }
127
+
128
+ /**
129
+ * @param {Object} alignSpec
130
+ */
131
+ addAligned(alignSpec) {
132
+ const
133
+ me = this,
134
+ { id } = alignSpec,
135
+ aligns = me._aligns || (me._aligns = new Map()),
136
+ resizeObserver = me._alignResizeObserver || (me._alignResizeObserver = new ResizeObserver(me.syncAligns)),
137
+ { constrainToElement } = alignSpec;
138
+
139
+ // Set up listeners which monitor for changes
140
+ if (!aligns.has(id)) {
141
+ // Realign when target's layout-controlling element changes size
142
+ resizeObserver.observe(alignSpec.offsetParent);
143
+
144
+ // Realign when align to target changes size
145
+ resizeObserver.observe(alignSpec.targetElement);
146
+
147
+ // Realign when constraining element changes size
148
+ if (constrainToElement) {
149
+ resizeObserver.observe(constrainToElement);
150
+ }
151
+ }
152
+
153
+ if (!me.hasDocumentScrollListener) {
154
+ document.addEventListener('scroll', me.syncAligns, {
155
+ capture: true,
156
+ passive: true
157
+ });
158
+
159
+ me.hasDocumentScrollListener = true;
160
+ }
161
+
162
+ if (!me.documentMutationObserver) {
163
+ me.documentMutationObserver = new MutationObserver(me.onDocumentMutation.bind(me));
164
+
165
+ me.documentMutationObserver.observe(document.body, {
166
+ childList: true,
167
+ subtree : true
168
+ })
169
+ }
170
+
171
+ aligns.set(id, alignSpec)
99
172
  }
100
173
 
101
174
  /**
@@ -116,6 +189,58 @@ class DomAccess extends Base {
116
189
  document.head.appendChild(script);
117
190
  }
118
191
 
192
+ /**
193
+ * @param {Object} data
194
+ * @returns {Promise<void>}
195
+ */
196
+ async align(data) {
197
+ const
198
+ me = this,
199
+ { constrainTo } = data,
200
+ subject = data.subject = me.getElement(data.id),
201
+ { style } = subject,
202
+ align = {...data},
203
+ lastAlign = me._aligns?.get(data.id);
204
+
205
+ if (lastAlign) {
206
+ subject.classList.remove(`neo-aligned-${lastAlign.result.position}`);
207
+ }
208
+
209
+ // Release any constrainTo or matchSize sizing which may have been imposed
210
+ // by a previous align call.
211
+ me.resetDimensions(align);
212
+
213
+ // The Rectangle's align spec target and constrainTo must be Rectangles
214
+ align.target = me.getBoundingClientRect({ id : data.targetElement = me.getElementOrBody(data.target) });
215
+ data.offsetParent = data.targetElement.offsetParent
216
+ if (constrainTo) {
217
+ align.constrainTo = me.getBoundingClientRect({ id : data.constrainToElement = me.getElementOrBody(constrainTo) });
218
+ }
219
+
220
+ // Get an aligned clone of myRect aligned according to the align object
221
+ const
222
+ myRect = me.getBoundingClientRect(data),
223
+ result = data.result = myRect.alignTo(align);
224
+
225
+ Object.assign(style, {
226
+ top : 0,
227
+ left : 0,
228
+ transform : `translate(${result.x}px,${result.y}px)`
229
+ });
230
+ if (result.width !== myRect.width) {
231
+ style.width = `${result.width}px`;
232
+ }
233
+ if (result.height !== myRect.height) {
234
+ style.height = `${result.height}px`;
235
+ }
236
+
237
+ // Place box shadow at correct edge
238
+ subject.classList.add(`neo-aligned-${result.position}`);
239
+
240
+ // Register an alignment to be kept in sync
241
+ me.addAligned(data);
242
+ }
243
+
119
244
  /**
120
245
  * @param {Object} data
121
246
  * @param {String[]} data.cls
@@ -170,7 +295,7 @@ class DomAccess extends Base {
170
295
  * @param {Object} data
171
296
  * @param {Array|String} data.id either an id or an array of ids
172
297
  * @param {Array|String} data.attributes either an attribute or an array of attributes
173
- * @returns {Array|Object} In case id is an array, an array of atrrbute objects is returned, otherwise an object
298
+ * @returns {Array|Object} In case id is an array, an array of attribute objects is returned, otherwise an object
174
299
  */
175
300
  getAttributes(data) {
176
301
  let returnData;
@@ -220,54 +345,73 @@ class DomAccess extends Base {
220
345
  });
221
346
  } else {
222
347
  let node = this.getElementOrBody(data.id),
223
- rect = {};
348
+ rect = {}, style, minWidth, minHeight;
224
349
 
225
350
  returnData = {};
226
351
 
227
352
  if (node) {
228
- rect = node.getBoundingClientRect();
353
+ rect = node.getBoundingClientRect();
354
+ style = node.ownerDocument.defaultView.getComputedStyle(node);
355
+ minWidth = style.getPropertyValue('min-width'),
356
+ minHeight = style.getPropertyValue('min-height');
229
357
 
230
358
  // DomRect does not support spreading => {...DomRect} => {}
231
- Object.assign(returnData, {
232
- bottom: rect.bottom,
233
- height: rect.height,
234
- left : rect.left,
235
- right : rect.right,
236
- top : rect.top,
237
- width : rect.width,
238
- x : rect.x,
239
- y : rect.y
240
- });
359
+ returnData = Rectangle.clone(rect);
360
+
361
+ // Measure minWidth/minHeight in other units like em/rem etc
362
+ // Note that 0px is what the DOM reports if no minWidth is specified
363
+ // so we do not report a minimum in these cases.
364
+ if (lengthRE.test(minWidth) && minWidth !== '0px') {
365
+ returnData.minWidth = this.measure({ value : minWidth, id : node});
366
+ }
367
+ if (lengthRE.test(minHeight) && minHeight !== '0px') {
368
+ returnData.minHeight = this.measure({ value : minHeight, id : node });
369
+ }
241
370
  }
242
371
  }
243
372
 
244
373
  return returnData;
245
374
  }
246
375
 
376
+ onDocumentMutation(mutations) {
377
+ const me = this;
378
+
379
+ // If the mutations are purely align subjects being added or removed, take no action.
380
+ if (!mutations.every(({ type, addedNodes, removedNodes }) => {
381
+ if (type === 'childList') {
382
+ const nodes = [...Array.from(addedNodes), ...Array.from(removedNodes)];
383
+
384
+ return nodes.every(a => me.isAlignSubject(a))
385
+ }
386
+ })) {
387
+ me.syncAligns();
388
+ }
389
+ }
390
+
247
391
  /**
248
- * @param {String} nodeId
392
+ * @param {String|HTMLElement} nodeId
249
393
  * @returns {HTMLElement}
250
394
  * @protected
251
395
  */
252
396
  getElement(nodeId) {
253
- if (Neo.config.useDomIds) {
254
- return document.getElementById(nodeId);
255
- }
256
-
257
- return document.querySelector(`[data-neo-id='${nodeId}']`);
397
+ return nodeId.nodeType ? nodeId : Neo.config.useDomIds ? document.getElementById(nodeId) : document.querySelector(`[data-neo-id='${nodeId}']`);
258
398
  }
259
399
 
260
400
  /**
261
- * @param {String} [nodeId='document.body']
401
+ * @param {String|HTMLElement} [nodeId='document.body']
262
402
  * @returns {HTMLElement}
263
403
  * @protected
264
404
  */
265
405
  getElementOrBody(nodeId='document.body') {
266
- if (nodeId === 'body' || nodeId === 'document.body') {
267
- return document.body;
268
- }
406
+ return nodeId.nodeType ? nodeId : (nodeId === 'body' || nodeId === 'document.body') ? document.body : this.getElement(nodeId);
407
+ }
269
408
 
270
- return this.getElement(nodeId);
409
+ /**
410
+ * @param {HTMLElement} el
411
+ * @returns {Boolean}
412
+ */
413
+ isAlignSubject(el) {
414
+ return [...this._aligns?.values()].some(align => align.subject === el);
271
415
  }
272
416
 
273
417
  /**
@@ -313,7 +457,53 @@ class DomAccess extends Base {
313
457
  });
314
458
 
315
459
  document.head.appendChild(link);
316
- });
460
+ })
461
+ }
462
+
463
+ /**
464
+ * @param {Object} data
465
+ * @param {String} data.id
466
+ * @param {Number|String} data.value
467
+ * @returns {Number|String}
468
+ */
469
+ measure({ value, id }) {
470
+ const node = id.nodeType === 1 ? id : this.getElement(id);
471
+
472
+ if (value.endsWith('%')) {
473
+ const fraction = parseFloat(value) / 100;
474
+
475
+ return (node.offsetParent?.getBoundingClientRect().height || 0) * fraction;
476
+ }
477
+ // If it's any other CSS unit than px, it needs to be measured using the DOM
478
+ else if (isNaN(value) && !value.endsWith('px')) {
479
+ const elStyle = node.ownerDocument.defaultView.getComputedStyle(node);
480
+
481
+ let d = this._measuringDiv;
482
+
483
+ if (!d) {
484
+ d = this._measuringDiv = document.createElement('div');
485
+ d.style = 'position:fixed;top:-10000px;left:-10000px';
486
+ }
487
+ // In case a DOM update cleared it out
488
+ document.body.appendChild(d);
489
+
490
+ // Set all the font-size, font-weight etc style properties so that
491
+ // em/ex/rem etc units will match
492
+ fontSizeProps.forEach(prop => {
493
+ d.style[prop] = elStyle[prop];
494
+ });
495
+ d.className = node.className;
496
+ d.style.width = value;
497
+
498
+ // Read back the resulting computed pixel width
499
+ value = elStyle.width;
500
+
501
+ }
502
+ // If it's a number, or ends with px, use the numeric value.
503
+ else {
504
+ value = parseFloat(value);
505
+ }
506
+ return value;
317
507
  }
318
508
 
319
509
  /**
@@ -419,6 +609,24 @@ class DomAccess extends Base {
419
609
  }
420
610
  }
421
611
 
612
+ /**
613
+ * Resets any DOM sizing configs to the last externally configured value.
614
+ *
615
+ * This is used during aligning to release any constraints applied by a previous alignment.
616
+ * @protected
617
+ */
618
+ async resetDimensions(align) {
619
+ const { style } = this.getElement(align.id);
620
+
621
+ style.flex = align.configuredFlex;
622
+ style.width = align.configuredWidth;
623
+ style.height = align.configuredHeight;
624
+ style.minWidth = align.configuredMinWidth;
625
+ style.minHeight = align.configuredMinHeight;
626
+ style.maxWidth = align.configuredMaxWidth;
627
+ style.maxHeight = align.configuredMaxHeight;
628
+ }
629
+
422
630
  /**
423
631
  * @param {Object} data
424
632
  * @param {String} data.direction left, top
@@ -555,6 +763,42 @@ class DomAccess extends Base {
555
763
  return {id: data.id};
556
764
  }
557
765
 
766
+ /**
767
+ *
768
+ */
769
+ syncAligns() {
770
+ const
771
+ me = this,
772
+ { _aligns } = me;
773
+
774
+ // Keep all registered aligns aligned on any detected change
775
+ _aligns?.forEach(align => {
776
+ // Align subject and target still in the DOM - correct its alignment
777
+ if (document.contains(align.subject) && document.contains(align.targetElement)) {
778
+ me.align(align);
779
+ }
780
+ // Align subject or target no longer in the DOM - remove it.
781
+ else {
782
+ const
783
+ { _alignResizeObserver } = me,
784
+ { constrainToElement } = align;
785
+
786
+ // Stop observing the align elements
787
+ _alignResizeObserver.unobserve(align.subject);
788
+ _alignResizeObserver.unobserve(align.offsetParent);
789
+ _alignResizeObserver.unobserve(align.targetElement);
790
+ if (constrainToElement) {
791
+ _alignResizeObserver.unobserve(constrainToElement);
792
+ }
793
+
794
+ // Clear the last aligned class.
795
+ align.subject.classList.remove(`neo-aligned-${align.result?.position}`);
796
+
797
+ _aligns.delete(align.id);
798
+ }
799
+ })
800
+ }
801
+
558
802
  /**
559
803
  * @param {Object} data
560
804
  * @param {String} [data.behavior='smooth'] // auto or smooth
package/src/menu/List.mjs CHANGED
@@ -1,6 +1,5 @@
1
1
  import BaseList from '../list/Base.mjs';
2
2
  import ListModel from '../selection/menu/ListModel.mjs';
3
- import NeoArray from '../util/Array.mjs';
4
3
  import Store from './Store.mjs';
5
4
 
6
5
  /**
@@ -28,11 +27,6 @@ class List extends BaseList {
28
27
  * @member {String[]} baseCls=['neo-menu-list','neo-list']
29
28
  */
30
29
  baseCls: ['neo-menu-list', 'neo-list'],
31
- /**
32
- * True will add 'neo-floating' to the instance cls list.
33
- * @member {Boolean} floating_=false
34
- */
35
- floating_: false,
36
30
  /**
37
31
  * setTimeout() id after a focus-leave event.
38
32
  * @member {Number|null} focusTimeoutId=null
@@ -115,19 +109,6 @@ class List extends BaseList {
115
109
  */
116
110
  parentComponent = null
117
111
 
118
- /**
119
- * Triggered after the floating config got changed
120
- * @param {Object[]} value
121
- * @param {Object[]} oldValue
122
- * @protected
123
- */
124
- afterSetFloating(value, oldValue) {
125
- let cls = this.cls;
126
-
127
- NeoArray[value ? 'add' : 'remove'](cls, 'neo-floating');
128
- this.cls = cls
129
- }
130
-
131
112
  /**
132
113
  * Triggered after the items config got changed
133
114
  * @param {Object[]} value
@@ -168,40 +149,17 @@ class List extends BaseList {
168
149
  }
169
150
 
170
151
  /**
171
- * Triggered after the mounted config got changed
172
- * @param {Boolean} value
173
- * @param {Boolean} oldValue
152
+ * Triggered after the theme config got changed
153
+ * @param {String|null} value
154
+ * @param {String|null} oldValue
174
155
  * @protected
175
156
  */
176
- afterSetMounted(value, oldValue) {
177
- super.afterSetMounted(value, oldValue);
178
-
179
- let me = this,
180
- id = me.id,
181
- parentId = me.parentComponent?.id;
157
+ afterSetTheme(value, oldValue) {
158
+ super.afterSetTheme(value, oldValue);
182
159
 
183
- if (parentId) {
184
- if (value) {
185
- Neo.main.addon.ScrollSync.register({
186
- sourceId: parentId,
187
- targetId: id
188
- });
189
-
190
- !me.parentMenu && me.getDomRect([id, parentId]).then(rects => {
191
- let style = me.style || {};
192
-
193
- style.left = `${rects[1].right - rects[0].width}px`;
194
- style.top = `${rects[1].bottom + 1}px`;
195
-
196
- me.style = style
197
- })
198
- } else if (oldValue !== undefined) {
199
- Neo.main.addon.ScrollSync.unregister({
200
- sourceId: parentId,
201
- targetId: id
202
- })
203
- }
204
- }
160
+ Object.values(this.subMenuMap || {}).forEach(menu => {
161
+ menu.theme = value
162
+ })
205
163
  }
206
164
 
207
165
  /**
@@ -243,9 +201,7 @@ class List extends BaseList {
243
201
  destroy(...args) {
244
202
  let me = this,
245
203
  activeSubMenu = me.activeSubMenu,
246
- subMenuMap = me.subMenuMap;
247
-
248
- me.store.destroy();
204
+ subMenuMap = me.subMenuMap || {};
249
205
 
250
206
  activeSubMenu?.unmount();
251
207
 
@@ -401,48 +357,37 @@ class List extends BaseList {
401
357
  * @param {Object} record
402
358
  */
403
359
  showSubMenu(nodeId, record) {
404
- let me = this,
360
+ const
361
+ me = this,
405
362
  store = me.store,
406
363
  recordId = record[store.keyProperty],
407
- subMenuMap = me.subMenuMap || {},
364
+ subMenuMap = me.subMenuMap || (me.subMenuMap = {}),
408
365
  subMenuMapId = me.getMenuMapId(recordId),
409
- subMenu = subMenuMap[subMenuMapId],
410
- menuStyle, style;
411
-
412
- me.getDomRect(nodeId).then(rect => {
413
- style = {
414
- left: `${rect.right + me.subMenuGap}px`,
415
- top : `${rect.top - 1}px` // minus the border
416
- };
417
-
418
- if (subMenu) {
419
- menuStyle = subMenu.style;
420
-
421
- Object.assign(menuStyle, style);
422
-
423
- subMenu.setSilent({style: menuStyle})
424
- } else {
425
- subMenuMap[subMenuMapId] = subMenu = Neo.create({
426
- module : List,
427
- appName : me.appName,
428
- displayField : me.displayField,
429
- floating : true,
430
- items : record.items,
431
- isRoot : false,
432
- parentComponent: me.parentComponent,
433
- parentId : Neo.apps[me.appName].mainView.id,
434
- parentIndex : store.indexOf(record),
435
- parentMenu : me,
436
- style,
437
- zIndex : me.zIndex + 1
438
- })
439
- }
440
-
366
+ subMenu = subMenuMap[subMenuMapId] || (subMenuMap[subMenuMapId] = Neo.create({
367
+ align : {
368
+ target : nodeId,
369
+ edgeAlign : 'l0-r0',
370
+ axisLock : true,
371
+ targetMargin : me.subMenuGap
372
+ },
373
+ module : List,
374
+ appName : me.appName,
375
+ displayField : me.displayField,
376
+ floating : true,
377
+ items : record.items,
378
+ isRoot : false,
379
+ parentComponent: me.parentComponent,
380
+ parentId : Neo.apps[me.appName].mainView.id,
381
+ parentIndex : store.indexOf(record),
382
+ parentMenu : me,
383
+ theme : me.theme,
384
+ zIndex : me.zIndex + 1
385
+ }));
386
+
387
+ if (me.activeSubMenu !== subMenu) {
441
388
  me.activeSubMenu = subMenu;
442
- me.subMenuMap = subMenuMap;
443
-
444
389
  subMenu.render(true)
445
- });
390
+ }
446
391
  }
447
392
 
448
393
  /**
@@ -1,6 +1,6 @@
1
1
  import BaseContainer from '../container/Base.mjs';
2
2
  import ClassSystemUtil from '../util/ClassSystem.mjs';
3
- import Css from '../util/Css.mjs';
3
+ import CssUtil from '../util/Css.mjs';
4
4
  import NeoArray from '../util/Array.mjs';
5
5
  import RowModel from '../selection/table/RowModel.mjs';
6
6
  import Store from '../data/Store.mjs';
@@ -207,7 +207,7 @@ class Container extends BaseContainer {
207
207
  cssRules.push('#' + id + '::-webkit-scrollbar-track:horizontal {margin-right: ' + me.dockRightMargin + 'px;}');
208
208
  }
209
209
  if (cssRules.length > 0) {
210
- Css.insertRules(cssRules);
210
+ CssUtil.insertRules(me.appName, cssRules);
211
211
  }
212
212
 
213
213
  me.scrollbarsCssApplied = true;
@@ -9,11 +9,11 @@ import TextField from '../../form/field/Text.mjs';
9
9
  class Button extends BaseButton {
10
10
  /**
11
11
  * Valid values for align
12
- * @member {String[]} alignValues: ['left','center','right']
12
+ * @member {String[]} cellAlignValues: ['left','center','right']
13
13
  * @protected
14
14
  * @static
15
15
  */
16
- static alignValues = ['left', 'center', 'right']
16
+ static cellAlignValues = ['left', 'center', 'right']
17
17
 
18
18
  static config = {
19
19
  /**
@@ -26,15 +26,15 @@ class Button extends BaseButton {
26
26
  * @protected
27
27
  */
28
28
  ntype: 'table-header-button',
29
- /**
30
- * Alignment of the matching table cells. Valid values are left, center, right
31
- * @member {String} align_='left'
32
- */
33
- align_: 'left',
34
29
  /**
35
30
  * @member {String[]} baseCls=['neo-table-header-button']
36
31
  */
37
32
  baseCls: ['neo-table-header-button'],
33
+ /**
34
+ * Alignment of the matching table cells. Valid values are left, center, right
35
+ * @member {String} cellAlign_='left'
36
+ */
37
+ cellAlign_: 'left',
38
38
  /**
39
39
  * @member {String|null} dataField=null
40
40
  */
@@ -111,19 +111,17 @@ class Button extends BaseButton {
111
111
  construct(config) {
112
112
  super.construct(config);
113
113
 
114
- let me = this;
115
-
116
- if (me.draggable) {
117
- me.addDomListeners({
118
- dragend : me.onDragEnd,
119
- dragenter: me.onDragEnter,
120
- dragleave: me.onDragLeave,
121
- dragover : me.onDragOver,
122
- dragstart: me.onDragStart,
123
- drop : me.onDrop,
124
- scope : me
125
- });
126
- }
114
+ let me = this;
115
+
116
+ me.draggable && me.addDomListeners({
117
+ dragend : me.onDragEnd,
118
+ dragenter: me.onDragEnter,
119
+ dragleave: me.onDragLeave,
120
+ dragover : me.onDragOver,
121
+ dragstart: me.onDragStart,
122
+ drop : me.onDrop,
123
+ scope : me
124
+ })
127
125
  }
128
126
 
129
127
  /**
@@ -255,13 +253,13 @@ class Button extends BaseButton {
255
253
  }
256
254
 
257
255
  /**
258
- * Triggered before the align config gets changed
256
+ * Triggered before the cellAlign config gets changed
259
257
  * @param {String} value
260
258
  * @param {String} oldValue
261
259
  * @protected
262
260
  */
263
- beforeSetAlign(value, oldValue) {
264
- return this.beforeSetEnumValue(value, oldValue, 'align', 'alignValues');
261
+ beforeSetCellAlign(value, oldValue) {
262
+ return this.beforeSetEnumValue(value, oldValue, 'cellAlign', 'cellAlignValues');
265
263
  }
266
264
 
267
265
  /**
@@ -266,7 +266,7 @@ class AccordionTree extends TreeList {
266
266
  cn : [{
267
267
  flag : 'iconCls',
268
268
  tag : 'span',
269
- cls : ['neo-accordion-item-icon', item[me.fields.icon]],
269
+ cls : itemIconCls,
270
270
  id : id + '__icon',
271
271
  removeDom: (!item.isLeaf || !me.showIcon)
272
272
  }, {