neo.mjs 4.2.6 → 4.3.0

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 (63) hide show
  1. package/apps/realworld/view/HomeComponent.mjs +3 -6
  2. package/apps/realworld/view/article/CommentComponent.mjs +3 -6
  3. package/apps/realworld/view/article/Component.mjs +4 -7
  4. package/apps/realworld/view/article/CreateCommentComponent.mjs +3 -6
  5. package/apps/realworld/view/article/CreateComponent.mjs +3 -6
  6. package/apps/realworld/view/article/PreviewComponent.mjs +2 -5
  7. package/apps/realworld/view/article/TagListComponent.mjs +2 -5
  8. package/apps/realworld/view/user/ProfileComponent.mjs +3 -6
  9. package/apps/realworld/view/user/SettingsComponent.mjs +3 -6
  10. package/apps/realworld/view/user/SignUpComponent.mjs +2 -5
  11. package/apps/realworld2/view/article/PreviewComponent.mjs +2 -5
  12. package/apps/realworld2/view/article/TagListComponent.mjs +2 -5
  13. package/examples/ConfigurationViewport.mjs +1 -1
  14. package/examples/button/base/MainContainer.mjs +80 -19
  15. package/examples/tab/container/MainContainer.mjs +3 -3
  16. package/examples/todoList/version1/MainComponent.mjs +3 -6
  17. package/package.json +2 -2
  18. package/resources/scss/src/button/Base.scss +59 -0
  19. package/resources/scss/src/tab/Container.scss +1 -3
  20. package/resources/scss/src/tab/header/Button.scss +6 -1
  21. package/resources/scss/src/table/header/Button.scss +21 -1
  22. package/resources/scss/theme-dark/button/Base.scss +7 -1
  23. package/resources/scss/theme-dark/table/header/Button.scss +11 -9
  24. package/resources/scss/theme-light/button/Base.scss +7 -1
  25. package/resources/scss/theme-light/table/header/Button.scss +11 -9
  26. package/src/button/Base.mjs +186 -23
  27. package/src/calendar/view/YearComponent.mjs +3 -6
  28. package/src/calendar/view/month/Component.mjs +3 -6
  29. package/src/calendar/view/week/Component.mjs +3 -6
  30. package/src/calendar/view/week/plugin/DragDrop.mjs +6 -9
  31. package/src/component/Base.mjs +17 -1
  32. package/src/component/Carousel.mjs +5 -17
  33. package/src/component/Chip.mjs +2 -7
  34. package/src/component/Circle.mjs +4 -7
  35. package/src/component/DateSelector.mjs +5 -8
  36. package/src/component/Gallery.mjs +4 -7
  37. package/src/component/Helix.mjs +2 -5
  38. package/src/component/Splitter.mjs +3 -6
  39. package/src/component/mwc/Button.mjs +4 -7
  40. package/src/component/mwc/TextField.mjs +2 -5
  41. package/src/draggable/DropZone.mjs +3 -7
  42. package/src/draggable/list/DragZone.mjs +6 -9
  43. package/src/draggable/toolbar/DragZone.mjs +5 -8
  44. package/src/form/Fieldset.mjs +3 -6
  45. package/src/form/field/CheckBox.mjs +2 -5
  46. package/src/form/field/Range.mjs +3 -6
  47. package/src/form/field/Text.mjs +2 -5
  48. package/src/form/field/trigger/Base.mjs +4 -12
  49. package/src/grid/header/Button.mjs +3 -6
  50. package/src/list/Base.mjs +4 -6
  51. package/src/plugin/Resizable.mjs +3 -6
  52. package/src/selection/grid/CellModel.mjs +3 -6
  53. package/src/selection/grid/ColumnModel.mjs +3 -6
  54. package/src/selection/grid/RowModel.mjs +3 -6
  55. package/src/selection/table/CellModel.mjs +3 -6
  56. package/src/selection/table/ColumnModel.mjs +3 -6
  57. package/src/selection/table/RowModel.mjs +3 -6
  58. package/src/sitemap/Component.mjs +3 -6
  59. package/src/tab/header/Button.mjs +13 -2
  60. package/src/table/header/Button.mjs +9 -5
  61. package/src/tooltip/Base.mjs +5 -15
  62. package/src/util/KeyNavigation.mjs +8 -13
  63. package/src/worker/App.mjs +3 -3
@@ -6,6 +6,8 @@ $neoMap: map-merge($neoMap, (
6
6
  'button-background-image' : linear-gradient(#434749, #323536),
7
7
  'button-background-gradient-end' : #323536,
8
8
  'button-background-gradient-start': #434749,
9
+ 'button-badge-background-color' : #64b5f6,
10
+ 'button-badge-color' : #282828,
9
11
  'button-border' : 1px solid #2b2b2b,
10
12
  'button-border-radius' : 0,
11
13
  'button-glyph-color' : #bbb,
@@ -15,6 +17,7 @@ $neoMap: map-merge($neoMap, (
15
17
  'button-margin' : 2px,
16
18
  'button-padding' : 5px 12px 5px 12px,
17
19
  'button-pressed-border-color' : #5d83a7,
20
+ 'button-ripple-background-color' : darken(#5d83a7, 10%),
18
21
  'button-text-color' : #bbb,
19
22
  'button-text-font-family' : #{neo(neo-font-family)},
20
23
  'button-text-font-size' : 11px,
@@ -33,6 +36,8 @@ $neoMap: map-merge($neoMap, (
33
36
  --button-background-image : #{neo(button-background-image)};
34
37
  --button-background-gradient-end : #{neo(button-background-gradient-end)};
35
38
  --button-background-gradient-start: #{neo(button-background-gradient-start)};
39
+ --button-badge-background-color : #{neo(button-badge-background-color)};
40
+ --button-badge-color : #{neo(button-badge-color)};
36
41
  --button-border : #{neo(button-border)};
37
42
  --button-border-radius : #{neo(button-border-radius)};
38
43
  --button-glyph-color : #{neo(button-glyph-color)};
@@ -42,6 +47,7 @@ $neoMap: map-merge($neoMap, (
42
47
  --button-margin : #{neo(button-margin)};
43
48
  --button-padding : #{neo(button-padding)};
44
49
  --button-pressed-border-color : #{neo(button-pressed-border-color)};
50
+ --button-ripple-background-color : #{neo(button-ripple-background-color)};
45
51
  --button-text-color : #{neo(button-text-color)};
46
52
  --button-text-font-family : #{neo(button-text-font-family)};
47
53
  --button-text-font-size : #{neo(button-text-font-size)};
@@ -50,4 +56,4 @@ $neoMap: map-merge($neoMap, (
50
56
  --button-text-transform : #{neo(button-text-transform)};
51
57
  --button-use-gradients : #{neo(button-use-gradients)};
52
58
  }
53
- }
59
+ }
@@ -1,15 +1,17 @@
1
1
  $neoMap: map-merge($neoMap, (
2
- 'table-header-button-background-color': #323232,
3
- 'table-header-button-background-image': linear-gradient(#3c3f41, #323232),
4
- 'table-header-button-color' : #bbb,
5
- 'table-header-button-glyph-color' : #bbb
2
+ 'table-header-button-background-color' : #323232,
3
+ 'table-header-button-background-image' : linear-gradient(#3c3f41, #323232),
4
+ 'table-header-button-color' : #bbb,
5
+ 'table-header-button-glyph-color' : #bbb,
6
+ 'table-header-button-ripple-background-color': darken(#5d83a7, 10%),
6
7
  ));
7
8
 
8
9
  @if $useCssVars == true {
9
10
  :root .neo-theme-dark { // .neo-table-header
10
- --table-header-button-background-color: #{neo(table-header-button-background-color)};
11
- --table-header-button-background-image: #{neo(table-header-button-background-image)};
12
- --table-header-button-color : #{neo(table-header-button-color)};
13
- --table-header-button-glyph-color : #{neo(table-header-button-glyph-color)};
11
+ --table-header-button-background-color : #{neo(table-header-button-background-color)};
12
+ --table-header-button-background-image : #{neo(table-header-button-background-image)};
13
+ --table-header-button-color : #{neo(table-header-button-color)};
14
+ --table-header-button-glyph-color : #{neo(table-header-button-glyph-color)};
15
+ --table-header-button-ripple-background-color: #{neo(table-header-button-ripple-background-color)};
14
16
  }
15
- }
17
+ }
@@ -6,6 +6,8 @@ $neoMap: map-merge($neoMap, (
6
6
  'button-background-image' : none,
7
7
  'button-background-gradient-end' : #323536,
8
8
  'button-background-gradient-start': #434749,
9
+ 'button-badge-background-color' : #1c60a0,
10
+ 'button-badge-color' : #fff,
9
11
  'button-border' : 1px solid #ddd,
10
12
  'button-border-radius' : 3px,
11
13
  'button-glyph-color' : #1c60a0,
@@ -15,6 +17,7 @@ $neoMap: map-merge($neoMap, (
15
17
  'button-margin' : 2px,
16
18
  'button-padding' : 5px 12px 5px 12px,
17
19
  'button-pressed-border-color' : #1c60a0,
20
+ 'button-ripple-background-color' : lighten(#1c60a0, 50%),
18
21
  'button-text-color' : #1c60a0,
19
22
  'button-text-font-family' : #{neo(neo-font-family)},
20
23
  'button-text-font-size' : 11px,
@@ -33,6 +36,8 @@ $neoMap: map-merge($neoMap, (
33
36
  --button-background-image : #{neo(button-background-image)};
34
37
  --button-background-gradient-end : #{neo(button-background-gradient-end)};
35
38
  --button-background-gradient-start: #{neo(button-background-gradient-start)};
39
+ --button-badge-background-color : #{neo(button-badge-background-color)};
40
+ --button-badge-color : #{neo(button-badge-color)};
36
41
  --button-border : #{neo(button-border)};
37
42
  --button-border-radius : #{neo(button-border-radius)};
38
43
  --button-glyph-color : #{neo(button-glyph-color)};
@@ -42,6 +47,7 @@ $neoMap: map-merge($neoMap, (
42
47
  --button-margin : #{neo(button-margin)};
43
48
  --button-padding : #{neo(button-padding)};
44
49
  --button-pressed-border-color : #{neo(button-pressed-border-color)};
50
+ --button-ripple-background-color : #{neo(button-ripple-background-color)};
45
51
  --button-text-color : #{neo(button-text-color)};
46
52
  --button-text-font-family : #{neo(button-text-font-family)};
47
53
  --button-text-font-size : #{neo(button-text-font-size)};
@@ -50,4 +56,4 @@ $neoMap: map-merge($neoMap, (
50
56
  --button-text-transform : #{neo(button-text-transform)};
51
57
  --button-use-gradients : #{neo(button-use-gradients)};
52
58
  }
53
- }
59
+ }
@@ -1,15 +1,17 @@
1
1
  $neoMap: map-merge($neoMap, (
2
- 'table-header-button-background-color': #5d83a7,
3
- 'table-header-button-background-image': none,
4
- 'table-header-button-color' : #fff,
5
- 'table-header-button-glyph-color' : #fff
2
+ 'table-header-button-background-color' : #5d83a7,
3
+ 'table-header-button-background-image' : none,
4
+ 'table-header-button-color' : #fff,
5
+ 'table-header-button-glyph-color' : #fff,
6
+ 'table-header-button-ripple-background-color': darken(#5d83a7, 10%),
6
7
  ));
7
8
 
8
9
  @if $useCssVars == true {
9
10
  :root .neo-theme-light { // .neo-table-header-button
10
- --table-header-button-background-color: #{neo(table-header-button-background-color)};
11
- --table-header-button-background-image: #{neo(table-header-button-background-image)};
12
- --table-header-button-color : #{neo(table-header-button-color)};
13
- --table-header-button-glyph-color : #{neo(table-header-button-glyph-color)};
11
+ --table-header-button-background-color : #{neo(table-header-button-background-color)};
12
+ --table-header-button-background-image : #{neo(table-header-button-background-image)};
13
+ --table-header-button-color : #{neo(table-header-button-color)};
14
+ --table-header-button-glyph-color : #{neo(table-header-button-glyph-color)};
15
+ --table-header-button-ripple-background-color: #{neo(table-header-button-ripple-background-color)};
14
16
  }
15
- }
17
+ }
@@ -6,7 +6,27 @@ import NeoArray from '../util/Array.mjs';
6
6
  * @extends Neo.component.Base
7
7
  */
8
8
  class Base extends Component {
9
+ /**
10
+ * Time in ms for the ripple effect when clicking on the button.
11
+ * Only active if useRippleEffect is set to true.
12
+ * @member {Number} rippleEffectDuration=400
13
+ */
14
+ rippleEffectDuration = 400
15
+ /**
16
+ * Internal flag to store the last setTimeout() id for ripple effect remove node callbacks
17
+ * @member {Number} #rippleTimeoutId=null
18
+ * @private
19
+ */
20
+ #rippleTimeoutId = null
21
+
9
22
  static getStaticConfig() {return {
23
+ /**
24
+ * Valid values for badgePosition
25
+ * @member {String[]} badgePositions=['bottom-left','bottom-right','top-left','top-right']
26
+ * @protected
27
+ * @static
28
+ */
29
+ badgePositions: ['bottom-left', 'bottom-right', 'top-left', 'top-right'],
10
30
  /**
11
31
  * Valid values for iconPosition
12
32
  * @member {String[]} iconPositions=['top','right','bottom','left']
@@ -27,6 +47,14 @@ class Base extends Component {
27
47
  * @protected
28
48
  */
29
49
  ntype: 'button',
50
+ /**
51
+ * @member {String} badgePosition_='top-right'
52
+ */
53
+ badgePosition_: 'top-right',
54
+ /**
55
+ * @member {String|null} badgeText_=null
56
+ */
57
+ badgeText_: null,
30
58
  /**
31
59
  * @member {String[]} cls=['neo-button']
32
60
  */
@@ -89,16 +117,61 @@ class Base extends Component {
89
117
  * @member {String} urlTarget_='_blank'
90
118
  */
91
119
  urlTarget_: '_blank',
120
+ /**
121
+ * True adds an expanding circle on click
122
+ * @member {Boolean} useRippleEffect_=true
123
+ */
124
+ useRippleEffect_: true,
92
125
  /**
93
126
  * @member {Object} _vdom
94
127
  */
95
128
  _vdom:
96
129
  {tag: 'button', type: 'button', cn: [
97
130
  {tag: 'span', cls: ['neo-button-glyph']},
98
- {tag: 'span', cls: ['neo-button-text']}
131
+ {tag: 'span', cls: ['neo-button-text']},
132
+ {cls: ['neo-button-badge']},
133
+ {cls: ['neo-button-ripple-wrapper'], cn: [
134
+ {cls: ['neo-button-ripple']}
135
+ ]}
99
136
  ]}
100
137
  }}
101
138
 
139
+ /**
140
+ * Triggered after the badgePosition config got changed
141
+ * @param {String} value
142
+ * @param {String} oldValue
143
+ * @protected
144
+ */
145
+ afterSetBadgePosition(value, oldValue) {
146
+ let me = this,
147
+ badgeEl = me.getBadgeNode(),
148
+ cls = badgeEl.cls || [],
149
+ vdom = me.vdom;
150
+
151
+ NeoArray.remove(cls, 'neo-' + oldValue);
152
+ NeoArray.add(cls, 'neo-' + value);
153
+
154
+ badgeEl.cls = cls;
155
+ me.vdom = vdom;
156
+ }
157
+
158
+ /**
159
+ * Triggered after the badgeText config got changed
160
+ * @param {String|null} value
161
+ * @param {String|null} oldValue
162
+ * @protected
163
+ */
164
+ afterSetBadgeText(value, oldValue) {
165
+ let me = this,
166
+ badgeNode = me.getBadgeNode(),
167
+ vdom = me.vdom;
168
+
169
+ badgeNode.html = value;
170
+ badgeNode.removeDom = !Boolean(value);
171
+
172
+ me.vdom = vdom;
173
+ }
174
+
102
175
  /**
103
176
  * Triggered after the handler config got changed
104
177
  * @param {String} value
@@ -106,17 +179,12 @@ class Base extends Component {
106
179
  * @protected
107
180
  */
108
181
  afterSetHandler(value, oldValue) {
109
- if (value) {
110
- let me = this,
111
- domListeners = me.domListeners || [];
112
-
113
- domListeners.push({
114
- click: value,
115
- scope: me.handlerScope || me
116
- });
182
+ let me = this;
117
183
 
118
- me.domListeners = domListeners;
119
- }
184
+ value && me.addDomListeners({
185
+ click: value,
186
+ scope: me.handlerScope || me
187
+ });
120
188
  }
121
189
 
122
190
  /**
@@ -128,7 +196,7 @@ class Base extends Component {
128
196
  afterSetIconCls(value, oldValue) {
129
197
  let me = this,
130
198
  vdom = me.vdom,
131
- iconNode = me.getVdomRoot().cn[0];
199
+ iconNode = me.getIconNode();
132
200
 
133
201
  NeoArray.remove(iconNode.cls, oldValue);
134
202
 
@@ -151,7 +219,7 @@ class Base extends Component {
151
219
  afterSetIconColor(value, oldValue) {
152
220
  let me = this,
153
221
  vdom = me.vdom,
154
- iconNode = me.getVdomRoot().cn[0];
222
+ iconNode = me.getIconNode();
155
223
 
156
224
  if (!iconNode.style) {
157
225
  iconNode.style = {};
@@ -200,17 +268,12 @@ class Base extends Component {
200
268
  * @protected
201
269
  */
202
270
  afterSetRoute(value, oldValue) {
203
- if (value) {
204
- let me = this,
205
- domListeners = me.domListeners || [];
206
-
207
- domListeners.push({
208
- click: me.changeRoute,
209
- scope: me
210
- });
271
+ let me = this;
211
272
 
212
- me.domListeners = domListeners;
213
- }
273
+ value && me.addDomListeners({
274
+ click: me.changeRoute,
275
+ scope: me
276
+ });
214
277
  }
215
278
 
216
279
  /**
@@ -261,6 +324,29 @@ class Base extends Component {
261
324
  me.vdom = vdom;
262
325
  }
263
326
 
327
+ /**
328
+ * Triggered after the useRippleEffect config got changed
329
+ * @param {Boolean} value
330
+ * @param {Boolean} oldValue
331
+ * @protected
332
+ */
333
+ afterSetUseRippleEffect(value, oldValue) {
334
+ let me = this,
335
+ listener = {click: me.showRipple, scope: me},
336
+ rippleWrapper = me.getRippleWrapper(),
337
+ vdom = me.vdom;
338
+
339
+ if (!value && oldValue) {
340
+ me.removeDomListeners(listener);
341
+ } else if (value) {
342
+ me.addDomListeners(listener);
343
+ }
344
+
345
+ // setting the config to false should end running ripple animations
346
+ rippleWrapper.removeDom = true;
347
+ me.vdom = vdom;
348
+ }
349
+
264
350
  /**
265
351
  * Triggered after the urlTarget config got changed
266
352
  * @param {String} value
@@ -296,6 +382,17 @@ class Base extends Component {
296
382
  return iconCls;
297
383
  }
298
384
 
385
+ /**
386
+ * Triggered before the badgePosition config gets changed
387
+ * @param {String} value
388
+ * @param {String} oldValue
389
+ * @returns {String}
390
+ * @protected
391
+ */
392
+ beforeSetBadgePosition(value, oldValue) {
393
+ return this.beforeSetEnumValue(value, oldValue, 'badgePosition');
394
+ }
395
+
299
396
  /**
300
397
  * Triggered before the iconCls config gets changed. Converts the string into an array if needed.
301
398
  * @param {Array|String|null} value
@@ -333,6 +430,72 @@ class Base extends Component {
333
430
  Neo.Main.setRoute({value: me.route});
334
431
  }
335
432
  }
433
+
434
+ /**
435
+ * Convenience shortcut
436
+ * @returns {Object}
437
+ */
438
+ getBadgeNode() {
439
+ return this.getVdomRoot().cn[2];
440
+ }
441
+
442
+ /**
443
+ * Convenience shortcut
444
+ * @returns {Object}
445
+ */
446
+ getIconNode() {
447
+ return this.getVdomRoot().cn[0];
448
+ }
449
+
450
+ /**
451
+ * Convenience shortcut
452
+ * @returns {Object}
453
+ */
454
+ getRippleWrapper() {
455
+ return this.getVdomRoot().cn[3];
456
+ }
457
+
458
+ /**
459
+ * @param {Object} data
460
+ */
461
+ async showRipple(data) {
462
+ let me = this,
463
+ buttonRect = data.path[0].rect,
464
+ diameter = Math.max(buttonRect.height, buttonRect.width),
465
+ radius = diameter / 2,
466
+ vdom = me.vdom,
467
+ rippleEffectDuration = me.rippleEffectDuration,
468
+ rippleWrapper = me.getRippleWrapper(),
469
+ rippleEl = rippleWrapper.cn[0],
470
+ rippleTimeoutId;
471
+
472
+ rippleEl.style = Object.assign(rippleEl.style || {}, {
473
+ animation: 'none',
474
+ left : `${data.clientX - buttonRect.left - radius}px`,
475
+ height : `${diameter}px`,
476
+ top : `${data.clientY - buttonRect.top - radius}px`,
477
+ width : `${diameter}px`
478
+ });
479
+
480
+ delete rippleWrapper.removeDom;
481
+
482
+ me.vdom = vdom;
483
+
484
+ await Neo.timeout(1);
485
+
486
+ rippleEl.style.animation = `ripple ${rippleEffectDuration}ms linear`;
487
+ me.vdom = vdom;
488
+
489
+ me.#rippleTimeoutId = rippleTimeoutId = setTimeout(() => {
490
+ // we do not want to break animations when clicking multiple times
491
+ if (me.#rippleTimeoutId === rippleTimeoutId) {
492
+ me.#rippleTimeoutId = null;
493
+
494
+ rippleWrapper.removeDom = true;
495
+ me.vdom = vdom;
496
+ }
497
+ }, rippleEffectDuration);
498
+ }
336
499
  }
337
500
 
338
501
  Neo.applyClassConfig(Base);
@@ -178,15 +178,12 @@ class YearComponent extends Component {
178
178
  construct(config) {
179
179
  super.construct(config);
180
180
 
181
- let me = this,
182
- domListeners = me.domListeners;
181
+ let me = this;
183
182
 
184
- domListeners.push(
183
+ me.addDomListeners([
185
184
  {click: me.onNavButtonClick, delegate: '.neo-nav-button', scope: me},
186
185
  {wheel: me.onWheel, scope: me}
187
- );
188
-
189
- me.domListeners = domListeners;
186
+ ]);
190
187
 
191
188
  if (me.calendarStore.getCount() > 0 && me.eventStore.getCount() > 0) {
192
189
  me.createMonths(true); // silent update
@@ -160,15 +160,12 @@ class Component extends BaseComponent {
160
160
  construct(config) {
161
161
  super.construct(config);
162
162
 
163
- let me = this,
164
- domListeners = me.domListeners;
163
+ let me = this;
165
164
 
166
- domListeners.push(
165
+ me.addDomListeners([
167
166
  {dblclick: me.onEventDoubleClick, delegate: 'neo-event', scope: me},
168
167
  {wheel : me.onWheel, scope: me}
169
- );
170
-
171
- me.domListeners = domListeners;
168
+ ]);
172
169
 
173
170
  if (me.calendarStore.getCount() > 0 && me.eventStore.getCount() > 0) {
174
171
  me.needsEventUpdate = true;
@@ -219,15 +219,12 @@ class Component extends BaseComponent {
219
219
  construct(config) {
220
220
  super.construct(config);
221
221
 
222
- let me = this,
223
- domListeners = me.domListeners;
222
+ let me = this;
224
223
 
225
- domListeners.push(
224
+ me.addDomListeners([
226
225
  {dblclick: me.onEventDoubleClick, scope: me, delegate: '.neo-event'},
227
226
  {wheel : me.onWheel, scope: me}
228
- );
229
-
230
- me.domListeners = domListeners;
227
+ ]);
231
228
 
232
229
  me.timeAxis = Neo.create(TimeAxisComponent, {
233
230
  appName : me.appName,
@@ -29,22 +29,19 @@ class DragDrop extends Base {
29
29
  construct(config) {
30
30
  super.construct(config);
31
31
 
32
- let me = this,
33
- columnOpts = {scope: me, delegate: '.neo-c-w-column'},
34
- eventOpts = {scope: me, delegate: '.neo-event'},
35
- owner = me.owner,
36
- domListeners = owner.domListeners;
32
+ let me = this,
33
+ columnOpts = {scope: me, delegate: '.neo-c-w-column'},
34
+ eventOpts = {scope: me, delegate: '.neo-event'},
35
+ owner = me.owner;
37
36
 
38
- domListeners.push(
37
+ owner.addDomListeners([
39
38
  {'drag:end' : me.onColumnDragEnd, ...columnOpts},
40
39
  {'drag:end' : me.onEventDragEnd, ...eventOpts},
41
40
  {'drag:move' : me.onColumnDragMove, ...columnOpts},
42
41
  {'drag:move' : me.onEventDragMove, ...eventOpts},
43
42
  {'drag:start': me.onColumnDragStart, ...columnOpts},
44
43
  {'drag:start': me.onEventDragStart, ...eventOpts}
45
- );
46
-
47
- owner.domListeners = domListeners;
44
+ ]);
48
45
  }
49
46
 
50
47
  /**
@@ -105,7 +105,7 @@ class Base extends CoreBase {
105
105
  * afterSetStayOnHover(value, oldValue) {
106
106
  * if (value) {
107
107
  * let me = this,
108
- * domListeners = me.domListeners || [];
108
+ * domListeners = me.domListeners;
109
109
  *
110
110
  * domListeners.push(
111
111
  * {mouseenter: me.onMouseEnter, scope: me},
@@ -432,6 +432,22 @@ class Base extends CoreBase {
432
432
  this.cls = cls;
433
433
  }
434
434
 
435
+ /**
436
+ * Convenience shortcut to add additional dom listeners
437
+ * @param {Object|Object[]} value
438
+ */
439
+ addDomListeners(value) {
440
+ if (!Array.isArray(value)) {
441
+ value = [value];
442
+ }
443
+
444
+ let domListeners = this.domListeners;
445
+
446
+ domListeners.push(...value);
447
+
448
+ this.domListeners = domListeners;
449
+ }
450
+
435
451
  /**
436
452
  * Either a string like 'color: red; background-color: blue;'
437
453
  * or an object containing style attributes
@@ -99,24 +99,12 @@ class Carousel extends Component {
99
99
  construct(config) {
100
100
  super.construct(config);
101
101
 
102
- let me = this,
103
- domListeners = me.domListeners;
104
-
105
- domListeners.push({
106
- click: {
107
- fn : me.onCarouselBtnClick,
108
- delegate: '.neo-carousel-btn',
109
- scope : me
110
- }
111
- }, {
112
- click: {
113
- fn : me.onClick,
114
- delegate: '.neo-carousel-item',
115
- scope : me
116
- }
117
- });
102
+ let me = this;
118
103
 
119
- me.domListeners = domListeners;
104
+ me.addDomListeners([
105
+ {click: me.onCarouselBtnClick, delegate: '.neo-carousel-btn', scope: me},
106
+ {click: me.onClick, delegate: '.neo-carousel-item', scope: me}
107
+ ]);
120
108
  }
121
109
 
122
110
  /**
@@ -63,19 +63,14 @@ class Chip extends Component {
63
63
  construct(config) {
64
64
  super.construct(config);
65
65
 
66
- let me = this,
67
- domListeners;
66
+ let me = this;
68
67
 
69
68
  if (me.useDomListeners) {
70
- domListeners = me.domListeners;
71
-
72
- domListeners.push({
69
+ me.addDomListeners({
73
70
  click : me.onCloseButtonClick,
74
71
  delegate: 'neo-chip-close-button',
75
72
  scope : me
76
73
  });
77
-
78
- me.domListeners = domListeners;
79
74
  }
80
75
  }
81
76
 
@@ -132,9 +132,8 @@ class Circle extends Component {
132
132
  cls : ['neo-circle', 'neo-circle-back']
133
133
  });
134
134
 
135
- let me = this,
136
- domListeners = me.domListeners,
137
- vdom = me.vdom;
135
+ let me = this,
136
+ vdom = me.vdom;
138
137
 
139
138
  if (!me.backsideIconPath) {
140
139
  me.backsideIconPath = Neo.config.resourcesPath + 'images/circle/';
@@ -144,7 +143,7 @@ class Circle extends Component {
144
143
  me.itemImagePath = Neo.config.resourcesPath + 'examples/';
145
144
  }
146
145
 
147
- domListeners.push({
146
+ me.addDomListeners([{
148
147
  mouseenter: me.expand,
149
148
  mouseleave: me.collapse,
150
149
  scope : me
@@ -166,9 +165,7 @@ class Circle extends Component {
166
165
  wheel : me.onMouseWheel,
167
166
  delegate : 'neo-circle',
168
167
  scope : me
169
- });
170
-
171
- me.domListeners = domListeners;
168
+ }]);
172
169
 
173
170
  me.store = Neo.create(Collection, {
174
171
  keyProperty: 'id'
@@ -143,15 +143,12 @@ class DateSelector extends Component {
143
143
  construct(config) {
144
144
  super.construct(config);
145
145
 
146
- let me = this,
147
- domListeners = me.domListeners;
148
-
149
- domListeners.push({
150
- click: {fn: me.onComponentClick, scope: me},
151
- wheel: {fn: me.onComponentWheel, scope: me}
152
- });
146
+ let me = this;
153
147
 
154
- me.domListeners = domListeners;
148
+ me.addDomListeners([
149
+ {click: me.onComponentClick, scope: me},
150
+ {wheel: me.onComponentWheel, scope: me}
151
+ ]);
155
152
 
156
153
  me.updateHeaderMonth(0, 0, true);
157
154
  me.updateHeaderYear(0, true);